예제 #1
0
        private static RequestDelegate CreateRouteHandler(
            string path, CarterModule module, IEnumerable <IStatusCodeHandler> statusCodeHandlers, ILogger logger)
        {
            return(async ctx =>
            {
                if (!module.Routes.TryGetValue((ctx.Request.Method, path), out var routeHandler))
                {
                    // if the path was registered but a handler matching the
                    // current method was not found, return MethodNotFound
                    ctx.Response.StatusCode = StatusCodes.Status405MethodNotAllowed;
                    return;
                }

                // begin handling the request
                if (HttpMethods.IsHead(ctx.Request.Method))
                {
                    //Cannot read the default stream once WriteAsync has been called on it
                    ctx.Response.Body = new MemoryStream();
                }

                // run the module handlers
                bool shouldContinue = true;

                if (module.Before != null)
                {
                    shouldContinue = await module.Before(ctx);
                }

                if (shouldContinue)
                {
                    // run the route handler
                    logger.LogDebug("Executing module route handler for {Method} /{Path}", ctx.Request.Method, path);
                    await routeHandler(ctx);

                    // run after handler
                    if (module.After != null)
                    {
                        await module.After(ctx);
                    }
                }

                // run status code handler
                var scHandler = statusCodeHandlers.FirstOrDefault(x => x.CanHandle(ctx.Response.StatusCode));
                if (scHandler != null)
                {
                    await scHandler.Handle(ctx);
                }

                if (HttpMethods.IsHead(ctx.Request.Method))
                {
                    var length = ctx.Response.Body.Length;
                    ctx.Response.Body.SetLength(0);
                    ctx.Response.ContentLength = length;
                }
            });
        }
        /// <inheritdoc />
        public void OnResourceExecuting(ResourceExecutingContext context)
        {
            if (context == null)
            {
                throw new System.ArgumentNullException(nameof(context));
            }

            var routeData = context.RouteData;
            var request   = context.HttpContext.Request;

            if (routeData.TryGetWebHookReceiverName(out var receiverName) &&
                (HttpMethods.IsGet(request.Method) || HttpMethods.IsHead(request.Method)))
            {
                var getHeadRequestMetadata = _getHeadRequestMetadata
                                             .FirstOrDefault(metadata => metadata.IsApplicable(receiverName));
                if (getHeadRequestMetadata != null)
                {
                    // First verify that we have the secret key configuration value. This may be redundant if the
                    // receiver also implements IWebHookVerifyCodeMetadata in its metadata. However this verification
                    // is necessary for some receivers because signature verification (for example) is not possible
                    // without a body.
                    var secretKey = GetSecretKey(
                        receiverName,
                        routeData,
                        getHeadRequestMetadata.SecretKeyMinLength,
                        getHeadRequestMetadata.SecretKeyMaxLength);
                    if (secretKey == null)
                    {
                        context.Result = new NotFoundResult();
                        return;
                    }

                    if (HttpMethods.IsHead(request.Method))
                    {
                        if (getHeadRequestMetadata.AllowHeadRequests)
                        {
                            // Success #1
                            context.Result = new OkResult();
                        }

                        // Never respond to a HEAD request with a challenge response.
                        return;
                    }

                    if (getHeadRequestMetadata.ChallengeQueryParameterName == null)
                    {
                        // Success #2: Simple GET case. Have done all necessary verification.
                        context.Result = new OkResult();
                        return;
                    }

                    // Success #3 unless required query parameter is missing.
                    context.Result = GetChallengeResponse(getHeadRequestMetadata, receiverName, request, routeData);
                }
            }
        }
        private static bool ShouldValidate(HttpContext context)
        {
            // as seen on https://github.com/aspnet/AspNetCore/blob/release/3.0/src/Mvc/Mvc.ViewFeatures/src/Filters/AutoValidateAntiforgeryTokenAuthorizationFilter.cs

            var method = context.Request.Method;

            return(!(HttpMethods.IsGet(method) ||
                     HttpMethods.IsHead(method) ||
                     HttpMethods.IsTrace(method) ||
                     HttpMethods.IsOptions(method)));
        }
    public override bool AttemptResponseCaching(ResponseCachingContext context)
    {
        var request = context.HttpContext.Request;

        if (!HttpMethods.IsGet(request.Method) && !HttpMethods.IsHead(request.Method))
        {
            context.Logger.LogRequestMethodNotCacheable(request.Method);
            return(false);
        }
        return(true);
    }
