Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
d48ca6a
add objs/* and autoconf to gitignore
detailyang Aug 14, 2016
4b5f079
add -i option (if not set) to more_set_input_headers
detailyang Aug 14, 2016
8344531
add -i option (if not set) to more_set_headers
detailyang Aug 14, 2016
3b64ac7
allow if no set on non builtin header on more_set_headers
detailyang Aug 15, 2016
6d45d4f
add test for -i option
detailyang Aug 15, 2016
5c73081
better prompt when skip with -i option
detailyang Aug 15, 2016
c802c27
add -i option description to README
detailyang Aug 15, 2016
48c4d43
if no set should work on multi header
detailyang Aug 16, 2016
12c3a00
work together on -r replace and -i if not set
detailyang Aug 17, 2016
30daad1
add test for -i (if not set) option
detailyang Aug 17, 2016
9c53270
Fix: do not set header when header already set
detailyang Aug 17, 2016
ec1fad6
add test for -r -t -i
detailyang Aug 17, 2016
ac52358
add test for more_set_headers on -i -t work together
detailyang Aug 17, 2016
b073439
Merge branch 'master' of https://github.com/detailyang/headers-more-n…
detailyang Aug 17, 2016
e9fbadf
remove misc in gitignore because of we are using the standard building
detailyang Aug 18, 2016
e4202d1
reindex t/*.t
detailyang Aug 18, 2016
0a6073d
correct code style
detailyang Aug 18, 2016
fe4f575
typo: grammer fix
detailyang Aug 18, 2016
0c93a4c
add new line in gitignore
detailyang Aug 18, 2016
c987b90
remove Makefile new line in gitignore
detailyang Aug 18, 2016
df0e156
trailing line space
detailyang Aug 18, 2016
5a0a562
typo -i to -a at t/sanity.t
detailyang Aug 18, 2016
cdfc604
boolean equal shoule use ! rather than 0
detailyang Aug 18, 2016
15ae885
Ditto, Boolean field test should use the !a instead of the a == 0
detailyang Aug 18, 2016
34c5f33
typo: doesnt => do not
detailyang Aug 18, 2016
bb8a365
typo it do not => it does not
detailyang Aug 18, 2016
964d53c
typo remove new values on README.markdown
detailyang Aug 18, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ Synopsis

# replace input header X-Foo *only* if it already exists
more_set_input_headers -r 'X-Foo: howdy';

# add input header X-Foo *only* if it does not exist
more_set_input_headers -a 'X-Foo: howdy';
```

Description
Expand Down Expand Up @@ -134,7 +137,7 @@ Directives

more_set_headers
----------------
**syntax:** *more_set_headers [-t <content-type list>]... [-s <status-code list>]... <new-header>...*
**syntax:** *more_set_headers [-a] [-t <content-type list>]... [-s <status-code list>]... <new-header>...*

**default:** *no*

Expand All @@ -153,6 +156,8 @@ If either `-s` or `-t` is not specified or has an empty list value, then no matc

Existing response headers with the same name are always overridden. If you want to add headers incrementally, use the standard [add_header](http://nginx.org/en/docs/http/ngx_http_headers_module.html#add_header) directive instead.

If the `-a` option is specified, then the headers will be added *only if* they do not exist.

A single directive can set/add multiple output headers. For example

```nginx
Expand Down Expand Up @@ -261,7 +266,7 @@ The `*` wildcard support was first introduced in [v0.09](#v009).

more_set_input_headers
----------------------
**syntax:** *more_set_input_headers [-r] [-t <content-type list>]... <new-header>...*
**syntax:** *more_set_input_headers [-r] [-a] [-t <content-type list>]... <new-header>...*

**default:** *no*

Expand All @@ -280,6 +285,8 @@ and works in subrequests as well.

If the `-r` option is specified, then the headers will be replaced to the new values *only if* they already exist.

If the `-a` options is specified, then the headers will be added *only if* they do not exist.

[Back to TOC](#table-of-contents)

more_clear_input_headers
Expand Down
1 change: 1 addition & 0 deletions src/ngx_http_headers_more_filter_module.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ struct ngx_http_headers_more_header_val_s {
ngx_http_headers_more_set_header_pt handler;
ngx_uint_t offset;
ngx_flag_t replace;
ngx_flag_t add_only;
ngx_flag_t wildcard;
};

Expand Down
68 changes: 43 additions & 25 deletions src/ngx_http_headers_more_headers_in.c
Original file line number Diff line number Diff line change
Expand Up @@ -247,33 +247,34 @@ ngx_http_set_header_helper(ngx_http_request_t *r,
&& ngx_strncasecmp(h[i].key.data, hv->key.data,
h[i].key.len) == 0)
{
if (value->len == 0 || (matched && matched != &h[i])) {
h[i].hash = 0;
if (!(hv->add_only && !hv->replace)) {
if (value->len == 0 || (matched && matched != &h[i])) {
h[i].hash = 0;

rc = ngx_http_headers_more_rm_header_helper(
rc = ngx_http_headers_more_rm_header_helper(
&r->headers_in.headers, part, i);

ngx_http_headers_more_assert(
!(r->headers_in.headers.part.next == NULL
&& r->headers_in.headers.last
!= &r->headers_in.headers.part));
ngx_http_headers_more_assert(
!(r->headers_in.headers.part.next == NULL
&& r->headers_in.headers.last
!= &r->headers_in.headers.part));

if (rc == NGX_OK) {
if (output_header) {
*output_header = NULL;
if (rc == NGX_OK) {
if (output_header) {
*output_header = NULL;
}

goto retry;
}

goto retry;
return NGX_ERROR;
}
h[i].value = *value;

return NGX_ERROR;
}

h[i].value = *value;

if (output_header) {
*output_header = &h[i];
dd("setting existing builtin input header");
if (output_header) {
*output_header = &h[i];
dd("setting existing builtin input header");
}
}

if (matched == NULL) {
Expand All @@ -286,7 +287,7 @@ ngx_http_set_header_helper(ngx_http_request_t *r,
return NGX_OK;
}

if (value->len == 0 || hv->replace) {
if (value->len == 0 || (hv->replace && !hv->add_only)) {
return NGX_OK;
}

Expand Down Expand Up @@ -358,6 +359,11 @@ ngx_http_set_builtin_header(ngx_http_request_t *r,
return ngx_http_set_header_helper(r, hv, value, old);
}

if (hv->add_only) {
dd("skip because %s does set", hv->key.data);
return NGX_OK;
}

h = *old;

if (value->len == 0) {
Expand Down Expand Up @@ -496,17 +502,17 @@ static char *
ngx_http_headers_more_parse_directive(ngx_conf_t *cf, ngx_command_t *ngx_cmd,
void *conf, ngx_http_headers_more_opcode_t opcode)
{
ngx_flag_t replace = 0;
ngx_flag_t add_only = 0;
ngx_http_headers_more_loc_conf_t *hlcf = conf;

ngx_uint_t i;
ngx_http_headers_more_cmd_t *cmd;
ngx_str_t *arg;
ngx_flag_t ignore_next_arg;
ngx_str_t *cmd_name;
ngx_int_t rc;
ngx_flag_t replace = 0;
ngx_uint_t i;
ngx_flag_t ignore_next_arg;
ngx_http_headers_more_cmd_t *cmd;
ngx_http_headers_more_header_val_t *h;

ngx_http_headers_more_main_conf_t *hmcf;

if (hlcf->cmds == NULL) {
Expand Down Expand Up @@ -595,6 +601,12 @@ ngx_http_headers_more_parse_directive(ngx_conf_t *cf, ngx_command_t *ngx_cmd,
replace = 1;
continue;
}

if (arg[i].data[1] == 'a') {
dd("Found add only flag");
add_only = 1;
continue;
}
}

ngx_log_error(NGX_LOG_ERR, cf->log, 0,
Expand All @@ -615,6 +627,7 @@ ngx_http_headers_more_parse_directive(ngx_conf_t *cf, ngx_command_t *ngx_cmd,
h = cmd->headers->elts;
for (i = 0; i < cmd->headers->nelts; i++) {
h[i].replace = replace;
h[i].add_only = add_only;
}
}

Expand Down Expand Up @@ -741,6 +754,11 @@ ngx_http_set_builtin_multi_header(ngx_http_request_t *r,
headers = (ngx_array_t *) ((char *) &r->headers_in + hv->offset);

if (headers->nelts > 0) {
if (hv->add_only) {
dd("skip multi-value headers because %s does set", hv->key.data);
return NGX_OK;
}

ngx_array_destroy(headers);

if (ngx_array_init(headers, r->pool, 2,
Expand Down
44 changes: 36 additions & 8 deletions src/ngx_http_headers_more_headers_out.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,12 @@ ngx_http_set_header_helper(ngx_http_request_t *r,

matched:

if (hv->add_only) {
dd("skip because %s does set", hv->key.data);
matched = 1;
continue;
}

if (value->len == 0 || matched) {
dd("clearing normal header for %.*s", (int) hv->key.len,
hv->key.data);
Expand Down Expand Up @@ -304,6 +310,11 @@ ngx_http_set_builtin_header(ngx_http_request_t *r,
return ngx_http_set_header_helper(r, hv, value, old, 0);
}

if (hv->add_only) {
dd("skip because %s does set", hv->key.data);
return NGX_OK;
}

h = *old;

if (value->len == 0) {
Expand Down Expand Up @@ -344,6 +355,11 @@ ngx_http_set_builtin_multi_header(ngx_http_request_t *r,
/* override old values (if any) */

