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); }
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); }
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); }
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); }
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); }
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; }
public TestHttpResponseBodyFeature(IHttpResponseBodyFeature innerResponseBodyFeature, TestHttpResponseFeature responseFeature) { _innerResponseBodyFeature = innerResponseBodyFeature ?? throw new ArgumentNullException(nameof(innerResponseBodyFeature)); _responseFeature = responseFeature ?? throw new ArgumentNullException(nameof(responseFeature)); }