[BUG] Posted requests not handled after dns resolving

Maxim Dounin mdounin at mdounin.ru
Wed Mar 13 16:29:37 UTC 2013


Hello!

On Wed, Mar 13, 2013 at 12:31:00AM +0800, lanshun zhou wrote:

> in ngx_http_upstream_resolve_handler, posted requests are not handled, so
> if a run time
> dns resolving is failed in a subrequest, (for example, the resolver can not
> be reached, or
> the domain does not exist) the main request will know nothing about this,
> until something
> else attached to this connection happens, like connection broken or a write
> timeout
> 
> a patch is attached and hope it helps
> 
> simple configuration that can reproduce the problem (with addition module
> enabled):
> 
>   addition_types *;
> 
>   resolver your_resolver_here;
> 
>   location /test {
>        set $ihost xxx;                        # xxx here causes a failed
> run-time dns resolving
>        proxy_pass http://$ihost;
>   }
> 
>   location /zzz {
>       add_after_body /test;
>       return 200 "test";
>   }
> 
>   curl -v http://localhost/zzz

Thank you for your report, see below for comments about the patch.


> diff -ruNp nginx-1.3.14/src/http/ngx_http_upstream.c nginx-1.3.14_zls/src/http/ngx_http_upstream.c
> --- nginx-1.3.14/src/http/ngx_http_upstream.c	2013-02-18 23:08:46.000000000 +0800
> +++ nginx-1.3.14_zls/src/http/ngx_http_upstream.c	2013-03-13 00:01:01.490582380 +0800
> @@ -878,11 +878,13 @@ ngx_http_upstream_cache_send(ngx_http_re
>  static void
>  ngx_http_upstream_resolve_handler(ngx_resolver_ctx_t *ctx)
>  {
> +    ngx_connection_t              *c;
>      ngx_http_request_t            *r;
>      ngx_http_upstream_t           *u;
>      ngx_http_upstream_resolved_t  *ur;
>  
>      r = ctx->data;
> +    c = r->connection;
>  
>      u = r->upstream;
>      ur = u->resolved;
> @@ -894,7 +896,8 @@ ngx_http_upstream_resolve_handler(ngx_re
>                        ngx_resolver_strerror(ctx->state));
>  
>          ngx_http_upstream_finalize_request(r, u, NGX_HTTP_BAD_GATEWAY);
> -        return;
> +
> +        goto posted_requests;
>      }
>  
>      ur->naddrs = ctx->naddrs;
> @@ -919,13 +922,17 @@ ngx_http_upstream_resolve_handler(ngx_re
>      if (ngx_http_upstream_create_round_robin_peer(r, ur) != NGX_OK) {
>          ngx_http_upstream_finalize_request(r, u,
>                                             NGX_HTTP_INTERNAL_SERVER_ERROR);
> -        return;
> +        goto posted_requests;
>      }
>  
>      ngx_resolve_name_done(ctx);
>      ur->ctx = NULL;
>  
>      ngx_http_upstream_connect(r, u);
> +
> +posted_requests:
> +
> +    ngx_http_run_posted_requests(c);
>  }

Any reason to run posted requests on successful resolution?  For 
me it looks like something like this should be enough:

--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -894,6 +894,7 @@ ngx_http_upstream_resolve_handler(ngx_re
                       ngx_resolver_strerror(ctx->state));
 
         ngx_http_upstream_finalize_request(r, u, NGX_HTTP_BAD_GATEWAY);
+        ngx_http_run_posted_requests(r->connection);
         return;
     }
 
@@ -919,6 +920,7 @@ ngx_http_upstream_resolve_handler(ngx_re
     if (ngx_http_upstream_create_round_robin_peer(r, ur) != NGX_OK) {
         ngx_http_upstream_finalize_request(r, u,
                                            NGX_HTTP_INTERNAL_SERVER_ERROR);
+        ngx_http_run_posted_requests(r->connection);
         return;
     }
 

-- 
Maxim Dounin
http://nginx.org/en/donation.html



More information about the nginx-devel mailing list