#include "stdafx.h" #include "SonyHttp_PS3.h" // static const int sc_HTTPPoolSize = (32 * 1024); // static const int sc_SSLPoolSize = (256 * 1024U); // static const int sc_CookiePoolSize = (256 * 1024U); static const int sc_HTTPPoolSize = (32 * 1024); static const int sc_SSLPoolSize = (512 * 1024U); static const int sc_CookiePoolSize = (256 * 1024U); void* SonyHttp_PS3::uriPool = NULL; void* SonyHttp_PS3::httpPool = NULL; void* SonyHttp_PS3::sslPool = NULL; void* SonyHttp_PS3::cookiePool = NULL; CellHttpClientId SonyHttp_PS3::client; CellHttpTransId SonyHttp_PS3::trans; bool SonyHttp_PS3:: bInitialised = false; bool SonyHttp_PS3::loadCerts(size_t *numBufPtr, CellHttpsData **caListPtr) { CellHttpsData *caList = NULL; size_t size = 0; int ret = 0; char *buf = NULL; caList = (CellHttpsData *)malloc(sizeof(CellHttpsData)*2); if (NULL == caList) { app.DebugPrintf("failed to malloc cert data"); return false; } ret = cellSslCertificateLoader(CELL_SSL_LOAD_CERT_ALL, NULL, 0, &size); if (ret < 0) { app.DebugPrintf("cellSslCertifacateLoader() failed(1): 0x%08x", ret); return ret; } buf = (char*)malloc(size); if (NULL == buf) { app.DebugPrintf("failed to malloc cert buffer"); free(caList); return false; } ret = cellSslCertificateLoader(CELL_SSL_LOAD_CERT_ALL, buf, size, NULL); if (ret < 0) { app.DebugPrintf("cellSslCertifacateLoader() failed(2): 0x%08x", ret); free(buf); free(caList); return false; } (&caList[0])->ptr = buf; (&caList[0])->size = size; *caListPtr = caList; *numBufPtr = 1; return true; } bool SonyHttp_PS3::init() { int ret; client = 0; trans = 0; /*E startup procedures */ httpPool = malloc(sc_HTTPPoolSize); if (httpPool == NULL) { app.DebugPrintf("failed to malloc libhttp memory pool\n"); return false; } ret = cellHttpInit(httpPool, sc_HTTPPoolSize); if (0 > ret) { app.DebugPrintf("unable to start libhttp... (0x%x)\n", ret); return false; } cookiePool = malloc(sc_CookiePoolSize); if (cookiePool == NULL) { app.DebugPrintf("failed to malloc ssl memory pool\n"); return false; } ret = cellHttpInitCookie(cookiePool, sc_CookiePoolSize); if (ret < 0 && ret != CELL_HTTP_ERROR_ALREADY_INITIALIZED) { app.DebugPrintf("cellHttpInitCookie failed... (0x%x)\n", ret); return false; } sslPool = malloc(sc_SSLPoolSize); if (sslPool == NULL) { app.DebugPrintf("failed to malloc ssl memory pool\n"); return false; } ret = cellSslInit(sslPool, sc_SSLPoolSize); if (0 > ret) { app.DebugPrintf("unable to start cellSslInit... (0x%x)\n", ret); return false; } size_t numBuf = 0; CellHttpsData *caList = NULL; if(!loadCerts(&numBuf, &caList)) return false; ret = cellHttpsInit(numBuf, caList); free(caList->ptr); free(caList); if (ret < 0 && ret != CELL_HTTP_ERROR_ALREADY_INITIALIZED) { app.DebugPrintf("unable to start https: 0x%08x", ret); return false; } ret = cellHttpCreateClient(&client); if (0 > ret) { app.DebugPrintf("unable to create http client... (0x%x)\n", ret); return false; } bInitialised = true; return true; } void SonyHttp_PS3::shutdown() { if (trans) { cellHttpDestroyTransaction(trans); trans = 0; } if (client) { cellHttpDestroyClient(client); client = 0; } cellHttpEnd(); free(httpPool); } bool SonyHttp_PS3::parseUri(const char* szUri, CellHttpUri& parsedUri) { /*E the main part */ size_t poolSize = 0; int ret = cellHttpUtilParseUri(NULL, szUri, NULL, 0, &poolSize); if (0 > ret) { app.DebugPrintf("error parsing URI... (0x%x)\n\n", ret); return false; } if (NULL == (uriPool = malloc(poolSize))) { app.DebugPrintf("error mallocing uriPool (%d)\n", poolSize); return false; } ret = cellHttpUtilParseUri(&parsedUri, szUri, uriPool, poolSize, NULL); if (0 > ret) { free(uriPool); app.DebugPrintf("error parsing URI... (0x%x)\n\n", ret); return false; } return true; } void* SonyHttp_PS3::getData(const char* url, int* pDataSize) { CellHttpUri uri; int ret; bool has_cl = true; uint64_t length = 0; uint64_t recvd; const char *serverName; size_t localRecv = 0; if(!parseUri(url, uri)) return NULL; app.DebugPrintf(" scheme: %s\n", uri.scheme); app.DebugPrintf(" hostname: %s\n", uri.hostname); app.DebugPrintf(" port: %d\n", uri.port); app.DebugPrintf(" path: %s\n", uri.path); app.DebugPrintf(" username: %s\n", uri.username); app.DebugPrintf(" password: %s\n", uri.password); ret = cellHttpCreateTransaction(&trans, client, CELL_HTTP_METHOD_GET, &uri); free(uriPool); if (0 > ret) { app.DebugPrintf("failed to create http transaction... (0x%x)\n\n", ret); return NULL; } ret = cellHttpSendRequest(trans, NULL, 0, NULL); if (0 > ret) { app.DebugPrintf("failed to complete http transaction... (0x%x)\n\n", ret); /*E continue down to check status code, just in case */ cellHttpDestroyTransaction(trans); trans = 0; } { int code = 0; ret = cellHttpResponseGetStatusCode(trans, &code); if (0 > ret) { app.DebugPrintf("failed to receive http response... (0x%x)\n\n", ret); cellHttpDestroyTransaction(trans); trans = 0; return NULL; } app.DebugPrintf("Status Code is %d\n", code); } ret = cellHttpResponseGetContentLength(trans, &length); if (0 > ret) { if (ret == CELL_HTTP_ERROR_NO_CONTENT_LENGTH) { app.DebugPrintf("Only supporting data that has a content length : CELL_HTTP_ERROR_NO_CONTENT_LENGTH\n", ret); cellHttpDestroyTransaction(trans); trans = 0; return NULL; } else { app.DebugPrintf("error in receiving content length... (0x%x)\n\n", ret); cellHttpDestroyTransaction(trans); trans = 0; return NULL; } } int bufferSize = length; char* buffer = (char*)malloc(bufferSize+1); recvd = 0; // 4J-PB - seems to be some limit to a read with cellHttpRecvResponse, even though it claims it's read all the data, it hasn't // reducing this to read 10k at a time. int iMaxRead=10240; app.DebugPrintf("\n===BEGINNING OF TRANSMISSION===\n"); while(recvd ret) { app.DebugPrintf("error receiving body... (0x%x)\n\n", ret); free(buffer); cellHttpDestroyTransaction(trans); trans = 0; return NULL; } else { if(localRecv==0) break; } recvd += localRecv; } buffer[bufferSize] = '\0'; ret = 0; app.DebugPrintf("\n===END OF TRANSMISSION===\n\n"); *pDataSize = bufferSize; cellHttpDestroyTransaction(trans); trans = 0; return buffer; } bool SonyHttp_PS3::getDataFromURL( const char* szURL, void** ppOutData, int* pDataSize) { if(!bInitialised) return false; *ppOutData = getData(szURL, pDataSize); if(*ppOutData) return true; return false; }