Exemplo n.º 1
0
        internal static bool TryParseRequestLine(ReadOnlySpan <byte> buffer, out HttpRequestLine requestLine, out int totalParsedBytes)
        {
            requestLine      = new HttpRequestLine();
            totalParsedBytes = 0;

            var reader = new HttpRequestReader();

            reader.Buffer = buffer;

            requestLine.Method = reader.ReadMethod();
            if (requestLine.Method == HttpMethod.Unknown)
            {
                return(false);
            }

            requestLine.RequestUri = reader.ReadRequestUri().Bytes.ToArray();
            if (requestLine.RequestUri.Length == 0)
            {
                return(false);
            }
            reader.Buffer = reader.Buffer.Slice(1);

            requestLine.Version = reader.ReadHttpVersion();
            if (requestLine.Version == HttpVersion.Unknown)
            {
                return(false);
            }

            totalParsedBytes = buffer.Length - reader.Buffer.Length;
            return(true);
        }
Exemplo n.º 2
0
        static public void TestParseHttpRequestLine()
        {
            // Test a well-formatted HTTP/1.1 request line
            var             rq1    = "GET / HTTP/1.1";
            var             rq1_nl = rq1 + "\r\n";
            HttpRequestLine hrl1   = TcpCommon.ParseHttpRequestLine(rq1_nl);

            Assert.AreEqual(rq1, hrl1.RequestLine);
            Assert.AreEqual("GET", hrl1.Method);
            Assert.AreEqual("/", hrl1.URI);
            Assert.AreEqual("1.1", hrl1.ProtocolVersion);

            // Test a well-formatted HTTP/1.0 request line
            var             rq2  = "HEAD http://www.idm.fr/index.html HTTP/1.0\r\n";
            HttpRequestLine hrl2 = TcpCommon.ParseHttpRequestLine(rq2);

            Assert.AreEqual("HEAD", hrl2.Method);
            Assert.AreEqual("http://www.idm.fr/index.html", hrl2.URI);
            Assert.AreEqual("1.0", hrl2.ProtocolVersion);

            // Test a wonky-but-still-acceptable request line
            var             rq3  = "OPTIONS   /freezepop    HTTP/1.2  \n";
            HttpRequestLine hrl3 = TcpCommon.ParseHttpRequestLine(rq3);

            Assert.AreEqual("OPTIONS", hrl3.Method);
            Assert.AreEqual("/freezepop", hrl3.URI);
            Assert.AreEqual("1.2", hrl3.ProtocolVersion);
        }
Exemplo n.º 3
0
        internal static int TryParseRequestLine(ReadOnlySpan <byte> buffer, out HttpRequestLine requestLine)
        {
            requestLine = new HttpRequestLine();

            var reader = new HttpRequestReader();

            reader.Buffer = buffer;

            requestLine.Method = reader.ReadMethod();
            if (requestLine.Method == HttpMethod.Unknown)
            {
                return(0);
            }

            requestLine.RequestUri = reader.ReadRequestUri().Bytes.ToArray();
            if (requestLine.RequestUri.Length == 0)
            {
                return(0);
            }
            reader.Buffer = reader.Buffer.Slice(1);

            requestLine.Version = reader.ReadHttpVersion();
            if (requestLine.Version == HttpVersion.Unknown)
            {
                return(0);
            }

            return(buffer.Length - reader.Buffer.Length);
        }
Exemplo n.º 4
0
        public static HttpRequest FromString(string value)
        {
            var result = new HttpRequest();

            result.Line = HttpRequestLine.FromString(result.Load(value));

            return(result);
        }
Exemplo n.º 5
0
        public void Parse_BufferIsInvalid_ThrowsBadHttpDataException(string input)
        {
            // Arrange
            var buffer = input.ToAsciiBytes();

            // Act & Assert
            Assert.Throws <BadHttpDataException>(() => HttpRequestLine.Parse(buffer, 3));
        }
Exemplo n.º 6
0
        public void OriginTest()
        {
            const string source = "CONNECT www.example.com:80 HTTP/1.1\r\n";

            HttpRequestLine.TryParse(source, out var line);
            line.Source.Is(line.Source);
            line.GetOrigin().IsNot(line.GetOrigin());
        }
Exemplo n.º 7
0
        public void Parse_StartIsOutOfRange_ThrowsArgumentOutOfRangeException(int start)
        {
            // Arrange

            // Act & Assert
            var ex = Assert.Throws <ArgumentOutOfRangeException>(() => HttpRequestLine.Parse(new byte[10], start));

            Assert.That(ex.ParamName, Is.EqualTo("start"));
        }
