mirror of
https://github.com/cesanta/mongoose.git
synced 2024-12-31 01:13:01 +08:00
Fix for deliver_normal_chunks() and a test case
This commit is contained in:
parent
c459c17fab
commit
740b609e1e
@ -2321,7 +2321,7 @@ static void deliver_chunked_chunks(struct mg_connection *c, size_t hlen,
|
|||||||
static void deliver_normal_chunks(struct mg_connection *c, size_t hlen,
|
static void deliver_normal_chunks(struct mg_connection *c, size_t hlen,
|
||||||
struct mg_http_message *hm, bool *next) {
|
struct mg_http_message *hm, bool *next) {
|
||||||
size_t left, processed = ((size_t) c->pfn_data) & ~MG_DMARK;
|
size_t left, processed = ((size_t) c->pfn_data) & ~MG_DMARK;
|
||||||
bool deleted = ((size_t) c->pfn_data) & MG_DMARK;
|
size_t deleted = ((size_t) c->pfn_data) & MG_DMARK;
|
||||||
hm->chunk = mg_str_n((char *) &c->recv.buf[hlen], c->recv.len - hlen);
|
hm->chunk = mg_str_n((char *) &c->recv.buf[hlen], c->recv.len - hlen);
|
||||||
if (processed <= hm->chunk.len && !deleted) {
|
if (processed <= hm->chunk.len && !deleted) {
|
||||||
hm->chunk.len -= processed;
|
hm->chunk.len -= processed;
|
||||||
@ -2331,14 +2331,14 @@ static void deliver_normal_chunks(struct mg_connection *c, size_t hlen,
|
|||||||
if (hm->chunk.len > left) hm->chunk.len = left;
|
if (hm->chunk.len > left) hm->chunk.len = left;
|
||||||
if (hm->chunk.len > 0) mg_call(c, MG_EV_HTTP_CHUNK, hm);
|
if (hm->chunk.len > 0) mg_call(c, MG_EV_HTTP_CHUNK, hm);
|
||||||
processed += hm->chunk.len;
|
processed += hm->chunk.len;
|
||||||
|
deleted = ((size_t) c->pfn_data) & MG_DMARK; // Re-evaluate after user call
|
||||||
if (processed >= hm->body.len) { // Last, 0-len chunk
|
if (processed >= hm->body.len) { // Last, 0-len chunk
|
||||||
hm->chunk.len = 0; // Reset length
|
hm->chunk.len = 0; // Reset length
|
||||||
mg_call(c, MG_EV_HTTP_CHUNK, hm); // Call user handler
|
mg_call(c, MG_EV_HTTP_CHUNK, hm); // Call user handler
|
||||||
c->pfn_data = NULL; // Reset processed counter
|
c->pfn_data = NULL; // Reset processed counter
|
||||||
if (processed && deleted) mg_iobuf_del(&c->recv, 0, hlen), *next = true;
|
if (processed && deleted) mg_iobuf_del(&c->recv, 0, hlen), *next = true;
|
||||||
} else {
|
} else {
|
||||||
size_t del = ((size_t) c->pfn_data) & MG_DMARK; // Keep deletion marker
|
c->pfn_data = (void *) (processed | deleted); // if it is set
|
||||||
c->pfn_data = (void *) (processed | del); // if it is set
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -899,7 +899,7 @@ static void deliver_chunked_chunks(struct mg_connection *c, size_t hlen,
|
|||||||
static void deliver_normal_chunks(struct mg_connection *c, size_t hlen,
|
static void deliver_normal_chunks(struct mg_connection *c, size_t hlen,
|
||||||
struct mg_http_message *hm, bool *next) {
|
struct mg_http_message *hm, bool *next) {
|
||||||
size_t left, processed = ((size_t) c->pfn_data) & ~MG_DMARK;
|
size_t left, processed = ((size_t) c->pfn_data) & ~MG_DMARK;
|
||||||
bool deleted = ((size_t) c->pfn_data) & MG_DMARK;
|
size_t deleted = ((size_t) c->pfn_data) & MG_DMARK;
|
||||||
hm->chunk = mg_str_n((char *) &c->recv.buf[hlen], c->recv.len - hlen);
|
hm->chunk = mg_str_n((char *) &c->recv.buf[hlen], c->recv.len - hlen);
|
||||||
if (processed <= hm->chunk.len && !deleted) {
|
if (processed <= hm->chunk.len && !deleted) {
|
||||||
hm->chunk.len -= processed;
|
hm->chunk.len -= processed;
|
||||||
@ -909,14 +909,14 @@ static void deliver_normal_chunks(struct mg_connection *c, size_t hlen,
|
|||||||
if (hm->chunk.len > left) hm->chunk.len = left;
|
if (hm->chunk.len > left) hm->chunk.len = left;
|
||||||
if (hm->chunk.len > 0) mg_call(c, MG_EV_HTTP_CHUNK, hm);
|
if (hm->chunk.len > 0) mg_call(c, MG_EV_HTTP_CHUNK, hm);
|
||||||
processed += hm->chunk.len;
|
processed += hm->chunk.len;
|
||||||
|
deleted = ((size_t) c->pfn_data) & MG_DMARK; // Re-evaluate after user call
|
||||||
if (processed >= hm->body.len) { // Last, 0-len chunk
|
if (processed >= hm->body.len) { // Last, 0-len chunk
|
||||||
hm->chunk.len = 0; // Reset length
|
hm->chunk.len = 0; // Reset length
|
||||||
mg_call(c, MG_EV_HTTP_CHUNK, hm); // Call user handler
|
mg_call(c, MG_EV_HTTP_CHUNK, hm); // Call user handler
|
||||||
c->pfn_data = NULL; // Reset processed counter
|
c->pfn_data = NULL; // Reset processed counter
|
||||||
if (processed && deleted) mg_iobuf_del(&c->recv, 0, hlen), *next = true;
|
if (processed && deleted) mg_iobuf_del(&c->recv, 0, hlen), *next = true;
|
||||||
} else {
|
} else {
|
||||||
size_t del = ((size_t) c->pfn_data) & MG_DMARK; // Keep deletion marker
|
c->pfn_data = (void *) (processed | deleted); // if it is set
|
||||||
c->pfn_data = (void *) (processed | del); // if it is set
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1909,6 +1909,13 @@ static void eY(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|||||||
(void) ev_data, (void) fn_data;
|
(void) ev_data, (void) fn_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void eZ(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||||
|
if (ev == MG_EV_HTTP_MSG) {
|
||||||
|
mg_http_reply(c, 200, "", "abcd");
|
||||||
|
}
|
||||||
|
(void) ev_data, (void) fn_data;
|
||||||
|
}
|
||||||
|
|
||||||
// Do not delete chunks as they arrive
|
// Do not delete chunks as they arrive
|
||||||
static void eh4(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
static void eh4(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||||
uint32_t *crc = (uint32_t *) fn_data;
|
uint32_t *crc = (uint32_t *) fn_data;
|
||||||
@ -1962,9 +1969,13 @@ static void test_http_chunked_case(mg_event_handler_t s, mg_event_handler_t c,
|
|||||||
static void test_http_chunked(void) {
|
static void test_http_chunked(void) {
|
||||||
// Non-chunked encoding
|
// Non-chunked encoding
|
||||||
test_http_chunked_case(eY, eh4, 1, "axbcxdxxabcd"); // Chunks not deleted
|
test_http_chunked_case(eY, eh4, 1, "axbcxdxxabcd"); // Chunks not deleted
|
||||||
test_http_chunked_case(eY, eh5, 1, "axbcxdxx"); // Chunks deleted
|
|
||||||
test_http_chunked_case(eY, eh4, 2, "axbcxdxxabcdaxbcxdxxabcd");
|
test_http_chunked_case(eY, eh4, 2, "axbcxdxxabcdaxbcxdxxabcd");
|
||||||
|
test_http_chunked_case(eY, eh5, 1, "axbcxdxx"); // Chunks deleted
|
||||||
test_http_chunked_case(eY, eh5, 2, "axbcxdxxaxbcxdxx");
|
test_http_chunked_case(eY, eh5, 2, "axbcxdxxaxbcxdxx");
|
||||||
|
test_http_chunked_case(eZ, eh4, 1, "abcdxxabcd"); // Not deleted
|
||||||
|
test_http_chunked_case(eZ, eh4, 2, "abcdxxabcdabcdxxabcd");
|
||||||
|
test_http_chunked_case(eZ, eh5, 1, "abcdxx"); // Deleted
|
||||||
|
test_http_chunked_case(eZ, eh5, 2, "abcdxxabcdxx");
|
||||||
|
|
||||||
// Chunked encoding
|
// Chunked encoding
|
||||||
test_http_chunked_case(eX, eh4, 1, "axbxcxdxxabcd"); // Chunks not deleted
|
test_http_chunked_case(eX, eh4, 1, "axbxcxdxxabcd"); // Chunks not deleted
|
||||||
|
Loading…
x
Reference in New Issue
Block a user