예제 #1
0
 public void OnRequest(UserKayak kayak, HttpRequestHead head)
 {
     if (OnRequestAction != null)
     {
         OnRequestAction(kayak, head);
     }
 }
예제 #2
0
        private static HttpRequestHead EchoPost(HttpRequestHead request, IDataProducer requestBody, IHttpResponseDelegate response)
        {
            var headers = new HttpResponseHead()
            {
                Status  = "200 OK",
                Headers = new Dictionary <string, string>()
                {
                    { "Content-Type", "text/plain" },
                    { "Connection", "close" }
                }
            };

            if (request.Headers.ContainsKey("Content-Length"))
            {
                headers.Headers["Content-Length"] = request.Headers["Content-Length"];
            }

            // if you call OnResponse before subscribing to the request body,
            // 100-continue will not be sent before the response is sent.
            // per rfc2616 this response must have a 'final' status code,
            // but the server does not enforce it.
            response.OnResponse(headers, requestBody);

            return(request);
        }
예제 #3
0
            private void ProcessPOSTRequest(HttpRequestHead head, IDataProducer body, IHttpResponseDelegate response)
            {
                body.Connect(new BufferedConsumer(
                                 (payload) =>
                {
                    try
                    {
                        _parent._systemMetrics.LogCount("listeners.http.bytes", Encoding.UTF8.GetByteCount(payload));
                        // Further split by ',' to match the GET while keeping backward compatibility and allowing you to use the join for both methods.
                        var lines = payload.Replace("\r", "")
                                    .Split(new char[] { '\n', ',' }, StringSplitOptions.RemoveEmptyEntries);

                        for (var index = 0; index < lines.Length; index++)
                        {
                            _parent._target.Post(lines[index]);
                        }
                        _parent._systemMetrics.LogCount("listeners.http.lines", lines.Length);
                        Respond(head, response, "200 OK");
                    }
                    catch
                    {
                        Respond(head, response, "400 bad request");
                    }
                },
                                 (error) =>
                {
                    Respond(head, response, "500 Internal server error");
                }));
            }
예제 #4
0
        private static async void HandleRequest(HttpRequestHead request, IDataProducer body, IHttpResponseDelegate response, IRequestHandler handler)
        {
            _log.DebugFormat("Matched a handler {0}:{1} {2}", handler.Method, handler.Path, DumpQueryParams(handler.QueryParams));

            if (handler.ResponseDelay > TimeSpan.Zero)
            {
                await Task.Delay(handler.ResponseDelay);
            }
            IDataProducer dataProducer = GetDataProducer(request, handler);

            if (request.HasBody())
            {
                body.Connect(new BufferedConsumer(
                                 bufferedBody =>
                {
                    handler.RecordRequest(request, bufferedBody);
                    _log.DebugFormat("Body: {0}", bufferedBody);
                    response.OnResponse(handler.ResponseBuilder.BuildHeaders(), dataProducer);
                },
                                 error =>
                {
                    _log.DebugFormat("Error while reading body {0}", error.Message);
                    response.OnResponse(handler.ResponseBuilder.BuildHeaders(), dataProducer);
                }
                                 ));
            }
            else
            {
                response.OnResponse(handler.ResponseBuilder.BuildHeaders(), dataProducer);
                handler.RecordRequest(request, null);
            }
            _log.DebugFormat("End Processing request for : {0}:{1}", request.Method, request.Uri);
        }
예제 #5
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);
 }
예제 #6
0
 public void OnRequest(HttpRequestHead head,
                       IDataProducer body,
                       IHttpResponseDelegate response)
 {
     if (head.Method.ToUpperInvariant() == "OPTIONS")
     {
         ProcessOPTIONSRequest(body, response);
     }
     else 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.Uri == "/clientaccesspolicy.xml")
     {
         ProcessClientAccessPolicyRequest(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);
     }
 }
예제 #7
0
            private void ProcessGETRequest(IDataProducer body, HttpRequestHead head, IHttpResponseDelegate response)
            {
                var qs = head.QueryString.Split(new char[] { '&' }, StringSplitOptions.RemoveEmptyEntries)
                         .Select(p => p.Split(new char[] { '=' }, StringSplitOptions.None))
                         .ToDictionary(p => p[0], p => HttpUtility.UrlDecode(p[1]));

                string[] lines = qs["metrics"].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                for (int index = 0; index < lines.Length; index++)
                {
                    _parent._target.Post(lines[index]);
                }
                _parent._systemMetrics.LogCount("listeners.http.lines", lines.Length);
                _parent._systemMetrics.LogCount("listeners.http.bytes", Encoding.UTF8.GetByteCount(qs["metrics"]));

                var responseHead = new HttpResponseHead()
                {
                    Status  = "200 OK",
                    Headers = new Dictionary <string, string>
                    {
                        { "Content-Type", "application-xml" },
                        { "Content-Length", "0" },
                        { "Access-Control-Allow-Origin", "*" }
                    }
                };

                response.OnResponse(responseHead, new EmptyResponse());
            }
