aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWolfgang Draxinger <Wolfgang.Draxinger@physik.uni-muenchen.de>2013-07-18 13:36:39 +0200
committerWolfgang Draxinger <Wolfgang.Draxinger@physik.uni-muenchen.de>2013-07-18 13:36:39 +0200
commitbee3c22a9a5156fe6a2b7f4a26b4d4f20cb7d8f1 (patch)
tree8168197742f7c86febddcfc4d37425e93ac4d6aa
parent97d36e88a0aa7d098aabb0916b59fceab6dbb2b1 (diff)
downloadlitheweb-bee3c22a9a5156fe6a2b7f4a26b4d4f20cb7d8f1.tar.gz
litheweb-bee3c22a9a5156fe6a2b7f4a26b4d4f20cb7d8f1.tar.bz2
multipart boundary handling breaks with CR CR ... CR runs
-rw-r--r--picohttp.c81
-rw-r--r--picohttp.h22
-rw-r--r--test/bsdsocket.c2
3 files changed, 54 insertions, 51 deletions
diff --git a/picohttp.c b/picohttp.c
index 15d8647..810fe1b 100644
--- a/picohttp.c
+++ b/picohttp.c
@@ -57,11 +57,11 @@ static char const PICOHTTP_STR_NAME__[] = " name=\"";
static char const PICOHTTP_STR_CHUNKED[] = "chunked";
/* compilation unit local function forward declarations */
-static int16_t picohttpProcessHeaders (
+static int picohttpProcessHeaders (
struct picohttpRequest * const req,
picohttpHeaderFieldCallback headerfieldcallback,
void * const data,
- int16_t ch );
+ int ch );
/* compilation unit local helper functions */
#if !defined(PICOHTTP_CONFIG_HAVE_LIBDJB)
@@ -99,7 +99,7 @@ static size_t picohttp_fmt_int(char *dest,int i) {
#define picohttp_fmt_int fmt_long
#endif
-static char const * const picohttpStatusString(int16_t code)
+static char const * const picohttpStatusString(int code)
{
switch(code) {
case 200:
@@ -121,14 +121,14 @@ static char const * const picohttpStatusString(int16_t code)
}
void picohttpStatusResponse(
- struct picohttpRequest *req, int16_t status )
+ struct picohttpRequest *req, int status )
{
req->status = status;
char const * const c = picohttpStatusString(req->status);
picohttpResponseWrite(req, strlen(c), c);
}
-static uint8_t picohttpIsCRLF(int16_t ch)
+static uint8_t picohttpIsCRLF(int ch)
{
switch(ch) {
case '\r':
@@ -138,16 +138,16 @@ static uint8_t picohttpIsCRLF(int16_t ch)
return 0;
}
-static uint8_t picohttpIsLWS(int16_t ch)
+static uint8_t picohttpIsLWS(int ch)
{
return
picohttpIsCRLF(ch) ||
' ' == ch || '\t' == ch;
}
-static int16_t picohttpIoSkipSpace (
+static int picohttpIoSkipSpace (
struct picohttpIoOps const * const ioops,
- int16_t ch)
+ int ch)
{
for(;;ch = -1) {
if(0 > ch) {
@@ -161,9 +161,9 @@ static int16_t picohttpIoSkipSpace (
return ch;
}
-static int16_t picohttpIoSkipOverCRLF (
+static int picohttpIoSkipOverCRLF (
struct picohttpIoOps const * const ioops,
- int16_t ch)
+ int ch)
{
for(;;ch = -1) {
if(0 > ch) {
@@ -192,10 +192,10 @@ static int16_t picohttpIoSkipOverCRLF (
return ch;
}
-static int16_t picohttpIoB10ToU8 (
+static int picohttpIoB10ToU8 (
uint8_t *i,
struct picohttpIoOps const * const ioops,
- int16_t ch )
+ int ch )
{
if( 0 > ch )
ch = picohttpIoGetch(ioops);
@@ -209,10 +209,10 @@ static int16_t picohttpIoB10ToU8 (
return ch;
}
-static int16_t picohttpIoB10ToU64 (
+static int picohttpIoB10ToU64 (
uint64_t *i,
struct picohttpIoOps const * const ioops,
- int16_t ch )
+ int ch )
{
if( 0 > ch )
ch = picohttpIoGetch(ioops);
@@ -226,11 +226,11 @@ static int16_t picohttpIoB10ToU64 (
return ch;
}
-static int16_t picohttpIoGetPercentCh(
+static int picohttpIoGetPercentCh(
struct picohttpIoOps const * const ioops )
{
char ch=0;
- int16_t chr;
+ int chr;
if( 0 > (chr = picohttpIoGetch(ioops)))
return chr;
@@ -256,9 +256,9 @@ static int16_t picohttpIoGetPercentCh(
return ch;
}
-int16_t picohttpGetch(struct picohttpRequest * const req)
+int picohttpGetch(struct picohttpRequest * const req)
{
- int16_t ch;
+ int ch;
/* skipping over Chunked Transfer Boundaries
* if Chunked Transfer Encoding is used */
if(req->query.transferencoding == PICOHTTP_CODING_CHUNKED ) {
@@ -338,7 +338,7 @@ int picohttpRead(struct picohttpRequest * const req, size_t len, char * const bu
* if Chunked Transfer Encoding is used */
if(req->query.transferencoding == PICOHTTP_CODING_CHUNKED ) {
if( !req->query.chunklength ) {
- int16_t ch;
+ int ch;
/* this is a new chunk;
* read the length and skip to after <CR><LF> */
if( 0 > (ch = picohttpIoGetch(req->ioops)) ) {
@@ -384,7 +384,7 @@ int picohttpRead(struct picohttpRequest * const req, size_t len, char * const bu
if(req->query.transferencoding == PICOHTTP_CODING_CHUNKED ) {
if( !req->query.chunklength <= req->received_octets ) {
- int16_t ch;
+ int ch;
/* end of chunk;
* skip over <CR><LF>, make sure the trailing '0' is
* there and read the headers, err, I mean footers
@@ -470,10 +470,10 @@ static int8_t picohttpMatchRoute(
return 0;
}
-static int16_t picohttpProcessRequestMethod (
+static int picohttpProcessRequestMethod (
struct picohttpIoOps const * const ioops )
{
- int16_t method = 0;
+ int method = 0;
/* Poor man's string matching tree; trade RAM for code */
switch( picohttpIoGetch(ioops) ) {
@@ -533,10 +533,10 @@ static int16_t picohttpProcessRequestMethod (
return method;
}
-static int16_t picohttpProcessURL (
+static int picohttpProcessURL (
struct picohttpRequest * const req,
size_t const url_max_length,
- int16_t ch )
+ int ch )
{
/* copy url up to the first query component; note that this is not
* fully compliant to RFC 3986, which permits query components in each
@@ -572,9 +572,9 @@ static int16_t picohttpProcessURL (
return ch;
}
-static int16_t picohttpProcessQuery (
+static int picohttpProcessQuery (
struct picohttpRequest * const req,
- int16_t ch )
+ int ch )
{
size_t var_max_length = 0;
if(req->route->get_vars) {
@@ -651,9 +651,9 @@ static int16_t picohttpProcessQuery (
return ch;
}
-static int16_t picohttpProcessHTTPVersion (
+static int picohttpProcessHTTPVersion (
struct picohttpRequest * const req,
- int16_t ch )
+ int ch )
{
if( !picohttpIsCRLF(ch) ) {
@@ -703,10 +703,10 @@ static int16_t picohttpProcessHTTPVersion (
return ch;
}
-static uint16_t picohttpProcessContentType(
+static int picohttpProcessContentType(
char const **contenttype)
{
- uint16_t ct = 0;
+ int ct = 0;
if(!strncmp(*contenttype,
PICOHTTP_STR_APPLICATION_, sizeof(PICOHTTP_STR_APPLICATION_)-1)) {
ct = PICOHTTP_CONTENTTYPE_APPLICATION;
@@ -799,11 +799,11 @@ static void picohttpProcessHeaderField(
}
}
-static int16_t picohttpProcessHeaders (
+static int picohttpProcessHeaders (
struct picohttpRequest * const req,
picohttpHeaderFieldCallback headerfieldcallback,
void * const data,
- int16_t ch )
+ int ch )
{
#define PICOHTTP_HEADERNAME_MAX_LEN 32
char headername[PICOHTTP_HEADERNAME_MAX_LEN+1] = {0,};
@@ -890,7 +890,7 @@ void picohttpProcessRequest (
struct picohttpURLRoute const * const routes )
{
- int16_t ch;
+ int ch;
struct picohttpRequest request = {0,};
size_t url_max_length = 0;
@@ -1113,10 +1113,10 @@ int picohttpResponseWrite (
return len;
}
-int16_t picohttpMultipartGetch(
+int picohttpMultipartGetch(
struct picohttpMultipart * const mp)
{
- int16_t ch;
+ int ch;
if( mp->finished ) {
return -1;
} else
@@ -1132,6 +1132,8 @@ int16_t picohttpMultipartGetch(
return ch;
}
} else {
+ mp->replay = 0;
+
ch = picohttpGetch(mp->req);
/* picohttp's query and header parsing is forgiving
@@ -1141,10 +1143,11 @@ int16_t picohttpMultipartGetch(
* a <CR><LF> sequence.
*/
- mp->replay = 0;
if( '\r' == ch ) {
mp->replayhead =
mp->in_boundary = 0;
+ if( '\r' == mp->req->query.prev_ch[1] )
+ return '\r';
} else
if( '\n' == ch &&
'\r' == mp->req->query.prev_ch[1] ) {
@@ -1157,7 +1160,7 @@ int16_t picohttpMultipartGetch(
) {
mp->replayhead =
mp->in_boundary = 2;
- }
+ }
while( 0 <= ch ) {
@@ -1252,7 +1255,7 @@ int picohttpMultipartRead(
* Probably a lot of code would be shared with the ...Getch variant
* and could be placed into a commonly used function.
*/
- int16_t ch;
+ int ch;
size_t i;
for(i = 0; i < len; i++) {
if( 0 > (ch = picohttpMultipartGetch(mp)) ) {
@@ -1357,7 +1360,7 @@ int picohttpMultipartNext(
}
for(;;) {
- int16_t ch = picohttpMultipartGetch(mp);
+ int ch = picohttpMultipartGetch(mp);
if( 0 > ch ) {
if( 2 == mp->finished ) {
return -1;
diff --git a/picohttp.h b/picohttp.h
index 8afa022..380584c 100644
--- a/picohttp.h
+++ b/picohttp.h
@@ -49,7 +49,7 @@
struct picohttpIoOps {
int (*read)(size_t /*count*/, char* /*buf*/, void*);
int (*write)(size_t /*count*/, char const* /*buf*/, void*);
- int16_t (*getch)(void*); // returns negative value on error
+ int (*getch)(void*); // returns negative value on error
int (*putch)(char, void*);
int (*flush)(void*);
void *data;
@@ -88,8 +88,8 @@ struct picohttpURLRoute {
char const * urlhead;
struct picohttpVarSpec const * get_vars;
picohttpHandler handler;
- uint16_t max_urltail_len;
- int16_t allowed_methods;
+ unsigned int max_urltail_len;
+ int allowed_methods;
};
#define PICOHTTP_EPOCH_YEAR 1970
@@ -109,14 +109,14 @@ struct picohttpRequest {
struct picohttpVar *get_vars;
char *url;
char *urltail;
- int16_t status;
- int16_t method;
+ int status;
+ int method;
struct {
uint8_t major;
uint8_t minor;
} httpversion;
struct {
- uint16_t contenttype;
+ int contenttype;
size_t contentlength;
uint8_t contentencoding;
uint8_t transferencoding;
@@ -128,7 +128,7 @@ struct picohttpRequest {
char const *contenttype;
char const *disposition;
struct picohttpDateTime lastmodified;
- uint16_t max_age;
+ int max_age;
size_t contentlength;
uint8_t contentencoding;
uint8_t transferencoding;
@@ -143,7 +143,7 @@ struct picohttpRequest {
struct picohttpMultipart {
struct picohttpRequest *req;
uint8_t finished;
- uint16_t contenttype;
+ int contenttype;
struct {
char name[PICOHTTP_DISPOSITION_NAME_MAX+1];
} disposition;
@@ -162,7 +162,7 @@ void picohttpProcessRequest(
struct picohttpURLRoute const * const routes );
void picohttpStatusResponse(
- struct picohttpRequest *req, int16_t status );
+ struct picohttpRequest *req, int status );
int picohttpResponseSendHeader (
struct picohttpRequest * const req );
@@ -172,7 +172,7 @@ int picohttpResponseWrite (
size_t len,
char const *buf );
-int16_t picohttpGetch(struct picohttpRequest * const req);
+int picohttpGetch(struct picohttpRequest * const req);
struct picohttpMultipart picohttpMultipartStart(
struct picohttpRequest * const req);
@@ -180,7 +180,7 @@ struct picohttpMultipart picohttpMultipartStart(
int picohttpMultipartNext(
struct picohttpMultipart * const mp);
-int16_t picohttpMultipartGetch(
+int picohttpMultipartGetch(
struct picohttpMultipart * const mp);
int picohttpMultipartRead(
diff --git a/test/bsdsocket.c b/test/bsdsocket.c
index b2d66c1..cb06d58 100644
--- a/test/bsdsocket.c
+++ b/test/bsdsocket.c
@@ -67,7 +67,7 @@ int bsdsock_write(size_t count, char const *buf, void *data)
return wb;
}
-int16_t bsdsock_getch(void *data)
+int bsdsock_getch(void *data)
{
char ch;
int err;