예제 #1
0
 public void OnRequest(HttpRequestHead head, 
   IDataProducer body, 
   IHttpResponseDelegate response)
 {
   if (head.Method.ToUpperInvariant() == "POST")
   {
     ProcessPOSTRequest(body, response);
   }
   else if (head.Method.ToUpperInvariant() == "GET" && head.Uri == "/crossdomain.xml")
   {
     ProcessCrossDomainRequest(body, response);
   }
   else if (head.Method.ToUpperInvariant() == "GET" && head.QueryString.Contains("metrics"))
   {
     ProcessGETRequest(body, head, response);
   }
   else if (head.Method.ToUpperInvariant() == "GET" && head.Uri == "/")
   {
     ProcessLoadBalancerRequest(body, response);
   }
   else
   {
     ProcessFileNotFound(body, response);
   }
 }
예제 #2
0
        public void OnRequest(HttpRequestHead head, IDataProducer body, IHttpResponseDelegate response)
        {
            var env = new Environment();

            if (context != null)
                foreach (var kv in context)
                    env[kv.Key] = kv.Value;

            env.Headers = head.Headers ?? new Dictionary<string, string>();
            env.Method = head.Method ?? "";
            env.Path = head.Path ?? "";
            env.PathBase = "";
            env.QueryString = head.QueryString ?? "";
            env.Scheme = "http"; // XXX
            env.Version = "1.0";

            if (body == null)
                env.Body = null;
            else
                env.Body = (onData, onError, onEnd) =>
                {
                    var d = body.Connect(new DataConsumer(onData, onError, onEnd));
                    return () => { if (d != null) d.Dispose(); };
                };

            appDelegate(env, HandleResponse(response), HandleError(response));
        }
예제 #3
0
 public static void AssertAreEqual(TestRequest expected, HttpRequestHead actual)
 {
     Assert.AreEqual(expected.Method, actual.Method, "Unexpected method.");
     Assert.AreEqual(expected.Uri, actual.Uri, "Unexpected URI.");
     Assert.AreEqual(expected.Version, actual.Version, "Unexpected version.");
     AssertHeaders(expected.Headers, actual.Headers);
 }
        public void OnRequest(HttpRequestHead request, IDataProducer requestBody, IHttpResponseDelegate response)
        {
            if (request.Uri.StartsWith("/feed.xml"))
            {
                var body = new FeedBuilder(Port).Generate(FeedTitle, FilePaths, ImagePath);

                var headers = new HttpResponseHead()
                                  {
                                      Status = "200 OK",
                                      Headers = new Dictionary<string, string>()
                                                    {
                                                        { "Content-Type", "text/plain" },
                                                        { "Content-Length", body.Length.ToString() },
                                                    }
                                  };

                response.OnResponse(headers, new SimpleProducer(body));
                return;
            }

            // deal with request for file content
            string uri = request.Uri.Replace("%20", " ").Replace("/", "\\");
            string filePath = FilePaths.Where(d => d.Contains(uri)).FirstOrDefault();

            if (filePath != null)
            {
                FileInfo fi = new FileInfo(filePath);
                string mimeType = GetMimeType(filePath);

                var headers = new HttpResponseHead()
                                  {
                                      Status = "200 OK",
                                      Headers = new Dictionary<string, string>()
                                                    {
                                                        { "Content-Type", mimeType },
                                                        { "Content-Length", fi.Length.ToString() },
                                                    }
                                  };

                response.OnResponse(headers, new FileProducer(filePath));
                return;
            }
            else
            {
                var responseBody = "The resource you requested ('" + request.Uri + "') could not be found.";
                var headers = new HttpResponseHead()
                                  {
                                      Status = "404 Not Found",
                                      Headers = new Dictionary<string, string>()
                                                    {
                                                        { "Content-Type", "text/plain" },
                                                        { "Content-Length", responseBody.Length.ToString() }
                                                    }
                                  };
                var body = new SimpleProducer(responseBody);

                response.OnResponse(headers, body);
                return;
            }
        }
