mirror of
https://github.com/SysRay/psOff_public.git
synced 2025-02-06 05:58:24 +00:00
Move http to core/networking
This commit is contained in:
parent
5853b969cc
commit
a4a54b34c4
@ -33,6 +33,7 @@ add_library(core SHARED
|
||||
|
||||
add_dependencies(core logging third_party config_emu gamereport)
|
||||
target_link_libraries(core PRIVATE
|
||||
libboost_url
|
||||
libboost_thread
|
||||
libboost_chrono
|
||||
libboost_program_options
|
||||
|
@ -5,6 +5,7 @@ add_library(networking OBJECT
|
||||
states/online/resolver.cpp
|
||||
states/online/socket.cpp
|
||||
states/online/epoll.cpp
|
||||
states/online/http.cpp
|
||||
wepoll.c
|
||||
|
||||
networking.cpp
|
||||
|
@ -1,9 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "modules/libSceHttp/httpsTypes.h"
|
||||
#include "modules/libSceHttp/types.h"
|
||||
#include "modules/libSceNet/resolverTypes.h"
|
||||
#include "modules/libSceNet/socketTypes.h"
|
||||
#include "modules/libSceNet/types.h"
|
||||
#include "modules/libSceNetCtl/types.h"
|
||||
#include "modules/libSceSsl/types.h"
|
||||
#include "modules_include/common.h"
|
||||
#include "utility/utility.h"
|
||||
|
||||
@ -79,6 +82,73 @@ class INetworking {
|
||||
virtual int socketShutdown(SceNetId s, int how) = 0;
|
||||
virtual int socketClose(SceNetId s) = 0;
|
||||
virtual int socketAbort(SceNetId s, int flags) = 0;
|
||||
|
||||
/* HTTP facility */
|
||||
|
||||
/* HTTP1 facility */
|
||||
virtual int httpInit(int libnetMemId, int libsslCtxId, size_t poolSize) = 0;
|
||||
virtual int httpTerm(int libhttpCtxId) = 0;
|
||||
virtual int httpGetMemoryPoolStats(int libhttpCtxId, SceHttpMemoryPoolStats* currentStat) = 0;
|
||||
virtual int httpCreateTemplate(int libhttpCtxId, const char* userAgent, int httpVer, int isAutoProxyConf) = 0;
|
||||
virtual int httpDeleteTemplate(int tmplId) = 0;
|
||||
virtual int httpCreateConnection(int tmplId, const char* serverName, const char* scheme, uint16_t port, int isEnableKeepalive) = 0;
|
||||
virtual int httpCreateConnectionWithURL(int tmplId, const char* url, int isEnableKeepalive) = 0;
|
||||
virtual int httpDeleteConnection(int connId) = 0;
|
||||
virtual int httpCreateRequest(int connId, int method, const char* path, uint64_t contentLength) = 0;
|
||||
virtual int httpCreateRequest2(int connId, const char* method, const char* path, uint64_t contentLength) = 0;
|
||||
virtual int httpCreateRequestWithURL(int connId, int method, const char* url, uint64_t contentLength) = 0;
|
||||
virtual int httpCreateRequestWithURL2(int connId, const char* method, const char* url, uint64_t contentLength) = 0;
|
||||
virtual int httpDeleteRequest(int reqId) = 0;
|
||||
virtual int httpSetRequestContentLength(int id, uint64_t contentLength) = 0;
|
||||
virtual int httpSetChunkedTransferEnabled(int id, int isEnable) = 0;
|
||||
virtual int httpSetInflateGZIPEnabled(int id, int isEnable) = 0;
|
||||
virtual int httpSendRequest(int reqId, const void* postData, size_t size) = 0;
|
||||
virtual int httpAbortRequest(int reqId) = 0;
|
||||
virtual int httpGetResponseContentLength(int reqId, int* result, uint64_t* contentLength) = 0;
|
||||
virtual int httpGetStatusCode(int reqId, int* statusCode) = 0;
|
||||
virtual int httpGetAllResponseHeaders(int reqId, char** header, size_t* headerSize) = 0;
|
||||
virtual int httpReadData(int reqId, void* data, size_t size) = 0;
|
||||
virtual int httpAddRequestHeader(int id, const char* name, const char* value, uint32_t mode) = 0;
|
||||
virtual int httpRemoveRequestHeader(int id, const char* name) = 0;
|
||||
virtual int httpParseResponseHeader(const char* header, size_t headerLen, const char* fieldStr, const char** fieldValue, size_t* valueLen) = 0;
|
||||
virtual int httpParseStatusLine(const char* statusLine, size_t lineLen, int* httpMajorVer, int* httpMinorVer, int* responseCode, const char** reasonPhrase,
|
||||
size_t* phraseLen) = 0;
|
||||
virtual int httpSetResponseHeaderMaxSize(int id, size_t headerSize) = 0;
|
||||
virtual int httpSetAuthInfoCallback(int id, SceHttpAuthInfoCallback cbfunc, void* userArg) = 0;
|
||||
virtual int httpSetAuthEnabled(int id, int isEnable) = 0;
|
||||
virtual int httpGetAuthEnabled(int id, int* isEnable) = 0;
|
||||
virtual int httpAuthCacheFlush(int libhttpCtxId) = 0;
|
||||
virtual int httpSetRedirectCallback(int id, SceHttpRedirectCallback cbfunc, void* userArg) = 0;
|
||||
virtual int httpSetAutoRedirect(int id, int isEnable) = 0;
|
||||
virtual int httpGetAutoRedirect(int id, int* isEnable) = 0;
|
||||
virtual int httpRedirectCacheFlush(int libhttpCtxId) = 0;
|
||||
virtual int httpSetResolveTimeOut(int id, uint32_t usec) = 0;
|
||||
virtual int httpSetResolveRetry(int id, int retry) = 0;
|
||||
virtual int httpSetConnectTimeOut(int id, uint32_t usec) = 0;
|
||||
virtual int httpSetSendTimeOut(int id, uint32_t usec) = 0;
|
||||
virtual int httpSetRecvTimeOut(int id, uint32_t usec) = 0;
|
||||
virtual int httpSetRequestStatusCallback(int id, SceHttpRequestStatusCallback cbfunc, void* userArg) = 0;
|
||||
virtual int httpGetLastErrno(int reqId, int* errNum) = 0;
|
||||
virtual int httpSetNonblock(int id, int isEnable) = 0;
|
||||
virtual int httpGetNonblock(int id, int* isEnable) = 0;
|
||||
virtual int httpTrySetNonblock(int id, int isEnable) = 0;
|
||||
virtual int httpTryGetNonblock(int id, int* isEnable) = 0;
|
||||
virtual int httpCreateEpoll(int libhttpCtxId, SceHttpEpollHandle* eh) = 0;
|
||||
virtual int httpSetEpoll(int id, SceHttpEpollHandle eh, void* userArg) = 0;
|
||||
virtual int httpUnsetEpoll(int id) = 0;
|
||||
virtual int httpGetEpoll(int id, SceHttpEpollHandle* eh, void** userArg) = 0;
|
||||
virtual int httpDestroyEpoll(int libhttpCtxId, SceHttpEpollHandle eh) = 0;
|
||||
virtual int httpWaitRequest(SceHttpEpollHandle eh, SceHttpNBEvent* nbev, int maxevents, int timeout) = 0;
|
||||
virtual int httpAbortWaitRequest(SceHttpEpollHandle eh) = 0;
|
||||
|
||||
// HTTPS
|
||||
virtual int httpsLoadCert(int libhttpCtxId, int caCertNum, const SceSslData** caList, const SceSslData* cert, const SceSslData* privKey) = 0;
|
||||
virtual int httpsUnloadCert(int libhttpCtxId) = 0;
|
||||
virtual int httpsEnableOption(int id, uint32_t sslFlags) = 0;
|
||||
virtual int httpsDisableOption(int id, uint32_t sslFlags) = 0;
|
||||
virtual int httpsGetSslError(int id, int* errNum, uint32_t* detail) = 0;
|
||||
virtual int httpsSetSslCallback(int id, SceHttpsCallback cbfunc, void* userArg) = 0;
|
||||
virtual int httpsSetSslVersion(int id, SceSslVersion version) = 0;
|
||||
};
|
||||
|
||||
#if defined(__APICALL_EXTERN)
|
||||
|
@ -135,3 +135,253 @@ int OfflineNet::socketClose(SceNetId s) {
|
||||
int OfflineNet::socketAbort(SceNetId s, int flags) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpInit(int libnetMemId, int libsslCtxId, size_t poolSize) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpTerm(int libhttpCtxId) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpGetMemoryPoolStats(int libhttpCtxId, SceHttpMemoryPoolStats* currentStat) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpCreateTemplate(int libhttpCtxId, const char* userAgent, int httpVer, int isAutoProxyConf) {
|
||||
static int id = 0;
|
||||
return ++id;
|
||||
}
|
||||
|
||||
int OfflineNet::httpDeleteTemplate(int tmplId) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpCreateConnection(int tmplId, const char* serverName, const char* scheme, uint16_t port, int isEnableKeepalive) {
|
||||
static int id = 0;
|
||||
return ++id;
|
||||
}
|
||||
|
||||
int OfflineNet::httpCreateConnectionWithURL(int tmplId, const char* url, int isEnableKeepalive) {
|
||||
static int id = 0;
|
||||
return ++id;
|
||||
}
|
||||
|
||||
int OfflineNet::httpDeleteConnection(int connId) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpCreateRequest(int connId, int method, const char* path, uint64_t contentLength) {
|
||||
static int id = 0;
|
||||
return ++id;
|
||||
}
|
||||
|
||||
int OfflineNet::httpCreateRequest2(int connId, const char* method, const char* path, uint64_t contentLength) {
|
||||
static int id = 0;
|
||||
return ++id;
|
||||
}
|
||||
|
||||
int OfflineNet::httpCreateRequestWithURL(int connId, int method, const char* url, uint64_t contentLength) {
|
||||
static int id = 0;
|
||||
return ++id;
|
||||
}
|
||||
|
||||
int OfflineNet::httpCreateRequestWithURL2(int connId, const char* method, const char* url, uint64_t contentLength) {
|
||||
static int id = 0;
|
||||
return ++id;
|
||||
}
|
||||
|
||||
int OfflineNet::httpDeleteRequest(int reqId) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpSetRequestContentLength(int id, uint64_t contentLength) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpSetChunkedTransferEnabled(int id, int isEnable) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpSetInflateGZIPEnabled(int id, int isEnable) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpSendRequest(int reqId, const void* postData, size_t size) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpAbortRequest(int reqId) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpGetResponseContentLength(int reqId, int* result, uint64_t* contentLength) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpGetStatusCode(int reqId, int* statusCode) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpGetAllResponseHeaders(int reqId, char** header, size_t* headerSize) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpReadData(int reqId, void* data, size_t size) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpAddRequestHeader(int id, const char* name, const char* value, uint32_t mode) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpRemoveRequestHeader(int id, const char* name) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpParseResponseHeader(const char* header, size_t headerLen, const char* fieldStr, const char** fieldValue, size_t* valueLen) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpParseStatusLine(const char* statusLine, size_t lineLen, int* httpMajorVer, int* httpMinorVer, int* responseCode, const char** reasonPhrase,
|
||||
size_t* phraseLen) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpSetResponseHeaderMaxSize(int id, size_t headerSize) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpSetAuthInfoCallback(int id, SceHttpAuthInfoCallback cbfunc, void* userArg) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpSetAuthEnabled(int id, int isEnable) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpGetAuthEnabled(int id, int* isEnable) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpAuthCacheFlush(int libhttpCtxId) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpSetRedirectCallback(int id, SceHttpRedirectCallback cbfunc, void* userArg) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpSetAutoRedirect(int id, int isEnable) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpGetAutoRedirect(int id, int* isEnable) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpRedirectCacheFlush(int libhttpCtxId) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpSetResolveTimeOut(int id, uint32_t usec) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpSetResolveRetry(int id, int retry) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpSetConnectTimeOut(int id, uint32_t usec) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpSetSendTimeOut(int id, uint32_t usec) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpSetRecvTimeOut(int id, uint32_t usec) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpSetRequestStatusCallback(int id, SceHttpRequestStatusCallback cbfunc, void* userArg) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpGetLastErrno(int reqId, int* errNum) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpSetNonblock(int id, int isEnable) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpGetNonblock(int id, int* isEnable) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpTrySetNonblock(int id, int isEnable) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpTryGetNonblock(int id, int* isEnable) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpCreateEpoll(int libhttpCtxId, SceHttpEpollHandle* eh) {
|
||||
static int id = 0;
|
||||
return ++id;
|
||||
}
|
||||
|
||||
int OfflineNet::httpSetEpoll(int id, SceHttpEpollHandle eh, void* userArg) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpUnsetEpoll(int id) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpGetEpoll(int id, SceHttpEpollHandle* eh, void** userArg) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpDestroyEpoll(int libhttpCtxId, SceHttpEpollHandle eh) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpWaitRequest(SceHttpEpollHandle eh, SceHttpNBEvent* nbev, int maxevents, int timeout) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpAbortWaitRequest(SceHttpEpollHandle eh) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
// HTTPS
|
||||
int OfflineNet::httpsLoadCert(int libhttpCtxId, int caCertNum, const SceSslData** caList, const SceSslData* cert, const SceSslData* privKey) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpsUnloadCert(int libhttpCtxId) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpsEnableOption(int id, uint32_t sslFlags) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpsDisableOption(int id, uint32_t sslFlags) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpsGetSslError(int id, int* errNum, uint32_t* detail) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpsSetSslCallback(int id, SceHttpsCallback cbfunc, void* userArg) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OfflineNet::httpsSetSslVersion(int id, SceSslVersion version) {
|
||||
return Ok;
|
||||
}
|
||||
|
@ -51,4 +51,71 @@ class OfflineNet: public INetworking {
|
||||
int socketShutdown(SceNetId s, int how) final;
|
||||
int socketClose(SceNetId s) final;
|
||||
int socketAbort(SceNetId s, int flags) final;
|
||||
|
||||
/* HTTP facility */
|
||||
|
||||
/* HTTP1 facility */
|
||||
int httpInit(int libnetMemId, int libsslCtxId, size_t poolSize) final;
|
||||
int httpTerm(int libhttpCtxId) final;
|
||||
int httpGetMemoryPoolStats(int libhttpCtxId, SceHttpMemoryPoolStats* currentStat) final;
|
||||
int httpCreateTemplate(int libhttpCtxId, const char* userAgent, int httpVer, int isAutoProxyConf) final;
|
||||
int httpDeleteTemplate(int tmplId) final;
|
||||
int httpCreateConnection(int tmplId, const char* serverName, const char* scheme, uint16_t port, int isEnableKeepalive) final;
|
||||
int httpCreateConnectionWithURL(int tmplId, const char* url, int isEnableKeepalive) final;
|
||||
int httpDeleteConnection(int connId) final;
|
||||
int httpCreateRequest(int connId, int method, const char* path, uint64_t contentLength) final;
|
||||
int httpCreateRequest2(int connId, const char* method, const char* path, uint64_t contentLength) final;
|
||||
int httpCreateRequestWithURL(int connId, int method, const char* url, uint64_t contentLength) final;
|
||||
int httpCreateRequestWithURL2(int connId, const char* method, const char* url, uint64_t contentLength) final;
|
||||
int httpDeleteRequest(int reqId) final;
|
||||
int httpSetRequestContentLength(int id, uint64_t contentLength) final;
|
||||
int httpSetChunkedTransferEnabled(int id, int isEnable) final;
|
||||
int httpSetInflateGZIPEnabled(int id, int isEnable) final;
|
||||
int httpSendRequest(int reqId, const void* postData, size_t size) final;
|
||||
int httpAbortRequest(int reqId) final;
|
||||
int httpGetResponseContentLength(int reqId, int* result, uint64_t* contentLength) final;
|
||||
int httpGetStatusCode(int reqId, int* statusCode) final;
|
||||
int httpGetAllResponseHeaders(int reqId, char** header, size_t* headerSize) final;
|
||||
int httpReadData(int reqId, void* data, size_t size) final;
|
||||
int httpAddRequestHeader(int id, const char* name, const char* value, uint32_t mode) final;
|
||||
int httpRemoveRequestHeader(int id, const char* name) final;
|
||||
int httpParseResponseHeader(const char* header, size_t headerLen, const char* fieldStr, const char** fieldValue, size_t* valueLen) final;
|
||||
int httpParseStatusLine(const char* statusLine, size_t lineLen, int* httpMajorVer, int* httpMinorVer, int* responseCode, const char** reasonPhrase,
|
||||
size_t* phraseLen) final;
|
||||
int httpSetResponseHeaderMaxSize(int id, size_t headerSize) final;
|
||||
int httpSetAuthInfoCallback(int id, SceHttpAuthInfoCallback cbfunc, void* userArg) final;
|
||||
int httpSetAuthEnabled(int id, int isEnable) final;
|
||||
int httpGetAuthEnabled(int id, int* isEnable) final;
|
||||
int httpAuthCacheFlush(int libhttpCtxId) final;
|
||||
int httpSetRedirectCallback(int id, SceHttpRedirectCallback cbfunc, void* userArg) final;
|
||||
int httpSetAutoRedirect(int id, int isEnable) final;
|
||||
int httpGetAutoRedirect(int id, int* isEnable) final;
|
||||
int httpRedirectCacheFlush(int libhttpCtxId) final;
|
||||
int httpSetResolveTimeOut(int id, uint32_t usec) final;
|
||||
int httpSetResolveRetry(int id, int retry) final;
|
||||
int httpSetConnectTimeOut(int id, uint32_t usec) final;
|
||||
int httpSetSendTimeOut(int id, uint32_t usec) final;
|
||||
int httpSetRecvTimeOut(int id, uint32_t usec) final;
|
||||
int httpSetRequestStatusCallback(int id, SceHttpRequestStatusCallback cbfunc, void* userArg) final;
|
||||
int httpGetLastErrno(int reqId, int* errNum) final;
|
||||
int httpSetNonblock(int id, int isEnable) final;
|
||||
int httpGetNonblock(int id, int* isEnable) final;
|
||||
int httpTrySetNonblock(int id, int isEnable) final;
|
||||
int httpTryGetNonblock(int id, int* isEnable) final;
|
||||
int httpCreateEpoll(int libhttpCtxId, SceHttpEpollHandle* eh) final;
|
||||
int httpSetEpoll(int id, SceHttpEpollHandle eh, void* userArg) final;
|
||||
int httpUnsetEpoll(int id) final;
|
||||
int httpGetEpoll(int id, SceHttpEpollHandle* eh, void** userArg) final;
|
||||
int httpDestroyEpoll(int libhttpCtxId, SceHttpEpollHandle eh) final;
|
||||
int httpWaitRequest(SceHttpEpollHandle eh, SceHttpNBEvent* nbev, int maxevents, int timeout) final;
|
||||
int httpAbortWaitRequest(SceHttpEpollHandle eh) final;
|
||||
|
||||
// HTTPS
|
||||
int httpsLoadCert(int libhttpCtxId, int caCertNum, const SceSslData** caList, const SceSslData* cert, const SceSslData* privKey) final;
|
||||
int httpsUnloadCert(int libhttpCtxId) final;
|
||||
int httpsEnableOption(int id, uint32_t sslFlags) final;
|
||||
int httpsDisableOption(int id, uint32_t sslFlags) final;
|
||||
int httpsGetSslError(int id, int* errNum, uint32_t* detail) final;
|
||||
int httpsSetSslCallback(int id, SceHttpsCallback cbfunc, void* userArg) final;
|
||||
int httpsSetSslVersion(int id, SceSslVersion version) final;
|
||||
};
|
||||
|
@ -55,4 +55,71 @@ class OnlineNet: public INetworking {
|
||||
int socketShutdown(SceNetId s, int how) final;
|
||||
int socketClose(SceNetId s) final;
|
||||
int socketAbort(SceNetId s, int flags) final;
|
||||
|
||||
/* HTTP facility */
|
||||
|
||||
/* HTTP1 facility */
|
||||
int httpInit(int libnetMemId, int libsslCtxId, size_t poolSize) final;
|
||||
int httpTerm(int libhttpCtxId) final;
|
||||
int httpGetMemoryPoolStats(int libhttpCtxId, SceHttpMemoryPoolStats* currentStat) final;
|
||||
int httpCreateTemplate(int libhttpCtxId, const char* userAgent, int httpVer, int isAutoProxyConf) final;
|
||||
int httpDeleteTemplate(int tmplId) final;
|
||||
int httpCreateConnection(int tmplId, const char* serverName, const char* scheme, uint16_t port, int isEnableKeepalive) final;
|
||||
int httpCreateConnectionWithURL(int tmplId, const char* url, int isEnableKeepalive) final;
|
||||
int httpDeleteConnection(int connId) final;
|
||||
int httpCreateRequest(int connId, int method, const char* path, uint64_t contentLength) final;
|
||||
int httpCreateRequest2(int connId, const char* method, const char* path, uint64_t contentLength) final;
|
||||
int httpCreateRequestWithURL(int connId, int method, const char* url, uint64_t contentLength) final;
|
||||
int httpCreateRequestWithURL2(int connId, const char* method, const char* url, uint64_t contentLength) final;
|
||||
int httpDeleteRequest(int reqId) final;
|
||||
int httpSetRequestContentLength(int id, uint64_t contentLength) final;
|
||||
int httpSetChunkedTransferEnabled(int id, int isEnable) final;
|
||||
int httpSetInflateGZIPEnabled(int id, int isEnable) final;
|
||||
int httpSendRequest(int reqId, const void* postData, size_t size) final;
|
||||
int httpAbortRequest(int reqId) final;
|
||||
int httpGetResponseContentLength(int reqId, int* result, uint64_t* contentLength) final;
|
||||
int httpGetStatusCode(int reqId, int* statusCode) final;
|
||||
int httpGetAllResponseHeaders(int reqId, char** header, size_t* headerSize) final;
|
||||
int httpReadData(int reqId, void* data, size_t size) final;
|
||||
int httpAddRequestHeader(int id, const char* name, const char* value, uint32_t mode) final;
|
||||
int httpRemoveRequestHeader(int id, const char* name) final;
|
||||
int httpParseResponseHeader(const char* header, size_t headerLen, const char* fieldStr, const char** fieldValue, size_t* valueLen) final;
|
||||
int httpParseStatusLine(const char* statusLine, size_t lineLen, int* httpMajorVer, int* httpMinorVer, int* responseCode, const char** reasonPhrase,
|
||||
size_t* phraseLen) final;
|
||||
int httpSetResponseHeaderMaxSize(int id, size_t headerSize) final;
|
||||
int httpSetAuthInfoCallback(int id, SceHttpAuthInfoCallback cbfunc, void* userArg) final;
|
||||
int httpSetAuthEnabled(int id, int isEnable) final;
|
||||
int httpGetAuthEnabled(int id, int* isEnable) final;
|
||||
int httpAuthCacheFlush(int libhttpCtxId) final;
|
||||
int httpSetRedirectCallback(int id, SceHttpRedirectCallback cbfunc, void* userArg) final;
|
||||
int httpSetAutoRedirect(int id, int isEnable) final;
|
||||
int httpGetAutoRedirect(int id, int* isEnable) final;
|
||||
int httpRedirectCacheFlush(int libhttpCtxId) final;
|
||||
int httpSetResolveTimeOut(int id, uint32_t usec) final;
|
||||
int httpSetResolveRetry(int id, int retry) final;
|
||||
int httpSetConnectTimeOut(int id, uint32_t usec) final;
|
||||
int httpSetSendTimeOut(int id, uint32_t usec) final;
|
||||
int httpSetRecvTimeOut(int id, uint32_t usec) final;
|
||||
int httpSetRequestStatusCallback(int id, SceHttpRequestStatusCallback cbfunc, void* userArg) final;
|
||||
int httpGetLastErrno(int reqId, int* errNum) final;
|
||||
int httpSetNonblock(int id, int isEnable) final;
|
||||
int httpGetNonblock(int id, int* isEnable) final;
|
||||
int httpTrySetNonblock(int id, int isEnable) final;
|
||||
int httpTryGetNonblock(int id, int* isEnable) final;
|
||||
int httpCreateEpoll(int libhttpCtxId, SceHttpEpollHandle* eh) final;
|
||||
int httpSetEpoll(int id, SceHttpEpollHandle eh, void* userArg) final;
|
||||
int httpUnsetEpoll(int id) final;
|
||||
int httpGetEpoll(int id, SceHttpEpollHandle* eh, void** userArg) final;
|
||||
int httpDestroyEpoll(int libhttpCtxId, SceHttpEpollHandle eh) final;
|
||||
int httpWaitRequest(SceHttpEpollHandle eh, SceHttpNBEvent* nbev, int maxevents, int timeout) final;
|
||||
int httpAbortWaitRequest(SceHttpEpollHandle eh) final;
|
||||
|
||||
// HTTPS
|
||||
int httpsLoadCert(int libhttpCtxId, int caCertNum, const SceSslData** caList, const SceSslData* cert, const SceSslData* privKey) final;
|
||||
int httpsUnloadCert(int libhttpCtxId) final;
|
||||
int httpsEnableOption(int id, uint32_t sslFlags) final;
|
||||
int httpsDisableOption(int id, uint32_t sslFlags) final;
|
||||
int httpsGetSslError(int id, int* errNum, uint32_t* detail) final;
|
||||
int httpsSetSslCallback(int id, SceHttpsCallback cbfunc, void* userArg) final;
|
||||
int httpsSetSslVersion(int id, SceSslVersion version) final;
|
||||
};
|
||||
|
715
core/networking/states/online/http.cpp
Normal file
715
core/networking/states/online/http.cpp
Normal file
@ -0,0 +1,715 @@
|
||||
#include "../online.h"
|
||||
#include "logging.h"
|
||||
|
||||
#include <Windows.h>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/url.hpp>
|
||||
|
||||
LOG_DEFINE_MODULE(OnlineNetCore_http);
|
||||
|
||||
using namespace boost::asio;
|
||||
|
||||
namespace {
|
||||
constexpr size_t ARRAY_LENGTH = 128;
|
||||
|
||||
template <typename T, size_t size>
|
||||
class HttpContainer {
|
||||
T* m_data[size] = {nullptr};
|
||||
|
||||
public:
|
||||
int lookupAvailableIdx(T* action) {
|
||||
int i;
|
||||
bool found = false;
|
||||
for (i = 1; i < size; i++) {
|
||||
if (!m_data[i]) {
|
||||
m_data[i] = action;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found == false) {
|
||||
delete action;
|
||||
return 0;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
int testId(int id) {
|
||||
if (id < 1 || id >= size || m_data[id] == nullptr) return Err::HTTP_BAD_ID;
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
void remove(int id) {
|
||||
delete m_data[id];
|
||||
m_data[id] = nullptr;
|
||||
}
|
||||
|
||||
T* getId(int id) { return m_data[id]; }
|
||||
};
|
||||
|
||||
static io_service svc;
|
||||
static ip::tcp::resolver resolver(svc);
|
||||
|
||||
struct HttpClient {
|
||||
int libnetMemId;
|
||||
int libsslCtxId;
|
||||
size_t poolSize;
|
||||
uint32_t connectTimeout;
|
||||
|
||||
HttpClient(int libnetMemId, int libsslCtxId, size_t poolSize): libnetMemId(libnetMemId), libsslCtxId(libsslCtxId), poolSize(poolSize) {}
|
||||
};
|
||||
|
||||
struct HttpTemplate {
|
||||
HttpClient* parentClient;
|
||||
const char* userAgent;
|
||||
int httpVer;
|
||||
int isAutoProxyConf;
|
||||
|
||||
HttpTemplate(HttpClient* parentClient, const char* userAgent, int httpVer, int isAutoProxyConf)
|
||||
: parentClient(parentClient), userAgent(userAgent), httpVer(httpVer), isAutoProxyConf(isAutoProxyConf) {}
|
||||
};
|
||||
|
||||
struct HttpConnection {
|
||||
HttpTemplate* parentTemplate;
|
||||
const char* serverName;
|
||||
const char* scheme;
|
||||
uint16_t port;
|
||||
int isEnableKeepalive;
|
||||
|
||||
bool connected = false;
|
||||
bool shouldFreeStrings;
|
||||
|
||||
ip::tcp::resolver::query* query = nullptr;
|
||||
ip::tcp::resolver::iterator endpoint_iterator;
|
||||
ip::tcp::socket* socket = nullptr;
|
||||
|
||||
HttpConnection(HttpTemplate* parentTemplate, const char* serverName, const char* scheme, uint16_t port, int isEnableKeepalive, bool shouldFreeStrings)
|
||||
: parentTemplate(parentTemplate), serverName(serverName), scheme(scheme), port(port), isEnableKeepalive(isEnableKeepalive),
|
||||
shouldFreeStrings(shouldFreeStrings) {}
|
||||
};
|
||||
|
||||
struct HttpResponse {
|
||||
int statusCode;
|
||||
uint32_t contentLength;
|
||||
const char* body = nullptr;
|
||||
};
|
||||
|
||||
struct HttpRequest {
|
||||
HttpConnection* parentConnection;
|
||||
int method;
|
||||
const char* path;
|
||||
uint64_t contentLength;
|
||||
const void* postData = nullptr;
|
||||
size_t size;
|
||||
HttpResponse* lastResponse = nullptr;
|
||||
|
||||
bool shouldFreePath;
|
||||
|
||||
HttpRequest(HttpConnection* parentConnection, int method, const char* path, uint64_t contentLength, bool shouldFreePath)
|
||||
: parentConnection(parentConnection), method(method), path(path), contentLength(contentLength), shouldFreePath(shouldFreePath) {}
|
||||
};
|
||||
|
||||
struct HttpRequestParams {
|
||||
HttpConnection* connection;
|
||||
HttpRequest* request;
|
||||
uint32_t connectTimeout;
|
||||
const char* userAgent;
|
||||
int httpVer;
|
||||
int isAutoProxyConf;
|
||||
const char* serverName;
|
||||
const char* scheme;
|
||||
uint16_t port;
|
||||
int isEnableKeepalive;
|
||||
int method;
|
||||
const char* path;
|
||||
uint64_t contentLength;
|
||||
const void* postData; // will be assigned to nullptr
|
||||
size_t size;
|
||||
|
||||
HttpRequestParams(HttpRequest* from) {
|
||||
connection = from->parentConnection;
|
||||
request = from;
|
||||
connectTimeout = from->parentConnection->parentTemplate->parentClient->connectTimeout;
|
||||
userAgent = from->parentConnection->parentTemplate->userAgent;
|
||||
httpVer = from->parentConnection->parentTemplate->httpVer;
|
||||
isAutoProxyConf = from->parentConnection->parentTemplate->isAutoProxyConf;
|
||||
serverName = from->parentConnection->serverName;
|
||||
scheme = from->parentConnection->scheme;
|
||||
port = from->parentConnection->port;
|
||||
isEnableKeepalive = from->parentConnection->isEnableKeepalive;
|
||||
method = from->method;
|
||||
path = from->path;
|
||||
contentLength = from->contentLength;
|
||||
postData = from->postData;
|
||||
size = from->size;
|
||||
}
|
||||
};
|
||||
|
||||
static HttpContainer<HttpClient, ARRAY_LENGTH> g_client;
|
||||
static HttpContainer<HttpTemplate, ARRAY_LENGTH> g_template;
|
||||
static HttpContainer<HttpConnection, ARRAY_LENGTH> g_connection;
|
||||
static HttpContainer<HttpRequest, ARRAY_LENGTH> g_request;
|
||||
|
||||
#define GET_LAST_RESPONSE \
|
||||
HttpRequest* request = g_request.getId(reqId); \
|
||||
HttpResponse* response = request->lastResponse; \
|
||||
if (response == nullptr) return Err::HTTP_SEND_REQUIRED;
|
||||
|
||||
static void deleteResponse(HttpResponse* response) {
|
||||
if (response->body != nullptr) {
|
||||
delete response->body;
|
||||
}
|
||||
delete response;
|
||||
}
|
||||
|
||||
static int httpMethodStringToInt(const char* method) {
|
||||
if (::_stricmp(method, "get") == 0) {
|
||||
return SCE_HTTP_GET;
|
||||
} else if (::_stricmp(method, "post") == 0) {
|
||||
return SCE_HTTP_POST;
|
||||
}
|
||||
LOG_USE_MODULE(OnlineNetCore_http);
|
||||
LOG_TRACE(L"unsupported http method: %s", method);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int32_t performHttpRequest(HttpRequestParams* request, HttpResponse* response) {
|
||||
LOG_USE_MODULE(OnlineNetCore_http);
|
||||
|
||||
HttpConnection* connection = request->connection;
|
||||
try {
|
||||
if (!connection->connected) {
|
||||
connection->query = new ip::tcp::resolver::query(request->serverName, std::to_string(request->port));
|
||||
connection->endpoint_iterator = resolver.resolve(*connection->query);
|
||||
connection->socket = new ip::tcp::socket(svc);
|
||||
boost::asio::connect(*connection->socket, connection->endpoint_iterator);
|
||||
connection->connected = true;
|
||||
|
||||
if (std::strcmp(connection->scheme, "https") == 0) {
|
||||
LOG_TRACE(L"detected an attempt to connect via https, it's not supported yet");
|
||||
|
||||
return Err::HTTP_SSL_ERROR;
|
||||
}
|
||||
if (std::strcmp(connection->scheme, "http") != 0) {
|
||||
LOG_TRACE(L"unknown scheme: %s://", connection->scheme);
|
||||
|
||||
return Err::HTTP_BAD_SCHEME;
|
||||
}
|
||||
}
|
||||
if (request->request->lastResponse != nullptr) {
|
||||
deleteResponse(request->request->lastResponse);
|
||||
}
|
||||
boost::asio::streambuf buffer;
|
||||
std::ostream bufferStream(&buffer);
|
||||
|
||||
if (request->method == SCE_HTTP_GET) {
|
||||
bufferStream << "GET ";
|
||||
} else if (request->method == SCE_HTTP_POST) {
|
||||
bufferStream << "POST ";
|
||||
} else {
|
||||
LOG_TRACE(L"unsupported request method code (%d), pretending we've failed to connect", request->method);
|
||||
|
||||
return Err::HTTP_FAILURE;
|
||||
}
|
||||
bufferStream << request->path;
|
||||
if (request->httpVer == 1)
|
||||
bufferStream << "HTTP/1.0";
|
||||
else
|
||||
bufferStream << "HTTP/1.1";
|
||||
bufferStream << "\r\n";
|
||||
if (request->httpVer != 1 /* means HTTP 1.1 */) {
|
||||
bufferStream << "Host: " << request->serverName << "\r\n";
|
||||
bufferStream << "User-Agent: " << request->userAgent << "\r\n";
|
||||
bufferStream << "Accept: */*\r\n";
|
||||
bufferStream << "Connection: " << (request->isEnableKeepalive ? "keep-alive" : "close") << "\r\n";
|
||||
}
|
||||
if (request->postData != nullptr) {
|
||||
bufferStream << "Content-Length: " << request->contentLength << "\r\n\r\n";
|
||||
for (size_t i = 0; i < request->size; i++) {
|
||||
bufferStream << ((char*)request->postData)[i];
|
||||
}
|
||||
}
|
||||
boost::asio::write(*connection->socket, buffer);
|
||||
|
||||
boost::asio::streambuf responseBuffer;
|
||||
boost::asio::read_until(*connection->socket, responseBuffer, "\r\n");
|
||||
std::istream responseBufferStream(&responseBuffer);
|
||||
|
||||
std::string httpVersion;
|
||||
int statusCode;
|
||||
std::string statusDescription;
|
||||
responseBufferStream >> httpVersion;
|
||||
responseBufferStream >> statusCode;
|
||||
std::getline(responseBufferStream, statusDescription);
|
||||
|
||||
boost::asio::read_until(*connection->socket, responseBuffer, "\r\n\r\n");
|
||||
|
||||
bool foundContentLengthHeader = false;
|
||||
uint32_t contentLength;
|
||||
std::string header;
|
||||
while (std::getline(responseBufferStream, header) && header != "\r") {
|
||||
if (header.rfind("Content-Length: ", 0) == 0) { // todo: remove case-sensitive check
|
||||
std::string contentLengthUnparsed = header.substr(16);
|
||||
contentLength = std::stoi(contentLengthUnparsed);
|
||||
foundContentLengthHeader = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundContentLengthHeader) {
|
||||
LOG_TRACE(L"failed to find \"Content-Length\" header in the response");
|
||||
|
||||
return Err::HTTP_FAILURE;
|
||||
}
|
||||
bool tooLow;
|
||||
if ((tooLow = contentLength < 1) || contentLength > 1610612736) {
|
||||
LOG_TRACE(L"bad content length: %s", (tooLow ? "less than 1 byte" : "more than 1.5 GiB"));
|
||||
|
||||
return Err::HTTP_FAILURE;
|
||||
}
|
||||
size_t currentIdx = 0;
|
||||
char* body;
|
||||
try {
|
||||
body = new char[contentLength];
|
||||
} catch (std::bad_alloc&) {
|
||||
LOG_TRACE(L"failed to allocate %d bytes", contentLength);
|
||||
|
||||
return Err::HTTP_FAILURE;
|
||||
}
|
||||
response->statusCode = statusCode;
|
||||
response->contentLength = contentLength;
|
||||
response->body = body;
|
||||
|
||||
boost::system::error_code error;
|
||||
while (boost::asio::read(*connection->socket, responseBuffer, boost::asio::transfer_at_least(1), error)) {
|
||||
std::streamsize available = responseBuffer.in_avail();
|
||||
char c;
|
||||
for (std::streamsize i = 0; i < available; i++) {
|
||||
responseBufferStream >> c;
|
||||
body[currentIdx++] = c;
|
||||
}
|
||||
}
|
||||
if (error != boost::asio::error::eof) throw boost::system::system_error(error);
|
||||
|
||||
return Ok;
|
||||
} catch (const boost::exception& e) {
|
||||
LOG_TRACE(L"caught a boost exception while performing an http request");
|
||||
|
||||
return Err::HTTP_FAILURE;
|
||||
} catch (const std::exception& e) {
|
||||
LOG_TRACE(L"caught an std::exception while performing an http request");
|
||||
|
||||
return Err::HTTP_FAILURE;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
int OnlineNet::httpInit(int libnetMemId, int libsslCtxId, size_t poolSize) {
|
||||
auto const handle = g_client.lookupAvailableIdx(new HttpClient(libnetMemId, libsslCtxId, poolSize));
|
||||
if (handle == 0) return Err::HTTP_OUT_OF_MEMORY;
|
||||
|
||||
LOG_USE_MODULE(OnlineNetCore_http);
|
||||
LOG_TRACE(L"new http client (id: %d, memId: %d, sslCtxId: %d, poolSize: %d)", handle, libnetMemId, libsslCtxId, poolSize);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
int OnlineNet::httpTerm(int libhttpCtxId) {
|
||||
if (auto ret = g_client.testId(libhttpCtxId)) return ret;
|
||||
|
||||
g_client.remove(libhttpCtxId);
|
||||
|
||||
LOG_USE_MODULE(OnlineNetCore_http);
|
||||
LOG_TRACE(L"http client removed (id: %d)", libhttpCtxId);
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpGetMemoryPoolStats(int libhttpCtxId, SceHttpMemoryPoolStats* currentStat) {
|
||||
if (auto ret = g_client.testId(libhttpCtxId)) return ret;
|
||||
|
||||
currentStat->currentInuseSize = 16384; // todo (?)
|
||||
currentStat->maxInuseSize = 131072;
|
||||
currentStat->poolSize = g_client.getId(libhttpCtxId)->poolSize;
|
||||
|
||||
LOG_USE_MODULE(OnlineNetCore_http);
|
||||
LOG_TRACE(L"memory pool stats were requested (client id: %d)", libhttpCtxId);
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpCreateTemplate(int libhttpCtxId, const char* userAgent, int httpVer, int isAutoProxyConf) {
|
||||
if (auto ret = g_client.testId(libhttpCtxId)) return ret;
|
||||
|
||||
HttpClient* client = g_client.getId(libhttpCtxId);
|
||||
|
||||
auto const handle = g_template.lookupAvailableIdx(new HttpTemplate(client, userAgent, httpVer, isAutoProxyConf));
|
||||
if (handle == 0) return Err::HTTP_OUT_OF_MEMORY;
|
||||
|
||||
LOG_USE_MODULE(OnlineNetCore_http);
|
||||
LOG_TRACE(L"new http template (id: %d, client id: %d)", handle, libhttpCtxId);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
int OnlineNet::httpDeleteTemplate(int tmplId) {
|
||||
if (auto ret = g_template.testId(tmplId)) return ret;
|
||||
|
||||
g_template.remove(tmplId);
|
||||
|
||||
LOG_USE_MODULE(OnlineNetCore_http);
|
||||
LOG_TRACE(L"http template removed (id: %d)", tmplId);
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
static int sceHttpCreateConnection(int tmplId, const char* serverName, const char* scheme, uint16_t port, int isEnableKeepalive, bool shouldFreeStrings) {
|
||||
if (auto ret = g_template.testId(tmplId)) return ret;
|
||||
|
||||
HttpTemplate* httpTemplate = g_template.getId(tmplId);
|
||||
auto const handle = g_connection.lookupAvailableIdx(new HttpConnection(httpTemplate, serverName, scheme, port, isEnableKeepalive, shouldFreeStrings));
|
||||
|
||||
LOG_USE_MODULE(OnlineNetCore_http);
|
||||
LOG_TRACE(L"new http connection (id: %d, template id: %d)", handle, tmplId);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
int OnlineNet::httpCreateConnection(int tmplId, const char* serverName, const char* scheme, uint16_t port, int isEnableKeepalive) {
|
||||
return sceHttpCreateConnection(tmplId, serverName, scheme, port, isEnableKeepalive, false);
|
||||
}
|
||||
|
||||
int OnlineNet::httpCreateConnectionWithURL(int tmplId, const char* url, int isEnableKeepalive) {
|
||||
boost::urls::url link(url);
|
||||
uint16_t port;
|
||||
|
||||
bool isNotHttp;
|
||||
if ((isNotHttp = std::strcmp(link.scheme().data(), "http") != 0) && std::strcmp(link.scheme().data(), "https") != 0) {
|
||||
|
||||
return Err::HTTP_BAD_SCHEME;
|
||||
}
|
||||
if (link.has_port()) {
|
||||
port = link.port_number();
|
||||
} else {
|
||||
if (isNotHttp)
|
||||
port = 443;
|
||||
else
|
||||
port = 80;
|
||||
}
|
||||
|
||||
int result = sceHttpCreateConnection(tmplId, link.host().data(), link.scheme().data(), port, isEnableKeepalive, true);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int OnlineNet::httpDeleteConnection(int connId) {
|
||||
if (auto ret = g_connection.testId(connId)) return ret;
|
||||
|
||||
HttpConnection* connection = g_connection.getId(connId);
|
||||
if (connection->query != nullptr) {
|
||||
delete connection->query;
|
||||
}
|
||||
if (connection->socket != nullptr) {
|
||||
connection->socket->close();
|
||||
|
||||
delete connection->socket;
|
||||
}
|
||||
if (connection->shouldFreeStrings) {
|
||||
delete connection->scheme;
|
||||
delete connection->serverName;
|
||||
}
|
||||
g_connection.remove(connId);
|
||||
|
||||
LOG_USE_MODULE(OnlineNetCore_http);
|
||||
LOG_TRACE(L"http connection removed (id: %d)", connId);
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
static int sceHttpCreateRequest(int connId, int method, const char* path, uint64_t contentLength, bool shouldFreePath) {
|
||||
if (auto ret = g_connection.testId(connId)) return ret;
|
||||
|
||||
HttpConnection* httpConnection = g_connection.getId(connId);
|
||||
|
||||
auto handle = g_request.lookupAvailableIdx(new HttpRequest(httpConnection, method, path, contentLength, shouldFreePath));
|
||||
|
||||
LOG_USE_MODULE(OnlineNetCore_http);
|
||||
LOG_TRACE(L"new http request (id: %d, connection id: %d)", handle, connId);
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpCreateRequest(int connId, int method, const char* path, uint64_t contentLength) {
|
||||
return sceHttpCreateRequest(connId, method, path, contentLength, false);
|
||||
}
|
||||
|
||||
int OnlineNet::httpCreateRequest2(int connId, const char* method, const char* path, uint64_t contentLength) {
|
||||
return httpCreateRequest(connId, httpMethodStringToInt(method), path, contentLength);
|
||||
}
|
||||
|
||||
int OnlineNet::httpCreateRequestWithURL(int connId, int method, const char* url, uint64_t contentLength) {
|
||||
boost::urls::url link(url);
|
||||
if (link.has_password()) {
|
||||
LOG_USE_MODULE(OnlineNetCore_http);
|
||||
LOG_TRACE(L"urls containing credentials are not supported");
|
||||
|
||||
return Err::HTTP_BAD_PARAM;
|
||||
}
|
||||
|
||||
int result = sceHttpCreateRequest(connId, method, link.path().data(), contentLength, true);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int OnlineNet::httpCreateRequestWithURL2(int connId, const char* method, const char* url, uint64_t contentLength) {
|
||||
return httpCreateRequestWithURL(connId, httpMethodStringToInt(method), url, contentLength);
|
||||
}
|
||||
|
||||
int OnlineNet::httpDeleteRequest(int reqId) {
|
||||
if (auto ret = g_request.testId(reqId)) return ret;
|
||||
|
||||
HttpRequest* request = g_request.getId(reqId);
|
||||
if (request->lastResponse != nullptr) {
|
||||
deleteResponse(request->lastResponse);
|
||||
}
|
||||
if (request->shouldFreePath) {
|
||||
delete request->path;
|
||||
}
|
||||
g_request.remove(reqId);
|
||||
|
||||
LOG_USE_MODULE(OnlineNetCore_http);
|
||||
LOG_TRACE(L"http request removed (id: %d)", reqId);
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpSetRequestContentLength(int id, uint64_t contentLength) {
|
||||
int reqId = id; // (?)
|
||||
if (auto ret = g_request.testId(reqId)) return ret;
|
||||
|
||||
g_request.getId(reqId)->contentLength = contentLength;
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpSetChunkedTransferEnabled(int id, int isEnable) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpSetInflateGZIPEnabled(int id, int isEnable) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpSendRequest(int reqId, const void* postData, size_t size) {
|
||||
if (auto ret = g_request.testId(reqId)) return ret;
|
||||
|
||||
HttpRequest* request = g_request.getId(reqId);
|
||||
request->postData = postData;
|
||||
request->size = size;
|
||||
HttpRequestParams* fullParams = new HttpRequestParams(request);
|
||||
HttpResponse* response = new HttpResponse();
|
||||
int32_t result = performHttpRequest(fullParams, response);
|
||||
delete fullParams;
|
||||
if (result == Ok) {
|
||||
request->lastResponse = response;
|
||||
} else {
|
||||
deleteResponse(response);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int OnlineNet::httpAbortRequest(int reqId) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpGetResponseContentLength(int reqId, int* result, uint64_t* contentLength) {
|
||||
if (auto ret = g_request.testId(reqId)) return ret;
|
||||
|
||||
GET_LAST_RESPONSE;
|
||||
*result = 0; // Content-Length is guaranteed to exist, otherwise performHttpRequest would have failed
|
||||
*contentLength = response->contentLength;
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpGetStatusCode(int reqId, int* statusCode) {
|
||||
if (auto ret = g_request.testId(reqId)) return ret;
|
||||
|
||||
GET_LAST_RESPONSE;
|
||||
*statusCode = response->statusCode;
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpGetAllResponseHeaders(int reqId, char** header, size_t* headerSize) {
|
||||
*headerSize = 0;
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpReadData(int reqId, void* data, size_t size) {
|
||||
if (auto ret = g_request.testId(reqId)) return ret;
|
||||
|
||||
GET_LAST_RESPONSE;
|
||||
size_t finalSize = min(size, response->contentLength);
|
||||
memcpy(data, response->body, finalSize);
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpAddRequestHeader(int id, const char* name, const char* value, uint32_t mode) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpRemoveRequestHeader(int id, const char* name) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpParseResponseHeader(const char* header, size_t headerLen, const char* fieldStr, const char** fieldValue, size_t* valueLen) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpParseStatusLine(const char* statusLine, size_t lineLen, int* httpMajorVer, int* httpMinorVer, int* responseCode, const char** reasonPhrase,
|
||||
size_t* phraseLen) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpSetResponseHeaderMaxSize(int id, size_t headerSize) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpSetAuthInfoCallback(int id, SceHttpAuthInfoCallback cbfunc, void* userArg) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpSetAuthEnabled(int id, int isEnable) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpGetAuthEnabled(int id, int* isEnable) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpAuthCacheFlush(int libhttpCtxId) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpSetRedirectCallback(int id, SceHttpRedirectCallback cbfunc, void* userArg) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpSetAutoRedirect(int id, int isEnable) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpGetAutoRedirect(int id, int* isEnable) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpRedirectCacheFlush(int libhttpCtxId) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpSetResolveTimeOut(int id, uint32_t usec) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpSetResolveRetry(int id, int retry) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpSetConnectTimeOut(int id, uint32_t usec) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpSetSendTimeOut(int id, uint32_t usec) {
|
||||
return Err::SEND_TIMEOUT;
|
||||
}
|
||||
|
||||
int OnlineNet::httpSetRecvTimeOut(int id, uint32_t usec) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpSetRequestStatusCallback(int id, SceHttpRequestStatusCallback cbfunc, void* userArg) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpGetLastErrno(int reqId, int* errNum) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpSetNonblock(int id, int isEnable) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpGetNonblock(int id, int* isEnable) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpTrySetNonblock(int id, int isEnable) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpTryGetNonblock(int id, int* isEnable) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpCreateEpoll(int libhttpCtxId, SceHttpEpollHandle* eh) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpSetEpoll(int id, SceHttpEpollHandle eh, void* userArg) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpUnsetEpoll(int id) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpGetEpoll(int id, SceHttpEpollHandle* eh, void** userArg) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpDestroyEpoll(int libhttpCtxId, SceHttpEpollHandle eh) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpWaitRequest(SceHttpEpollHandle eh, SceHttpNBEvent* nbev, int maxevents, int timeout) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpAbortWaitRequest(SceHttpEpollHandle eh) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
// HTTPS
|
||||
int OnlineNet::httpsLoadCert(int libhttpCtxId, int caCertNum, const SceSslData** caList, const SceSslData* cert, const SceSslData* privKey) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpsUnloadCert(int libhttpCtxId) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpsEnableOption(int id, uint32_t sslFlags) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpsDisableOption(int id, uint32_t sslFlags) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpsGetSslError(int id, int* errNum, uint32_t* detail) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpsSetSslCallback(int id, SceHttpsCallback cbfunc, void* userArg) {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int OnlineNet::httpsSetSslVersion(int id, SceSslVersion version) {
|
||||
return Ok;
|
||||
}
|
@ -5,8 +5,7 @@ set(libName libSceHttp)
|
||||
project(${libName})
|
||||
|
||||
add_library(${libName} SHARED entry.cpp)
|
||||
add_dependencies(${libName} third_party)
|
||||
target_link_libraries(${libName} PUBLIC libboost_url)
|
||||
target_compile_definitions(${libName} PRIVATE BOOST_ALL_NO_LIB)
|
||||
add_dependencies(${libName} core)
|
||||
target_link_libraries(${libName} PUBLIC core.lib)
|
||||
|
||||
setupModule(${libName})
|
||||
setupModule(${libName})
|
||||
|
@ -1,728 +1,253 @@
|
||||
#include "../libSceSsl/types.h"
|
||||
#include "common.h"
|
||||
#include "core/networking/networking.h"
|
||||
#include "httpsTypes.h"
|
||||
#include "logging.h"
|
||||
#include "types.h"
|
||||
#include "utility/utility.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include <Windows.h>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/url.hpp>
|
||||
|
||||
using namespace boost::asio;
|
||||
|
||||
LOG_DEFINE_MODULE(libSceHttp);
|
||||
|
||||
namespace {
|
||||
using SceHttpsCallback = SYSV_ABI int (*)(int libsslCtxId, unsigned int verifyErr, SceSslCert* const sslCert[], int certNum, void* userArg);
|
||||
|
||||
constexpr size_t ARRAY_LENGTH = 128;
|
||||
|
||||
template <typename T, size_t size>
|
||||
class HttpContainer {
|
||||
T* m_data[size] = {nullptr};
|
||||
|
||||
public:
|
||||
int lookupAvailableIdx(T* action) {
|
||||
int i;
|
||||
bool found = false;
|
||||
for (i = 1; i < size; i++) {
|
||||
if (!m_data[i]) {
|
||||
m_data[i] = action;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found == false) {
|
||||
delete action;
|
||||
return 0;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
int testId(int id) {
|
||||
if (id < 1 || id >= size || m_data[id] == nullptr) return Err::HTTP_BAD_ID;
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
void remove(int id) {
|
||||
delete m_data[id];
|
||||
m_data[id] = nullptr;
|
||||
}
|
||||
|
||||
T* getId(int id) { return m_data[id]; }
|
||||
};
|
||||
|
||||
static io_service svc;
|
||||
static ip::tcp::resolver resolver(svc);
|
||||
|
||||
struct HttpClient {
|
||||
int libnetMemId;
|
||||
int libsslCtxId;
|
||||
size_t poolSize;
|
||||
uint32_t connectTimeout;
|
||||
|
||||
HttpClient(int libnetMemId, int libsslCtxId, size_t poolSize): libnetMemId(libnetMemId), libsslCtxId(libsslCtxId), poolSize(poolSize) {}
|
||||
};
|
||||
|
||||
struct HttpTemplate {
|
||||
HttpClient* parentClient;
|
||||
const char* userAgent;
|
||||
int httpVer;
|
||||
int isAutoProxyConf;
|
||||
|
||||
HttpTemplate(HttpClient* parentClient, const char* userAgent, int httpVer, int isAutoProxyConf)
|
||||
: parentClient(parentClient), userAgent(userAgent), httpVer(httpVer), isAutoProxyConf(isAutoProxyConf) {}
|
||||
};
|
||||
|
||||
struct HttpConnection {
|
||||
HttpTemplate* parentTemplate;
|
||||
const char* serverName;
|
||||
const char* scheme;
|
||||
uint16_t port;
|
||||
int isEnableKeepalive;
|
||||
|
||||
bool connected = false;
|
||||
bool shouldFreeStrings;
|
||||
|
||||
ip::tcp::resolver::query* query = nullptr;
|
||||
ip::tcp::resolver::iterator endpoint_iterator;
|
||||
ip::tcp::socket* socket = nullptr;
|
||||
|
||||
HttpConnection(HttpTemplate* parentTemplate, const char* serverName, const char* scheme, uint16_t port, int isEnableKeepalive, bool shouldFreeStrings)
|
||||
: parentTemplate(parentTemplate), serverName(serverName), scheme(scheme), port(port), isEnableKeepalive(isEnableKeepalive),
|
||||
shouldFreeStrings(shouldFreeStrings) {}
|
||||
};
|
||||
|
||||
struct HttpResponse {
|
||||
int statusCode;
|
||||
uint32_t contentLength;
|
||||
const char* body = nullptr;
|
||||
};
|
||||
|
||||
struct HttpRequest {
|
||||
HttpConnection* parentConnection;
|
||||
int method;
|
||||
const char* path;
|
||||
uint64_t contentLength;
|
||||
const void* postData = nullptr;
|
||||
size_t size;
|
||||
HttpResponse* lastResponse = nullptr;
|
||||
|
||||
bool shouldFreePath;
|
||||
|
||||
HttpRequest(HttpConnection* parentConnection, int method, const char* path, uint64_t contentLength, bool shouldFreePath)
|
||||
: parentConnection(parentConnection), method(method), path(path), contentLength(contentLength), shouldFreePath(shouldFreePath) {}
|
||||
};
|
||||
|
||||
struct HttpRequestParams {
|
||||
HttpConnection* connection;
|
||||
HttpRequest* request;
|
||||
uint32_t connectTimeout;
|
||||
const char* userAgent;
|
||||
int httpVer;
|
||||
int isAutoProxyConf;
|
||||
const char* serverName;
|
||||
const char* scheme;
|
||||
uint16_t port;
|
||||
int isEnableKeepalive;
|
||||
int method;
|
||||
const char* path;
|
||||
uint64_t contentLength;
|
||||
const void* postData; // will be assigned to nullptr
|
||||
size_t size;
|
||||
|
||||
HttpRequestParams(HttpRequest* from) {
|
||||
connection = from->parentConnection;
|
||||
request = from;
|
||||
connectTimeout = from->parentConnection->parentTemplate->parentClient->connectTimeout;
|
||||
userAgent = from->parentConnection->parentTemplate->userAgent;
|
||||
httpVer = from->parentConnection->parentTemplate->httpVer;
|
||||
isAutoProxyConf = from->parentConnection->parentTemplate->isAutoProxyConf;
|
||||
serverName = from->parentConnection->serverName;
|
||||
scheme = from->parentConnection->scheme;
|
||||
port = from->parentConnection->port;
|
||||
isEnableKeepalive = from->parentConnection->isEnableKeepalive;
|
||||
method = from->method;
|
||||
path = from->path;
|
||||
contentLength = from->contentLength;
|
||||
postData = from->postData;
|
||||
size = from->size;
|
||||
}
|
||||
};
|
||||
|
||||
static HttpContainer<HttpClient, ARRAY_LENGTH> g_client;
|
||||
static HttpContainer<HttpTemplate, ARRAY_LENGTH> g_template;
|
||||
static HttpContainer<HttpConnection, ARRAY_LENGTH> g_connection;
|
||||
static HttpContainer<HttpRequest, ARRAY_LENGTH> g_request;
|
||||
|
||||
#define GET_LAST_RESPONSE \
|
||||
HttpRequest* request = g_request.getId(reqId); \
|
||||
HttpResponse* response = request->lastResponse; \
|
||||
if (response == nullptr) return Err::HTTP_SEND_REQUIRED;
|
||||
|
||||
static void deleteResponse(HttpResponse* response) {
|
||||
if (response->body != nullptr) {
|
||||
delete response->body;
|
||||
}
|
||||
delete response;
|
||||
}
|
||||
|
||||
static int httpMethodStringToInt(const char* method) {
|
||||
if (std::strcmp(method, "get") == 0 || std::strcmp(method, "GET") == 0) {
|
||||
return SCE_HTTP_GET;
|
||||
} else if (std::strcmp(method, "post") == 0 || std::strcmp(method, "POST") == 0) {
|
||||
return SCE_HTTP_POST;
|
||||
}
|
||||
LOG_USE_MODULE(libSceHttp);
|
||||
LOG_TRACE(L"unsupported http method: %s", method);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int32_t performHttpRequest(HttpRequestParams* request, HttpResponse* response) {
|
||||
LOG_USE_MODULE(libSceHttp);
|
||||
|
||||
HttpConnection* connection = request->connection;
|
||||
try {
|
||||
if (!connection->connected) {
|
||||
connection->query = new ip::tcp::resolver::query(request->serverName, std::to_string(request->port));
|
||||
connection->endpoint_iterator = resolver.resolve(*connection->query);
|
||||
connection->socket = new ip::tcp::socket(svc);
|
||||
boost::asio::connect(*connection->socket, connection->endpoint_iterator);
|
||||
connection->connected = true;
|
||||
|
||||
if (std::strcmp(connection->scheme, "https") == 0) {
|
||||
LOG_TRACE(L"detected an attempt to connect via https, it's not supported yet");
|
||||
|
||||
return Err::HTTP_SSL_ERROR;
|
||||
}
|
||||
if (std::strcmp(connection->scheme, "http") != 0) {
|
||||
LOG_TRACE(L"unknown scheme: %s://", connection->scheme);
|
||||
|
||||
return Err::HTTP_BAD_SCHEME;
|
||||
}
|
||||
}
|
||||
if (request->request->lastResponse != nullptr) {
|
||||
deleteResponse(request->request->lastResponse);
|
||||
}
|
||||
boost::asio::streambuf buffer;
|
||||
std::ostream bufferStream(&buffer);
|
||||
|
||||
if (request->method == SCE_HTTP_GET) {
|
||||
bufferStream << "GET ";
|
||||
} else if (request->method == SCE_HTTP_POST) {
|
||||
bufferStream << "POST ";
|
||||
} else {
|
||||
LOG_TRACE(L"unsupported request method code (%d), pretending we've failed to connect", request->method);
|
||||
|
||||
return Err::HTTP_FAILURE;
|
||||
}
|
||||
bufferStream << request->path;
|
||||
if (request->httpVer == 1)
|
||||
bufferStream << "HTTP/1.0";
|
||||
else
|
||||
bufferStream << "HTTP/1.1";
|
||||
bufferStream << "\r\n";
|
||||
if (request->httpVer != 1 /* means HTTP 1.1 */) {
|
||||
bufferStream << "Host: " << request->serverName << "\r\n";
|
||||
bufferStream << "User-Agent: " << request->userAgent << "\r\n";
|
||||
bufferStream << "Accept: */*\r\n";
|
||||
bufferStream << "Connection: " << (request->isEnableKeepalive ? "keep-alive" : "close") << "\r\n";
|
||||
}
|
||||
if (request->postData != nullptr) {
|
||||
bufferStream << "Content-Length: " << request->contentLength << "\r\n\r\n";
|
||||
for (size_t i = 0; i < request->size; i++) {
|
||||
bufferStream << ((char*)request->postData)[i];
|
||||
}
|
||||
}
|
||||
boost::asio::write(*connection->socket, buffer);
|
||||
|
||||
boost::asio::streambuf responseBuffer;
|
||||
boost::asio::read_until(*connection->socket, responseBuffer, "\r\n");
|
||||
std::istream responseBufferStream(&responseBuffer);
|
||||
|
||||
std::string httpVersion;
|
||||
int statusCode;
|
||||
std::string statusDescription;
|
||||
responseBufferStream >> httpVersion;
|
||||
responseBufferStream >> statusCode;
|
||||
std::getline(responseBufferStream, statusDescription);
|
||||
|
||||
boost::asio::read_until(*connection->socket, responseBuffer, "\r\n\r\n");
|
||||
|
||||
bool foundContentLengthHeader = false;
|
||||
uint32_t contentLength;
|
||||
std::string header;
|
||||
while (std::getline(responseBufferStream, header) && header != "\r") {
|
||||
if (header.rfind("Content-Length: ", 0) == 0) { // todo: remove case-sensitive check
|
||||
std::string contentLengthUnparsed = header.substr(16);
|
||||
contentLength = std::stoi(contentLengthUnparsed);
|
||||
foundContentLengthHeader = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundContentLengthHeader) {
|
||||
LOG_TRACE(L"failed to find \"Content-Length\" header in the response");
|
||||
|
||||
return Err::HTTP_FAILURE;
|
||||
}
|
||||
bool tooLow;
|
||||
if ((tooLow = contentLength < 1) || contentLength > 1610612736) {
|
||||
LOG_TRACE(L"bad content length: %s", (tooLow ? "less than 1 byte" : "more than 1.5 GiB"));
|
||||
|
||||
return Err::HTTP_FAILURE;
|
||||
}
|
||||
size_t currentIdx = 0;
|
||||
char* body;
|
||||
try {
|
||||
body = new char[contentLength];
|
||||
} catch (std::bad_alloc&) {
|
||||
LOG_TRACE(L"failed to allocate %d bytes", contentLength);
|
||||
|
||||
return Err::HTTP_FAILURE;
|
||||
}
|
||||
response->statusCode = statusCode;
|
||||
response->contentLength = contentLength;
|
||||
response->body = body;
|
||||
|
||||
boost::system::error_code error;
|
||||
while (boost::asio::read(*connection->socket, responseBuffer, boost::asio::transfer_at_least(1), error)) {
|
||||
std::streamsize available = responseBuffer.in_avail();
|
||||
char c;
|
||||
for (std::streamsize i = 0; i < available; i++) {
|
||||
responseBufferStream >> c;
|
||||
body[currentIdx++] = c;
|
||||
}
|
||||
}
|
||||
if (error != boost::asio::error::eof) throw boost::system::system_error(error);
|
||||
|
||||
return Ok;
|
||||
} catch (const boost::exception& e) {
|
||||
LOG_TRACE(L"caught a boost exception while performing an http request");
|
||||
|
||||
return Err::HTTP_FAILURE;
|
||||
} catch (const std::exception& e) {
|
||||
LOG_TRACE(L"caught an std::exception while performing an http request");
|
||||
|
||||
return Err::HTTP_FAILURE;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
extern "C" {
|
||||
|
||||
EXPORT const char* MODULE_NAME = "libSceHttp";
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpInit(int libnetMemId, int libsslCtxId, size_t poolSize) {
|
||||
auto const handle = g_client.lookupAvailableIdx(new HttpClient(libnetMemId, libsslCtxId, poolSize));
|
||||
if (handle == 0) return Err::HTTP_OUT_OF_MEMORY;
|
||||
|
||||
LOG_USE_MODULE(libSceHttp);
|
||||
LOG_TRACE(L"new http client (id: %d, memId: %d, sslCtxId: %d, poolSize: %d)", handle, libnetMemId, libsslCtxId, poolSize);
|
||||
|
||||
return handle;
|
||||
return accessNetworking().httpInit(libnetMemId, libsslCtxId, poolSize);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpTerm(int libhttpCtxId) {
|
||||
if (auto ret = g_client.testId(libhttpCtxId)) return ret;
|
||||
|
||||
g_client.remove(libhttpCtxId);
|
||||
|
||||
LOG_USE_MODULE(libSceHttp);
|
||||
LOG_TRACE(L"http client removed (id: %d)", libhttpCtxId);
|
||||
|
||||
return Ok;
|
||||
return accessNetworking().httpTerm(libhttpCtxId);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpGetMemoryPoolStats(int libhttpCtxId, SceHttpMemoryPoolStats* currentStat) {
|
||||
if (auto ret = g_client.testId(libhttpCtxId)) return ret;
|
||||
|
||||
currentStat->currentInuseSize = 16384; // todo (?)
|
||||
currentStat->maxInuseSize = 131072;
|
||||
currentStat->poolSize = g_client.getId(libhttpCtxId)->poolSize;
|
||||
|
||||
LOG_USE_MODULE(libSceHttp);
|
||||
LOG_TRACE(L"memory pool stats were requested (client id: %d)", libhttpCtxId);
|
||||
|
||||
return Ok;
|
||||
return accessNetworking().httpGetMemoryPoolStats(libhttpCtxId, currentStat);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpCreateTemplate(int libhttpCtxId, const char* userAgent, int httpVer, int isAutoProxyConf) {
|
||||
if (auto ret = g_client.testId(libhttpCtxId)) return ret;
|
||||
|
||||
HttpClient* client = g_client.getId(libhttpCtxId);
|
||||
|
||||
auto const handle = g_template.lookupAvailableIdx(new HttpTemplate(client, userAgent, httpVer, isAutoProxyConf));
|
||||
if (handle == 0) return Err::HTTP_OUT_OF_MEMORY;
|
||||
|
||||
LOG_USE_MODULE(libSceHttp);
|
||||
LOG_TRACE(L"new http template (id: %d, client id: %d)", handle, libhttpCtxId);
|
||||
|
||||
return handle;
|
||||
return accessNetworking().httpCreateTemplate(libhttpCtxId, userAgent, httpVer, isAutoProxyConf);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpDeleteTemplate(int tmplId) {
|
||||
if (auto ret = g_template.testId(tmplId)) return ret;
|
||||
|
||||
g_template.remove(tmplId);
|
||||
|
||||
LOG_USE_MODULE(libSceHttp);
|
||||
LOG_TRACE(L"http template removed (id: %d)", tmplId);
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
static int sceHttpCreateConnection(int tmplId, const char* serverName, const char* scheme, uint16_t port, int isEnableKeepalive, bool shouldFreeStrings) {
|
||||
if (auto ret = g_template.testId(tmplId)) return ret;
|
||||
|
||||
HttpTemplate* httpTemplate = g_template.getId(tmplId);
|
||||
auto const handle = g_connection.lookupAvailableIdx(new HttpConnection(httpTemplate, serverName, scheme, port, isEnableKeepalive, shouldFreeStrings));
|
||||
|
||||
LOG_USE_MODULE(libSceHttp);
|
||||
LOG_TRACE(L"new http connection (id: %d, template id: %d)", handle, tmplId);
|
||||
|
||||
return handle;
|
||||
return accessNetworking().httpDeleteTemplate(tmplId);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpCreateConnection(int tmplId, const char* serverName, const char* scheme, uint16_t port, int isEnableKeepalive) {
|
||||
return sceHttpCreateConnection(tmplId, serverName, scheme, port, isEnableKeepalive, false);
|
||||
return accessNetworking().httpCreateConnection(tmplId, serverName, scheme, port, isEnableKeepalive);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpCreateConnectionWithURL(int tmplId, const char* url, int isEnableKeepalive) {
|
||||
boost::urls::url link(url);
|
||||
uint16_t port;
|
||||
|
||||
bool isNotHttp;
|
||||
if ((isNotHttp = std::strcmp(link.scheme().data(), "http") != 0) && std::strcmp(link.scheme().data(), "https") != 0) {
|
||||
|
||||
return Err::HTTP_BAD_SCHEME;
|
||||
}
|
||||
if (link.has_port()) {
|
||||
port = link.port_number();
|
||||
} else {
|
||||
if (isNotHttp)
|
||||
port = 443;
|
||||
else
|
||||
port = 80;
|
||||
}
|
||||
|
||||
int result = sceHttpCreateConnection(tmplId, link.host().data(), link.scheme().data(), port, isEnableKeepalive, true);
|
||||
|
||||
return result;
|
||||
return accessNetworking().httpCreateConnectionWithURL(tmplId, url, isEnableKeepalive);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpDeleteConnection(int connId) {
|
||||
if (auto ret = g_connection.testId(connId)) return ret;
|
||||
|
||||
HttpConnection* connection = g_connection.getId(connId);
|
||||
if (connection->query != nullptr) {
|
||||
delete connection->query;
|
||||
}
|
||||
if (connection->socket != nullptr) {
|
||||
connection->socket->close();
|
||||
|
||||
delete connection->socket;
|
||||
}
|
||||
if (connection->shouldFreeStrings) {
|
||||
delete connection->scheme;
|
||||
delete connection->serverName;
|
||||
}
|
||||
g_connection.remove(connId);
|
||||
|
||||
LOG_USE_MODULE(libSceHttp);
|
||||
LOG_TRACE(L"http connection removed (id: %d)", connId);
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
static int sceHttpCreateRequest(int connId, int method, const char* path, uint64_t contentLength, bool shouldFreePath) {
|
||||
if (auto ret = g_connection.testId(connId)) return ret;
|
||||
|
||||
HttpConnection* httpConnection = g_connection.getId(connId);
|
||||
|
||||
auto handle = g_request.lookupAvailableIdx(new HttpRequest(httpConnection, method, path, contentLength, shouldFreePath));
|
||||
|
||||
LOG_USE_MODULE(libSceHttp);
|
||||
LOG_TRACE(L"new http request (id: %d, connection id: %d)", handle, connId);
|
||||
|
||||
return Ok;
|
||||
return accessNetworking().httpDeleteConnection(connId);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpCreateRequest(int connId, int method, const char* path, uint64_t contentLength) {
|
||||
return sceHttpCreateRequest(connId, method, path, contentLength, false);
|
||||
return accessNetworking().httpCreateRequest(connId, method, path, contentLength);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpCreateRequest2(int connId, const char* method, const char* path, uint64_t contentLength) {
|
||||
return sceHttpCreateRequest(connId, httpMethodStringToInt(method), path, contentLength);
|
||||
return accessNetworking().httpCreateRequest2(connId, method, path, contentLength);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpCreateRequestWithURL(int connId, int method, const char* url, uint64_t contentLength) {
|
||||
boost::urls::url link(url);
|
||||
if (link.has_password()) {
|
||||
LOG_USE_MODULE(libSceHttp);
|
||||
LOG_TRACE(L"urls containing credentials are not supported");
|
||||
|
||||
return Err::HTTP_BAD_PARAM;
|
||||
}
|
||||
|
||||
int result = sceHttpCreateRequest(connId, method, link.path().data(), contentLength, true);
|
||||
|
||||
return result;
|
||||
return accessNetworking().httpCreateRequestWithURL(connId, method, url, contentLength);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpCreateRequestWithURL2(int connId, const char* method, const char* url, uint64_t contentLength) {
|
||||
return sceHttpCreateRequestWithURL(connId, httpMethodStringToInt(method), url, contentLength);
|
||||
return accessNetworking().httpCreateRequestWithURL2(connId, method, url, contentLength);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpDeleteRequest(int reqId) {
|
||||
if (auto ret = g_request.testId(reqId)) return ret;
|
||||
|
||||
HttpRequest* request = g_request.getId(reqId);
|
||||
if (request->lastResponse != nullptr) {
|
||||
deleteResponse(request->lastResponse);
|
||||
}
|
||||
if (request->shouldFreePath) {
|
||||
delete request->path;
|
||||
}
|
||||
g_request.remove(reqId);
|
||||
|
||||
LOG_USE_MODULE(libSceHttp);
|
||||
LOG_TRACE(L"http request removed (id: %d)", reqId);
|
||||
|
||||
return Ok;
|
||||
return accessNetworking().httpDeleteRequest(reqId);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpSetRequestContentLength(int id, uint64_t contentLength) {
|
||||
int reqId = id; // (?)
|
||||
if (auto ret = g_request.testId(reqId)) return ret;
|
||||
|
||||
g_request.getId(reqId)->contentLength = contentLength;
|
||||
|
||||
return Ok;
|
||||
return accessNetworking().httpSetRequestContentLength(id, contentLength);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpSetChunkedTransferEnabled(int id, int isEnable) {
|
||||
return Ok;
|
||||
return accessNetworking().httpSetChunkedTransferEnabled(id, isEnable);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpSetInflateGZIPEnabled(int id, int isEnable) {
|
||||
return Ok;
|
||||
return accessNetworking().httpSetInflateGZIPEnabled(id, isEnable);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpSendRequest(int reqId, const void* postData, size_t size) {
|
||||
if (auto ret = g_request.testId(reqId)) return ret;
|
||||
|
||||
HttpRequest* request = g_request.getId(reqId);
|
||||
request->postData = postData;
|
||||
request->size = size;
|
||||
HttpRequestParams* fullParams = new HttpRequestParams(request);
|
||||
HttpResponse* response = new HttpResponse();
|
||||
int32_t result = performHttpRequest(fullParams, response);
|
||||
delete fullParams;
|
||||
if (result == Ok) {
|
||||
request->lastResponse = response;
|
||||
} else {
|
||||
deleteResponse(response);
|
||||
}
|
||||
|
||||
return result;
|
||||
return accessNetworking().httpSendRequest(reqId, postData, size);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpAbortRequest(int reqId) {
|
||||
return Ok;
|
||||
return accessNetworking().httpAbortRequest(reqId);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpGetResponseContentLength(int reqId, int* result, uint64_t* contentLength) {
|
||||
if (auto ret = g_request.testId(reqId)) return ret;
|
||||
|
||||
GET_LAST_RESPONSE;
|
||||
*result = 0; // Content-Length is guaranteed to exist, otherwise performHttpRequest would have failed
|
||||
*contentLength = response->contentLength;
|
||||
|
||||
return Ok;
|
||||
return accessNetworking().httpGetResponseContentLength(reqId, result, contentLength);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpGetStatusCode(int reqId, int* statusCode) {
|
||||
if (auto ret = g_request.testId(reqId)) return ret;
|
||||
|
||||
GET_LAST_RESPONSE;
|
||||
*statusCode = response->statusCode;
|
||||
|
||||
return Ok;
|
||||
return accessNetworking().httpGetStatusCode(reqId, statusCode);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpGetAllResponseHeaders(int reqId, char** header, size_t* headerSize) {
|
||||
*headerSize = 0;
|
||||
|
||||
return Ok;
|
||||
return accessNetworking().httpGetAllResponseHeaders(reqId, header, headerSize);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpReadData(int reqId, void* data, size_t size) {
|
||||
if (auto ret = g_request.testId(reqId)) return ret;
|
||||
|
||||
GET_LAST_RESPONSE;
|
||||
size_t finalSize = min(size, response->contentLength);
|
||||
memcpy(data, response->body, finalSize);
|
||||
|
||||
return Ok;
|
||||
return accessNetworking().httpReadData(reqId, data, size);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpAddRequestHeader(int id, const char* name, const char* value, uint32_t mode) {
|
||||
return Ok;
|
||||
return accessNetworking().httpAddRequestHeader(id, name, value, mode);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpRemoveRequestHeader(int id, const char* name) {
|
||||
return Ok;
|
||||
return accessNetworking().httpRemoveRequestHeader(id, name);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpParseResponseHeader(const char* header, size_t headerLen, const char* fieldStr, const char** fieldValue, size_t* valueLen) {
|
||||
return Ok;
|
||||
return accessNetworking().httpParseResponseHeader(header, headerLen, fieldStr, fieldValue, valueLen);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpParseStatusLine(const char* statusLine, size_t lineLen, int* httpMajorVer, int* httpMinorVer, int* responseCode,
|
||||
const char** reasonPhrase, size_t* phraseLen) {
|
||||
return Ok;
|
||||
return accessNetworking().httpParseStatusLine(statusLine, lineLen, httpMajorVer, httpMinorVer, responseCode, reasonPhrase, phraseLen);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpSetResponseHeaderMaxSize(int id, size_t headerSize) {
|
||||
return Ok;
|
||||
return accessNetworking().httpSetResponseHeaderMaxSize(id, headerSize);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpSetAuthInfoCallback(int id, SceHttpAuthInfoCallback cbfunc, void* userArg) {
|
||||
return Ok;
|
||||
return accessNetworking().httpSetAuthInfoCallback(id, cbfunc, userArg);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpSetAuthEnabled(int id, int isEnable) {
|
||||
return Ok;
|
||||
return accessNetworking().httpSetAuthEnabled(id, isEnable);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpGetAuthEnabled(int id, int* isEnable) {
|
||||
return Ok;
|
||||
return accessNetworking().httpGetAuthEnabled(id, isEnable);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpAuthCacheFlush(int libhttpCtxId) {
|
||||
return Ok;
|
||||
return accessNetworking().httpAuthCacheFlush(libhttpCtxId);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpSetRedirectCallback(int id, SceHttpRedirectCallback cbfunc, void* userArg) {
|
||||
return Ok;
|
||||
return accessNetworking().httpSetRedirectCallback(id, cbfunc, userArg);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpSetAutoRedirect(int id, int isEnable) {
|
||||
return Ok;
|
||||
return accessNetworking().httpSetAutoRedirect(id, isEnable);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpGetAutoRedirect(int id, int* isEnable) {
|
||||
return Ok;
|
||||
return accessNetworking().httpGetAutoRedirect(id, isEnable);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpRedirectCacheFlush(int libhttpCtxId) {
|
||||
return Ok;
|
||||
return accessNetworking().httpRedirectCacheFlush(libhttpCtxId);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpSetResolveTimeOut(int id, uint32_t usec) {
|
||||
return Ok;
|
||||
return accessNetworking().httpSetResolveTimeOut(id, usec);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpSetResolveRetry(int id, int retry) {
|
||||
return Ok;
|
||||
return accessNetworking().httpSetResolveRetry(id, retry);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpSetConnectTimeOut(int id, uint32_t usec) {
|
||||
return Ok;
|
||||
return accessNetworking().httpSetConnectTimeOut(id, usec);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpSetSendTimeOut(int id, uint32_t usec) {
|
||||
return Err::SEND_TIMEOUT;
|
||||
return accessNetworking().httpSetSendTimeOut(id, usec);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpSetRecvTimeOut(int id, uint32_t usec) {
|
||||
return Ok;
|
||||
return accessNetworking().httpSetRecvTimeOut(id, usec);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpSetRequestStatusCallback(int id, SceHttpRequestStatusCallback cbfunc, void* userArg) {
|
||||
return Ok;
|
||||
return accessNetworking().httpSetRequestStatusCallback(id, cbfunc, userArg);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpGetLastErrno(int reqId, int* errNum) {
|
||||
return Ok;
|
||||
return accessNetworking().httpGetLastErrno(reqId, errNum);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpSetNonblock(int id, int isEnable) {
|
||||
return Ok;
|
||||
return accessNetworking().httpSetNonblock(id, isEnable);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpGetNonblock(int id, int* isEnable) {
|
||||
return Ok;
|
||||
return accessNetworking().httpGetNonblock(id, isEnable);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpTrySetNonblock(int id, int isEnable) {
|
||||
return Ok;
|
||||
return accessNetworking().httpTrySetNonblock(id, isEnable);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpTryGetNonblock(int id, int* isEnable) {
|
||||
return Ok;
|
||||
return accessNetworking().httpTryGetNonblock(id, isEnable);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpCreateEpoll(int libhttpCtxId, SceHttpEpollHandle* eh) {
|
||||
return Ok;
|
||||
return accessNetworking().httpCreateEpoll(libhttpCtxId, eh);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpSetEpoll(int id, SceHttpEpollHandle eh, void* userArg) {
|
||||
return Ok;
|
||||
return accessNetworking().httpSetEpoll(id, eh, userArg);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpUnsetEpoll(int id) {
|
||||
return Ok;
|
||||
return accessNetworking().httpUnsetEpoll(id);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpGetEpoll(int id, SceHttpEpollHandle* eh, void** userArg) {
|
||||
return Ok;
|
||||
return accessNetworking().httpGetEpoll(id, eh, userArg);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpDestroyEpoll(int libhttpCtxId, SceHttpEpollHandle eh) {
|
||||
return Ok;
|
||||
return accessNetworking().httpDestroyEpoll(libhttpCtxId, eh);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpWaitRequest(SceHttpEpollHandle eh, SceHttpNBEvent* nbev, int maxevents, int timeout) {
|
||||
return Ok;
|
||||
return accessNetworking().httpWaitRequest(eh, nbev, maxevents, timeout);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpAbortWaitRequest(SceHttpEpollHandle eh) {
|
||||
return Ok;
|
||||
return accessNetworking().httpAbortWaitRequest(eh);
|
||||
}
|
||||
|
||||
// HTTPS
|
||||
EXPORT SYSV_ABI int sceHttpsLoadCert(int libhttpCtxId, int caCertNum, const SceSslData** caList, const SceSslData* cert, const SceSslData* privKey) {
|
||||
return Ok;
|
||||
return accessNetworking().httpsLoadCert(libhttpCtxId, caCertNum, caList, cert, privKey);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpsUnloadCert(int libhttpCtxId) {
|
||||
return Ok;
|
||||
return accessNetworking().httpsUnloadCert(libhttpCtxId);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpsEnableOption(int id, uint32_t sslFlags) {
|
||||
return Ok;
|
||||
return accessNetworking().httpsEnableOption(id, sslFlags);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpsDisableOption(int id, uint32_t sslFlags) {
|
||||
return Ok;
|
||||
return accessNetworking().httpsDisableOption(id, sslFlags);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpsGetSslError(int id, int* errNum, uint32_t* detail) {
|
||||
return Ok;
|
||||
return accessNetworking().httpsGetSslError(id, errNum, detail);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpsSetSslCallback(int id, SceHttpsCallback cbfunc, void* userArg) {
|
||||
return Ok;
|
||||
return accessNetworking().httpsSetSslCallback(id, cbfunc, userArg);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceHttpsSetSslVersion(int id, SceSslVersion version) {
|
||||
return Ok;
|
||||
return accessNetworking().httpsSetSslVersion(id, version);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../libSceSsl/types.h"
|
||||
|
||||
enum class SceHttpsFlags : unsigned int {
|
||||
SERVER_VERIFY = 0x01U, // Server Certificate Verify
|
||||
CLIENT_VERIFY = 0x02U, // Client Certificate Verify
|
||||
@ -12,4 +14,6 @@ enum class SceHttpsFlags : unsigned int {
|
||||
|
||||
};
|
||||
|
||||
enum class SceHttpSslVersion { SSLV23, SSLV2, SSLV3, TLSV1 };
|
||||
enum class SceHttpSslVersion { SSLV23, SSLV2, SSLV3, TLSV1 };
|
||||
|
||||
using SceHttpsCallback = SYSV_ABI int (*)(int libsslCtxId, unsigned int verifyErr, SceSslCert* const sslCert[], int certNum, void* userArg);
|
||||
|
@ -57,4 +57,4 @@ struct SceHttpNBEvent {
|
||||
uint32_t eventDetail;
|
||||
int id;
|
||||
void* userArg;
|
||||
};
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user