From 8d66d3911d45e61956d7fe0ee4879482998d0a8e Mon Sep 17 00:00:00 2001 From: Wolfgang Draxinger Date: Fri, 28 Jun 2013 21:00:57 +0200 Subject: chunked transfer read done --- picohttp.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/picohttp.c b/picohttp.c index 1a01888..f4c45bd 100644 --- a/picohttp.c +++ b/picohttp.c @@ -329,10 +329,47 @@ int16_t picohttpGetch(struct picohttpRequest * const req) int picohttpRead(struct picohttpRequest * const req, size_t len, char * const buf) { - /* TODO: skipping over Chunked Transfer Boundaries + /* skipping over Chunked Transfer Boundaries * if Chunked Transfer Encoding is used */ - int r = picohttpIoRead(req->ioops, len, buf); + if(req->query.transferencoding == PICOHTTP_CODING_CHUNKED ) { + if( !req->query.chunklength ) { + int16_t ch; + /* this is a new chunk; + * read the length and skip to after */ + if( 0 > (ch = picohttpIoGetch(req->ioops)) ) { + return -1; + } + uint64_t len; + if( 0 > (ch = picohttpIoB10ToU64( + &len, + req->ioops, + ch)) + ) { + return ch; + } + if( 0 > (ch = picohttpIoSkipOverCRLF(req->ioops, ch)) ) { + return ch; + } + req->query.chunklength = len; + return ch; + } + + if( req->query.chunklength <= req->received_octets ) { + /* If this happens the data is corrupted, or + * the client is nonconforming, or an attack is + * underway, or something entierely different, + * or all of that. + * Abort processing the query! + */ + return -1; + } + } + + if( req->received_octets + len > req->query.chunklength ) { + len = req->query.chunklength - req->received_octets; + } + int r = picohttpIoRead(req->ioops, len, buf); if( 5 < r ) { memmove(req->query.prev_ch + r, req->query.prev_ch, 5-r); memcpy(req->query.prev_ch, buf, r); @@ -340,6 +377,34 @@ int picohttpRead(struct picohttpRequest * const req, size_t len, char * const bu memcpy(req->query.prev_ch, buf + len - 5, 5); } + if(req->query.transferencoding == PICOHTTP_CODING_CHUNKED ) { + if( !req->query.chunklength <= req->received_octets ) { + int16_t ch; + /* end of chunk; + * skip over , make sure the trailing '0' is + * there and read the headers, err, I mean footers + * (whatever, the header processing code will do for + * chunk footers just fine). + */ + if( '0' != (ch = picohttpIoGetch(req->ioops)) ) { + return -1; + } + if( 0 > (ch = picohttpIoGetch(req->ioops)) ) { + return -1; + } + if( 0 > (ch = picohttpProcessHeaders( + req, + NULL, NULL, + ch)) + ) { + return ch; + } + + req->received_octets = + req->query.chunklength = 0; + } + } + return r; } -- cgit v1.2.3