@@ -130,9 +130,13 @@ static u_char* ngx_http_c_func_strdup_with_p(ngx_pool_t *pool, const char *src,
130130
131131// 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);
132132// static void ngx_http_c_func_set_resp_var_with_r(ngx_http_request_t *r, ngx_http_c_func_ctx_t *ctx, const char* resp_content, size_t resp_len);
133+ #if (nginx_version > 1013003 )
133134static void ngx_http_c_func_output_filter (ngx_http_request_t * r );
135+ #else
136+ static ngx_int_t ngx_http_c_func_output_filter (ngx_http_request_t * r );
137+ #endif
134138
135- #if (NGX_THREADS )
139+ #if (NGX_THREADS && nginx_version > 1013003 )
136140static void ngx_http_c_func_after_process (ngx_event_t * ev );
137141static void ngx_http_c_func_process_t_handler (void * data , ngx_log_t * log );
138142#endif
@@ -531,18 +535,20 @@ ngx_http_c_func_post_configuration(ngx_conf_t *cf) {
531535 /**Access Phase is the only last phase for multi thread, we need to mimic to trick nginx c function access phase at first to register,
532536 then it will be last to called as it is reverse order
533537 **/
534- h = ngx_array_push (& cmcf -> phases [NGX_HTTP_ACCESS_PHASE ].handlers );
535- if (h == NULL ) {
536- return NGX_ERROR ;
537- }
538-
539- h = cmcf -> phases [NGX_HTTP_ACCESS_PHASE ].handlers .elts ;
540- ngx_uint_t i ;
541- for (i = 0 ; i < cmcf -> phases [NGX_HTTP_ACCESS_PHASE ].handlers .nelts - 1 ; i ++ ) {
542- h [i + 1 ] = h [i ];
543- }
538+ h = ngx_array_push (& cmcf -> phases [NGX_HTTP_CONTENT_PHASE ].handlers );
539+ // if (h == NULL) {
540+ // return NGX_ERROR;
541+ // }
542+
543+ // h = cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers.elts;
544+ // ngx_uint_t i;
545+ // for (i = 0; i < cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers.nelts - 1; i++) {
546+ // h[i + 1] = h[i];
547+ // }
548+
549+ // h[0] = ngx_http_c_func_precontent_handler;
550+ * h = ngx_http_c_func_precontent_handler ;
544551
545- h [0 ] = ngx_http_c_func_precontent_handler ;
546552#endif
547553
548554 }
@@ -596,7 +602,7 @@ ngx_http_c_func_module_init(ngx_cycle_t *cycle) {
596602
597603 cscfp = cmcf -> servers .elts ;
598604
599- #if (NGX_THREADS )
605+ #if (NGX_THREADS && nginx_version > 1013003 )
600606 ngx_log_error (NGX_LOG_NOTICE , cycle -> log , 0 , " enabled aio threads for c-function module " );
601607#endif
602608
@@ -909,7 +915,7 @@ ngx_http_c_func_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) {
909915 return NGX_CONF_OK ;
910916}
911917
912- #if (NGX_THREADS )
918+ #if (NGX_THREADS && nginx_version > 1013003 )
913919static void
914920ngx_http_c_func_process_t_handler (void * data , ngx_log_t * log )
915921{
@@ -943,8 +949,18 @@ ngx_http_c_func_after_process(ngx_event_t *ev) {
943949 r -> main -> blocked -- ;
944950 r -> aio = 0 ;
945951
946- r -> write_event_handler (r );
947- ngx_http_run_posted_requests (c );
952+ if (r -> done ) {
953+ /*
954+ * trigger connection event handler if the subrequest was
955+ * already finalized; this can happen if the handler is used
956+ * for sendfile() in threads
957+ */
958+ c -> write -> handler (c -> write );
959+
960+ } else {
961+ r -> write_event_handler (r );
962+ ngx_http_run_posted_requests (c );
963+ }
948964}
949965#endif
950966
@@ -977,8 +993,12 @@ ngx_http_c_func_precontent_handler(ngx_http_request_t *r) {
977993 if (internal_ctx -> aio_processing ) {
978994 return NGX_AGAIN ;
979995 } else {
996+ #if (nginx_version > 1013003 )
980997 ngx_http_c_func_output_filter (r );
981998 return NGX_DONE ;
999+ #else
1000+ return ngx_http_c_func_output_filter (r );
1001+ #endif
9821002 }
9831003
9841004new_task :
@@ -1090,7 +1110,7 @@ ngx_http_c_func_precontent_handler(ngx_http_request_t *r) {
10901110 new_ctx -> req_body_len = 0 ;
10911111 }
10921112
1093- #if (NGX_THREADS )
1113+ #if (NGX_THREADS && nginx_version > 1013003 )
10941114 internal_ctx -> aio_processing = 1 ;
10951115 ngx_thread_pool_t * tp ;
10961116 ngx_http_core_loc_conf_t * clcf ;
@@ -1117,11 +1137,17 @@ ngx_http_c_func_precontent_handler(ngx_http_request_t *r) {
11171137 r -> aio = 1 ;
11181138 return NGX_DONE ;
11191139single_thread :
1140+ #else
1141+ ngx_log_error (NGX_LOG_WARN , r -> connection -> log , 0 , " nginx c function with nginx 1.13.3 and below is running single thread only, upgrade to nginx > 1.13.3 for concurrent request" );
11201142#endif
11211143 lcf -> _handler (new_ctx );
1144+ #if (nginx_version > 1013003 )
11221145 ngx_http_c_func_output_filter (r );
1123-
11241146 return NGX_DONE ;
1147+ #else
1148+ return ngx_http_c_func_output_filter (r );
1149+ #endif
1150+
11251151} /* ngx_http_c_func_precontent_handler */
11261152
11271153
@@ -1657,6 +1683,7 @@ ngx_http_c_func_write_resp(
16571683 );
16581684}
16591685
1686+ #if (nginx_version > 1013003 )
16601687static void
16611688ngx_http_c_func_output_filter (
16621689 ngx_http_request_t * r
@@ -1717,6 +1744,63 @@ ngx_http_c_func_output_filter(
17171744 ngx_http_finalize_request (r , ngx_http_output_filter (r , & out )); // only using when request client body
17181745 // rc = ngx_http_output_filter(r, &out);
17191746}
1747+ #else
1748+ static ngx_int_t
1749+ ngx_http_c_func_output_filter (
1750+ ngx_http_request_t * r
1751+ ) {
1752+ // ngx_int_t rc;
1753+ ngx_chain_t out ;
1754+ ngx_http_c_func_internal_ctx_t * internal_ctx ;
1755+ ngx_str_t * resp_content_type , * resp_status_line ;
1756+ ngx_buf_t * b ;
1757+
1758+ internal_ctx = ngx_http_get_module_ctx (r , ngx_http_c_func_module );
1759+
1760+ if (internal_ctx == NULL ) {
1761+ ngx_log_error (NGX_LOG_EMERG , r -> connection -> log , 0 , "Session is not valid" );
1762+ return NGX_HTTP_INTERNAL_SERVER_ERROR ;
1763+ }
1764+
1765+ if (internal_ctx -> rc == NGX_HTTP_INTERNAL_SERVER_ERROR ) {
1766+ ngx_log_error (NGX_LOG_EMERG , r -> connection -> log , 0 , "Apps Internal Server error" );
1767+ return NGX_HTTP_INTERNAL_SERVER_ERROR ;
1768+ }
1769+
1770+ resp_status_line = & internal_ctx -> status_line ;
1771+ resp_content_type = & internal_ctx -> content_type ;
1772+ b = internal_ctx -> resp_content ;
1773+
1774+ r -> headers_out .status = internal_ctx -> status_code ;
1775+
1776+ if (resp_status_line -> len ) {
1777+ r -> headers_out .status_line .len = resp_status_line -> len ;
1778+ r -> headers_out .status_line .data = resp_status_line -> data ;
1779+ }
1780+
1781+ /* Set the Content-Type header. */
1782+ r -> headers_out .content_type .len = resp_content_type -> len ;
1783+ r -> headers_out .content_type .data = resp_content_type -> data ;
1784+
1785+ /* Get the content length of the body. */
1786+ r -> headers_out .content_length_n = ngx_buf_size (b );
1787+
1788+ /* Send the headers */
1789+ if ( ngx_http_send_header (r ) == NGX_ERROR ) {
1790+ ngx_log_error (NGX_LOG_ERR , r -> connection -> log , 0 , "response processing failed." );
1791+ // ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1792+ return NGX_HTTP_INTERNAL_SERVER_ERROR ;
1793+ }
1794+
1795+ /* Insertion in the buffer chain. */
1796+ out .buf = b ;
1797+ out .next = NULL ; /* just one buffer */
1798+
1799+ /* Send the body, and return the status code of the output filter chain. */
1800+ // ngx_http_finalize_request(r, ngx_http_output_filter(r, &out)); // only using when request client body
1801+ return ngx_http_output_filter (r , & out );
1802+ }
1803+ #endif
17201804
17211805/****Download Feature Support ****/
17221806static int
0 commit comments