浏览代码

Complete chunked transfer encoding

Remove commented rest of merge #95
bel2125 10 年之前
父节点
当前提交
a5fbd4e199
共有 1 个文件被更改,包括 39 次插入57 次删除
  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 num_bytes_sent;         /* Total bytes sent to client */
     int64_t content_len;            /* Content-Length header value */
     int64_t content_len;            /* Content-Length header value */
     int64_t consumed_content;       /* How many bytes of content have been read */
     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 */
     size_t chunk_remainder;         /* Unread data from the last chunk */
     char *buf;                      /* Buffer for received data */
     char *buf;                      /* Buffer for received data */
     char *path_info;                /* PATH_INFO part of the URL */
     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;
     return nread;
 }
 }
 
 
+
 static void discard_unread_request_data(struct mg_connection *conn)
 static void discard_unread_request_data(struct mg_connection *conn)
 {
 {
     char buf[MG_BUF_LEN];
     char buf[MG_BUF_LEN];
     int to_read, nread;
     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)
 int mg_read_inner(struct mg_connection *conn, void *buf, size_t len)
 {
 {
     int64_t n, buffered_len, nread;
     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;
     return (int)nread;
 }
 }
 
 
+
 static char mg_getc(struct mg_connection *conn)
 static char mg_getc(struct mg_connection *conn)
 {
 {
     char c;
     char c;
@@ -2661,8 +2680,11 @@ static char mg_getc(struct mg_connection *conn)
     return c;
     return c;
 }
 }
 
 
+
 int mg_read(struct mg_connection *conn, void *buf, size_t len)
 int mg_read(struct mg_connection *conn, void *buf, size_t len)
 {
 {
+    if (len>INT_MAX) len=INT_MAX;
+
     if (conn->is_chunked)
     if (conn->is_chunked)
     {
     {
         size_t all_read = 0;
         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) {
             if (conn->chunk_remainder) {
                 /* copy from the remainder of the last received chunk */
                 /* 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;
                 conn->content_len += read_now;
                 read_ret = mg_read_inner(conn, (char*)buf+all_read, 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;
                 conn->chunk_remainder = chunkSize;
                 if (chunkSize == 0) {
                 if (chunkSize == 0) {
                     /* regular end of content */
                     /* regular end of content */
+                    conn->is_chunked = 2;
                     break;
                     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);
     return mg_read_inner(conn,buf,len);
 }
 }
@@ -6560,7 +6538,7 @@ static int get_request_handler(struct mg_connection *conn,
     return 0; /* none found */
     return 0; /* none found */
 }
 }
 
 
-
+#if defined(USE_WEBSOCKET)
 static int deprecated_websocket_connect_wrapper(const struct mg_connection * conn, void *cbdata)
 static int deprecated_websocket_connect_wrapper(const struct mg_connection * conn, void *cbdata)
 {
 {
     struct mg_callbacks *pcallbacks = (struct mg_callbacks*)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" */
     /* No handler set - assume "OK" */
     return 1;
     return 1;
 }
 }
+#endif
 
 
 /* This is the heart of the Civetweb's logic.
 /* This is the heart of the Civetweb's logic.
    This function is called when the request is read, parsed and validated,
    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)));
     dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
     dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
     dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
     dwBuild = ((dwVersion < 0x80000000) ? (DWORD)(HIWORD(dwVersion)) : 0);
     dwBuild = ((dwVersion < 0x80000000) ? (DWORD)(HIWORD(dwVersion)) : 0);
+    (void)dwBuild;
 
 
     sprintf(name, "Windows %u.%u", (unsigned)dwMajorVersion, (unsigned)dwMinorVersion);
     sprintf(name, "Windows %u.%u", (unsigned)dwMajorVersion, (unsigned)dwMinorVersion);
     *sysName = mg_strdup(name);
     *sysName = mg_strdup(name);
@@ -8365,7 +8345,9 @@ struct mg_context *mg_start(const struct mg_callbacks *callbacks,
 #if defined(_WIN32) && !defined(__SYMBIAN32__)
 #if defined(_WIN32) && !defined(__SYMBIAN32__)
     WSADATA data;
     WSADATA data;
     WSAStartup(MAKEWORD(2,2), &data);
     WSAStartup(MAKEWORD(2,2), &data);
+#ifdef _MSC_VER
 #pragma warning(suppress: 28125)
 #pragma warning(suppress: 28125)
+#endif
     if (!sTlsInit) InitializeCriticalSection(&global_log_file_lock);
     if (!sTlsInit) InitializeCriticalSection(&global_log_file_lock);
 #endif /* _WIN32 && !__SYMBIAN32__ */
 #endif /* _WIN32 && !__SYMBIAN32__ */