Exemplo n.º 8
0
        public void Parse_BufferIsNull_ThrowsArgumentNullException(int start)
        {
            // Arrange

            // Act & Assert
            var ex = Assert.Throws <ArgumentNullException>(() => HttpRequestLine.Parse(null, 5));

            Assert.That(ex.ParamName, Is.EqualTo("buffer"));
        }
Exemplo n.º 9
0
        public void BrokenRequestLineTest()
        {
            const string source      = "hogeeeee\r\n";
            var          isSucceeded = HttpRequestLine.TryParse(source, out var line);

            isSucceeded.IsFalse();
            line.Source.Is(source);
            line.ToString().Is(source);
        }
Exemplo n.º 10
0
 public TRequestId GetRequestId(HttpRequestLine requestLine)
 {
     for (int i = 0; i < _count; i++)
     {
         if (requestLine.RequestUri.Span.SequenceEqual(_uris[i]) && requestLine.Method == _verbs[i])
         {
             return(_requestIds[i]);
         }
     }
     return(default);
Exemplo n.º 11
0
 static void WriteResponseForGetTime(BufferFormatter formatter, HttpRequestLine request)
 {
     // TODO: this needs to not allocate
     var body = string.Format(@"<html><head><title>Time</title></head><body>{0}</body></html>", DateTime.UtcNow.ToString("O"));
     WriteCommonHeaders(formatter, "1.1", "200", "Ok", keepAlive: false);
     // TOOD: this needs to not allocate
     formatter.WriteHttpHeader(new Utf8String("Content-Length"), new Utf8String(body.Length.ToString()));
     formatter.EndHttpHeaderSection();
     formatter.WriteHttpBody(new Utf8String(body));
 }
Exemplo n.º 12
0
        public void Constructor_HeadersIsNull_ThrowsArgumentNullException()
        {
            // Arrange
            var line = new HttpRequestLine(HttpMethod.Get, "/");

            // Act & Assert
            var ex = Assert.Throws <ArgumentNullException>(() => new HttpRequestMetadata(line, null));

            Assert.That(ex.ParamName, Is.EqualTo("headers"));
        }
Exemplo n.º 13
0
        /// <summary>
        /// スタートラインを解釈
        /// </summary>
        /// <param name="startLine"></param>
        protected override void ParseStartLine(string startLine)
        {
            var isParseSucceeded = HttpRequestLine.TryParse(startLine, out var requestLine);

            this.RequestLine = requestLine;
            if (!isParseSucceeded)
            {
                Debug.WriteLine($"###start###{startLine}###end###");
                throw new BadRequestException("Invalid Request Line", this.GetRequest());
            }
        }
Exemplo n.º 14
0
    static void WriteResponseForGetTime(BufferFormatter formatter, HttpRequestLine request)
    {
        // TODO: this needs to not allocate
        var body = string.Format(@"<html><head><title>Time</title></head><body>{0}</body></html>", DateTime.UtcNow.ToString("O"));

        WriteCommonHeaders(formatter, "1.1", "200", "Ok", keepAlive: false);
        // TOOD: this needs to not allocate
        formatter.WriteHttpHeader(new Utf8String("Content-Length"), new Utf8String(body.Length.ToString()));
        formatter.EndHttpHeaderSection();
        formatter.WriteHttpBody(new Utf8String(body));
    }
Exemplo n.º 15
0
        public void OriginFormTest()
        {
            const string source = "GET /where?q=now HTTP/1.1\r\n";

            HttpRequestLine.TryParse(source, out var line);
            line.Method.Is(HttpMethod.Get);
            line.HttpVersion.Is(HttpVersion.Version11);
            line.RequestTargetForm.Is(RequestTargetForm.OriginForm);
            line.RequestTarget.Is("/where?q=now");
            line.ToString().Is(source);
        }
Exemplo n.º 16
0
        public void AbsoluteFormTest()
        {
            const string source = "GET http://www.example.org/pub/WWW/TheProject.html HTTP/1.1\r\n";

            HttpRequestLine.TryParse(source, out var line);
            line.Method.Is(HttpMethod.Get);
            line.HttpVersion.Is(HttpVersion.Version11);
            line.RequestTargetForm.Is(RequestTargetForm.AbsoluteForm);
            line.RequestTarget.Is("http://www.example.org/pub/WWW/TheProject.html");
            line.ToString().Is(source);
        }
Exemplo n.º 17
0
        public void AuthorityForm()
        {
            const string source = "CONNECT www.example.com:80 HTTP/1.1\r\n";

            HttpRequestLine.TryParse(source, out var line);
            line.Method.Is(new HttpMethod("CONNECT"));
            line.HttpVersion.Is(HttpVersion.Version11);
            line.RequestTargetForm.Is(RequestTargetForm.AuthorityForm);
            line.RequestTarget.Is("www.example.com:80");
            line.ToString().Is(source);
        }
Exemplo n.º 18
0
            protected override void OnReceiveRequest(HttpRequestLine e)
            {
#if DEBUG
                Console.ForegroundColor = ConsoleColor.DarkBlue;
                Console.WriteLine(System.Threading.Thread.CurrentThread.ManagedThreadId + " -> " + RequestLine
                                  + (RequestHeaders.Referer != null ? ", Referer: " + RequestHeaders.Referer : "")
                                  );
                Console.ForegroundColor = ConsoleColor.Gray;
#endif
                requestUri = RequestLine.Uri;                   // NOTE: used by ReceiveResponse
                if (blacklistHosts.Contains(requestUri?.Host))
                {
                    SocketBP.CloseSocket();
                }

                var method = e.Method.ToUpper();
                if (method != "CONNECT")
                {
                    timer = new System.Threading.Timer(new System.Threading.TimerCallback(OnExpire), null, 300 * 1000, System.Threading.Timeout.Infinite);
                }
                if ((method == "POST" || method == "PUT" || method == "PATCH"))
                {
                    if (skipHosts.Contains(e.Uri.Host))
                    {
                        return;
                    }

                    // Typical requests endpoint:
                    //http://summonerswar-gb.qpyou.cn/api/gateway_c2.php
                    if (e.Uri.AbsoluteUri.Contains("summonerswar") && e.Uri.AbsoluteUri.Contains("/api/gateway"))
                    {
                        string bodyString = Encoding.ASCII.GetString(SocketBP.Buffer, 0, Array.IndexOf(SocketBP.Buffer, (byte)0));
                        bodyString = bodyString.Substring(bodyString.IndexOf("\r\n\r\n"));                                      // TODO: FIXME: this needs to match first \r?\n\r?\n

                        decRequest = decryptRequest(bodyString, e.Uri.AbsolutePath.Contains("_c2.php") ? 2 : 1);
                        try {
                            req = JsonConvert.DeserializeObject <JObject>(decRequest);
                            if (!Directory.Exists("Json"))
                            {
                                Directory.CreateDirectory("Json");
                            }
                            File.WriteAllText($"Json\\{req["command"]}" +
#if DEBUG
                                              $"_{DateTime.Now.ToString("yyyyMMddHHmmssfff")}" +
#endif
                                              ".req.json", JsonConvert.SerializeObject(req, Formatting.Indented));
                            Console.ForegroundColor = ConsoleColor.DarkGray;
                            Console.WriteLine($">{req["command"]}");
                            Console.ForegroundColor = ConsoleColor.Gray;
                        }
                        catch { };
                    }
                }
            }
Exemplo n.º 19
0
        public void AsteriskFormTest()
        {
            const string source = "OPTIONS * HTTP/1.1\r\n";

            HttpRequestLine.TryParse(source, out var line);
            line.Method.Is(HttpMethod.Options);
            line.HttpVersion.Is(HttpVersion.Version11);
            line.RequestTargetForm.Is(RequestTargetForm.AsteriskForm);
            line.RequestTarget.Is("*");
            line.ToString().Is(source);
        }
Exemplo n.º 20
0
    protected override HttpServerBuffer CreateResponse(HttpRequestLine requestLine, Span <byte> headerAndBody)
    {
        var api = Apis.Map(requestLine);

        switch (api)
        {
        case Api.GetTime:
            return(CreateResponseForGetTime());

        default:
            return(CreateResponseFor404(requestLine, headerAndBody));
        }
    }
Exemplo n.º 21
0
    static HttpServerBuffer CreateResponseForGetTime(HttpRequestLine request)
    {
        var body      = string.Format(@"<html><head><title>Time</title></head><body>{0}</body></html>", DateTime.UtcNow.ToString("O"));
        var formatter = new BufferFormatter(1024, FormattingData.InvariantUtf8);

        WriteCommonHeaders(formatter, "1.1", "200", "Ok", request.IsKeepAlive());
        formatter.WriteHttpHeader(new Utf8String("Content-Length"), new Utf8String(body.Length.ToString()));
        formatter.EndHttpHeaderSection();

        formatter.WriteHttpBody(new Utf8String(body));

        return(new HttpServerBuffer(formatter.Buffer, formatter.CommitedByteCount, BufferPool.Shared));
    }
Exemplo n.º 22
0
        protected override void OnReceiveRequest(HttpRequestLine req)
        {
            _requestUri = req.Uri;

            /*var method = req.Method.ToUpper();
             * if ((method == "POST" || method == "PUT" || method == "PATCH") && req.Uri.AbsoluteUri.Contains("api/gateway_c2"))
             * {
             *      var content = Encoding.ASCII.GetString(SocketBP.Buffer, 0, Array.IndexOf(SocketBP.Buffer, (byte)0));
             *      content = content.Substring(content.IndexOf("\r\n\r\n", StringComparison.Ordinal));
             *
             *      JObject json = JObject.Parse(Proxy.DecryptRequest(content));
             *      Debug.WriteLine(json["command"]);
             * }*/
        }
Exemplo n.º 23
0
        public void Parse_ValidArguments_CreatesLine(string input, string expectedMethod, string expectedUri, string expectedVersion)
        {
            // Arrange
            var buffer = input.ToAsciiBytes();

            // Act
            var line = HttpRequestLine.Parse(buffer, 3);

            // Assert
            Assert.That(line, Is.Not.Null);
            Assert.That(line.Method.ToString(), Is.EqualTo(expectedMethod));
            Assert.That(line.RequestUri, Is.EqualTo(expectedUri));
            Assert.That(line.Version, Is.EqualTo(expectedVersion));
        }
Exemplo n.º 24
0
        public void OriginTest()
        {
            const string lineSource = "GET / HTTP/1.1\r\n";

            HttpRequestLine.TryParse(lineSource, out var line);
            var headers = HttpHeaders.Empty;

            headers.Host.Value = "example.com";
            var request = new HttpRequest(line, headers, new byte[0], HttpHeaders.Empty);

            // Request 系は BadRequest への対処として Source プロパティを持つ
            request.Source.Is(request.Source);
            request.GetOrigin().IsNot(request.GetOrigin());
        }
Exemplo n.º 25
0
        public void Constructor_3ArgumentsValid_RunsOk(string method, string uri, string version)
        {
            // Arrange

            // Act
            var line = new HttpRequestLine(new HttpMethod(method), uri, version);

            // Assert
            Assert.That(line.Method.ToString(), Is.EqualTo(method));
            Assert.That(line.RequestUri, Is.EqualTo(uri));
            Assert.That(line.Version, Is.EqualTo(version));
            Assert.That(line.ToString(), Is.EqualTo($"{method} {uri} {version}\r\n"));
            Assert.That(line.ByteCount, Is.EqualTo($"{method} {uri} {version}\r\n".Length));
            Assert.That(line.ToArray(), Is.EquivalentTo($"{method} {uri} {version}\r\n".ToAsciiBytes()));
        }
Exemplo n.º 26
0
        public void GetOriginTest()
        {
            const string lineSource = "GET / HTTP/1.1\r\n";

            HttpRequestLine.TryParse(lineSource, out var line);
            HttpHeaders.TryParse("Host: example.com\r\n", out var headers);
            headers.Host.Value = "example2.com";
            var request = new HttpRequest(line, headers, new byte[0], HttpHeaders.Empty);

            request.GetOrigin().ToString().Is(
                @"GET / HTTP/1.1
Host: example.com

");
        }
Exemplo n.º 27
0
        public void ChangeRequestTargetTest()
        {
            const string lineSource = "GET /hoge?fuga=piyo HTTP/1.1\r\n";

            HttpRequestLine.TryParse(lineSource, out var line);
            HttpHeaders.TryParse("Host: example.com\r\n", out var headers);
            var request = new HttpRequest(line, headers, new byte[0], HttpHeaders.Empty);

            request.RequestTargetUri.ToString().Is("http://example.com/hoge?fuga=piyo");
            request.RequestLine.RequestTargetForm.Is(RequestTargetForm.OriginForm);

            request.ChangeRequestTarget("http://absolute.example.com/hoge?fuga=piyo");
            request.RequestTargetUri.ToString().Is("http://absolute.example.com/hoge?fuga=piyo");
            request.RequestLine.RequestTargetForm.Is(RequestTargetForm.AbsoluteForm);
        }
Exemplo n.º 28
0
        public void Constructor_ValidArguments_RunsOk()
        {
            // Arrange
            var line         = new HttpRequestLine(HttpMethod.Get, "/");
            var headersArray = new[]
            {
                new HttpHeader("Accept", "text/html, application/xhtml+xml, image/jxr, */*"),
                new HttpHeader("Accept-Language", "ru-RU"),
                new HttpHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299"),
                new HttpHeader("Accept-Encoding", "gzip, deflate"),
                new HttpHeader("Host", "allitebooks.com"),
                new HttpHeader("Connection", "Keep-Alive"),
            };
            var headers = new HttpHeaderCollection(headersArray);

            // Act
            var requestMetadata = new HttpRequestMetadata(line, headers);

            // Assert
            Assert.That(requestMetadata.Line.Method.ToString(), Is.EqualTo("GET"));
            Assert.That(requestMetadata.Line.RequestUri, Is.EqualTo("/"));
            Assert.That(requestMetadata.Line.Version, Is.EqualTo("HTTP/1.1"));

            Assert.That(requestMetadata.Headers.Count(), Is.EqualTo(6));
            Assert.That(requestMetadata.Headers.ElementAt(0), Is.SameAs(headersArray[0]));
            Assert.That(requestMetadata.Headers.ElementAt(1), Is.SameAs(headersArray[1]));
            Assert.That(requestMetadata.Headers.ElementAt(2), Is.SameAs(headersArray[2]));
            Assert.That(requestMetadata.Headers.ElementAt(3), Is.SameAs(headersArray[3]));
            Assert.That(requestMetadata.Headers.ElementAt(4), Is.SameAs(headersArray[4]));
            Assert.That(requestMetadata.Headers.ElementAt(5), Is.SameAs(headersArray[5]));

            var expectedString = @"GET / HTTP/1.1
Accept: text/html, application/xhtml+xml, image/jxr, */*
Accept-Language: ru-RU
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299
Accept-Encoding: gzip, deflate
Host: allitebooks.com
Connection: Keep-Alive

";
            var toString       = requestMetadata.ToString();

            Assert.That(toString, Is.EqualTo(expectedString));

            var bytes = requestMetadata.Serialize();

            Assert.That(bytes, Is.EquivalentTo(expectedString.ToAsciiBytes()));
        }
Exemplo n.º 29
0
        public void HeadersAsByteTest()
        {
            const string lineSource = "GET / HTTP/1.1\r\n";

            HttpRequestLine.TryParse(lineSource, out var line);
            var headers = HttpHeaders.Empty;

            headers.Host.Value = "example.com";
            var request = new HttpRequest(line, headers, new byte[0], HttpHeaders.Empty);

            request.HeadersAsByte().Is(Encoding.ASCII.GetBytes(
                                           @"GET / HTTP/1.1
Host: example.com

"));
        }
Exemplo n.º 30
0
        /// <summary>
        /// HTTPリクエスト文字列からHTTPRequestオブジェクトを構築します
        /// </summary>
        /// <param name="requests">行毎に区切られたHTTPリクエストの文字列表現</param>
        public HttpRequest(HttpRequestLine reqLine, IEnumerable <string> requests)
        {
            Method       = reqLine.Method;
            Protocol     = reqLine.Protocol;
            PathAndQuery = reqLine.PathAndQuery;
            var headers = new RequestHeaders();

            foreach (var req in requests)
            {
                Match match = null;
                if ((match = OtherHeaderRegex.Match(req)).Success)
                {
                    headers.Add(match.Groups[1].Value, match.Groups[2].Value.Trim());
                }
            }
            Headers = headers;
        }
Exemplo n.º 31
0
        public void CreateOptionsInstanceTest()
        {
            const string lineSource = "OPTIONS * HTTP/1.1\r\n";

            HttpRequestLine.TryParse(lineSource, out var line);
            var headers = HttpHeaders.Empty;

            headers.Host.Value = "example.com";
            var request = new HttpRequest(line, headers, new byte[0], HttpHeaders.Empty);

            request.ToString().Is(
                @"OPTIONS * HTTP/1.1
Host: example.com

");
            request.RequestTargetUri.ToString().Is("*");
            request.RequestLine.RequestTargetForm.Is(RequestTargetForm.AsteriskForm);
        }
 HttpRequestLine ReadRequestLine()
 {
     var str = ReadLine(_strm);
     var strArray = str.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
     if (strArray.Length == 3)
     {
         var line = new HttpRequestLine(
             strArray[0].Trim(), strArray[1].Trim(),
             new Version(strArray[2].Trim().Replace("HTTP/", "")));
         return line;
     }
     else
         return null;
 }
Exemplo n.º 33
0
 protected virtual void WriteResponseFor404(BufferFormatter formatter, HttpRequestLine requestLine) // Not Found
 {
     Log.LogMessage(Log.Level.Warning, "Request {0}, Response: 404 Not Found", requestLine);
     WriteCommonHeaders(formatter, "1.1", "404", "Not Found", false);
     formatter.Append(HttpNewline);
 }
Exemplo n.º 34
0
 private TestRequest(HttpRequestLine requestLine) {
     _requestLine = requestLine;
 }