Ejemplo n.º 1
0
        private async Task HandleGrpcWebRequest(HttpContext httpContext, ServerGrpcWebContext grcpWebContext)
        {
            var feature = new GrpcWebFeature(grcpWebContext, httpContext);

            var initialProtocol = httpContext.Request.Protocol;

            // Modifying the request is required to stop Grpc.AspNetCore.Server from rejecting it
            httpContext.Request.Protocol    = GrpcWebProtocolConstants.Http2Protocol;
            httpContext.Request.ContentType = ResolveContentType(GrpcWebProtocolConstants.GrpcContentType, httpContext.Request.ContentType !);

            // Update response content type back to gRPC-Web
            httpContext.Response.OnStarting(() =>
            {
                // Reset request protocol back to its original value. Not doing this causes a 2 second
                // delay when making HTTP/1.1 calls.
                httpContext.Request.Protocol = initialProtocol;

                if (CommonGrpcProtocolHelpers.IsContentType(GrpcWebProtocolConstants.GrpcContentType, httpContext.Response.ContentType !))
                {
                    var contentType = grcpWebContext.Response == ServerGrpcWebMode.GrpcWeb
                        ? GrpcWebProtocolConstants.GrpcWebContentType
                        : GrpcWebProtocolConstants.GrpcWebTextContentType;
                    var responseContentType = ResolveContentType(contentType, httpContext.Response.ContentType);

                    httpContext.Response.ContentType = responseContentType;
                    Log.SendingGrpcWebResponse(_logger, responseContentType);
                }

                return(Task.CompletedTask);
            });

            try
            {
                await _next(httpContext);

                // If trailers have already been written in CompleteAsync then this will no-op
                await feature.WriteTrailersAsync();
            }
            finally
            {
                feature.DetachFromContext(httpContext);
            }
        }
Ejemplo n.º 2
0
        public GrpcWebFeature(ServerGrpcWebContext grcpWebContext, HttpContext httpContext)
        {
            // Capture existing features. We'll use these internally, and restore them onto the context
            // once the middleware has finished executing.

            // Note that some of these will be missing depending on the host and protocol.
            // e.g.
            // - IHttpResponseTrailersFeature and IHttpResetFeature will be missing when HTTP/1.1.
            // - IRequestBodyPipeFeature will be missing when in IIS.
            _initialRequestFeature  = httpContext.Features.Get <IRequestBodyPipeFeature>();
            _initialResponseFeature = GetRequiredFeature <IHttpResponseBodyFeature>(httpContext);
            _initialResetFeature    = httpContext.Features.Get <IHttpResetFeature>();
            _initialTrailersFeature = httpContext.Features.Get <IHttpResponseTrailersFeature>();

            var innerReader = _initialRequestFeature?.Reader ?? httpContext.Request.BodyReader;
            var innerWriter = _initialResponseFeature.Writer ?? httpContext.Response.BodyWriter;

            Trailers = new HeaderDictionary();
            if (grcpWebContext.Request == ServerGrpcWebMode.GrpcWebText)
            {
                Reader = new Base64PipeReader(innerReader);
            }
            else
            {
                Reader = innerReader;
            }
            if (grcpWebContext.Response == ServerGrpcWebMode.GrpcWebText)
            {
                Writer = new Base64PipeWriter(innerWriter);
            }
            else
            {
                Writer = innerWriter;
            }

            httpContext.Features.Set <IRequestBodyPipeFeature>(this);
            httpContext.Features.Set <IHttpResponseBodyFeature>(this);
            httpContext.Features.Set <IHttpResponseTrailersFeature>(this);
            httpContext.Features.Set <IHttpResetFeature>(this);
        }