예제 #1
0
        private void FastReset()
        {
            _currentIHttpRequestFeature              = this;
            _currentIHttpResponseFeature             = this;
            _currentIHttpResponseBodyFeature         = this;
            _currentIRouteValuesFeature              = this;
            _currentIEndpointFeature                 = this;
            _currentIHttpRequestIdentifierFeature    = this;
            _currentIHttpRequestTrailersFeature      = this;
            _currentIHttpUpgradeFeature              = this;
            _currentIRequestBodyPipeFeature          = this;
            _currentIHttpConnectionFeature           = this;
            _currentIHttpRequestLifetimeFeature      = this;
            _currentIHttpBodyControlFeature          = this;
            _currentIHttpMaxRequestBodySizeFeature   = this;
            _currentIHttpRequestBodyDetectionFeature = this;

            _currentIServiceProvidersFeature           = null;
            _currentIItemsFeature                      = null;
            _currentIQueryFeature                      = null;
            _currentIFormFeature                       = null;
            _currentIHttpAuthenticationFeature         = null;
            _currentISessionFeature                    = null;
            _currentIResponseCookiesFeature            = null;
            _currentIHttpResponseTrailersFeature       = null;
            _currentITlsConnectionFeature              = null;
            _currentIHttpWebSocketFeature              = null;
            _currentIHttp2StreamIdFeature              = null;
            _currentIHttpMinRequestBodyDataRateFeature = null;
            _currentIHttpMinResponseDataRateFeature    = null;
            _currentIHttpResetFeature                  = null;
        }
예제 #2
0
 public WebSocketHandshake(HttpContext context, IHttpUpgradeFeature?upgradeFeature, IHttpExtendedConnectFeature?connectFeature, WebSocketOptions options, ILogger logger)
 {
     _context        = context;
     _upgradeFeature = upgradeFeature;
     _connectFeature = connectFeature;
     _options        = options;
     _logger         = logger;
 }
