Commit 5c9f463c authored by Deomid Ryabkov's avatar Deomid Ryabkov Committed by Cesanta Bot

Add MG_EV_HTTP_MULTIPART_REQUEST_END

This event is sent at the end of the request

PUBLISHED_FROM=0b841a26320e3edbf73126e2ed8d286d4e5f3fa8
parent 3a8f47be
...@@ -12,11 +12,6 @@ The user-defined event handler will receive following extra events: ...@@ -12,11 +12,6 @@ The user-defined event handler will receive following extra events:
- MG_EV_HTTP_REQUEST: HTTP request has arrived. Parsed HTTP request - MG_EV_HTTP_REQUEST: HTTP request has arrived. Parsed HTTP request
is passed as is passed as
`struct http_message` through the handler's `void *ev_data` pointer. `struct http_message` through the handler's `void *ev_data` pointer.
- MG_EV_HTTP_MULTIPART_REQUEST: A multipart POST request has received.
This event is sent before body is parsed. After this, the user
should expect a sequence of MG_EV_HTTP_PART_BEGIN/DATA/END requests.
This is also the last time when headers and other request fields are
accessible.
- MG_EV_HTTP_REPLY: The HTTP reply has arrived. The parsed HTTP reply is - MG_EV_HTTP_REPLY: The HTTP reply has arrived. The parsed HTTP reply is
passed as `struct http_message` through the handler's `void *ev_data` passed as `struct http_message` through the handler's `void *ev_data`
pointer. pointer.
...@@ -38,14 +33,27 @@ The user-defined event handler will receive following extra events: ...@@ -38,14 +33,27 @@ The user-defined event handler will receive following extra events:
handshake. `ev_data` is `NULL`. handshake. `ev_data` is `NULL`.
- MG_EV_WEBSOCKET_FRAME: new WebSocket frame has arrived. `ev_data` is - MG_EV_WEBSOCKET_FRAME: new WebSocket frame has arrived. `ev_data` is
`struct websocket_message *` `struct websocket_message *`
- MG_EV_HTTP_PART_BEGIN: new part of multipart message is started,
extra parameters are passed in mg_http_multipart_part When compiled with MG_ENABLE_HTTP_STREAMING_MULTIPART, Mongoose parses
- MG_EV_HTTP_PART_DATA: new portion of data from the multiparted message multipart requests and splits them into separate events:
no additional headers are available, only data and data size - MG_EV_HTTP_MULTIPART_REQUEST: Start of the request.
- MG_EV_HTTP_PART_END: final boundary received, analogue to maybe used to This event is sent before body is parsed. After this, the user
find the end of packet should expect a sequence of PART_BEGIN/DATA/END requests.
Note: Mongoose should be compiled with MG_ENABLE_HTTP_STREAMING_MULTIPART This is also the last time when headers and other request fields are
to enable MG_EV_HTTP_MULTIPART_REQUEST, MG_EV_HTTP_REQUEST_END, accessible.
MG_EV_HTTP_REQUEST_CANCEL, MG_EV_HTTP_PART_BEGIN, MG_EV_HTTP_PART_DATA, - MG_EV_HTTP_PART_BEGIN: Start of a part of a multipart message.
MG_EV_HTTP_PART_END constants Argument: mg_http_multipart_part with var_name and file_name set
(if present). No data is passed in this message.
- MG_EV_HTTP_PART_DATA: new portion of data from the multipart message.
Argument: mg_http_multipart_part. var_name and file_name are preserved,
data is available in mg_http_multipart_part.data.
- MG_EV_HTTP_PART_END: End of the current part. var_name, file_name are
the same, no data in the message. If status is 0, then the part is
properly terminated with a boundary, status < 0 means that connection
was terminated.
- MG_EV_HTTP_MULTIPART_REQUEST_END: End of the multipart request.
Argument: mg_http_multipart_part, var_name and file_name are NULL,
status = 0 means request was properly closed, < 0 means connection
was terminated (note: in this case both PART_END and REQUEST_END are
delivered).
...@@ -4506,17 +4506,20 @@ void mg_http_handler(struct mg_connection *nc, int ev, void *ev_data) { ...@@ -4506,17 +4506,20 @@ void mg_http_handler(struct mg_connection *nc, int ev, void *ev_data) {
#if MG_ENABLE_HTTP_STREAMING_MULTIPART #if MG_ENABLE_HTTP_STREAMING_MULTIPART
if (pd->mp_stream.boundary != NULL) { if (pd->mp_stream.boundary != NULL) {
/* /*
* Multipart message is in progress, but we get close * Multipart message is in progress, but connection is closed.
* MG_EV_HTTP_PART_END with error flag * Finish part and request with an error flag.
*/ */
struct mg_http_multipart_part mp; struct mg_http_multipart_part mp;
memset(&mp, 0, sizeof(mp)); memset(&mp, 0, sizeof(mp));
mp.status = -1; mp.status = -1;
mp.var_name = pd->mp_stream.var_name; mp.var_name = pd->mp_stream.var_name;
mp.file_name = pd->mp_stream.file_name; mp.file_name = pd->mp_stream.file_name;
mg_call(nc, (pd->endpoint_handler ? pd->endpoint_handler : nc->handler), mg_call(nc, (pd->endpoint_handler ? pd->endpoint_handler : nc->handler),
MG_EV_HTTP_PART_END, &mp); MG_EV_HTTP_PART_END, &mp);
mp.var_name = NULL;
mp.file_name = NULL;
mg_call(nc, (pd->endpoint_handler ? pd->endpoint_handler : nc->handler),
MG_EV_HTTP_MULTIPART_REQUEST_END, &mp);
} else } else
#endif #endif
if (io->len > 0 && mg_parse_http(io->buf, io->len, hm, is_req) > 0) { if (io->len > 0 && mg_parse_http(io->buf, io->len, hm, is_req) > 0) {
...@@ -4766,6 +4769,11 @@ static int mg_http_multipart_finalize(struct mg_connection *c) { ...@@ -4766,6 +4769,11 @@ static int mg_http_multipart_finalize(struct mg_connection *c) {
struct mg_http_proto_data *pd = mg_http_get_proto_data(c); struct mg_http_proto_data *pd = mg_http_get_proto_data(c);
mg_http_multipart_call_handler(c, MG_EV_HTTP_PART_END, NULL, 0); mg_http_multipart_call_handler(c, MG_EV_HTTP_PART_END, NULL, 0);
free((void *) pd->mp_stream.file_name);
pd->mp_stream.file_name = NULL;
free((void *) pd->mp_stream.var_name);
pd->mp_stream.var_name = NULL;
mg_http_multipart_call_handler(c, MG_EV_HTTP_MULTIPART_REQUEST_END, NULL, 0);
mg_http_free_proto_data_mp_stream(&pd->mp_stream); mg_http_free_proto_data_mp_stream(&pd->mp_stream);
pd->mp_stream.state = MPS_FINISHED; pd->mp_stream.state = MPS_FINISHED;
...@@ -4783,11 +4791,13 @@ static int mg_http_multipart_wait_for_boundary(struct mg_connection *c) { ...@@ -4783,11 +4791,13 @@ static int mg_http_multipart_wait_for_boundary(struct mg_connection *c) {
boundary = c_strnstr(io->buf, pd->mp_stream.boundary, io->len); boundary = c_strnstr(io->buf, pd->mp_stream.boundary, io->len);
if (boundary != NULL) { if (boundary != NULL) {
if (io->len - (boundary - io->buf) < 4) { const char *boundary_end = (boundary + pd->mp_stream.boundary_len);
if (io->len - (boundary_end - io->buf) < 4) {
return 0; return 0;
} }
if (memcmp(boundary + pd->mp_stream.boundary_len, "--", 2) == 0) { if (memcmp(boundary_end, "--\r\n", 4) == 0) {
pd->mp_stream.state = MPS_FINALIZE; pd->mp_stream.state = MPS_FINALIZE;
mbuf_remove(io, (boundary_end - io->buf) + 4);
} else { } else {
pd->mp_stream.state = MPS_GOT_BOUNDARY; pd->mp_stream.state = MPS_GOT_BOUNDARY;
} }
......
...@@ -2827,6 +2827,7 @@ struct mg_ssi_call_ctx { ...@@ -2827,6 +2827,7 @@ struct mg_ssi_call_ctx {
#define MG_EV_HTTP_PART_BEGIN 122 /* struct mg_http_multipart_part */ #define MG_EV_HTTP_PART_BEGIN 122 /* struct mg_http_multipart_part */
#define MG_EV_HTTP_PART_DATA 123 /* struct mg_http_multipart_part */ #define MG_EV_HTTP_PART_DATA 123 /* struct mg_http_multipart_part */
#define MG_EV_HTTP_PART_END 124 /* struct mg_http_multipart_part */ #define MG_EV_HTTP_PART_END 124 /* struct mg_http_multipart_part */
#define MG_EV_HTTP_MULTIPART_REQUEST_END 125 /* struct mg_http_multipart_part */
#endif #endif
/* /*
...@@ -2836,11 +2837,6 @@ struct mg_ssi_call_ctx { ...@@ -2836,11 +2837,6 @@ struct mg_ssi_call_ctx {
* - MG_EV_HTTP_REQUEST: HTTP request has arrived. Parsed HTTP request * - MG_EV_HTTP_REQUEST: HTTP request has arrived. Parsed HTTP request
* is passed as * is passed as
* `struct http_message` through the handler's `void *ev_data` pointer. * `struct http_message` through the handler's `void *ev_data` pointer.
* - MG_EV_HTTP_MULTIPART_REQUEST: A multipart POST request has received.
* This event is sent before body is parsed. After this, the user
* should expect a sequence of MG_EV_HTTP_PART_BEGIN/DATA/END requests.
* This is also the last time when headers and other request fields are
* accessible.
* - MG_EV_HTTP_REPLY: The HTTP reply has arrived. The parsed HTTP reply is * - MG_EV_HTTP_REPLY: The HTTP reply has arrived. The parsed HTTP reply is
* passed as `struct http_message` through the handler's `void *ev_data` * passed as `struct http_message` through the handler's `void *ev_data`
* pointer. * pointer.
...@@ -2862,16 +2858,29 @@ struct mg_ssi_call_ctx { ...@@ -2862,16 +2858,29 @@ struct mg_ssi_call_ctx {
* handshake. `ev_data` is `NULL`. * handshake. `ev_data` is `NULL`.
* - MG_EV_WEBSOCKET_FRAME: new WebSocket frame has arrived. `ev_data` is * - MG_EV_WEBSOCKET_FRAME: new WebSocket frame has arrived. `ev_data` is
* `struct websocket_message *` * `struct websocket_message *`
* - MG_EV_HTTP_PART_BEGIN: new part of multipart message is started, *
* extra parameters are passed in mg_http_multipart_part * When compiled with MG_ENABLE_HTTP_STREAMING_MULTIPART, Mongoose parses
* - MG_EV_HTTP_PART_DATA: new portion of data from the multiparted message * multipart requests and splits them into separate events:
* no additional headers are available, only data and data size * - MG_EV_HTTP_MULTIPART_REQUEST: Start of the request.
* - MG_EV_HTTP_PART_END: final boundary received, analogue to maybe used to * This event is sent before body is parsed. After this, the user
* find the end of packet * should expect a sequence of PART_BEGIN/DATA/END requests.
* Note: Mongoose should be compiled with MG_ENABLE_HTTP_STREAMING_MULTIPART * This is also the last time when headers and other request fields are
* to enable MG_EV_HTTP_MULTIPART_REQUEST, MG_EV_HTTP_REQUEST_END, * accessible.
* MG_EV_HTTP_REQUEST_CANCEL, MG_EV_HTTP_PART_BEGIN, MG_EV_HTTP_PART_DATA, * - MG_EV_HTTP_PART_BEGIN: Start of a part of a multipart message.
* MG_EV_HTTP_PART_END constants * Argument: mg_http_multipart_part with var_name and file_name set
* (if present). No data is passed in this message.
* - MG_EV_HTTP_PART_DATA: new portion of data from the multipart message.
* Argument: mg_http_multipart_part. var_name and file_name are preserved,
* data is available in mg_http_multipart_part.data.
* - MG_EV_HTTP_PART_END: End of the current part. var_name, file_name are
* the same, no data in the message. If status is 0, then the part is
* properly terminated with a boundary, status < 0 means that connection
* was terminated.
* - MG_EV_HTTP_MULTIPART_REQUEST_END: End of the multipart request.
* Argument: mg_http_multipart_part, var_name and file_name are NULL,
* status = 0 means request was properly closed, < 0 means connection
* was terminated (note: in this case both PART_END and REQUEST_END are
* delivered).
*/ */
void mg_set_protocol_http_websocket(struct mg_connection *nc); void mg_set_protocol_http_websocket(struct mg_connection *nc);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment