public void HttpSocket3TimeNativeSocket(int count)
        {
            var ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 50651);

            var req = new HttpRequest {
                Uri = new Uri("http://127.0.0.1:50651/x2.html")
            };
            var reader = new HttpResponseReader();
            var sw     = Stopwatch.StartNew();

            for (var i = 0; i < count; i++)
            {
                HttpResponse r;
                using (var socket = new Socket(SocketType.Stream, ProtocolType.Tcp)){
                    socket.Connect(ep);
                    using (var s = new NetworkStream(socket)){
                        var w = new HttpRequestWriter(s);
                        w.Write(req);
                        r = reader.Read(s);
                    }
                    Assert.Greater(r.StringData.Length, 10);
                }
            }
            sw.Stop();
            Console.WriteLine(sw.Elapsed);
        }
Example #2
0
        public void HandleResponseTest()
        {
            using (var reader = new HttpResponseReader(true, int.MaxValue))
            {
                var counter = 0;
                var tcs     = new TaskCompletionSource <HttpResponse>();
                reader.ReceivedResponseBody += r =>
                {
                    counter++;
                    if (1 < counter)
                    {
                        tcs.TrySetResult(r);
                    }
                };

                reader.HandleReceive(
                    @"HTTP/1.1 100 Continue
Date: Mon, 01 Jan 2018 01:00:00 GMT

");

                reader.HandleReceive(
                    @"HTTP/1.1 200 OK
Date: Mon, 01 Jan 2018 01:00:00 GMT

");

                var response = tcs.GetResult();
                response.StatusLine.StatusCode.Is(System.Net.HttpStatusCode.OK);
            }
        }
Example #3
0
        public void CanReadPreamble(int pageSize)
        {
            var b      = new StringBuilder();
            var s      = GetStream("HTTP/1.1 200 OK\r\n\r\n");
            var reader = new HttpResponseReader {
                BufferSize = pageSize
            };
            var resp = reader.Read(s);

            Assert.AreEqual(200, resp.State);
            Assert.AreEqual("OK", resp.StateName);
            Assert.True(resp.Success);
        }
Example #4
0
        public void CanReadHeaders(int pageSize)
        {
            var b      = new StringBuilder();
            var s      = GetStream("HTTP/1.1 200 OK\r\nAaa: Bbb\r\nCcc: Ddd\r\n\r\n");
            var reader = new HttpResponseReader {
                BufferSize = pageSize
            };
            var resp = reader.Read(s);

            Assert.AreEqual(200, resp.State);
            Assert.AreEqual("OK", resp.StateName);
            Assert.AreEqual("Bbb", resp.Headers["Aaa"]);
            Assert.AreEqual("Ddd", resp.Headers["Ccc"]);
            Assert.True(resp.Success);
        }
Example #5
0
        public void CanReadEncodedData(int pageSize)
        {
            var s      = GetStream("HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=Windows-1251\r\nAaa: Bbb\r\nCcc: Ddd\r\nContent-Length: 10\r\n\r\nабвгдежзик", Encoding.GetEncoding("Windows-1251"));
            var reader = new HttpResponseReader {
                BufferSize = pageSize
            };
            var resp = reader.Read(s);

            Assert.AreEqual(200, resp.State);
            Assert.AreEqual("OK", resp.StateName);
            Assert.AreEqual("Bbb", resp.Headers["Aaa"]);
            Assert.AreEqual("Ddd", resp.Headers["Ccc"]);
            Assert.AreEqual(10, resp.ContentLength);
            Assert.AreEqual(10, resp.Data.Length);
            Assert.AreEqual("Windows-1251", resp.Charset);
            Assert.AreEqual("абвгдежзик", resp.StringData);
            Assert.True(resp.Success);
        }
Example #6
0
        public void CanReadData(int pageSize)
        {
            var b      = new StringBuilder();
            var s      = GetStream("HTTP/1.1 200 OK\r\nAaa: Bbb\r\nCcc: Ddd\r\nContent-Length: 10\r\n\r\nABCDEFGHIJ");
            var reader = new HttpResponseReader {
                BufferSize = pageSize
            };
            var resp = reader.Read(s);

            Assert.AreEqual(200, resp.State);
            Assert.AreEqual("OK", resp.StateName);
            Assert.AreEqual("Bbb", resp.Headers["Aaa"]);
            Assert.AreEqual("Ddd", resp.Headers["Ccc"]);
            Assert.AreEqual(10, resp.ContentLength);
            Assert.AreEqual(10, resp.Data.Length);
            Assert.AreEqual("ABCDEFGHIJ", resp.StringData);
            Assert.True(resp.Success);
        }
Example #7
0
        public void CanReadChunkedData(int pageSize)
        {
            var b      = new StringBuilder();
            var s      = GetStream("HTTP/1.1 200 OK\r\nAaa: Bbb\r\nCcc: Ddd\r\nTransfer-Encoding: chunked\r\n\r\n2\r\nAB\r\n3\r\nCDE\r\n5\r\nFGHIJ\r\n0\r\n");
            var reader = new HttpResponseReader {
                BufferSize = pageSize
            };
            var resp = reader.Read(s);

            Assert.AreEqual(200, resp.State);
            Assert.AreEqual("OK", resp.StateName);
            Assert.AreEqual("Bbb", resp.Headers["Aaa"]);
            Assert.AreEqual("Ddd", resp.Headers["Ccc"]);
            Assert.True(resp.Chunked);
            Assert.AreEqual("ABCDEFGHIJ", resp.StringData);
            Assert.AreEqual(10, resp.Data.Length);

            Assert.True(resp.Success);
        }
Example #8
0
        static async Task Run()
        {
            HttpClient          client   = new HttpClient();
            HttpResponseMessage response = await client.GetAsync("https://github.com");

            var reader = new HttpResponseReader <MessageResult>();

            reader.UseBrotliDecompression();
            reader.EnsureHtmlContent((x, result) => result.Html = x);
            reader.UseResponseCode((x, result) => result.Code   = (int)x);

            MessageResult res = new MessageResult();

            if (await reader.TryReadMessageAsync(response, res))
            {
                Console.WriteLine(res.Html);
                Console.WriteLine("Status code: " + res.Code);
            }

            Console.Read();
        }
Example #9
0
        public void StartWithLFFragmentTest()
        {
            var heades = Encoding.ASCII.GetBytes(@"HTTP/1.1 200
Content-Type: application/json;charset=UTF-8
Date: Mon, 03 Dec 2018 02:54:48 GMT
transfer-encoding: chunked

");

            using (var reader = new HttpResponseReader(true, 1024 * 1024 * 1024))
            {
                var tcs = new TaskCompletionSource <HttpResponse>();
                reader.ReceivedResponseBody += r => tcs.TrySetResult(r);

                reader.HandleReceive(heades, heades.Length);
                reader.HandleReceive("2\r\n");
                reader.HandleReceive("{}\r");
                reader.HandleReceive("\n0\r\n\r\n");

                var response = tcs.GetResult();
                response.GetBodyAsString().Is("{}");
            }
        }
        /// <summary>
        /// Read response from stream
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="response"></param>
        /// <param name="rewrite"></param>
        /// <returns>redirected target</returns>
        protected async Task <string> ReadAsync(Stream stream, HttpResponse response,
                                                string host, Func <string, string> rewrite)
        {
            // Now read response back and write out to response
            var reader = new HttpResponseReader(stream);

            var    isChunked       = false;
            string contentEncoding = null;
            var    headers         = new HeaderDictionary();

            // Parse headers and status code
            Console.WriteLine();
            var s = await reader.ReadLineAsync().ConfigureAwait(false); // header

            if (string.IsNullOrEmpty(s))
            {
                return(null);  // throw
            }
            Console.WriteLine(s);

            var    statusCode = int.Parse(s.Split(' ')[1]);
            string target     = null;

            while (true)
            {
                s = await reader.ReadLineAsync().ConfigureAwait(false);

                if (string.IsNullOrEmpty(s))
                {
                    break;
                }
                Console.WriteLine(s);
                var index = s.IndexOf(':');
                if (index < 0)
                {
                    continue;
                }
                var key = s.Substring(0, index).Trim();
                var val = s.Substring(index + 1).Trim();

                /**/ if (key.Equals("Transfer-Encoding",
                                    StringComparison.CurrentCultureIgnoreCase))
                {
                    isChunked = val.Equals("chunked", StringComparison.CurrentCultureIgnoreCase);
                }
                else if (key.Equals("Content-Encoding",
                                    StringComparison.CurrentCultureIgnoreCase))
                {
                    contentEncoding = val.ToLowerInvariant();
                }
                else if (key.Equals("Set-Cookie"))
                {
                    // TODO:
                    // continue;
                }
                else
                {
                    if (key.Equals("Location",
                                   StringComparison.CurrentCultureIgnoreCase))
                    {
                        target = val;
                    }
                    val = _urls.Replace(val, (f) => rewrite(f.Value));
                }
                if (headers.ContainsKey(key))
                {
                    headers.Remove(key);
                }
                headers.Add(key, val);
            }

            if (statusCode >= StatusCodes.Status300MultipleChoices ||
                statusCode < StatusCodes.Status400BadRequest)
            {
                if (!string.IsNullOrEmpty(target))
                {
                    // Redirect to new location
                    return(target);
                }
            }

            // Copy headers to response
            response.StatusCode = statusCode;
            response.Headers.Clear();
            foreach (var entry in headers)
            {
                response.Headers.Add(entry.Key, entry.Value);
            }

            if (response.StatusCode == StatusCodes.Status204NoContent ||
                response.StatusCode == StatusCodes.Status205ResetContent ||
                response.StatusCode == StatusCodes.Status304NotModified)
            {
                response.ContentLength = 0;
                await response.Body.FlushAsync();
            }
            else if (IsTextContent(response.ContentType, out var encoder))
            {
                // Remember host as fallback
                response.Cookies.Append("host", host);

                await reader.ReadBodyAsync(response, isChunked, (body, len) => {
                    if (!string.IsNullOrWhiteSpace(contentEncoding))
                    {
                        var mem = new MemoryStream(body, 0, len);
                        /**/
                        if (contentEncoding.Equals("gzip"))
                        {
                            using (var gzip = new GZipStream(mem,
                                                             CompressionMode.Decompress, false)) {
                                s = gzip.ToString(encoder);
                            }
                        }
                        else if (contentEncoding.Equals("deflate"))
                        {
                            using (var deflate = new DeflateStream(mem,
                                                                   CompressionMode.Decompress, false)) {
                                s = deflate.ToString(encoder);
                            }
                        }
                        else
                        {
                            throw new Exception("Unexpected content encoding");
                        }
                    }
Example #11
0
        public static void HandleReceive(this HttpResponseReader reader, string value)
        {
            var bytes = Encoding.ASCII.GetBytes(value);

            reader.HandleReceive(bytes, bytes.Length);
        }
Example #12
0
        public void TooLongBodyTest()
        {
            //var maxCaptureSize = ProxyConfig.MaxByteArrayLength;
            var maxCaptureSize = 10_000_000;
            var config         = new ProxyConfig
            {
                MaxCaptureSize = maxCaptureSize
            };


            var contentLengthResponseHeader = Encoding.ASCII.GetBytes(
                $@"HTTP/1.1 200 OK
Date: Thu, 20 Sep 2018 01:59:09 GMT
Content-Length: {maxCaptureSize + 1}

");

            using (var reader = new HttpResponseReader(config.IsCaptureBody, config.MaxCaptureSize))
            {
                var tcs = new TaskCompletionSource <HttpResponse>();
                reader.ReceivedResponseBody += r => tcs.TrySetResult(r);
                reader.HandleReceive(contentLengthResponseHeader, contentLengthResponseHeader.Length);
                for (var i = 0m; i < maxCaptureSize + 1;)
                {
                    Debug.WriteLine(i);
                    var length = 200000000m;
                    if (maxCaptureSize < length + i)
                    {
                        length = maxCaptureSize + 1 - i;
                    }
                    var bytes = Enumerable.Repeat((byte)0, (int)length).ToArray();
                    reader.HandleReceive(bytes, bytes.Length);
                    i += bytes.Length;
                }
                var response = tcs.GetResult();
                response.Body.Length.Is(0);
            }



            var chunkedBodyResonseHeader = Encoding.ASCII.GetBytes(
                $@"HTTP/1.1 200 OK
Date: Thu, 20 Sep 2018 01:59:09 GMT
Transfer-Encoding: chunked

");

            using (var reader = new HttpResponseReader(config.IsCaptureBody, config.MaxCaptureSize))
            {
                var tcs = new TaskCompletionSource <HttpResponse>();
                reader.ReceivedResponseBody += r => tcs.TrySetResult(r);
                reader.HandleReceive(chunkedBodyResonseHeader, chunkedBodyResonseHeader.Length);

                var lastChunk     = Encoding.ASCII.GetBytes("\r\n0\r\n\r\n");
                var maxSize       = maxCaptureSize + 1 - Convert.ToString(maxCaptureSize, 16).Length - lastChunk.Length;
                var maxSizeString = Convert.ToString(maxSize, 16);
                var chunkSize     = Encoding.ASCII.GetBytes(maxSizeString + "\r\n");

                reader.HandleReceive(chunkSize, chunkSize.Length);

                for (var i = 0m; i < maxSize;)
                {
                    Debug.WriteLine(i);
                    var length = 200000000m;
                    if (maxCaptureSize < length + i)
                    {
                        length = maxSize - i;
                    }
                    var bytes = Enumerable.Repeat((byte)0, (int)length).ToArray();
                    reader.HandleReceive(bytes, bytes.Length);
                    i += bytes.Length;
                }
                reader.HandleReceive(lastChunk, lastChunk.Length);
                var response = tcs.GetResult();
                response.Body.Length.Is(0);
            }



            var terminateWithCloseResponseHeader = Encoding.ASCII.GetBytes(
                $@"HTTP/1.1 200 OK
Date: Thu, 20 Sep 2018 01:59:09 GMT
Transfer-Encoding: hoge

");

            using (var reader = new HttpResponseReader(config.IsCaptureBody, config.MaxCaptureSize))
            {
                var tcs = new TaskCompletionSource <HttpResponse>();
                reader.ReceivedResponseBody += r => tcs.TrySetResult(r);
                reader.HandleReceive(terminateWithCloseResponseHeader, terminateWithCloseResponseHeader.Length);
                for (var i = 0m; i < maxCaptureSize + 1;)
                {
                    Debug.WriteLine(i);
                    var length = 200000000m;
                    if (maxCaptureSize < length + i)
                    {
                        length = maxCaptureSize + 1 - i;
                    }
                    var bytes = Enumerable.Repeat((byte)0, (int)length).ToArray();
                    reader.HandleReceive(bytes, bytes.Length);
                    i += bytes.Length;
                }
                reader.CloseTcp();
                var response = tcs.GetResult();
                response.Body.Length.Is(0);
            }
        }