提交 c02b2427 authored 作者: Seven Du's avatar Seven Du

refactor http parsing and prevent read body more than content-length

上级 aa15994c
...@@ -1116,13 +1116,14 @@ typedef struct switch_http_request_s { ...@@ -1116,13 +1116,14 @@ typedef struct switch_http_request_s {
switch_bool_t keepalive; switch_bool_t keepalive;
const char *content_type; const char *content_type;
switch_size_t content_length; switch_size_t content_length;
switch_size_t bytes_header;
switch_size_t bytes_read;
switch_size_t bytes_buffered;
switch_event_t *headers; switch_event_t *headers;
void *user_data; /* private user data */ void *user_data; /* private user data */
/* private members used by the parser internally */ /* private members used by the parser internally */
char *_buffer; char *_buffer;
const char *_unparsed_data;
switch_size_t _unparsed_len;
switch_bool_t _destroy_headers; switch_bool_t _destroy_headers;
} switch_http_request_t; } switch_http_request_t;
......
...@@ -1287,17 +1287,29 @@ static uint8_t *http_stream_read(switch_stream_handle_t *handle, int *len) ...@@ -1287,17 +1287,29 @@ static uint8_t *http_stream_read(switch_stream_handle_t *handle, int *len)
jsock_t *jsock = r->user_data; jsock_t *jsock = r->user_data;
wsh_t *wsh = &jsock->ws; wsh_t *wsh = &jsock->ws;
*len = r->_unparsed_len; *len = r->bytes_buffered - r->bytes_read;
if (*len) { // we already read part of the body if (*len > 0) { // we already read part of the body
r->_unparsed_len = 0; // reset for the next read uint8_t *data = (uint8_t *)wsh->buffer + r->bytes_read;
return (uint8_t *)r->_unparsed_data; r->bytes_read = r->bytes_buffered;
return data;
} }
if ((*len = ws_raw_read(wsh, wsh->buffer, 4096, wsh->block)) < 0) { if (r->content_length && (r->bytes_read - r->bytes_header) >= r->content_length) {
*len = 0;
return NULL; return NULL;
} }
*len = r->content_length - (r->bytes_read - r->bytes_header);
*len = *len > sizeof(wsh->buffer) ? sizeof(wsh->buffer) : *len;
if ((*len = ws_raw_read(wsh, wsh->buffer, *len, wsh->block)) <= 0) {
*len = 0;
return NULL;
}
r->bytes_read += *len;
return (uint8_t *)wsh->buffer; return (uint8_t *)wsh->buffer;
} }
...@@ -1453,9 +1465,8 @@ static void http_run(jsock_t *jsock) ...@@ -1453,9 +1465,8 @@ static void http_run(jsock_t *jsock)
goto request_err; goto request_err;
} }
if (request._unparsed_len) { if ((bytes = request.bytes_buffered - (request.bytes_read - request.bytes_header)) > 0) {
bytes += request._unparsed_len; memcpy(buffer, jsock->ws.buffer + request.bytes_read, bytes);
memcpy(buffer, request._unparsed_data, bytes);
} }
while(bytes < request.content_length) { while(bytes < request.content_length) {
......
...@@ -3675,10 +3675,10 @@ SWITCH_DECLARE(switch_status_t) switch_http_parse_header(char *buffer, uint32_t ...@@ -3675,10 +3675,10 @@ SWITCH_DECLARE(switch_status_t) switch_http_parse_header(char *buffer, uint32_t
request->_buffer = strdup(buffer); request->_buffer = strdup(buffer);
request->method = request->_buffer; request->method = request->_buffer;
if (body && *body) { request->bytes_buffered = datalen;
request->_unparsed_data = body; if (body) {
request->_unparsed_len = datalen - (body - buffer); request->bytes_header = body - buffer;
switch_assert(request->_unparsed_len > 0); request->bytes_read = body - buffer;
} }
p = strchr(request->method, ' '); p = strchr(request->method, ' ');
...@@ -3796,7 +3796,8 @@ SWITCH_DECLARE(void) switch_http_dump_request(switch_http_request_t *request) ...@@ -3796,7 +3796,8 @@ SWITCH_DECLARE(void) switch_http_dump_request(switch_http_request_t *request)
if (request->referer) printf("referer: %s\n", request->referer); if (request->referer) printf("referer: %s\n", request->referer);
if (request->user) printf("user: %s\n", request->user); if (request->user) printf("user: %s\n", request->user);
if (request->keepalive) printf("uri: %d\n", request->keepalive); if (request->keepalive) printf("uri: %d\n", request->keepalive);
if (request->_unparsed_data) printf("body: %p\n", request->_unparsed_data); if (request->content_type) printf("uri: %s\n", request->content_type);
if (request->content_length) printf("uri: %" SWITCH_SIZE_T_FMT "\n", request->content_length);
{ {
switch_event_header_t *header = request->headers->headers; switch_event_header_t *header = request->headers->headers;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论