예제 #5
0
 public async Task InvokeAsync(HttpContext context, RequestDelegate next)
 {
     if (HttpMethods.IsGet(context.Request.Method) || HttpMethods.IsHead(context.Request.Method))
     {
         context.Response.StatusCode = StatusCodes.Status200OK;
         await context.Response.WriteAsync("I'm alive");
     }
     else
     {
         context.Response.StatusCode = StatusCodes.Status404NotFound;
     }
 }
예제 #6
0
        private static HttpRequestMessage CreateProxiedHttpRequest(this HttpContext context, string uriString, bool shouldAddForwardedHeaders)
        {
            var uri     = new Uri(uriString);
            var request = context.Request;

            var requestMessage    = new HttpRequestMessage();
            var requestMethod     = request.Method;
            var usesStreamContent = true; // When using other content types, they specify the Content-Type header, and may also change the Content-Length.

            // Write to request content, when necessary.
            if (!HttpMethods.IsGet(requestMethod) &&
                !HttpMethods.IsHead(requestMethod) &&
                !HttpMethods.IsDelete(requestMethod) &&
                !HttpMethods.IsTrace(requestMethod))
            {
                if (request.HasFormContentType)
                {
                    usesStreamContent      = false;
                    requestMessage.Content = request.Form.ToHttpContent(request.ContentType);
                }
                else
                {
                    requestMessage.Content = new StreamContent(request.Body);
                }
            }

            // Copy the request headers.
            foreach (var header in request.Headers)
            {
                if (!usesStreamContent && (header.Key.Equals("Content-Type", StringComparison.OrdinalIgnoreCase) || header.Key.Equals("Content-Length", StringComparison.OrdinalIgnoreCase)))
                {
                    continue;
                }
                if (!requestMessage.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray()))
                {
                    requestMessage.Content?.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray());
                }
            }

            // Add forwarded headers.
            if (shouldAddForwardedHeaders)
            {
                AddForwardedHeadersToHttpRequest(context, requestMessage);
            }

            // Set destination and method.
            requestMessage.Headers.Host = uri.Authority;
            requestMessage.RequestUri   = uri;
            requestMessage.Method       = new HttpMethod(requestMethod);

            return(requestMessage);
        }
예제 #7
0
        static bool SetupMethodAndContent(HttpRequest request, HttpRequestMessage proxiedMessage)
        {
            var hasContent    = false;
            var requestMethod = request.Method;

            // Try to use the static HttpMethods rather than creating a new one.
            if (HttpMethods.IsGet(requestMethod))
            {
                proxiedMessage.Method = HttpMethod.Get;
            }
            else if (HttpMethods.IsHead(requestMethod))
            {
                proxiedMessage.Method = HttpMethod.Head;
            }
            else if (HttpMethods.IsDelete(requestMethod))
            {
                proxiedMessage.Method = HttpMethod.Delete;
            }
            else if (HttpMethods.IsTrace(requestMethod))
            {
                proxiedMessage.Method = HttpMethod.Trace;
            }
            else
            {
                hasContent = true;

                if (HttpMethods.IsPost(requestMethod))
                {
                    proxiedMessage.Method = HttpMethod.Post;
                }
                else if (HttpMethods.IsOptions(requestMethod))
                {
                    proxiedMessage.Method = HttpMethod.Options;
                }
                else if (HttpMethods.IsPut(requestMethod))
                {
                    proxiedMessage.Method = HttpMethod.Put;
                }
                else if (HttpMethods.IsPatch(requestMethod))
                {
                    proxiedMessage.Method = HttpMethod.Patch;
                }
                else
                {
                    proxiedMessage.Method = new HttpMethod(request.Method);
                }

                proxiedMessage.Content = new StreamContent(request.Body);
            }

            return(hasContent);
        }
