Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Buffering the entire request body in the pipe does not return the buffered data on the next read #8142

Closed
davidfowl opened this issue Mar 4, 2019 · 1 comment
Assignees
Labels
area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions bug This issue describes a behavior which is not expected - a bug. Done This issue has been fixed

Comments

@davidfowl
Copy link
Member

davidfowl commented Mar 4, 2019

Describe the bug

Buffering a content-length request body to the end doesn't return the buffered data after reading.

To Reproduce

using System;
using System.Buffers;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace WebApplication101
{
    public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.Use(async (context, next) =>
            {
                if (context.Request.ContentLength is null)
                {
                    await next();
                    return;
                }

                await context.Request.BufferAsync();

                await next();
            });

            app.UseRouting(routes =>
            {
                routes.MapGet("/", async context =>
                {
                    await context.Response.WriteAsync("Hello World!");
                });

                routes.MapPost("/api/values", async context =>
                {
                    var result = await context.Request.BodyPipe.ReadAsync();
                    var buffer = result.Buffer;

                    var value = Encoding.UTF8.GetString(buffer.ToArray());

                    await context.Response.WriteAsync(value);
                });
            });
        }
    }

    public static class RequestBufferingExtensions
    {
        public static async Task BufferAsync(this HttpRequest request)
        {
            // Buffer the entire request body into the pipe
            var cancellationToken = request.HttpContext.RequestAborted;

            while (true)
            {
                var result = await request.BodyPipe.ReadAsync(cancellationToken);
                var buffer = result.Buffer;
                request.BodyPipe.AdvanceTo(buffer.Start, buffer.End);

                if (result.IsCompleted)
                {
                    break;
                }
            }
        }
    }
}

Reading the request body hangs in the second middleware.

Expected behavior

The api/values end point should parse the buffered body

@davidfowl davidfowl added this to the 3.0.0-preview4 milestone Mar 4, 2019
@davidfowl davidfowl added area-servers bug This issue describes a behavior which is not expected - a bug. labels Mar 4, 2019
@jkotalik
Copy link
Contributor

jkotalik commented Mar 5, 2019

This will have a very similar fix to #8200

@jkotalik jkotalik added Done This issue has been fixed and removed 2 - Working labels Mar 19, 2019
@ghost ghost locked as resolved and limited conversation to collaborators Dec 3, 2019
@amcasey amcasey added area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions and removed area-runtime labels Aug 24, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions bug This issue describes a behavior which is not expected - a bug. Done This issue has been fixed
Projects
None yet
Development

No branches or pull requests

4 participants