예제 #5
0
        private void RequestReadCompleted(HttpRequestHead head, Stream requestStream, IHttpResponseDelegate response)
        {
            Uri baseUri = new Uri("http://localhost/");
            Uri requestUrl = new Uri(baseUri, head.Uri);
            Url nancyUrl = new Url
            {
                Scheme = requestUrl.Scheme,
                HostName = requestUrl.Host,
                Port = requestUrl.IsDefaultPort ? null : (int?)requestUrl.Port,
                BasePath = baseUri.AbsolutePath.TrimEnd('/'),
                Path = HttpUtility.UrlDecode(head.Uri),
                Query = requestUrl.Query,
                Fragment = requestUrl.Fragment,
            };
            Dictionary<string, IEnumerable<string>> headers = new Dictionary<string, IEnumerable<string>>();
            foreach (var kvp in head.Headers)
                headers[kvp.Key] = new List<string> { kvp.Value };

            Request req = new Request(
                head.Method,
                nancyUrl,
                Nancy.IO.RequestStream.FromStream(requestStream, requestStream.Length),
                headers,
                null);

            m_Engine.HandleRequest(req, context => RequestProcessingCompleted(context, response), ex => RequestProcessingError(ex, response));
        }
예제 #6
0
        public void OnRequest(HttpRequestHead head, IDataProducer body, IHttpResponseDelegate response)
        {
            var env = new Dictionary<string, object>();
            var request = new RequestEnvironment(env);

            if (context != null)
                foreach (var kv in context)
                    env[kv.Key] = kv.Value;

            if (head.Headers == null)
                request.Headers = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase);
            else
                request.Headers = head.Headers.ToDictionary(kv => kv.Key, kv => new[] { kv.Value }, StringComparer.OrdinalIgnoreCase);

            request.Method = head.Method ?? "";
            request.Path = head.Path ?? "";
            request.PathBase = "";
            request.QueryString = head.QueryString ?? "";
            request.Scheme = "http"; // XXX
            request.Version = "1.0";

            if (body == null)
                request.BodyDelegate = null;
            else
                request.BodyDelegate = (write, end, cancellationToken) =>
                {
                    var d = body.Connect(new DataConsumer(
                        write,
                        end,
                        () => end(null)));
                    cancellationToken.Register(d.Dispose);
                };

            appDelegate(env, HandleResponse(response), HandleError(response));
        }
예제 #7
0
        public IRequestHandler Match(HttpRequestHead request, IEnumerable<IRequestHandler> requestHandlerList)
        {
            var matches = requestHandlerList
                .Where(handler => _matchingRule.IsEndpointMatch(handler, request))
                .Where(handler => handler.CanVerifyConstraintsFor(request.Uri));

            return matches.FirstOrDefault();
        }
 public IHttpResponseDelegateInternal Create(HttpRequestHead requestHead, bool shouldKeepAlive, Action end)
 {
     // XXX freelist
     return(new HttpResponseDelegate(
                prohibitBody: requestHead.Method.ToUpperInvariant() == "HEAD",
                shouldKeepAlive: shouldKeepAlive,
                closeConnection: end));
 }
 public IHttpResponseDelegateInternal Create(HttpRequestHead requestHead, bool shouldKeepAlive, Action end)
 {
     // XXX freelist
     return new IosHttpResponseDelegate(
            prohibitBody: requestHead.Method.ToUpperInvariant() == "HEAD",
            shouldKeepAlive: shouldKeepAlive,
            closeConnection: end);
 }
예제 #10
0
        private static void TurnOnElement(HttpRequestHead request, IHttpResponseDelegate response)
        {
            var status = new Status();
            NameValueCollection parms = GetParameters(request);

            if (!parms.HasKeys() && parms["id"] != null && parms["time"] != null && parms["color"]!=null)
            {
                HttpResponseHead headers = GetHeaders(0, HttpStatusCode.BadRequest.ToString());
                response.OnResponse(headers, new BufferedProducer(""));
                return;
            }

            if (parms["color"].Length != 7 || !parms["color"].StartsWith("#"))
            {
                status.Message = "Invalid color. Must be Hex.";
                SerializeResponse(status,response);
                return;
            }

            Guid elementId = Guid.Empty;
            bool allElements = false;
            int seconds;

            if ("all".Equals(parms["id"]))
            {
                allElements = true;
            } else
            {
                Guid.TryParse(parms["id"], out elementId);
            }
            if (!int.TryParse(parms["time"], out seconds))
            {
                status.Message = "Time must be numeric.";
                SerializeResponse(status,response);
                return;
            }

            Color elementColor = ColorTranslator.FromHtml(parms["color"]);

            //TODO the following logic for all does not properly deal with discrete color elements when turning all on
            //TODO they will not respond to turning on white if they are set up with a filter.
            //TODO enhance this to figure out what colors there are and turn them all on when we are turning all elements on.

            var effect = new SetLevel
            {
                TimeSpan = TimeSpan.FromSeconds(seconds),
                Color = elementColor,
                IntensityLevel = 1,
                TargetNodes =
                    allElements ? VixenSystem.Nodes.GetRootNodes().ToArray() : new[] {VixenSystem.Nodes.GetElementNode(elementId)}
            };

            Module.LiveSystemContext.Execute(new EffectNode(effect, TimeSpan.Zero));
            status.Message = string.Format("{0} element(s) turned on for {1} seconds at 100% intensity.",
                allElements?"All":VixenSystem.Nodes.GetElementNode(elementId).Name, seconds);

            SerializeResponse(status,response);
        }
예제 #11
0
 bool ShouldKeepAlive(HttpRequestHead head)
 {
     if (head.Version.Major > 0 && head.Version.Minor > 0)
         // HTTP/1.1
         return !(head.Headers.ContainsKey("connection") && head.Headers["connection"] == "close");
     else
         // < HTTP/1.1
         return (head.Headers.ContainsKey("connection") && head.Headers["connection"] == "keep-alive");
 }
예제 #12
0
 public void urls_and_methods_differ_it_returns_false()
 {
     var requestHandler = MockRepository.GenerateStub<IRequestHandler>();
     requestHandler.Path = "test";
     requestHandler.Method = "GET";
     requestHandler.QueryParams = new Dictionary<string, string>();
     var httpRequestHead = new HttpRequestHead { Uri = "test", Method = "PUT" };
     var endpointMatchingRule = new EndpointMatchingRule();
     Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandler, httpRequestHead), Is.False);
 }
 public void OnRequest(HttpRequestHead request, bool shouldKeepAlive)
 {
     _realDelegate.OnRequest(request, shouldKeepAlive);
     if (request.Uri.StartsWith("/reverse"))
     {
         _isTwoWay = true;
         if (_connectionWatcher != null)
             _connectionWatcher.TwoWaySocketAvailable(_socket);
     }
 }
예제 #14
0
 public void SendRequestToDevice(System.Collections.IDictionary plistBody)
 {
     HttpRequestHead head = new HttpRequestHead();
     head.Headers = new Dictionary<string, string>();
     head.Method="POST";
     head.Path="/event";
     head.Version=new Version(1,1);
     var requestBytes=ResponseMessageHelper.GetBytes(head, plistBody);
     this.scheduler.Post(() => SendRequest(requestBytes));           
 }
예제 #15
0
        private void GetSequences(HttpRequestHead request, IHttpResponseDelegate response)
        {
            var sequenceNames = SequenceService.Instance.GetAllSequenceFileNames().Select(Path.GetFileName);
            var sequences = sequenceNames.Select(sequenceName => new Sequence
            {
                Name = Path.GetFileNameWithoutExtension(sequenceName), FileName = sequenceName
            }).ToList();

            SerializeResponse(sequences,response);
        }
예제 #16
0
 public override void ProcessPost(HttpRequestHead request, IDataProducer requestBody, IHttpResponseDelegate response)
 {
     //Figure out how to get the post params from within Kayak so some of these operations that
     //should be a post can be. Right now I am limited to just post based on verbs on the url.
     if (request.Uri.StartsWith("/api/play/stopSequence"))
     {
         StopSequence(request, response);
         return;
     }
     UnsupportedOperation(request,response);
 }
예제 #17
0
        public void urls_and_methods_match_and_queryparams_does_not_exist_it_returns_false()
        {
            var requestHandler = MockRepository.GenerateStub<IRequestHandler>();
            requestHandler.Path = "test";
            requestHandler.Method = "GET";
            requestHandler.QueryParams = new Dictionary<string, string> { { "myParam", "one" } };

            var httpRequestHead = new HttpRequestHead { Uri = "test?oauth_consumer_key=test-api&elvis=alive&moonlandings=faked", Method = "GET" };
            var endpointMatchingRule = new EndpointMatchingRule();
            Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandler, httpRequestHead), Is.False);
        }
