private async Task <HttpResponseMessage> ExecuteServiceCallAsync(HttpCommunicationClient client, HttpContext context, byte[] contextRequestBody)
        {
            // We don't throw because this would result in a retry loop.
            if (context.RequestAborted.IsCancellationRequested)
            {
                return(null);
            }

            // create request and copy all details

            HttpRequestMessage req = new HttpRequestMessage
            {
                Method     = new HttpMethod(context.Request.Method),
                RequestUri = new Uri(context.Request.Path + context.Request.QueryString, UriKind.Relative)
            };

            if (contextRequestBody != null)
            {
                req.Content = new ByteArrayContent(contextRequestBody);
            }

            req.CopyHeadersFromCurrentContext(context);
            req.AddProxyHeaders(context);

            // execute request

            HttpResponseMessage response;

            try
            {
                response = await client.SendAsync(req, context.RequestAborted, _gatewayOptions.ShouldForwardCookies);
            }
            catch (OperationCanceledException) when(context.RequestAborted.IsCancellationRequested)
            {
                // We don't have to retry if the client is no longer connected.
                return(null);
            }

            // cases in which we want to invoke the retry logic from the ClientFactory

            InvokeRetryIfNecessary(response);

            return(response);
        }
        private async Task <HttpResponseMessage> ExecuteServiceCallAsync(HttpCommunicationClient httpClient, HttpContext context, ServiceProviderInfomation options)
        {
            var requestMessage = new HttpRequestMessage();

            //
            // Copy the request method
            //
            requestMessage.Method = new HttpMethod(context.Request.Method);

            //
            // Copy the request content
            //
            if (!StringComparer.OrdinalIgnoreCase.Equals(context.Request.Method, "GET") &&
                !StringComparer.OrdinalIgnoreCase.Equals(context.Request.Method, "HEAD") &&
                !StringComparer.OrdinalIgnoreCase.Equals(context.Request.Method, "DELETE") &&
                !StringComparer.OrdinalIgnoreCase.Equals(context.Request.Method, "TRACE"))
            {
                requestMessage.Content = new StreamContent(context.Request.Body);
            }


            requestMessage.CopyHeadersFromCurrentContext(context);
            requestMessage.AddProxyHeaders(context);

            //
            // Construct the request URL
            //
            var baseAddress = httpClient.BaseAddress;

            // Sticky Sessions
            string value;

            context.Request.Cookies.TryGetValue("SERVER-SF", out value);
            if (options.StickySession && !string.IsNullOrEmpty(value))
            {
                baseAddress = new Uri(value);
            }


            var pathAndQuery = PathString.FromUriComponent(baseAddress) + context.Request.Path + context.Request.QueryString;

            requestMessage.RequestUri = new Uri($"{baseAddress.Scheme}://{baseAddress.Host}:{baseAddress.Port}{pathAndQuery}", UriKind.Absolute);



            //
            // Send request and copy the result back to HttpResponse
            //
            var responseMessage = await httpClient.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead, context.RequestAborted);

            //
            // If the service is temporarily unavailable, throw to retry later.
            //
            if (responseMessage.StatusCode == HttpStatusCode.ServiceUnavailable)
            {
                responseMessage.EnsureSuccessStatusCode();
            }

            // cases in which we want to invoke the retry logic from the ClientFactory
            int statusCode = (int)responseMessage.StatusCode;

            if ((statusCode >= 500 && statusCode < 600) || statusCode == (int)HttpStatusCode.NotFound)
            {
                throw new SimpleHttpResponseException(responseMessage.StatusCode, "Service call failed");
            }

            if (options.StickySession && string.IsNullOrEmpty(value))
            {
                context.Response.Cookies.Append("SERVER-SF", baseAddress.AbsoluteUri);
            }

            return(responseMessage);
        }