From ddb7d61f6173c2f191f4eddc15f1f912e940e42c Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Wed, 19 Jul 2023 13:36:59 +0200 Subject: HTTP: filter: supporting a list of filter_handlers Filter handlers are a new handler that takes place when a buffer is about to be sent. It filters (modifies) the contents of the buffer in-place, so that the new contents will be sent. Several filters can be applied in a loop. Signed-off-by: Alejandro Colomar Signed-off-by: Alejandro Colomar --- src/nxt_http.h | 2 ++ src/nxt_http_filter.h | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/nxt_http_request.c | 13 +++++++++++++ 3 files changed, 68 insertions(+) create mode 100644 src/nxt_http_filter.h diff --git a/src/nxt_http.h b/src/nxt_http.h index d614b303..300c197d 100644 --- a/src/nxt_http.h +++ b/src/nxt_http.h @@ -142,6 +142,7 @@ struct nxt_http_request_s { nxt_work_handler_t body_handler; void *body_handler_data; + nxt_list_t *response_filters; nxt_nsec_t start_time; @@ -439,4 +440,5 @@ nxt_msec_t nxt_h1p_conn_request_timer_value(nxt_conn_t *c, uintptr_t data); extern const nxt_conn_state_t nxt_h1p_idle_close_state; + #endif /* _NXT_HTTP_H_INCLUDED_ */ diff --git a/src/nxt_http_filter.h b/src/nxt_http_filter.h new file mode 100644 index 00000000..d26ae1a9 --- /dev/null +++ b/src/nxt_http_filter.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) Alejandro Colomar + * Copyright (C) NGINX, Inc. + */ + +#ifndef NXT_HTTP_FILTER_H_INCLUDED_ +#define NXT_HTTP_FILTER_H_INCLUDED_ + + +#include "nxt_router.h" + +#include "nxt_auto_config.h" + +#include + +#include "nxt_clang.h" +#include "nxt_errno.h" +#include "nxt_list.h" +#include "nxt_main.h" + + +typedef struct nxt_http_filter_handler_s nxt_http_filter_handler_t; + + +struct nxt_http_filter_handler_s { + nxt_work_handler_t filter_handler; + void *data; +}; + + +nxt_inline nxt_int_t nxt_http_filter_handler_add(nxt_http_request_t *r, + nxt_work_handler_t filter_handler, void *data); + + +nxt_inline nxt_int_t +nxt_http_filter_handler_add(nxt_http_request_t *r, + nxt_work_handler_t filter_handler, void *data) +{ + nxt_http_filter_handler_t *elem; + + elem = nxt_list_add(r->response_filters); + if (nxt_slow_path(elem == NULL)) { + return NXT_ERROR; + } + + elem->filter_handler = filter_handler; + elem->data = data; + + return NXT_OK; +} + + +#endif /* NXT_HTTP_FILTER_H_INCLUDED_ */ diff --git a/src/nxt_http_request.c b/src/nxt_http_request.c index 3bcf3d94..e72a7492 100644 --- a/src/nxt_http_request.c +++ b/src/nxt_http_request.c @@ -7,6 +7,8 @@ #include #include +#include "nxt_http_filter.h" + static nxt_int_t nxt_http_validate_host(nxt_str_t *host, nxt_mp_t *mp); static void nxt_http_request_start(nxt_task_t *task, void *obj, void *data); @@ -262,6 +264,11 @@ nxt_http_request_create(nxt_task_t *task) goto fail; } + r->response_filters = nxt_list_create(mp, 1, sizeof(nxt_http_filter_handler_t)); + if (nxt_slow_path(r->response_filters == NULL)) { + goto fail; + } + last = nxt_mp_zget(mp, NXT_BUF_SYNC_SIZE); if (nxt_slow_path(last == NULL)) { goto fail; @@ -723,6 +730,12 @@ nxt_http_request_ws_frame_start(nxt_task_t *task, nxt_http_request_t *r, void nxt_http_request_send(nxt_task_t *task, nxt_http_request_t *r, nxt_buf_t *out) { + nxt_http_filter_handler_t *filter; + + nxt_list_each(filter, r->response_filters) { + filter->filter_handler(task, &out, filter->data); + } nxt_list_loop; + if (nxt_fast_path(r->proto.any != NULL)) { nxt_http_proto[r->protocol].send(task, r, out); } -- cgit