예제 #8
0
파일: Mocks.cs 프로젝트: yukiyuki/kayak
 public void OnRequest(IHttpServerTransaction tx, HttpRequestHead request, bool shouldKeepAlive)
 {
     current = new HttpRequest()
     {
         Head = request, ShouldKeepAlive = shouldKeepAlive, Data = new DataBuffer()
     };
 }
예제 #9
0
파일: Mocks.cs 프로젝트: yukiyuki/kayak
 public void OnRequest(HttpRequestHead head, IDataProducer body, IHttpResponseDelegate response)
 {
     if (OnRequestAction != null)
     {
         OnRequestAction(head, body, response);
     }
 }
        public void urls_and_methods_match_and_headers_match_it_returns_true()
        {
            var requestHandler = MockRepository.GenerateStub <IRequestHandler>();

            requestHandler.Path           = "test";
            requestHandler.Method         = "GET";
            requestHandler.QueryParams    = new Dictionary <string, string>();
            requestHandler.RequestHeaders = new Dictionary <string, string> {
                { "myHeader", "one" }
            };

            var httpRequestHead = new HttpRequestHead
            {
                Uri     = "test",
                Method  = "GET",
                Headers = new Dictionary <string, string>
                {
                    { "myHeader", "one" },
                    { "anotherHeader", "two" }
                }
            };
            var endpointMatchingRule = new EndpointMatchingRule();

            Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandler, httpRequestHead));
        }
        public void should_do_a_case_insensitive_match_on_header_names_and_values()
        {
            var requestHandler = MockRepository.GenerateStub <IRequestHandler>();

            requestHandler.Path           = "test";
            requestHandler.Method         = "GET";
            requestHandler.QueryParams    = new Dictionary <string, string>();
            requestHandler.RequestHeaders = new Dictionary <string, string> {
                { "myHeader", "one" }
            };

            var httpRequestHead = new HttpRequestHead
            {
                Uri     = "test",
                Method  = "GET",
                Headers = new Dictionary <string, string>
                {
                    { "MYheaDER", "OnE" }
                }
            };

            var endpointMatchingRule = new EndpointMatchingRule();

            Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandler, httpRequestHead));
        }
        public static byte[] GetBytes(HttpRequestHead header, IDictionary pList)
        {
            var    plistWriter = new System.Runtime.Serialization.Plists.BinaryPlistWriter();
            string content     = System.Runtime.Serialization.Plists.PlistXmlDocument.CreateDocument(pList);

            var sb = new StringBuilder();

            sb.AppendFormat("{0} {1}  /1.1 HTTP/{2}.{3}\r\n", header.Method, header.Path, header.Version.Major, header.Version.Minor);
            if (!string.IsNullOrEmpty(content))
            {
                header.Headers["Content-Length"] = Encoding.UTF8.GetByteCount(content).ToString();
                header.Headers["Content-Type"]   = @"text/x-apple-plist+xml";
            }

            foreach (var pair in header.Headers)
            {
                foreach (var line in pair.Value.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries))
                {
                    sb.AppendFormat("{0}: {1}\r\n", pair.Key, line);
                }
            }
            sb.Append("\r\n");
            sb.Append(content);
            sb.Append("\r\n");

            return(Encoding.UTF8.GetBytes(sb.ToString()));
        }
