diff --git a/include/common/htx.h b/include/common/htx.h index ec9909851..25c28c8c4 100644 --- a/include/common/htx.h +++ b/include/common/htx.h @@ -161,7 +161,7 @@ struct htx { uint64_t extra; /* known bytes amount remaining to receive */ uint32_t flags; /* HTX_FL_* */ - int32_t sl_pos; /* position of the start-line of the HTTP message. -1 if unset */ + int32_t first; /* position of the first block to (re)start the analyse. -1 if unset. */ struct htx_blk blocks[0]; /* Blocks representing the HTTP message itself */ }; @@ -413,8 +413,8 @@ static inline enum htx_blk_type htx_get_tail_type(const struct htx *htx) return (blk ? htx_get_blk_type(blk) : HTX_BLK_UNUSED); } -/* Returns the position of the first block in the HTX message . It is the - * sl_pos if set, otherwise it is the head. +/* Returns the position of the first block in the HTX message . If unset, + * or if is empty, -1 is returned. * * An signed 32-bits integer is returned to handle -1 case. Blocks position are * store on unsigned 32-bits integer, but it is impossible to have so much @@ -422,13 +422,13 @@ static inline enum htx_blk_type htx_get_tail_type(const struct htx *htx) */ static inline int32_t htx_get_first(const struct htx *htx) { - if (htx->sl_pos != -1) - return htx->sl_pos; - return htx->head; + if (!htx->used) + return -1; + return htx->first; } -/* Returns the first HTX block in the HTX message . If is the head, - * NULL returned. +/* Returns the first HTX block in the HTX message . If unset or if is + * empty, NULL returned. */ static inline struct htx_blk *htx_get_first_blk(const struct htx *htx) { @@ -717,7 +717,7 @@ static inline void htx_reset(struct htx *htx) htx->data = htx->used = htx->tail = htx->head = htx->front = 0; htx->extra = 0; htx->flags = HTX_FL_NONE; - htx->sl_pos = -1; + htx->first = -1; } /* returns the available room for raw data in buffer once HTX overhead is @@ -832,8 +832,8 @@ static inline void htx_dump(struct htx *htx) fprintf(stderr, "htx:%p [ size=%u - data=%u - used=%u - wrap=%s - extra=%llu]\n", htx, htx->size, htx->data, htx->used, (htx->tail >= htx->head) ? "NO" : "YES", (unsigned long long)htx->extra); - fprintf(stderr, "\tsl_pos=%d - head=%u, tail=%u - front=%u\n", - htx->sl_pos, htx->head, htx->tail, htx->front); + fprintf(stderr, "\tfirst=%d - head=%u, tail=%u - front=%u\n", + htx->first, htx->head, htx->tail, htx->front); for (pos = htx_get_head(htx); pos != -1; pos = htx_get_next(htx, pos)) { struct htx_sl *sl; diff --git a/include/proto/channel.h b/include/proto/channel.h index 077b3ae1f..3ebaf7fce 100644 --- a/include/proto/channel.h +++ b/include/proto/channel.h @@ -923,7 +923,7 @@ static inline void channel_htx_fwd_headers(struct channel *chn, struct htx *htx) struct htx_blk *blk = htx_get_blk(htx, pos); data += htx_get_blksz(blk); if (htx_get_blk_type(blk) == HTX_BLK_EOH) { - htx->sl_pos = htx_get_next(htx, pos); + htx->first = htx_get_next(htx, pos); break; } } diff --git a/src/cache.c b/src/cache.c index 1fec57e24..4371910fc 100644 --- a/src/cache.c +++ b/src/cache.c @@ -913,10 +913,6 @@ static size_t htx_cache_dump_headers(struct appctx *appctx, struct htx *htx) if (!blk) return 0; - /* Set the start-line offset */ - if (type == HTX_BLK_RES_SL) - htx->sl_pos = htx_get_blk_pos(htx, blk); - /* Copy info and data */ blk->info = info; memcpy(htx_get_blk_ptr(htx, blk), b_peek(tmp, offset+4), sz); diff --git a/src/hlua.c b/src/hlua.c index bb8c93da6..3c9c70a78 100644 --- a/src/hlua.c +++ b/src/hlua.c @@ -3944,11 +3944,16 @@ static int hlua_applet_http_new(lua_State *L, struct appctx *ctx) if (IS_HTX_STRM(s)) { /* HTX version */ struct htx *htx = htxbuf(&s->req.buf); - struct htx_sl *sl = http_get_stline(htx); + struct htx_blk *blk; + struct htx_sl *sl; struct ist path; unsigned long long len = 0; int32_t pos; + blk = htx_get_first_blk(htx); + BUG_ON(htx_get_blk_type(blk) != HTX_BLK_REQ_SL); + sl = htx_get_blk_ptr(htx, blk); + /* Stores the request method. */ lua_pushstring(L, "method"); lua_pushlstring(L, HTX_SL_REQ_MPTR(sl), HTX_SL_REQ_MLEN(sl)); @@ -4366,7 +4371,7 @@ __LJMP static int hlua_applet_htx_recv_yield(lua_State *L, int status, lua_KCont htx = htx_from_buf(&req->buf); len = MAY_LJMP(luaL_checkinteger(L, 2)); count = co_data(req); - blk = htx_get_first_blk(htx); + blk = htx_get_head_blk(htx); while (count && len && blk) { enum htx_blk_type type = htx_get_blk_type(blk); uint32_t sz = htx_get_blksz(blk); diff --git a/src/http_fetch.c b/src/http_fetch.c index 05074d6eb..a184f2f3b 100644 --- a/src/http_fetch.c +++ b/src/http_fetch.c @@ -203,7 +203,7 @@ struct htx *smp_prefetch_htx(struct sample *smp, struct channel *chn, int vol) if (msg->msg_state < HTTP_MSG_BODY) { /* Analyse not yet started */ - if (htx_is_empty(htx) || htx->sl_pos == -1) { + if (htx_is_empty(htx) || htx->first == -1) { /* Parsing is done by the mux, just wait */ smp->flags |= SMP_F_MAY_CHANGE; return NULL; diff --git a/src/http_htx.c b/src/http_htx.c index 15865d502..b9501bed7 100644 --- a/src/http_htx.c +++ b/src/http_htx.c @@ -11,6 +11,7 @@ */ #include +#include #include #include #include @@ -21,19 +22,18 @@ struct buffer htx_err_chunks[HTTP_ERR_SIZE]; /* Returns the next unporocessed start line in the HTX message. It returns NULL - * is the start-line is undefined (sl_pos == 1). Otherwise, it returns the + * if the start-line is undefined (first == -1). Otherwise, it returns the * pointer on the htx_sl structure. */ struct htx_sl *http_get_stline(struct htx *htx) { struct htx_blk *blk; - if (htx->sl_pos == -1) - return NULL; - - blk = htx_get_blk(htx, htx->sl_pos); + BUG_ON(htx->first == -1); + blk = htx_get_first_blk(htx); if (!blk) return NULL; + BUG_ON(htx_get_blk_type(blk) != HTX_BLK_REQ_SL && htx_get_blk_type(blk) != HTX_BLK_RES_SL); return htx_get_blk_ptr(htx, blk); } @@ -143,7 +143,7 @@ int http_add_header(struct htx *htx, const struct ist n, const struct ist v) /* is the head, swap it iteratively with its predecessor to place * it just before the end-of-header block. So blocks remains ordered. */ - for (prev = htx_get_prev(htx, htx->tail); prev != htx->sl_pos; prev = htx_get_prev(htx, prev)) { + for (prev = htx_get_prev(htx, htx->tail); prev != htx->first; prev = htx_get_prev(htx, prev)) { struct htx_blk *pblk = htx_get_blk(htx, prev); enum htx_blk_type type = htx_get_blk_type(pblk); @@ -169,18 +169,14 @@ int http_add_header(struct htx *htx, const struct ist n, const struct ist v) } /* Replaces parts of the start-line of the HTX message . It returns 1 on - * success, otherwise it returns 0. The right block is search in the HTX - * message. + * success, otherwise it returns 0. */ int http_replace_stline(struct htx *htx, const struct ist p1, const struct ist p2, const struct ist p3) { struct htx_blk *blk; - if (htx->sl_pos == -1) - return 0; - - blk = htx_get_blk(htx, htx->sl_pos); - if (!htx_replace_stline(htx, blk, p1, p2, p3)) + blk = htx_get_first_blk(htx); + if (!blk || !htx_replace_stline(htx, blk, p1, p2, p3)) return 0; return 1; } diff --git a/src/htx.c b/src/htx.c index a7623b6d9..dbf8dea37 100644 --- a/src/htx.c +++ b/src/htx.c @@ -28,7 +28,7 @@ struct htx_blk *htx_defrag(struct htx *htx, struct htx_blk *blk) struct htx_blk *newblk, *oldblk; uint32_t new, old, blkpos; uint32_t addr, blksz; - int32_t sl_pos = -1; + int32_t first = -1; if (!htx->used) return NULL; @@ -51,8 +51,8 @@ struct htx_blk *htx_defrag(struct htx *htx, struct htx_blk *blk) blksz = htx_get_blksz(oldblk); /* update the start-line position */ - if (htx->sl_pos == old) - sl_pos = new; + if (htx->first == old) + first = new; /* if is defined, set its new position */ if (blk != NULL && blk == oldblk) @@ -65,7 +65,7 @@ struct htx_blk *htx_defrag(struct htx *htx, struct htx_blk *blk) } htx->used = new; - htx->sl_pos = sl_pos; + htx->first = first; htx->head = 0; htx->front = htx->tail = new - 1; memcpy((void *)htx->blocks, (void *)tmp->blocks, htx->size); @@ -94,7 +94,7 @@ static struct htx_blk *htx_reserve_nxblk(struct htx *htx, uint32_t blksz) if (!htx->used) { /* Empty message */ - htx->front = htx->head = htx->tail = 0; + htx->front = htx->head = htx->tail = htx->first = 0; htx->used = 1; blk = htx_get_blk(htx, htx->tail); blk->addr = 0; @@ -188,6 +188,9 @@ static struct htx_blk *htx_reserve_nxblk(struct htx *htx, uint32_t blksz) htx->tail = tail; htx->used = used; htx->data += blksz; + /* Set first position if not already set */ + if (htx->first == -1) + htx->first = tail; return blk; } @@ -220,15 +223,11 @@ struct htx_blk *htx_remove_blk(struct htx *htx, struct htx_blk *blk) /* Mark the block as unused, decrement allocated size */ htx->data -= htx_get_blksz(blk); blk->info = ((uint32_t)HTX_BLK_UNUSED << 28); - if (htx->sl_pos == pos) - htx->sl_pos = -1; } /* This is the last block in use */ - if (htx->used == 1/* || !htx->data */) { - htx->front = htx->head = htx->tail = 0; - htx->used = 0; - htx->data = 0; + if (htx->used == 1) { + htx_reset(htx); return NULL; } @@ -271,13 +270,9 @@ struct htx_blk *htx_remove_blk(struct htx *htx, struct htx_blk *blk) } blk = htx_get_blk(htx, next); - if (htx->sl_pos == -1) { - /* Try to update the start-line payload addr, if possible */ - type = htx_get_blk_type(blk); - if (type == HTX_BLK_REQ_SL || type == HTX_BLK_RES_SL) - htx->sl_pos = htx_get_blk_pos(htx, blk); - } end: + if (pos == htx->first) + htx->first = (blk ? htx_get_blk_pos(htx, blk) : -1); if (pos == htx->front) htx->front = htx_find_front(htx); return blk; @@ -542,9 +537,6 @@ struct htx_ret htx_xfer_blks(struct htx *dst, struct htx *src, uint32_t count, htx_cut_data_blk(src, blk, sz); break; } - - if (dst->sl_pos == -1 && src->sl_pos == htx_get_blk_pos(src, blk)) - dst->sl_pos = htx_get_blk_pos(dst, dstblk); next: blk = htx_remove_blk(src, blk); if (type == mark) @@ -682,8 +674,6 @@ struct htx_sl *htx_add_stline(struct htx *htx, enum htx_blk_type type, unsigned blk->info += size; sl = htx_get_blk_ptr(htx, blk); - if (htx->sl_pos == -1) - htx->sl_pos = htx_get_blk_pos(htx, blk); sl->hdrs_bytes = -1; sl->flags = flags; diff --git a/src/proto_htx.c b/src/proto_htx.c index dc0762d73..7cc26ba31 100644 --- a/src/proto_htx.c +++ b/src/proto_htx.c @@ -132,7 +132,7 @@ int htx_wait_for_request(struct stream *s, struct channel *req, int an_bit) * a timeout or connection reset is not counted as an error. However * a bad request is. */ - if (unlikely(htx_is_empty(htx) || htx->sl_pos == -1)) { + if (unlikely(htx_is_empty(htx) || htx->first == -1)) { if (htx->flags & HTX_FL_UPGRADE) goto failed_keep_alive; @@ -279,6 +279,7 @@ int htx_wait_for_request(struct stream *s, struct channel *req, int an_bit) txn->flags &= ~TX_WAIT_NEXT_RQ; req->analyse_exp = TICK_ETERNITY; + BUG_ON(htx_get_first_type(htx) != HTX_BLK_REQ_SL); sl = http_get_stline(htx); /* 0: we might have to print this header in debug mode */ @@ -1470,7 +1471,7 @@ int htx_wait_for_response(struct stream *s, struct channel *rep, int an_bit) * errors somewhere else. */ next_one: - if (unlikely(htx_is_empty(htx) || htx->sl_pos == -1)) { + if (unlikely(htx_is_empty(htx) || htx->first == -1)) { /* 1: have we encountered a read error ? */ if (rep->flags & CF_READ_ERROR) { struct connection *conn = NULL; @@ -1625,6 +1626,7 @@ int htx_wait_for_response(struct stream *s, struct channel *rep, int an_bit) */ msg->msg_state = HTTP_MSG_BODY; + BUG_ON(htx_get_first_type(htx) != HTX_BLK_RES_SL); sl = http_get_stline(htx); /* 0: we might have to print this header in debug mode */