From 9427f2989eae96106090d77ddff1656f8510957d Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Tue, 19 Mar 2013 09:33:47 +0000 Subject: http: put parser-private attrs in a private struct This will allow easy use of memset to reset attributes in between requests without clobbering more important data. --- chunk_parser.rl | 48 +++++++++---------- cmogstored.h | 36 ++++++++------- http.c | 46 +++++++++--------- http_common.rl | 32 +++++++------ http_get.c | 50 ++++++++++---------- http_parser.rl | 76 +++++++++++++++--------------- http_put.c | 126 +++++++++++++++++++++++++------------------------- test/chunk-parser-1.c | 58 +++++++++++------------ test/http-parser-1.c | 112 ++++++++++++++++++++++---------------------- 9 files changed, 295 insertions(+), 289 deletions(-) diff --git a/chunk_parser.rl b/chunk_parser.rl index 9234f71..926db26 100644 --- a/chunk_parser.rl +++ b/chunk_parser.rl @@ -26,69 +26,69 @@ static inline off_t hexchar2off(int xdigit) off_t buf_remain; size_t wr_len; - if (http->content_len == 0) { /* final chunk */ - http->chunk_state = MOG_CHUNK_STATE_TRAILER; + if (http->_p.content_len == 0) { /* final chunk */ + http->_p.chunk_state = MOG_CHUNK_STATE_TRAILER; fhold; /* XXX this feels wrong ... */ if (fpc >= buf) { assert(fc == '\n' && "bad chunk end"); - http->line_end = to_u16(fpc - buf); + http->_p.line_end = to_u16(fpc - buf); } fgoto more_trailers; } - assert(http->content_len > 0 && "impossible content_len"); + assert(http->_p.content_len > 0 && "impossible content_len"); buf_remain = len - (fpc - buf); if (buf_remain == 0) fbreak; assert(buf_remain > 0 && "impossible buf_remain"); - wr_len = MIN((size_t)http->content_len, (size_t)buf_remain); + wr_len = MIN((size_t)http->_p.content_len, (size_t)buf_remain); assert(wr_len != 0 && "invalid wr_len"); if (! mog_http_write_full(http->forward, fpc, wr_len)) fbreak; - http->content_len -= wr_len; + http->_p.content_len -= wr_len; p += wr_len - 1; assert(p < pe && "buffer overrun"); - if (http->content_len > 0) { + if (http->_p.content_len > 0) { really_done = 1; /* let caller handle reading the rest of the body */ fbreak; } /* next chunk header */ - http->chunk_state = MOG_CHUNK_STATE_SIZE; + http->_p.chunk_state = MOG_CHUNK_STATE_SIZE; if (wr_len == buf_remain) { - if (http->content_len == 0) + if (http->_p.content_len == 0) fgoto main; really_done = 1; fbreak; } /* more chunks in this buffer */ - assert(http->content_len == 0 && + assert(http->_p.content_len == 0 && "bad content_len at chunk end"); fgoto main; }; chunk = "\r\n"? # account for trailing CRLF in previous chunk (xdigit+) $ { - off_t prev = http->content_len; + off_t prev = http->_p.content_len; - http->content_len *= 16; - http->content_len += hexchar2off(fc); - if (http->content_len < prev) { + http->_p.content_len *= 16; + http->_p.content_len += hexchar2off(fc); + if (http->_p.content_len < prev) { errno = ERANGE; - http->content_len = -1; + http->_p.content_len = -1; fbreak; } } (any -- [\r\n])* - '\r' '\n' @ { http->chunk_state = MOG_CHUNK_STATE_DATA; } + '\r' '\n' @ { http->_p.chunk_state = MOG_CHUNK_STATE_DATA; } chunk_data; main := chunk+; }%% @@ -100,12 +100,12 @@ void mog_chunk_init(struct mog_http *http) int cs; %% write init; - assert(http->chunked && "not chunked"); + assert(http->_p.chunked && "not chunked"); http->cs = cs; - http->line_end = 0; - http->content_len = 0; - http->offset = 0; - http->chunk_state = MOG_CHUNK_STATE_SIZE; + http->_p.line_end = 0; + http->_p.content_len = 0; + http->_p.offset = 0; + http->_p.chunk_state = MOG_CHUNK_STATE_SIZE; } enum mog_parser_state @@ -114,7 +114,7 @@ mog_chunk_parse(struct mog_http *http, char *buf, size_t len) char *p, *pe, *eof = NULL; int cs = http->cs; int really_done = 0; - size_t off = http->offset; + size_t off = http->_p.offset; assert(http->wbuf == NULL && "unwritten data in buffer"); assert(off <= len && "http offset past end of buffer"); @@ -132,13 +132,13 @@ mog_chunk_parse(struct mog_http *http, char *buf, size_t len) cs = chunk_parser_first_final; http->cs = cs; - http->offset = p - buf; + http->_p.offset = p - buf; if (cs == chunk_parser_error || errno) return MOG_PARSER_ERROR; assert(p <= pe && "buffer overflow after chunk parse"); - assert(http->offset <= len && "offset longer than len"); + assert(http->_p.offset <= len && "offset longer than len"); if (http->cs == chunk_parser_first_final) return MOG_PARSER_DONE; return MOG_PARSER_CONTINUE; diff --git a/cmogstored.h b/cmogstored.h index e72c071..1681e1e 100644 --- a/cmogstored.h +++ b/cmogstored.h @@ -169,24 +169,26 @@ enum mog_chunk_state { struct mog_http { int cs; - enum mog_http_method http_method:8; - unsigned persistent:1; - unsigned chunked:1; - unsigned has_trailer_md5:1; - unsigned has_expect_md5:1; - unsigned has_content_range:1; /* for PUT */ - unsigned has_range:1; /* for GET */ - unsigned skip_rbuf_defer:1; - enum mog_chunk_state chunk_state:2; - uint8_t path_tip; - uint8_t path_end; - uint16_t line_end; - uint16_t tmp_tip; + struct { + enum mog_http_method http_method:8; + unsigned persistent:1; + unsigned chunked:1; + unsigned has_trailer_md5:1; + unsigned has_expect_md5:1; + unsigned has_content_range:1; /* for PUT */ + unsigned has_range:1; /* for GET */ + unsigned skip_rbuf_defer:1; + enum mog_chunk_state chunk_state:2; + uint8_t path_tip; + uint8_t path_end; + uint16_t line_end; + uint16_t tmp_tip; + size_t offset; + off_t range_beg; + off_t range_end; + off_t content_len; + } _p; struct mog_fd *forward; - size_t offset; - off_t range_beg; - off_t range_end; - off_t content_len; struct mog_rbuf *rbuf; struct mog_wbuf *wbuf; /* uncommonly needed */ struct mog_svc *svc; diff --git a/http.c b/http.c index 1485eb2..4519498 100644 --- a/http.c +++ b/http.c @@ -33,15 +33,15 @@ static void http_defer_rbuf(struct mog_http *http, struct mog_rbuf *rbuf, size_t buf_len) { struct mog_rbuf *old = http->rbuf; - size_t defer_bytes = buf_len - http->offset; - char *src = rbuf->rptr + http->offset; + size_t defer_bytes = buf_len - http->_p.offset; + char *src = rbuf->rptr + http->_p.offset; - if (http->skip_rbuf_defer) { - http->skip_rbuf_defer = 0; + if (http->_p.skip_rbuf_defer) { + http->_p.skip_rbuf_defer = 0; return; } - assert(http->offset >= 0 && "http->offset negative"); + assert(http->_p.offset >= 0 && "http->_p.offset negative"); assert(defer_bytes <= MOG_RBUF_MAX_SIZE && "defer bytes overflow"); if (defer_bytes == 0) { @@ -55,13 +55,13 @@ http_defer_rbuf(struct mog_http *http, struct mog_rbuf *rbuf, size_t buf_len) memcpy(http->rbuf->rptr, src, defer_bytes); http->rbuf->rsize = defer_bytes; } - http->offset = 0; + http->_p.offset = 0; } static void http_process_client(struct mog_http *http, char *buf, size_t buf_len) { - switch (http->http_method) { + switch (http->_p.http_method) { case MOG_HTTP_METHOD_NONE: assert(0 && "BUG: unset HTTP method"); case MOG_HTTP_METHOD_GET: mog_http_get_open(http, buf); break; case MOG_HTTP_METHOD_HEAD: mog_http_get_open(http, buf); break; @@ -99,10 +99,10 @@ static enum mog_next http_wbuf_in_progress(struct mog_http *http) case MOG_WRSTATE_ERR: return MOG_NEXT_CLOSE; case MOG_WRSTATE_DONE: - if (!http->persistent) return MOG_NEXT_CLOSE; + if (!http->_p.persistent) return MOG_NEXT_CLOSE; if (http->forward == NULL) mog_http_reset(http); - assert(http->offset == 0 && "bad offset"); + assert(http->_p.offset == 0 && "bad offset"); return MOG_NEXT_ACTIVE; case MOG_WRSTATE_BUSY: /* unlikely, we never put anything big in wbuf */ @@ -114,7 +114,7 @@ static enum mog_next http_wbuf_in_progress(struct mog_http *http) static enum mog_next http_forward_in_progress(struct mog_fd *mfd) { - enum mog_http_method method = mfd->as.http.http_method; + enum mog_http_method method = mfd->as.http._p.http_method; if (method == MOG_HTTP_METHOD_GET) return mog_http_get_in_progress(mfd); @@ -142,15 +142,16 @@ static enum mog_next http_queue_step(struct mog_fd *mfd) /* we may have pipelined data in http->rbuf */ rbuf = http->rbuf ? http->rbuf : mog_rbuf_get(MOG_RBUF_BASE_SIZE); buf = rbuf->rptr; - off = http->offset; + off = http->_p.offset; assert(off >= 0 && "offset is negative"); assert(off < rbuf->rcapa && "offset is too big"); if (http->rbuf) { /* request got pipelined, resuming now */ buf_len = http->rbuf->rsize; - assert(http->offset <= buf_len && "bad offset from pipelining"); + assert(http->_p.offset <= buf_len + && "bad offset from pipelining"); assert(buf_len <= http->rbuf->rcapa && "bad rsize stashed"); - if (http->offset < buf_len) + if (http->_p.offset < buf_len) goto parse; } reread: @@ -166,14 +167,14 @@ parse: case MOG_PARSER_CONTINUE: assert(http->wbuf == NULL && "tried to write (and failed) with partial req"); - if (http->offset >= rbuf->rcapa) { + if (http->_p.offset >= rbuf->rcapa) { rbuf->rsize = buf_len; http->rbuf = rbuf = mog_rbuf_grow(rbuf); if (!rbuf) goto err400; buf = rbuf->rptr; } - off = http->offset; + off = http->_p.offset; goto reread; case MOG_PARSER_DONE: http_process_client(http, buf, buf_len); @@ -185,7 +186,7 @@ parse: } else if (http->forward) { http_defer_rbuf(http, rbuf, buf_len); return http_forward_in_progress(mfd); - } else if (!http->persistent) { + } else if (!http->_p.persistent) { return MOG_NEXT_CLOSE; } else { http_defer_rbuf(http, rbuf, buf_len); @@ -288,15 +289,16 @@ void mog_httpget_post_accept(int fd, struct mog_svc *svc) */ char *mog_http_path(struct mog_http *http, char *buf) { - char *path = buf + http->path_tip; - size_t len = http->path_end - http->path_tip; + char *path = buf + http->_p.path_tip; + size_t len = http->_p.path_end - http->_p.path_tip; - assert(http->path_end > http->path_tip && "bad HTTP path from parser"); + assert(http->_p.path_end > http->_p.path_tip + && "bad HTTP path from parser"); if (! mog_valid_path(path, len)) return NULL; - if (http->http_method == MOG_HTTP_METHOD_PUT) { + if (http->_p.http_method == MOG_HTTP_METHOD_PUT) { if (!mog_valid_put_path(path, len)) { errno = EINVAL; return NULL; @@ -330,12 +332,12 @@ mog_http_resp0( dst = CPY("\r\nDate: "); now = mog_now(); dst = mempcpy(dst, now->httpdate, sizeof(now->httpdate)-1); - if (alive && http->persistent) { + if (alive && http->_p.persistent) { dst = CPY("\r\nContent-Length: 0" "\r\nContent-Type: text/plain" "\r\nConnection: keep-alive\r\n\r\n"); } else { - http->persistent = 0; + http->_p.persistent = 0; dst = CPY("\r\nContent-Length: 0" "\r\nContent-Type: text/plain" "\r\nConnection: close\r\n\r\n"); diff --git a/http_common.rl b/http_common.rl index 8df5fed..de54bc1 100644 --- a/http_common.rl +++ b/http_common.rl @@ -6,18 +6,20 @@ machine http_common; LWS = (' ' | '\t'); - LF = '\n' > { http->line_end = to_u16(fpc - buf); }; + LF = '\n' > { http->_p.line_end = to_u16(fpc - buf); }; eor = LWS*'\r'LF; CTL = (cntrl | 127); header_name = [a-zA-Z0-9\-]+; header_value = (any -- (LWS|CTL))(any -- CTL)*; sep = (LWS*)|(eor LWS+); - b64_val = ([a-zA-Z0-9/+]{22}) > { http->tmp_tip = to_u16(fpc - buf); } - "==" - eor > { + b64_val = ([a-zA-Z0-9/+]{22}) > { + http->_p.tmp_tip = to_u16(fpc - buf); + } + "==" + eor > { uint16_t tmp_end = to_u16(fpc - buf); - char *in = buf + http->tmp_tip; - size_t inlen = tmp_end - http->tmp_tip; + char *in = buf + http->_p.tmp_tip; + size_t inlen = tmp_end - http->_p.tmp_tip; char *out = (char *)http->expect_md5; size_t outlen = sizeof(http->expect_md5); bool rc; @@ -25,10 +27,10 @@ rc = base64_decode_ctx(NULL, in, inlen, out, &outlen); assert(rc == true && outlen == 16 && "base64_decoder broke for HTTP"); - http->has_expect_md5 = 1; - }; + http->_p.has_expect_md5 = 1; + }; content_md5 = "Content-MD5:"i sep ( b64_val ) $! { - if (!http->has_expect_md5) { + if (!http->_p.has_expect_md5) { errno = EINVAL; fbreak; } @@ -38,10 +40,10 @@ }; trailer_line = ( content_md5 ) $! { - if (http->line_end > 0) { - assert(buf[http->line_end] == '\n' - && "bad http->line_end"); - p = buf + http->line_end + 1; + if (http->_p.line_end > 0) { + assert(buf[http->_p.line_end] == '\n' + && "bad http->_p.line_end"); + p = buf + http->_p.line_end + 1; } else { p = buf; } @@ -49,8 +51,8 @@ fgoto ignored_trailer; }; trailers = trailer_line* '\r''\n' > { - http->chunk_state = MOG_CHUNK_STATE_DONE; - http->line_end = to_u16(fpc - buf); + http->_p.chunk_state = MOG_CHUNK_STATE_DONE; + http->_p.line_end = to_u16(fpc - buf); really_done = 1; fbreak; }; diff --git a/http_get.c b/http_get.c index a104b47..cb3a6eb 100644 --- a/http_get.c +++ b/http_get.c @@ -60,42 +60,42 @@ static off_t http_get_resp_hdr(struct mog_http *http, struct stat *sb) mog_http_date(modified, MOG_HTTPDATE_CAPA, &sb->st_mtime); /* validate ranges */ - if (http->has_range) { + if (http->_p.has_range) { long long offset; - if (http->range_end < 0 && http->range_beg < 0) + if (http->_p.range_end < 0 && http->_p.range_beg < 0) goto bad_range; - if (http->range_beg >= sb->st_size) + if (http->_p.range_beg >= sb->st_size) goto bad_range; /* bytes=M-N where M > N */ - if (http->range_beg >= 0 && http->range_end >= 0 - && http->range_beg > http->range_end) + if (http->_p.range_beg >= 0 && http->_p.range_end >= 0 + && http->_p.range_beg > http->_p.range_end) goto bad_range; - if (http->range_end < 0) { /* bytes=M- */ + if (http->_p.range_end < 0) { /* bytes=M- */ /* bytes starting at M until EOF */ - assert(http->range_beg >= 0 && "should've sent 416"); - offset = (long long)http->range_beg; + assert(http->_p.range_beg >= 0 && "should've sent 416"); + offset = (long long)http->_p.range_beg; count = (long long)(sb->st_size - offset); - } else if (http->range_beg < 0) { /* bytes=-N */ + } else if (http->_p.range_beg < 0) { /* bytes=-N */ /* last N bytes */ - assert(http->range_end >= 0 && "should've sent 416"); - offset = (long long)(sb->st_size - http->range_end); + assert(http->_p.range_end >= 0 && "should've sent 416"); + offset = (long long)(sb->st_size - http->_p.range_end); /* serve the entire file if client requested too much */ if (offset < 0) goto resp_200; count = (long long)(sb->st_size - offset); } else { /* bytes=M-N*/ - assert(http->range_beg >= 0 && http->range_end >= 0 + assert(http->_p.range_beg >= 0 && http->_p.range_end >= 0 && "should've sent 416"); - offset = (long long)http->range_beg; + offset = (long long)http->_p.range_beg; /* truncate responses to current file size */ - if (http->range_end >= sb->st_size) - http->range_end = sb->st_size - 1; - count = (long long)http->range_end + 1 - offset; + if (http->_p.range_end >= sb->st_size) + http->_p.range_end = sb->st_size - 1; + count = (long long)http->_p.range_end + 1 - offset; } assert(count > 0 && "bad count for 206 response"); @@ -123,7 +123,7 @@ static off_t http_get_resp_hdr(struct mog_http *http, struct stat *sb) count, /* Content-Length */ offset, offset + count - 1, /* bytes M-N */ (long long)sb->st_size, - http->persistent ? "keep-alive" : "close"); + http->_p.persistent ? "keep-alive" : "close"); } else { resp_200: count = (long long)sb->st_size; @@ -140,7 +140,7 @@ resp_200: now->httpdate, modified, count, - http->persistent ? "keep-alive" : "close"); + http->_p.persistent ? "keep-alive" : "close"); } /* TODO: put down the crack pipe and refactor this */ @@ -151,7 +151,7 @@ bad_range: mog_file_close(http->forward); http->forward = NULL; } else { - assert(http->http_method == MOG_HTTP_METHOD_HEAD + assert(http->_p.http_method == MOG_HTTP_METHOD_HEAD && "not HTTP HEAD"); } rc = snprintf(buf, len, @@ -165,14 +165,14 @@ bad_range: "\r\n", now->httpdate, (long long)sb->st_size, - http->persistent ? "keep-alive" : "close"); + http->_p.persistent ? "keep-alive" : "close"); } assert(rc > 0 && rc < len && "we suck at snprintf"); len = (size_t)rc; assert(http->wbuf == NULL && "tried to write to a busy client"); - if (http->http_method == MOG_HTTP_METHOD_HEAD) + if (http->_p.http_method == MOG_HTTP_METHOD_HEAD) count = 0; http->wbuf = mog_trysend(mog_fd_of(http)->fd, buf, len, (off_t)count); @@ -194,7 +194,7 @@ void mog_http_get_open(struct mog_http *http, char *buf) if (path[1] == '\0') { /* keep "mogadm check" happy */ sb.st_mtime = 0; sb.st_size = 0; - } else if (http->http_method == MOG_HTTP_METHOD_HEAD) { + } else if (http->_p.http_method == MOG_HTTP_METHOD_HEAD) { if (mog_stat(http->svc, path, &sb) < 0) goto err; if (!S_ISREG(sb.st_mode)) goto forbidden; } else { @@ -272,20 +272,20 @@ retry: case_EAGAIN: return MOG_NEXT_WAIT_WR; case EINTR: goto retry; } - http->persistent = 0; + http->_p.persistent = 0; } else { /* w == 0 */ /* * if we can't fulfill the value set by our Content-Length: * header, we must kill the TCP connection */ - http->persistent = 0; + http->_p.persistent = 0; syslog(LOG_ERR, "sendfile()-d 0 bytes at offset=%lld; file truncated?", (long long)file->foff); } done: mog_file_close(http->forward); - if (http->persistent) { + if (http->_p.persistent) { mog_http_reset(http); return MOG_NEXT_ACTIVE; } diff --git a/http_parser.rl b/http_parser.rl index d84d0ce..a643862 100644 --- a/http_parser.rl +++ b/http_parser.rl @@ -30,69 +30,69 @@ static bool length_incr(off_t *len, unsigned c) }; mog_path = '/'[a-zA-Z0-9/\.\-]{0,36}; # only stuff MogileFS will use - GET = "GET "> { http->http_method = MOG_HTTP_METHOD_GET; }; - HEAD = "HEAD "> { http->http_method = MOG_HTTP_METHOD_HEAD; }; - PUT = "PUT "> { http->http_method = MOG_HTTP_METHOD_PUT; }; - DELETE = "DELETE "> { http->http_method = MOG_HTTP_METHOD_DELETE; }; - MKCOL = "MKCOL "> { http->http_method = MOG_HTTP_METHOD_MKCOL; }; + GET = "GET "> { http->_p.http_method = MOG_HTTP_METHOD_GET; }; + HEAD = "HEAD "> { http->_p.http_method = MOG_HTTP_METHOD_HEAD; }; + PUT = "PUT "> { http->_p.http_method = MOG_HTTP_METHOD_PUT; }; + DELETE = "DELETE "> { http->_p.http_method = MOG_HTTP_METHOD_DELETE; }; + MKCOL = "MKCOL "> { http->_p.http_method = MOG_HTTP_METHOD_MKCOL; }; # no HTTP/0.9 for now, sorry (not :P) req_line = (HEAD|GET|PUT|DELETE|MKCOL) ("http://" [^/]+)? - '/'*(mog_path) > { http->path_tip = to_u8(fpc - buf); } + '/'*(mog_path) > { http->_p.path_tip = to_u8(fpc - buf); } # TODO: maybe folks use query string/fragments for logging... - (" HTTP/1.") > { http->path_end = to_u8(fpc - buf); } - ('0'|'1'> { http->persistent = 1; }) '\r'LF; + (" HTTP/1.") > { http->_p.path_end = to_u8(fpc - buf); } + ('0'|'1'> { http->_p.persistent = 1; }) '\r'LF; content_length = "Content-Length:"i sep (digit+) $ { - if (!length_incr(&http->content_len, fc)) + if (!length_incr(&http->_p.content_len, fc)) fbreak; } $! { errno = EINVAL; fbreak; } eor; content_range = "Content-Range:"i sep "bytes"LWS+ (digit+) $ { - if (!length_incr(&http->range_beg, fc)) + if (!length_incr(&http->_p.range_beg, fc)) fbreak; } $! { errno = EINVAL; fbreak; } "-" (digit+) $ { - if (!length_incr(&http->range_end, fc)) + if (!length_incr(&http->_p.range_end, fc)) fbreak; } $! { errno = EINVAL; fbreak; } "/*" - eor > { http->has_content_range = 1; }; + eor > { http->_p.has_content_range = 1; }; range = "Range:"i sep ( "bytes=" > { - http->range_beg = http->range_end = -1; + http->_p.range_beg = http->_p.range_end = -1; } (digit*) $ { - if (http->range_beg < 0) - http->range_beg = 0; - if (!length_incr(&http->range_beg, fc)) + if (http->_p.range_beg < 0) + http->_p.range_beg = 0; + if (!length_incr(&http->_p.range_beg, fc)) fbreak; } '-' (digit*) $ { - if (http->range_end < 0) - http->range_end = 0; - if (!length_incr(&http->range_end, fc)) + if (http->_p.range_end < 0) + http->_p.range_end = 0; + if (!length_incr(&http->_p.range_end, fc)) fbreak; } ) $! { errno = EINVAL; fbreak; } - eor @ { http->has_range = 1; }; + eor @ { http->_p.has_range = 1; }; transfer_encoding_chunked = "Transfer-Encoding:"i sep - "chunked"i eor > { http->chunked = 1; }; + "chunked"i eor > { http->_p.chunked = 1; }; trailer = "Trailer:"i sep - (("Content-MD5"i @ { http->has_trailer_md5 = 1; }) + (("Content-MD5"i @ { http->_p.has_trailer_md5 = 1; }) | header_name | ',') eor; connection = "Connection:"i sep - (("close"i @ { http->persistent = 0; }) | - ("keep-alive"i @ { http->persistent = 1; })) eor; + (("close"i @ { http->_p.persistent = 0; }) | + ("keep-alive"i @ { http->_p.persistent = 1; })) eor; header_line = ( content_length | transfer_encoding_chunked | @@ -102,11 +102,11 @@ static bool length_incr(off_t *len, unsigned c) content_md5 | connection ) $! { - assert(http->line_end > 0 && + assert(http->_p.line_end > 0 && "no previous request/header line"); - assert(buf[http->line_end] == '\n' && - "bad http->line_end"); - p = buf + http->line_end + 1; + assert(buf[http->_p.line_end] == '\n' && + "bad http->_p.line_end"); + p = buf + http->_p.line_end + 1; assert(p <= pe && "overflow"); fgoto ignored_header; }; @@ -120,21 +120,21 @@ static bool length_incr(off_t *len, unsigned c) void mog_http_reset_parser(struct mog_http *http) { int cs; - struct mog_rbuf *rbuf = http->rbuf; - struct mog_svc *svc = http->svc; %% write init; - memset(http, 0, sizeof(struct mog_http)); http->cs = cs; - http->rbuf = rbuf; - http->svc = svc; + memset(&http->_p, 0, sizeof(http->_p)); + + /* these should probably be in mog_http_init */ + http->forward = NULL; + http->wbuf = NULL; } void mog_http_init(struct mog_http *http, struct mog_svc *svc) { - http->svc = svc; - http->rbuf = NULL; mog_http_reset_parser(http); + http->rbuf = NULL; + http->svc = svc; } enum mog_parser_state @@ -143,7 +143,7 @@ mog_http_parse(struct mog_http *http, char *buf, size_t len) char *p, *pe, *eof = NULL; int cs = http->cs; int really_done = 0; - size_t off = http->offset; + size_t off = http->_p.offset; assert(http->wbuf == NULL && "unwritten data in buffer"); assert(off <= len && "http offset past end of buffer"); @@ -161,13 +161,13 @@ mog_http_parse(struct mog_http *http, char *buf, size_t len) cs = http_parser_first_final; http->cs = cs; - http->offset = p - buf; + http->_p.offset = p - buf; if (cs == http_parser_error || errno) return MOG_PARSER_ERROR; assert(p <= pe && "buffer overflow after http parse"); - assert(http->offset <= len && "offset longer than len"); + assert(http->_p.offset <= len && "offset longer than len"); if (http->cs == http_parser_first_final) return MOG_PARSER_DONE; return MOG_PARSER_CONTINUE; diff --git a/http_put.c b/http_put.c index 15ff9f7..740ce08 100644 --- a/http_put.c +++ b/http_put.c @@ -173,7 +173,7 @@ static enum mog_next http_put_commit(struct mog_http *http) if (http->wbuf && http->wbuf != MOG_WR_ERROR) return MOG_NEXT_WAIT_WR; - if (!http->persistent || http->wbuf == MOG_WR_ERROR) + if (!http->_p.persistent || http->wbuf == MOG_WR_ERROR) return MOG_NEXT_CLOSE; mog_http_reset(http); return MOG_NEXT_ACTIVE; @@ -182,65 +182,65 @@ static enum mog_next http_put_commit(struct mog_http *http) static void stash_advance_rbuf(struct mog_http *http, char *buf, size_t buf_len) { struct mog_rbuf *rbuf = http->rbuf; - size_t end = http->line_end + 1; + size_t end = http->_p.line_end + 1; - if (http->line_end == 0 || buf_len <= end) { - http->offset = 0; + if (http->_p.line_end == 0 || buf_len <= end) { + http->_p.offset = 0; mog_rbuf_free_and_null(&http->rbuf); return; } - assert(buf[http->line_end] == '\n' && "line_end is not LF"); + assert(buf[http->_p.line_end] == '\n' && "line_end is not LF"); assert(buf_len <= MOG_RBUF_MAX_SIZE && "bad rbuf size"); - assert(end <= http->offset && "invalid line end"); + assert(end <= http->_p.offset && "invalid line end"); if (rbuf == NULL) http->rbuf = rbuf = mog_rbuf_new(MOG_RBUF_BASE_SIZE); memmove(rbuf->rptr, buf + end, buf_len - end); rbuf->rsize = buf_len - end; - http->offset -= end; - if (http->tmp_tip >= end) - http->tmp_tip -= end; - http->line_end = 0; + http->_p.offset -= end; + if (http->_p.tmp_tip >= end) + http->_p.tmp_tip -= end; + http->_p.line_end = 0; } static void chunked_body_after_header(struct mog_http *http, char *buf, size_t buf_len) { - size_t tmpoff = http->offset; + size_t tmpoff = http->_p.offset; mog_chunk_init(http); - http->offset = tmpoff; + http->_p.offset = tmpoff; switch (mog_chunk_parse(http, buf, buf_len)) { case MOG_PARSER_ERROR: (void)write_err(http, "400 Bad Request"); return; case MOG_PARSER_CONTINUE: - assert(http->chunk_state != MOG_CHUNK_STATE_DONE); + assert(http->_p.chunk_state != MOG_CHUNK_STATE_DONE); /* fall through */ case MOG_PARSER_DONE: - switch (http->chunk_state) { + switch (http->_p.chunk_state) { case MOG_CHUNK_STATE_SIZE: - assert(http->offset == buf_len + assert(http->_p.offset == buf_len && "HTTP chunk parser didn't finish size"); return; case MOG_CHUNK_STATE_DATA: - assert(http->offset == buf_len + assert(http->_p.offset == buf_len && "HTTP chunk parser didn't finish data"); return; case MOG_CHUNK_STATE_TRAILER: - assert(http->offset > 0 && - "http->offset unset while in trailer"); + assert(http->_p.offset > 0 && + "http->_p.offset unset while in trailer"); stash_advance_rbuf(http, buf, buf_len); - http->skip_rbuf_defer = 1; + http->_p.skip_rbuf_defer = 1; return; case MOG_CHUNK_STATE_DONE: put_commit_resp(http); - assert(http->offset > 0 && - "http->offset unset after chunk body done"); + assert(http->_p.offset > 0 && + "http->_p.offset unset after chunk body done"); stash_advance_rbuf(http, buf, buf_len); - http->skip_rbuf_defer = 1; + http->_p.skip_rbuf_defer = 1; } } } @@ -248,45 +248,45 @@ chunked_body_after_header(struct mog_http *http, char *buf, size_t buf_len) static void identity_body_after_header(struct mog_http *http, char *buf, size_t buf_len) { - size_t body_len = buf_len - http->offset; - char *body_ptr = buf + http->offset; + size_t body_len = buf_len - http->_p.offset; + char *body_ptr = buf + http->_p.offset; - if (http->content_len < body_len) - body_len = http->content_len; + if (http->_p.content_len < body_len) + body_len = http->_p.content_len; if (body_len == 0) return; - http->offset += body_len; + http->_p.offset += body_len; if (!mog_http_write_full(http->forward, body_ptr, body_len)) (void)write_err(http, NULL); } static bool lengths_ok(struct mog_http *http) { - if (http->content_len < 0) + if (http->_p.content_len < 0) return false; /* ERANGE */ - if (http->has_content_range) { - if (http->chunked) + if (http->_p.has_content_range) { + if (http->_p.chunked) return false; - if (http->range_end < 0 || http->range_beg < 0) + if (http->_p.range_end < 0 || http->_p.range_beg < 0) return false; /* ERANGE */ - assert(http->range_end >= 0 && http->range_beg >= 0 && + assert(http->_p.range_end >= 0 && http->_p.range_beg >= 0 && "bad range, http_parser.rl broken"); /* can't end after we start */ - if (http->range_end < http->range_beg) + if (http->_p.range_end < http->_p.range_beg) return false; /* * Content-Length should match Content-Range boundaries * WARNING: Eric Wong sucks at arithmetic, check this: */ - if (http->content_len >= 0) { - off_t expect = http->range_end - http->range_beg + 1; + if (http->_p.content_len >= 0) { + off_t expect = http->_p.range_end - http->_p.range_beg + 1; - if (http->content_len != expect) + if (http->_p.content_len != expect) return false; } } @@ -324,7 +324,7 @@ static struct mog_file * open_put(struct mog_http *http, char *path) * we can't do an atomic rename(2) on successful PUT * if we have a partial upload */ - if (http->has_content_range) { + if (http->_p.has_content_range) { http->forward = mog_file_open_put(http->svc, path, O_CREAT); if (http->forward == NULL) return NULL; @@ -354,9 +354,9 @@ static struct mog_file * open_put(struct mog_http *http, char *path) file->path = xstrdup(path); assert(file->foff == 0 && "file->foff should be zero"); - if (http->has_content_range) - file->foff = http->range_beg; - if (http->has_trailer_md5 || http->has_expect_md5) + if (http->_p.has_content_range) + file->foff = http->_p.range_beg; + if (http->_p.has_trailer_md5 || http->_p.has_expect_md5) mog_digest_init(&file->digest, GC_MD5); return file; @@ -387,12 +387,12 @@ void mog_http_put(struct mog_http *http, char *buf, size_t buf_len) if (file == NULL) goto err; - if (buf_len == http->offset) { + if (buf_len == http->_p.offset) { /* we got the HTTP header in one read() */ - if (http->chunked) { + if (http->_p.chunked) { mog_rbuf_free_and_null(&http->rbuf); mog_chunk_init(http); - http->offset = buf_len; + http->_p.offset = buf_len; } return; } @@ -400,10 +400,10 @@ void mog_http_put(struct mog_http *http, char *buf, size_t buf_len) * otherwise we got part of the request body with the header, * write partially read body */ - assert(buf_len > http->offset && http->offset > 0 - && "http->offset is wrong"); + assert(buf_len > http->_p.offset && http->_p.offset > 0 + && "http->_p.offset is wrong"); - if (http->chunked) + if (http->_p.chunked) chunked_body_after_header(http, buf, buf_len); else identity_body_after_header(http, buf, buf_len); @@ -502,9 +502,9 @@ static enum mog_next identity_put_in_progress(struct mog_fd *mfd) assert(http->wbuf == NULL && "can't receive file with http->wbuf"); assert(http->forward && http->forward != MOG_IOSTAT && "bad forward"); - need = http->content_len - http->forward->as.file.foff; - if (http->has_content_range) - need += http->range_beg; + need = http->_p.content_len - http->forward->as.file.foff; + if (http->_p.has_content_range) + need += http->_p.range_beg; if (need == 0) return http_put_commit(http); @@ -549,19 +549,19 @@ again: assert(http->wbuf == NULL && "can't receive file with http->wbuf"); assert(http->forward && http->forward != MOG_IOSTAT && "bad forward"); - switch (http->chunk_state) { + switch (http->_p.chunk_state) { case MOG_CHUNK_STATE_DATA: assert(http->rbuf == NULL && "unexpected http->rbuf"); - if (http->content_len == 0) { /* final chunk */ - http->chunk_state = MOG_CHUNK_STATE_TRAILER; - http->offset = 0; + if (http->_p.content_len == 0) { /* final chunk */ + http->_p.chunk_state = MOG_CHUNK_STATE_TRAILER; + http->_p.offset = 0; goto chunk_state_trailer; } - assert(http->content_len > 0 && "bad chunk length"); + assert(http->_p.content_len > 0 && "bad chunk length"); /* read the chunk into memory */ buf = mog_fsbuf_get(&buf_len); - if (buf_len > http->content_len) - buf_len = http->content_len; + if (buf_len > http->_p.content_len) + buf_len = http->_p.content_len; do { r = read(mfd->fd, buf, buf_len); } while (r < 0 && errno == EINTR); @@ -571,10 +571,10 @@ again: if (!mog_http_write_full(http->forward, buf, r)) return write_err(http, NULL); - http->content_len -= r; + http->_p.content_len -= r; /* chunk is complete */ - if (http->content_len == 0) + if (http->_p.content_len == 0) mog_chunk_init(http); goto again; case MOG_CHUNK_STATE_TRAILER: @@ -610,15 +610,15 @@ chunk_state_trailer: case MOG_PARSER_ERROR: return write_err(http, "400 Bad Request"); case MOG_PARSER_CONTINUE: - assert(http->chunk_state != MOG_CHUNK_STATE_DONE); + assert(http->_p.chunk_state != MOG_CHUNK_STATE_DONE); case MOG_PARSER_DONE: - switch (http->chunk_state) { + switch (http->_p.chunk_state) { case MOG_CHUNK_STATE_SIZE: if (in_trailer) assert(0 && "bad chunk state: size"); /* client is trickling chunk size :< */ mog_rbuf_free_and_null(&http->rbuf); - http->offset = 0; + http->_p.offset = 0; goto again; case MOG_CHUNK_STATE_DATA: if (in_trailer) @@ -635,7 +635,7 @@ chunk_state_trailer: /* pipelined HTTP request after trailers! */ if (http->rbuf) assert(http->rbuf->rsize > 0 - && http->offset == 0 + && http->_p.offset == 0 && "bad rbuf"); return http_put_commit(http); } @@ -657,7 +657,7 @@ read_err: enum mog_next mog_http_put_in_progress(struct mog_fd *mfd) { - if (mfd->as.http.chunked) + if (mfd->as.http._p.chunked) return chunked_put_in_progress(mfd); return identity_put_in_progress(mfd); diff --git a/test/chunk-parser-1.c b/test/chunk-parser-1.c index 6804a17..335a39b 100644 --- a/test/chunk-parser-1.c +++ b/test/chunk-parser-1.c @@ -23,7 +23,7 @@ static void buf_set(const char *s) { struct mog_file *file; - http->chunked = 1; + http->_p.chunked = 1; reset(); tmpfp = tmpfile(); assert(tmpfp != NULL && "tmpfile(3) failed"); @@ -46,16 +46,16 @@ int main(void) buf_set("666\r\n"); state = mog_chunk_parse(http, buf, len); assert(state == MOG_PARSER_DONE); - assert(http->content_len == 0x666); - assert(http->chunk_state == MOG_CHUNK_STATE_DATA); + assert(http->_p.content_len == 0x666); + assert(http->_p.chunk_state == MOG_CHUNK_STATE_DATA); } if ("incomplete chunk") { buf_set("666\r"); state = mog_chunk_parse(http, buf, len); assert(state == MOG_PARSER_CONTINUE); - assert(http->content_len == 0x666); - assert(http->chunk_state == MOG_CHUNK_STATE_SIZE); + assert(http->_p.content_len == 0x666); + assert(http->_p.chunk_state == MOG_CHUNK_STATE_SIZE); } if ("bad chunk") { @@ -68,8 +68,8 @@ int main(void) buf_set("abcde; foo=bar\r\n"); state = mog_chunk_parse(http, buf, len); assert(state == MOG_PARSER_DONE); - assert(http->content_len == 0xabcde); - assert(http->chunk_state == MOG_CHUNK_STATE_DATA); + assert(http->_p.content_len == 0xabcde); + assert(http->_p.chunk_state == MOG_CHUNK_STATE_DATA); } if ("chunk with complete header and data") { @@ -77,8 +77,8 @@ int main(void) buf_set("5\r\nabcde"); state = mog_chunk_parse(http, buf, len); assert(state == MOG_PARSER_CONTINUE); - assert(http->content_len == 0); - assert(http->chunk_state == MOG_CHUNK_STATE_SIZE); + assert(http->_p.content_len == 0); + assert(http->_p.chunk_state == MOG_CHUNK_STATE_SIZE); assert(sizeof(tmp) == pread(tmpfd, tmp, sizeof(tmp), 0)); assert(0 == memcmp(tmp, "abcde", sizeof(tmp))); } @@ -88,33 +88,33 @@ int main(void) buf_set("5\r\nabcde\r\n3"); state = mog_chunk_parse(http, buf, len); assert(state == MOG_PARSER_CONTINUE); - assert(http->content_len == 3); - assert(http->chunk_state == MOG_CHUNK_STATE_SIZE); + assert(http->_p.content_len == 3); + assert(http->_p.chunk_state == MOG_CHUNK_STATE_SIZE); assert(sizeof(tmp) == pread(tmpfd, tmp, sizeof(tmp), 0)); assert(0 == memcmp(tmp, "abcde", sizeof(tmp))); - assert(http->offset == len); + assert(http->_p.offset == len); } if ("multiple chunks with end") { char tmp[8]; buf_set("5\r\nabcde\r\n3\r\n123\r\n0\r\n\r\n"); state = mog_chunk_parse(http, buf, len); assert(state == MOG_PARSER_DONE); - assert(http->chunk_state == MOG_CHUNK_STATE_DONE); + assert(http->_p.chunk_state == MOG_CHUNK_STATE_DONE); assert(sizeof(tmp) == pread(tmpfd, tmp, sizeof(tmp), 0)); assert(0 == memcmp(tmp, "abcde123", sizeof(tmp))); - assert(http->offset == len); + assert(http->_p.offset == len); } if ("multiple chunks with trailer") { char tmp[8]; buf_set("5\r\nabcde\r\n3\r\n123\r\n0\r\nFoo: bar\r\n\r\n"); state = mog_chunk_parse(http, buf, len); - assert(http->chunk_state == MOG_CHUNK_STATE_DONE); + assert(http->_p.chunk_state == MOG_CHUNK_STATE_DONE); assert(state == MOG_PARSER_DONE); - assert(http->content_len == 0); + assert(http->_p.content_len == 0); assert(sizeof(tmp) == pread(tmpfd, tmp, sizeof(tmp), 0)); assert(0 == memcmp(tmp, "abcde123", sizeof(tmp))); - assert(http->offset == len); + assert(http->_p.offset == len); } if ("multiple chunks with almost end") { @@ -122,11 +122,11 @@ int main(void) buf_set("5\r\nabcde\r\n3\r\n123\r\n0\r\n"); state = mog_chunk_parse(http, buf, len); assert(state == MOG_PARSER_DONE); - assert(http->chunk_state == MOG_CHUNK_STATE_DATA); - assert(http->content_len == 0); + assert(http->_p.chunk_state == MOG_CHUNK_STATE_DATA); + assert(http->_p.content_len == 0); assert(sizeof(tmp) == pread(tmpfd, tmp, sizeof(tmp), 0)); assert(0 == memcmp(tmp, "abcde123", sizeof(tmp))); - assert(http->offset == len); + assert(http->_p.offset == len); } if ("multiple chunks with almost end (more)") { @@ -134,11 +134,11 @@ int main(void) buf_set("5\r\nabcde\r\n3\r\n123\r\n0\r\n\r"); state = mog_chunk_parse(http, buf, len); assert(state == MOG_PARSER_CONTINUE); - assert(http->chunk_state == MOG_CHUNK_STATE_TRAILER); - assert(http->content_len == 0); + assert(http->_p.chunk_state == MOG_CHUNK_STATE_TRAILER); + assert(http->_p.content_len == 0); assert(sizeof(tmp) == pread(tmpfd, tmp, sizeof(tmp), 0)); assert(0 == memcmp(tmp, "abcde123", sizeof(tmp))); - assert(http->offset == len); + assert(http->_p.offset == len); } if ("multiple chunks with incomplete") { @@ -146,11 +146,11 @@ int main(void) buf_set("5\r\nabcde\r\n3\r\n12"); state = mog_chunk_parse(http, buf, len); assert(state == MOG_PARSER_DONE); - assert(http->chunk_state == MOG_CHUNK_STATE_DATA); - assert(http->content_len == 1); + assert(http->_p.chunk_state == MOG_CHUNK_STATE_DATA); + assert(http->_p.content_len == 1); assert(sizeof(tmp) == pread(tmpfd, tmp, sizeof(tmp), 0)); assert(0 == memcmp(tmp, "abcde12", sizeof(tmp))); - assert(http->offset == len); + assert(http->_p.offset == len); } if ("incomplete data") { @@ -158,11 +158,11 @@ int main(void) buf_set("666\r\nabc"); state = mog_chunk_parse(http, buf, len); assert(state == MOG_PARSER_DONE); - assert(http->chunk_state == MOG_CHUNK_STATE_DATA); - assert(http->content_len == (0x666 - sizeof(tmp))); + assert(http->_p.chunk_state == MOG_CHUNK_STATE_DATA); + assert(http->_p.content_len == (0x666 - sizeof(tmp))); assert(sizeof(tmp) == pread(tmpfd, tmp, sizeof(tmp), 0)); assert(0 == memcmp(tmp, "abc", sizeof(tmp))); - assert(http->offset == len); + assert(http->_p.offset == len); } reset(); diff --git a/test/http-parser-1.c b/test/http-parser-1.c index 688e0a5..861c19f 100644 --- a/test/http-parser-1.c +++ b/test/http-parser-1.c @@ -14,8 +14,8 @@ static void assert_path_equal(const char *str) { size_t slen = strlen(str); - assert(0 == memcmp(str, buf + http->path_tip, slen)); - assert(http->path_end == http->path_tip + slen); + assert(0 == memcmp(str, buf + http->_p.path_tip, slen)); + assert(http->_p.path_end == http->_p.path_tip + slen); } static void reset(void) @@ -36,9 +36,9 @@ int main(void) if ("normal HTTP GET request") { buf_set("GET /foo HTTP/1.1\r\nHost: 127.6.6.6\r\n\r\n"); state = mog_http_parse(http, buf, len); - assert(http->http_method == MOG_HTTP_METHOD_GET + assert(http->_p.http_method == MOG_HTTP_METHOD_GET && "http_method should be GET"); - assert(http->persistent && "not persistent"); + assert(http->_p.persistent && "not persistent"); assert(state == MOG_PARSER_DONE && "parser not done"); assert_path_equal("/foo"); } @@ -46,9 +46,9 @@ int main(void) if ("normal HTTP GET request with redundant leading slash") { buf_set("GET //foo HTTP/1.1\r\nHost: 127.6.6.6\r\n\r\n"); state = mog_http_parse(http, buf, len); - assert(http->http_method == MOG_HTTP_METHOD_GET + assert(http->_p.http_method == MOG_HTTP_METHOD_GET && "http_method should be GET"); - assert(http->persistent && "not persistent"); + assert(http->_p.persistent && "not persistent"); assert(state == MOG_PARSER_DONE && "parser not done"); assert_path_equal("/foo"); } @@ -59,9 +59,9 @@ int main(void) "Connection: close\r\n" "\r\n"); state = mog_http_parse(http, buf, len); - assert(http->http_method == MOG_HTTP_METHOD_GET + assert(http->_p.http_method == MOG_HTTP_METHOD_GET && "http_method should be GET"); - assert(http->persistent == 0 && "should not be persistent"); + assert(http->_p.persistent == 0 && "should not be persistent"); assert(state == MOG_PARSER_DONE && "parser not done"); assert_path_equal("/foo"); } @@ -71,9 +71,9 @@ int main(void) "Connection:\r\n keep-alive\r\n" "\r\n"); state = mog_http_parse(http, buf, len); - assert(http->http_method == MOG_HTTP_METHOD_GET + assert(http->_p.http_method == MOG_HTTP_METHOD_GET && "http_method should be GET"); - assert(http->persistent == 1 && "should be persistent"); + assert(http->_p.persistent == 1 && "should be persistent"); assert(state == MOG_PARSER_DONE && "parser not done"); assert_path_equal("/foo"); } @@ -99,9 +99,9 @@ int main(void) "Host: 127.6.6.6\r\n" "\r\n"); state = mog_http_parse(http, buf, len); - assert(http->http_method == MOG_HTTP_METHOD_HEAD + assert(http->_p.http_method == MOG_HTTP_METHOD_HEAD && "http_method should be HEAD "); - assert(http->persistent == 1 && "should be persistent"); + assert(http->_p.persistent == 1 && "should be persistent"); assert(state == MOG_PARSER_DONE && "parser not done"); assert_path_equal("/foo"); } @@ -113,13 +113,13 @@ int main(void) "\r\n" "partial body request"); state = mog_http_parse(http, buf, len); - assert(http->content_len == 12345); - assert(http->http_method == MOG_HTTP_METHOD_PUT + assert(http->_p.content_len == 12345); + assert(http->_p.http_method == MOG_HTTP_METHOD_PUT && "http_method should be PUT"); - assert(http->persistent == 1 && "should be persistent"); + assert(http->_p.persistent == 1 && "should be persistent"); assert(state == MOG_PARSER_DONE && "parser not done"); assert_path_equal("/foo"); - assert(strcmp(buf + http->offset, "partial body request") == 0 + assert(strcmp(buf + http->_p.offset, "partial body request") == 0 && "buffer repositioned to body start"); } @@ -130,14 +130,14 @@ int main(void) "\r\n" "16\r\npartial..."); state = mog_http_parse(http, buf, len); - assert(http->chunked); - assert(http->has_trailer_md5 == 0); - assert(http->http_method == MOG_HTTP_METHOD_PUT + assert(http->_p.chunked); + assert(http->_p.has_trailer_md5 == 0); + assert(http->_p.http_method == MOG_HTTP_METHOD_PUT && "http_method should be PUT"); - assert(http->persistent == 1 && "should be persistent"); + assert(http->_p.persistent == 1 && "should be persistent"); assert(state == MOG_PARSER_DONE && "parser not done"); assert_path_equal("/foo"); - assert(strcmp(buf + http->offset, "16\r\npartial...") == 0 + assert(strcmp(buf + http->_p.offset, "16\r\npartial...") == 0 && "buffer repositioned to body start"); } @@ -149,16 +149,16 @@ int main(void) "\r\n" "16\r\npartial..."); state = mog_http_parse(http, buf, len); - assert(http->range_beg == 666); - assert(http->range_end == 666666); - assert(http->has_content_range == 1); - assert(http->has_trailer_md5 == 0); - assert(http->http_method == MOG_HTTP_METHOD_PUT + assert(http->_p.range_beg == 666); + assert(http->_p.range_end == 666666); + assert(http->_p.has_content_range == 1); + assert(http->_p.has_trailer_md5 == 0); + assert(http->_p.http_method == MOG_HTTP_METHOD_PUT && "http_method should be PUT"); - assert(http->persistent == 1 && "should be persistent"); + assert(http->_p.persistent == 1 && "should be persistent"); assert(state == MOG_PARSER_DONE && "parser not done"); assert_path_equal("/foo"); - assert(strcmp(buf + http->offset, "16\r\npartial...") == 0 + assert(strcmp(buf + http->_p.offset, "16\r\npartial...") == 0 && "buffer repositioned to body start"); } @@ -170,14 +170,14 @@ int main(void) "\r\n" "16\r\npartial..."); state = mog_http_parse(http, buf, len); - assert(http->chunked); - assert(http->has_trailer_md5 == 1); - assert(http->http_method == MOG_HTTP_METHOD_PUT + assert(http->_p.chunked); + assert(http->_p.has_trailer_md5 == 1); + assert(http->_p.http_method == MOG_HTTP_METHOD_PUT && "http_method should be PUT"); - assert(http->persistent == 1 && "should be persistent"); + assert(http->_p.persistent == 1 && "should be persistent"); assert(state == MOG_PARSER_DONE && "parser not done"); assert_path_equal("/foo"); - assert(strcmp(buf + http->offset, "16\r\npartial...") == 0 + assert(strcmp(buf + http->_p.offset, "16\r\npartial...") == 0 && "buffer repositioned to body start"); } @@ -186,11 +186,11 @@ int main(void) "Host: 127.6.6.6\r\n" "\r\n"); state = mog_http_parse(http, buf, len); - assert(http->content_len == 0); - assert(http->has_trailer_md5 == 0); - assert(http->http_method == MOG_HTTP_METHOD_DELETE + assert(http->_p.content_len == 0); + assert(http->_p.has_trailer_md5 == 0); + assert(http->_p.http_method == MOG_HTTP_METHOD_DELETE && "http_method should be DELETE"); - assert(http->persistent == 1 && "should be persistent"); + assert(http->_p.persistent == 1 && "should be persistent"); assert(state == MOG_PARSER_DONE && "parser not done"); assert_path_equal("/foo"); } @@ -200,11 +200,11 @@ int main(void) "Host: 127.6.6.6\r\n" "\r\n"); state = mog_http_parse(http, buf, len); - assert(http->content_len == 0); - assert(http->has_trailer_md5 == 0); - assert(http->http_method == MOG_HTTP_METHOD_MKCOL + assert(http->_p.content_len == 0); + assert(http->_p.has_trailer_md5 == 0); + assert(http->_p.http_method == MOG_HTTP_METHOD_MKCOL && "http_method should be MKCOL"); - assert(http->persistent == 1 && "should be persistent"); + assert(http->_p.persistent == 1 && "should be persistent"); assert(state == MOG_PARSER_DONE && "parser not done"); assert_path_equal("/foo"); } @@ -215,12 +215,12 @@ int main(void) "Range: bytes=5-55\r\n" "\r\n"); state = mog_http_parse(http, buf, len); - assert(http->has_range == 1); - assert(http->range_beg == 5 && "range_beg didn't match"); - assert(http->range_end == 55 && "range_end didn't match"); - assert(http->http_method == MOG_HTTP_METHOD_GET + assert(http->_p.has_range == 1); + assert(http->_p.range_beg == 5 && "range_beg didn't match"); + assert(http->_p.range_end == 55 && "range_end didn't match"); + assert(http->_p.http_method == MOG_HTTP_METHOD_GET && "http_method should be GET"); - assert(http->persistent == 1 && "should be persistent"); + assert(http->_p.persistent == 1 && "should be persistent"); assert(state == MOG_PARSER_DONE && "parser not done"); assert_path_equal("/foo"); } @@ -231,12 +231,12 @@ int main(void) "Range: bytes=-55\r\n" "\r\n"); state = mog_http_parse(http, buf, len); - assert(http->has_range == 1); - assert(http->range_beg == -1 && "range_beg didn't match"); - assert(http->range_end == 55 && "range_end didn't match"); - assert(http->http_method == MOG_HTTP_METHOD_GET + assert(http->_p.has_range == 1); + assert(http->_p.range_beg == -1 && "range_beg didn't match"); + assert(http->_p.range_end == 55 && "range_end didn't match"); + assert(http->_p.http_method == MOG_HTTP_METHOD_GET && "http_method should be GET"); - assert(http->persistent == 1 && "should be persistent"); + assert(http->_p.persistent == 1 && "should be persistent"); assert(state == MOG_PARSER_DONE && "parser not done"); assert_path_equal("/foo"); } @@ -247,12 +247,12 @@ int main(void) "Range: bytes=55-\r\n" "\r\n"); state = mog_http_parse(http, buf, len); - assert(http->has_range == 1); - assert(http->range_beg == 55 && "range_beg didn't match"); - assert(http->range_end == -1 && "range_end didn't match"); - assert(http->http_method == MOG_HTTP_METHOD_GET + assert(http->_p.has_range == 1); + assert(http->_p.range_beg == 55 && "range_beg didn't match"); + assert(http->_p.range_end == -1 && "range_end didn't match"); + assert(http->_p.http_method == MOG_HTTP_METHOD_GET && "http_method should be GET"); - assert(http->persistent == 1 && "should be persistent"); + assert(http->_p.persistent == 1 && "should be persistent"); assert(state == MOG_PARSER_DONE && "parser not done"); assert_path_equal("/foo"); } -- cgit v1.2.3-24-ge0c7