예제 #13
0
        public bool IsEndpointMatch(IRequestHandler requestHandler, HttpRequestHead request)
        {
            if (requestHandler.QueryParams == null)
            {
                throw new ArgumentException("requestHandler QueryParams cannot be null");
            }

            var requestQueryParams = GetQueryParams(request);
            var requestHeaders     = GetHeaders(request);

            bool uriStartsWith = MatchPath(requestHandler, request);

            bool httpMethodsMatch = requestHandler.Method == request.Method;

            bool queryParamMatch        = true;
            bool shouldMatchQueryParams = (requestHandler.QueryParams.Count > 0);

            if (shouldMatchQueryParams)
            {
                queryParamMatch = _queryParamMatch.MatchQueryParams(requestHandler, requestQueryParams);
            }

            bool headerMatch        = true;
            bool shouldMatchHeaders = requestHandler.RequestHeaders != null &&
                                      requestHandler.RequestHeaders.Count > 0;

            if (shouldMatchHeaders)
            {
                headerMatch = _headerMatch.MatchHeaders(requestHandler, requestHeaders);
            }

            return(uriStartsWith && httpMethodsMatch && queryParamMatch && headerMatch);
        }
        public void Should_match_a_specific_handler()
        {
            var expectedRequest = MockRepository.GenerateStub <IRequestHandler>();

            expectedRequest.Method      = "GET";
            expectedRequest.Path        = "/path/specific";
            expectedRequest.QueryParams = new Dictionary <string, string>();
            expectedRequest.Stub(s => s.CanVerifyConstraintsFor("", "")).IgnoreArguments().Return(true);


            var otherRequest = MockRepository.GenerateStub <IRequestHandler>();

            otherRequest.Method      = "GET";
            otherRequest.Path        = "/path/";
            otherRequest.QueryParams = new Dictionary <string, string>();
            otherRequest.Stub(s => s.CanVerifyConstraintsFor("", "")).IgnoreArguments().Return(true);

            var requestMatcher = new RequestMatcher(new EndpointMatchingRule());

            var requestHandlerList = new List <IRequestHandler> {
                otherRequest, expectedRequest
            };


            var httpRequestHead = new HttpRequestHead {
                Method = "GET", Path = "/path/specific", Uri = "/path/specific"
            };

            var matchedRequest = requestMatcher.Match(httpRequestHead, null, requestHandlerList);


            Assert.That(matchedRequest.Path, Is.EqualTo(expectedRequest.Path));
        }
예제 #15
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);
        }
예제 #16
0
 public IHttpResponseDelegateInternal Create(HttpRequestHead requestHead, bool shouldKeepAlive, Action end)
 {
     // XXX freelist
     return(new IosHttpResponseDelegate(
                prohibitBody: requestHead.Method.ToUpperInvariant() == "HEAD",
                shouldKeepAlive: shouldKeepAlive,
                closeConnection: end));
 }
예제 #17
0
        public IRequestHandler Match(HttpRequestHead request, string body, IEnumerable <IRequestHandler> requestHandlerList)
        {
            var matches = requestHandlerList
                          .Where(handler => _matchingRule.IsEndpointMatch(handler, request))
                          .Where(handler => handler.CanVerifyConstraintsFor(request.Uri, body));

            return(matches.FirstOrDefault());
        }
예제 #18
0
        public ResponseBuilder Get(HttpRequestHead request)
        {
            var stubNotFoundResponseBuilder = new ResponseBuilder();

            stubNotFoundResponseBuilder.Return(string.Format("Stub not found for {0} : {1}", request.Method, request.Uri));
            stubNotFoundResponseBuilder.WithStatus(HttpStatusCode.NotFound);
            return(stubNotFoundResponseBuilder);
        }
예제 #19
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");
 }
예제 #20
0
 public void OnRequest(UserKayak kayak, HttpRequestHead head)
 {
     current = new RequestInfo()
     {
         Head = head, Data = Enumerable.Empty <string>()
     };
     receivedRequests.Add(current);
     next.OnRequest(kayak, head);
 }
예제 #21
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);
        }
예제 #22
0
파일: Request.cs 프로젝트: yukiyuki/kayak
 public static bool IsContinueExpected(this HttpRequestHead request)
 {
     return
         (request.Version != null &&
          request.Version.Major == 1 &&
          request.Version.Minor == 1 &&
          request.Headers != null &&
          request.Headers.ContainsKey("expect") &&
          request.Headers["expect"] == "100-continue");
 }
예제 #23
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);
 }
예제 #24
0
            public void OnRequest(HttpRequestHead request, IDataProducer requestBody,
                                  IHttpResponseDelegate response)
            {
                var verror      = "404 Not Found";
                var errorString = "Not Found";

                try
                {
                    var path = request.Uri;

                    if (path == "/api")
                    {
                        var method = request.Method;
                        var stream = new MemoryStream();
                        if (method == "POST")
                        {
                            requestBody.Connect(new BufferedConsumer(bufferedBody =>
                            {
                                var data = Encoding.UTF8.GetBytes(Encoding.UTF8.GetString(bufferedBody).Split(new[] { "\r\n\r\n" }, 2, StringSplitOptions.RemoveEmptyEntries)[1]);
                                stream.Write(data, 0, data.Length);
                                stream.Position = 0;

                                HandleAPIRequest(stream, method, response);
                            }, error =>
                            {
                                Log.Error(error.ToString());
                            }));
                        }
                        else
                        {
                            HandleAPIRequest(stream, method, response);
                        }

                        return;
                    }
                }
                catch (Exception ex)
                {
                    verror = "500 Internal Server Error";

                    Log.Error(ex.ToString());
                    errorString = ex.ToString();
                }

                response.OnResponse(new HttpResponseHead()
                {
                    Status  = verror,
                    Headers = new Dictionary <string, string>()
                    {
                        { "Content-Type", "text/plain" },
                        { "Content-Length", errorString.Length.ToString() }
                    }
                }, new BufferedProducer(errorString));
            }
