mirror of
https://github.com/cesanta/mongoose.git
synced 2025-01-19 16:13:07 +08:00
Process chunked body before sending MG_EV_HTTP_MSG
This commit is contained in:
parent
2dcb10ef36
commit
e84ea91a4a
23
mongoose.c
23
mongoose.c
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2004-2013 Sergey Lyubka
|
||||
// Copyright (c) 2013-2020 Cesanta Software Limited
|
||||
// Copyright (c) 2013-2021 Cesanta Software Limited
|
||||
// All rights reserved
|
||||
//
|
||||
// This software is dual-licensed: you can redistribute it and/or modify
|
||||
@ -15,7 +15,6 @@
|
||||
// Alternatively, you can license this software under a commercial
|
||||
// license, as set out in <https://www.cesanta.com/license>.
|
||||
|
||||
|
||||
#include "mongoose.h"
|
||||
|
||||
#ifdef MG_ENABLE_LINES
|
||||
@ -1189,7 +1188,7 @@ static size_t get_chunk_length(const char *buf, size_t len, size_t *ll) {
|
||||
// an MG_EV_HTTP_CHUNK event.
|
||||
static void walkchunks(struct mg_connection *c, struct mg_http_message *hm,
|
||||
int reqlen) {
|
||||
size_t off = 0, ll;
|
||||
size_t off = 0, bl, ll;
|
||||
while (off < c->recv.len - reqlen) {
|
||||
char *buf = (char *) &c->recv.buf[reqlen];
|
||||
size_t memo = c->recv.len;
|
||||
@ -1201,10 +1200,22 @@ static void walkchunks(struct mg_connection *c, struct mg_http_message *hm,
|
||||
// Increase offset only if user has not deleted this chunk
|
||||
if (memo == c->recv.len) off += cl;
|
||||
if (cl <= 5) {
|
||||
// Zero chunk - last one. Set message length to indicate we've received
|
||||
// Zero chunk - last one. Prepare body - cut off chunk lengths
|
||||
off = bl = 0;
|
||||
while (off < c->recv.len - reqlen) {
|
||||
char *buf = (char *) &c->recv.buf[reqlen];
|
||||
size_t memo = c->recv.len;
|
||||
size_t cl = get_chunk_length(&buf[off], memo - reqlen - off, &ll);
|
||||
size_t n = cl < ll + 2 ? 0 : cl - ll - 2;
|
||||
if (cl <= 5) break;
|
||||
memmove(buf + bl, buf + off + ll, n);
|
||||
bl += n;
|
||||
off += cl;
|
||||
}
|
||||
// Set message length to indicate we've received
|
||||
// everything, to fire MG_EV_HTTP_MSG
|
||||
hm->message.len = off + reqlen;
|
||||
hm->body.len = off;
|
||||
hm->message.len = bl + reqlen;
|
||||
hm->body.len = bl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
20
src/http.c
20
src/http.c
@ -769,7 +769,7 @@ static size_t get_chunk_length(const char *buf, size_t len, size_t *ll) {
|
||||
// an MG_EV_HTTP_CHUNK event.
|
||||
static void walkchunks(struct mg_connection *c, struct mg_http_message *hm,
|
||||
int reqlen) {
|
||||
size_t off = 0, ll;
|
||||
size_t off = 0, bl, ll;
|
||||
while (off < c->recv.len - reqlen) {
|
||||
char *buf = (char *) &c->recv.buf[reqlen];
|
||||
size_t memo = c->recv.len;
|
||||
@ -781,10 +781,22 @@ static void walkchunks(struct mg_connection *c, struct mg_http_message *hm,
|
||||
// Increase offset only if user has not deleted this chunk
|
||||
if (memo == c->recv.len) off += cl;
|
||||
if (cl <= 5) {
|
||||
// Zero chunk - last one. Set message length to indicate we've received
|
||||
// Zero chunk - last one. Prepare body - cut off chunk lengths
|
||||
off = bl = 0;
|
||||
while (off < c->recv.len - reqlen) {
|
||||
char *buf = (char *) &c->recv.buf[reqlen];
|
||||
size_t memo = c->recv.len;
|
||||
size_t cl = get_chunk_length(&buf[off], memo - reqlen - off, &ll);
|
||||
size_t n = cl < ll + 2 ? 0 : cl - ll - 2;
|
||||
if (cl <= 5) break;
|
||||
memmove(buf + bl, buf + off + ll, n);
|
||||
bl += n;
|
||||
off += cl;
|
||||
}
|
||||
// Set message length to indicate we've received
|
||||
// everything, to fire MG_EV_HTTP_MSG
|
||||
hm->message.len = off + reqlen;
|
||||
hm->body.len = off;
|
||||
hm->message.len = bl + reqlen;
|
||||
hm->body.len = bl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1231,7 +1231,7 @@ static void eh5(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||
|
||||
static void test_http_chunked(void) {
|
||||
struct mg_mgr mgr;
|
||||
const char *url = "http://127.0.0.1:12344";
|
||||
const char *data, *url = "http://127.0.0.1:12344";
|
||||
uint32_t i, done = 0;
|
||||
mg_mgr_init(&mgr);
|
||||
mg_http_listen(&mgr, url, eh2, NULL);
|
||||
@ -1239,41 +1239,20 @@ static void test_http_chunked(void) {
|
||||
mg_http_connect(&mgr, url, eh3, &done);
|
||||
for (i = 0; i < 50 && done == 0; i++) mg_mgr_poll(&mgr, 1);
|
||||
ASSERT(i < 50);
|
||||
{
|
||||
const char *data =
|
||||
"7\r\nchunk 0\r\n"
|
||||
"7\r\nchunk 1\r\n"
|
||||
"7\r\nchunk 2\r\n"
|
||||
"0\r\n\r\n";
|
||||
ASSERT(done == mg_crc32(0, data, strlen(data)));
|
||||
}
|
||||
data = "chunk 0chunk 1chunk 2";
|
||||
ASSERT(done == mg_crc32(0, data, strlen(data)));
|
||||
|
||||
done = 0;
|
||||
mg_http_connect(&mgr, url, eh4, &done);
|
||||
for (i = 0; i < 50 && done == 0; i++) mg_mgr_poll(&mgr, 1);
|
||||
{
|
||||
const char *data =
|
||||
"chunk 0"
|
||||
"chunk 0"
|
||||
"chunk 1"
|
||||
"chunk 2"
|
||||
"7\r\nchunk 0\r\n"
|
||||
"7\r\nchunk 1\r\n"
|
||||
"7\r\nchunk 2\r\n"
|
||||
"0\r\n\r\n";
|
||||
ASSERT(done == mg_crc32(0, data, strlen(data)));
|
||||
}
|
||||
data = "chunk 0chunk 0chunk 1chunk 2chunk 0chunk 1chunk 2";
|
||||
ASSERT(done == mg_crc32(0, data, strlen(data)));
|
||||
|
||||
done = 0;
|
||||
mg_http_connect(&mgr, url, eh5, &done);
|
||||
for (i = 0; i < 50 && done == 0; i++) mg_mgr_poll(&mgr, 1);
|
||||
{
|
||||
const char *data =
|
||||
"chunk 0"
|
||||
"chunk 1"
|
||||
"chunk 2";
|
||||
ASSERT(done == mg_crc32(0, data, strlen(data)));
|
||||
}
|
||||
data = "chunk 0chunk 1chunk 2";
|
||||
ASSERT(done == mg_crc32(0, data, strlen(data)));
|
||||
|
||||
mg_mgr_free(&mgr);
|
||||
ASSERT(mgr.conns == NULL);
|
||||
|
Loading…
Reference in New Issue
Block a user