Quellcode durchsuchen

fix: httpsrv,当请求的数据长度大于mtu,出现分包时,会出现数据处理非常慢的情况

https://gitee.com/openLuat/LuatOS/issues/ID23GD
Wendal Chen vor 5 Monaten
Ursprung
Commit
2a5d19cf7f
1 geänderte Dateien mit 39 neuen und 17 gelöschten Zeilen
  1. 39 17
      components/network/httpsrv/src/luat_httpsrv_lwip.c

+ 39 - 17
components/network/httpsrv/src/luat_httpsrv_lwip.c

@@ -32,6 +32,8 @@ typedef struct client_socket_ctx
     char *body;
 
     size_t body_size;
+    size_t expect_body_size;
+    int next_header_value_is_content_length;
     uint32_t recv_done;
     char *buff;
     size_t buff_offset;
@@ -58,8 +60,8 @@ static int my_on_message_complete(http_parser* parser);
 // static int my_on_chunk_complete(http_parser* parser);
 static int my_on_url(http_parser* parser, const char *at, size_t length);
 // static int my_on_status(http_parser* parser, const char *at, size_t length);
-// static int my_on_header_field(http_parser* parser, const char *at, size_t length);
-// static int my_on_header_value(http_parser* parser, const char *at, size_t length);
+static int my_on_header_field(http_parser* parser, const char *at, size_t length);
+static int my_on_header_value(http_parser* parser, const char *at, size_t length);
 static int my_on_body(http_parser* parser, const char *at, size_t length);
 
 //================================
@@ -69,8 +71,8 @@ static const struct http_parser_settings hp_settings = {
     // .on_message_begin = my_on_message_begin,
     .on_url = my_on_url,
     // .on_status = my_on_status,
-    // .on_header_field = my_on_header_field,
-    // .on_header_value = my_on_header_value,
+    .on_header_field = my_on_header_field,
+    .on_header_value = my_on_header_value,
     // .on_headers_complete = my_on_headers_complete,
     .on_body = my_on_body,
     .on_message_complete = my_on_message_complete,
@@ -170,10 +172,9 @@ static void client_resp(void* arg) {
         LLOGD("send body %d", body_size);
         client_write(client, client->body, body_size);
     }
-    // client_cleanup(client);
-    // tcp_output(pcb);
-    // tcp_close(pcb);
     client->write_done = 1;
+    LLOGD("resp done, total send %d", client->send_size);
+    tcp_output(client->pcb);
 }
 
 //================================
@@ -405,11 +406,12 @@ static err_t client_sent_cb(void *arg, struct tcp_pcb *tpcb, u16_t len) {
     return ERR_OK;
 }
 static void client_err_cb(void *arg, err_t err) {
-    LLOGD("client cb %d", err);
+    LLOGD("client_err_cb %d", err);
     client_socket_ctx_t* client = (client_socket_ctx_t*)arg;
     if(ERR_RST == err)
     {
         tcp_err(client->pcb, NULL);
+        tcp_sent(client->pcb, NULL);
     }
     client_cleanup(client);
 }
@@ -632,6 +634,10 @@ static int handle_static_file(client_socket_ctx_t *client) {
 static int my_on_message_complete(http_parser* parser) {
     LLOGD("on_message_complete");
     client_socket_ctx_t* client = (client_socket_ctx_t*)parser->data;
+    if (client->expect_body_size > 0 && client->body_size < client->expect_body_size) {
+        LLOGD("body size not match expect %d/%d", client->body_size, client->expect_body_size);
+        return HPE_INVALID_CONTENT_LENGTH;
+    }
     client->recv_done = 1;
     return 0;
 }
@@ -671,23 +677,39 @@ static int my_on_url(http_parser* parser, const char *at, size_t length) {
 //     return 0;
 // }
 
-// static int my_on_header_field(http_parser* parser, const char *at, size_t length) {
-//     // LLOGD("on_header_field %p %d", at, length);
-//     return 0;
-// }
+static int my_on_header_field(http_parser* parser, const char *at, size_t length) {
+    // LLOGI("on_header_field %.*s", (int)length, at);
+    if (length == 14 && !memcmp(at, "Content-Length", 14)) {
+        client_socket_ctx_t* client = (client_socket_ctx_t*)parser->data;
+        client->next_header_value_is_content_length = 1;
+    }
+    else {
+        client_socket_ctx_t* client = (client_socket_ctx_t*)parser->data;
+        client->next_header_value_is_content_length = 0;
+    }
+    return 0;
+}
 
-// static int my_on_header_value(http_parser* parser, const char *at, size_t length) {
-//     // LLOGD("on_header_value %p %d", at, length);
-//     return 0;
-// }
+static int my_on_header_value(http_parser* parser, const char *at, size_t length) {
+    // LLOGI("on_header_value %.*s", (int)length, at);
+    client_socket_ctx_t* client = (client_socket_ctx_t*)parser->data;
+    if (client->next_header_value_is_content_length) {
+        client->expect_body_size = atoi(at);
+        client->next_header_value_is_content_length = 0;
+    }
+    return 0;
+}
 
 static int my_on_body(http_parser* parser, const char *at, size_t length) {
     LLOGD("on_body %p %d", at, length);
     if (length == 0)
         return 0;
     client_socket_ctx_t* client = (client_socket_ctx_t*)parser->data;
+    if (client->expect_body_size > 0 && length < client->expect_body_size) {
+        return 0; // 等数据
+    }
     if (client->body == NULL) {
-        client->body = luat_heap_malloc(length);
+        client->body = luat_heap_malloc(client->expect_body_size > 0 ? client->expect_body_size : length);
         //client->body_size = length;
         if (client->body == NULL) {
             LLOGE("malloc body FAIL!!!");