예제 #8
0
        private static void SetProxyRequestBody(HttpRequestMessage requestMessage, HttpContext context)
        {
            var requestMethod = context.Request.Method;

            //previously had DELETE as a part of this but we were actually passing up body content as part of our delete wallet calls :-|
            if (HttpMethods.IsGet(requestMethod) ||
                HttpMethods.IsHead(requestMethod) ||
                HttpMethods.IsTrace(requestMethod))
            {
                return;
            }
            requestMessage.Content = new StreamContent(context.Request.Body);
        }
        public async void HealthCheck_Get_Status200(string method)
        {
            var response = await _client.SendAsync(new HttpRequestMessage(new HttpMethod(method), "api/_system/healthcheck"));

            if (!HttpMethods.IsHead(method) &&
                !HttpMethods.IsDelete(method) &&
                !HttpMethods.IsTrace(method))
            {
                Assert.Equal("system_ok", await response.Content.ReadAsStringAsync());
            }

            Assert.Equal(HttpStatusCode.OK, response.StatusCode);
        }
        private static void SetProxyRequestBody(HttpRequestMessage requestMessage, HttpContext context)
        {
            var requestMethod = context.Request.Method;

            if (HttpMethods.IsGet(requestMethod) ||
                HttpMethods.IsHead(requestMethod) ||
                HttpMethods.IsDelete(requestMethod) ||
                HttpMethods.IsTrace(requestMethod))
            {
                return;
            }
            requestMessage.Content = new StreamContent(context.Request.Body);
        }
예제 #11
0
        /// <summary>
        /// Creates an HttpRequestMessage from the given context and assign the
        /// returned HttpRequestMessage to the given destination.
        /// </summary>
        /// <param name="context">HttpContext to get HttpRequest from.</param>
        /// <param name="destination">Destination of the HttpRequestMessage.</param>
        /// <returns></returns>
        public static HttpRequestMessage CreateProxyHttpRequest(HttpContext context, Uri destination)
        {
            /*
             * Code copied an modified a little from AspNetCore Proxy middleware.
             * https://github.com/aspnet/Proxy/blob/dev/src/Microsoft.AspNetCore.Proxy/ProxyAdvancedExtensions.cs
             */

            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            if (destination == null)
            {
                throw new ArgumentNullException(nameof(destination));
            }

            // Get the request from the HttpContext.
            var request = context.Request;

            // Create an HttpRequestMessage.
            var requestMessage = new HttpRequestMessage();

            // Get request method from the HttpContext.
            var requestMethod = request.Method;

            // Copy content of the request body, if neccesary.
            if (!HttpMethods.IsGet(requestMethod) &&
                !HttpMethods.IsHead(requestMethod) &&
                !HttpMethods.IsDelete(requestMethod) &&
                !HttpMethods.IsTrace(requestMethod))
            {
                var streamContent = new StreamContent(request.Body);
                requestMessage.Content = streamContent;
            }

            // Copy the request headers.
            foreach (var header in request.Headers)
            {
                if (!requestMessage.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray()))
                {
                    requestMessage.Content?.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray());
                }
            }

            // Copy host, request an so on from HttpContext request.
            requestMessage.Headers.Host = destination.Authority;
            requestMessage.RequestUri   = destination;
            requestMessage.Method       = new HttpMethod(request.Method);

            return(requestMessage);
        }
