properly deal with client sending chunked data
this fixes OPTIONS requests sent from apache SVN client using their native HTTP proxy support. closes #421 tested with `svn info http://svnmir.bme.freebsd.org/ports/`
This commit is contained in:
parent
17d3733be3
commit
eced6822f8
56
src/reqs.c
56
src/reqs.c
@ -523,7 +523,7 @@ fail:
|
||||
* server headers can be processed.
|
||||
* - rjkaes
|
||||
*/
|
||||
static int pull_client_data (struct conn_s *connptr, long int length)
|
||||
static int pull_client_data (struct conn_s *connptr, long int length, int iehack)
|
||||
{
|
||||
char *buffer;
|
||||
ssize_t len;
|
||||
@ -548,6 +548,7 @@ static int pull_client_data (struct conn_s *connptr, long int length)
|
||||
length -= len;
|
||||
} while (length > 0);
|
||||
|
||||
if (iehack) {
|
||||
/*
|
||||
* BUG FIX: Internet Explorer will leave two bytes (carriage
|
||||
* return and line feed) at the end of a POST message. These
|
||||
@ -582,6 +583,41 @@ static int pull_client_data (struct conn_s *connptr, long int length)
|
||||
"Could not read two bytes from POST message");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
safefree (buffer);
|
||||
return 0;
|
||||
|
||||
ERROR_EXIT:
|
||||
safefree (buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* pull chunked client data */
|
||||
static int pull_client_data_chunked (struct conn_s *connptr) {
|
||||
char *buffer = 0;
|
||||
ssize_t len;
|
||||
long chunklen;
|
||||
|
||||
while(1) {
|
||||
if (buffer) safefree(buffer);
|
||||
len = readline (connptr->client_fd, &buffer);
|
||||
|
||||
if (len <= 0)
|
||||
goto ERROR_EXIT;
|
||||
|
||||
if (!connptr->error_variables) {
|
||||
if (safe_write (connptr->server_fd, buffer, len) < 0)
|
||||
goto ERROR_EXIT;
|
||||
}
|
||||
|
||||
chunklen = strtol (buffer, (char**)0, 16);
|
||||
|
||||
if (pull_client_data (connptr, chunklen+2, 0) < 0)
|
||||
goto ERROR_EXIT;
|
||||
|
||||
if(!chunklen) break;
|
||||
}
|
||||
|
||||
safefree (buffer);
|
||||
return 0;
|
||||
@ -787,7 +823,7 @@ static int remove_connection_headers (orderedmap hashofheaders)
|
||||
|
||||
/*
|
||||
* If there is a Content-Length header, then return the value; otherwise, return
|
||||
* a negative number.
|
||||
* -1.
|
||||
*/
|
||||
static long get_content_length (orderedmap hashofheaders)
|
||||
{
|
||||
@ -802,6 +838,13 @@ static long get_content_length (orderedmap hashofheaders)
|
||||
return content_length;
|
||||
}
|
||||
|
||||
static int is_chunked_transfer (orderedmap hashofheaders)
|
||||
{
|
||||
char *data;
|
||||
data = orderedmap_find (hashofheaders, "transfer-encoding");
|
||||
return data ? !strcmp (data, "chunked") : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Search for Via header in a hash of headers and either write a new Via
|
||||
* header, or append our information to the end of an existing Via header.
|
||||
@ -896,6 +939,10 @@ process_client_headers (struct conn_s *connptr, orderedmap hashofheaders)
|
||||
*/
|
||||
connptr->content_length.client = get_content_length (hashofheaders);
|
||||
|
||||
/* Check whether client sends chunked data. */
|
||||
if (connptr->content_length.client == -1 && is_chunked_transfer (hashofheaders))
|
||||
connptr->content_length.client = -2;
|
||||
|
||||
/*
|
||||
* See if there is a "Connection" header. If so, we need to do a bit
|
||||
* of processing. :)
|
||||
@ -960,8 +1007,9 @@ process_client_headers (struct conn_s *connptr, orderedmap hashofheaders)
|
||||
PULL_CLIENT_DATA:
|
||||
if (connptr->content_length.client > 0) {
|
||||
ret = pull_client_data (connptr,
|
||||
connptr->content_length.client);
|
||||
}
|
||||
connptr->content_length.client, 1);
|
||||
} else if (connptr->content_length.client == -2)
|
||||
ret = pull_client_data_chunked (connptr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user