Skip to content

Commit c93a0c4

Browse files
committed
Headers filter: inheritance control for add_header and add_trailer.
The new directives add_header_inherit and add_trailer_inherit allow to alter inheritance rules for the values specified in the add_header and add_trailer directives in a convenient way. The "merge" parameter enables appending the values from the previous level to the current level values. The "off" parameter cancels inheritance of the values from the previous configuration level, similar to add_header "" (2194e75). The "on" parameter (default) enables the standard inheritance behaviour, which is to inherit values from the previous level only if there are no directives on the current level. The inheritance rules themselves are inherited in a standard way. Thus, for example, "add_header_inherit merge;" specified at the top level will be inherited in all nested levels recursively unless redefined below.
1 parent ac72ca6 commit c93a0c4

File tree

1 file changed

+70
-4
lines changed

1 file changed

+70
-4
lines changed

src/http/modules/ngx_http_headers_filter_module.c

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@
1010
#include <ngx_http.h>
1111

1212

13+
#define NGX_HTTP_HEADERS_INHERIT_OFF 0
14+
#define NGX_HTTP_HEADERS_INHERIT_ON 1
15+
#define NGX_HTTP_HEADERS_INHERIT_MERGE 2
16+
17+
1318
typedef struct ngx_http_header_val_s ngx_http_header_val_t;
1419

1520
typedef ngx_int_t (*ngx_http_set_header_pt)(ngx_http_request_t *r,
@@ -49,6 +54,8 @@ typedef struct {
4954
ngx_http_complex_value_t *expires_value;
5055
ngx_array_t *headers;
5156
ngx_array_t *trailers;
57+
ngx_uint_t headers_inherit;
58+
ngx_uint_t trailers_inherit;
5259
} ngx_http_headers_conf_t;
5360

5461

@@ -97,6 +104,14 @@ static ngx_http_set_header_t ngx_http_set_headers[] = {
97104
};
98105

99106

107+
static ngx_conf_enum_t ngx_http_headers_inherit[] = {
108+
{ ngx_string("off"), NGX_HTTP_HEADERS_INHERIT_OFF },
109+
{ ngx_string("on"), NGX_HTTP_HEADERS_INHERIT_ON },
110+
{ ngx_string("merge"), NGX_HTTP_HEADERS_INHERIT_MERGE },
111+
{ ngx_null_string, 0 }
112+
};
113+
114+
100115
static ngx_command_t ngx_http_headers_filter_commands[] = {
101116

102117
{ ngx_string("expires"),
@@ -123,6 +138,22 @@ static ngx_command_t ngx_http_headers_filter_commands[] = {
123138
offsetof(ngx_http_headers_conf_t, trailers),
124139
NULL },
125140

141+
{ ngx_string("add_header_inherit"),
142+
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
143+
|NGX_CONF_TAKE1,
144+
ngx_conf_set_enum_slot,
145+
NGX_HTTP_LOC_CONF_OFFSET,
146+
offsetof(ngx_http_headers_conf_t, headers_inherit),
147+
&ngx_http_headers_inherit },
148+
149+
{ ngx_string("add_trailer_inherit"),
150+
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
151+
|NGX_CONF_TAKE1,
152+
ngx_conf_set_enum_slot,
153+
NGX_HTTP_LOC_CONF_OFFSET,
154+
offsetof(ngx_http_headers_conf_t, trailers_inherit),
155+
&ngx_http_headers_inherit },
156+
126157
ngx_null_command
127158
};
128159

@@ -657,6 +688,8 @@ ngx_http_headers_create_conf(ngx_conf_t *cf)
657688
*/
658689

659690
conf->expires = NGX_HTTP_EXPIRES_UNSET;
691+
conf->headers_inherit = NGX_CONF_UNSET;
692+
conf->trailers_inherit = NGX_CONF_UNSET;
660693

661694
return conf;
662695
}
@@ -668,6 +701,8 @@ ngx_http_headers_merge_conf(ngx_conf_t *cf, void *parent, void *child)
668701
ngx_http_headers_conf_t *prev = parent;
669702
ngx_http_headers_conf_t *conf = child;
670703

704+
ngx_http_header_val_t *hv;
705+
671706
if (conf->expires == NGX_HTTP_EXPIRES_UNSET) {
672707
conf->expires = prev->expires;
673708
conf->expires_time = prev->expires_time;
@@ -678,12 +713,43 @@ ngx_http_headers_merge_conf(ngx_conf_t *cf, void *parent, void *child)
678713
}
679714
}
680715

681-
if (conf->headers == NULL) {
682-
conf->headers = prev->headers;
716+
ngx_conf_merge_uint_value(conf->headers_inherit, prev->headers_inherit,
717+
NGX_HTTP_HEADERS_INHERIT_ON);
718+
ngx_conf_merge_uint_value(conf->trailers_inherit, prev->trailers_inherit,
719+
NGX_HTTP_HEADERS_INHERIT_ON);
720+
721+
if (conf->headers_inherit != NGX_HTTP_HEADERS_INHERIT_OFF
722+
&& prev->headers)
723+
{
724+
if (conf->headers == NULL) {
725+
conf->headers = prev->headers;
726+
727+
} else if (conf->headers_inherit == NGX_HTTP_HEADERS_INHERIT_MERGE) {
728+
hv = ngx_array_push_n(conf->headers, prev->headers->nelts);
729+
if (hv == NULL) {
730+
return NGX_CONF_ERROR;
731+
}
732+
733+
ngx_memcpy(hv, prev->headers->elts,
734+
sizeof(ngx_http_header_val_t) * prev->headers->nelts);
735+
}
683736
}
684737

685-
if (conf->trailers == NULL) {
686-
conf->trailers = prev->trailers;
738+
if (conf->trailers_inherit != NGX_HTTP_HEADERS_INHERIT_OFF
739+
&& prev->trailers)
740+
{
741+
if (conf->trailers == NULL) {
742+
conf->trailers = prev->trailers;
743+
744+
} else if (conf->trailers_inherit == NGX_HTTP_HEADERS_INHERIT_MERGE) {
745+
hv = ngx_array_push_n(conf->trailers, prev->trailers->nelts);
746+
if (hv == NULL) {
747+
return NGX_CONF_ERROR;
748+
}
749+
750+
ngx_memcpy(hv, prev->trailers->elts,
751+
sizeof(ngx_http_header_val_t) * prev->trailers->nelts);
752+
}
687753
}
688754

689755
return NGX_CONF_OK;

0 commit comments

Comments
 (0)