diff options
-rw-r--r-- | cmogstored.h | 5 | ||||
-rw-r--r-- | http_parser.rl | 16 |
2 files changed, 16 insertions, 5 deletions
diff --git a/cmogstored.h b/cmogstored.h index 5b4493b..2dffbb2 100644 --- a/cmogstored.h +++ b/cmogstored.h @@ -197,15 +197,16 @@ enum mog_chunk_state { struct mog_http { int cs; struct { - /* only needs 4 bits, but we use 8 for alignment */ - enum mog_http_method http_method:8; + enum mog_http_method http_method:4; unsigned persistent:1; + unsigned persist_client_at_start:1; unsigned chunked:1; unsigned has_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; + unsigned unused_padding:3; uint8_t path_tip; uint8_t path_end; uint16_t line_end; diff --git a/http_parser.rl b/http_parser.rl index ef854ba..fc4bfd5 100644 --- a/http_parser.rl +++ b/http_parser.rl @@ -125,6 +125,16 @@ void mog_http_reset_parser(struct mog_http *http) http->cs = cs; memset(&http->_p, 0, sizeof(http->_p)); + if (http->rbuf) /* already pipelined */ + http->_p.persist_client_at_start = 1; + else + /* + * we need to know persist_client when we start reading + * the request because we do not want to break pipelined + * requests + */ + http->_p.persist_client_at_start = http->svc->persist_client; + /* these should probably be in mog_http_init */ http->forward = NULL; http->wbuf = NULL; @@ -132,9 +142,9 @@ void mog_http_reset_parser(struct mog_http *http) void mog_http_init(struct mog_http *http, struct mog_svc *svc) { - mog_http_reset_parser(http); - http->rbuf = NULL; http->svc = svc; + http->rbuf = NULL; + mog_http_reset_parser(http); } enum mog_parser_state @@ -171,7 +181,7 @@ mog_http_parse(struct mog_http *http, char *buf, size_t len) assert(http->_p.buf_off <= len && "offset longer than len"); if (http->cs == http_parser_first_final) { - http->_p.persistent &= http->svc->persist_client; + http->_p.persistent &= http->_p.persist_client_at_start; return MOG_PARSER_DONE; } return MOG_PARSER_CONTINUE; |