예제 #1
0
        public void HttpParsingMultipeResponsesTest()
        {
            const string HttpString = "HTTP/1.1 200 OK\r\n" +
                                      "Transfer-Encoding: chunked\r\n" +
                                      "\r\n" +
                                      "b\r\n" +
                                      "12345678901\r\n" +
                                      "0\r\n" +
                                      "HTTP/1.1 404 Not Found\r\n" +
                                      "Content-Length: 6\r\n" +
                                      "\r\n" +
                                      "123456" +
                                      "HTTP/1.1 302 Moved\r\n" +
                                      "Transfer-Encoding: chunked\r\n" +
                                      "\r\n" +
                                      "8\r\n" +
                                      "12345678\r\n" +
                                      "0\r\n";

            Packet packet = BuildPacket(HttpString);
            var    https  = packet.Ethernet.IpV4.Tcp.HttpCollection;

            Assert.AreEqual(3, https.Count);
            foreach (HttpDatagram http in https)
            {
                Assert.IsFalse(http.IsRequest);
                Assert.IsTrue(http.IsResponse);
                Assert.AreEqual(HttpVersion.Version11, http.Version);
            }
            HttpResponseDatagram response = (HttpResponseDatagram)https[0];

            Assert.AreEqual(new Datagram(Encoding.ASCII.GetBytes("b\r\n12345678901\r\n0\r\n")), response.Body);
            Assert.AreEqual(new HttpHeader(new HttpTransferEncodingField("chunked")), response.Header);
            Assert.AreEqual(new Datagram(Encoding.ASCII.GetBytes("OK")), response.ReasonPhrase);
            Assert.AreEqual <uint>(200, response.StatusCode.Value);

            response = (HttpResponseDatagram)https[1];
            Assert.AreEqual(new Datagram(Encoding.ASCII.GetBytes("123456")), response.Body);
            Assert.AreEqual(new HttpHeader(new HttpContentLengthField(6)), response.Header);
            Assert.AreEqual(new Datagram(Encoding.ASCII.GetBytes("Not Found")), response.ReasonPhrase);
            Assert.AreEqual <uint>(404, response.StatusCode.Value);

            response = (HttpResponseDatagram)https[2];
            Assert.AreEqual(new Datagram(Encoding.ASCII.GetBytes("8\r\n12345678\r\n0\r\n")), response.Body);
            Assert.AreEqual(new HttpHeader(new HttpTransferEncodingField("chunked")), response.Header);
            Assert.AreEqual(new Datagram(Encoding.ASCII.GetBytes("Moved")), response.ReasonPhrase);
            Assert.AreEqual <uint>(302, response.StatusCode.Value);
        }
예제 #2
0
        private static bool IsBadHttp(HttpDatagram httpDatagram)
        {
            if (httpDatagram.IsResponse)
            {
                HttpResponseDatagram httpResponseDatagram = (HttpResponseDatagram)httpDatagram;
                if (httpResponseDatagram.StatusCode == null)
                {
                    Assert.IsNull(httpResponseDatagram.Header);
                    return(true);
                }
            }
            else
            {
                HttpRequestDatagram httpRequestDatagram = (HttpRequestDatagram)httpDatagram;
                if (httpRequestDatagram.Version == null)
                {
                    return(true);
                }
            }

            return(false);
        }
예제 #3
0
        private static void TestHttpResponse(string httpString, HttpVersion expectedVersion = null, uint?expectedStatusCode = null, string expectedReasonPhrase = null, HttpHeader expectedHeader = null, string expectedBodyString = null)
        {
            Datagram expectedBody = expectedBodyString == null ? null : new Datagram(Encoding.ASCII.GetBytes(expectedBodyString));

            Packet packet = BuildPacket(httpString);

            // HTTP
            HttpDatagram http = packet.Ethernet.IpV4.Tcp.Http;

            Assert.IsFalse(http.IsRequest, "IsRequest " + httpString);
            Assert.IsTrue(http.IsResponse, "IsResponse " + httpString);
            Assert.AreEqual(expectedVersion, http.Version, "Version " + httpString);
            Assert.AreEqual(expectedHeader, http.Header, "Header " + httpString);
            if (expectedHeader != null)
            {
                Assert.IsNotNull(http.Header.ToString());
            }

            HttpResponseDatagram response = (HttpResponseDatagram)http;

            Assert.AreEqual(expectedStatusCode, response.StatusCode, "StatusCode " + httpString);
            Assert.AreEqual(expectedReasonPhrase == null ? null : new Datagram(Encoding.ASCII.GetBytes(expectedReasonPhrase)), response.ReasonPhrase, "ReasonPhrase " + httpString);
            Assert.AreEqual(expectedBody, response.Body, "Body " + httpString);
        }
