public async Task Invoke_GrpcWebContentTypeAndMetadata_Processed()
        {
            // Arrange
            var middleware  = CreateMiddleware(options: new GrpcWebOptions());
            var httpContext = new DefaultHttpContext();

            httpContext.Request.Protocol    = "HTTP/1.1";
            httpContext.Request.Method      = HttpMethods.Post;
            httpContext.Request.ContentType = GrpcWebProtocolConstants.GrpcWebContentType;
            httpContext.SetEndpoint(new Endpoint(c => Task.CompletedTask, new EndpointMetadataCollection(new EnableGrpcWebAttribute()), string.Empty));

            var testHttpResponseFeature = new TestHttpResponseFeature();

            httpContext.Features.Set <IHttpResponseFeature>(testHttpResponseFeature);

            // Act 1
            await middleware.Invoke(httpContext);

            // Assert 1
            Assert.AreEqual(GrpcWebProtocolConstants.GrpcContentType, httpContext.Request.ContentType);
            Assert.AreEqual(GrpcWebProtocolConstants.Http2Protocol, httpContext.Request.Protocol);
            Assert.AreEqual(1, testHttpResponseFeature.StartingCallbackCount);

            // Act 2
            httpContext.Response.ContentType = GrpcWebProtocolConstants.GrpcContentType;

            var c = testHttpResponseFeature.StartingCallbacks[0];
            await c.callback(c.state);

            // Assert 2
            Assert.AreEqual("HTTP/1.1", httpContext.Request.Protocol);
            Assert.AreEqual(GrpcWebProtocolConstants.GrpcWebContentType, httpContext.Response.ContentType);
        }
예제 #2
0
        public async Task UseGrpcWeb_RegisteredMultipleTimesCalledWithMatchingHttpContext_MiddlewareRuns()
        {
            // Arrange
            var services = new ServiceCollection();

            services.AddLogging();
            var app = new ApplicationBuilder(services.BuildServiceProvider());

            app.UseGrpcWeb(new GrpcWebOptions {
                DefaultEnabled = true
            });
            app.UseGrpcWeb(new GrpcWebOptions {
                DefaultEnabled = true
            });

            var appFunc = app.Build();

            var httpContext = new DefaultHttpContext();

            httpContext.Request.Method      = HttpMethods.Post;
            httpContext.Request.ContentType = GrpcWebProtocolConstants.GrpcWebContentType;

            var testHttpResponseFeature = new TestHttpResponseFeature();

            httpContext.Features.Set <IHttpResponseFeature>(testHttpResponseFeature);

            // Act
            await appFunc(httpContext);

            // Assert
            Assert.AreEqual(GrpcWebProtocolConstants.GrpcContentType, httpContext.Request.ContentType);
            Assert.AreEqual(1, testHttpResponseFeature.StartingCallbackCount);
        }
예제 #3
0
        public async Task RequestServicesAreDisposedAsynOnCompleted()
        {
            var serviceProvider = new AsyncDisposableServiceProvider(new ServiceCollection()
                                                                     .AddTransient <DisposableThing>()
                                                                     .BuildServiceProvider());

            var             scopeFactory = serviceProvider.GetRequiredService <IServiceScopeFactory>();
            DisposableThing instance     = null;

            var context = new DefaultHttpContext();

            context.ServiceScopeFactory = scopeFactory;
            var responseFeature = new TestHttpResponseFeature();

            context.Features.Set <IHttpResponseFeature>(responseFeature);

            Assert.NotNull(context.RequestServices);
            Assert.Single(responseFeature.CompletedCallbacks);

            instance = context.RequestServices.GetRequiredService <DisposableThing>();

            var callback = responseFeature.CompletedCallbacks[0];
            await callback.callback(callback.state);

            Assert.Null(context.RequestServices);
            Assert.True(instance.Disposed);
            var scope = Assert.Single(serviceProvider.Scopes);

            Assert.True(scope.DisposeAsyncCalled);
            Assert.False(scope.DisposeCalled);
        }
예제 #4
0
        public static HttpContext CreateContext(
            bool isMaxRequestBodySizeFeatureReadOnly = false,
            bool skipTrailerFeatureSet       = false,
            string?protocol                  = null,
            string?contentType               = null,
            IServiceProvider?serviceProvider = null,
            Func <Task>?completeAsyncAction  = null)
        {
            var httpContext         = new DefaultHttpContext();
            var responseFeature     = new TestHttpResponseFeature();
            var responseBodyFeature = new TestHttpResponseBodyFeature(httpContext.Features.Get <IHttpResponseBodyFeature>(), responseFeature, completeAsyncAction);

            httpContext.RequestServices     = serviceProvider !;
            httpContext.Request.Protocol    = protocol ?? GrpcProtocolConstants.Http2Protocol;
            httpContext.Request.ContentType = contentType ?? GrpcProtocolConstants.GrpcContentType;
            httpContext.Features.Set <IHttpMinRequestBodyDataRateFeature>(new TestMinRequestBodyDataRateFeature());
            httpContext.Features.Set <IHttpMaxRequestBodySizeFeature>(new TestMaxRequestBodySizeFeature(isMaxRequestBodySizeFeatureReadOnly, 100));
            httpContext.Features.Set <IHttpResponseFeature>(responseFeature);
            httpContext.Features.Set <IHttpResponseBodyFeature>(responseBodyFeature);
            if (!skipTrailerFeatureSet)
            {
                httpContext.Features.Set <IHttpResponseTrailersFeature>(new TestHttpResponseTrailersFeature());
            }

            return(httpContext);
        }
예제 #5
0
        public async Task RequestServicesAreDisposedOnCompleted()
        {
            var serviceProvider = new ServiceCollection()
                                  .AddTransient <DisposableThing>()
                                  .BuildServiceProvider();

            var             scopeFactory = serviceProvider.GetRequiredService <IServiceScopeFactory>();
            DisposableThing instance     = null;

            var middleware = new RequestServicesContainerMiddleware(
                ctx =>
            {
                instance = ctx.RequestServices.GetRequiredService <DisposableThing>();
                return(Task.CompletedTask);
            },
                scopeFactory);

            var context         = new DefaultHttpContext();
            var responseFeature = new TestHttpResponseFeature();

            context.Features.Set <IHttpResponseFeature>(responseFeature);

            await middleware.Invoke(context);

            Assert.NotNull(context.RequestServices);
            Assert.Single(responseFeature.CompletedCallbacks);

            var callback = responseFeature.CompletedCallbacks[0];
            await callback.callback(callback.state);

            Assert.Null(context.RequestServices);
            Assert.True(instance.Disposed);
        }
예제 #6
0
 public TestHttpResponseBodyFeature(IHttpResponseBodyFeature innerResponseBodyFeature, TestHttpResponseFeature responseFeature, Func <Task>?completeAsyncAction = null)
 {
     _innerResponseBodyFeature = innerResponseBodyFeature ?? throw new ArgumentNullException(nameof(innerResponseBodyFeature));
     _responseFeature          = responseFeature ?? throw new ArgumentNullException(nameof(responseFeature));
     _completeAsyncAction      = completeAsyncAction;
 }
예제 #7
0
 public TestHttpResponseBodyFeature(IHttpResponseBodyFeature innerResponseBodyFeature, TestHttpResponseFeature responseFeature)
 {
     _innerResponseBodyFeature = innerResponseBodyFeature ?? throw new ArgumentNullException(nameof(innerResponseBodyFeature));
     _responseFeature          = responseFeature ?? throw new ArgumentNullException(nameof(responseFeature));
 }