From 2033101b3e9ca9fdc4efa8a658404594df67131f Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sun, 2 Aug 2009 18:49:55 -0700 Subject: http: process Content-Length and Transfer-Encoding Explicitly track if our request will need Content-Length or chunked body decoding. --- ext/unicorn_http/c_util.h | 56 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'ext/unicorn_http/c_util.h') diff --git a/ext/unicorn_http/c_util.h b/ext/unicorn_http/c_util.h index 78ad168..895c686 100644 --- a/ext/unicorn_http/c_util.h +++ b/ext/unicorn_http/c_util.h @@ -6,6 +6,9 @@ #ifndef UH_util_h #define UH_util_h +#include +#include + #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) #ifndef SIZEOF_OFF_T @@ -40,4 +43,57 @@ static void downcase_char(char *c) *c |= 0x20; } +static int hexchar2int(int xdigit) +{ + if (xdigit >= 'A' && xdigit <= 'F') + return xdigit - 'A' + 10; + if (xdigit >= 'a' && xdigit <= 'f') + return xdigit - 'a' + 10; + + /* Ragel already does runtime range checking for us in Unicorn: */ + assert(xdigit >= '0' && xdigit <= '9'); + + return xdigit - '0'; +} + +/* + * multiplies +i+ by +base+ and increments the result by the parsed + * integer value of +xdigit+. +xdigit+ is a character byte + * representing a number the range of 0..(base-1) + * returns the new value of +i+ on success + * returns -1 on errors (including overflow) + */ +static off_t step_incr(off_t i, int xdigit, const int base) +{ + static const off_t max = UH_OFF_T_MAX; + const off_t next_max = (max - (max % base)) / base; + off_t offset = hexchar2int(xdigit); + + if (offset > (base - 1)) + return -1; + if (i > next_max) + return -1; + i *= base; + + if ((offset > (base - 1)) || ((max - i) < offset)) + return -1; + + return i + offset; +} + +/* + * parses a non-negative length according to base-10 and + * returns it as an off_t value. Returns -1 on errors + * (including overflow). + */ +static off_t parse_length(const char *value, size_t length) +{ + off_t rv; + + for (rv = 0; length-- && rv >= 0; ++value) + rv = step_incr(rv, *value, 10); + + return rv; +} + #endif /* UH_util_h */ -- cgit v1.2.3-24-ge0c7