예제 #4
0
        public void RandomHttpTest()
        {
            int seed = new Random().Next();

            Console.WriteLine("Seed: " + seed);
            Random random = new Random(seed);

            for (int i = 0; i != 200; ++i)
            {
                EthernetLayer ethernetLayer = random.NextEthernetLayer(EthernetType.None);
                IpV4Layer     ipV4Layer     = random.NextIpV4Layer(null);
                ipV4Layer.HeaderChecksum = null;
                Layer    ipLayer  = random.NextBool() ? (Layer)ipV4Layer : random.NextIpV6Layer(true);
                TcpLayer tcpLayer = random.NextTcpLayer();
                tcpLayer.Checksum = null;
                HttpLayer httpLayer = random.NextHttpLayer();

                Packet packet = PacketBuilder.Build(DateTime.Now, ethernetLayer, ipLayer, tcpLayer, httpLayer);
                Assert.IsTrue(packet.IsValid, "IsValid");

                HttpDatagram httpDatagram = packet.Ethernet.Ip.Tcp.Http;
                Assert.AreEqual(httpLayer.Version, httpDatagram.Version);
                if (httpLayer.Version != null)
                {
                    Assert.AreEqual(httpLayer.Version.GetHashCode(), httpDatagram.Version.GetHashCode());
                }
                if (httpLayer is HttpRequestLayer)
                {
                    Assert.IsTrue(httpDatagram.IsRequest);
                    Assert.IsTrue(httpLayer.IsRequest);
                    Assert.IsFalse(httpDatagram.IsResponse);
                    Assert.IsFalse(httpLayer.IsResponse);

                    HttpRequestLayer    httpRequestLayer    = (HttpRequestLayer)httpLayer;
                    HttpRequestDatagram httpRequestDatagram = (HttpRequestDatagram)httpDatagram;
                    Assert.AreEqual(httpRequestLayer.Method, httpRequestDatagram.Method);
                    if (httpRequestLayer.Method != null)
                    {
                        Assert.AreEqual(httpRequestLayer.Method.GetHashCode(), httpRequestDatagram.Method.GetHashCode());
                        Assert.AreEqual(httpRequestLayer.Method.KnownMethod, httpRequestDatagram.Method.KnownMethod);
                    }
                    Assert.AreEqual(httpRequestLayer.Uri, httpRequestDatagram.Uri);
                }
                else
                {
                    Assert.IsFalse(httpDatagram.IsRequest);
                    Assert.IsFalse(httpLayer.IsRequest);
                    Assert.IsTrue(httpDatagram.IsResponse);
                    Assert.IsTrue(httpLayer.IsResponse);

                    HttpResponseLayer    httpResponseLayer    = (HttpResponseLayer)httpLayer;
                    HttpResponseDatagram httpResponseDatagram = (HttpResponseDatagram)httpDatagram;
                    Assert.AreEqual(httpResponseLayer.StatusCode, httpResponseDatagram.StatusCode);
                    Assert.AreEqual(httpResponseLayer.ReasonPhrase, httpResponseDatagram.ReasonPhrase);
                }
                Assert.AreEqual(httpLayer.Header, httpDatagram.Header);
                if (httpLayer.Header != null)
                {
                    Assert.AreEqual(httpLayer.Header.GetHashCode(), httpDatagram.Header.GetHashCode());
                    if (!httpDatagram.IsRequest || ((HttpRequestDatagram)httpDatagram).Uri != "")
                    {
                        Assert.IsTrue(httpDatagram.IsValidStart, "IsValidStart");
                    }

                    foreach (var field in httpLayer.Header)
                    {
                        Assert.IsFalse(field.Equals("abc"));
                    }
                    foreach (var field in (IEnumerable)httpLayer.Header)
                    {
                        Assert.IsFalse(field.Equals("abc"));
                    }

                    MoreAssert.AreSequenceEqual(httpLayer.Header.Select(field => field.GetHashCode()), httpDatagram.Header.Select(field => field.GetHashCode()));

                    if (httpLayer.Header.ContentType != null)
                    {
                        var parameters = httpLayer.Header.ContentType.Parameters;
                        Assert.IsNotNull(((IEnumerable)parameters).GetEnumerator());
                        Assert.AreEqual <object>(parameters, httpDatagram.Header.ContentType.Parameters);
                        Assert.AreEqual(parameters.GetHashCode(), httpDatagram.Header.ContentType.Parameters.GetHashCode());
                        Assert.AreEqual(parameters.Count, httpDatagram.Header.ContentType.Parameters.Count);
                        int maxParameterNameLength = parameters.Any() ? parameters.Max(pair => pair.Key.Length) : 0;
                        Assert.IsNull(parameters[new string('a', maxParameterNameLength + 1)]);
                    }
                }
                Assert.AreEqual(httpLayer.Body, httpDatagram.Body);
                Assert.AreEqual(httpLayer, httpDatagram.ExtractLayer(), "HTTP Layer");
                Assert.AreEqual(httpLayer.Length, httpDatagram.Length);
            }
        }
