[BUG] Posted requests not handled after dns resolving

lanshun zhou zls.sogou at gmail.com
Wed Mar 13 22:44:48 UTC 2013


Because there is chance to call ngx_http_upstream_finalize_request in
function ngx_http_upstream_connect or it's sub calls, and i think this
makes no difference with failed resolution~
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

_______________________________________________
nginx-devel mailing list
nginx-devel at nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20130314/435f4fb4/attachment-0001.html>


More information about the nginx-devel mailing list