Skip to content

Commit 702519a

Browse files
committed
update add request header feature in nginx config
Enable to add extra header in nginx config
1 parent 6a05d73 commit 702519a

File tree

4 files changed

+398
-62
lines changed

4 files changed

+398
-62
lines changed

build_test_resources/sanity_test_raw_parse.t

Lines changed: 62 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ foo: foovalue
151151
152152
153153
154-
=== TEST 10: Authentication
154+
=== TEST 10: Authentication with nginx c function header
155155
--- config
156156
ngx_http_c_func_link_lib "/home/taymindis/github/nginx-c-function/t/libcfuntest.so";
157157
location /backend {
@@ -161,7 +161,31 @@ location = /auth {
161161
internal;
162162
ngx_http_c_func_call "my_simple_authentication";
163163
}
164-
location = /my_simple_authentication {
164+
location = /my_simple_authentication {
165+
ngx_http_c_func_add_req_header userId $arg_userId;
166+
ngx_http_c_func_add_req_header userPass $arg_userPass;
167+
auth_request /auth;
168+
proxy_pass http://127.0.0.1:${server_port}/backend?userName=$http_userName;
169+
}
170+
--- request
171+
GET /my_simple_authentication?userId=foo&userPass=xxxx
172+
--- error_code: 200
173+
--- response_body_like eval
174+
qr/Welcome foo$/
175+
176+
177+
178+
=== TEST 11: Authentication with nginx c function header
179+
--- config
180+
ngx_http_c_func_link_lib "/home/taymindis/github/nginx-c-function/t/libcfuntest.so";
181+
location /backend {
182+
return 200 "Welcome ${arg_userName}";
183+
}
184+
location = /auth {
185+
internal;
186+
ngx_http_c_func_call "my_simple_authentication";
187+
}
188+
location = /my_simple_authentication {
165189
auth_request /auth;
166190
proxy_pass http://127.0.0.1:${server_port}/backend?userName=$http_userName;
167191
}
@@ -178,7 +202,7 @@ qr/Welcome foo$/
178202
# Test Suite below is aio threads
179203
180204
181-
=== TEST 11: Set C_FUNC_TEST_1
205+
=== TEST 21: aio threads Set C_FUNC_TEST_1
182206
--- main_config eval: $::main_conf
183207
--- config
184208
aio threads=my_thread_pool;
@@ -195,7 +219,7 @@ Content-Type: text/plain
195219
qr/greeting from ngx_http_c_func testing$/
196220
197221
198-
=== TEST 12: Set C_FUNC_TEST_ARGS
222+
=== TEST 22: aio threads Set C_FUNC_TEST_ARGS
199223
--- main_config eval: $::main_conf
200224
--- config
201225
aio threads=my_thread_pool;
@@ -212,7 +236,7 @@ Content-Type: text/plain
212236
qr/greeting=hello_nginx\?id=129310923$/
213237
214238
215-
=== TEST 13: Set C_FUNC_TEST_POST_NONE
239+
=== TEST 23: aio threads Set C_FUNC_TEST_POST_NONE
216240
--- main_config eval: $::main_conf
217241
--- config
218242
aio threads=my_thread_pool;
@@ -230,7 +254,7 @@ Content-Type: text/plain
230254
qr/\s/
231255
232256
233-
=== TEST 14: Set C_FUNC_TEST_GET_TOKEN
257+
=== TEST 24: aio threads Set C_FUNC_TEST_GET_TOKEN
234258
--- main_config eval: $::main_conf
235259
--- config
236260
aio threads=my_thread_pool;
@@ -247,7 +271,7 @@ Content-Type: text/plain
247271
qr/QVNKS0pDQVNLTEpDS0xBU0pXbGtlandrbGplIGpka2FqbGthc2tsZGtqbHNrICBrZGpha2xzZGphc2Rhcw==$/
248272
249273
250-
=== TEST 15: Set C_FUNC_TEST_GET_ERROR_RESP
274+
=== TEST 25: aio threads Set C_FUNC_TEST_GET_ERROR_RESP
251275
--- main_config eval: $::main_conf
252276
--- config
253277
aio threads=my_thread_pool;
@@ -263,7 +287,7 @@ GET /testCFUNCERRORRESP?token=QVNKS0pDQVNLTEpDS0xBU0pXbGtlandrbGplIGpka2FqbGthc2
263287
Content-Type: text/html
264288
265289
266-
=== TEST 16: Set C_FUNC_TEST_GET_CALLOC_FROM_POOL
290+
=== TEST 26: aio threads Set C_FUNC_TEST_GET_CALLOC_FROM_POOL
267291
--- main_config eval: $::main_conf
268292
--- config
269293
aio threads=my_thread_pool;
@@ -280,7 +304,7 @@ Content-Type: text/plain
280304
qr/This is the message calloc from pool$/
281305
282306
283-
=== TEST 17: Set C_FUNC_TEST_POST_BODY
307+
=== TEST 27: aio threads Set C_FUNC_TEST_POST_BODY
284308
--- main_config eval: $::main_conf
285309
--- config
286310
aio threads=my_thread_pool;
@@ -298,7 +322,7 @@ Content-Type: text/plain
298322
qr/greeting=enjoy-http-c-function-testing$/
299323
300324
301-
=== TEST 18: Set C_FUNC_TEST_CACHE
325+
=== TEST 28: aio threads Set C_FUNC_TEST_CACHE
302326
--- main_config eval: $::main_conf
303327
--- config
304328
aio threads=my_thread_pool;
@@ -315,7 +339,7 @@ location = /testCFunSetCache {
315339
["OK", "This is cache value"]
316340
317341
318-
=== TEST 19: output headers
342+
=== TEST 29: aio threads output headers
319343
--- main_config eval: $::main_conf
320344
--- config
321345
aio threads=my_thread_pool;
@@ -331,7 +355,33 @@ foo: foovalue
331355
332356
333357
334-
=== TEST 20: Authentication
358+
=== TEST 30: aio threads Authentication with nginx c function header
359+
--- main_config eval: $::main_conf
360+
--- config
361+
aio threads=my_thread_pool;
362+
ngx_http_c_func_link_lib "/home/taymindis/github/nginx-c-function/t/libcfuntest.so";
363+
location /backend {
364+
return 200 "Welcome ${arg_userName}";
365+
}
366+
location = /auth {
367+
internal;
368+
ngx_http_c_func_call "my_simple_authentication";
369+
}
370+
location = /my_simple_authentication {
371+
ngx_http_c_func_add_req_header userId $arg_userId;
372+
ngx_http_c_func_add_req_header userPass $arg_userPass;
373+
auth_request /auth;
374+
proxy_pass http://127.0.0.1:${server_port}/backend?userName=$http_userName;
375+
}
376+
--- request
377+
GET /my_simple_authentication?userId=foo&userPass=xxxx
378+
--- error_code: 200
379+
--- response_body_like eval
380+
qr/Welcome foo$/
381+
382+
383+
384+
=== TEST 31: aio threads Authentication with client header
335385
--- main_config eval: $::main_conf
336386
--- config
337387
aio threads=my_thread_pool;

src/ngx_http_c_func_module.c

Lines changed: 102 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,14 @@ typedef struct {
7979
} ngx_http_c_func_srv_conf_t;
8080

8181
typedef struct {
82-
ngx_str_t _method_name;
82+
ngx_str_t key;
83+
ngx_http_complex_value_t value;
84+
} ngx_http_c_func_req_header_t;
85+
86+
typedef struct {
87+
ngx_str_t _method_name;
8388
ngx_http_c_func_app_handler _handler;
89+
ngx_array_t *ext_req_headers;
8490
// ngx_msec_t proc_timeout;
8591
} ngx_http_c_func_loc_conf_t;
8692

@@ -113,8 +119,10 @@ static void * ngx_http_c_func_create_srv_conf(ngx_conf_t *cf);
113119
static char * ngx_http_c_func_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child);
114120
static void * ngx_http_c_func_create_loc_conf(ngx_conf_t *cf);
115121
static char * ngx_http_c_func_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child);
122+
static char *ngx_http_c_func_ext_req_headers_add_cmd(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
116123
static char *ngx_http_c_func_init_method(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
117124
static ngx_int_t ngx_http_c_func_precontent_handler(ngx_http_request_t *r);
125+
static void ngx_http_c_func_parse_ext_request_headers(ngx_http_request_t *r, ngx_array_t *ext_req_headers);
118126
static ngx_int_t ngx_http_c_func_rewrite_handler(ngx_http_request_t *r);
119127
static ngx_int_t ngx_http_c_func_process_init(ngx_cycle_t *cycle);
120128
static void ngx_http_c_func_process_exit(ngx_cycle_t *cycle);
@@ -230,6 +238,13 @@ static ngx_command_t ngx_http_c_func_commands[] = {
230238
offsetof(ngx_http_c_func_srv_conf_t, _ca_cart),
231239
NULL
232240
},
241+
{ ngx_string("ngx_http_c_func_add_req_header"),
242+
NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_HTTP_LIF_CONF | NGX_CONF_TAKE2,
243+
ngx_http_c_func_ext_req_headers_add_cmd,
244+
NGX_HTTP_LOC_CONF_OFFSET,
245+
0,
246+
NULL
247+
},
233248
{ ngx_string("ngx_http_c_func_call"), /* directive */
234249
NGX_HTTP_LOC_CONF | NGX_CONF_TAKE1, /* location context and takes 1 or 2 arguments*/
235250
ngx_http_c_func_init_method, /* configuration setup function */
@@ -425,6 +440,42 @@ ngx_http_c_func_validation_check_and_set_str_slot(ngx_conf_t *cf, ngx_command_t
425440
// return NGX_CONF_OK;
426441
// } /* ngx_http_c_func_srv_post_conf_handler */
427442

443+
static char *
444+
ngx_http_c_func_ext_req_headers_add_cmd(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) {
445+
ngx_http_c_func_loc_conf_t *lcf = conf;
446+
ngx_str_t *value;
447+
ngx_http_c_func_req_header_t *hdr;
448+
ngx_http_compile_complex_value_t ccv;
449+
450+
value = cf->args->elts;
451+
452+
if (lcf->ext_req_headers == NULL || lcf->ext_req_headers == NGX_CONF_UNSET_PTR) {
453+
lcf->ext_req_headers = ngx_array_create(cf->pool, 2,
454+
sizeof(ngx_http_c_func_req_header_t));
455+
if (lcf->ext_req_headers == NULL) {
456+
return NGX_CONF_ERROR;
457+
}
458+
}
459+
460+
hdr = ngx_array_push(lcf->ext_req_headers);
461+
if (hdr == NULL) {
462+
return NGX_CONF_ERROR;
463+
}
464+
465+
hdr->key = value[1];
466+
467+
ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
468+
469+
ccv.cf = cf;
470+
ccv.value = &value[2];
471+
ccv.complex_value = &hdr->value;
472+
473+
if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
474+
return NGX_CONF_ERROR;
475+
}
476+
return NGX_CONF_OK;
477+
}
478+
428479
/**
429480
* Configuration setup function that installs the content handler.
430481
*
@@ -439,34 +490,12 @@ ngx_http_c_func_validation_check_and_set_str_slot(ngx_conf_t *cf, ngx_command_t
439490
*/
440491
static char *
441492
ngx_http_c_func_init_method(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) {
442-
// ngx_str_t *value;
443493
ngx_http_c_func_srv_conf_t *scf;
444494
ngx_http_c_func_loc_conf_t *lcf = conf;
445-
// ngx_str_t varname;
446495

447496

448497
scf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_c_func_module);
449498

450-
// value = cf->args->elts;
451-
452-
// if (cf->args->nelts == 3 &&
453-
// value[2].len > sizeof("respTo=") - 1 &&
454-
// ngx_strncmp(value[2].data, "respTo=", 6) == 0 ) {
455-
456-
// lcf->_is_call_to_var = 1;
457-
458-
// varname.data = value[2].data + sizeof("respTo=") - 1;
459-
// varname.len = value[2].len - (sizeof("respTo=") - 1);
460-
461-
// ngx_http_variable_t *var;
462-
// var = ngx_http_add_variable(cf, &varname, NGX_HTTP_VAR_CHANGEABLE | NGX_HTTP_VAR_NOCACHEABLE | NGX_HTTP_VAR_NOHASH);
463-
// if (var == NULL) {
464-
// return NGX_CONF_ERROR;
465-
// }
466-
// var->get_handler = ngx_http_c_func_get_resp_var;
467-
// var->data = 0;
468-
// }
469-
470499
if (scf && scf->_libname.len > 0) {
471500
ngx_http_c_func_loc_q_t *loc_q = ngx_pcalloc(cf->pool, sizeof(ngx_http_c_func_loc_q_t));
472501
loc_q->_loc_conf = lcf;
@@ -883,18 +912,19 @@ ngx_http_c_func_create_loc_conf(ngx_conf_t *cf) {
883912
if (conf == NULL) {
884913
return NGX_CONF_ERROR;
885914
}
886-
/***ngx_pcalloc has inited properly*/
887-
// conf->_method_name.len = NGX_CONF_UNSET_SIZE;
915+
916+
conf->ext_req_headers = NGX_CONF_UNSET_PTR;
888917
return conf;
889918
}
890919

891920

892921

893922
static char*
894923
ngx_http_c_func_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) {
895-
// ngx_http_c_func_loc_conf_t *prev = parent;
896-
// ngx_http_c_func_loc_conf_t *conf = child;
924+
ngx_http_c_func_loc_conf_t *prev = parent;
925+
ngx_http_c_func_loc_conf_t *conf = child;
897926

927+
ngx_conf_merge_ptr_value(conf->ext_req_headers, prev->ext_req_headers, NULL);
898928
// ngx_conf_merge_str_value(conf->_method_name, prev->_method_name, "");
899929

900930
// if (conf->_method_name.len == 0) {
@@ -1146,7 +1176,48 @@ ngx_http_c_func_precontent_handler(ngx_http_request_t *r) {
11461176

11471177
} /* ngx_http_c_func_precontent_handler */
11481178

1179+
static void
1180+
ngx_http_c_func_parse_ext_request_headers(ngx_http_request_t *r, ngx_array_t *ext_req_headers) {
1181+
ngx_uint_t i, nelts;
1182+
ngx_http_c_func_req_header_t *hdrs;
1183+
ngx_str_t hdr_val;
1184+
ngx_table_elt_t *h;
1185+
ngx_http_header_t *hh;
1186+
ngx_http_core_main_conf_t *cmcf;
1187+
1188+
hdrs = ext_req_headers->elts;
1189+
nelts = ext_req_headers->nelts;
1190+
cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
11491191

1192+
for (i = 0; i < nelts; i++) {
1193+
if (ngx_http_complex_value(r, &hdrs->value, &hdr_val) == NGX_OK) {
1194+
1195+
h = ngx_list_push(&r->headers_in.headers);
1196+
if (h == NULL) {
1197+
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "error when adding header %s", "insufficient memory allocate");
1198+
break;
1199+
}
1200+
1201+
h->key.len = hdrs->key.len;
1202+
h->key.data = hdrs->key.data;
1203+
h->hash = ngx_hash_key(h->key.data, h->key.len);
1204+
1205+
h->value.len = hdr_val.len;
1206+
h->value.data = hdr_val.data;
1207+
1208+
h->lowcase_key = h->key.data;
1209+
1210+
hh = ngx_hash_find(&cmcf->headers_in_hash, h->hash, h->lowcase_key, h->key.len);
1211+
1212+
if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
1213+
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "%s", "error when adding header");
1214+
}
1215+
} else {
1216+
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "%s", "error when adding header");
1217+
}
1218+
hdrs++;
1219+
}
1220+
}
11501221
/**
11511222
* Rewrite handler.
11521223
* Ref:: https://github.com/calio/form-input-nginx-module
@@ -1161,6 +1232,10 @@ ngx_http_c_func_rewrite_handler(ngx_http_request_t *r) {
11611232
ngx_http_c_func_internal_ctx_t *ctx;
11621233
ngx_int_t rc;
11631234

1235+
if (lcf->ext_req_headers) {
1236+
ngx_http_c_func_parse_ext_request_headers(r, lcf->ext_req_headers);
1237+
}
1238+
11641239
if (lcf->_handler == NULL) {
11651240
return NGX_DECLINED;
11661241
}

t/libcfuntest.so

320 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)