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 */
};
return (blk ? htx_get_blk_type(blk) : HTX_BLK_UNUSED);
}
-/* Returns the position of the first block in the HTX message <htx>. It is the
- * sl_pos if set, otherwise it is the head.
+/* Returns the position of the first block in the HTX message <htx>. If unset,
+ * or if <htx> 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
*/
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 <htx>. If <blk> is the head,
- * NULL returned.
+/* Returns the first HTX block in the HTX message <htx>. If unset or if <htx> is
+ * empty, NULL returned.
*/
static inline struct htx_blk *htx_get_first_blk(const 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 <buf> once HTX overhead is
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;
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;
}
}
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);
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));
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);
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;
*/
#include <common/config.h>
+#include <common/debug.h>
#include <common/cfgparse.h>
#include <common/h1.h>
#include <common/http.h>
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);
}
/* <blk> 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);
}
/* Replaces parts of the start-line of the HTX message <htx>. 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;
}
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;
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 <blk> is defined, set its new position */
if (blk != NULL && blk == oldblk)
}
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);
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;
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;
}
/* 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;
}
}
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;
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)
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;
* 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;
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 */
* 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;
*/
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 */