예제 #18
0
        public void Matching_HEAD_handler_should_output_handlers_expected_response_with_null_body()
        {
            _processor = new RequestProcessor(_ruleThatReturnsFirstHandler, new RequestHandlerList());

            RequestHandler requestHandler = _requestHandlerFactory.Head("test");
            _processor.Add(requestHandler);
            var httpRequestHead = new HttpRequestHead { Method = "HEAD", Headers = new Dictionary<string, string>() };
            _processor.OnRequest(httpRequestHead, _dataProducer, _httpResponseDelegate);

            _httpResponseDelegate.AssertWasCalled(x => x.OnResponse(requestHandler.ResponseBuilder.BuildHeaders(), null));
        }
예제 #19
0
 private static bool MatchPath(IRequestHandler requestHandler, HttpRequestHead request)
 {
     var pathToMatch = request.Uri;
     int positionOfQueryStart = GetStartOfQueryString(request.Uri);
     if (positionOfQueryStart > -1)
     {
         pathToMatch = request.Uri.Substring(0, positionOfQueryStart);
     }
     var pathMatch = new Regex(string.Format(@"^{0}\/*$", requestHandler.Path));
     return pathMatch.IsMatch(pathToMatch);
 }
예제 #20
0
        private static Dictionary<string, string> GetQueryParams(HttpRequestHead request)
        {
            int positionOfQueryStart = request.Uri.LastIndexOf('?');
            if(positionOfQueryStart < 1)
                return new Dictionary<string, string>();

            string queryString = request.Uri.Substring(positionOfQueryStart);
            NameValueCollection valueCollection = HttpUtility.ParseQueryString(queryString);
            var requestQueryParams = valueCollection.AllKeys.ToDictionary(k => k, k => valueCollection[k]);
            return requestQueryParams;
        }
예제 #21
0
        public void should_do_a_case_insensitive_match_on_query_string_parameter_values()
        {
            var requestHandler = MockRepository.GenerateStub<IRequestHandler>();
            requestHandler.Path = "test";
            requestHandler.Method = "GET";
            requestHandler.QueryParams = new Dictionary<string, string> { { "myParam", "one" } };

            var httpRequestHead = new HttpRequestHead { Uri = "test?myParam=OnE", Method = "GET" };

            var endpointMatchingRule = new EndpointMatchingRule();
            Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandler, httpRequestHead));
        }
        public void should_match_when_the_query_string_has_a_trailing_ampersand()
        {
            var requestHandler = MockRepository.GenerateStub<IRequestHandler>();
            requestHandler.Path = "test";
            requestHandler.Method = "GET";
            requestHandler.QueryParams = new Dictionary<string, string> { { "a", "b" } ,{"c","d"}};

            var httpRequestHead = new HttpRequestHead { Uri = "test?a=b&c=d&", Method = "GET" };

            var endpointMatchingRule = new EndpointMatchingRule();
            Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandler, httpRequestHead));
        }
예제 #23
0
        public void urls_and_methods_and_queryparams_match_it_returns_true()
        {
            var requestHandler = MockRepository.GenerateStub<IRequestHandler>();
            requestHandler.Path = "test";
            requestHandler.Method = "GET";
            requestHandler.QueryParams = new Dictionary<string, string>{{"myParam", "one"}};

            var httpRequestHead = new HttpRequestHead { Uri = "test?myParam=one", Method = "GET" };

            var endpointMatchingRule = new EndpointMatchingRule();
            Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandler, httpRequestHead));
        }
예제 #24
0
 internal static HttpRequestHead UnsupportedOperation(HttpRequestHead request, IHttpResponseDelegate response)
 {
     var serializer = new JavaScriptSerializer();
     string json = serializer.Serialize(new Status
     {
         Message = "Unknown request"
     });
     HttpResponseHead headers = GetOkHeaders(json.Length);
     headers.Status = HttpStatusCode.BadRequest.ToString();
     response.OnResponse(headers, new BufferedProducer(json));
     return request;
 }
예제 #25
0
        public void urls_and_methods_match_and_no_query_params_are_set_but_request_has_query_params_returns_true()
        {
            var requestHandler = MockRepository.GenerateStub<IRequestHandler>();
            requestHandler.Path = "test";
            requestHandler.Method = "GET";
            requestHandler.QueryParams = new Dictionary<string, string> ();

            var httpRequestHead = new HttpRequestHead { Uri = "test?oauth_consumer_key=test-api&elvis=alive&moonlandings=faked", Method = "GET" };
            var endpointMatchingRule = new EndpointMatchingRule();

            Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandler, httpRequestHead), Is.True);
        }
