Skip to content
This repository was archived by the owner on Dec 18, 2018. It is now read-only.

Random 502 cgi gateway error when response 304 then flush response #952

Closed
Tratcher opened this issue Jul 5, 2016 · 4 comments
Closed

Comments

@Tratcher
Copy link
Member

Tratcher commented Jul 5, 2016

From @303248153 on July 2, 2016 22:58

First I found this problem with my project, sometime static files will return 502 with cgi gateway error.
Today I do a diggup, to reproduce this problem you needs:

  • Host asp.net core application on IIS, if you run with kestrel only, this problem won't happen.
  • Response 304, only 304 cause this problem.
  • Explict flush the response
  • Do the request parallel

I uploaded a minimal reproduce project, please check it.
It maybe a thread race condition problem because only parallel request will cause this problem.
WebApplication1.zip

I don't known if it's same with other 502.3 issues,
and I already using asp.net core 1.0.0 as you can see in the project.json.

Copied from original issue: aspnet/IISIntegration#219

@Tratcher
Copy link
Member Author

Tratcher commented Jul 5, 2016

This seems to be a Kestrel issue. Updated repro code:

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole();

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.Run(ThreadPoolVersion);
        }

        private async Task DefaultVersion(HttpContext context)
        {
            if (context.Request.Path == "/")
            {
                context.Response.ContentType = "text/html";
                var html = string.Join("",
                    Enumerable.Range(0, 100).Select(n => $"<img src='/{n}.jpg'></img>"));
                await context.Response.WriteAsync(html);
            }
            else if (context.Request.Path.Value.EndsWith(".jpg"))
            {
                context.Response.Headers.Add("Last-Modified", "Fri, 17 Jun 2016 06:56:44 GMT");
                context.Response.ContentType = "image/jpeg";
                context.Response.StatusCode = 304;
                await context.Response.Body.FlushAsync();
                // context.Response.Body.Flush();
            }
        }

I saw the same behaviors with both the DefaultVersion and ThreadPoolVersion repro methods. If I start the site with just Kestrel then the browser will make many parallel requests but only the first 8 will complete, the remainder time out. If I launch IIS Express then most of the requests complete, but 1/10 fail with a 502.

@muratg
Copy link
Contributor

muratg commented Jul 8, 2016

@CesarBS will investigate.

@benaadams
Copy link
Contributor

benaadams commented Jul 9, 2016

On sync flush, CreateResponseHeader gets called with appCompleted: false which writes Transfer-Encoding chunked, but no terminating chunk comes out so browser hangs waiting.

HTTP/1.1 304 Not Modified
Date: Sat, 09 Jul 2016 06:47:04 GMT
Transfer-Encoding: chunked
Content-Type: image/jpeg
Last-Modified: Fri, 17 Jun 2016 06:56:44 GMT
Server: Kestrel

Adding context.Response.ContentLength = 0; or taking out the Flush resolves it, so is something on the chunked path when no data is written.

However it does look like WriteChunkedResponseSuffix() gets called, so it may be sending 304 with a chunked encoding?

benaadams added a commit to benaadams/KestrelHttpServer that referenced this issue Jul 9, 2016
@benaadams
Copy link
Contributor

Fix in "Don't set TE header for non-body responses" #962

benaadams added a commit to benaadams/KestrelHttpServer that referenced this issue Jul 9, 2016
benaadams added a commit to benaadams/KestrelHttpServer that referenced this issue Jul 9, 2016
benaadams added a commit to benaadams/KestrelHttpServer that referenced this issue Jul 11, 2016
benaadams added a commit to benaadams/KestrelHttpServer that referenced this issue Jul 19, 2016
benaadams added a commit to benaadams/KestrelHttpServer that referenced this issue Jul 19, 2016
benaadams added a commit to benaadams/KestrelHttpServer that referenced this issue Jul 19, 2016
benaadams added a commit to benaadams/KestrelHttpServer that referenced this issue Jul 19, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants