* Real proper handling of chunked requests.

This commit is contained in:
Justin Maggard 2009-11-10 00:01:06 +00:00
parent c4170af521
commit db4b8d0a02

View File

@ -350,25 +350,25 @@ next_header:
} }
if( h->reqflags & FLAG_CHUNKED ) if( h->reqflags & FLAG_CHUNKED )
{ {
if( h->req_buflen > h->req_contentoff ) char *endptr;
h->req_chunklen = -1;
if( h->req_buflen <= h->req_contentoff )
return;
while( (h->req_chunklen = strtol(line, &endptr, 16)) && (endptr != line) )
{ {
h->req_chunklen = strtol(line, NULL, 16); while(!(endptr[0] == '\r' && endptr[1] == '\n'))
while(!(line[0] == '\r' && line[1] == '\n'))
{ {
line++; endptr++;
h->req_contentoff++;
} }
h->req_contentoff += 2; line = endptr+h->req_chunklen+2;
h->req_contentlen = h->req_buflen - h->req_contentoff;
} }
else
if( endptr == line )
{ {
h->req_chunklen = -1; h->req_chunklen = -1;
}
}
/* Don't bother checking client type until we have the whole request. */
if( (h->req_buflen - h->req_contentoff) < h->req_contentlen )
return; return;
}
}
/* If the client type wasn't found, search the cache. /* If the client type wasn't found, search the cache.
* This is done because a lot of clients like to send a * This is done because a lot of clients like to send a
* different User-Agent with different types of requests. */ * different User-Agent with different types of requests. */
@ -670,30 +670,38 @@ ProcessHttpQuery_upnphttp(struct upnphttp * h)
HttpVer[i] = '\0'; HttpVer[i] = '\0';
/*DPRINTF(E_INFO, L_HTTP, "HTTP REQUEST : %s %s (%s)\n", /*DPRINTF(E_INFO, L_HTTP, "HTTP REQUEST : %s %s (%s)\n",
HttpCommand, HttpUrl, HttpVer);*/ HttpCommand, HttpUrl, HttpVer);*/
DPRINTF(E_DEBUG, L_HTTP, "HTTP REQUEST: %.*s\n", h->req_buflen, h->req_buf);
ParseHttpHeaders(h); ParseHttpHeaders(h);
/* see if we need to wait for remaining data */ /* see if we need to wait for remaining data */
if( (h->reqflags & FLAG_CHUNKED) ) if( (h->reqflags & FLAG_CHUNKED) )
{ {
char * chunkstart = h->req_buf+h->req_contentoff; if( h->req_chunklen )
char * numstart; {
h->state = 2; h->state = 2;
while( h->req_chunklen )
{
if( chunkstart >= (h->req_buf+h->req_buflen) )
return;
numstart = chunkstart+h->req_chunklen+2;
h->req_chunklen = strtol(numstart, &chunkstart, 16);
if( !h->req_chunklen && (chunkstart == numstart) )
{
DPRINTF(E_DEBUG, L_HTTP, "Chunked request needs more input.\n");
return; return;
} }
chunkstart = chunkstart+2; char *chunkstart, *chunk, *endptr, *endbuf;
chunk = endbuf = chunkstart = h->req_buf + h->req_contentoff;
while( (h->req_chunklen = strtol(chunk, &endptr, 16)) && (endptr != chunk) )
{
while(!(endptr[0] == '\r' && endptr[1] == '\n'))
{
endptr++;
} }
endptr += 2;
memmove(endbuf, endptr, h->req_chunklen);
endbuf += h->req_chunklen;
chunk = endptr + h->req_chunklen;
}
h->req_contentlen = endbuf - chunkstart;
h->req_buflen = endbuf - h->req_buf;
h->state = 100; h->state = 100;
} }
DPRINTF(E_DEBUG, L_HTTP, "HTTP REQUEST: %.*s\n", h->req_buflen, h->req_buf);
if(strcmp("POST", HttpCommand) == 0) if(strcmp("POST", HttpCommand) == 0)
{ {
h->req_command = EPost; h->req_command = EPost;
@ -887,13 +895,17 @@ Process_upnphttp(struct upnphttp * h)
if((h->req_buflen - h->req_contentoff) >= h->req_contentlen) if((h->req_buflen - h->req_contentoff) >= h->req_contentlen)
{ {
/* Need the struct to point to the realloc'd memory locations */ /* Need the struct to point to the realloc'd memory locations */
ParseHttpHeaders(h);
if( h->state == 1 ) if( h->state == 1 )
{
ParseHttpHeaders(h);
ProcessHTTPPOST_upnphttp(h); ProcessHTTPPOST_upnphttp(h);
}
else if( h->state == 2 ) else if( h->state == 2 )
{
ProcessHttpQuery_upnphttp(h); ProcessHttpQuery_upnphttp(h);
} }
} }
}
break; break;
default: default:
DPRINTF(E_WARN, L_HTTP, "Unexpected state: %d\n", h->state); DPRINTF(E_WARN, L_HTTP, "Unexpected state: %d\n", h->state);