]> Chaos Git - corbenik/ctrulib.git/commitdiff
httpc fixes and extensions
authorKen Sanislo <ksanislo@users.noreply.github.com>
Fri, 29 Jan 2016 22:16:50 +0000 (14:16 -0800)
committerDave Murphy <davem@devkitpro.org>
Fri, 12 Feb 2016 16:38:43 +0000 (16:38 +0000)
Signed-off-by: Dave Murphy <davem@devkitpro.org>
libctru/include/3ds/services/httpc.h
libctru/source/services/httpc.c

index 1ac41a7b05be5a4cac5503b7c0209d3119b2068a..c49069bd91df9c3bf8e130de663a337d137b1194 100644 (file)
@@ -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.
index b0daef8b347155004efede077d47187e3953c3e9..ec979fa718201984750e85d176ff995b2f6cfe9c 100644 (file)
@@ -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);
-
-               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;
-               }
-
-               if(downloadedsize)*downloadedsize = pos;
+               dlret=httpcReceiveData(context, &buffer[pos], sz);
+
+               ret=httpcGetDownloadSizeState(context, &dlpos, NULL);
+               if(R_FAILED(ret))return ret;
+
+               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;