diff --git a/libctru/include/3ds/services/httpc.h b/libctru/include/3ds/services/httpc.h index 1ac41a7..c49069b 100644 --- a/libctru/include/3ds/services/httpc.h +++ b/libctru/include/3ds/services/httpc.h @@ -10,6 +10,15 @@ typedef struct { u32 httphandle; ///< HTTP handle. } httpcContext; +/// HTTP request method. +typedef enum { + HTTPC_METHOD_GET = 0x1, + HTTPC_METHOD_POST = 0x2, + HTTPC_METHOD_HEAD = 0x3, + HTTPC_METHOD_PUT = 0x4, + HTTPC_METHOD_DELETE = 0x5 +} HTTPC_RequestMethod; + /// HTTP request status. typedef enum { HTTPC_STATUS_REQUEST_IN_PROGRESS = 0x5, ///< Request in progress. @@ -19,6 +28,9 @@ typedef enum { /// Result code returned when a download is pending. #define HTTPC_RESULTCODE_DOWNLOADPENDING 0xd840a02b +// Result code returned when asked about a non-existing header +#define HTTPC_RESULTCODE_NOTFOUND 0xd840a028 + /// Initializes HTTPC. Result httpcInit(void); @@ -31,7 +43,7 @@ void httpcExit(void); * @param url URL to connect to. * @param use_defaultproxy Whether the default proxy should be used (0 for default) */ -Result httpcOpenContext(httpcContext *context, char* url, u32 use_defaultproxy); +Result httpcOpenContext(httpcContext *context, HTTPC_RequestMethod method, char* url, u32 use_defaultproxy); /** * @brief Closes a HTTP context. @@ -124,7 +136,7 @@ Result HTTPC_InitializeConnectionSession(Handle handle, Handle contextHandle); * @param url URL to connect to. * @param contextHandle Pointer to output the created HTTP context handle to. */ -Result HTTPC_CreateContext(Handle handle, char* url, Handle* contextHandle); +Result HTTPC_CreateContext(Handle handle, HTTPC_RequestMethod method, char* url, Handle* contextHandle); /** * @brief Closes a HTTP context. diff --git a/libctru/source/services/httpc.c b/libctru/source/services/httpc.c index b0daef8..ec979fa 100644 --- a/libctru/source/services/httpc.c +++ b/libctru/source/services/httpc.c @@ -33,11 +33,11 @@ void httpcExit(void) svcCloseHandle(__httpc_servhandle); } -Result httpcOpenContext(httpcContext *context, char* url, u32 use_defaultproxy) +Result httpcOpenContext(httpcContext *context, HTTPC_RequestMethod method, char* url, u32 use_defaultproxy) { Result ret=0; - ret = HTTPC_CreateContext(__httpc_servhandle, url, &context->httphandle); + ret = HTTPC_CreateContext(__httpc_servhandle, method, url, &context->httphandle); if(R_FAILED(ret))return ret; ret = srvGetServiceHandle(&context->servhandle, "http:C"); @@ -113,38 +113,31 @@ Result httpcGetResponseStatusCode(httpcContext *context, u32* out, u64 delay) Result httpcDownloadData(httpcContext *context, u8* buffer, u32 size, u32 *downloadedsize) { Result ret=0; - u32 contentsize=0; + Result dlret=HTTPC_RESULTCODE_DOWNLOADPENDING; u32 pos=0, sz=0; + u32 dlstartpos=0; + u32 dlpos=0; if(downloadedsize)*downloadedsize = 0; - ret=httpcGetDownloadSizeState(context, NULL, &contentsize); + ret=httpcGetDownloadSizeState(context, &dlstartpos, NULL); if(R_FAILED(ret))return ret; - while(pos < size) + while(pos < size && dlret==HTTPC_RESULTCODE_DOWNLOADPENDING) { sz = size - pos; - ret=httpcReceiveData(context, &buffer[pos], sz); + dlret=httpcReceiveData(context, &buffer[pos], sz); - if(ret==HTTPC_RESULTCODE_DOWNLOADPENDING) - { - ret=httpcGetDownloadSizeState(context, &pos, NULL); - if(R_FAILED(ret))return ret; - } - else if(R_FAILED(ret)) - { - return ret; - } - else - { - pos+= sz; - } + ret=httpcGetDownloadSizeState(context, &dlpos, NULL); + if(R_FAILED(ret))return ret; - if(downloadedsize)*downloadedsize = pos; + pos = dlpos - dlstartpos; } - return 0; + if(downloadedsize)*downloadedsize = pos; + + return dlret; } Result HTTPC_Initialize(Handle handle) @@ -152,10 +145,10 @@ Result HTTPC_Initialize(Handle handle) u32* cmdbuf=getThreadCommandBuffer(); cmdbuf[0]=IPC_MakeHeader(0x1,1,4); // 0x10044 - cmdbuf[1]=0x1000; //unk + cmdbuf[1]=0x1000; // POST buffer size (page aligned) cmdbuf[2]=IPC_Desc_CurProcessHandle(); cmdbuf[4]=IPC_Desc_SharedHandles(1); - cmdbuf[5]=0;//Some sort of handle. + cmdbuf[5]=0;// POST buffer memory block handle Result ret=0; if(R_FAILED(ret=svcSendSyncRequest(handle)))return ret; @@ -163,14 +156,14 @@ Result HTTPC_Initialize(Handle handle) return cmdbuf[1]; } -Result HTTPC_CreateContext(Handle handle, char* url, Handle* contextHandle) +Result HTTPC_CreateContext(Handle handle, HTTPC_RequestMethod method, char* url, Handle* contextHandle) { u32* cmdbuf=getThreadCommandBuffer(); u32 l=strlen(url)+1; cmdbuf[0]=IPC_MakeHeader(0x2,2,2); // 0x20082 cmdbuf[1]=l; - cmdbuf[2]=0x01; //unk + cmdbuf[2]=method; cmdbuf[3]=IPC_Desc_Buffer(l,IPC_BUFFER_R); cmdbuf[4]=(u32)url;