瀏覽代碼

Merge pull request #34 from jawi/master

Make content length available in request_info
bel2125 11 年之前
父節點
當前提交
59833c4842
共有 3 個文件被更改,包括 39 次插入3 次删除
  1. 2 0
      include/civetweb.h
  2. 3 0
      src/civetweb.c
  3. 34 3
      test/unit_test.c

+ 2 - 0
include/civetweb.h

@@ -62,6 +62,8 @@ struct mg_request_info {
     const char *remote_user;    /* Authenticated user, or NULL if no auth
                                    used */
     long remote_ip;             /* Client's IP address */
+    long long content_length;   /* Length (in bytes) of the request body,
+                                   can be -1 if no length was given. */
     int remote_port;            /* Client's port */
     int is_ssl;                 /* 1 if SSL-ed, 0 if not */
     void *user_data;            /* User data pointer passed to mg_start() */

+ 3 - 0
src/civetweb.c

@@ -6232,6 +6232,7 @@ static void reset_per_request_attributes(struct mg_connection *conn)
     conn->num_bytes_sent = conn->consumed_content = 0;
     conn->status_code = -1;
     conn->must_close = conn->request_len = conn->throttle = 0;
+    conn->request_info.content_length = -1;
 }
 
 static void close_socket_gracefully(struct mg_connection *conn)
@@ -6394,6 +6395,8 @@ static int getreq(struct mg_connection *conn, char *ebuf, size_t ebuf_len)
         if ((cl = get_header(&conn->request_info, "Content-Length")) != NULL) {
             /* Request/response has content length set */
             conn->content_len = strtoll(cl, NULL, 10);
+            /* Publish the content length back to the request info. */
+            conn->request_info.content_length = conn->content_len;
         } else if (!mg_strcasecmp(conn->request_info.request_method, "POST") ||
                    !mg_strcasecmp(conn->request_info.request_method, "PUT")) {
             /* POST or PUT request without content length set */

+ 34 - 3
test/unit_test.c

@@ -63,8 +63,8 @@ static int s_failed_tests = 0;
 #define HTTPS_PORT HTTP_PORT
 #define LISTENING_ADDR "127.0.0.1:" HTTP_PORT
 #else
-#define HTTPS_PORT "443"
-#define LISTENING_ADDR "127.0.0.1:" HTTP_PORT ",127.0.0.1:" HTTPS_PORT "s"
+#define HTTPS_PORT "8443"
+#define LISTENING_ADDR "127.0.0.1:" HTTP_PORT ",127.0.0.1:" HTTPS_PORT
 #endif
 
 static void test_parse_http_message() {
@@ -280,6 +280,15 @@ static int begin_request_handler_cb(struct mg_connection *conn) {
         return 1;
     }
 
+    if (!strcmp(ri->uri, "/content_length")) {
+        mg_printf(conn, "HTTP/1.1 200 OK\r\n"
+            "X-Content-Length: %d\r\n"
+            "Content-Type: text/plain\r\n\r\n"
+            "%s", ri->content_length, fetch_data);
+        close_connection(conn);
+        return 1;
+    }
+
     if (!strcmp(ri->uri, "/upload")) {
         ASSERT(ri->query_string != NULL);
         ASSERT(mg_upload(conn, ".") == atoi(ri->query_string));
@@ -338,7 +347,7 @@ static char *read_conn(struct mg_connection *conn, int *size) {
 }
 
 static void test_mg_download(int use_ssl) {
-    char *p1, *p2, ebuf[100];
+    char *p1, *p2, *h, ebuf[100];
     int len1, len2, port;
     struct mg_connection *conn;
     struct mg_context *ctx;
@@ -395,6 +404,28 @@ static void test_mg_download(int use_ssl) {
     mg_free(p1);
     mg_close_connection(conn);
 
+    /* Fetch in-memory data with Content-Length, should succeed and return the defined length. */
+    ASSERT((conn = mg_download("localhost", port, use_ssl, ebuf, sizeof(ebuf), "%s",
+        "GET /content_length HTTP/1.1\r\nContent-Length: 10\r\n\r\n0123456789")) != NULL);
+    ASSERT((h = mg_get_header(conn, "X-Content-Length")) != NULL);
+    ASSERT(strcmp(h, "10") == 0);
+    ASSERT((p1 = read_conn(conn, &len1)) != NULL);
+    ASSERT(len1 == (int) strlen(fetch_data));
+    ASSERT(memcmp(p1, fetch_data, len1) == 0);
+    mg_free(p1);
+    mg_close_connection(conn);
+
+    /* Fetch in-memory data without Content-Length, should succeed and return an undefined length. */
+    ASSERT((conn = mg_download("localhost", port, use_ssl, ebuf, sizeof(ebuf), "%s",
+        "GET /content_length HTTP/1.1\r\n\r\n0123456789")) != NULL);
+    ASSERT((h = mg_get_header(conn, "X-Content-Length")) != NULL);
+    ASSERT(strcmp(h, "-1") == 0);
+    ASSERT((p1 = read_conn(conn, &len1)) != NULL);
+    ASSERT(len1 == (int) strlen(fetch_data));
+    ASSERT(memcmp(p1, fetch_data, len1) == 0);
+    mg_free(p1);
+    mg_close_connection(conn);
+
     /* Test SSL redirect, IP address */
     /* TODO(bel):
     ASSERT((conn = mg_download("localhost", atoi(HTTP_PORT), 0,