4646*/
4747#if (nginx_version > 1013003 )
4848
49- #define NGX_SUBREQ_SEQUENTIAL 0
50- #define NGX_SUBREQ_PARALLEL 1
49+ #define NGX_SUBREQ_SEQUENTIAL 0
50+ #define NGX_SUBREQ_PARALLEL 1
51+ #define NGX_SUBREQ_SEQUENTIAL_CHK 2
5152
5253static ngx_conf_enum_t ngx_http_link_func_subrequest_flags [] = {
5354 { ngx_string ("sequential" ), NGX_SUBREQ_SEQUENTIAL }, // subrequest run synchronizely but waiting for response
55+ { ngx_string ("sequential_check" ), NGX_SUBREQ_SEQUENTIAL_CHK }, // subrequest run synchronizely but waiting for response and check status
5456 { ngx_string ("parallel" ), NGX_SUBREQ_PARALLEL }, // subrequest run parallely but waiting for response
5557 { ngx_null_string , 0 }
5658};
@@ -129,6 +131,7 @@ typedef struct {
129131 ngx_uint_t subreq_curr_index ;
130132 ngx_uint_t subreq_parallel_wait_cnt ;
131133 ngx_uint_t subreq_sequential_wait_cnt ;
134+ ngx_flag_t status_check ;
132135#endif
133136} ngx_http_link_func_internal_ctx_t ;
134137
@@ -545,12 +548,17 @@ ngx_http_link_func_subrequest_cmd(ngx_conf_t *cf, ngx_command_t *cmd, void *conf
545548 if (e [j ].name .len == values [i ].len
546549 && ngx_strcasecmp (e [j ].name .data , values [i ].data ) == 0 ) {
547550 subreq -> flag = e [j ].value ;
551+ #if (nginx_version < 1013010 )
552+ if (subreq -> flag == NGX_SUBREQ_PARALLEL ) {
553+ return "parallel request is not applicable to nginx version less than 1.13.10." ;
554+ }
555+ #endif
548556 break ;
549557 }
550558 }
551559
552560 if (e [j ].name .len == 0 ) {
553- return "invalid subrequest flag given, either parallel or sequential ." ;
561+ return "invalid subrequest flag given, either parallel, sequential or sequential_check ." ;
554562 }
555563 } else if (i == 3 ) {
556564 if ( (sizeof ("on" ) - 1 ) == values [i ].len && ngx_strcasecmp ((u_char * )"on" , values [i ].data ) == 0 ) {
@@ -1075,7 +1083,7 @@ static ngx_int_t
10751083ngx_http_link_func_subreqest_parallel_done (ngx_http_request_t * r , void * data , ngx_int_t rc ) {
10761084 ngx_http_link_func_internal_ctx_t * ctx = data ;
10771085 ngx_uint_t status = r -> headers_out .status ;
1078-
1086+
10791087 ngx_log_debug1 (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 ,
10801088 "subrequest parallel done:%ui" , status );
10811089 if (status ) {
@@ -1091,6 +1099,12 @@ ngx_http_link_func_subreqest_sequential_done(ngx_http_request_t *r, void *data,
10911099 ngx_log_debug1 (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 ,
10921100 "subrequest sequential done:%ui" , status );
10931101 if (status ) {
1102+ if ( ctx -> status_check ) {
1103+ if ( (status < 200 || status >= 300 ) && ctx -> status_code == 0 ) {
1104+ ctx -> status_code = status ;
1105+ }
1106+ ctx -> status_check = 0 ;
1107+ }
10941108 ctx -> subreq_sequential_wait_cnt -- ;
10951109 }
10961110 return rc ;
@@ -1102,6 +1116,7 @@ ngx_http_link_func_process_subrequest(ngx_http_request_t *r, ngx_http_link_func_
11021116 ngx_http_post_subrequest_t * ps ;
11031117 ngx_str_t * args ;
11041118 // ngx_uint_t subreq_flag;
1119+ ngx_int_t rc ;
11051120
11061121 if (subreq -> uri .len == 0 ) {
11071122 return NGX_ERROR ;
@@ -1122,13 +1137,25 @@ ngx_http_link_func_process_subrequest(ngx_http_request_t *r, ngx_http_link_func_
11221137 switch (subreq -> flag ) {
11231138 case NGX_SUBREQ_PARALLEL :
11241139 ps -> handler = ngx_http_link_func_subreqest_parallel_done ;
1140+ ctx -> subreq_parallel_wait_cnt ++ ;
1141+ rc = NGX_AGAIN ;
11251142 break ;
1143+ case NGX_SUBREQ_SEQUENTIAL_CHK :
1144+ ps -> handler = ngx_http_link_func_subreqest_sequential_done ;
1145+ ctx -> subreq_sequential_wait_cnt ++ ;
1146+ ctx -> status_check = 1 ;
1147+ rc = NGX_DONE ;
1148+ break ;
1149+ case NGX_SUBREQ_SEQUENTIAL :
11261150 default :
11271151 ps -> handler = ngx_http_link_func_subreqest_sequential_done ;
1152+ ctx -> subreq_sequential_wait_cnt ++ ;
1153+ rc = NGX_DONE ;
11281154 // ps = NULL;
11291155 break ;
11301156 }
11311157
1158+ ctx -> subreq_curr_index ++ ;
11321159
11331160 if (ngx_http_subrequest (r , & subreq -> uri , args , & sr , ps , NGX_HTTP_SUBREQUEST_IN_MEMORY ) == NGX_ERROR ) {
11341161 return NGX_ERROR ;
@@ -1154,7 +1181,7 @@ ngx_http_link_func_process_subrequest(ngx_http_request_t *r, ngx_http_link_func_
11541181 sr -> method = r -> method ;
11551182 sr -> method_name = r -> method_name ;
11561183 // ctx->subrequest = sr;
1157- return NGX_OK ;
1184+ return rc ;
11581185}
11591186#endif
11601187
@@ -1174,6 +1201,7 @@ ngx_http_link_func_precontent_handler(ngx_http_request_t *r) {
11741201 ngx_link_func_ctx_t * new_ctx ;
11751202
11761203#if (nginx_version > 1013003 )
1204+ ngx_int_t rc ;
11771205 ngx_uint_t i , n_sub_reqs ;
11781206 ngx_http_link_func_subreq_conf_t * subreqs , * subreq ;
11791207
@@ -1200,26 +1228,28 @@ ngx_http_link_func_precontent_handler(ngx_http_request_t *r) {
12001228 return NGX_DONE ;
12011229 }
12021230
1231+ if ( internal_ctx -> status_code && internal_ctx -> rc == NGX_CONF_UNSET ) {
1232+ if ( !internal_ctx -> subreq_parallel_wait_cnt ) {
1233+ ngx_http_finalize_request (r , internal_ctx -> status_code );
1234+ }
1235+ return NGX_DONE ;
1236+ }
1237+
1238+
12031239 n_sub_reqs = lcf -> subrequests -> nelts ;
12041240 subreqs = lcf -> subrequests -> elts ;
12051241
12061242 for (i = internal_ctx -> subreq_curr_index ; i < n_sub_reqs ; i ++ ) {
12071243 subreq = subreqs + i ;
1208- if (ngx_http_link_func_process_subrequest (r , subreq , internal_ctx ) != NGX_OK ) {
1244+ if ( ( rc = ngx_http_link_func_process_subrequest (r , subreq , internal_ctx )) == NGX_ERROR ) {
12091245 return NGX_ERROR ;
12101246 }
12111247
1212- switch (subreq -> flag ) {
1213- case NGX_SUBREQ_PARALLEL :
1214- internal_ctx -> subreq_curr_index = i + 1 ;
1215- internal_ctx -> subreq_parallel_wait_cnt ++ ;
1248+ if (rc == NGX_AGAIN ) {
12161249 continue ;
1217- case NGX_SUBREQ_SEQUENTIAL :
1218- default :
1219- internal_ctx -> subreq_curr_index = i + 1 ;
1220- internal_ctx -> subreq_sequential_wait_cnt ++ ;
1221- return NGX_DONE ;
12221250 }
1251+
1252+ return rc ; /*NGX_DONE*/
12231253 }
12241254
12251255 if (internal_ctx -> subreq_parallel_wait_cnt ) {
@@ -2294,7 +2324,6 @@ ngx_http_link_func_connect_and_request_via_ssl(int *sockfd, ngx_http_link_func_s
22942324DONE :
22952325 ngx_pfree (cycle -> pool , url_str );
22962326 return rc ;
2297-
22982327}
22992328
23002329static ngx_http_link_func_http_header_body *
0 commit comments