예제 #3
0
        void IFeatureCollection.Set <TFeature>(TFeature?feature) where TFeature : default
        {
            // Using Unsafe.As for the cast due to https://github.com/dotnet/runtime/issues/49614
            // The type of TFeature is confirmed by the typeof() check and the As cast only accepts
            // that type; however the Jit does not eliminate a regular cast in a shared generic.

            _featureRevision++;
            if (typeof(TFeature) == typeof(IHttpRequestFeature))
            {
                _currentIHttpRequestFeature = Unsafe.As <TFeature?, IHttpRequestFeature?>(ref feature);
            }
            else if (typeof(TFeature) == typeof(IHttpResponseFeature))
            {
                _currentIHttpResponseFeature = Unsafe.As <TFeature?, IHttpResponseFeature?>(ref feature);
            }
            else if (typeof(TFeature) == typeof(IHttpResponseBodyFeature))
            {
                _currentIHttpResponseBodyFeature = Unsafe.As <TFeature?, IHttpResponseBodyFeature?>(ref feature);
            }
            else if (typeof(TFeature) == typeof(IRouteValuesFeature))
            {
                _currentIRouteValuesFeature = Unsafe.As <TFeature?, IRouteValuesFeature?>(ref feature);
            }
            else if (typeof(TFeature) == typeof(IEndpointFeature))
            {
                _currentIEndpointFeature = Unsafe.As <TFeature?, IEndpointFeature?>(ref feature);
            }
            else if (typeof(TFeature) == typeof(IServiceProvidersFeature))
            {
                _currentIServiceProvidersFeature = Unsafe.As <TFeature?, IServiceProvidersFeature?>(ref feature);
            }
            else if (typeof(TFeature) == typeof(IItemsFeature))
            {
                _currentIItemsFeature = Unsafe.As <TFeature?, IItemsFeature?>(ref feature);
            }
            else if (typeof(TFeature) == typeof(IQueryFeature))
            {
                _currentIQueryFeature = Unsafe.As <TFeature?, IQueryFeature?>(ref feature);
            }
            else if (typeof(TFeature) == typeof(IRequestBodyPipeFeature))
            {
                _currentIRequestBodyPipeFeature = Unsafe.As <TFeature?, IRequestBodyPipeFeature?>(ref feature);
            }
            else if (typeof(TFeature) == typeof(IFormFeature))
            {
                _currentIFormFeature = Unsafe.As <TFeature?, IFormFeature?>(ref feature);
            }
            else if (typeof(TFeature) == typeof(IHttpAuthenticationFeature))
            {
                _currentIHttpAuthenticationFeature = Unsafe.As <TFeature?, IHttpAuthenticationFeature?>(ref feature);
            }
            else if (typeof(TFeature) == typeof(IHttpRequestIdentifierFeature))
            {
                _currentIHttpRequestIdentifierFeature = Unsafe.As <TFeature?, IHttpRequestIdentifierFeature?>(ref feature);
            }
            else if (typeof(TFeature) == typeof(IHttpConnectionFeature))
            {
                _currentIHttpConnectionFeature = Unsafe.As <TFeature?, IHttpConnectionFeature?>(ref feature);
            }
            else if (typeof(TFeature) == typeof(ISessionFeature))
            {
                _currentISessionFeature = Unsafe.As <TFeature?, ISessionFeature?>(ref feature);
            }
            else if (typeof(TFeature) == typeof(IResponseCookiesFeature))
            {
                _currentIResponseCookiesFeature = Unsafe.As <TFeature?, IResponseCookiesFeature?>(ref feature);
            }
            else if (typeof(TFeature) == typeof(IHttpRequestTrailersFeature))
            {
                _currentIHttpRequestTrailersFeature = Unsafe.As <TFeature?, IHttpRequestTrailersFeature?>(ref feature);
            }
            else if (typeof(TFeature) == typeof(IHttpResponseTrailersFeature))
            {
                _currentIHttpResponseTrailersFeature = Unsafe.As <TFeature?, IHttpResponseTrailersFeature?>(ref feature);
            }
            else if (typeof(TFeature) == typeof(ITlsConnectionFeature))
            {
                _currentITlsConnectionFeature = Unsafe.As <TFeature?, ITlsConnectionFeature?>(ref feature);
            }
            else if (typeof(TFeature) == typeof(IHttpUpgradeFeature))
            {
                _currentIHttpUpgradeFeature = Unsafe.As <TFeature?, IHttpUpgradeFeature?>(ref feature);
            }
            else if (typeof(TFeature) == typeof(IHttpWebSocketFeature))
            {
                _currentIHttpWebSocketFeature = Unsafe.As <TFeature?, IHttpWebSocketFeature?>(ref feature);
            }
            else if (typeof(TFeature) == typeof(IHttp2StreamIdFeature))
            {
                _currentIHttp2StreamIdFeature = Unsafe.As <TFeature?, IHttp2StreamIdFeature?>(ref feature);
            }
            else if (typeof(TFeature) == typeof(IHttpRequestLifetimeFeature))
            {
                _currentIHttpRequestLifetimeFeature = Unsafe.As <TFeature?, IHttpRequestLifetimeFeature?>(ref feature);
            }
            else if (typeof(TFeature) == typeof(IHttpMaxRequestBodySizeFeature))
            {
                _currentIHttpMaxRequestBodySizeFeature = Unsafe.As <TFeature?, IHttpMaxRequestBodySizeFeature?>(ref feature);
            }
            else if (typeof(TFeature) == typeof(IHttpMinRequestBodyDataRateFeature))
            {
                _currentIHttpMinRequestBodyDataRateFeature = Unsafe.As <TFeature?, IHttpMinRequestBodyDataRateFeature?>(ref feature);
            }
            else if (typeof(TFeature) == typeof(IHttpMinResponseDataRateFeature))
            {
                _currentIHttpMinResponseDataRateFeature = Unsafe.As <TFeature?, IHttpMinResponseDataRateFeature?>(ref feature);
            }
            else if (typeof(TFeature) == typeof(IHttpBodyControlFeature))
            {
                _currentIHttpBodyControlFeature = Unsafe.As <TFeature?, IHttpBodyControlFeature?>(ref feature);
            }
            else if (typeof(TFeature) == typeof(IHttpRequestBodyDetectionFeature))
            {
                _currentIHttpRequestBodyDetectionFeature = Unsafe.As <TFeature?, IHttpRequestBodyDetectionFeature?>(ref feature);
            }
            else if (typeof(TFeature) == typeof(IHttpResetFeature))
            {
                _currentIHttpResetFeature = Unsafe.As <TFeature?, IHttpResetFeature?>(ref feature);
            }
            else
            {
                ExtraFeatureSet(typeof(TFeature), feature);
            }
        }