예제 #26
0
        public void OnRequest(HttpRequestHead request, bool shouldKeepAlive)
        {
            var responseDelegate = responseDelegateFactory.Create(request, shouldKeepAlive, CloseConnection);

            DataSubject subject = null;
            bool        requestBodyConnected = false;

            Debug.WriteLine("[{0}] {1} {2} shouldKeepAlive = {3}",
                            DateTime.Now, request.Method, request.Uri, shouldKeepAlive);

            if (request.HasBody())
            {
                subject = new DataSubject(() =>
                {
                    if (requestBodyConnected)
                    {
                        throw new InvalidOperationException("Request body was already connected.");
                    }

                    requestBodyConnected = true;

                    if (request.IsContinueExpected())
                    {
                        responseDelegate.WriteContinue();
                    }

                    return(new Disposable(() =>
                    {
                        // XXX what to do?
                        // ideally we stop reading from the socket.
                        // equivalent to a parse error
                    }));
                });
            }

            requestBody = subject;

            if (remoteAddress != null)
            {
                if (request.Headers.ContainsKey("X-Forwarded-For"))
                {
                    request.Headers["X-Forwarded-For"] += "," + remoteAddress.ToString();
                }
                else
                {
                    request.Headers["X-Forwarded-For"] = remoteAddress.ToString();
                }
            }

            requestDelegate.OnRequest(request, subject, responseDelegate);
            observer.OnNext(responseDelegate);
        }
예제 #27
0
        private static Dictionary<string, string> GetQueryParams(HttpRequestHead request)
        {
            int positionOfQueryStart = GetStartOfQueryString(request.Uri);
            if(positionOfQueryStart < 1)
                return new Dictionary<string, string>();

            string queryString = request.Uri.Substring(positionOfQueryStart);
            NameValueCollection valueCollection = HttpUtility.ParseQueryString(queryString);
            var requestQueryParams = valueCollection.AllKeys
                .Where(k => !string.IsNullOrEmpty(k))
                .ToDictionary(k => k, k => valueCollection[k]);
            return requestQueryParams;
        }
예제 #28
0
 void AddXFF(HttpRequestHead request, IPEndPoint remoteEndPoint)
 {
     if (remoteEndPoint != null)
     {
         if (request.Headers.ContainsKey("X-Forwarded-For"))
         {
             request.Headers["X-Forwarded-For"] += "," + remoteEndPoint.Address.ToString();
         }
         else
         {
             request.Headers["X-Forwarded-For"] = remoteEndPoint.Address.ToString();
         }
     }
 }
 void AddXFF(HttpRequestHead request, IPEndPoint remoteEndPoint)
 {
     if (remoteEndPoint != null && request.Headers != null)
     {
         if (request.Headers.ContainsKey("X-Forwarded-For"))
         {
             request.Headers["X-Forwarded-For"] += "," + remoteEndPoint.Address.ToString();
         }
         else
         {
             request.Headers["X-Forwarded-For"] = remoteEndPoint.Address.ToString();
         }
     }
 }
