diff --git a/include/types/filters.h b/include/types/filters.h index 34818cf05..e01e22599 100644 --- a/include/types/filters.h +++ b/include/types/filters.h @@ -87,6 +87,10 @@ struct flt_kw_list { * it needs to wait, any other value otherwise. * * + * - http_headers : Called before the body parsing, after all HTTP + * headers was parsed and analyzed. + * Returns a negative value if an error occurs, 0 if + * it needs to wait, any other value otherwise. * - http_data : Called when unparsed body data are available. * Returns a negative value if an error occurs, else * the number of consumed bytes. @@ -142,6 +146,7 @@ struct flt_ops { /* * HTTP callbacks */ + int (*http_headers) (struct stream *s, struct filter *f, struct http_msg *msg); int (*http_data) (struct stream *s, struct filter *f, struct http_msg *msg); int (*http_chunk_trailers)(struct stream *s, struct filter *f, struct http_msg *msg); int (*http_end) (struct stream *s, struct filter *f, struct http_msg *msg); diff --git a/src/filters.c b/src/filters.c index e96af31a7..051aa4873 100644 --- a/src/filters.c +++ b/src/filters.c @@ -680,20 +680,21 @@ flt_analyze(struct stream *s, struct channel *chn, unsigned int an_bit) } /* - * This function do the same that the previsous one, but for the - * AN_FLT_HTTP_HDRS analyzer. The difference is what is done when all filters - * have been called. Returns 0 if an error occurs or if it needs to wait, any - * other value otherwise. + * This function is the AN_FLT_HTTP_HDRS analyzer, used to filter HTTP headers + * or a request or a response. Returns 0 if an error occurs or if it needs to + * wait, any other value otherwise. */ int flt_analyze_http_headers(struct stream *s, struct channel *chn, unsigned int an_bit) { - struct filter *filter; - int ret = 1; + struct filter *filter; + struct http_msg *msg; + int ret = 1; + msg = ((chn->flags & CF_ISRESP) ? &s->txn->rsp : &s->txn->req); RESUME_FILTER_LOOP(s, chn) { - if (FLT_OPS(filter)->channel_analyze) { - ret = FLT_OPS(filter)->channel_analyze(s, filter, chn, an_bit); + if (FLT_OPS(filter)->http_headers) { + ret = FLT_OPS(filter)->http_headers(s, filter, msg); if (ret <= 0) BREAK_EXECUTION(s, chn, check_result); } @@ -707,9 +708,7 @@ flt_analyze_http_headers(struct stream *s, struct channel *chn, unsigned int an_ /* Handle "data" filters only */ if (!IS_DATA_FILTER(filter, chn)) continue; - - FLT_NXT(filter, chn) = ((chn->flags & CF_ISRESP) - ? s->txn->rsp.sov : s->txn->req.sov); + FLT_NXT(filter, chn) = msg->sov; } check_result: diff --git a/src/flt_http_comp.c b/src/flt_http_comp.c index fb431c13c..9ddc85837 100644 --- a/src/flt_http_comp.c +++ b/src/flt_http_comp.c @@ -102,31 +102,6 @@ comp_start_analyze(struct stream *s, struct filter *filter, struct channel *chn) return 1; } -static int -comp_analyze(struct stream *s, struct filter *filter, struct channel *chn, - unsigned int an_bit) -{ - struct comp_state *st = filter->ctx; - - if (!strm_fe(s)->comp && !s->be->comp) - goto end; - - if (an_bit == AN_FLT_HTTP_HDRS) { - if (!(chn->flags & CF_ISRESP)) - select_compression_request_header(st, s, &s->txn->req); - else { - select_compression_response_header(st, s, &s->txn->rsp); - if (st->comp_algo) { - register_data_filter(s, chn, filter); - st->hdrs_len = s->txn->rsp.sov; - } - } - } - - end: - return 1; -} - static int comp_end_analyze(struct stream *s, struct filter *filter, struct channel *chn) { @@ -153,6 +128,28 @@ comp_end_analyze(struct stream *s, struct filter *filter, struct channel *chn) return 1; } +static int +comp_http_headers(struct stream *s, struct filter *filter, struct http_msg *msg) +{ + struct comp_state *st = filter->ctx; + + if (!strm_fe(s)->comp && !s->be->comp) + goto end; + + if (!(msg->chn->flags & CF_ISRESP)) + select_compression_request_header(st, s, msg); + else { + select_compression_response_header(st, s, msg); + if (st->comp_algo) { + register_data_filter(s, msg->chn, filter); + st->hdrs_len = s->txn->rsp.sov; + } + } + + end: + return 1; +} + static int comp_http_data(struct stream *s, struct filter *filter, struct http_msg *msg) { @@ -756,9 +753,9 @@ struct flt_ops comp_ops = { .deinit = comp_flt_deinit, .channel_start_analyze = comp_start_analyze, - .channel_analyze = comp_analyze, .channel_end_analyze = comp_end_analyze, + .http_headers = comp_http_headers, .http_data = comp_http_data, .http_chunk_trailers = comp_http_chunk_trailers, .http_forward_data = comp_http_forward_data, diff --git a/src/flt_trace.c b/src/flt_trace.c index 8b47651ed..8a9d14dfa 100644 --- a/src/flt_trace.c +++ b/src/flt_trace.c @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -196,9 +197,6 @@ trace_chn_analyze(struct stream *s, struct filter *filter, case AN_REQ_HTTP_XFER_BODY: ana = "AN_REQ_HTTP_XFER_BODY"; break; - case AN_REQ_ALL: - ana = "AN_REQ_ALL"; - break; case AN_RES_INSPECT: ana = "AN_RES_INSPECT"; break; @@ -211,15 +209,9 @@ trace_chn_analyze(struct stream *s, struct filter *filter, case AN_RES_STORE_RULES: ana = "AN_RES_STORE_RULES"; break; - case AN_FLT_HTTP_HDRS: - ana = "AN_FLT_HTTP_HDRS"; - break; case AN_RES_HTTP_XFER_BODY: ana = "AN_RES_HTTP_XFER_BODY"; break; - case AN_FLT_XFER_DATA: - ana = "AN_FLT_XFER_DATA"; - break; default: ana = "unknown"; } @@ -247,6 +239,33 @@ trace_chn_end_analyze(struct stream *s, struct filter *filter, /************************************************************************** * Hooks to filter HTTP messages *************************************************************************/ +static int +trace_http_headers(struct stream *s, struct filter *filter, + struct http_msg *msg) +{ + struct trace_config *conf = FLT_CONF(filter); + struct hdr_idx *hdr_idx; + char *cur_hdr; + int cur_idx; + + STRM_TRACE(conf, s, "%-25s: channel=%-10s - mode=%-5s (%s)", + __FUNCTION__, + channel_label(msg->chn), proxy_mode(s), stream_pos(s)); + + STRM_TRACE(conf, s, "\t%.*s", MIN(msg->sl.rq.l, 74), msg->chn->buf->p); + hdr_idx = &s->txn->hdr_idx; + cur_idx = hdr_idx_first_idx(hdr_idx); + cur_hdr = msg->chn->buf->p + hdr_idx_first_pos(hdr_idx); + while (cur_idx) { + STRM_TRACE(conf, s, "\t%.*s", + MIN(hdr_idx->v[cur_idx].len, 74), cur_hdr); + cur_hdr += hdr_idx->v[cur_idx].len + hdr_idx->v[cur_idx].cr + 1; + cur_idx = hdr_idx->v[cur_idx].next; + } + register_data_filter(s, msg->chn, filter); + return 1; +} + static int trace_http_data(struct stream *s, struct filter *filter, struct http_msg *msg) @@ -398,6 +417,7 @@ struct flt_ops trace_ops = { .channel_end_analyze = trace_chn_end_analyze, /* Filter HTTP requests and responses */ + .http_headers = trace_http_headers, .http_data = trace_http_data, .http_chunk_trailers = trace_http_chunk_trailers, .http_end = trace_http_end,