diff options
author | Eric Wong <e@80x24.org> | 2015-11-09 00:51:32 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2015-11-09 05:34:22 +0000 |
commit | f715f6f228f9da83309a515a94de26fa3766b230 (patch) | |
tree | 18632edeabb25092a733a4d96a362e62f52b95a5 /http_parser.rl | |
parent | 225d5fb10474d853261b6ee2f9ceeff9c2bd73c6 (diff) | |
download | cmogstored-f715f6f228f9da83309a515a94de26fa3766b230.tar.gz |
For completely unparseable Range: headers, we'll ignore them entirely as nginx does. However, if /bytes=/ is matched, we'll start returning 416 errors instead of 400.
Diffstat (limited to 'http_parser.rl')
-rw-r--r-- | http_parser.rl | 56 |
1 files changed, 37 insertions, 19 deletions
diff --git a/http_parser.rl b/http_parser.rl index 8e82828..5683b7d 100644 --- a/http_parser.rl +++ b/http_parser.rl @@ -21,6 +21,18 @@ static bool length_incr(off_t *len, unsigned c) return false; } +static char *skip_header(struct mog_http *http, char *buf, const char *pe) +{ + char *p; + + assert(http->_p.line_end > 0 && "no previous request/header line"); + assert(buf[http->_p.line_end] == '\n' && "bad http->_p.line_end"); + p = buf + http->_p.line_end + 1; + assert(p <= pe && "overflow"); + + return p; +} + %%{ machine http_parser; include http_common "http_common.rl"; @@ -69,20 +81,31 @@ static bool length_incr(off_t *len, unsigned c) "bytes=" > { http->_p.range_beg = http->_p.range_end = -1; } - (digit*) $ { - if (http->_p.range_beg < 0) - http->_p.range_beg = 0; - if (!length_incr(&http->_p.range_beg, fc)) - fbreak; - } - '-' - (digit*) $ { - if (http->_p.range_end < 0) - http->_p.range_end = 0; - if (!length_incr(&http->_p.range_end, fc)) - fbreak; + ( + (digit*) $ { + if (http->_p.range_beg < 0) + http->_p.range_beg = 0; + if (!length_incr(&http->_p.range_beg, + fc)) + fbreak; + } + '-' + (digit*) $ { + if (http->_p.range_end < 0) + http->_p.range_end = 0; + if (!length_incr(&http->_p.range_end, + fc)) + fbreak; + } + ) $! { + http->_p.bad_range = 1; + p = skip_header(http, buf, pe); + fgoto ignored_header; } - ) $! { errno = EINVAL; fbreak; } + ) $! { + p = skip_header(http, buf, pe); + fgoto ignored_header; + } eor @ { http->_p.has_range = 1; }; transfer_encoding_chunked = "Transfer-Encoding:"i sep "chunked"i eor > { http->_p.chunked = 1; }; @@ -102,12 +125,7 @@ static bool length_incr(off_t *len, unsigned c) content_md5 | connection ) $! { - assert(http->_p.line_end > 0 && - "no previous request/header line"); - assert(buf[http->_p.line_end] == '\n' && - "bad http->_p.line_end"); - p = buf + http->_p.line_end + 1; - assert(p <= pe && "overflow"); + p = skip_header(http, buf, pe); fgoto ignored_header; }; headers = header_line* '\r''\n' > { really_done = 1; fbreak; }; |