예제 #12
0
        public async Task Invoke(HttpContext context, IRedisManager redisManager)
        {
            try
            {
                var requestMessage = new HttpRequestMessage();
                var requestMethod  = context.Request.Method;

                if (!HttpMethods.IsGet(requestMethod) && !HttpMethods.IsHead(requestMethod) && !HttpMethods.IsDelete(requestMethod) && !HttpMethods.IsTrace(requestMethod))
                {
                    var streamContent = new StreamContent(context.Request.Body);
                    requestMessage.Content = streamContent;
                }

                // All request headers and cookies must be transferend to remote server. Some headers will be skipped
                foreach (var header in context.Request.Headers)
                {
                    if (!requestMessage.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray()) && requestMessage.Content != null)
                    {
                        requestMessage.Content?.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray());
                    }
                }

                string uriString = GetUri(context, redisManager);

                //recreate remote url
                requestMessage.RequestUri = new Uri(uriString);
                requestMessage.Method     = new HttpMethod(context.Request.Method);
                var responseMessage = await redisManager.GetConnection().SendAsync(requestMessage);


                context.Response.StatusCode = (int)responseMessage.StatusCode;
                foreach (var header in responseMessage.Headers)
                {
                    context.Response.Headers[header.Key] = header.Value.ToArray();
                }

                foreach (var header in responseMessage.Content.Headers)
                {
                    context.Response.Headers[header.Key] = header.Value.ToArray();
                }


                //tell to the browser that response is not chunked
                //context.Response.Headers.Remove("transfer-encoding");
                await responseMessage.Content.CopyToAsync(context.Response.Body);
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.Message);
            }
        }
        /// <summary>
        /// Return a corresponding VerbsHttpMethod with the verb used in the request.
        /// </summary>
        /// <param name="context">ActionExecutingContext</param>
        /// <returns>Return VerbsHttpMethod corresponding to the request.</returns>
        public static VerbsHttpMethod GetVerbs(this ActionExecutingContext context)
        {
            var method = context.HttpContext.Request.Method;

            if (HttpMethods.IsGet(method))
            {
                return(VerbsHttpMethod.Get);
            }

            if (HttpMethods.IsPost(method))
            {
                return(VerbsHttpMethod.Post);
            }

            if (HttpMethods.IsDelete(method))
            {
                return(VerbsHttpMethod.Delete);
            }

            if (HttpMethods.IsPut(method))
            {
                return(VerbsHttpMethod.Put);
            }

            if (HttpMethods.IsHead(method))
            {
                return(VerbsHttpMethod.Head);
            }

            if (HttpMethods.IsOptions(method))
            {
                return(VerbsHttpMethod.Options);
            }

            if (HttpMethods.IsPatch(method))
            {
                return(VerbsHttpMethod.Patch);
            }

            if (HttpMethods.IsTrace(method))
            {
                return(VerbsHttpMethod.Trace);
            }

            if (HttpMethods.IsConnect(method))
            {
                return(VerbsHttpMethod.Connect);
            }

            throw new HttpMethodNotFoundException($"Could not find the HttpMethod '{method}'");
        }
예제 #14
0
        private StreamContent GetStreamContent(HttpContext context)
        {
            var requestMethod = context.Request.Method;

            if (HttpMethods.IsGet(requestMethod) ||
                HttpMethods.IsHead(requestMethod) ||
                HttpMethods.IsDelete(requestMethod) ||
                HttpMethods.IsTrace(requestMethod))
            {
                return(null);
            }

            return(new StreamContent(context.Request.Body));
        }
예제 #15
0
        public async Task <HttpResponseMessage> Send(HttpContext httpContext, string url)
        {
            var requestMessage = new HttpRequestMessage();
            var requestMethod  = httpContext.Request.Method;

            if (!HttpMethods.IsGet(requestMethod) &&
                !HttpMethods.IsHead(requestMethod) &&
                !HttpMethods.IsDelete(requestMethod) &&
                !HttpMethods.IsTrace(requestMethod))
            {
                var streamContent = new StreamContent(httpContext.Request.Body);
                requestMessage.Content = streamContent;
            }

            _httpClient.DefaultRequestHeaders.Clear();

            CopyRequestHeaders(
                httpContext.Request.Headers,
                requestMessage.Headers,
                requestMessage.Content?.Headers,
                new HashSet <string>(StringComparer.OrdinalIgnoreCase)
            {
                "host"
            }                                                                    // Use HOST header for backend: it might use it for routing
                );

            requestMessage.RequestUri = new Uri(url);
            requestMessage.Method     = new HttpMethod(requestMethod);

            try
            {
                Console.WriteLine("CALLING: " + url);

                return(await _httpClient.SendAsync(
                           requestMessage,
                           HttpCompletionOption.ResponseHeadersRead,
                           httpContext.RequestAborted));
            }
            catch (HttpRequestException ex)
            {
                if (ex.InnerException?.GetType().Name == "CurlException")
                {
                    var newEx = new HttpRequestException("Error requesting backend URL: " + url, ex);
                    newEx.Data.Add("url", url);
                    throw newEx;
                }

                throw;
            }
        }