예제 #4
0
        object?IFeatureCollection.this[Type key]
        {
            get
            {
                object?feature = null;
                if (key == typeof(IHttpRequestFeature))
                {
                    feature = _currentIHttpRequestFeature;
                }
                else if (key == typeof(IHttpResponseFeature))
                {
                    feature = _currentIHttpResponseFeature;
                }
                else if (key == typeof(IHttpResponseBodyFeature))
                {
                    feature = _currentIHttpResponseBodyFeature;
                }
                else if (key == typeof(IRouteValuesFeature))
                {
                    feature = _currentIRouteValuesFeature;
                }
                else if (key == typeof(IEndpointFeature))
                {
                    feature = _currentIEndpointFeature;
                }
                else if (key == typeof(IServiceProvidersFeature))
                {
                    feature = _currentIServiceProvidersFeature;
                }
                else if (key == typeof(IItemsFeature))
                {
                    feature = _currentIItemsFeature;
                }
                else if (key == typeof(IQueryFeature))
                {
                    feature = _currentIQueryFeature;
                }
                else if (key == typeof(IRequestBodyPipeFeature))
                {
                    feature = _currentIRequestBodyPipeFeature;
                }
                else if (key == typeof(IFormFeature))
                {
                    feature = _currentIFormFeature;
                }
                else if (key == typeof(IHttpAuthenticationFeature))
                {
                    feature = _currentIHttpAuthenticationFeature;
                }
                else if (key == typeof(IHttpRequestIdentifierFeature))
                {
                    feature = _currentIHttpRequestIdentifierFeature;
                }
                else if (key == typeof(IHttpConnectionFeature))
                {
                    feature = _currentIHttpConnectionFeature;
                }
                else if (key == typeof(ISessionFeature))
                {
                    feature = _currentISessionFeature;
                }
                else if (key == typeof(IResponseCookiesFeature))
                {
                    feature = _currentIResponseCookiesFeature;
                }
                else if (key == typeof(IHttpRequestTrailersFeature))
                {
                    feature = _currentIHttpRequestTrailersFeature;
                }
                else if (key == typeof(IHttpResponseTrailersFeature))
                {
                    feature = _currentIHttpResponseTrailersFeature;
                }
                else if (key == typeof(ITlsConnectionFeature))
                {
                    feature = _currentITlsConnectionFeature;
                }
                else if (key == typeof(IHttpUpgradeFeature))
                {
                    feature = _currentIHttpUpgradeFeature;
                }
                else if (key == typeof(IHttpWebSocketFeature))
                {
                    feature = _currentIHttpWebSocketFeature;
                }
                else if (key == typeof(IHttp2StreamIdFeature))
                {
                    feature = _currentIHttp2StreamIdFeature;
                }
                else if (key == typeof(IHttpRequestLifetimeFeature))
                {
                    feature = _currentIHttpRequestLifetimeFeature;
                }
                else if (key == typeof(IHttpMaxRequestBodySizeFeature))
                {
                    feature = _currentIHttpMaxRequestBodySizeFeature;
                }
                else if (key == typeof(IHttpMinRequestBodyDataRateFeature))
                {
                    feature = _currentIHttpMinRequestBodyDataRateFeature;
                }
                else if (key == typeof(IHttpMinResponseDataRateFeature))
                {
                    feature = _currentIHttpMinResponseDataRateFeature;
                }
                else if (key == typeof(IHttpBodyControlFeature))
                {
                    feature = _currentIHttpBodyControlFeature;
                }
                else if (key == typeof(IHttpRequestBodyDetectionFeature))
                {
                    feature = _currentIHttpRequestBodyDetectionFeature;
                }
                else if (key == typeof(IHttpResetFeature))
                {
                    feature = _currentIHttpResetFeature;
                }
                else if (MaybeExtra != null)
                {
                    feature = ExtraFeatureGet(key);
                }

                return(feature ?? ConnectionFeatures[key]);
            }

            set
            {
                _featureRevision++;

                if (key == typeof(IHttpRequestFeature))
                {
                    _currentIHttpRequestFeature = (IHttpRequestFeature?)value;
                }
                else if (key == typeof(IHttpResponseFeature))
                {
                    _currentIHttpResponseFeature = (IHttpResponseFeature?)value;
                }
                else if (key == typeof(IHttpResponseBodyFeature))
                {
                    _currentIHttpResponseBodyFeature = (IHttpResponseBodyFeature?)value;
                }
                else if (key == typeof(IRouteValuesFeature))
                {
                    _currentIRouteValuesFeature = (IRouteValuesFeature?)value;
                }
                else if (key == typeof(IEndpointFeature))
                {
                    _currentIEndpointFeature = (IEndpointFeature?)value;
                }
                else if (key == typeof(IServiceProvidersFeature))
                {
                    _currentIServiceProvidersFeature = (IServiceProvidersFeature?)value;
                }
                else if (key == typeof(IItemsFeature))
                {
                    _currentIItemsFeature = (IItemsFeature?)value;
                }
                else if (key == typeof(IQueryFeature))
                {
                    _currentIQueryFeature = (IQueryFeature?)value;
                }
                else if (key == typeof(IRequestBodyPipeFeature))
                {
                    _currentIRequestBodyPipeFeature = (IRequestBodyPipeFeature?)value;
                }
                else if (key == typeof(IFormFeature))
                {
                    _currentIFormFeature = (IFormFeature?)value;
                }
                else if (key == typeof(IHttpAuthenticationFeature))
                {
                    _currentIHttpAuthenticationFeature = (IHttpAuthenticationFeature?)value;
                }
                else if (key == typeof(IHttpRequestIdentifierFeature))
                {
                    _currentIHttpRequestIdentifierFeature = (IHttpRequestIdentifierFeature?)value;
                }
                else if (key == typeof(IHttpConnectionFeature))
                {
                    _currentIHttpConnectionFeature = (IHttpConnectionFeature?)value;
                }
                else if (key == typeof(ISessionFeature))
                {
                    _currentISessionFeature = (ISessionFeature?)value;
                }
                else if (key == typeof(IResponseCookiesFeature))
                {
                    _currentIResponseCookiesFeature = (IResponseCookiesFeature?)value;
                }
                else if (key == typeof(IHttpRequestTrailersFeature))
                {
                    _currentIHttpRequestTrailersFeature = (IHttpRequestTrailersFeature?)value;
                }
                else if (key == typeof(IHttpResponseTrailersFeature))
                {
                    _currentIHttpResponseTrailersFeature = (IHttpResponseTrailersFeature?)value;
                }
                else if (key == typeof(ITlsConnectionFeature))
                {
                    _currentITlsConnectionFeature = (ITlsConnectionFeature?)value;
                }
                else if (key == typeof(IHttpUpgradeFeature))
                {
                    _currentIHttpUpgradeFeature = (IHttpUpgradeFeature?)value;
                }
                else if (key == typeof(IHttpWebSocketFeature))
                {
                    _currentIHttpWebSocketFeature = (IHttpWebSocketFeature?)value;
                }
                else if (key == typeof(IHttp2StreamIdFeature))
                {
                    _currentIHttp2StreamIdFeature = (IHttp2StreamIdFeature?)value;
                }
                else if (key == typeof(IHttpRequestLifetimeFeature))
                {
                    _currentIHttpRequestLifetimeFeature = (IHttpRequestLifetimeFeature?)value;
                }
                else if (key == typeof(IHttpMaxRequestBodySizeFeature))
                {
                    _currentIHttpMaxRequestBodySizeFeature = (IHttpMaxRequestBodySizeFeature?)value;
                }
                else if (key == typeof(IHttpMinRequestBodyDataRateFeature))
                {
                    _currentIHttpMinRequestBodyDataRateFeature = (IHttpMinRequestBodyDataRateFeature?)value;
                }
                else if (key == typeof(IHttpMinResponseDataRateFeature))
                {
                    _currentIHttpMinResponseDataRateFeature = (IHttpMinResponseDataRateFeature?)value;
                }
                else if (key == typeof(IHttpBodyControlFeature))
                {
                    _currentIHttpBodyControlFeature = (IHttpBodyControlFeature?)value;
                }
                else if (key == typeof(IHttpRequestBodyDetectionFeature))
                {
                    _currentIHttpRequestBodyDetectionFeature = (IHttpRequestBodyDetectionFeature?)value;
                }
                else if (key == typeof(IHttpResetFeature))
                {
                    _currentIHttpResetFeature = (IHttpResetFeature?)value;
                }
                else
                {
                    ExtraFeatureSet(key, value);
                }
            }
        }
