]> Nishi Git Mirror - libw3.git/commitdiff
added chunk support
authornishi <nishi@d27a3e52-49c5-7645-884c-6793ebffc270>
Wed, 24 Jan 2024 13:08:25 +0000 (13:08 +0000)
committernishi <nishi@d27a3e52-49c5-7645-884c-6793ebffc270>
Wed, 24 Jan 2024 13:08:25 +0000 (13:08 +0000)
git-svn-id: file:///raid/svn-main/nishi-libw3/trunk@58 d27a3e52-49c5-7645-884c-6793ebffc270

.clang-format
Example/fetch.c
Library/HTTP.c
W3Version.h.p

index 4fbff0ca4a585336dc05cd2932362b8b119d2d6d..0554a6a6c625810b56e3895c28920221f2cd3cc2 100644 (file)
@@ -7,5 +7,6 @@ IndentWidth: 8
 PointerAlignment: Left
 ColumnLimit: 1024
 AllowShortIfStatementsOnASingleLine: Always
+AllowShortBlocksOnASingleLine: Never
 AllowShortLoopsOnASingleLine: True
 SpaceBeforeParens: Never
index 393ff29c54ba31993002010f97177d50871fc842..2d0d4c7aed7cc467b1cc54b31a0822c83b4d8109 100644 (file)
 
 FILE* f;
 
-void fetch_data(struct W3* w3, char* data, size_t size) { fwrite(data, size, 1, f); }
+void fetch_data(struct W3* w3, char* data, size_t size) {
+       fwrite(data, size, 1, f);
+       printf("Got data, %d bytes\n", size);
+}
 
 void status(struct W3* w3, int status) { fprintf(stderr, "Response code is %d\n", status); }
 
@@ -34,7 +37,7 @@ int main(int argc, char** argv) {
                return 1;
        }
        W3_Library_Init();
-       struct W3* w3 = W3_Create("http", argv[1], 80);
+       struct W3* w3 = W3_Create("https", argv[1], 443);
        if(w3 != NULL) {
                W3_Set_Read_Size(w3, 1024);
                W3_Set_Method(w3, argv[3] == NULL ? "GET" : argv[3]);
index 75e0b1952633e6ddded8aa8638ede9e9649f8203..336bcf0191fee0925d149996bf4e24b9f01dd86f 100644 (file)
@@ -64,6 +64,13 @@ void __W3_HTTP_Request(struct W3* w3) {
        char* headerbuf = malloc(1);
        headerbuf[0] = 0;
        int phase = 0;
+       bool chunked = false;
+       int chunkphase = 0;
+       char* chunklen = NULL;
+       int chunkincr = 0;
+       char* chunk = NULL;
+       bool breakchunk = false;
+       int chunksize;
        while(true) {
                int l = __W3_Auto_Read(w3, buf, w3->readsize);
                if(l <= 0) break;
@@ -138,6 +145,9 @@ void __W3_HTTP_Request(struct W3* w3) {
                                                                                                void (*func)(struct W3*, char*, char*) = (void (*)(struct W3*, char*, char*))funcptr;
                                                                                                func(w3, data, data + k + 1);
                                                                                        }
+                                                                                       if(strcasecmp(data, "transfer-encoding") == 0 && strcasecmp(data + k + 1, "chunked") == 0) {
+                                                                                               chunked = true;
+                                                                                       }
                                                                                }
                                                                                break;
                                                                        }
@@ -157,19 +167,75 @@ void __W3_HTTP_Request(struct W3* w3) {
                                        }
                                }
                        } else if(phase == 2) {
-                               void* funcptr = __W3_Get_Event(w3, "data");
-                               if(funcptr != NULL) {
-                                       void (*func)(struct W3*, char*, size_t) = (void (*)(struct W3*, char*, size_t))funcptr;
-                                       char* buffer = malloc(l - i);
-                                       memcpy(buffer, buf + i, l - i);
-                                       func(w3, buffer, l - i);
-                                       free(buffer);
+                               if(chunked) {
+                                       int j;
+                                       for(j = i; j < l; j++) {
+                                               char c = buf[j];
+                                               if(chunkphase == 0) {
+                                                       if(c == '\n') {
+                                                               if(chunklen != NULL) {
+                                                                       chunkphase = 1;
+                                                                       chunkincr = strtol(chunklen, NULL, 16);
+                                                                       free(chunklen);
+                                                                       chunklen = NULL;
+                                                                       if(chunkincr == 0) {
+                                                                               breakchunk = true;
+                                                                               break;
+                                                                       } else {
+                                                                               chunk = malloc(chunkincr);
+                                                                               chunksize = chunkincr;
+                                                                       }
+                                                               }
+                                                               continue;
+                                                       } else if(c == '\r')
+                                                               continue;
+                                                       if(chunklen == NULL) {
+                                                               chunklen = malloc(1);
+                                                               chunklen[0] = 0;
+                                                       }
+                                                       char* cbuf = malloc(2);
+                                                       cbuf[0] = c;
+                                                       cbuf[1] = 0;
+                                                       char* tmp = chunklen;
+                                                       chunklen = __W3_Concat(tmp, cbuf);
+                                                       free(tmp);
+                                                       free(cbuf);
+                                               } else if(chunkphase == 1) {
+                                                       chunkincr--;
+                                                       if(chunkincr >= 0) {
+                                                               chunk[chunksize - chunkincr - 1] = c;
+                                                       }
+                                                       if(chunkincr == -2) {
+                                                               chunkphase = 0;
+                                                               free(chunk);
+                                                               chunk = NULL;
+                                                       } else if(chunkincr == 0) {
+                                                               void* funcptr = __W3_Get_Event(w3, "data");
+                                                               if(funcptr != NULL) {
+                                                                       void (*func)(struct W3*, char*, size_t) = (void (*)(struct W3*, char*, size_t))funcptr;
+                                                                       func(w3, chunk, chunksize);
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               } else {
+                                       void* funcptr = __W3_Get_Event(w3, "data");
+                                       if(funcptr != NULL) {
+                                               void (*func)(struct W3*, char*, size_t) = (void (*)(struct W3*, char*, size_t))funcptr;
+                                               char* buffer = malloc(l - i);
+                                               memcpy(buffer, buf + i, l - i);
+                                               func(w3, buffer, l - i);
+                                               free(buffer);
+                                       }
                                }
                                break;
                        }
                }
+               if(breakchunk) break;
        }
        free(headerbuf);
        free(statusbuf);
        free(buf);
+       if(chunklen != NULL) free(chunklen);
+       if(chunk != NULL) free(chunk);
 }
index 9bb9cdbcf1b059078b746bdfbbf968313e8f3cd7..1146e87f38b58b525fdb2b87a16bfe326d9e26f3 100644 (file)
@@ -6,7 +6,7 @@
 extern "C" {
 #endif
 
-#define LIBW3_VERSION "1.2C" \
+#define LIBW3_VERSION "1.3" \
 SUFFIX
 
 #ifdef __cplusplus