예제 #16
0
        /// <summary>
        /// Converts the given HTTP method (usually obtained from <see cref="HttpRequest.Method"/>)
        /// into the corresponding <see cref="HttpMethod"/> static instance.
        /// </summary>
        public static HttpMethod GetHttpMethod(string method)
        {
            if (HttpMethods.IsGet(method))
            {
                return(HttpMethod.Get);
            }

            if (HttpMethods.IsPost(method))
            {
                return(HttpMethod.Post);
            }

            if (HttpMethods.IsPut(method))
            {
                return(HttpMethod.Put);
            }

            if (HttpMethods.IsDelete(method))
            {
                return(HttpMethod.Delete);
            }

            if (HttpMethods.IsOptions(method))
            {
                return(HttpMethod.Options);
            }

            if (HttpMethods.IsHead(method))
            {
                return(HttpMethod.Head);
            }

            if (HttpMethods.IsPatch(method))
            {
                return(HttpMethod.Patch);
            }

            if (HttpMethods.IsTrace(method))
            {
                return(HttpMethod.Trace);
            }

            // NOTE: Proxying "CONNECT" is not supported (by design!)
            //if (HttpMethods.IsConnect(method))
            //{
            //    return new HttpMethod("CONNECT");
            //}

            throw new InvalidOperationException($"Unsupported request method '{method}'.");
        }
예제 #17
0
        private static void SetRequestBody(HttpRequestMessage message, HttpContext ctx)
        {
            var method = ctx.Request.Method;

            if (HttpMethods.IsGet(method) || HttpMethods.IsDelete(method) || HttpMethods.IsHead(method) ||
                HttpMethods.IsOptions(method))
            {
                return;
            }

            var content = new StreamContent(ctx.Request.Body);

            message.Content = content;
        }
예제 #18
0
        private async Task HandleHttpRequest(HttpContext context)
        {
            var requestMessage = new HttpRequestMessage();

            var requestMethod = context.Request.Method;

            if (!HttpMethods.IsGet(requestMethod) &&
                !HttpMethods.IsHead(requestMethod) &&
                !HttpMethods.IsDelete(requestMethod) &&
                !HttpMethods.IsTrace(requestMethod))
            {
                requestMessage.Content = new StreamContent(context.Request.Body);
            }

            foreach (var header in context.Request.Headers)
            {
                if (!requestMessage.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray()) && requestMessage.Content != null)
                {
                    requestMessage.Content?.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray());
                }
            }
            requestMessage.Headers.Host = this.options.Host + ":" + this.options.Port;

            var uriString = $"{this.options.Scheme}://{this.options.Host}:{this.options.Port}{context.Request.PathBase}{context.Request.Path}{context.Request.QueryString}";

            requestMessage.RequestUri = new Uri(uriString);
            requestMessage.Method     = new HttpMethod(context.Request.Method);

            var responseMessage = await this.httpClient.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead, context.RequestAborted);

            using (responseMessage)
            {
                context.Response.StatusCode = (int)responseMessage.StatusCode;

                var responseHeaders = responseMessage.Headers.Concat(responseMessage.Content.Headers);
                foreach (var header in responseHeaders)
                {
                    context.Response.Headers[header.Key] = header.Value.ToArray();
                }

                // SendAsync removes chunking from the response. This removes the header so it doesn't expect a chunked response.
                context.Response.Headers.Remove(HeaderNames.TransferEncoding);

                if (context.Response.StatusCode != StatusCodes.Status304NotModified)
                {
                    await responseMessage.Content.CopyToAsync(context.Response.Body);
                }
            }
        }
        public async Task Invoke(HttpContext context)
        {
            if (!HttpMethods.IsHead(context.Request.Method))
            {
                await _next.Invoke(context);

                return;
            }

            context.Request.Method = HttpMethods.Get;
            context.Response.Body  = Stream.Null;

            await _next.Invoke(context);

            context.Request.Method = HttpMethods.Head;
        }
예제 #20
0
        private static bool ValidateMethod(HttpContext context)
        {
            var method  = context.Request.Method;
            var isValid = false;

            if (HttpMethods.IsGet(method))
            {
                isValid = true;
            }
            else if (HttpMethods.IsHead(method))
            {
                isValid = true;
            }

            return(isValid);
        }
