Browse Source

Complete chunked transfer encoding

Remove commented rest of merge #95
bel2125 10 years ago
parent
commit
a5fbd4e199
1 changed files with 39 additions and 57 deletions
  1. 39 57
      src/civetweb.c

+ 39 - 57
src/civetweb.c

@@ -897,7 +897,7 @@ struct mg_connection {
     int64_t num_bytes_sent;         /* Total bytes sent to client */
     int64_t content_len;            /* Content-Length header value */
     int64_t consumed_content;       /* How many bytes of content have been read */
-    int is_chunked;                 /* Transfer-encoding is chunked */
+    int is_chunked;                 /* Transfer-encoding is chunked: 0=no, 1=yes: data available, 2: all data read */
     size_t chunk_remainder;         /* Unread data from the last chunk */
     char *buf;                      /* Buffer for received data */
     char *path_info;                /* PATH_INFO part of the URL */
@@ -2587,24 +2587,42 @@ static int pull_all(FILE *fp, struct mg_connection *conn, char *buf, int len)
     return nread;
 }
 
+
 static void discard_unread_request_data(struct mg_connection *conn)
 {
     char buf[MG_BUF_LEN];
     int to_read, nread;
 
-    while (conn->consumed_content < conn->content_len) {
-        to_read = sizeof(buf);
-        if ((int64_t) to_read > conn->content_len - conn->consumed_content) {
-            to_read = (int) (conn->content_len - conn->consumed_content);
+    to_read = sizeof(buf);
+
+    if (conn->is_chunked) {
+
+        /* Chunked encoding: 1=chunk not read completely, 2=chunk read completely */
+        while (conn->is_chunked == 1) {
+            nread = mg_read(conn, buf, to_read);
+            if (nread <= 0) {
+                break;
+            }
         }
 
-        nread = mg_read(conn, buf, to_read);
-        if (nread <= 0) {
-            break;
+    } else {
+
+        /* Not chunked: content length is known */
+        while (conn->consumed_content < conn->content_len) {
+
+            if ((int64_t) to_read > (conn->content_len - conn->consumed_content)) {
+                to_read = (int) (conn->content_len - conn->consumed_content);
+            }
+
+            nread = mg_read(conn, buf, to_read);
+            if (nread <= 0) {
+                break;
+            }
         }
     }
 }
 
+
 int mg_read_inner(struct mg_connection *conn, void *buf, size_t len)
 {
     int64_t n, buffered_len, nread;
@@ -2650,6 +2668,7 @@ int mg_read_inner(struct mg_connection *conn, void *buf, size_t len)
     return (int)nread;
 }
 
+
 static char mg_getc(struct mg_connection *conn)
 {
     char c;
@@ -2661,8 +2680,11 @@ static char mg_getc(struct mg_connection *conn)
     return c;
 }
 
+
 int mg_read(struct mg_connection *conn, void *buf, size_t len)
 {
+    if (len>INT_MAX) len=INT_MAX;
+
     if (conn->is_chunked)
     {
         size_t all_read = 0;
@@ -2670,8 +2692,8 @@ int mg_read(struct mg_connection *conn, void *buf, size_t len)
 
             if (conn->chunk_remainder) {
                 /* copy from the remainder of the last received chunk */
-                int read_ret;
-                int read_now = ((conn->chunk_remainder>len) ? (len) : (conn->chunk_remainder));
+                long read_ret;
+                int read_now = (int)((conn->chunk_remainder>len) ? (len) : (conn->chunk_remainder));
 
                 conn->content_len += read_now;
                 read_ret = mg_read_inner(conn, (char*)buf+all_read, read_now);
@@ -2716,57 +2738,13 @@ int mg_read(struct mg_connection *conn, void *buf, size_t len)
                 conn->chunk_remainder = chunkSize;
                 if (chunkSize == 0) {
                     /* regular end of content */
+                    conn->is_chunked = 2;
                     break;
                 }
             }
         }
 
-        return all_read;
-
-        /* TODO: chunked transfer encoding (#95) is currently not working. See #98. */
-        /*
-        if (conn->content_len <= 0)
-        {
-            conn->content_len = 0;
-        }
-        if (conn->consumed_content < conn->content_len)
-        {
-            return mg_read_inner(conn, buf,len);
-        }
-
-        while (1)
-        {
-            int c = mg_getc(conn);
-            if (!(c == '\n' || c == '\r'))
-            {
-                buf[i++] = c;
-                break;
-            }
-        }
-        for (; i < (int)sizeof(buf); i++)
-        {
-            int c = mg_getc(conn);
-            if ( c == EOF )
-            {
-                return -1;
-            }
-            buf[i] = (char) c;
-            if (buf[i] == '\n' && buf[i-1] == '\r')
-            {
-                break;
-            }
-        }
-
-        if (end != buf+(i-1))
-        {
-            return -1;
-        }
-        if (chunkSize == 0)
-        {
-            return 0;
-        }
-        conn->content_len += chunkSize;
-        */
+        return (int)all_read;
     }
     return mg_read_inner(conn,buf,len);
 }
@@ -6560,7 +6538,7 @@ static int get_request_handler(struct mg_connection *conn,
     return 0; /* none found */
 }
 
-
+#if defined(USE_WEBSOCKET)
 static int deprecated_websocket_connect_wrapper(const struct mg_connection * conn, void *cbdata)
 {
     struct mg_callbacks *pcallbacks = (struct mg_callbacks*)cbdata;
@@ -6588,6 +6566,7 @@ static int deprecated_websocket_data_wrapper(const struct mg_connection * conn,
     /* No handler set - assume "OK" */
     return 1;
 }
+#endif
 
 /* This is the heart of the Civetweb's logic.
    This function is called when the request is read, parsed and validated,
@@ -8338,6 +8317,7 @@ static void get_system_name(char **sysName)
     dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
     dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
     dwBuild = ((dwVersion < 0x80000000) ? (DWORD)(HIWORD(dwVersion)) : 0);
+    (void)dwBuild;
 
     sprintf(name, "Windows %u.%u", (unsigned)dwMajorVersion, (unsigned)dwMinorVersion);
     *sysName = mg_strdup(name);
@@ -8365,7 +8345,9 @@ struct mg_context *mg_start(const struct mg_callbacks *callbacks,
 #if defined(_WIN32) && !defined(__SYMBIAN32__)
     WSADATA data;
     WSAStartup(MAKEWORD(2,2), &data);
+#ifdef _MSC_VER
 #pragma warning(suppress: 28125)
+#endif
     if (!sTlsInit) InitializeCriticalSection(&global_log_file_lock);
 #endif /* _WIN32 && !__SYMBIAN32__ */