mirror of
https://github.com/nodejs/http-parser.git
synced 2025-10-21 07:02:06 +08:00
Bug Fix: Connection:close with missing Content-Length.
The test and bug report are from tomika.
This commit is contained in:
@@ -96,7 +96,7 @@ struct http_parser {
|
||||
unsigned short method; /* requests only */
|
||||
short version;
|
||||
short keep_alive;
|
||||
size_t content_length;
|
||||
ssize_t content_length;
|
||||
|
||||
/** PUBLIC **/
|
||||
void *data; /* A pointer to get hook to the "connection" or "socket" object */
|
||||
|
@@ -30,6 +30,7 @@
|
||||
#define EATING 0x01
|
||||
#define ERROR 0x02
|
||||
#define CHUNKED 0x04
|
||||
#define EAT_FOREVER 0x10
|
||||
|
||||
static int unhex[] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
|
||||
,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
|
||||
@@ -79,7 +80,7 @@ do { \
|
||||
parser->method = 0; \
|
||||
parser->version = HTTP_VERSION_OTHER; \
|
||||
parser->keep_alive = -1; \
|
||||
parser->content_length = 0; \
|
||||
parser->content_length = -1; \
|
||||
parser->body_read = 0
|
||||
|
||||
#define END_REQUEST \
|
||||
@@ -226,6 +227,7 @@ do { \
|
||||
}
|
||||
|
||||
action content_length {
|
||||
if (parser->content_length == -1) parser->content_length = 0;
|
||||
if (parser->content_length > INT_MAX) {
|
||||
parser->flags |= ERROR;
|
||||
return 0;
|
||||
@@ -281,11 +283,25 @@ do { \
|
||||
if (parser->flags & CHUNKED) {
|
||||
fnext ChunkedBody;
|
||||
} else {
|
||||
/* this is pretty stupid. i'd prefer to combine this with skip_chunk_data */
|
||||
/* this is pretty stupid. i'd prefer to combine this with
|
||||
* skip_chunk_data */
|
||||
if (parser->content_length < 0) {
|
||||
/* If we didn't get a content length; if not keep-alive
|
||||
* just read body until EOF */
|
||||
if (!http_parser_should_keep_alive(parser)) {
|
||||
parser->flags |= EAT_FOREVER;
|
||||
parser->chunk_size = REMAINING;
|
||||
} else {
|
||||
/* Otherwise, if keep-alive, then assume the message
|
||||
* has no body. */
|
||||
parser->chunk_size = parser->content_length = 0;
|
||||
}
|
||||
} else {
|
||||
parser->chunk_size = parser->content_length;
|
||||
}
|
||||
p += 1;
|
||||
|
||||
SKIP_BODY(MIN(REMAINING, parser->content_length));
|
||||
SKIP_BODY(MIN(REMAINING, parser->chunk_size));
|
||||
|
||||
if (callback_return_value != 0) {
|
||||
parser->flags |= ERROR;
|
||||
@@ -444,11 +460,27 @@ http_parser_execute (http_parser *parser, const char *buffer, size_t len)
|
||||
{
|
||||
size_t tmp; // REMOVE ME this is extremely hacky
|
||||
int callback_return_value = 0;
|
||||
const char *p, *pe;
|
||||
const char *p, *pe, *eof;
|
||||
int cs = parser->cs;
|
||||
|
||||
p = buffer;
|
||||
pe = buffer+len;
|
||||
eof = len ? NULL : pe;
|
||||
|
||||
if (parser->flags & EAT_FOREVER) {
|
||||
if (len == 0) {
|
||||
if (parser->on_message_complete) {
|
||||
callback_return_value = parser->on_message_complete(parser);
|
||||
if (callback_return_value != 0) parser->flags |= ERROR;
|
||||
}
|
||||
} else {
|
||||
if (parser->on_body) {
|
||||
callback_return_value = parser->on_body(parser, p, len);
|
||||
if (callback_return_value != 0) parser->flags |= ERROR;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
if (0 < parser->chunk_size && (parser->flags & EATING)) {
|
||||
/* eat body */
|
||||
|
39
test.c
39
test.c
@@ -344,6 +344,45 @@ const struct message responses[] =
|
||||
"</BODY></HTML>\r\n"
|
||||
}
|
||||
|
||||
, {.name= "no content-length response"
|
||||
,.type= HTTP_RESPONSE
|
||||
,.raw= "HTTP/1.1 200 OK\r\n"
|
||||
"Date: Tue, 04 Aug 2009 07:59:32 GMT\r\n"
|
||||
"Server: Apache\r\n"
|
||||
"X-Powered-By: Servlet/2.5 JSP/2.1\r\n"
|
||||
"Content-Type: text/xml; charset=utf-8\r\n"
|
||||
"Connection: close\r\n"
|
||||
"\r\n"
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
"<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">\n"
|
||||
" <SOAP-ENV:Body>\n"
|
||||
" <SOAP-ENV:Fault>\n"
|
||||
" <faultcode>SOAP-ENV:Client</faultcode>\n"
|
||||
" <faultstring>Client Error</faultstring>\n"
|
||||
" </SOAP-ENV:Fault>\n"
|
||||
" </SOAP-ENV:Body>\n"
|
||||
"</SOAP-ENV:Envelope>"
|
||||
,.should_keep_alive= FALSE
|
||||
,.status_code= 200
|
||||
,.num_headers= 5
|
||||
,.headers=
|
||||
{ { "Date", "Tue, 04 Aug 2009 07:59:32 GMT" }
|
||||
, { "Server", "Apache" }
|
||||
, { "X-Powered-By", "Servlet/2.5 JSP/2.1" }
|
||||
, { "Content-Type", "text/xml; charset=utf-8" }
|
||||
, { "Connection", "close" }
|
||||
}
|
||||
,.body= "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
"<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">\n"
|
||||
" <SOAP-ENV:Body>\n"
|
||||
" <SOAP-ENV:Fault>\n"
|
||||
" <faultcode>SOAP-ENV:Client</faultcode>\n"
|
||||
" <faultstring>Client Error</faultstring>\n"
|
||||
" </SOAP-ENV:Fault>\n"
|
||||
" </SOAP-ENV:Body>\n"
|
||||
"</SOAP-ENV:Envelope>"
|
||||
}
|
||||
|
||||
, {.name= "404 no headers no body"
|
||||
,.type= HTTP_RESPONSE
|
||||
,.raw= "HTTP/1.1 404 Not Found\r\n\r\n"
|
||||
|
Reference in New Issue
Block a user