예제 #21
0
        private static (RangeItemHeaderValue?range, long rangeLength, bool serveBody) SetRangeHeaders(
            HttpContext httpContext,
            RequestHeaders httpRequestHeaders,
            long fileLength,
            ILogger logger)
        {
            var response            = httpContext.Response;
            var httpResponseHeaders = response.GetTypedHeaders();
            var serveBody           = !HttpMethods.IsHead(httpContext.Request.Method);

            // Range may be null for empty range header, invalid ranges, parsing errors, multiple ranges
            // and when the file length is zero.
            var(isRangeRequest, range) = RangeHelper.ParseRange(
                httpContext,
                httpRequestHeaders,
                fileLength,
                logger);

            if (!isRangeRequest)
            {
                return(range : null, rangeLength : 0, serveBody);
            }

            // Requested range is not satisfiable
            if (range == null)
            {
                // 14.16 Content-Range - A server sending a response with status code 416 (Requested range not satisfiable)
                // SHOULD include a Content-Range field with a byte-range-resp-spec of "*". The instance-length specifies
                // the current length of the selected resource.  e.g. */length
                response.StatusCode = StatusCodes.Status416RangeNotSatisfiable;
                httpResponseHeaders.ContentRange = new ContentRangeHeaderValue(fileLength);
                response.ContentLength           = 0;

                return(range : null, rangeLength : 0, serveBody : false);
            }

            response.StatusCode = StatusCodes.Status206PartialContent;
            httpResponseHeaders.ContentRange = new ContentRangeHeaderValue(
                range.From !.Value,
                range.To !.Value,
                fileLength);

            // Overwrite the Content-Length header for valid range requests with the range length.
            var rangeLength = SetContentLength(response, range);

            return(range, rangeLength, serveBody);
        }
예제 #22
0
        /// <summary>
        /// This middleware transforms incoming Http HEAD request
        /// internally to Http GET and ensures that a null stream is
        /// being sent back.
        /// </summary>
        public async Task Invoke(HttpContext context)
        {
            var isHead = HttpMethods.IsHead(context.Request.Method);

            if (isHead)
            {
                context.Request.Method = HttpMethods.Get;
                context.Response.Body  = Stream.Null;
            }

            await _next(context);

            if (isHead)
            {
                context.Request.Method = HttpMethods.Head;
            }
        }
예제 #23
0
        private static bool ValidateMethod(HttpContext context)
        {
            string method = context.Request.Method;

            bool flag = false;

            if (HttpMethods.IsGet(method))
            {
                flag = true;
            }
            else if (HttpMethods.IsHead(method))
            {
                flag = true;
            }

            return(flag);
        }
예제 #24
0
        public static async Task HandleHttpRequestX(HttpContext context, string uriString)
        {
            var _httpClient    = new HttpClient(new HttpClientHandler());
            var requestMessage = new HttpRequestMessage();
            var requestMethod  = context.Request.Method;

            if (!HttpMethods.IsGet(requestMethod) &&
                !HttpMethods.IsHead(requestMethod) &&
                !HttpMethods.IsDelete(requestMethod) &&
                !HttpMethods.IsTrace(requestMethod))
            {
                var streamContent = new StreamContent(context.Request.Body);
                requestMessage.Content = streamContent;
            }

            // Copy the request headers
            foreach (var header in context.Request.Headers)
            {
                if (!requestMessage.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray()) && requestMessage.Content != null)
                {
                    requestMessage.Content?.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray());
                }
            }

            requestMessage.RequestUri   = new Uri(uriString);
            requestMessage.Headers.Host = $"{requestMessage.RequestUri.Host}:{requestMessage.RequestUri.Port}";

            requestMessage.Method = new HttpMethod(context.Request.Method);
            using (var responseMessage = await _httpClient.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead, context.RequestAborted))
            {
                context.Response.StatusCode = (int)responseMessage.StatusCode;
                foreach (var header in responseMessage.Headers)
                {
                    context.Response.Headers[header.Key] = header.Value.ToArray();
                }

                foreach (var header in responseMessage.Content.Headers)
                {
                    context.Response.Headers[header.Key] = header.Value.ToArray();
                }

                // SendAsync removes chunking from the response. This removes the header so it doesn't expect a chunked response.
                context.Response.Headers.Remove("transfer-encoding");
                await responseMessage.Content.CopyToAsync(context.Response.Body);
            }
        }
예제 #25
0
        public static string ReadRequestBodyAsString(this HttpRequest request)
        {
            string requestBodyAsText = "";

            if (!HttpMethods.IsGet(request.Method) &&
                !HttpMethods.IsHead(request.Method) &&
                !HttpMethods.IsDelete(request.Method) &&
                !HttpMethods.IsTrace(request.Method) &&
                request.ContentLength > 0)
            {
                using (var reader = new StreamReader(request.Body))
                {
                    requestBodyAsText = reader.ReadToEnd();
                }
            }
            return(requestBodyAsText);
        }
