diff --git a/rpcs3/Emu/Cell/Modules/cellHttp.cpp b/rpcs3/Emu/Cell/Modules/cellHttp.cpp index 781d622f31..3e0b9137f8 100644 --- a/rpcs3/Emu/Cell/Modules/cellHttp.cpp +++ b/rpcs3/Emu/Cell/Modules/cellHttp.cpp @@ -1,7 +1,10 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" +#include "Emu/IdManager.h" +#include "cellHttpUtil.h" #include "cellHttp.h" +#include "cellSsl.h" LOG_CHANNEL(cellHttp); @@ -1088,723 +1091,2692 @@ void fmt_class_string::format(std::string& out, u64 arg) }); } -error_code cellHttpAuthCacheExport() +error_code cellHttpAuthCacheExport(vm::ptr buf, u32 len, vm::ptr outsize) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpAuthCacheExport(buf=*0x%x, len=%d, outsize=*0x%x)", buf, len, outsize); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (!buf) + { + if (!outsize) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + } + else + { + if (len < 9) + { + return CELL_HTTP_ERROR_INSUFFICIENT; + } + + // TODO + } + + u32 size = 0; + + // TODO + + if (outsize) + { + *outsize = 0; + } + return CELL_OK; } error_code cellHttpAuthCacheFlush() { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpAuthCacheFlush()"); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + return CELL_OK; } -error_code cellHttpAuthCacheGetEntryMax() +error_code cellHttpAuthCacheGetEntryMax(u32 unk_ptr) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpAuthCacheGetEntryMax(unk_ptr=*0x%x)", unk_ptr); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (!unk_ptr) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + return CELL_OK; } -error_code cellHttpAuthCacheImport() +error_code cellHttpAuthCacheImport(vm::ptr unk1, u32 unk2) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpAuthCacheImport(unk1=*0x%x, unk2=0x%x)", unk1, unk2); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (!unk1 || !unk2) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + + if (unk2 < 9) + { + return CELL_HTTP_ERROR_INSUFFICIENT; + } + + if (unk1[0] != '\x01') + { + return CELL_HTTP_ERROR_INVALID_DATA; + } + return CELL_OK; } -error_code cellHttpAuthCacheSetEntryMax() +error_code cellHttpAuthCacheSetEntryMax(u32 unk) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpAuthCacheSetEntryMax(unk=0x%x)", unk); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + return CELL_OK; } -error_code cellHttpInit() +error_code cellHttpInit(vm::ptr pool, u32 poolSize) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.notice("cellHttpInit(pool=*0x%x, poolSize=0x%x)", pool, poolSize); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (man.initialized) + { + return CELL_HTTP_ERROR_ALREADY_INITIALIZED; + } + + if (!pool || !poolSize) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + + man.initialized = true; return CELL_OK; } error_code cellHttpEnd() { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.notice("cellHttpEnd()"); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + man.initialized = false; return CELL_OK; } -error_code cellHttpsInit() +error_code cellHttpsInit(u32 caCertNum, vm::cptr caList) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpsInit(caCertNum=0x%x, caList=*0x%x)", caCertNum, caList); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (man.https_initialized) + { + return CELL_HTTP_ERROR_ALREADY_INITIALIZED; + } + + man.https_initialized = true; return CELL_OK; } error_code cellHttpsEnd() { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpsEnd()"); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.https_initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (!_cellSslIsInitd()) + { + return CELL_SSL_ERROR_NOT_INITIALIZED; + } + + man.https_initialized = false; + return CELL_OK; } -error_code cellHttpSetProxy() +error_code cellHttpSetProxy(vm::cptr proxy) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpSetProxy(proxy=*0x%x)", proxy); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (proxy) + { + if (!proxy->hostname || !proxy->hostname[0]) + { + return CELL_HTTP_ERROR_INVALID_URI; + } + } + return CELL_OK; } -error_code cellHttpGetCookie() +error_code cellHttpGetCookie(vm::ptr buf) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpGetCookie(buf=*0x%x)", buf); + + if (!buf) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_COOKIE_NOT_FOUND; + } + return CELL_OK; } -error_code cellHttpGetProxy() +error_code cellHttpGetProxy(vm::ptr proxy, vm::ptr pool, u32 poolSize, vm::ptr required) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpGetProxy(proxy=*0x%x, pool=*0x%x, poolSize=0x%x, required=*0x%x)", proxy, pool, poolSize, required); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + //if (todo) + //{ + // return cellHttpUtilCopyUri(proxy, some CellHttpUri, pool, poolSize, required); + //} + + if (required) + { + *required = 0; + } + return CELL_OK; } -error_code cellHttpInitCookie() +error_code cellHttpInitCookie(vm::ptr pool, u32 poolSize) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpInitCookie(pool=*0x%x, poolSize=0x%x)", pool, poolSize); + + if (!pool || !poolSize) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (man.cookie_initialized) + { + return CELL_HTTP_ERROR_ALREADY_INITIALIZED; + } + + man.cookie_initialized = true; return CELL_OK; } error_code cellHttpEndCookie() { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpEndCookie()"); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.cookie_initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + man.cookie_initialized = false; return CELL_OK; } -error_code cellHttpAddCookieWithClientId() +error_code cellHttpAddCookieWithClientId(vm::cptr uri, vm::cptr cookie, CellHttpClientId clientId) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpAddCookieWithClientId(uri=*0x%x, cookie=%s, clientId=0x%x)", uri, cookie, clientId); + + if (!uri) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + + if (!cookie || !uri->hostname || !uri->path) + { + return CELL_HTTP_ERROR_NO_STRING; + } + return CELL_OK; } -error_code cellHttpSessionCookieFlush() +error_code cellHttpSessionCookieFlush(CellHttpClientId clientId) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpSessionCookieFlush(clientId=0x%x)", clientId); return CELL_OK; } -error_code cellHttpCookieExport() +error_code cellHttpCookieExport(vm::ptr buffer, u32 size, vm::ptr exportSize) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpCookieExport(buffer=*0x%x, size=0x%x, exportSize=*0x%x)", buffer, size, exportSize); + + if (buffer && size < 0x14) + { + return CELL_HTTP_ERROR_INSUFFICIENT; + } + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.cookie_initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + return CELL_OK; } -error_code cellHttpCookieExportWithClientId() +error_code cellHttpCookieExportWithClientId(vm::ptr buffer, u32 size, vm::ptr exportSize, CellHttpClientId clientId) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpCookieExportWithClientId(buffer=*0x%x, size=0x%x, exportSize=*0x%x, clientId=0x%x)", buffer, size, exportSize, clientId); + + if (buffer && size < 0x14) + { + return CELL_HTTP_ERROR_INSUFFICIENT; + } + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.cookie_initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + return CELL_OK; } error_code cellHttpCookieFlush() { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpCookieFlush()"); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.cookie_initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + return CELL_OK; } -error_code cellHttpCookieImport() +error_code cellHttpCookieImport(vm::cptr buffer, u32 size) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpCookieImport(buffer=*0x%x, size=0x%x)", buffer, size); + + if (error_code error = cellHttpCookieFlush()) + { + cellHttp.error("cellHttpCookieImport: cellHttpCookieFlush returned 0x%x", +error); + // No return + } + return CELL_OK; } -error_code cellHttpCookieImportWithClientId() +error_code cellHttpCookieImportWithClientId(vm::cptr buffer, u32 size, CellHttpClientId clientId) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpCookieImportWithClientId(buffer=*0x%x, size=0x%x, clientId=0x%x)", buffer, size, clientId); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.cookie_initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + return CELL_OK; } -error_code cellHttpClientSetCookieSendCallback() +error_code cellHttpClientSetCookieSendCallback(CellHttpClientId clientId, vm::ptr cbfunc, vm::ptr userArg) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientSetCookieSendCallback(clientId=0x%x, cbfunc=*0x%x, userArg=*0x%x)", clientId, cbfunc, userArg); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + return CELL_OK; } -error_code cellHttpClientSetCookieRecvCallback() +error_code cellHttpClientSetCookieRecvCallback(CellHttpClientId clientId, vm::ptr cbfunc, vm::ptr userArg) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientSetCookieRecvCallback(clientId=0x%x, cbfunc=*0x%x, userArg=*0x%x)", clientId, cbfunc, userArg); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + return CELL_OK; } -error_code cellHttpCreateClient() +error_code cellHttpCreateClient(vm::ptr clientId) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpCreateClient(clientId=*0x%x)", clientId); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (!clientId) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + return CELL_OK; } -error_code cellHttpDestroyClient() +error_code cellHttpDestroyClient(CellHttpClientId clientId) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpDestroyClient(clientId=0x%x)", clientId); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + return CELL_OK; } -error_code cellHttpClientSetAuthenticationCallback() +error_code cellHttpClientSetAuthenticationCallback(CellHttpClientId clientId, vm::ptr cbfunc, vm::ptr userArg) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientSetAuthenticationCallback(clientId=0x%x, cbfunc=*0x%x, userArg=*0x%x)", clientId, cbfunc, userArg); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + return CELL_OK; } -error_code cellHttpClientSetTransactionStateCallback() +error_code cellHttpClientSetCacheStatus(CellHttpClientId clientId, b8 enable) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientSetCacheStatus(clientId=0x%x, enable=%d)", clientId, enable); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + return CELL_OK; } -error_code cellHttpClientSetRedirectCallback() +error_code cellHttpClientSetTransactionStateCallback(CellHttpClientId clientId, vm::ptr cbfunc, vm::ptr userArg) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientSetTransactionStateCallback(clientId=0x%x, cbfunc=*0x%x, userArg=*0x%x)", clientId, cbfunc, userArg); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + return CELL_OK; } -error_code cellHttpClientSetProxy() +error_code cellHttpClientSetRedirectCallback(CellHttpClientId clientId, vm::ptr cbfunc, vm::ptr userArg) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientSetRedirectCallback(clientId=0x%x, cbfunc=*0x%x, userArg=*0x%x)", clientId, cbfunc, userArg); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + return CELL_OK; } -error_code cellHttpClientGetProxy() +error_code cellHttpClientSetProxy(CellHttpClientId clientId, vm::cptr proxy) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientSetProxy(clientId=0x%x, proxy=*0x%x)", clientId, proxy); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + + if (proxy) + { + if (!proxy->hostname || !proxy->hostname[0]) + { + return CELL_HTTP_ERROR_INVALID_URI; + } + } + return CELL_OK; } -error_code cellHttpClientSetVersion() +error_code cellHttpClientGetProxy(CellHttpClientId clientId, vm::ptr proxy, vm::ptr pool, u32 poolSize, vm::ptr required) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientGetProxy(clientId=0x%x, proxy=*0x%x, pool=*0x%x, poolSize=0x%x, required=*0x%x)", clientId, proxy, pool, poolSize, required); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + return CELL_OK; } -error_code cellHttpClientGetVersion() +error_code cellHttpClientSetVersion(CellHttpClientId clientId, u32 major, u32 minor) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientSetPipeline(clientId=0x%x, major=0x%x, minor=0x%x)", clientId, major, minor); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + return CELL_OK; } -error_code cellHttpClientSetPipeline() +error_code cellHttpClientGetVersion(CellHttpClientId clientId, vm::ptr major, vm::ptr minor) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientGetVersion(clientId=0x%x, major=*0x%x, minor=*0x%x)", clientId, major, minor); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + + if (!major || !minor) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + return CELL_OK; } -error_code cellHttpClientGetPipeline() +error_code cellHttpClientSetPipeline(CellHttpClientId clientId, b8 enable) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientSetPipeline(clientId=0x%x, enable=%d)", clientId, enable); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + return CELL_OK; } -error_code cellHttpClientSetKeepAlive() +error_code cellHttpClientGetPipeline(CellHttpClientId clientId, vm::ptr enable) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientGetPipeline(clientId=0x%x, enable=*0x%x)", clientId, enable); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + + if (!enable) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + return CELL_OK; } -error_code cellHttpClientGetKeepAlive() +error_code cellHttpClientSetKeepAlive(CellHttpClientId clientId, b8 enable) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientSetKeepAlive(clientId=0x%x, enable=%d)", clientId, enable); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + return CELL_OK; } -error_code cellHttpClientSetAutoRedirect() +error_code cellHttpClientGetKeepAlive(CellHttpClientId clientId, vm::ptr enable) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientGetKeepAlive(clientId=0x%x, enable=*0x%x)", clientId, enable); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + + if (!enable) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + return CELL_OK; } -error_code cellHttpClientGetAutoRedirect() +error_code cellHttpClientSetAutoRedirect(CellHttpClientId clientId, b8 enable) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientSetAutoRedirect(clientId=0x%x, enable=%d)", clientId, enable); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + return CELL_OK; } -error_code cellHttpClientSetAutoAuthentication() +error_code cellHttpClientGetAutoRedirect(CellHttpClientId clientId, vm::ptr enable) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientGetAutoRedirect(clientId=0x%x, enable=*0x%x)", clientId, enable); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + + if (!enable) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + return CELL_OK; } -error_code cellHttpClientGetAutoAuthentication() +error_code cellHttpClientSetAutoAuthentication(CellHttpClientId clientId, b8 enable) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientSetAutoAuthentication(clientId=0x%x, enable=%d)", clientId, enable); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + return CELL_OK; } -error_code cellHttpClientSetAuthenticationCacheStatus() +error_code cellHttpClientGetAutoAuthentication(CellHttpClientId clientId, vm::ptr enable) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientGetAutoAuthentication(clientId=0x%x, enable=*0x%x)", clientId, enable); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + + if (!enable) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + return CELL_OK; } -error_code cellHttpClientGetAuthenticationCacheStatus() +error_code cellHttpClientSetAuthenticationCacheStatus(CellHttpClientId clientId, b8 enable) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientSetAuthenticationCacheStatus(clientId=0x%x, enable=%d)", clientId, enable); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + return CELL_OK; } -error_code cellHttpClientSetCookieStatus() +error_code cellHttpClientGetAuthenticationCacheStatus(CellHttpClientId clientId, vm::ptr enable) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientGetAuthenticationCacheStatus(clientId=0x%x, enable=*0x%x)", clientId, enable); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + + if (!enable) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + return CELL_OK; } -error_code cellHttpClientGetCookieStatus() +error_code cellHttpClientSetCookieStatus(CellHttpClientId clientId, b8 enable) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientSetCookieStatus(clientId=0x%x, enable=%d)", clientId, enable); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + return CELL_OK; } -error_code cellHttpClientSetUserAgent() +error_code cellHttpClientGetCookieStatus(CellHttpClientId clientId, vm::ptr enable) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientGetCookieStatus(clientId=0x%x, enable=*0x%x)", clientId, enable); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + + if (!enable) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + return CELL_OK; } -error_code cellHttpClientGetUserAgent() +error_code cellHttpClientSetUserAgent(CellHttpClientId clientId, vm::cptr userAgent) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientSetUserAgent(clientId=0x%x, userAgent=%s)", clientId, userAgent); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + + if (!userAgent) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + return CELL_OK; } -error_code cellHttpClientSetResponseBufferMax() +error_code cellHttpClientGetUserAgent(CellHttpClientId clientId, vm::ptr userAgent, u32 size, vm::ptr required) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientGetUserAgent(clientId=0x%x, userAgent=*0x%x, size=%d, required=*0x%x)", clientId, size, userAgent, required); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + + if (!userAgent || !size) + { + if (!required) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + } + return CELL_OK; } -error_code cellHttpClientGetResponseBufferMax() +error_code cellHttpClientSetResponseBufferMax(CellHttpClientId clientId, u32 max) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientSetResponseBufferMax(clientId=0x%x, max=%d)", clientId, max); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + + if (max < 1500) + { + max = 1500; + } + return CELL_OK; } -error_code cellHttpClientCloseAllConnections() +error_code cellHttpClientGetResponseBufferMax(CellHttpClientId clientId, vm::ptr max) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientGetResponseBufferMax(clientId=0x%x, max=*0x%x)", clientId, max); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + + if (!max) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + return CELL_OK; } -error_code cellHttpClientCloseConnections() +error_code cellHttpClientCloseAllConnections(CellHttpClientId clientId) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientCloseAllConnections(clientId=0x%x)", clientId); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + return CELL_OK; } -error_code cellHttpClientPollConnections() +error_code cellHttpClientCloseConnections(CellHttpClientId clientId, vm::cptr uri) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientCloseConnections(clientId=0x%x, uri=*0x%x)", clientId, uri); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + return CELL_OK; } -error_code cellHttpClientSetConnectionStateCallback() +error_code cellHttpClientPollConnections(CellHttpClientId clientId, vm::ptr transId, s64 usec) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientPollConnections(clientId=0x%x, transId=*0x%x, usec=%d)", clientId, transId, usec); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + return CELL_OK; } -error_code cellHttpClientSetConnectionWaitStatus() +error_code cellHttpClientSetConnectionStateCallback(CellHttpClientId clientId, vm::ptr cbfunc, vm::ptr userArg) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientSetConnectionStateCallback(clientId=0x%x, cbfunc=*0x%x, userArg=*0x%x)", clientId, cbfunc, userArg); + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + return CELL_OK; } -error_code cellHttpClientGetConnectionWaitStatus() +error_code cellHttpClientSetConnectionWaitStatus(CellHttpClientId clientId, b8 enable) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientSetConnectionWaitStatus(clientId=0x%x, enable=%d)", clientId, enable); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + return CELL_OK; } -error_code cellHttpClientSetConnectionWaitTimeout() +error_code cellHttpClientGetConnectionWaitStatus(CellHttpClientId clientId, vm::ptr enable) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientGetConnectionWaitStatus(clientId=0x%x, enable=*0x%x)", clientId, enable); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + + if (!enable) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + return CELL_OK; } -error_code cellHttpClientGetConnectionWaitTimeout() +error_code cellHttpClientSetConnectionWaitTimeout(CellHttpClientId clientId, s64 usec) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientSetConnectionWaitTimeout(clientId=0x%x, usec=%d)", clientId, usec); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + return CELL_OK; } -error_code cellHttpClientSetRecvTimeout() +error_code cellHttpClientGetConnectionWaitTimeout(CellHttpClientId clientId, vm::ptr usec) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientGetConnectionWaitTimeout(clientId=0x%x, usec=*0x%x)", clientId, usec); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + + if (!usec) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + return CELL_OK; } -error_code cellHttpClientGetRecvTimeout() +error_code cellHttpClientSetRecvTimeout(CellHttpClientId clientId, s64 usec) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientSetRecvTimeout(clientId=0x%x, usec=%d)", clientId, usec); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + return CELL_OK; } -error_code cellHttpClientSetSendTimeout() +error_code cellHttpClientGetRecvTimeout(CellHttpClientId clientId, vm::ptr usec) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientGetRecvTimeout(clientId=0x%x, usec=*0x%x)", clientId, usec); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + + if (!usec) // TODO + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + return CELL_OK; } -error_code cellHttpClientGetSendTimeout() +error_code cellHttpClientSetSendTimeout(CellHttpClientId clientId, s64 usec) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientSetSendTimeout(clientId=0x%x, usec=%d)", clientId, usec); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + return CELL_OK; } -error_code cellHttpClientSetConnTimeout() +error_code cellHttpClientGetSendTimeout(CellHttpClientId clientId, vm::ptr usec) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientGetSendTimeout(clientId=0x%x, usec=*0x%x)", clientId, usec); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + + if (!usec) // TODO + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + return CELL_OK; } -error_code cellHttpClientGetConnTimeout() +error_code cellHttpClientSetConnTimeout(CellHttpClientId clientId, s64 usec) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientSetConnTimeout(clientId=0x%x, usec=%d)", clientId, usec); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + return CELL_OK; } -error_code cellHttpClientSetTotalPoolSize() +error_code cellHttpClientGetConnTimeout(CellHttpClientId clientId, vm::ptr usec) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientGetConnTimeout(clientId=0x%x, usec=*0x%x)", clientId, usec); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + + if (!usec) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + return CELL_OK; } -error_code cellHttpClientGetTotalPoolSize() +error_code cellHttpClientSetTotalPoolSize(CellHttpClientId clientId, u32 poolSize) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientSetTotalPoolSize(clientId=0x%x, poolSize=%d)", clientId, poolSize); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + return CELL_OK; } -error_code cellHttpClientSetPerHostPoolSize() +error_code cellHttpClientGetTotalPoolSize(CellHttpClientId clientId, vm::ptr poolSize) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientGetTotalPoolSize(clientId=0x%x, poolSize=*0x%x)", clientId, poolSize); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + + if (!poolSize) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + return CELL_OK; } -error_code cellHttpClientGetPerHostPoolSize() +error_code cellHttpClientSetPerHostPoolSize(CellHttpClientId clientId, u32 poolSize) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientSetPerHostPoolSize(clientId=0x%x, poolSize=%d)", clientId, poolSize); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + return CELL_OK; } -error_code cellHttpClientSetPerHostKeepAliveMax() +error_code cellHttpClientGetPerHostPoolSize(CellHttpClientId clientId, vm::ptr poolSize) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientGetPerHostPoolSize(clientId=0x%x, poolSize=*0x%x)", clientId, poolSize); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + + if (!poolSize) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + return CELL_OK; } -error_code cellHttpClientGetPerHostKeepAliveMax() +error_code cellHttpClientSetPerHostKeepAliveMax(CellHttpClientId clientId, u32 maxSize) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientSetPerHostKeepAliveMax(clientId=0x%x, maxSize=%d)", clientId, maxSize); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + return CELL_OK; } -error_code cellHttpClientSetPerPipelineMax() +error_code cellHttpClientGetPerHostKeepAliveMax(CellHttpClientId clientId, vm::ptr maxSize) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientGetPerHostKeepAliveMax(clientId=0x%x, maxSize=*0x%x)", clientId, maxSize); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + + if (!maxSize) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + return CELL_OK; } -error_code cellHttpClientGetPerPipelineMax() +error_code cellHttpClientSetPerPipelineMax(CellHttpClientId clientId, u32 pipeMax) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientSetPerPipelineMax(clientId=0x%x, pipeMax=%d)", clientId, pipeMax); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + return CELL_OK; } -error_code cellHttpClientSetRecvBufferSize() +error_code cellHttpClientGetPerPipelineMax(CellHttpClientId clientId, vm::ptr pipeMax) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientGetPerPipelineMax(clientId=0x%x, pipeMax=*0x%x)", clientId, pipeMax); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + + if (!pipeMax) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + return CELL_OK; } -error_code cellHttpClientGetRecvBufferSize() +error_code cellHttpClientSetRecvBufferSize(CellHttpClientId clientId, s32 size) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientSetRecvBufferSize(clientId=0x%x, size=%d)", clientId, size); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + return CELL_OK; } -error_code cellHttpClientSetSendBufferSize() +error_code cellHttpClientGetRecvBufferSize(CellHttpClientId clientId, vm::ptr size) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientGetRecvBufferSize(clientId=0x%x, size=*0x%x)", clientId, size); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + + if (!size) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + return CELL_OK; } -error_code cellHttpClientGetSendBufferSize() +error_code cellHttpClientSetSendBufferSize(CellHttpClientId clientId, s32 size) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientSetSendBufferSize(clientId=0x%x, size=%d)", clientId, size); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + return CELL_OK; } -error_code cellHttpClientGetAllHeaders() +error_code cellHttpClientGetSendBufferSize(CellHttpClientId clientId, vm::ptr size) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientGetSendBufferSize(clientId=0x%x, size=*0x%x)", clientId, size); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + + if (!size) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + return CELL_OK; } -error_code cellHttpClientSetHeader() +error_code cellHttpClientGetAllHeaders(CellHttpClientId clientId, vm::pptr headers, vm::ptr items, vm::ptr pool, u32 poolSize, vm::ptr required) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientGetAllHeaders(clientId=0x%x, headers=*0x%x, items=*0x%x, pool=*0x%x, poolSize=0x%x, required=*0x%x)", clientId, headers, items, pool, poolSize, required); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + + if ((!pool || !headers) && !required) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + return CELL_OK; } -error_code cellHttpClientGetHeader() +error_code cellHttpClientSetHeader(CellHttpClientId clientId, vm::cptr header) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientSetHeader(clientId=0x%x, header=*0x%x)", clientId, header); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + + if (!header) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + return CELL_OK; } -error_code cellHttpClientAddHeader() +error_code cellHttpClientGetHeader(CellHttpClientId clientId, vm::ptr header, vm::cptr name, vm::ptr pool, u32 poolSize, vm::ptr required) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientGetHeader(clientId=0x%x, header=*0x%x, name=%s, pool=*0x%x, poolSize=0x%x, required=*0x%x)", clientId, header, name, pool, poolSize, required); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + + if (!name) + { + return CELL_HTTP_ERROR_NO_STRING; + } + return CELL_OK; } -error_code cellHttpClientDeleteHeader() +error_code cellHttpClientAddHeader(CellHttpClientId clientId, vm::cptr header) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientAddHeader(clientId=0x%x, header=*0x%x)", clientId, header); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + return CELL_OK; } -error_code cellHttpClientSetSslCallback() +error_code cellHttpClientDeleteHeader(CellHttpClientId clientId, vm::cptr name) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientDeleteHeader(clientId=0x%x, name=%s)", clientId, name); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + return CELL_OK; } -error_code cellHttpClientSetSslClientCertificate() +error_code cellHttpClientSetSslCallback(CellHttpClientId clientId, vm::ptr cbfunc, vm::ptr userArg) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientSetSslCallback(clientId=0x%x, cbfunc=*0x%x, userArg=*0x%x)", clientId, cbfunc, userArg); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + return CELL_OK; } -error_code cellHttpCreateTransaction() +error_code cellHttpClientSetSslClientCertificate(CellHttpClientId clientId, vm::cptr cert, vm::cptr privKey) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientSetSslClientCertificate(clientId=0x%x, cert=*0x%x, privKey=*0x%x)", clientId, cert, privKey); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + + if (!cert && privKey) + { + return CELL_HTTPS_ERROR_KEY_NEEDS_CERT; + } + + if (cert && !privKey) + { + return CELL_HTTPS_ERROR_CERT_NEEDS_KEY; + } + return CELL_OK; } -error_code cellHttpDestroyTransaction() +error_code cellHttpCreateTransaction(vm::ptr transId, CellHttpClientId clientId, vm::cptr method, vm::cptr uri) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpCreateTransaction(transId=*0x%x, clientId=0x%x, method=%s, uri=*0x%x)", transId, clientId, method, uri); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + //if (error_code error = syscall_sys_memory_get_page_attribute(clientId)) + //{ + // return error; + //} + + if (!uri || !uri->hostname || !uri->hostname[0]) + { + return CELL_HTTP_ERROR_INVALID_URI; + } + return CELL_OK; } -error_code cellHttpTransactionGetUri() +error_code cellHttpDestroyTransaction(CellHttpTransId transId) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpDestroyTransaction(transId=0x%x)", transId); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_TRANS; + } + return CELL_OK; } -error_code cellHttpTransactionCloseConnection() +error_code cellHttpTransactionGetUri(CellHttpTransId transId, vm::ptr uri, vm::ptr pool, u32 poolSize, vm::ptr required) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpTransactionGetUri(transId=0x%x, uri=*0x%x, pool=*0x%x, poolSize=0x%x, required=*0x%x)", transId, uri, pool, poolSize, required); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_TRANS; + } + return CELL_OK; } -error_code cellHttpTransactionReleaseConnection() +error_code cellHttpTransactionSetUri(CellHttpTransId transId, vm::cptr uri) // TODO: more params? { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpTransactionSetUri(transId=0x%x, uri=*0x%x)", transId, uri); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_TRANS; + } + + if (!uri || !uri->hostname || !uri->hostname[0]) + { + return CELL_HTTP_ERROR_INVALID_URI; + } + + if (uri->scheme && false) // TODO + { + return CELL_HTTP_ERROR_INVALID_URI; + } + return CELL_OK; } -error_code cellHttpTransactionAbortConnection() +error_code cellHttpTransactionCloseConnection(CellHttpTransId transId) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpTransactionCloseConnection(transId=0x%x)", transId); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_TRANS; + } + return CELL_OK; } -error_code cellHttpSendRequest() +error_code cellHttpTransactionReleaseConnection(CellHttpTransId transId, vm::ptr sid) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpTransactionReleaseConnection(transId=0x%x, sid=*0x%x)", transId, sid); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_TRANS; + } + + if (!sid) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + return CELL_OK; } -error_code cellHttpRequestSetContentLength() +error_code cellHttpTransactionAbortConnection(CellHttpTransId transId) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpTransactionAbortConnection(transId=0x%x)", transId); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_TRANS; + } + return CELL_OK; } -error_code cellHttpRequestGetContentLength() +error_code cellHttpSendRequest(CellHttpTransId transId, vm::cptr buf, u32 size, vm::ptr sent) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpSendRequest(transId=0x%x, buf=*0x%x, size=0x%x, sent=*0x%x)", transId, buf, size, sent); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_TRANS; + } + return CELL_OK; } -error_code cellHttpRequestSetChunkedTransferStatus() +error_code cellHttpRequestSetContentLength(CellHttpTransId transId, u64 totalSize) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpRequestSetContentLength(transId=0x%x, totalSize=0x%x)", transId, totalSize); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_TRANS; + } + return CELL_OK; } -error_code cellHttpRequestGetChunkedTransferStatus() +error_code cellHttpRequestGetContentLength(CellHttpTransId transId, vm::ptr totalSize) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpRequestGetContentLength(transId=0x%x, totalSize=*0x%x)", transId, totalSize); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_TRANS; + } + + if (!totalSize) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_NO_CONTENT_LENGTH; + } + return CELL_OK; } -error_code cellHttpRequestGetAllHeaders() +error_code cellHttpRequestSetChunkedTransferStatus(CellHttpTransId transId, b8 enable) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpRequestSetChunkedTransferStatus(transId=0x%x, enable=%d)", transId, enable); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_TRANS; + } + return CELL_OK; } -error_code cellHttpRequestSetHeader() +error_code cellHttpRequestGetChunkedTransferStatus(CellHttpTransId transId, vm::ptr enable) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpRequestGetChunkedTransferStatus(transId=0x%x, enable=*0x%x)", transId, enable); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_TRANS; + } + + if (!enable) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + return CELL_OK; } -error_code cellHttpRequestGetHeader() +error_code cellHttpRequestGetAllHeaders(CellHttpTransId transId, vm::pptr headers, vm::ptr items, vm::ptr pool, u32 poolSize, vm::ptr required) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpRequestGetAllHeaders(transId=0x%x, headers=*0x%x, items=*0x%x, pool=*0x%x, poolSize=0x%x, required=*0x%x)", transId, headers, items, pool, poolSize, required); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_TRANS; + } + + if (!required && (!pool || !headers)) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + return CELL_OK; } -error_code cellHttpRequestAddHeader() +error_code cellHttpRequestSetHeader(CellHttpTransId transId, vm::cptr header) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpRequestSetHeader(transId=0x%x, header=*0x%x)", transId, header); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_TRANS; + } + + if (!header) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + return CELL_OK; } -error_code cellHttpRequestDeleteHeader() +error_code cellHttpRequestGetHeader(CellHttpTransId transId, vm::ptr header, vm::cptr name, vm::ptr pool, u32 poolSize, vm::ptr required) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpRequestGetHeader(transId=0x%x, header=*0x%x, name=%s, pool=*0x%x, poolSize=0x%x, required=*0x%x)", transId, header, name, pool, poolSize, required); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_TRANS; + } + + if (!name) + { + return CELL_HTTP_ERROR_NO_STRING; + } + return CELL_OK; } -error_code cellHttpRecvResponse() +error_code cellHttpRequestAddHeader(CellHttpTransId transId, vm::cptr header) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpRequestAddHeader(transId=0x%x, header=*0x%x)", transId, header); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_TRANS; + } + + if (!header) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + return CELL_OK; } -error_code cellHttpResponseGetAllHeaders() +error_code cellHttpRequestDeleteHeader(CellHttpTransId transId, vm::cptr name) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpRequestDeleteHeader(transId=0x%x, name=%s)", transId, name); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_TRANS; + } + + if (!name) + { + return CELL_HTTP_ERROR_NO_STRING; + } + return CELL_OK; } -error_code cellHttpResponseGetHeader() +error_code cellHttpRecvResponse(CellHttpTransId transId, vm::ptr buf, u32 size, vm::ptr recvd) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpRecvResponse(transId=0x%x, buf=*0x%x, size=0x%x, recvd=*0x%x)", transId, buf, size, recvd); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_TRANS; + } + return CELL_OK; } -error_code cellHttpResponseGetContentLength() +error_code cellHttpResponseGetAllHeaders(CellHttpTransId transId, vm::pptr headers, vm::ptr items, vm::ptr pool, u32 poolSize, vm::ptr required) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpResponseGetAllHeaders(transId=0x%x, headers=*0x%x, items=*0x%x, pool=*0x%x, poolSize=0x%x, required=*0x%x)", transId, headers, items, pool, poolSize, required); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_TRANS; + } + + if (!required && (!pool || !headers)) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + return CELL_OK; } -error_code cellHttpResponseGetStatusCode() +error_code cellHttpResponseGetHeader(CellHttpTransId transId, vm::ptr header, vm::cptr name, vm::ptr pool, u32 poolSize, vm::ptr required) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpResponseGetHeader(transId=0x%x, header=*0x%x, name=%s, pool=*0x%x, poolSize=0x%x, required=*0x%x)", transId, header, name, pool, poolSize, required); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_TRANS; + } + + if (!name) + { + return CELL_HTTP_ERROR_NO_STRING; + } + return CELL_OK; } -error_code cellHttpResponseGetStatusLine() +error_code cellHttpResponseGetContentLength(CellHttpTransId transId, vm::ptr length) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpResponseGetContentLength(transId=0x%x, length=*0x%x)", transId, length); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_TRANS; + } + + if (!length) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_NO_CONTENT_LENGTH; + } + return CELL_OK; } -error_code cellHttpTransactionGetSslCipherName() +error_code cellHttpResponseGetStatusCode(CellHttpTransId transId, vm::ptr code) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpResponseGetStatusCode(transId=0x%x, code=*0x%x)", transId, code); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_TRANS; + } + + if (!code) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + return CELL_OK; } -error_code cellHttpTransactionGetSslCipherId() +error_code cellHttpResponseGetStatusLine(CellHttpTransId transId, vm::ptr status, vm::ptr pool, u32 poolSize, vm::ptr required) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpResponseGetStatusLine(transId=0x%x, status=*0x%x, pool=*0x%x, poolSize=0x%x, required=*0x%x)", transId, status, pool, poolSize, required); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_TRANS; + } + return CELL_OK; } -error_code cellHttpTransactionGetSslCipherVersion() +error_code cellHttpTransactionGetSslCipherName(CellHttpTransId transId, vm::ptr name, u32 size, vm::ptr required) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpTransactionGetSslCipherName(transId=0x%x, name=*0x%x, size=0x%x, required=*0x%x)", transId, name, size, required); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_TRANS; + } + return CELL_OK; } -error_code cellHttpTransactionGetSslCipherBits() +error_code cellHttpTransactionGetSslCipherId(CellHttpTransId transId, vm::ptr id) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpTransactionGetSslCipherId(transId=0x%x, id=*0x%x)", transId, id); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_TRANS; + } + return CELL_OK; } -error_code cellHttpTransactionGetSslCipherString() +error_code cellHttpTransactionGetSslCipherVersion(CellHttpTransId transId, vm::ptr version, u32 size, vm::ptr required) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpTransactionGetSslCipherVersion(transId=0x%x, version=*0x%x, size=0x%x, required=*0x%x)", transId, version, size, required); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_TRANS; + } + return CELL_OK; } -error_code cellHttpTransactionGetSslVersion() +error_code cellHttpTransactionGetSslCipherBits(CellHttpTransId transId, vm::ptr effectiveBits, vm::ptr algorithmBits) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpTransactionGetSslCipherBits(transId=0x%x, effectiveBits=*0x%x, effectiveBits=*0x%x)", transId, effectiveBits, algorithmBits); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_TRANS; + } + return CELL_OK; } -error_code cellHttpTransactionGetSslId() +error_code cellHttpTransactionGetSslCipherString(CellHttpTransId transId, vm::ptr buffer, u32 size) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpTransactionGetSslCipherString(transId=0x%x, buffer=*0x%x, size=0x%x)", transId, buffer, size); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_TRANS; + } + + return CELL_OK; +} + +error_code cellHttpTransactionGetSslVersion(CellHttpTransId transId, vm::ptr version) +{ + cellHttp.todo("cellHttpTransactionGetSslVersion(transId=0x%x, version=*0x%x)", transId, version); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_TRANS; + } + return CELL_OK; } -error_code cellHttpClientSetMinSslVersion() +error_code cellHttpTransactionGetSslId(CellHttpTransId transId, vm::pptr id) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpTransactionGetSslId(transId=0x%x, id=*0x%x)", transId, id); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_TRANS; + } + return CELL_OK; } -error_code cellHttpClientGetMinSslVersion() +error_code cellHttpClientSetSslVersion(CellHttpClientId clientId, s32 version) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientSetSslVersion(clientId=0x%x, version=%d)", clientId, version); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + return CELL_OK; } -error_code cellHttpClientSetSslVersion() +error_code cellHttpClientGetSslVersion(CellHttpClientId clientId, vm::ptr version) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientGetSslVersion(clientId=0x%x, version=*0x%x)", clientId, version); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + + if (!version) + { + return CELL_HTTP_ERROR_NO_BUFFER; + } + return CELL_OK; } -error_code cellHttpClientGetSslVersion() +error_code cellHttpClientSetMinSslVersion(CellHttpClientId clientId, s32 version) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientSetMinSslVersion(clientId=0x%x, version=%d)", clientId, version); + + if (version != CELL_SSL_VERSION_TLS1) + { + if (version != CELL_SSL_VERSION_SSL3) + { + return CELL_HTTP_ERROR_INVALID_VALUE; + } + + version = 2; // TODO: this can't be right, can it ? + } + + return cellHttpClientSetSslVersion(clientId, version); +} + +error_code cellHttpClientGetMinSslVersion(CellHttpClientId clientId, vm::ptr version) +{ + cellHttp.todo("cellHttpClientGetMinSslVersion(clientId=0x%x, version=*0x%x)", clientId, version); + + if (error_code error = cellHttpClientGetSslVersion(clientId, version)) + { + return error; + } + + if (*version == 2) + { + *version = CELL_SSL_VERSION_SSL3; + } + return CELL_OK; } -error_code cellHttpClientSetSslIdDestroyCallback() +error_code cellHttpClientSetSslIdDestroyCallback(CellHttpClientId clientId, vm::ptr cbfunc, vm::ptr userArg) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpClientSetSslIdDestroyCallback(clientId=0x%x, cbfunc=*0x%x, userArg=*0x%x)", clientId, cbfunc, userArg); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.initialized) + { + return CELL_HTTP_ERROR_NOT_INITIALIZED; + } + + if (false) // TODO + { + return CELL_HTTP_ERROR_BAD_CLIENT; + } + return CELL_OK; } error_code cellHttpFlushCache() { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpFlushCache()"); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.cache_initialized) + { + return CELL_HTTP_ERROR_CACHE_NOT_INITIALIZED; + } + return CELL_OK; } error_code cellHttpEndCache() { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpEndCache()"); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.cache_initialized) + { + return CELL_HTTP_ERROR_CACHE_NOT_INITIALIZED; + } + + man.cache_initialized = false; return CELL_OK; } -error_code cellHttpInitCache() +error_code cellHttpInitCache(u32 unk) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpInitCache(unk=0x%x)", unk); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (man.cache_initialized) + { + return CELL_HTTP_ERROR_CACHE_ALREADY_INITIALIZED; + } + + man.cache_initialized = true; return CELL_OK; } -error_code cellHttpGetCacheInfo() +error_code cellHttpEndExternalCache() { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpEndExternalCache()"); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.ext_cache_initialized) + { + return CELL_HTTP_ERROR_CACHE_NOT_INITIALIZED; + } + + man.ext_cache_initialized = false; return CELL_OK; } -error_code cellHttpGetMemoryInfo() +error_code cellHttpInitExternalCache(vm::ptr buf, u32 size) { - UNIMPLEMENTED_FUNC(cellHttp); + cellHttp.todo("cellHttpInitExternalCache(buf=*0x%x, size=0x%x)", size); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (man.ext_cache_initialized) + { + return CELL_HTTP_ERROR_CACHE_ALREADY_INITIALIZED; + } + + if (buf) + { + std::memset(buf.get_ptr(), 0, size); + } + + if (size >= 512) + { + // TODO + } + + man.ext_cache_initialized = true; + return CELL_OK; +} + +error_code cellHttpFlushExternalCache() +{ + cellHttp.todo("cellHttpFlushExternalCache()"); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.ext_cache_initialized) + { + return CELL_HTTP_ERROR_CACHE_NOT_INITIALIZED; + } + + return CELL_OK; +} + +error_code cellHttpGetCacheInfo(vm::ptr buf) +{ + cellHttp.todo("cellHttpGetCacheInfo(buf=*0x%x)", buf); + + auto& man = g_fxo->get(); + std::lock_guard lock(man.mtx); + + if (!man.cache_initialized) + { + return CELL_HTTP_ERROR_CACHE_NOT_INITIALIZED; + } + + return CELL_OK; +} + +error_code cellHttpGetMemoryInfo(vm::ptr heapSize, vm::ptr param_2, vm::ptr param_3) +{ + cellHttp.todo("cellHttpGetMemoryInfo(heapSize=*0x%x, param_2=*0x%x, param_3=*0x%x)", heapSize, param_2, param_3); + + if (heapSize) + { + //*heapSize = _sys_heap_get_total_free_size(); + } + + if (!param_2 && !param_3) + { + return CELL_OK; + } + + if (param_2) + { + *param_2 = *param_3; + } + + //*param_3 = _sys_heap_get_mallinfo(); + return CELL_OK; } @@ -1842,6 +3814,7 @@ DECLARE(ppu_module_manager::cellHttp)("cellHttp", []() REG_FUNC(cellHttp, cellHttpClientSetAuthenticationCallback); REG_FUNC(cellHttp, cellHttpClientSetTransactionStateCallback); REG_FUNC(cellHttp, cellHttpClientSetRedirectCallback); + REG_FUNC(cellHttp, cellHttpClientSetCacheStatus); REG_FUNC(cellHttp, cellHttpClientSetProxy); REG_FUNC(cellHttp, cellHttpClientGetProxy); @@ -1904,6 +3877,7 @@ DECLARE(ppu_module_manager::cellHttp)("cellHttp", []() REG_FUNC(cellHttp, cellHttpCreateTransaction); REG_FUNC(cellHttp, cellHttpDestroyTransaction); REG_FUNC(cellHttp, cellHttpTransactionGetUri); + REG_FUNC(cellHttp, cellHttpTransactionSetUri); REG_FUNC(cellHttp, cellHttpTransactionCloseConnection); REG_FUNC(cellHttp, cellHttpTransactionReleaseConnection); REG_FUNC(cellHttp, cellHttpTransactionAbortConnection); @@ -1942,6 +3916,7 @@ DECLARE(ppu_module_manager::cellHttp)("cellHttp", []() REG_FUNC(cellHttp, cellHttpFlushCache); REG_FUNC(cellHttp, cellHttpEndCache); + REG_FUNC(cellHttp, cellHttpEndExternalCache); REG_FUNC(cellHttp, cellHttpInitCache); REG_FUNC(cellHttp, cellHttpGetCacheInfo); REG_FUNC(cellHttp, cellHttpGetMemoryInfo); diff --git a/rpcs3/Emu/Cell/Modules/cellHttp.h b/rpcs3/Emu/Cell/Modules/cellHttp.h index fda1b8fd26..3840498fd0 100644 --- a/rpcs3/Emu/Cell/Modules/cellHttp.h +++ b/rpcs3/Emu/Cell/Modules/cellHttp.h @@ -1087,3 +1087,128 @@ enum CellHttpErrorNet CELL_HTTP_ERROR_NET_SSL_RECV_ENOSTR = 0x80710d5b, CELL_HTTP_ERROR_NET_SSL_RECV_ETIME = 0x80710d5c, }; + +enum +{ + CELL_HTTP_TRANSACTION_STATE_GETTING_CONNECTION = 1, + CELL_HTTP_TRANSACTION_STATE_PREPARING_REQUEST = 2, + CELL_HTTP_TRANSACTION_STATE_SENDING_REQUEST = 3, + CELL_HTTP_TRANSACTION_STATE_SENDING_BODY = 4, + CELL_HTTP_TRANSACTION_STATE_WAITING_FOR_REPLY = 5, + CELL_HTTP_TRANSACTION_STATE_READING_REPLY = 6, + CELL_HTTP_TRANSACTION_STATE_SETTING_REDIRECTION = 7, + CELL_HTTP_TRANSACTION_STATE_SETTING_AUTHENTICATION = 8, +}; + +enum +{ + CELL_HTTP_STATUS_CODE_Continue = 100, + CELL_HTTP_STATUS_CODE_Switching_Protocols = 101, + CELL_HTTP_STATUS_CODE_Processing = 102, + + // Success codes + CELL_HTTP_STATUS_CODE_OK = 200, + CELL_HTTP_STATUS_CODE_Created = 201, + CELL_HTTP_STATUS_CODE_Accepted = 202, + CELL_HTTP_STATUS_CODE_NonAuthoritive_Information = 203, + CELL_HTTP_STATUS_CODE_No_Content = 204, + CELL_HTTP_STATUS_CODE_Reset_Content = 205, + CELL_HTTP_STATUS_CODE_Partial_Content = 206, + CELL_HTTP_STATUS_CODE_MultiStatus = 207, + /* Redirection 3xx */ + CELL_HTTP_STATUS_CODE_Multiple_Choices = 300, + CELL_HTTP_STATUS_CODE_Moved_Permanently = 301, + CELL_HTTP_STATUS_CODE_Moved_Temporarily = 302, + CELL_HTTP_STATUS_CODE_Found = CELL_HTTP_STATUS_CODE_Moved_Temporarily, + CELL_HTTP_STATUS_CODE_See_Other = 303, + CELL_HTTP_STATUS_CODE_Not_Modified = 304, + CELL_HTTP_STATUS_CODE_Use_Proxy = 305, + //CELL_HTTP_STATUS_CODE_UNUSED = 306, + CELL_HTTP_STATUS_CODE_Temporary_Redirect = 307, + + // Client errors + CELL_HTTP_STATUS_CODE_Bad_Request = 400, + CELL_HTTP_STATUS_CODE_Unauthorized = 401, + CELL_HTTP_STATUS_CODE_Payment_Required = 402, + CELL_HTTP_STATUS_CODE_Forbidden = 403, + CELL_HTTP_STATUS_CODE_Not_Found = 404, + CELL_HTTP_STATUS_CODE_Method_Not_Allowed = 405, + CELL_HTTP_STATUS_CODE_Not_Acceptable = 406, + CELL_HTTP_STATUS_CODE_Proxy_Authentication_Required = 407, + CELL_HTTP_STATUS_CODE_Request_Timeout = 408, + CELL_HTTP_STATUS_CODE_Conflict = 409, + CELL_HTTP_STATUS_CODE_Gone = 410, + CELL_HTTP_STATUS_CODE_Length_Required = 411, + CELL_HTTP_STATUS_CODE_Precondition_Failed = 412, + CELL_HTTP_STATUS_CODE_Request_Entity_Too_Large = 413, + CELL_HTTP_STATUS_CODE_RequestURI_Too_Long = 414, + CELL_HTTP_STATUS_CODE_Unsupported_Media_Type = 415, + CELL_HTTP_STATUS_CODE_Requested_Range_Not_Satisfiable = 416, + CELL_HTTP_STATUS_CODE_Expectation_Failed = 417, + CELL_HTTP_STATUS_CODE_Unprocessable_Entity = 422, + CELL_HTTP_STATUS_CODE_Locked = 423, + CELL_HTTP_STATUS_CODE_Failed_Dependency = 424, + CELL_HTTP_STATUS_CODE_Upgrade_Required = 426, + + // Server error + CELL_HTTP_STATUS_CODE_Internal_Server_Error = 500, + CELL_HTTP_STATUS_CODE_Not_Implemented = 501, + CELL_HTTP_STATUS_CODE_Bad_Gateway = 502, + CELL_HTTP_STATUS_CODE_Service_Unavailable = 503, + CELL_HTTP_STATUS_CODE_Gateway_Timeout = 504, + CELL_HTTP_STATUS_CODE_HTTP_Version_Not_Supported = 505, + CELL_HTTP_STATUS_CODE_Insufficient_Storage = 507, +}; + +enum +{ + CELL_HTTPS_VERIFY_ERROR_NONE = 0x00000000U, + CELL_HTTPS_VERIFY_ERROR_NO_CERT = 0x00000001U, + CELL_HTTPS_VERIFY_ERROR_BAD_SSL = 0x00000002U, + CELL_HTTPS_VERIFY_ERROR_BAD_CLIENT = 0x00000004U, + CELL_HTTPS_VERIFY_ERROR_UNKNOWN_CA = 0x00000008U, + CELL_HTTPS_VERIFY_ERROR_BAD_CHAIN = 0x00000010U, + CELL_HTTPS_VERIFY_ERROR_NO_MEMORY = 0x00000020U, + CELL_HTTPS_VERIFY_ERROR_NOT_VERIFIABLE = 0x00000040U, + CELL_HTTPS_VERIFY_ERROR_INVALID_CERT = 0x00000080U, + CELL_HTTPS_VERIFY_ERROR_BAD_CONSTRAINT = 0x00000100U, + CELL_HTTPS_VERIFY_ERROR_VERIFY_FAILED = 0x00000200U, + CELL_HTTPS_VERIFY_ERROR_COMMON_NAME = 0x00000400U, + CELL_HTTPS_VERIFY_ERROR_EXPIRED = 0x00000800U, + CELL_HTTPS_VERIFY_ERROR_NOT_YET_VALID = 0x00001000U, +}; + +static constexpr const char* CELL_HTTP_METHOD_OPTIONS = "OPTIONS"; +static constexpr const char* CELL_HTTP_METHOD_GET = "GET"; +static constexpr const char* CELL_HTTP_METHOD_HEAD = "HEAD"; +static constexpr const char* CELL_HTTP_METHOD_POST = "POST"; +static constexpr const char* CELL_HTTP_METHOD_PUT = "PUT"; +static constexpr const char* CELL_HTTP_METHOD_DELETE = "DELETE"; +static constexpr const char* CELL_HTTP_METHOD_TRACE = "TRACE"; + +typedef u32 CellHttpClientId; //typedef struct CellHttpClient* CellHttpClientId; +typedef u32 CellHttpTransId; //typedef struct CellHttpTransaction* CellHttpTransId; +typedef const void* CellHttpSslId; + +using CellHttpAuthenticationCallback = s32(CellHttpTransId transId, vm::cptr realm, vm::cptr uri, vm::ptr username, vm::ptr password, vm::ptr save, vm::ptr userArg); +using CellHttpTransactionStateCallback = s32(CellHttpTransId transId, s32 state, vm::ptr userArg); +using CellHttpRedirectCallback = s32(CellHttpTransId transId, vm::cptr response, vm::cptr from, vm::cptr to, vm::ptr userArg); +using CellHttpsSslCallback = s32(u32 verifyErr, vm::cpptr sslCerts, s32 certNum, vm::cptr hostname, vm::cptr id, vm::ptr userArg); +using CellHttpCookieSendCallback = s32(CellHttpTransId transId, vm::cptr uri, vm::cptr cookieValue, vm::ptr userArg); +using CellHttpCookieRecvCallback = s32(CellHttpTransId transId, vm::cptr uri, vm::cptr cookieValue, vm::ptr userArg); + +struct CellHttpsData +{ + vm::bptr ptr; + be_t size; +}; + +struct http_manager +{ + shared_mutex mtx; + bool initialized = false; + bool cookie_initialized = false; + bool cache_initialized = false; + bool ext_cache_initialized = false; + bool https_initialized = false; +}; diff --git a/rpcs3/Emu/Cell/Modules/cellHttpUtil.cpp b/rpcs3/Emu/Cell/Modules/cellHttpUtil.cpp index b1548ad551..4df193b536 100644 --- a/rpcs3/Emu/Cell/Modules/cellHttpUtil.cpp +++ b/rpcs3/Emu/Cell/Modules/cellHttpUtil.cpp @@ -38,6 +38,20 @@ void fmt_class_string::format(std::string& out, u64 arg) error_code cellHttpUtilParseUri(vm::ptr uri, vm::cptr str, vm::ptr pool, u32 size, vm::ptr required) { cellHttpUtil.trace("cellHttpUtilParseUri(uri=*0x%x, str=%s, pool=*0x%x, size=%d, required=*0x%x)", uri, str, pool, size, required); + + if (!str) + { + return CELL_HTTP_UTIL_ERROR_NO_STRING; + } + + if (!pool || !uri) + { + if (!required) + { + return CELL_HTTP_UTIL_ERROR_NO_BUFFER; + } + } + LUrlParser::clParseURL URL = LUrlParser::clParseURL::ParseURL(str.get_ptr()); if ( URL.IsValid() ) { @@ -127,55 +141,144 @@ error_code cellHttpUtilParseUri(vm::ptr uri, vm::cptr str, vm error_code cellHttpUtilParseUriPath(vm::ptr path, vm::cptr str, vm::ptr pool, u32 size, vm::ptr required) { cellHttpUtil.todo("cellHttpUtilParseUriPath(path=*0x%x, str=%s, pool=*0x%x, size=%d, required=*0x%x)", path, str, pool, size, required); + + if (!str) + { + return CELL_HTTP_UTIL_ERROR_NO_STRING; + } + + if (!pool || !path) + { + if (!required) + { + return CELL_HTTP_UTIL_ERROR_NO_BUFFER; + } + } + return CELL_OK; } error_code cellHttpUtilParseProxy(vm::ptr uri, vm::cptr str, vm::ptr pool, u32 size, vm::ptr required) { cellHttpUtil.todo("cellHttpUtilParseProxy(uri=*0x%x, str=%s, pool=*0x%x, size=%d, required=*0x%x)", uri, str, pool, size, required); + + if (!str) + { + return CELL_HTTP_UTIL_ERROR_NO_STRING; + } + + if (!pool || !uri) + { + if (!required) + { + return CELL_HTTP_UTIL_ERROR_NO_BUFFER; + } + } + return CELL_OK; } error_code cellHttpUtilParseStatusLine(vm::ptr resp, vm::cptr str, u32 len, vm::ptr pool, u32 size, vm::ptr required, vm::ptr parsedLength) { cellHttpUtil.todo("cellHttpUtilParseStatusLine(resp=*0x%x, str=%s, len=%d, pool=*0x%x, size=%d, required=*0x%x, parsedLength=*0x%x)", resp, str, len, pool, size, required, parsedLength); + + if (!str) + { + return CELL_HTTP_UTIL_ERROR_NO_STRING; + } + + if (!pool || !resp) + { + if (!required) + { + return CELL_HTTP_UTIL_ERROR_NO_BUFFER; + } + } + return CELL_OK; } error_code cellHttpUtilParseHeader(vm::ptr header, vm::cptr str, u32 len, vm::ptr pool, u32 size, vm::ptr required, vm::ptr parsedLength) { cellHttpUtil.todo("cellHttpUtilParseHeader(header=*0x%x, str=%s, len=%d, pool=*0x%x, size=%d, required=*0x%x, parsedLength=*0x%x)", header, str, len, pool, size, required, parsedLength); + + if (!str) + { + return CELL_HTTP_UTIL_ERROR_NO_STRING; + } + + if (!pool || !header) + { + if (!required) + { + return CELL_HTTP_UTIL_ERROR_NO_BUFFER; + } + } + return CELL_OK; } error_code cellHttpUtilBuildRequestLine(vm::cptr req, vm::ptr buf, u32 len, vm::ptr required) { - cellHttpUtil.todo("cellHttpUtilBuildRequestLine(req=*0x%x, buf=*0x%x, len=%d, required=*0x%x)", req, buf, len, required); + cellHttpUtil.notice("cellHttpUtilBuildRequestLine(req=*0x%x, buf=*0x%x, len=%d, required=*0x%x)", req, buf, len, required); - if (!req->method || !req->path || !req->protocol) { + if (!req || !req->method || !req->path || !req->protocol) + { return CELL_HTTP_UTIL_ERROR_INVALID_REQUEST; } - // TODO + std::string path = fmt::format("%s", req->path); + if (path.empty()) + { + path = "/"; + } - const std::string& result = fmt::format("%s %s %s/%d.%d\r\n", req->method, req->path, req->protocol, req->majorVersion, req->minorVersion); - std::memcpy(buf.get_ptr(), result.c_str(), result.size() + 1); + // TODO: are the numbers properly formatted ? + const std::string result = fmt::format("%s %s %s/%d.%d\r\n", req->method, path, req->protocol, req->majorVersion, req->minorVersion); + + if (buf) + { + if (len < result.size()) + { + return CELL_HTTP_UTIL_ERROR_INSUFFICIENT; + } + + std::memcpy(buf.get_ptr(), result.c_str(), result.size()); + } + + if (required) + { + *required = result.size(); + } return CELL_OK; } error_code cellHttpUtilBuildHeader(vm::cptr header, vm::ptr buf, u32 len, vm::ptr required) { - cellHttpUtil.todo("cellHttpUtilBuildHeader(header=*0x%x, buf=*0x%x, len=%d, required=*0x%x)", header, buf, len, required); + cellHttpUtil.notice("cellHttpUtilBuildHeader(header=*0x%x, buf=*0x%x, len=%d, required=*0x%x)", header, buf, len, required); - if (!header->name || !header->value) { + if (!header || !header->name) + { return CELL_HTTP_UTIL_ERROR_INVALID_HEADER; } - // TODO + const std::string result = fmt::format("%s: %s\r\n", header->name, header->value); - const std::string& result = fmt::format("%s: %s\r\n", header->name, header->value); - std::memcpy(buf.get_ptr(), result.c_str(), result.size() + 1); + if (buf) + { + if (len < result.size()) + { + return CELL_HTTP_UTIL_ERROR_INSUFFICIENT; + } + + std::memcpy(buf.get_ptr(), result.c_str(), result.size()); + } + + if (required) + { + *required = result.size(); + } return CELL_OK; } @@ -184,10 +287,71 @@ error_code cellHttpUtilBuildUri(vm::cptr uri, vm::ptr buf, u3 { cellHttpUtil.todo("cellHttpUtilBuildUri(uri=*0x%x, buf=*0x%x, len=%d, required=*0x%x, flags=%d)", uri, buf, len, required, flags); - // TODO + if (!uri || !uri->hostname) + { + return CELL_HTTP_UTIL_ERROR_INVALID_URI; + } - const std::string& result = fmt::format("%s://%s:%s@%s:%d/%s", uri->scheme, uri->username, uri->password, uri->hostname, uri->port, uri->path); - std::memcpy(buf.get_ptr(), result.c_str(), result.size() + 1); + std::string result; + + if (!(flags & CELL_HTTP_UTIL_URI_FLAG_NO_SCHEME)) + { + if (uri->scheme && uri->scheme[0]) + { + result = fmt::format("%s", uri->scheme); + } + else if (uri->port == 443u) + { + result = "https"; // TODO: confirm + } + else + { + result = "http"; // TODO: confirm + } + + fmt::append(result, "://"); + } + + if (!(flags & CELL_HTTP_UTIL_URI_FLAG_NO_CREDENTIALS) && uri->username && uri->username[0]) + { + fmt::append(result, "%s", uri->username); + + if (!(flags & CELL_HTTP_UTIL_URI_FLAG_NO_PASSWORD) && uri->password && uri->password[0]) + { + fmt::append(result, ":%s", uri->password); + } + + fmt::append(result, "@"); + } + + fmt::append(result, "%s", uri->hostname); + + if (true) // TODO: there seems to be a case where the port isn't added + { + fmt::append(result, ":%d", uri->port); + } + + if (!(flags & CELL_HTTP_UTIL_URI_FLAG_NO_PATH) && uri->path && uri->path[0]) + { + fmt::append(result, "%s", uri->path); + } + + const u32 size_needed = result.size() + 1; // Including '\0' + + if (buf) + { + if (len < size_needed) + { + return CELL_HTTP_UTIL_ERROR_INSUFFICIENT; + } + + std::memcpy(buf.get_ptr(), result.c_str(), size_needed); + } + + if (required) + { + *required = size_needed; + } return CELL_OK; } @@ -195,72 +359,469 @@ error_code cellHttpUtilBuildUri(vm::cptr uri, vm::ptr buf, u3 error_code cellHttpUtilCopyUri(vm::ptr dest, vm::cptr src, vm::ptr pool, u32 poolSize, vm::ptr required) { cellHttpUtil.todo("cellHttpUtilCopyUri(dest=*0x%x, src=*0x%x, pool=*0x%x, poolSize=%d, required=*0x%x)", dest, src, pool, poolSize, required); + + if (!src) + { + return CELL_HTTP_UTIL_ERROR_NO_BUFFER; + } + + if (!pool || !dest) + { + if (!required) + { + return CELL_HTTP_UTIL_ERROR_NO_BUFFER; + } + } + return CELL_OK; } error_code cellHttpUtilMergeUriPath(vm::ptr uri, vm::cptr src, vm::cptr path, vm::ptr pool, u32 poolSize, vm::ptr required) { cellHttpUtil.todo("cellHttpUtilMergeUriPath(uri=*0x%x, src=*0x%x, path=%s, pool=*0x%x, poolSize=%d, required=*0x%x)", uri, src, path, pool, poolSize, required); + + if (!path) + { + return CELL_HTTP_UTIL_ERROR_NO_STRING; + } + + if (!src) + { + return CELL_HTTP_UTIL_ERROR_NO_BUFFER; + } + + if (!pool || !uri) + { + if (!required) + { + return CELL_HTTP_UTIL_ERROR_NO_BUFFER; + } + } + return CELL_OK; } error_code cellHttpUtilSweepPath(vm::ptr dst, vm::cptr src, u32 srcSize) { cellHttpUtil.todo("cellHttpUtilSweepPath(dst=*0x%x, src=%s, srcSize=%d)", dst, src, srcSize); + + if (!dst || !src) + { + return CELL_HTTP_UTIL_ERROR_NO_BUFFER; + } + + if (!srcSize) + { + return CELL_OK; + } + + u32 pos = 0; + + if (src[pos] != '/') + { + std::memcpy(dst.get_ptr(), src.get_ptr(), srcSize - 1); + dst[srcSize - 1] = '\0'; + return CELL_OK; + } + + // TODO + return CELL_OK; } error_code cellHttpUtilCopyStatusLine(vm::ptr dest, vm::cptr src, vm::ptr pool, u32 poolSize, vm::ptr required) { cellHttpUtil.todo("cellHttpUtilCopyStatusLine(dest=*0x%x, src=*0x%x, pool=*0x%x, poolSize=%d, required=*0x%x)", dest, src, pool, poolSize, required); + + if (!src) + { + return CELL_HTTP_UTIL_ERROR_NO_BUFFER; + } + + if (!pool || !dest) + { + if (!required) + { + return CELL_HTTP_UTIL_ERROR_NO_BUFFER; + } + } + return CELL_OK; } error_code cellHttpUtilCopyHeader(vm::ptr dest, vm::cptr src, vm::ptr pool, u32 poolSize, vm::ptr required) { cellHttpUtil.todo("cellHttpUtilCopyHeader(dest=*0x%x, src=*0x%x, pool=*0x%x, poolSize=%d, required=*0x%x)", dest, src, pool, poolSize, required); + + if (!src) + { + return CELL_HTTP_UTIL_ERROR_NO_BUFFER; + } + + if (!pool || !dest) + { + if (!required) + { + return CELL_HTTP_UTIL_ERROR_NO_BUFFER; + } + } + return CELL_OK; } error_code cellHttpUtilAppendHeaderValue(vm::ptr dest, vm::cptr src, vm::cptr value, vm::ptr pool, u32 poolSize, vm::ptr required) { cellHttpUtil.todo("cellHttpUtilAppendHeaderValue(dest=*0x%x, src=*0x%x, value=%s, pool=*0x%x, poolSize=%d, required=*0x%x)", dest, src, value, pool, poolSize, required); + + if (!src) + { + return CELL_HTTP_UTIL_ERROR_NO_BUFFER; + } + + if (!pool || !dest) + { + if (!required) + { + return CELL_HTTP_UTIL_ERROR_NO_BUFFER; + } + } + return CELL_OK; } error_code cellHttpUtilEscapeUri(vm::ptr out, u32 outSize, vm::cptr in, u32 inSize, vm::ptr required) { cellHttpUtil.todo("cellHttpUtilEscapeUri(out=*0x%x, outSize=%d, in=*0x%x, inSize=%d, required=*0x%x)", out, outSize, in, inSize, required); + + if (!in || !inSize) + { + return CELL_HTTP_UTIL_ERROR_NO_STRING; + } + + if (!out && !required) + { + return CELL_HTTP_UTIL_ERROR_NO_BUFFER; + } + + u32 size_needed = 0; + u32 out_pos = 0; + s32 rindex = 0; + + if (const u32 end = in.addr() + inSize; end && end >= in.addr()) + { + rindex = inSize; + } + + for (u32 pos = 0; rindex >= 0; rindex--, pos++) + { + char c1 = in[pos]; + + if (false) // DAT[c1] == '\x03') // TODO + { + size_needed += 3; + + if (out) + { + if (outSize < size_needed) + { + return CELL_HTTP_UTIL_ERROR_NO_MEMORY; + } + + const char* chars = "0123456789ABCDEF"; + out[out_pos++] = '%'; // 0x25 + out[out_pos++] = chars[c1 >> 4]; + out[out_pos++] = chars[c1 & 0xf]; + } + } + else + { + size_needed++; + + if (out) + { + if (outSize < size_needed) + { + return CELL_HTTP_UTIL_ERROR_NO_MEMORY; + } + + out[out_pos++] = c1; + } + } + } + + size_needed++; + + if (out) + { + if (outSize < size_needed) + { + return CELL_HTTP_UTIL_ERROR_NO_MEMORY; + } + + out[out_pos] = '\0'; + } + + if (required) + { + *required = size_needed; + } + return CELL_OK; } error_code cellHttpUtilUnescapeUri(vm::ptr out, u32 size, vm::cptr in, vm::ptr required) { cellHttpUtil.todo("cellHttpUtilUnescapeUri(out=*0x%x, size=%d, in=*0x%x, required=*0x%x)", out, size, in, required); + + if (!in) + { + return CELL_HTTP_UTIL_ERROR_NO_STRING; + } + + if (!out && !required) + { + return CELL_HTTP_UTIL_ERROR_NO_BUFFER; + } + + if (required) + { + *required = 0; // TODO + } + return CELL_OK; } error_code cellHttpUtilFormUrlEncode(vm::ptr out, u32 outSize, vm::cptr in, u32 inSize, vm::ptr required) { cellHttpUtil.todo("cellHttpUtilFormUrlEncode(out=*0x%x, outSize=%d, in=*0x%x, inSize=%d, required=*0x%x)", out, outSize, in, inSize, required); + + if (!in || !inSize) + { + return CELL_HTTP_UTIL_ERROR_NO_STRING; + } + + if (!out && !required) + { + return CELL_HTTP_UTIL_ERROR_NO_BUFFER; + } + + u32 size_needed = 0; + u32 out_pos = 0; + s32 rindex = 0; + + if (const u32 end = in.addr() + inSize; end && end >= in.addr()) + { + rindex = inSize; + } + + for (u32 pos = 0; rindex >= 0; rindex--, pos++) + { + char c1 = in[pos]; + + if (c1 == ' ') + { + size_needed++; + + if (out) + { + if (outSize < size_needed) + { + return CELL_HTTP_UTIL_ERROR_NO_MEMORY; + } + + out[out_pos++] = '+'; + } + } + else if (false) // DAT[c1] == '\x03') // TODO + { + size_needed += 3; + + if (out) + { + if (outSize < size_needed) + { + return CELL_HTTP_UTIL_ERROR_NO_MEMORY; + } + + const char* chars = "0123456789ABCDEF"; + out[out_pos++] = '%'; // 0x25 + out[out_pos++] = chars[c1 >> 4]; + out[out_pos++] = chars[c1 & 0xf]; + } + } + else + { + size_needed++; + + if (out) + { + if (outSize < size_needed) + { + return CELL_HTTP_UTIL_ERROR_NO_MEMORY; + } + + out[out_pos++] = c1; + } + } + } + + size_needed++; + + if (out) + { + if (outSize < size_needed) + { + return CELL_HTTP_UTIL_ERROR_NO_MEMORY; + } + + out[out_pos++] = '\0'; + } + + if (required) + { + *required = size_needed; + } + return CELL_OK; } error_code cellHttpUtilFormUrlDecode(vm::ptr out, u32 size, vm::cptr in, vm::ptr required) { cellHttpUtil.todo("cellHttpUtilFormUrlDecode(out=*0x%x, size=%d, in=%s, required=*0x%x)", out, size, in, required); + + if (!in) + { + return CELL_HTTP_UTIL_ERROR_NO_STRING; + } + + if (!out && !required) + { + return CELL_HTTP_UTIL_ERROR_NO_BUFFER; + } + + u32 size_needed = 0; + u32 out_pos = 0; + + for (s32 index = 0, pos = 0;; index++) + { + size_needed = index + 1; + char c1 = in[pos++]; + + if (!c1) + { + break; + } + + if (out && (size < size_needed)) + { + return CELL_HTTP_UTIL_ERROR_NO_MEMORY; + } + + if (c1 == '%') + { + const char c2 = in[pos++]; + const char c3 = in[pos++]; + + if (!c2 || !c3) + { + return CELL_HTTP_UTIL_ERROR_INVALID_URI; + } + + const auto FUN_00036710 = [](b8 c) + { + u32 utmp = static_cast(c); + s32 stmp = utmp - 48; + if (static_cast(c - 48) > 9) + { + stmp = utmp - 55; + if (static_cast(c + 191) > 5) + { + stmp = -1; + if (static_cast(c + 159) < 6) + { + stmp = utmp - 87; + } + } + } + return stmp; + }; + + const s32 tmp1 = FUN_00036710(c2); + const s32 tmp2 = FUN_00036710(c3); + + if (tmp1 < 0 || tmp2 < 0) + { + return CELL_HTTP_UTIL_ERROR_INVALID_URI; + } + + if (out) + { + out[out_pos++] = static_cast((tmp1 & 0xffffffff) << 4) + static_cast(tmp2); + } + } + else + { + if (out) + { + out[out_pos++] = (c1 == '+' ? ' ' : c1); + } + } + } + + if (out) + { + if (size < size_needed) + { + return CELL_HTTP_UTIL_ERROR_NO_MEMORY; + } + + out[out_pos] = '\0'; + } + + if (required) + { + *required = size_needed; + } + return CELL_OK; } error_code cellHttpUtilBase64Encoder(vm::ptr out, vm::cptr input, u32 len) { cellHttpUtil.todo("cellHttpUtilBase64Encoder(out=*0x%x, input=*0x%x, len=%d)", out, input, len); + + if (!input || !len) + { + return CELL_HTTP_UTIL_ERROR_NO_STRING; + } + + if (!out) + { + return CELL_HTTP_UTIL_ERROR_NO_BUFFER; + } + return CELL_OK; } error_code cellHttpUtilBase64Decoder(vm::ptr output, vm::cptr in, u32 len) { - cellHttpUtil.todo("cellHttpUtilBase64Decoder(output=*0x%x, in=*0x%x, len=%d)", output, in, len); + cellHttpUtil.todo("cellHttpUtilBase64Decoder(output=*0x%x, in=*0x%x, len=%d)", output, in, len); + + if (!in) + { + return CELL_HTTP_UTIL_ERROR_NO_STRING; + } + + if ((len & 3) != 0) + { + return CELL_HTTP_UTIL_ERROR_INVALID_LENGTH; + } + + if (!output) + { + return CELL_HTTP_UTIL_ERROR_NO_BUFFER; + } + return CELL_OK; } diff --git a/rpcs3/Emu/Cell/Modules/cellHttpUtil.h b/rpcs3/Emu/Cell/Modules/cellHttpUtil.h index 9e4cc8e006..93f94c0d70 100644 --- a/rpcs3/Emu/Cell/Modules/cellHttpUtil.h +++ b/rpcs3/Emu/Cell/Modules/cellHttpUtil.h @@ -70,3 +70,5 @@ struct CellHttpHeader vm::bcptr name; vm::bcptr value; }; + +error_code cellHttpUtilCopyUri(vm::ptr dest, vm::cptr src, vm::ptr pool, u32 poolSize, vm::ptr required); diff --git a/rpcs3/Emu/Cell/Modules/cellSsl.cpp b/rpcs3/Emu/Cell/Modules/cellSsl.cpp index 0f36371a96..d7f32a5636 100644 --- a/rpcs3/Emu/Cell/Modules/cellSsl.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSsl.cpp @@ -326,10 +326,10 @@ error_code _cellSslConvertSslVersion() return CELL_OK; } -error_code _cellSslIsInitd() +b8 _cellSslIsInitd() { UNIMPLEMENTED_FUNC(cellSsl); - return CELL_OK; + return false; } error_code _cellSslPemReadPrivateKey() diff --git a/rpcs3/Emu/Cell/Modules/cellSsl.h b/rpcs3/Emu/Cell/Modules/cellSsl.h index 1df827d585..a1f96aec7d 100644 --- a/rpcs3/Emu/Cell/Modules/cellSsl.h +++ b/rpcs3/Emu/Cell/Modules/cellSsl.h @@ -203,3 +203,5 @@ struct ssl_manager { atomic_t is_init{ false }; }; + +b8 _cellSslIsInitd();