public async Task AddResponseHeader_Success(string startValue, int status, string value, bool append, bool always, string expected)
        {
            var httpContext = new DefaultHttpContext();

            httpContext.Response.Headers["name"] = startValue.Split(";", System.StringSplitOptions.RemoveEmptyEntries);
            httpContext.Response.StatusCode      = status;
            var transformContext = new ResponseTransformContext()
            {
                HttpContext   = httpContext,
                ProxyResponse = new HttpResponseMessage(),
                HeadersCopied = true,
            };
            var transform = new ResponseHeaderValueTransform("name", value, append, always);
            await transform.ApplyAsync(transformContext);

            Assert.Equal(expected.Split(";", System.StringSplitOptions.RemoveEmptyEntries), httpContext.Response.Headers["name"]);
        }
예제 #2
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="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)
        {
            var existingValues = StringValues.Empty;

            if (context.HttpContext.Response.Headers.TryGetValue(headerName, out var responseValues))
            {
                context.HttpContext.Response.Headers.Remove(headerName);
                existingValues = responseValues;
            }
            else if (!context.HeadersCopied &&
                     (context.ProxyResponse.Headers.TryGetValues(headerName, out var values) ||
                      context.ProxyResponse.Content.Headers.TryGetValues(headerName, out values)))
            {
                existingValues = (string[])values;
            }

            return(existingValues);
        }
예제 #3
0
        // Assumes the response status code has been set on the HttpContext already.
        /// <inheritdoc/>
        public override ValueTask ApplyAsync(ResponseTransformContext context)
        {
            if (context is null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (Always || Success(context))
            {
                var existingHeader = TakeHeader(context, HeaderName);
                if (Append)
                {
                    var value = StringValues.Concat(existingHeader, Value);
                    SetHeader(context, HeaderName, value);
                }
                else if (!string.IsNullOrEmpty(Value))
                {
                    SetHeader(context, HeaderName, Value);
                }
                // If the given value is empty, any existing header is removed.
            }

            return(default);
        public override async Task TransformResponseAsync(HttpContext httpContext, HttpResponseMessage proxyResponse)
        {
            if (ShouldCopyResponseHeaders.GetValueOrDefault(true))
            {
                await base.TransformResponseAsync(httpContext, proxyResponse);
            }

            if (ResponseTransforms.Count == 0)
            {
                return;
            }

            var transformContext = new ResponseTransformContext()
            {
                HttpContext   = httpContext,
                ProxyResponse = proxyResponse,
                HeadersCopied = ShouldCopyResponseHeaders.GetValueOrDefault(true),
            };

            foreach (var responseTransform in ResponseTransforms)
            {
                await responseTransform.ApplyAsync(transformContext);
            }
        }
예제 #5
0
 /// <summary>
 /// Sets the given header on the HttpResponse.
 /// </summary>
 public static void SetHeader(ResponseTransformContext context, string headerName, StringValues values)
 {
     context.HttpContext.Response.Headers[headerName] = values;
 }
예제 #6
0
 /// <summary>
 /// Transforms the given response. The status and headers will have (optionally) already been
 /// copied to the <see cref="HttpResponse"/> and any changes should be made there.
 /// </summary>
 public abstract Task ApplyAsync(ResponseTransformContext context);
예제 #7
0
 /// <inheritdoc/>
 public override ValueTask ApplyAsync(ResponseTransformContext context)
 {
     return(_func(context));
 }
 private static bool Success(ResponseTransformContext context)
 {
     // TODO: How complex should this get? Compare with http://nginx.org/en/docs/http/ngx_http_headers_module.html#add_header
     return(context.HttpContext.Response.StatusCode < 400);
 }