@@ -82,19 +82,23 @@ typedef struct {
8282typedef struct {
8383 ngx_str_t _method_name ;
8484 ngx_http_c_func_app_handler _handler ;
85+ ngx_flag_t _is_call_to_var ;
8586} ngx_http_c_func_loc_conf_t ;
8687
8788typedef struct {
8889 unsigned done : 1 ;
8990 unsigned waiting_more_body : 1 ;
91+
92+ /*** For store Response ***/
93+ size_t resp_len ;
94+ u_char * resp ;
9095} ngx_http_c_func_internal_ctx_t ;
9196
9297typedef struct {
9398 ngx_queue_t _queue ;
9499 ngx_http_c_func_loc_conf_t * _loc_conf ;
95100} ngx_http_c_func_loc_q_t ;
96101
97-
98102static ngx_int_t ngx_http_c_func_pre_configuration (ngx_conf_t * cf );
99103static ngx_int_t ngx_http_c_func_post_configuration (ngx_conf_t * cf );
100104static char * ngx_http_c_func_validation_check_and_set_str_slot (ngx_conf_t * cf , ngx_command_t * cmd , void * conf );
@@ -117,6 +121,8 @@ static void ngx_http_c_func_client_body_handler(ngx_http_request_t *r);
117121static ngx_int_t ngx_http_c_func_proceed_init_calls (ngx_cycle_t * cycle , ngx_http_c_func_srv_conf_t * scf , ngx_http_c_func_main_conf_t * mcf );
118122static u_char * ngx_http_c_func_strdup (ngx_pool_t * pool , const char * src , size_t len );
119123
124+ static ngx_int_t ngx_http_c_func_get_resp_var (ngx_http_request_t * r , ngx_http_variable_value_t * v , uintptr_t data );
125+
120126/*** Download Feature Support ***/
121127typedef struct {
122128 char * header_content ;
@@ -160,6 +166,12 @@ void* ngx_http_c_func_cache_put(void *shared_mem, const char* key, void* value);
160166void * ngx_http_c_func_cache_new (void * shared_mem , const char * key , size_t size );
161167void * ngx_http_c_func_cache_remove (void * shared_mem , const char * key );
162168
169+ void
170+ ngx_http_c_func_set_resp_var (
171+ ngx_http_c_func_ctx_t * ctx ,
172+ const char * resp_content
173+ );
174+
163175void ngx_http_c_func_write_resp (
164176 ngx_http_c_func_ctx_t * ctx ,
165177 uintptr_t status_code ,
@@ -172,6 +184,7 @@ void ngx_http_c_func_write_resp(
172184// ngx_http_c_func_srv_post_conf_handler
173185// };
174186
187+
175188/**
176189 * This module provided directive.
177190 */
@@ -209,8 +222,7 @@ static ngx_command_t ngx_http_c_func_commands[] = {
209222 NULL
210223 },
211224 { ngx_string ("ngx_http_c_func_call" ), /* directive */
212- NGX_HTTP_LOC_CONF | NGX_CONF_TAKE1 , /* location context and takes
213- no arguments*/
225+ NGX_HTTP_LOC_CONF | NGX_CONF_TAKE12 , /* location context and takes 1 or 2 arguments*/
214226 ngx_http_c_func_init_method , /* configuration setup function */
215227 NGX_HTTP_LOC_CONF_OFFSET , /* No offset. Only one context is supported. */
216228 offsetof(ngx_http_c_func_loc_conf_t , _method_name ), /* No offset when storing the module configuration on struct. */
@@ -259,7 +271,8 @@ ngx_http_c_func_shm_cache_init(ngx_shm_zone_t *shm_zone, void *data)
259271 ngx_slab_pool_t * shpool ;
260272
261273 if (oshm ) {
262- shm_zone -> data = oshm ;
274+ nshm -> name = oshm -> name ;
275+ nshm -> shared_mem = oshm -> shared_mem ;
263276 return NGX_OK ;
264277 }
265278
@@ -418,18 +431,43 @@ ngx_http_c_func_validation_check_and_set_str_slot(ngx_conf_t *cf, ngx_command_t
418431 */
419432static char *
420433ngx_http_c_func_init_method (ngx_conf_t * cf , ngx_command_t * cmd , void * conf ) {
421- // ngx_str_t *value;
434+ ngx_str_t * value ;
422435 ngx_http_core_loc_conf_t * clcf ; /* pointer to core location configuration */
423436 ngx_http_c_func_srv_conf_t * scf ;
424437 ngx_http_c_func_loc_conf_t * lcf = conf ;
438+ ngx_str_t varname ;
425439
426- // value = cf->args->elts;
427440
428441 clcf = ngx_http_conf_get_module_loc_conf (cf , ngx_http_core_module );
429442 scf = ngx_http_conf_get_module_srv_conf (cf , ngx_http_c_func_module );
430443
444+ value = cf -> args -> elts ;
445+
446+ if (cf -> args -> nelts == 3 &&
447+ value [2 ].len > sizeof ("respTo=" ) - 1 &&
448+ ngx_strncmp (value [2 ].data , "respTo=" , 6 ) == 0 ) {
449+
450+ lcf -> _is_call_to_var = 1 ;
451+
452+ varname .data = value [2 ].data + sizeof ("respTo=" ) - 1 ;
453+ varname .len = value [2 ].len - (sizeof ("respTo=" ) - 1 );
454+
455+ ngx_http_variable_t * var ;
456+ var = ngx_http_add_variable (cf , & varname , NGX_HTTP_VAR_CHANGEABLE | NGX_HTTP_VAR_NOCACHEABLE | NGX_HTTP_VAR_NOHASH );
457+ if (var == NULL ) {
458+ return NGX_CONF_ERROR ;
459+ }
460+ var -> get_handler = ngx_http_c_func_get_resp_var ;
461+ var -> data = 0 ;
462+ }
463+
464+
465+
431466 /***This handler is under NGX_HTTP_CONTENT_PHASE which is the phase ready to generate response ****/
432- clcf -> handler = ngx_http_c_func_content_handler ;
467+ if (!lcf -> _is_call_to_var ) {
468+ clcf -> handler = ngx_http_c_func_content_handler ;
469+ }
470+
433471 if (scf && scf -> _libname .len > 0 ) {
434472 ngx_http_c_func_loc_q_t * loc_q = ngx_pcalloc (cf -> pool , sizeof (ngx_http_c_func_loc_q_t ));
435473 loc_q -> _loc_conf = lcf ;
@@ -439,6 +477,7 @@ ngx_http_c_func_init_method(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) {
439477 return ngx_conf_set_str_slot (cf , cmd , conf );
440478} /* ngx_http_c_func_init_method */
441479
480+
442481static ngx_int_t
443482ngx_http_c_func_proceed_init_calls (ngx_cycle_t * cycle , ngx_http_c_func_srv_conf_t * scf , ngx_http_c_func_main_conf_t * mcf ) {
444483 /**** Init the client apps ngx_http_c_func_init ***/
@@ -503,7 +542,7 @@ ngx_http_c_func_post_configuration(ngx_conf_t *cf) {
503542static ngx_int_t
504543ngx_http_c_func_pre_configuration (ngx_conf_t * cf ) {
505544
506- #ifndef ngx_http_c_func_module_version_7
545+ #ifndef ngx_http_c_func_module_version_8
507546 ngx_conf_log_error (NGX_LOG_EMERG , cf , 0 , "%s" , "the latest ngx_http_c_func_module.h not found in the c header path, \
508547 please copy latest ngx_http_c_func_module.h to your /usr/include or /usr/local/include or relavent header search path \
509548 with read and write permission." );
@@ -701,6 +740,7 @@ ngx_http_c_func_master_exit(ngx_cycle_t *cycle) {
701740 return ;
702741 }
703742
743+
704744 // if (cfunmcf->shm_ctx && cfunmcf->shm_ctx->shared_mem) {
705745 // if (cfunmcf->shm_ctx->shared_mem->shpool && cfunmcf->shm_ctx->shared_mem->shpool->log_ctx) {
706746 // ngx_slab_free(cfunmcf->shm_ctx->shared_mem->shpool, cfunmcf->shm_ctx->shared_mem->shpool->log_ctx);
@@ -800,6 +840,7 @@ ngx_http_c_func_create_loc_conf(ngx_conf_t *cf) {
800840 if (conf == NULL ) {
801841 return NGX_CONF_ERROR ;
802842 }
843+ conf -> _is_call_to_var = 0 ;
803844 /***ngx_pcalloc has inited properly*/
804845 // conf->_method_name.len = NGX_CONF_UNSET_SIZE;
805846 return conf ;
@@ -965,6 +1006,7 @@ ngx_http_c_func_content_handler(ngx_http_request_t *r) {
9651006 */
9661007static ngx_int_t
9671008ngx_http_c_func_rewrite_handler (ngx_http_request_t * r ) {
1009+ ngx_http_c_func_loc_conf_t * lcf = ngx_http_get_module_loc_conf (r , ngx_http_c_func_module );
9681010 ngx_http_c_func_internal_ctx_t * ctx ;
9691011 ngx_int_t rc ;
9701012
@@ -977,6 +1019,9 @@ ngx_http_c_func_rewrite_handler(ngx_http_request_t *r) {
9771019 if (ctx != NULL ) {
9781020 if (ctx -> done ) {
9791021 /***Done Reading***/
1022+ if (lcf -> _is_call_to_var ) {
1023+ return ngx_http_c_func_content_handler (r );
1024+ }
9801025 return NGX_DECLINED ;
9811026 }
9821027 return NGX_DONE ;
@@ -990,6 +1035,8 @@ ngx_http_c_func_rewrite_handler(ngx_http_request_t *r) {
9901035 return NGX_HTTP_INTERNAL_SERVER_ERROR ;
9911036 }
9921037
1038+ ctx -> resp = NULL ;
1039+
9931040 ngx_http_set_ctx (r , ctx , ngx_http_c_func_module );
9941041
9951042 /****Reading Body Request ****/
@@ -1007,8 +1054,26 @@ ngx_http_c_func_rewrite_handler(ngx_http_request_t *r) {
10071054 ctx -> waiting_more_body = 1 ;
10081055 return NGX_DONE ;
10091056 }
1057+
1058+ if (lcf -> _is_call_to_var ) {
1059+ return ngx_http_c_func_content_handler (r );
1060+ }
10101061 return NGX_DECLINED ;
10111062 } else { //if (!(r->method & (NGX_HTTP_POST | NGX_HTTP_PUT | NGX_HTTP_PATCH))) {
1063+ ctx = ngx_http_get_module_ctx (r , ngx_http_c_func_module );
1064+ if (ctx == NULL ) {
1065+ /* calloc, has init with 0 value*/
1066+ ctx = ngx_pcalloc (r -> pool , sizeof (ngx_http_c_func_internal_ctx_t ));
1067+ if (ctx == NULL ) {
1068+ ngx_log_error (NGX_LOG_ERR , r -> connection -> log , 0 , "Insufficient Memory to create ngx_http_c_func_internal_ctx_t" );
1069+ return NGX_HTTP_INTERNAL_SERVER_ERROR ;
1070+ }
1071+ ctx -> resp = NULL ;
1072+ ngx_http_set_ctx (r , ctx , ngx_http_c_func_module );
1073+ }
1074+ if (lcf -> _is_call_to_var ) {
1075+ return ngx_http_c_func_content_handler (r );
1076+ }
10121077 return NGX_DECLINED ;
10131078 }
10141079}
@@ -1259,6 +1324,50 @@ ngx_http_c_func_cache_remove(void *shared_mem, const char* key) {
12591324 return NULL ;
12601325}
12611326
1327+ /***This handler when nginx.conf call $ngx_c_func_resp*/
1328+ static ngx_int_t
1329+ ngx_http_c_func_get_resp_var (ngx_http_request_t * r ,
1330+ ngx_http_variable_value_t * v , uintptr_t data )
1331+ {
1332+ ngx_http_c_func_internal_ctx_t * internal_ctx ;
1333+
1334+ internal_ctx = ngx_http_get_module_ctx (r , ngx_http_c_func_module );
1335+
1336+ if (internal_ctx == NULL ) {
1337+ v -> not_found = 1 ;
1338+ return NGX_OK ;
1339+ }
1340+
1341+ v -> len = internal_ctx -> resp_len ;
1342+ v -> valid = 1 ;
1343+ v -> no_cacheable = 0 ;
1344+ v -> not_found = 0 ;
1345+ v -> data = internal_ctx -> resp ;
1346+
1347+ return NGX_OK ;
1348+ }
1349+
1350+ void
1351+ ngx_http_c_func_set_resp_var (
1352+ ngx_http_c_func_ctx_t * ctx ,
1353+ const char * resp_content
1354+ ) {
1355+ ngx_http_c_func_internal_ctx_t * internal_ctx ;
1356+ ngx_http_request_t * r = (ngx_http_request_t * )ctx -> __r__ ;
1357+ internal_ctx = ngx_http_get_module_ctx (r , ngx_http_c_func_module );
1358+
1359+ if (internal_ctx != NULL ) {
1360+ internal_ctx -> resp_len = ngx_strlen (resp_content );
1361+ internal_ctx -> resp = (u_char * )resp_content ;
1362+
1363+ /** Decline means continue to next handler for this phase **/
1364+ ctx -> __rc__ = NGX_DECLINED ;
1365+ } else {
1366+ ngx_log_error (NGX_LOG_ERR , r -> connection -> log , 0 , "Error while storing resp to variable." );
1367+ ctx -> __rc__ = NGX_HTTP_INTERNAL_SERVER_ERROR ;
1368+ }
1369+ }
1370+
12621371void
12631372ngx_http_c_func_write_resp (
12641373 ngx_http_c_func_ctx_t * ctx ,
@@ -1271,6 +1380,15 @@ ngx_http_c_func_write_resp(
12711380 ngx_chain_t out ;
12721381 size_t resp_content_len ;
12731382 ngx_http_request_t * r = (ngx_http_request_t * )ctx -> __r__ ;
1383+
1384+ if ( ((ngx_http_c_func_loc_conf_t * ) ngx_http_get_module_loc_conf (r , ngx_http_c_func_module ) )-> _is_call_to_var ) {
1385+ ngx_log_error (NGX_LOG_WARN ,
1386+ r -> connection -> log ,
1387+ 0 ,
1388+ ", \n Recommended to call ngx_http_c_func_set_resp_var. \n ngx_http_c_func_write_resp only applicable when no variable stored" );
1389+ return ngx_http_c_func_set_resp_var (ctx , resp_content );
1390+ }
1391+
12741392 /* Set the Content-Type header. */
12751393 if (content_type ) {
12761394 r -> headers_out .content_type .len = ngx_strlen (content_type );
0 commit comments