예제 #25
0
        public void Handle(string appname, string[] components, HttpRequestHead head, IDataProducer body, IHttpResponseDelegate response)
        {
            // Get a list of all of the files in the store for this application.
            Cache c = new Cache(false);
            IEnumerable <string> files = c.ListRecursive("server/" + appname + "/store");

            // Create ZIP file and copy files into it.
            using (ZipFile zip = new ZipFile())
            {
                // Add the files.
                foreach (string s in files)
                {
                    ZipEntry e = zip.AddFile(c.GetFilePath("server/" + appname + "/store/" + s), this.GetDirectoryName(s));
                    e.Comment = "Added by Pivot.Server.";
                }

                // Add the README-UPDATES.txt file.
                zip.AddEntry("README-UPDATES.txt",
                             @"About
===============
This ZIP file was automatically generated by the Pivot.Update server.
Refer to https://github.com/hach-que/Pivot.Update/ for more information.

Usage Notice
===============
The software contained in this ZIP file may use Pivot.Update to
automatically update itself when new versions are released.  In the
event that it does, a UAC prompt may appear when the related Windows
service first needs to be installed.  This Windows service is responsible
for automatically updating applications on a periodic basis; without
this service, the associated software will not automatially update.
");

                zip.Comment = "ZIP file automatically generated by Pivot.Server.";

                using (MemoryStream output = new MemoryStream())
                {
                    zip.Save(output);

                    // Send the ZIP file.
                    response.OnResponse(new HttpResponseHead()
                    {
                        Status  = "200 OK",
                        Headers = new Dictionary <string, string>
                        {
                            { "Content-Type", "application/zip" },
                            { "Content-Length", output.Length.ToString() },
                            { "Content-Disposition", "attachment; filename=\"" + appname + ".zip\"" },
                            { "Connection", "close" }
                        }
                    }, new BufferedProducer(output.ToArray()));
                }
            }
        }
예제 #26
0
 public void OnRequest(HttpRequestHead request, bool shouldKeepAlive)
 {
     _realDelegate.OnRequest(request, shouldKeepAlive);
     if (request.Uri.StartsWith("/reverse"))
     {
         _isTwoWay = true;
         if (_connectionWatcher != null)
         {
             _connectionWatcher.TwoWaySocketAvailable(_socket);
         }
     }
 }
예제 #27
0
        private void GetElements(HttpRequestHead request, IHttpResponseDelegate response)
        {
            IEnumerable <ElementNode> elementNodes = VixenSystem.Nodes.GetRootNodes();
            var elements = new List <Element>();

            foreach (var elementNode in elementNodes)
            {
                AddNodes(elements, elementNode);
            }

            SerializeResponse(elements, response);
        }
예제 #28
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));
        }
예제 #29
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)
            {
                env[OwinConstants.RequestHeaders] = new Dictionary <string, string[]>(StringComparer.OrdinalIgnoreCase);
            }
            else
            {
                env[OwinConstants.RequestHeaders] = head.Headers.ToDictionary(kv => kv.Key, kv => new[] { kv.Value }, StringComparer.OrdinalIgnoreCase);
            }

            env[OwinConstants.ResponseHeaders] = new Dictionary <string, string[]>(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)
            {
                env[OwinConstants.RequestBody] = Stream.Null;
            }

            /*
             * else
             * request.Body = (write, end, cancellationToken) =>
             * {
             *  var d = body.Connect(new DataConsumer(
             *      write,
             *      end,
             *      () => end(null)));
             *  cancellationToken.Register(d.Dispose);
             * };
             */// TODO: Request body stream

            appFunc(env)
            .Then(() => HandleResponse(response, env))
            .Catch(errorInfo => HandleError(response, errorInfo));
        }
예제 #30
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}\/*$", Regex.Escape(requestHandler.Path)));

            return(pathMatch.IsMatch(pathToMatch));
        }