From cb7dd015be4603af3564466d394ac4335aa8102b Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Fri, 3 Apr 2015 22:16:32 +0200 Subject: [PATCH] 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. --- include/types/proto_http.h | 1 - include/types/stream.h | 3 +++ src/frontend.c | 12 ++++++------ src/hlua.c | 4 ++-- src/log.c | 24 +++++++++++------------ src/peers.c | 4 ++-- src/proto_http.c | 40 +++++++++++++++----------------------- src/proto_tcp.c | 2 +- src/stream.c | 8 ++++---- 9 files changed, 46 insertions(+), 52 deletions(-) diff --git a/include/types/proto_http.h b/include/types/proto_http.h index a8c44e5d11..b7dc4b53f9 100644 --- a/include/types/proto_http.h +++ b/include/types/proto_http.h @@ -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 { diff --git a/include/types/stream.h b/include/types/stream.h index db6810c133..80d84ac105 100644 --- a/include/types/stream.h +++ b/include/types/stream.h @@ -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 */ diff --git a/src/frontend.c b/src/frontend.c index caf0fc238d..3a71bc4eeb 100644 --- a/src/frontend.c +++ b/src/frontend.c @@ -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; } diff --git a/src/hlua.c b/src/hlua.c index 650051abe1..e54c02914e 100644 --- a/src/hlua.c +++ b/src/hlua.c @@ -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; diff --git a/src/log.c b/src/log.c index d2f8ad5590..949dc29fcd 100644 --- a/src/log.c +++ b/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; diff --git a/src/peers.c b/src/peers.c index c27fad048e..08ccfa9bbc 100644 --- a/src/peers.c +++ b/src/peers.c @@ -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; diff --git a/src/proto_http.c b/src/proto_http.c index f5149282ec..fac05b77d1 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -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; } diff --git a/src/proto_tcp.c b/src/proto_tcp.c index 6a67785a47..e77edc43b1 100644 --- a/src/proto_tcp.c +++ b/src/proto_tcp.c @@ -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); diff --git a/src/stream.c b/src/stream.c index 70c07a7789..d28684ead0 100644 --- a/src/stream.c +++ b/src/stream.c @@ -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); -- 2.47.3