示例#1
0
    /// <summary>
    /// Removes and returns the current header value by first checking the HttpResponse
    /// and falling back to the value from HttpResponseMessage or HttpContent only if
    /// <see cref="ResponseTransformContext.HeadersCopied"/> is not set.
    /// This ordering allows multiple transforms to mutate the same header.
    /// </summary>
    /// <param name="context">The transform context.</param>
    /// <param name="headerName">The name of the header to take.</param>
    /// <returns>The response header value, or StringValues.Empty if none.</returns>
    public static StringValues TakeHeader(ResponseTransformContext context, string headerName)
    {
        if (context is null)
        {
            throw new ArgumentNullException(nameof(context));
        }

        if (string.IsNullOrEmpty(headerName))
        {
            throw new ArgumentException($"'{nameof(headerName)}' cannot be null or empty.", nameof(headerName));
        }

        if (context.HttpContext.Response.Headers.TryGetValue(headerName, out var existingValues))
        {
            context.HttpContext.Response.Headers.Remove(headerName);
        }
        else if (context.ProxyResponse is { } proxyResponse&& !context.HeadersCopied)
        {
            if (!RequestUtilities.TryGetValues(proxyResponse.Headers, headerName, out existingValues))
            {
                RequestUtilities.TryGetValues(proxyResponse.Content.Headers, headerName, out existingValues);
            }
        }

        return(existingValues);
    }
示例#2
0
    /// <summary>
    /// Removes and returns the current trailer value by first checking the HttpResponse
    /// and falling back to the value from HttpResponseMessage only if
    /// <see cref="ResponseTrailersTransformContext.HeadersCopied"/> is not set.
    /// This ordering allows multiple transforms to mutate the same header.
    /// </summary>
    /// <param name="context">The transform context.</param>
    /// <param name="headerName">The name of the header to take.</param>
    /// <returns>The response header value, or StringValues.Empty if none.</returns>
    public static StringValues TakeHeader(ResponseTrailersTransformContext context, string headerName)
    {
        if (context is null)
        {
            throw new ArgumentNullException(nameof(context));
        }

        if (string.IsNullOrEmpty(headerName))
        {
            throw new ArgumentException($"'{nameof(headerName)}' cannot be null or empty.", nameof(headerName));
        }

        Debug.Assert(context.ProxyResponse is not null);

        var responseTrailersFeature = context.HttpContext.Features.Get <IHttpResponseTrailersFeature>();
        var responseTrailers        = responseTrailersFeature?.Trailers;

        // Support should have already been checked by the caller.
        Debug.Assert(responseTrailers is not null);
        Debug.Assert(!responseTrailers.IsReadOnly);

        if (responseTrailers.TryGetValue(headerName, out var existingValues))
        {
            responseTrailers.Remove(headerName);
        }
        else if (!context.HeadersCopied)
        {
            RequestUtilities.TryGetValues(context.ProxyResponse.TrailingHeaders, headerName, out existingValues);
        }

        return(existingValues);
    }
示例#3
0
    public void TryGetValues(params string[] headerValues)
    {
        var request = new HttpRequestMessage();

        foreach (var value in headerValues)
        {
            request.Headers.TryAddWithoutValidation("foo", value);
        }
        request.Headers.TryAddWithoutValidation("bar", headerValues);

        Assert.True(RequestUtilities.TryGetValues(request.Headers, "foo", out var actualValues));
        Assert.Equal(headerValues, actualValues);

        Assert.True(RequestUtilities.TryGetValues(request.Headers, "bar", out actualValues));
        Assert.Equal(headerValues, actualValues);
    }
示例#4
0
    /// <summary>
    /// Removes and returns the current header value by first checking the HttpRequestMessage,
    /// then the HttpContent, and falling back to the HttpContext only if
    /// <see cref="RequestTransformContext.HeadersCopied"/> is not set.
    /// This ordering allows multiple transforms to mutate the same header.
    /// </summary>
    /// <param name="context">The transform context.</param>
    /// <param name="headerName">The name of the header to take.</param>
    /// <returns>The requested header value, or StringValues.Empty if none.</returns>
    public static StringValues TakeHeader(RequestTransformContext context, string headerName)
    {
        if (string.IsNullOrEmpty(headerName))
        {
            throw new ArgumentException($"'{nameof(headerName)}' cannot be null or empty.", nameof(headerName));
        }

        var proxyRequest = context.ProxyRequest;

        if (RequestUtilities.TryGetValues(proxyRequest.Headers, headerName, out var existingValues))
        {
            proxyRequest.Headers.Remove(headerName);
        }
        else if (proxyRequest.Content is { } content&& RequestUtilities.TryGetValues(content.Headers, headerName, out existingValues))
        {
            content.Headers.Remove(headerName);
        }
示例#5
0
 private static void RestoreUpgradeHeaders(HttpContext context, HttpResponseMessage response)
 {
     // We don't use NonValidated for the Connection header as we do want value validation.
     // HttpHeaders.TryGetValues will handle the parsing and split the values for us.
     if (RequestUtilities.TryGetValues(response.Headers, HeaderNames.Upgrade, out var upgradeValues) &&
         response.Headers.TryGetValues(HeaderNames.Connection, out var connectionValues))
     {
         foreach (var value in connectionValues)
         {
             if (value.Equals("upgrade", StringComparison.OrdinalIgnoreCase))
             {
                 context.Response.Headers.TryAdd(HeaderNames.Connection, value);
                 context.Response.Headers.TryAdd(HeaderNames.Upgrade, upgradeValues);
                 break;
             }
         }
     }
 }