예제 #5
0
        public HttpResponse Get(string url, ushort port)
        {
            // Get TCP session
            if (url.StartsWith("http"))
            {
                url = url.Split(':')[1].Remove(0, 2);
            }
            if (url.Split('/').Length == 1)
            {
                url = url + "/";
            }


            bool keepWaiting = true;

            long length = 0;
            long read   = 0;
            HttpResponseDatagram response = null;
            ConcurrentDictionary <uint, byte[]> datagrams = new ConcurrentDictionary <uint, byte[]>();

            TCP.TcpSession session = Client.Tcp.Connect(url.Split('/')[0], port);
            session.PacketReceived += (packet) =>
            {
                if (packet.Type == PacketType.Http && false)
                {
                    response    = packet.Packet.Ethernet.IpV4.Tcp.Http as HttpResponseDatagram;
                    keepWaiting = false;
                    return;
                }

                var tcp = packet.Packet.Ethernet.IpV4.Tcp;
                if (tcp == null)
                {
                    return;
                }
                if (datagrams.ContainsKey(tcp.SequenceNumber))
                {
                    return;
                }
                if (tcp.Payload.ToArray() == null)
                {
                    return;
                }
                datagrams.AddOrUpdate(tcp.SequenceNumber, tcp.Payload.ToArray(), (a, b) => b);
                string str = Encoding.UTF8.GetString(tcp.Payload.ToArray());
                if (str.Contains("Content-Length: "))
                {
                    using (MemoryStream ms = new MemoryStream(tcp.Payload.ToArray()))
                        using (StreamReader reader = new StreamReader(ms))
                        {
                            int pos = 0;
                            while (!reader.EndOfStream)
                            {
                                string line = reader.ReadLine();
                                pos += line.Length + 2;
                                if (line == "")
                                {
                                    //read -= pos;
                                    break;
                                }
                            }
                        }
                    length = long.Parse(System.Text.RegularExpressions.Regex.Split(str, "Content-Length: ")[1].Split('\r')[0]);
                }
                read += tcp.Payload.ToArray().Length;

                if (read >= length && length != 0)
                {
                    keepWaiting = false;
                }
            };
            session.CloseConnection += () =>
            {
                keepWaiting = false;
            };

            TcpPacket tcpPacket = new TcpPacket();

            using (var ms = new MemoryStream())
                using (var writer = new StreamWriter(ms))
                {
                    writer.WriteLine("GET /" + url.Split('/').Last() + " HTTP/1.0");
                    writer.WriteLine("Host: " + url.Split('/')[0]);
                    writer.WriteLine("Connection: close");
                    writer.WriteLine();
                    writer.Flush();
                    tcpPacket.Layers.Add(new PayloadLayer()
                    {
                        Data = new Datagram(ms.ToArray())
                    });
                }



            tcpPacket.Destination = url.Split('/')[0];
            tcpPacket.DestPort    = port;

            session.SendPacket(tcpPacket);



            while (keepWaiting)
            {
                ;
            }

            session.Disconnect();


            if (response == null)
            {
                byte[] data = new byte[0];

                foreach (KeyValuePair <uint, byte[]> dg in (from a in datagrams orderby a.Key ascending select a))
                {
                    data = data.Concat(dg.Value).ToArray();
                }
                return(new HttpResponse(data));
            }
            else
            {
                return(new HttpResponse(response.ToArray()));
            }
        }