From 4244fd63ef360a1b5a201d82e323c54842f0db55 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Fri, 12 Jul 2013 20:49:46 +0000 Subject: http: check persist_client state when parsing starts We don't want drop in-flight pipelined requests when disabling persistent connections. Disabling persistent connections will always be potentially racy, but hopefully this makes the race small enough that lower-level latencies are the only thing which affect that. --- cmogstored.h | 5 +++-- 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; -- cgit v1.2.3-24-ge0c7