예제 #5
0
    private async Task InvokeInternal(HttpContext context)
    {
        var options = _options.CurrentValue;
        RequestBufferingStream?requestBufferingStream = null;
        Stream?originalBody = null;

        if ((HttpLoggingFields.Request & options.LoggingFields) != HttpLoggingFields.None)
        {
            var request = context.Request;
            var list    = new List <KeyValuePair <string, object?> >(
                request.Headers.Count + DefaultRequestFieldsMinusHeaders);

            if (options.LoggingFields.HasFlag(HttpLoggingFields.RequestProtocol))
            {
                AddToList(list, nameof(request.Protocol), request.Protocol);
            }

            if (options.LoggingFields.HasFlag(HttpLoggingFields.RequestMethod))
            {
                AddToList(list, nameof(request.Method), request.Method);
            }

            if (options.LoggingFields.HasFlag(HttpLoggingFields.RequestScheme))
            {
                AddToList(list, nameof(request.Scheme), request.Scheme);
            }

            if (options.LoggingFields.HasFlag(HttpLoggingFields.RequestPath))
            {
                AddToList(list, nameof(request.PathBase), request.PathBase);
                AddToList(list, nameof(request.Path), request.Path);
            }

            if (options.LoggingFields.HasFlag(HttpLoggingFields.RequestQuery))
            {
                AddToList(list, nameof(request.QueryString), request.QueryString.Value);
            }

            if (options.LoggingFields.HasFlag(HttpLoggingFields.RequestHeaders))
            {
                FilterHeaders(list, request.Headers, options._internalRequestHeaders);
            }

            if (options.LoggingFields.HasFlag(HttpLoggingFields.RequestBody))
            {
                if (request.ContentType is null)
                {
                    _logger.NoMediaType("request");
                }
                else if (MediaTypeHelpers.TryGetEncodingForMediaType(request.ContentType,
                                                                     options.MediaTypeOptions.MediaTypeStates,
                                                                     out var encoding))
                {
                    originalBody           = request.Body;
                    requestBufferingStream = new RequestBufferingStream(
                        request.Body,
                        options.RequestBodyLogLimit,
                        _logger,
                        encoding);
                    request.Body = requestBufferingStream;
                }
                else
                {
                    _logger.UnrecognizedMediaType("request");
                }
            }

            var httpRequestLog = new HttpRequestLog(list);

            _logger.RequestLog(httpRequestLog);
        }

        ResponseBufferingStream? responseBufferingStream = null;
        IHttpResponseBodyFeature?originalBodyFeature     = null;

        UpgradeFeatureLoggingDecorator?loggableUpgradeFeature = null;
        IHttpUpgradeFeature?           originalUpgradeFeature = null;

        try
        {
            var response = context.Response;

            if (options.LoggingFields.HasFlag(HttpLoggingFields.ResponseStatusCode) || options.LoggingFields.HasFlag(HttpLoggingFields.ResponseHeaders))
            {
                originalUpgradeFeature = context.Features.Get <IHttpUpgradeFeature>();

                if (originalUpgradeFeature != null && originalUpgradeFeature.IsUpgradableRequest)
                {
                    loggableUpgradeFeature = new UpgradeFeatureLoggingDecorator(originalUpgradeFeature, response, options, _logger);

                    context.Features.Set <IHttpUpgradeFeature>(loggableUpgradeFeature);
                }
            }

            if (options.LoggingFields.HasFlag(HttpLoggingFields.ResponseBody))
            {
                originalBodyFeature = context.Features.Get <IHttpResponseBodyFeature>() !;

                // TODO pool these.
                responseBufferingStream = new ResponseBufferingStream(originalBodyFeature,
                                                                      options.ResponseBodyLogLimit,
                                                                      _logger,
                                                                      context,
                                                                      options.MediaTypeOptions.MediaTypeStates,
                                                                      options);
                response.Body = responseBufferingStream;
                context.Features.Set <IHttpResponseBodyFeature>(responseBufferingStream);
            }

            await _next(context);

            if (requestBufferingStream?.HasLogged == false)
            {
                // If the middleware pipeline didn't read until 0 was returned from readasync,
                // make sure we log the request body.
                requestBufferingStream.LogRequestBody();
            }

            if (ResponseHeadersNotYetWritten(responseBufferingStream, loggableUpgradeFeature))
            {
                // No body, not an upgradable request or request not upgraded, write headers here.
                LogResponseHeaders(response, options, _logger);
            }

            if (responseBufferingStream != null)
            {
                var responseBody = responseBufferingStream.GetString(responseBufferingStream.Encoding);
                if (!string.IsNullOrEmpty(responseBody))
                {
                    _logger.ResponseBody(responseBody);
                }
            }
        }
        finally
        {
            responseBufferingStream?.Dispose();

            if (originalBodyFeature != null)
            {
                context.Features.Set(originalBodyFeature);
            }

            requestBufferingStream?.Dispose();

            if (originalBody != null)
            {
                context.Request.Body = originalBody;
            }

            if (loggableUpgradeFeature != null)
            {
                context.Features.Set(originalUpgradeFeature);
            }
        }
    }