1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-06 04:31:29 +00:00

Use a separate boolean to remember whether Content-Length was set.

Previous content_length == 0 was overloaded to mean that Content-Length
was set. But that was wrong when the Content-Length was actually 0.

The error message you got when running an HTTP proxy that received
0-length POSTs was
	POST request with no Content-Length.
This commit is contained in:
david
2014-03-07 16:57:42 +00:00
parent d5d8cd3033
commit 0c4cf69074
3 changed files with 16 additions and 8 deletions

View File

@@ -843,6 +843,7 @@ void http_request_init(struct http_request *request)
uri_init(&request->uri);
request->version = HTTP_UNKNOWN;
request->header = NULL;
request->content_length_set = 0;
request->content_length = 0;
request->bytes_transferred = 0;
}
@@ -898,6 +899,7 @@ void http_response_init(struct http_response *response)
response->code = 0;
response->phrase = NULL;
response->header = NULL;
response->content_length_set = 0;
response->content_length = 0;
response->bytes_transferred = 0;
}
@@ -1053,7 +1055,7 @@ int http_parse_header(struct http_header **result, const char *header)
return 0;
}
static int http_header_get_content_length(const struct http_header *header, unsigned long *content_length)
static int http_header_get_content_length(const struct http_header *header, int *content_length_set, unsigned long *content_length)
{
char *content_length_s;
char *tail;
@@ -1061,6 +1063,7 @@ static int http_header_get_content_length(const struct http_header *header, unsi
content_length_s = http_header_get_first(header, "Content-Length");
if (content_length_s == NULL) {
*content_length_set = 0;
*content_length = 0;
return 0;
}
@@ -1068,6 +1071,7 @@ static int http_header_get_content_length(const struct http_header *header, unsi
code = 0;
errno = 0;
*content_length_set = 1;
*content_length = parse_long(content_length_s, (char **) &tail);
if (errno != 0 || *tail != '\0' || tail == content_length_s)
code = 400;
@@ -1084,7 +1088,7 @@ int http_request_parse_header(struct http_request *request, const char *header)
code = http_parse_header(&request->header, header);
if (code != 0)
return code;
code = http_header_get_content_length(request->header, &request->content_length);
code = http_header_get_content_length(request->header, &request->content_length_set, &request->content_length);
if (code != 0)
return code;
@@ -1099,7 +1103,7 @@ int http_response_parse_header(struct http_response *response, const char *heade
code = http_parse_header(&response->header, header);
if (code != 0)
return code;
code = http_header_get_content_length(response->header, &response->content_length);
code = http_header_get_content_length(response->header, &response->content_length_set, &response->content_length);
if (code != 0)
return code;

View File

@@ -184,6 +184,7 @@ struct http_request {
struct uri uri;
enum http_version version;
struct http_header *header;
int content_length_set;
unsigned long content_length;
unsigned long bytes_transferred;
};
@@ -193,6 +194,7 @@ struct http_response {
int code;
char *phrase;
struct http_header *header;
int content_length_set;
unsigned long content_length;
unsigned long bytes_transferred;
};

View File

@@ -660,7 +660,7 @@ static int do_transaction(struct http_request *request,
request) if it cannot determine the length of the message, or with 411
(length required) if it wishes to insist on receiving a valid
Content-Length." */
if (strcmp(request->method, "POST") == 0 && request->content_length == 0) {
if (strcmp(request->method, "POST") == 0 && !request->content_length_set) {
if (o.debug)
logdebug("POST request with no Content-Length.\n");
return 400;
@@ -771,14 +771,16 @@ static int do_transaction(struct http_request *request,
/* If the Content-Length is 0, read until the connection is closed.
Otherwise read until the Content-Length. At this point it's too late to
return our own error code so return 0 in case of any error. */
while (response.content_length == 0
while (!response.content_length_set
|| response.bytes_transferred < response.content_length) {
size_t remaining = response.content_length - response.bytes_transferred;
size_t count;
count = sizeof(buf);
if (response.content_length > 0 && remaining < count)
count = remaining;
if (response.content_length_set) {
size_t remaining = response.content_length - response.bytes_transferred;
if (remaining < count)
count = remaining;
}
n = socket_buffer_read(server_sock, buf, count);
if (n <= 0)
break;