예제 #30
0
        public void Handle(string appname, string[] components, HttpRequestHead head, IDataProducer body, IHttpResponseDelegate response)
        {
            // Look inside the cache for the specified file.
            Cache c = new Cache(false);
            string path = HttpUtility.UrlDecode(components.Where((value, row) => row >= 2).Aggregate((a, b) => a + "/" + b));
            if (!c.Exists("server/" + appname + "/store/" + path))
            {
                response.OnResponse(HttpErrorResponseHead.Get(), new HttpErrorDataProducer());
                return;
            }

            // Calculate patch path from source to destination.
            string result = "";
            Hash source = Hash.FromString(components[0]);
            Hash destination = Hash.FromString(components[1]);

            while (source != destination)
            {
                // Find the patch in the patches that will turn source
                // into the next patch.
                IEnumerable<string> patches = c.List("server/" + appname + "/patches/" + path).Where(v => v.StartsWith(source.ToString() + "-"));
                if (patches.Count() != 1)
                {
                    response.OnResponse(HttpErrorResponseHead.Get(), new HttpErrorDataProducer());
                    return;
                }
                string next = patches.First();
                source = Hash.FromString(next.Substring((source.ToString() + "-").Length));
                using (StreamReader reader = new StreamReader(c.GetFilePath("server/" + appname + "/patches/" + path + "/" + next)))
                {
                    result += "--- NEXT PATCH (" + reader.BaseStream.Length + ") ---\r\n";
                    result += reader.ReadToEnd();
                    result += "\r\n";
                }
            }
            result += "--- END OF PATCHES ---\r\n";

            // Return data.
            response.OnResponse(new HttpResponseHead()
            {
                Status = "200 OK",
                Headers = new Dictionary<string, string>
                    {
                        { "Content-Type", "text/plain" },
                        { "Content-Length", result.Length.ToString() },
                        { "Connection", "close" }
                    }
            }, new BufferedProducer(result));
        }
        public void OnRequest(IHttpServerTransaction transaction, HttpRequestHead request, bool shouldKeepAlive)
        {
            AddXFF(request, transaction.RemoteEndPoint);

            var expectContinue = request.IsContinueExpected();
            var ignoreResponseBody = request.Method != null && request.Method.ToUpperInvariant() == "HEAD";

            currentContext = new TransactionContext(expectContinue, ignoreResponseBody, shouldKeepAlive);

            if (lastSegment == null)
                currentContext.Segment.AttachTransaction(transaction);

            QueueSegment(currentContext.Segment);
            requestDelegate.OnRequest(request, currentContext.RequestBody, currentContext);
        }
        public void OnRequest(HttpRequestHead request, bool shouldKeepAlive)
        {
            var responseDelegate = responseDelegateFactory.Create(request, shouldKeepAlive, CloseConnection);

            DataSubject subject = null;
            bool requestBodyConnected = false;

            Debug.WriteLine("[{0}] {1} {2} shouldKeepAlive = {3}",
                DateTime.Now, request.Method, request.Uri, shouldKeepAlive);

            if (request.HasBody())
            {
                subject = new DataSubject(() =>
                {
                    if (requestBodyConnected) 
                        throw new InvalidOperationException("Request body was already connected.");

                    requestBodyConnected = true;

                    if (request.IsContinueExpected())
                        responseDelegate.WriteContinue();

                    return new Disposable(() =>
                    {
                        // XXX what to do?
                        // ideally we stop reading from the socket. 
                        // equivalent to a parse error
                    });
                });
            }

            requestBody = subject;

            if (remoteAddress != null)
            {
                if (request.Headers.ContainsKey("X-Forwarded-For"))
                {
                    request.Headers["X-Forwarded-For"] += "," + remoteAddress.ToString();
                }
                else
                {
                    request.Headers["X-Forwarded-For"] = remoteAddress.ToString();
                }
            }

            requestDelegate.OnRequest(request, subject, responseDelegate);
            observer.OnNext(responseDelegate);
        }
예제 #33
0
        private static void ApiGet(HttpRequestHead request, IHttpResponseDelegate response)
        {
            const string pattern = @"^/api/([A-Za-z]+)/.*$";
            Match match = Regex.Match(request.Uri, pattern);
            if (match.Success)
            {
                IController controller = ControllerFactory.Get(match.Groups[1].Value);
                if (controller != null)
                {
                    controller.ProcessGet(request, response);
                    return;
                }
            }

            NotFoundResponse(request, response);
        }
예제 #34
0
        public void OnRequest(IHttpServerTransaction transaction, HttpRequestHead request, bool shouldKeepAlive)
        {
            AddXFF(request, transaction.RemoteEndPoint);

            var expectContinue     = request.IsContinueExpected();
            var ignoreResponseBody = request.Method != null && request.Method.ToUpperInvariant() == "HEAD";

            currentContext = new TransactionContext(expectContinue, ignoreResponseBody, shouldKeepAlive);

            if (lastSegment == null)
            {
                currentContext.Segment.AttachTransaction(transaction);
            }

            QueueSegment(currentContext.Segment);
            requestDelegate.OnRequest(request, currentContext.RequestBody, currentContext);
        }
        void AddXFF(ref HttpRequestHead request, IPEndPoint remoteEndPoint)
        {
            if (remoteEndPoint != null)
            {
                if (request.Headers == null)
                {
                    request.Headers = new Dictionary <string, string>(StringComparer.InvariantCultureIgnoreCase);
                }

                if (request.Headers.ContainsKey("X-Forwarded-For"))
                {
                    request.Headers["X-Forwarded-For"] += "," + remoteEndPoint.Address.ToString();
                }
                else
                {
                    request.Headers["X-Forwarded-For"] = remoteEndPoint.Address.ToString();
                }
            }
        }