예제 #26
0
        private void CopyOriginalReqContent(HttpRequest req, HttpRequestMessage requestMessage)
        {
            if (!HttpMethods.IsGet(req.Method) &&
                !HttpMethods.IsHead(req.Method) &&
                !HttpMethods.IsDelete(req.Method))
            {
                // here is is a method with a BODY
                var streamContent = new StreamContent(req.Body);
                requestMessage.Content = streamContent;
            }

            // copy headers
            foreach (var header in req.Headers)
            {
                requestMessage.Content?.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray());
            }
        }
예제 #27
0
        private bool SetupContent(object content, string contentMediaType, bool contentAsJson, bool contentUseCamelCase, HttpRequest request, HttpRequestMessage requestMessage, string requestMethod)
        {
            if (!HttpMethods.IsGet(requestMethod) && !HttpMethods.IsHead(requestMethod) && !HttpMethods.IsDelete(requestMethod) && !HttpMethods.IsTrace(requestMethod))
            {
                if (request.HasFormContentType)
                {
                    var dataToSend = content != null ? content as IFormCollection : request.Form;
                    requestMessage.Content = ToHttpContent(dataToSend, request.ContentType);
                    return(false);
                }
                else
                {
                    requestMessage.Content = content != null?CreateHttpContent(content, contentMediaType, contentAsJson, contentUseCamelCase) : new StreamContent(request.Body);
                }
            }

            return(true);
        }
예제 #28
0
        private static void SetProxyRequestBody(HttpRequestMessage requestMessage, HttpContext context)
        {
            var requestMethod = context.Request.Method;

            if (HttpMethods.IsGet(requestMethod) ||
                HttpMethods.IsHead(requestMethod) ||
                HttpMethods.IsDelete(requestMethod) ||
                HttpMethods.IsTrace(requestMethod))
            {
                return;
            }
            // We need to copy the stream to not get exceptions
            var memStr = new System.IO.MemoryStream();

            context.Request.Body.CopyTo(memStr);
            memStr.Position        = 0;
            requestMessage.Content = new StreamContent(memStr);
        }
예제 #29
0
        private void CopyFromOriginalRequestContentAndHeaders(HttpContext context, HttpRequestMessage requestMessage)
        {
            var requestMethod = context.Request.Method;

            if (!HttpMethods.IsGet(requestMethod) &&
                !HttpMethods.IsHead(requestMethod) &&
                !HttpMethods.IsDelete(requestMethod) &&
                !HttpMethods.IsTrace(requestMethod))
            {
                var streamContent = new StreamContent(context.Request.Body);
                requestMessage.Content = streamContent;
            }

            foreach (var header in context.Request.Headers)
            {
                requestMessage.Content?.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray());
            }
        }
예제 #30
0
        private static HttpRequestMessage CreateProxyHttpRequest(this HttpRequest request)
        {
            var requestMessage = new HttpRequestMessage();
            var requestMethod  = request.Method;

            if (!HttpMethods.IsGet(requestMethod) &&
                !HttpMethods.IsHead(requestMethod) &&
                !HttpMethods.IsDelete(requestMethod) &&
                !HttpMethods.IsTrace(requestMethod))
            {
                var streamContent = new StreamContent(request.Body);
                requestMessage.Content = streamContent;
            }

            // Copy the request headers *except* x-forwarded-* headers.
            foreach (var header in request.Headers)
            {
                if (header.Key.StartsWith("X-Forwarded-", StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }
                if (!requestMessage.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray()))
                {
                    requestMessage.Content?.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray());
                }
            }

            // HACK: Attempting to send a malformed User-Agent will throw from with HttpClient
            // Remove when .net core 3 is released. Consider supporting netcoreapp2.x with #ifdef
            // https://github.com/damianh/ProxyKit/issues/53
            // https://github.com/dotnet/corefx/issues/34933
            try
            {
                requestMessage.Headers.TryGetValues("User-Agent", out var _);
            }
            catch (IndexOutOfRangeException)
            {
                requestMessage.Headers.Remove("User-Agent");
            }

            requestMessage.Method = new HttpMethod(request.Method);

            return(requestMessage);
        }