Files
MinecraftConsoles/Minecraft.Client/Orbis/Network/SonyHttp_Orbis.cpp
2026-03-01 12:16:08 +08:00

286 lines
7.4 KiB
C++

#include "stdafx.h"
#include "SonyHttp_Orbis.h"
static const int sc_SSLHeapSize = (304 * 1024U);
static const int sc_HTTPHeapSize = (48 * 1024);
static const int sc_NetHeapSize = (16 * 1024);
#define TEST_USER_AGENT "SimpleSample/1.00"
int SonyHttp_Orbis::libnetMemId = 0;
int SonyHttp_Orbis::libsslCtxId = 0;
int SonyHttp_Orbis::libhttpCtxId = 0;
bool SonyHttp_Orbis:: bInitialised = false;
bool SonyHttp_Orbis::init()
{
int ret = sceNetPoolCreate("simple", sc_NetHeapSize, 0);
assert(ret >= 0);
libnetMemId = ret;
ret = sceSslInit(sc_SSLHeapSize);
assert(ret >= 0);
libsslCtxId = ret;
ret = sceHttpInit(libnetMemId, libsslCtxId, sc_HTTPHeapSize);
assert(ret >= 0);
libhttpCtxId = ret;
bInitialised = true;
return true;
}
void SonyHttp_Orbis::shutdown()
{
int ret = sceHttpTerm(libhttpCtxId);
assert(ret == SCE_OK);
ret = sceSslTerm(libsslCtxId);
assert(ret == SCE_OK);
/* libnet */
ret = sceNetPoolDestroy(libnetMemId);
assert(ret == SCE_OK);
}
void SonyHttp_Orbis::printSslError(SceInt32 sslErr, SceUInt32 sslErrDetail)
{
switch (sslErr)
{
case (SCE_HTTPS_ERROR_CERT): /* Verify error */
/* Internal error at verifying certificate*/
if (sslErrDetail & SCE_HTTPS_ERROR_SSL_INTERNAL){
app.DebugPrintf("ssl verify error: unexpcted error\n");
}
/* Error of server certificate or CA certificate */
if (sslErrDetail & SCE_HTTPS_ERROR_SSL_INVALID_CERT){
app.DebugPrintf("ssl verify error: invalid server cert or CA cert\n");
}
/* Server hostname and server certificate are mismatched*/
if (sslErrDetail & SCE_HTTPS_ERROR_SSL_CN_CHECK){
app.DebugPrintf("ssl verify error: invalid server hostname\n");
}
/* Server certificate or CA certificate is expired.*/
if (sslErrDetail & SCE_HTTPS_ERROR_SSL_NOT_AFTER_CHECK){
app.DebugPrintf("ssl verify error: server cert or CA cert had expired\n");
}
/* Server certificate or CA certificate is before validated.*/
if (sslErrDetail & SCE_HTTPS_ERROR_SSL_NOT_BEFORE_CHECK){
app.DebugPrintf("ssl verify error: server cert or CA cert isn't validated yet.\n");
}
/* Unknown CA error */
if (sslErrDetail & SCE_HTTPS_ERROR_SSL_UNKNOWN_CA){
app.DebugPrintf("ssl verify error: unknown CA\n");
}
break;
case (SCE_HTTPS_ERROR_HANDSHAKE): /* fail to ssl-handshake */
app.DebugPrintf("ssl error: handshake error\n");
break;
case (SCE_HTTPS_ERROR_IO): /* Error of Socket IO */
app.DebugPrintf("ssl error: io error\n");
break;
case (SCE_HTTP_ERROR_OUT_OF_MEMORY): /* Out of memory*/
app.DebugPrintf("ssl error: out of memory\n");
break;
case (SCE_HTTPS_ERROR_INTERNAL): /* Unexpected Internal Error*/
app.DebugPrintf("ssl error: unexpcted error\n");
break;
default:
break;
}
return;
}
void SonyHttp_Orbis::printSslCertInfo(int libsslCtxId,SceSslCert *sslCert)
{
SceInt32 ret;
SceUChar8 *sboData = NULL ;
SceSize sboLen, counter;
ret = sceSslGetSerialNumber(libsslCtxId, sslCert, NULL, &sboLen);
if (ret < 0){
app.DebugPrintf("sceSslGetSerialNumber() returns 0x%x\n", ret);
}
else {
sboData = (SceUChar8*)malloc(sboLen);
if ( sboData != NULL ) {
ret = sceSslGetSerialNumber(libsslCtxId, sslCert, sboData, &sboLen);
if (ret < 0){
app.DebugPrintf ("sceSslGetSerialNumber() returns 0x%x\n", ret);
}
else {
app.DebugPrintf("Serial number=");
for (counter = 0; counter < sboLen; counter++){
app.DebugPrintf("%02X", sboData[counter]);
}
app.DebugPrintf("\n");
}
free(sboData);
}
}
}
bool SonyHttp_Orbis::getDataFromURL( const char* szURL, void** ppOutData, int* pDataSize)
{
if(!bInitialised)
return false;
return http_get(szURL, ppOutData, pDataSize);
}
SceInt32 SonyHttp_Orbis::sslCallback(int libsslCtxId,unsigned int verifyErr,SceSslCert * const sslCert[],int certNum,void *userArg)
{
SceInt32 i;
(void)userArg;
app.DebugPrintf("Ssl callback:\n");
app.DebugPrintf("\tbase tmpl[%x]\n", (*(SceInt32*)(userArg)) );
if (verifyErr != 0){
printSslError((SceInt32)SCE_HTTPS_ERROR_CERT, verifyErr);
}
for (i = 0; i < certNum; i++){
printSslCertInfo(libsslCtxId,sslCert[i]);
}
if (verifyErr == 0){
return SCE_OK;
} else {
return -1;
}
}
bool SonyHttp_Orbis::http_get_close(bool bOK, SceInt32 tmplId, SceInt32 connId, SceInt32 reqId)
{
SceInt32 ret;
if (reqId > 0)
{
ret = sceHttpDeleteRequest(reqId);
assert(ret >= 0);
}
if (connId > 0)
{
ret = sceHttpDeleteConnection(connId);
assert(ret >= 0);
}
if (tmplId > 0)
{
ret = sceHttpDeleteTemplate(tmplId);
assert(ret >= 0);
}
assert(bOK);
return bOK;
}
bool SonyHttp_Orbis::http_get(const char *targetUrl, void** ppOutData, int* pDataSize)
{
SceInt32 ret, tmplId=0, connId=0, reqId=0, statusCode;
SceULong64 contentLength=0;
SceBool finFlag=SCE_FALSE;
SceUChar8* recvBuf;
ret = sceHttpCreateTemplate(libhttpCtxId, TEST_USER_AGENT, SCE_HTTP_VERSION_1_1, SCE_TRUE);
if (ret < 0)
{
app.DebugPrintf("sceHttpCreateTemplate() error: 0x%08X\n", ret);
return http_get_close(false, tmplId, connId, reqId);
}
tmplId = ret;
/* Perform http_get without server verification */
ret = sceHttpsDisableOption(tmplId,SCE_HTTPS_FLAG_SERVER_VERIFY);
if (ret < 0)
{
app.DebugPrintf("sceHttpsDisableOption() error: 0x%08X\n", ret);
return http_get_close(false, tmplId, connId, reqId);
}
/* Register SSL callback */
ret = sceHttpsSetSslCallback(tmplId, sslCallback, (void*)&tmplId);
if (ret < 0)
{
app.DebugPrintf("sceHttpsSetSslCallback() error: 0x%08X\n", ret);
return http_get_close(false, tmplId, connId, reqId);
}
ret = sceHttpCreateConnectionWithURL(tmplId, targetUrl, SCE_TRUE);
if (ret < 0)
{
app.DebugPrintf("sceHttpCreateConnectionWithURL() error: 0x%08X\n", ret);
return http_get_close(false, tmplId, connId, reqId);
}
connId = ret;
ret = sceHttpCreateRequestWithURL(connId, SCE_HTTP_METHOD_GET, targetUrl, 0);
if (ret < 0)
{
app.DebugPrintf("sceHttpCreateRequestWithURL() error: 0x%08X\n", ret);
return http_get_close(false, tmplId, connId, reqId);
}
reqId = ret;
ret = sceHttpSendRequest(reqId, NULL, 0);
if (ret < 0)
{
app.DebugPrintf("sceHttpSendRequest() error: 0x%08X\n", ret);
return http_get_close(false, tmplId, connId, reqId);
}
ret = sceHttpGetStatusCode(reqId, &statusCode);
if (ret < 0)
{
app.DebugPrintf("sceHttpGetStatusCode() error: 0x%08X\n", ret);
return http_get_close(false, tmplId, connId, reqId);
}
app.DebugPrintf("response code = %d\n", statusCode);
if(statusCode == 200)
{
int contentLengthType;
ret = sceHttpGetResponseContentLength(reqId, &contentLengthType, &contentLength);
if(ret < 0)
{
app.DebugPrintf("sceHttpGetContentLength() error: 0x%08X\n", ret);
return http_get_close(false, tmplId, connId, reqId);
}
else
{
if (contentLengthType == SCE_HTTP_CONTENTLEN_EXIST)
{
app.DebugPrintf("Content-Length = %lu\n", contentLength);
}
}
recvBuf = new SceUChar8[contentLength+1];
int bufferLeft = contentLength+1;
SceUChar8* pCurrBuffPos = recvBuf;
int totalBytesRead = 0;
while(finFlag != SCE_TRUE)
{
ret = sceHttpReadData(reqId, pCurrBuffPos, bufferLeft);
if (ret < 0)
{
app.DebugPrintf("\n sceHttpReadData() failed 0x%08X\n", ret);
return http_get_close(false, tmplId, connId, reqId);
}
else if (ret == 0)
{
finFlag = SCE_TRUE;
}
app.DebugPrintf("\n sceHttpReadData() read %d bytes\n", ret);
pCurrBuffPos += ret;
totalBytesRead += ret;
bufferLeft -= ret;
}
}
*ppOutData = recvBuf;
*pDataSize = contentLength;
return http_get_close(true, tmplId, connId, reqId);
}