if (pa->nelts > 0) {
if (hv->add_only) {
dd("skip because %s does set", hv->key.data);
return NGX_OK;
}

ph = pa->elts;
for (i = 1; i < pa->nelts; i++) {
ph[i]->hash = 0;
Expand Down Expand Up @@ -565,16 +581,17 @@ static char *
ngx_http_headers_more_parse_directive(ngx_conf_t *cf, ngx_command_t *ngx_cmd,
void *conf, ngx_http_headers_more_opcode_t opcode)
{
ngx_flag_t add_only = 0;
ngx_http_headers_more_loc_conf_t *hlcf = conf;

ngx_uint_t i;
ngx_http_headers_more_cmd_t *cmd;
ngx_str_t *arg;
ngx_flag_t ignore_next_arg;
ngx_str_t *cmd_name;
ngx_int_t rc;

ngx_http_headers_more_main_conf_t *hmcf;
ngx_str_t *arg;
ngx_str_t *cmd_name;
ngx_int_t rc;
ngx_flag_t ignore_next_arg;
ngx_uint_t i;
ngx_http_headers_more_cmd_t *cmd;
ngx_http_headers_more_main_conf_t *hmcf;
ngx_http_headers_more_header_val_t *h;

if (hlcf->cmds == NULL) {
hlcf->cmds = ngx_array_create(cf->pool, 1,
Expand Down Expand Up @@ -680,6 +697,10 @@ ngx_http_headers_more_parse_directive(ngx_conf_t *cf, ngx_command_t *ngx_cmd,
ignore_next_arg = 1;

continue;

} else if (arg[i].data[1] == 'a') {
add_only = 1;
continue;
}
}

Expand All @@ -695,6 +716,13 @@ ngx_http_headers_more_parse_directive(ngx_conf_t *cf, ngx_command_t *ngx_cmd,

if (cmd->headers->nelts == 0) {
cmd->headers = NULL;

} else {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto.

h = cmd->headers->elts;

for (i = 0; i < cmd->headers->nelts; i++) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need a blank line before the for statement.

h[i].add_only = add_only;
}
}

if (cmd->types->nelts == 0) {
Expand Down
112 changes: 111 additions & 1 deletion t/input.t
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use Test::Nginx::Socket; # 'no_plan';

repeat_each(2);

plan tests => repeat_each() * 124;
plan tests => repeat_each() * 142;

no_long_string();
#no_diff;
Expand Down Expand Up @@ -1289,3 +1289,113 @@ X-Forwarded-For: 8.8.8.8
Foo: 127.0.0.1
--- no_error_log
[error]



=== TEST 50: set request header if not set the header with -a option
--- config
location /foo {
more_set_input_headers -a 'X-Foo: howdy';
echo "input_header: $http_x_foo";
}
--- request
GET /foo
--- response_body
input_header: howdy



=== TEST 51: do not set request header if set the header with -a option
--- config
location /foo {
more_set_input_headers -a 'X-Foo: howdy';
content_by_lua '
local headers = ngx.req.get_headers()
ngx.say(headers["X-Foo"])
';
}
--- request
GET /foo
--- more_headers
X-Foo: blah

--- response_body
blah



=== TEST 52: do not remove multi request header if set the header with -a option
--- config
location /foo {
more_set_input_headers -a 'X-Foo: howdy';
content_by_lua '
local headers = ngx.req.get_headers()
ngx.say(headers["AAA"])
';
}
--- request
GET /foo
--- more_headers
AAA: blah
AAA: baz

--- response_body
blahbaz



=== TEST 53: test -a -t work together
--- config
location /foo {
more_set_input_headers -a -t 'text/html' 'X-Foo: howdy';
content_by_lua '
local headers = ngx.req.get_headers()
ngx.say(headers["X-Foo"])
';
}
--- request
GET /foo
--- more_headers
Content-Type: text/html

--- response_body
howdy



=== TEST 54: test -a -r work together
--- config
location /foo {
more_set_input_headers -a -r 'X-Foo: howdy';
content_by_lua '
local headers = ngx.req.get_headers()
ngx.say(headers["X-Foo"])
';
}
--- request eval
["GET /foo", "GET /foo"]
--- more_headers eval
["X-Foo: hi", ""]

--- response_body eval
["howdy\n", "howdy\n"]



=== TEST 55: test -a -r -t work together
--- config
location /foo {
more_set_input_headers -a -r -t 'text/html' 'X-Foo: howdy';
content_by_lua '
local headers = ngx.req.get_headers()
ngx.say(headers["X-Foo"])
';
}
--- request eval
["GET /foo", "GET /foo", "GET /foo"]
--- more_headers eval
["Content-Type: text/html", "", "Content-Type: text/html\nX-Foo: hi\n"]

--- response_body eval
["howdy\n", "nil\n", "howdy\n"]

Loading