mirror of
https://github.com/haproxy/haproxy.git
synced 2026-04-22 14:49:45 -04:00
MEDIUM: http: move header captures from http_txn to struct stream
The header captures are now general purpose captures since tcp rules can use them to capture various contents. That removes a dependency on http_txn that appeared in some sample fetch functions and in the order by which captures and http_txn were allocated. Interestingly the reset of the header captures were done at too many places as http_init_txn() used to do it while it was done previously in every call place.
This commit is contained in:
parent
53c9b4db41
commit
cb7dd015be
9 changed files with 46 additions and 52 deletions
|
|
@ -399,7 +399,6 @@ struct http_msg {
|
|||
} sl; /* start line */
|
||||
unsigned long long chunk_len; /* cache for last chunk size or content-length header value */
|
||||
unsigned long long body_len; /* total known length of the body, excluding encoding */
|
||||
char **cap; /* array of captured headers (may be NULL) */
|
||||
};
|
||||
|
||||
struct http_auth_data {
|
||||
|
|
|
|||
|
|
@ -141,6 +141,9 @@ struct stream {
|
|||
|
||||
struct stkctr stkctr[MAX_SESS_STKCTR]; /* stick counters */
|
||||
|
||||
char **req_cap; /* array of captures from the request (may be NULL) */
|
||||
char **res_cap; /* array of captures from the response (may be NULL) */
|
||||
|
||||
struct stream_interface si[2]; /* client and server stream interfaces */
|
||||
struct strm_logs logs; /* logs for this stream */
|
||||
|
||||
|
|
|
|||
|
|
@ -111,15 +111,15 @@ int frontend_accept(struct stream *s)
|
|||
setsockopt(cfd, SOL_SOCKET, SO_RCVBUF, &global.tune.client_rcvbuf, sizeof(global.tune.client_rcvbuf));
|
||||
|
||||
if (unlikely(fe->nb_req_cap > 0)) {
|
||||
if ((s->txn.req.cap = pool_alloc2(fe->req_cap_pool)) == NULL)
|
||||
if ((s->req_cap = pool_alloc2(fe->req_cap_pool)) == NULL)
|
||||
goto out_return; /* no memory */
|
||||
memset(s->txn.req.cap, 0, fe->nb_req_cap * sizeof(void *));
|
||||
memset(s->req_cap, 0, fe->nb_req_cap * sizeof(void *));
|
||||
}
|
||||
|
||||
if (unlikely(fe->nb_rsp_cap > 0)) {
|
||||
if ((s->txn.rsp.cap = pool_alloc2(fe->rsp_cap_pool)) == NULL)
|
||||
if ((s->res_cap = pool_alloc2(fe->rsp_cap_pool)) == NULL)
|
||||
goto out_free_reqcap; /* no memory */
|
||||
memset(s->txn.rsp.cap, 0, fe->nb_rsp_cap * sizeof(void *));
|
||||
memset(s->res_cap, 0, fe->nb_rsp_cap * sizeof(void *));
|
||||
}
|
||||
|
||||
if (fe->http_needed) {
|
||||
|
|
@ -209,9 +209,9 @@ int frontend_accept(struct stream *s)
|
|||
|
||||
/* Error unrolling */
|
||||
out_free_rspcap:
|
||||
pool_free2(fe->rsp_cap_pool, s->txn.rsp.cap);
|
||||
pool_free2(fe->rsp_cap_pool, s->res_cap);
|
||||
out_free_reqcap:
|
||||
pool_free2(fe->req_cap_pool, s->txn.req.cap);
|
||||
pool_free2(fe->req_cap_pool, s->req_cap);
|
||||
out_return:
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2165,14 +2165,14 @@ __LJMP static int hlua_socket_new(lua_State *L)
|
|||
|
||||
/* XXX: ? */
|
||||
socket->s->pend_pos = NULL;
|
||||
socket->s->req_cap = NULL;
|
||||
socket->s->res_cap = NULL;
|
||||
|
||||
/* XXX: See later. */
|
||||
socket->s->txn.sessid = NULL;
|
||||
socket->s->txn.srv_cookie = NULL;
|
||||
socket->s->txn.cli_cookie = NULL;
|
||||
socket->s->txn.uri = NULL;
|
||||
socket->s->txn.req.cap = NULL;
|
||||
socket->s->txn.rsp.cap = NULL;
|
||||
socket->s->txn.hdr_idx.v = NULL;
|
||||
socket->s->txn.hdr_idx.size = 0;
|
||||
socket->s->txn.hdr_idx.used = 0;
|
||||
|
|
|
|||
24
src/log.c
24
src/log.c
|
|
@ -1415,16 +1415,16 @@ int build_logline(struct stream *s, char *dst, size_t maxsize, struct list *list
|
|||
|
||||
case LOG_FMT_HDRREQUEST: // %hr
|
||||
/* request header */
|
||||
if (fe->nb_req_cap && txn->req.cap) {
|
||||
if (fe->nb_req_cap && s->req_cap) {
|
||||
if (tmp->options & LOG_OPT_QUOTE)
|
||||
LOGCHAR('"');
|
||||
LOGCHAR('{');
|
||||
for (hdr = 0; hdr < fe->nb_req_cap; hdr++) {
|
||||
if (hdr)
|
||||
LOGCHAR('|');
|
||||
if (txn->req.cap[hdr] != NULL) {
|
||||
if (s->req_cap[hdr] != NULL) {
|
||||
ret = encode_string(tmplog, dst + maxsize,
|
||||
'#', hdr_encode_map, txn->req.cap[hdr]);
|
||||
'#', hdr_encode_map, s->req_cap[hdr]);
|
||||
if (ret == NULL || *ret != '\0')
|
||||
goto out;
|
||||
tmplog = ret;
|
||||
|
|
@ -1439,15 +1439,15 @@ int build_logline(struct stream *s, char *dst, size_t maxsize, struct list *list
|
|||
|
||||
case LOG_FMT_HDRREQUESTLIST: // %hrl
|
||||
/* request header list */
|
||||
if (fe->nb_req_cap && txn->req.cap) {
|
||||
if (fe->nb_req_cap && s->req_cap) {
|
||||
for (hdr = 0; hdr < fe->nb_req_cap; hdr++) {
|
||||
if (hdr > 0)
|
||||
LOGCHAR(' ');
|
||||
if (tmp->options & LOG_OPT_QUOTE)
|
||||
LOGCHAR('"');
|
||||
if (txn->req.cap[hdr] != NULL) {
|
||||
if (s->req_cap[hdr] != NULL) {
|
||||
ret = encode_string(tmplog, dst + maxsize,
|
||||
'#', hdr_encode_map, txn->req.cap[hdr]);
|
||||
'#', hdr_encode_map, s->req_cap[hdr]);
|
||||
if (ret == NULL || *ret != '\0')
|
||||
goto out;
|
||||
tmplog = ret;
|
||||
|
|
@ -1463,16 +1463,16 @@ int build_logline(struct stream *s, char *dst, size_t maxsize, struct list *list
|
|||
|
||||
case LOG_FMT_HDRRESPONS: // %hs
|
||||
/* response header */
|
||||
if (fe->nb_rsp_cap && txn->rsp.cap) {
|
||||
if (fe->nb_rsp_cap && s->res_cap) {
|
||||
if (tmp->options & LOG_OPT_QUOTE)
|
||||
LOGCHAR('"');
|
||||
LOGCHAR('{');
|
||||
for (hdr = 0; hdr < fe->nb_rsp_cap; hdr++) {
|
||||
if (hdr)
|
||||
LOGCHAR('|');
|
||||
if (txn->rsp.cap[hdr] != NULL) {
|
||||
if (s->res_cap[hdr] != NULL) {
|
||||
ret = encode_string(tmplog, dst + maxsize,
|
||||
'#', hdr_encode_map, txn->rsp.cap[hdr]);
|
||||
'#', hdr_encode_map, s->res_cap[hdr]);
|
||||
if (ret == NULL || *ret != '\0')
|
||||
goto out;
|
||||
tmplog = ret;
|
||||
|
|
@ -1487,15 +1487,15 @@ int build_logline(struct stream *s, char *dst, size_t maxsize, struct list *list
|
|||
|
||||
case LOG_FMT_HDRRESPONSLIST: // %hsl
|
||||
/* response header list */
|
||||
if (fe->nb_rsp_cap && txn->rsp.cap) {
|
||||
if (fe->nb_rsp_cap && s->res_cap) {
|
||||
for (hdr = 0; hdr < fe->nb_rsp_cap; hdr++) {
|
||||
if (hdr > 0)
|
||||
LOGCHAR(' ');
|
||||
if (tmp->options & LOG_OPT_QUOTE)
|
||||
LOGCHAR('"');
|
||||
if (txn->rsp.cap[hdr] != NULL) {
|
||||
if (s->res_cap[hdr] != NULL) {
|
||||
ret = encode_string(tmplog, dst + maxsize,
|
||||
'#', hdr_encode_map, txn->rsp.cap[hdr]);
|
||||
'#', hdr_encode_map, s->res_cap[hdr]);
|
||||
if (ret == NULL || *ret != '\0')
|
||||
goto out;
|
||||
tmplog = ret;
|
||||
|
|
|
|||
|
|
@ -1154,6 +1154,8 @@ static struct stream *peer_session_create(struct peer *peer, struct peer_session
|
|||
s->sess->fe = p;
|
||||
s->be = s->sess->fe;
|
||||
s->req.buf = s->res.buf = NULL;
|
||||
s->req_cap = NULL;
|
||||
s->res_cap = NULL;
|
||||
|
||||
s->si[0].flags = SI_FL_NONE;
|
||||
s->si[1].flags = SI_FL_ISBACK;
|
||||
|
|
@ -1225,8 +1227,6 @@ static struct stream *peer_session_create(struct peer *peer, struct peer_session
|
|||
txn->srv_cookie = NULL;
|
||||
txn->cli_cookie = NULL;
|
||||
txn->uri = NULL;
|
||||
txn->req.cap = NULL;
|
||||
txn->rsp.cap = NULL;
|
||||
txn->hdr_idx.v = NULL;
|
||||
txn->hdr_idx.size = txn->hdr_idx.used = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -2951,9 +2951,9 @@ int http_wait_for_request(struct stream *s, struct channel *req, int an_bit)
|
|||
msg->flags &= ~HTTP_MSGF_XFER_LEN;
|
||||
|
||||
/* 5: we may need to capture headers */
|
||||
if (unlikely((s->logs.logwait & LW_REQHDR) && txn->req.cap))
|
||||
if (unlikely((s->logs.logwait & LW_REQHDR) && s->req_cap))
|
||||
capture_headers(req->buf->p, &txn->hdr_idx,
|
||||
txn->req.cap, sess->fe->req_cap);
|
||||
s->req_cap, sess->fe->req_cap);
|
||||
|
||||
/* 6: determine the transfer-length.
|
||||
* According to RFC2616 #4.4, amended by the HTTPbis working group,
|
||||
|
|
@ -6076,9 +6076,9 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
|
|||
* 3: we may need to capture headers
|
||||
*/
|
||||
s->logs.logwait &= ~LW_RESP;
|
||||
if (unlikely((s->logs.logwait & LW_RSPHDR) && txn->rsp.cap))
|
||||
if (unlikely((s->logs.logwait & LW_RSPHDR) && s->res_cap))
|
||||
capture_headers(rep->buf->p, &txn->hdr_idx,
|
||||
txn->rsp.cap, sess->fe->rsp_cap);
|
||||
s->res_cap, sess->fe->rsp_cap);
|
||||
|
||||
/* 4: determine the transfer-length.
|
||||
* According to RFC2616 #4.4, amended by the HTTPbis working group,
|
||||
|
|
@ -8824,12 +8824,6 @@ void http_init_txn(struct stream *s)
|
|||
if (fe->options2 & PR_O2_REQBUG_OK)
|
||||
txn->req.err_pos = -1; /* let buggy requests pass */
|
||||
|
||||
if (txn->req.cap)
|
||||
memset(txn->req.cap, 0, fe->nb_req_cap * sizeof(void *));
|
||||
|
||||
if (txn->rsp.cap)
|
||||
memset(txn->rsp.cap, 0, fe->nb_rsp_cap * sizeof(void *));
|
||||
|
||||
if (txn->hdr_idx.v)
|
||||
hdr_idx_init(&txn->hdr_idx);
|
||||
}
|
||||
|
|
@ -8859,18 +8853,18 @@ void http_end_txn(struct stream *s)
|
|||
txn->srv_cookie = NULL;
|
||||
txn->cli_cookie = NULL;
|
||||
|
||||
if (txn->req.cap) {
|
||||
if (s->req_cap) {
|
||||
struct cap_hdr *h;
|
||||
for (h = fe->req_cap; h; h = h->next)
|
||||
pool_free2(h->pool, txn->req.cap[h->index]);
|
||||
memset(txn->req.cap, 0, fe->nb_req_cap * sizeof(void *));
|
||||
pool_free2(h->pool, s->req_cap[h->index]);
|
||||
memset(s->req_cap, 0, fe->nb_req_cap * sizeof(void *));
|
||||
}
|
||||
|
||||
if (txn->rsp.cap) {
|
||||
if (s->res_cap) {
|
||||
struct cap_hdr *h;
|
||||
for (h = fe->rsp_cap; h; h = h->next)
|
||||
pool_free2(h->pool, txn->rsp.cap[h->index]);
|
||||
memset(txn->rsp.cap, 0, fe->nb_rsp_cap * sizeof(void *));
|
||||
pool_free2(h->pool, s->res_cap[h->index]);
|
||||
memset(s->res_cap, 0, fe->nb_rsp_cap * sizeof(void *));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -10830,7 +10824,6 @@ smp_fetch_capture_header_req(struct proxy *px, struct stream *l4, void *l7, unsi
|
|||
const struct arg *args, struct sample *smp, const char *kw, void *private)
|
||||
{
|
||||
struct proxy *fe = strm_sess(l4)->fe;
|
||||
struct http_txn *txn = l7;
|
||||
int idx;
|
||||
|
||||
if (!args || args->type != ARGT_UINT)
|
||||
|
|
@ -10838,13 +10831,13 @@ smp_fetch_capture_header_req(struct proxy *px, struct stream *l4, void *l7, unsi
|
|||
|
||||
idx = args->data.uint;
|
||||
|
||||
if (idx > (fe->nb_req_cap - 1) || txn->req.cap == NULL || txn->req.cap[idx] == NULL)
|
||||
if (idx > (fe->nb_req_cap - 1) || l4->req_cap == NULL || l4->req_cap[idx] == NULL)
|
||||
return 0;
|
||||
|
||||
smp->type = SMP_T_STR;
|
||||
smp->flags |= SMP_F_CONST;
|
||||
smp->data.str.str = txn->req.cap[idx];
|
||||
smp->data.str.len = strlen(txn->req.cap[idx]);
|
||||
smp->data.str.str = l4->req_cap[idx];
|
||||
smp->data.str.len = strlen(l4->req_cap[idx]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -10857,7 +10850,6 @@ smp_fetch_capture_header_res(struct proxy *px, struct stream *l4, void *l7, unsi
|
|||
const struct arg *args, struct sample *smp, const char *kw, void *private)
|
||||
{
|
||||
struct proxy *fe = strm_sess(l4)->fe;
|
||||
struct http_txn *txn = l7;
|
||||
int idx;
|
||||
|
||||
if (!args || args->type != ARGT_UINT)
|
||||
|
|
@ -10865,13 +10857,13 @@ smp_fetch_capture_header_res(struct proxy *px, struct stream *l4, void *l7, unsi
|
|||
|
||||
idx = args->data.uint;
|
||||
|
||||
if (idx > (fe->nb_rsp_cap - 1) || txn->rsp.cap == NULL || txn->rsp.cap[idx] == NULL)
|
||||
if (idx > (fe->nb_rsp_cap - 1) || l4->res_cap == NULL || l4->res_cap[idx] == NULL)
|
||||
return 0;
|
||||
|
||||
smp->type = SMP_T_STR;
|
||||
smp->flags |= SMP_F_CONST;
|
||||
smp->data.str.str = txn->rsp.cap[idx];
|
||||
smp->data.str.len = strlen(txn->rsp.cap[idx]);
|
||||
smp->data.str.str = l4->res_cap[idx];
|
||||
smp->data.str.len = strlen(l4->res_cap[idx]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1190,7 +1190,7 @@ resume_execution:
|
|||
else if (rule->action == TCP_ACT_CAPTURE) {
|
||||
struct sample *key;
|
||||
struct cap_hdr *h = rule->act_prm.cap.hdr;
|
||||
char **cap = s->txn.req.cap;
|
||||
char **cap = s->req_cap;
|
||||
int len;
|
||||
|
||||
key = sample_fetch_string(s->be, s, &s->txn, SMP_OPT_DIR_REQ | partial, rule->act_prm.cap.expr);
|
||||
|
|
|
|||
|
|
@ -452,6 +452,8 @@ int stream_complete(struct stream *s)
|
|||
s->be = sess->fe;
|
||||
s->comp_algo = NULL;
|
||||
s->req.buf = s->res.buf = NULL;
|
||||
s->req_cap = NULL;
|
||||
s->res_cap = NULL;
|
||||
|
||||
/* Let's count a stream now */
|
||||
proxy_inc_fe_sess_ctr(l, p);
|
||||
|
|
@ -538,8 +540,6 @@ int stream_complete(struct stream *s)
|
|||
txn->srv_cookie = NULL;
|
||||
txn->cli_cookie = NULL;
|
||||
txn->uri = NULL;
|
||||
txn->req.cap = NULL;
|
||||
txn->rsp.cap = NULL;
|
||||
txn->hdr_idx.v = NULL;
|
||||
txn->hdr_idx.size = txn->hdr_idx.used = 0;
|
||||
txn->flags = 0;
|
||||
|
|
@ -651,8 +651,8 @@ static void stream_free(struct stream *s)
|
|||
|
||||
pool_free2(pool2_hdr_idx, txn->hdr_idx.v);
|
||||
if (fe) {
|
||||
pool_free2(fe->rsp_cap_pool, txn->rsp.cap);
|
||||
pool_free2(fe->req_cap_pool, txn->req.cap);
|
||||
pool_free2(fe->rsp_cap_pool, s->res_cap);
|
||||
pool_free2(fe->req_cap_pool, s->req_cap);
|
||||
}
|
||||
|
||||
stream_store_counters(s);
|
||||
|
|
|
|||
Loading…
Reference in a new issue