From c50c12e6206772273f62752c1c0091ac78698665 Mon Sep 17 00:00:00 2001 From: Wolfgang Draxinger Date: Tue, 18 Jun 2013 21:24:59 +0200 Subject: added header processing for content type and transfer encoding - chunked --- picohttp.c | 34 +++++++++++++++++++++++++++++----- picohttp.h | 5 ++++- test/bsdsocket.c | 35 +++++++++++++++++++++++++++++------ test/bufbsdsocket.c | 22 ++++++++++------------ 4 files changed, 72 insertions(+), 24 deletions(-) diff --git a/picohttp.c b/picohttp.c index 487a870..f7b6948 100644 --- a/picohttp.c +++ b/picohttp.c @@ -21,6 +21,8 @@ static char const PICOHTTP_STR_SERVER[] = "Server"; static char const PICOHTTP_STR_PICOWEB[] = "picoweb/0.1"; static char const PICOHTTP_STR_ACCEPT[] = "Accept"; +static char const PICOHTTP_STR_TRANSFER[] = "Transfer"; + static char const PICOHTTP_STR__ENCODING[] = "-Encoding"; static char const PICOHTTP_STR_CONTENT[] = "Content"; @@ -41,11 +43,12 @@ static char const PICOHTTP_STR_CONNECTION[] = "Connection"; static char const PICOHTTP_STR_CLOSE[] = "close"; static char const PICOHTTP_STR_DATE[] = "Date"; - static char const PICOHTTP_STR_EXPECT[] = "Expect"; static char const PICOHTTP_STR_BOUNDARY[] = " boundary="; +static char const PICOHTTP_STR_CHUNKED[] = "chunked"; + #if !defined(PICOHTTP_CONFIG_HAVE_LIBDJB) /* Number formating functions modified from libdjb by * Daniel J. Bernstein, packaged at http://www.fefe.de/djb/ @@ -540,24 +543,45 @@ static void picohttpProcessContentType( static void picohttpProcessHeaderField( struct picohttpRequest * const req, - char const * const headername, - char const * const headervalue) + char const *headername, + char const *headervalue) { debug_printf("%s: %s\n", headername, headervalue); if(!strncmp(headername, PICOHTTP_STR_CONTENT, sizeof(PICOHTTP_STR_CONTENT)-1)) { + headername += sizeof(PICOHTTP_STR_CONTENT)-1; /* Content Length */ - if(!strncmp(headername + sizeof(PICOHTTP_STR_CONTENT)-1, + if(!strncmp(headername, PICOHTTP_STR__LENGTH, sizeof(PICOHTTP_STR__LENGTH)-1)) { req->query.contentlength = atol(headervalue); + return; } /* Content Type */ - if(!strncmp(headername + sizeof(PICOHTTP_STR_CONTENT)-1, + if(!strncmp(headername, PICOHTTP_STR__TYPE, sizeof(PICOHTTP_STR__TYPE)-1)) { picohttpProcessContentType(req, headervalue); + return; + } + return; + } + + if(!strncmp(headername, + PICOHTTP_STR_TRANSFER, + sizeof(PICOHTTP_STR_TRANSFER)-1)) { + headername += sizeof(PICOHTTP_STR_TRANSFER)-1; + /* Transfer Encoding */ + if(!strncmp(headername, + PICOHTTP_STR__ENCODING, sizeof(PICOHTTP_STR__ENCODING)-1)) { + if(!strncmp(headervalue, + PICOHTTP_STR_CHUNKED, + sizeof(PICOHTTP_STR_CHUNKED)-1)) { + req->query.transferencoding = PICOHTTP_CODING_CHUNKED; + } + return; } + return; } } diff --git a/picohttp.h b/picohttp.h index ced2ef5..34fc59b 100644 --- a/picohttp.h +++ b/picohttp.h @@ -126,7 +126,7 @@ struct picohttpRequest { } contenttype; size_t contentlength; uint8_t contentencoding; - uint8_t te; + uint8_t transferencoding; char multipartboundary[PICOHTTP_MULTIPARTBOUNDARY_MAX_LEN+1]; } query; struct { @@ -138,6 +138,9 @@ struct picohttpRequest { uint8_t contentencoding; uint8_t transferencoding; } response; + struct { + size_t length; + } currentchunk; struct { size_t octets; uint8_t header; diff --git a/test/bsdsocket.c b/test/bsdsocket.c index d4bd5a2..cb6cde2 100644 --- a/test/bsdsocket.c +++ b/test/bsdsocket.c @@ -80,6 +80,11 @@ int bsdsock_putch(char ch, void *data) return bsdsock_write(1, &ch, data); } +int bsdsock_flush(void* data) +{ + return 0; +} + int sockfd = -1; void bye(void) @@ -97,13 +102,18 @@ void rhRoot(struct picohttpRequest *req) { fprintf(stderr, "handling request /%s\n", req->urltail); - char http_header[] = "HTTP/x.x 200 OK\r\nServer: picoweb\r\nContent-Type: text/html\r\n\r\n"; - http_header[5] = '0'+req->httpversion.major; - http_header[7] = '0'+req->httpversion.minor; - picohttpIoWrite(req->ioops, sizeof(http_header)-1, http_header); - char http_test[] = "handling request /\n/test\n"; + req->response.contenttype = "text/html"; - picohttpIoWrite(req->ioops, sizeof(http_test)-1, http_test); + char http_test[] = +"handling request /\n" +"/test" +"
" +"" +"" +"
" +"\n"; + + picohttpResponseWrite(req, sizeof(http_test)-1, http_test); } void rhTest(struct picohttpRequest *req) @@ -120,6 +130,17 @@ void rhTest(struct picohttpRequest *req) } } +void rhUpload(struct picohttpRequest *req) +{ + fprintf(stderr, "handling request /upload%s\n", req->urltail); + + char http_test[] = "handling request /upload"; + picohttpResponseWrite(req, sizeof(http_test)-1, http_test); + if(req->urltail) { + picohttpResponseWrite(req, strlen(req->urltail), req->urltail); + } +} + int main(int argc, char *argv[]) { sockfd = socket(AF_INET, SOCK_STREAM, 0); @@ -170,11 +191,13 @@ int main(int argc, char *argv[]) .write = bsdsock_write, .getch = bsdsock_getch, .putch = bsdsock_putch, + .flush = bsdsock_flush, .data = &confd }; struct picohttpURLRoute routes[] = { { "/test", 0, rhTest, 16, PICOHTTP_METHOD_GET }, + { "/upload|", 0, rhUpload, 0, PICOHTTP_METHOD_GET }, { "/|", 0, rhRoot, 0, PICOHTTP_METHOD_GET }, { NULL, 0, 0, 0, 0 } }; diff --git a/test/bufbsdsocket.c b/test/bufbsdsocket.c index 596bc3d..22a4a99 100644 --- a/test/bufbsdsocket.c +++ b/test/bufbsdsocket.c @@ -6,12 +6,15 @@ #include #include #include +#include #include #include #include +#include #include +#include #include "../picohttp.h" @@ -57,7 +60,7 @@ int bufbsdsock_read(size_t count, char *buf, void *data_) assert(pfd.revents & (POLLIN | POLLPRI)); - if( -1 == ioctl(fd, FIONREAD, &avail) ) { + if( -1 == ioctl(data->fd, FIONREAD, &avail) ) { perror("ioctl(FIONREAD)"); return -1; } @@ -66,7 +69,7 @@ int bufbsdsock_read(size_t count, char *buf, void *data_) data->recvbuf = malloc( avail); int r; - while( 0 > (r = read(data->fd, data->recvbuf, avail)) ) + while( 0 > (r = read(data->fd, data->recvbuf, avail)) ) { if( EINTR == errno ) continue; @@ -119,11 +122,6 @@ int bufbsdsock_flush(void *data) return 0; } -int bsdsock_flush(void* data) -{ - return 0; -} - int sockfd = -1; void bye(void) @@ -255,11 +253,11 @@ int main(int argc, char *argv[]) } struct picohttpIoOps ioops = { - .read = bsdsock_read, - .write = bsdsock_write, - .getch = bsdsock_getch, - .putch = bsdsock_putch, - .flush = bsdsock_flush, + .read = bufbsdsock_read, + .write = bufbsdsock_write, + .getch = bufbsdsock_getch, + .putch = bufbsdsock_putch, + .flush = bufbsdsock_flush, .data = &confd }; -- cgit v1.2.3