Beispiel #1
0
        public void HttpCreateFieldNullNameTest()
        {
            HttpField field = HttpField.CreateField(null, "cde");

            Assert.IsNull(field);
            Assert.Fail();
        }
Beispiel #2
0
        public void HttpCreateFieldNullEncodingTest()
        {
            HttpField field = HttpField.CreateField("abc", "cde", null);

            Assert.IsNull(field);
            Assert.Fail();
        }
Beispiel #3
0
        public void HttpParsingMultipeRequestsTest()
        {
            const string HttpString = "GET /url1 HTTP/1.1\r\n" +
                                      "A: B\r\n" +
                                      "B: C\r\n" +
                                      "\r\n" +
                                      "GET /url2 HTTP/1.1\r\n" +
                                      "C: D\r\n" +
                                      "D: E\r\n" +
                                      "\r\n";

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

            Assert.AreEqual(2, https.Count);
            foreach (HttpDatagram http in https)
            {
                Assert.IsTrue(http.IsRequest);
                Assert.IsFalse(http.IsResponse);
                Assert.AreEqual(HttpVersion.Version11, http.Version);
                Assert.AreEqual(Datagram.Empty, http.Body);
            }
            HttpRequestDatagram request = (HttpRequestDatagram)https[0];

            Assert.AreEqual(new HttpRequestMethod(HttpRequestKnownMethod.Get), request.Method);
            Assert.AreEqual("/url1", request.Uri);
            Assert.AreEqual(new HttpHeader(HttpField.CreateField("A", "B"), HttpField.CreateField("B", "C")), request.Header);

            request = (HttpRequestDatagram)https[1];
            Assert.AreEqual(new HttpRequestMethod(HttpRequestKnownMethod.Get), request.Method);
            Assert.AreEqual("/url2", request.Uri);
            Assert.AreEqual(new HttpHeader(HttpField.CreateField("C", "D"), HttpField.CreateField("D", "E")), request.Header);
        }
        private void SendGet(PacketCommunicator communicator)
        {
            // Ethernet Layer
            EthernetLayer ethernetLayer = new EthernetLayer
            {
                Source      = SourceMac,
                Destination = DestinationMac,
            };

            // IPv4 Layer
            IpV4Layer ipV4Layer = new IpV4Layer
            {
                Source             = SourceIpV4,
                CurrentDestination = DestinationIpV4,
                Ttl           = 128,
                Fragmentation =
                    new IpV4Fragmentation(IpV4FragmentationOptions.DoNotFragment, 0),
                Identification = 1235,
            };

            // TCP Layer
            TcpLayer tcpLayer = new TcpLayer
            {
                SourcePort           = _sourcePort,
                DestinationPort      = _destinationPort,
                SequenceNumber       = _seqNumber,
                AcknowledgmentNumber = _ackNumber,
                ControlBits          = TcpControlBits.Acknowledgment,
                Window = _windowSize,
            };

            // HTTP Layer
            HttpLayer httpLayer = new HttpRequestLayer
            {
                Uri     = "/",
                Header  = new HttpHeader(HttpField.CreateField("Host", Host)),
                Method  = new HttpRequestMethod(HttpRequestKnownMethod.Get),
                Version = HttpVersion.Version11,
            };

            Packet packet = PacketBuilder.Build(DateTime.Now, ethernetLayer, ipV4Layer, tcpLayer, httpLayer);

            communicator.SendPacket(packet);
            _expectedAckNumber = (uint)(_seqNumber + packet.Ethernet.IpV4.Tcp.PayloadLength);
        }
Beispiel #5
0
        public void SendSlowReadCompleteGet(PacketCommunicator communicator)
        {
            //// Ethernet Layer
            //var ethernetLayer = new EthernetLayer
            //{
            //    Source = SourceMac,
            //    Destination = DestinationMac,
            //};
            //
            //// IPv4 Layer
            //var ipV4Layer = new IpV4Layer
            //{
            //    Source = SourceIpV4,
            //    CurrentDestination = DestinationIpV4,
            //    Ttl = 128,
            //    Fragmentation = new IpV4Fragmentation(IpV4FragmentationOptions.DoNotFragment, 0),
            //    Identification = _identificatioNumber,
            //};
            CreateEthAndIpv4Layer(out var ethernetLayer, out var ipV4Layer);

            // TCP Layer
            //var tcpLayer = new TcpLayer
            //{
            //    SourcePort = SourcePort,
            //    DestinationPort = DestinationPort,
            //    SequenceNumber = SeqNumber,
            //    AcknowledgmentNumber = AckNumber,
            //    ControlBits = TcpControlBits.Acknowledgment,
            //    Window = WindowSize,
            //};
            CreateTcpLayer(out var tcpLayer, TcpControlBits.Acknowledgment);
            HttpRequestLayer httpRequestLayer = new HttpRequestLayer
            {
                Uri     = SlowReadUrl,
                Method  = new HttpRequestMethod(HttpRequestKnownMethod.Get),
                Version = HttpVersion.Version11,
                Header  = new HttpHeader(HttpField.CreateField("Host", Host))
            };

            var packet = PacketBuilder.Build(DateTime.Now, ethernetLayer, ipV4Layer, tcpLayer, httpRequestLayer);

            communicator.SendPacket(packet);
            SeqNumber += (uint)packet.Ethernet.IpV4.Tcp.Http.Length;
            _identificatioNumber++;
        }
Beispiel #6
0
        public static HttpField NextHttpField(this Random random, string fieldName)
        {
            switch (fieldName.ToUpperInvariant())
            {
            case HttpTransferEncodingField.FieldNameUpper:
                string[] transferCodings = ((Func <string>)(() => random.NextHttpTransferCoding())).GenerateArray(random.NextInt(1, 10));
                return(new HttpTransferEncodingField(transferCodings));

            case HttpContentLengthField.FieldNameUpper:
                return(new HttpContentLengthField(random.NextUInt(1000)));

            case HttpContentTypeField.FieldNameUpper:
                return(new HttpContentTypeField(random.NextHttpToken(), random.NextHttpToken(), random.NextHttpFieldParameters()));

            case HttpTrailerField.FieldNameUpper:
                return(new HttpTrailerField(((Func <string>)(() => random.NextHttpToken())).GenerateArray(random.NextInt(1, 5))));

            default:
                return(HttpField.CreateField(fieldName, random.NextHttpFieldValue()));
            }
        }
Beispiel #7
0
        protected override bool CompareField(XElement field, Datagram datagram)
        {
            HttpDatagram httpDatagram = (HttpDatagram)datagram;

            if (field.Name() == "data" || field.Name() == "data.data")
            {
                if (field.Name() == "data")
                {
                    field.AssertNoShow();
                }

                MoreAssert.AreSequenceEqual(httpDatagram.Subsegment(0, _data.Length / 2), HexEncoding.Instance.GetBytes(_data.ToString()));
                // TODO: Uncomment once https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10707 is fixed.
//                field.AssertValue(httpDatagram.Subsegment(_data.Length / 2 + 2, httpDatagram.Length - _data.Length / 2 - 2));
                return(false);
            }

            string fieldShow = field.Show();
            string httpFieldName;

            switch (field.Name())
            {
            case "http.request":
                field.AssertShowDecimal(httpDatagram.IsRequest);
                break;

            case "http.response":
                field.AssertShowDecimal(httpDatagram.IsResponse);
                break;

            case "":
                if (fieldShow == "HTTP chunked response")
                {
                    throw new InvalidOperationException("HTTP chunked response");
                }
                if (fieldShow == @"\r\n" || fieldShow == "HTTP response 1/1" || fieldShow == "HTTP request 1/1")
                {
                    break;
                }

                _data.Append(field.Value());

                if (_isFirstEmptyName)
                {
                    CompareHttpFirstLine(field, httpDatagram);
                    _isFirstEmptyName = false;
                }
                else if (fieldShow.StartsWith("Content-encoded entity body"))
                {
                    break;
                }
                else
                {
                    fieldShow = EncodingExtensions.Iso88591.GetString(HexEncoding.Instance.GetBytes(field.Value()));
                    fieldShow = fieldShow.Substring(0, fieldShow.Length - 2);
                    int colonIndex = fieldShow.IndexOf(':');
                    MoreAssert.IsBiggerOrEqual(0, colonIndex, "Can't find colon in field with empty name");

                    if (httpDatagram.Header == null)
                    {
                        if (httpDatagram.IsRequest)
                        {
                            Assert.IsNull(httpDatagram.Version);
                        }
                        else
                        {
                            Assert.IsTrue(IsBadHttp(httpDatagram));
                        }
                        break;
                    }
                    httpFieldName = fieldShow.Substring(0, colonIndex);
                    if (!field.Value().EndsWith("0d0a"))
                    {
                        Assert.IsNull(httpDatagram.Header[httpFieldName]);
                    }
                    else
                    {
                        string fieldValue         = fieldShow.Substring(colonIndex + 1).SkipWhile(c => c == ' ').TakeWhile(c => c != '\\').SequenceToString();
                        string expectedFieldValue = httpDatagram.Header[httpFieldName].ValueString;
                        Assert.IsTrue(expectedFieldValue.Contains(fieldValue),
                                      string.Format("{0} <{1}> doesn't contain <{2}>", field.Name(), expectedFieldValue, fieldValue));
                    }
                }
                break;

            case "data.len":
                field.AssertShowDecimal(httpDatagram.Length - _data.Length / 2);
                break;

            case "http.host":
            case "http.user_agent":
            case "http.accept":
            case "http.accept_language":
            case "http.accept_encoding":
            case "http.connection":
            case "http.cookie":
            case "http.cache_control":
            case "http.content_encoding":
            case "http.date":
            case "http.referer":
            case "http.last_modified":
            case "http.server":
            case "http.set_cookie":
            case "http.location":
                _data.Append(field.Value());
                httpFieldName = field.Name().Substring(5).Replace('_', '-');
                HttpField httpField = httpDatagram.Header[httpFieldName];
                if (!field.Value().EndsWith("0d0a"))
                {
                    Assert.IsNull(httpField);
                }
                else
                {
                    string fieldValue         = field.Show().Replace("\\\"", "\"");
                    string expectedFieldValue = httpField.ValueString;
                    Assert.IsTrue(expectedFieldValue.Contains(fieldValue),
                                  string.Format("{0} <{1}> doesn't contain <{2}>", field.Name(), expectedFieldValue, fieldValue));
                }
                break;

            case "http.content_length_header":
                _data.Append(field.Value());
                if (!IsBadHttp(httpDatagram))
                {
                    if (!field.Value().EndsWith("0d0a"))
                    {
                        Assert.IsNull(httpDatagram.Header.ContentLength);
                    }
                    else
                    {
                        field.AssertShowDecimal(httpDatagram.Header.ContentLength.ContentLength.Value);
                    }
                }
                break;

            case "http.content_type":
                _data.Append(field.Value());
                string[] mediaType = fieldShow.Split(new[] { ';', ' ', '/' }, StringSplitOptions.RemoveEmptyEntries);
                if (!IsBadHttp(httpDatagram))
                {
                    if (!field.Value().EndsWith("0d0a"))
                    {
                        Assert.IsNull(httpDatagram.Header.ContentType);
                    }
                    else
                    {
                        Assert.AreEqual(httpDatagram.Header.ContentType.MediaType, mediaType[0]);
                        Assert.AreEqual(httpDatagram.Header.ContentType.MediaSubtype, mediaType[1]);
                        int fieldShowParametersStart = fieldShow.IndexOf(';');
                        if (fieldShowParametersStart == -1)
                        {
                            Assert.IsFalse(httpDatagram.Header.ContentType.Parameters.Any());
                        }
                        else
                        {
                            string expected =
                                httpDatagram.Header.ContentType.Parameters.Select(pair => pair.Key + '=' + pair.Value.ToWiresharkLiteral()).
                                SequenceToString(';');
                            Assert.AreEqual(expected, fieldShow.Substring(fieldShowParametersStart + 1));
                        }
                    }
                }
                break;

            case "http.request.line":
            case "http.response.line":
                if (_data.ToString().EndsWith(field.Value()))
                {
                    break;
                }
                {
                    _data.Append(field.Value());
                }
                break;

            case "http.transfer_encoding":
                if (!IsBadHttp(httpDatagram))
                {
                    Assert.AreEqual(fieldShow.ToWiresharkLowerLiteral(),
                                    httpDatagram.Header.TransferEncoding.TransferCodings.SequenceToString(',').ToLowerInvariant().ToWiresharkLiteral());
                }
                break;

            case "http.request.full_uri":
                // TODO: Uncomment when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10681 is fixed.
                // Assert.AreEqual(fieldShow, ("http://" + httpDatagram.Header["Host"].ValueString + ((HttpRequestDatagram)httpDatagram).Uri).ToWiresharkLiteral());
                break;

            default:
                throw new InvalidOperationException("Invalid HTTP field " + field.Name());
            }

            return(true);
        }
Beispiel #8
0
        public void HttpParsingTest()
        {
            // Request First Line
            TestHttpRequest("");
            TestHttpRequest(" ");
            TestHttpRequest("G", "G");
            TestHttpRequest("GET", "GET");
            TestHttpRequest("GET ", "GET", "");
            TestHttpRequest("GET /url", "GET", "/url");
            TestHttpRequest("GET /url ", "GET", "/url");
            TestHttpRequest("GET /url H", "GET", "/url");
            TestHttpRequest("GET /url HTTP/", "GET", "/url");
            TestHttpRequest("GET /url HTTP/1.0", "GET", "/url", HttpVersion.Version10);
            TestHttpRequest("GET /url HTTP/1234567890.0", "GET", "/url"); // Version
            TestHttpRequest("GET /url HTTP/1.1", "GET", "/url", HttpVersion.Version11);
            TestHttpRequest("GET /url HTTP/1.1A", "GET", "/url", HttpVersion.Version11);
            TestHttpRequest("GET /url  HTTP/1.1", "GET", "/url");
            TestHttpRequest("GET  HTTP/1.1", "GET", "", HttpVersion.Version11);
            TestHttpRequest("GET /url HTTP/1.1\r\n", "GET", "/url", HttpVersion.Version11, HttpHeader.Empty);

            // Request Header
            TestHttpRequest("GET /url HTTP/1.1\r\n" +
                            "Cache-Control: no-cache\r\n",
                            "GET", "/url", HttpVersion.Version11,
                            new HttpHeader(
                                HttpField.CreateField("Cache-Control", "no-cache")));

            TestHttpRequest("GET /url HTTP/1.1\r\n" +
                            "A:B\r\n" +
                            "B: C\r\n" +
                            "C: \r\n \r\n D\r\n" +
                            "D: E\r\n" +
                            "D: F\r\n" +
                            "E: G,H\r\n" +
                            "E: I,J\r\n",
                            "GET", "/url", HttpVersion.Version11,
                            new HttpHeader(
                                HttpField.CreateField("A", "B"),
                                HttpField.CreateField("B", "C"),
                                HttpField.CreateField("C", "D"),
                                HttpField.CreateField("D", "E,F"),
                                HttpField.CreateField("E", "G,H,I,J")));

            TestHttpRequest("GET /url HTTP/1.1\r\n" +
                            "\r\n" +
                            "A: B\r\n",
                            "GET", "/url", HttpVersion.Version11,
                            new HttpHeader(), string.Empty);

            TestHttpRequest("GET /url HTTP/1.1\r\n" +
                            "A: B\r\n" +
                            "\r\n" +
                            "B: C\r\n",
                            "GET", "/url", HttpVersion.Version11,
                            new HttpHeader(
                                HttpField.CreateField("A", "B")), string.Empty);

            TestHttpRequest("GET /url HTTP/1.1\r\n" +
                            "A: B\r\n" +
                            "abc\r\n" +
                            "B: C\r\n",
                            "GET", "/url", HttpVersion.Version11,
                            new HttpHeader(
                                HttpField.CreateField("A", "B")));

            TestHttpRequest("GET /url HTTP/1.1\r\n" +
                            "A: B\r\n" +
                            "abc:\r\n" +
                            "B: C\r\n",
                            "GET", "/url", HttpVersion.Version11,
                            new HttpHeader(
                                HttpField.CreateField("A", "B"),
                                HttpField.CreateField("abc", ""),
                                HttpField.CreateField("B", "C")));

            TestHttpRequest("GET /url HTTP/1.1\r\n" +
                            "A:B\r\n" +
                            "B",
                            "GET", "/url", HttpVersion.Version11,
                            new HttpHeader(HttpField.CreateField("A", "B")));

            TestHttpRequest("GET /url HTTP/1.1\r\n" +
                            "A:B\r\n" +
                            "B\r\n",
                            "GET", "/url", HttpVersion.Version11,
                            new HttpHeader(HttpField.CreateField("A", "B")));

            TestHttpRequest("GET /url HTTP/1.1\r\n" +
                            "A:B\r\n" +
                            "B\r\n" +
                            "C:D\r\n",
                            "GET", "/url", HttpVersion.Version11,
                            new HttpHeader(HttpField.CreateField("A", "B")));

            TestHttpRequest("GET /url HTTP/1.1\r\n" +
                            "A:B\r\n" +
                            "B:",
                            "GET", "/url", HttpVersion.Version11,
                            new HttpHeader(HttpField.CreateField("A", "B")));

            TestHttpRequest("GET /url HTTP/1.1\r\n" +
                            "A:B\r\n" +
                            "B:\r\n",
                            "GET", "/url", HttpVersion.Version11,
                            new HttpHeader(HttpField.CreateField("A", "B"),
                                           HttpField.CreateField("B", string.Empty)));

            TestHttpRequest("GET /url HTTP/1.1\r\n" +
                            "A:B\r\n" +
                            "B:\r\n" +
                            "C:D\r\n",
                            "GET", "/url", HttpVersion.Version11,
                            new HttpHeader(HttpField.CreateField("A", "B"),
                                           HttpField.CreateField("B", string.Empty),
                                           HttpField.CreateField("C", "D")));

            // Request Body
            TestHttpRequest("GET /url HTTP/1.1\r\n" +
                            "\r\n",
                            "GET", "/url", HttpVersion.Version11,
                            HttpHeader.Empty,
                            string.Empty);

            TestHttpRequest("GET /url HTTP/1.1\r\n" +
                            "Content-Length: 10\r\n" +
                            "\r\n" +
                            "1234567890",
                            "GET", "/url", HttpVersion.Version11,
                            new HttpHeader(new HttpContentLengthField(10)),
                            "1234567890");

            // Response

            TestHttpResponse("HTTP/");
            TestHttpResponse("HTTP/1");
            TestHttpResponse("HTTP/1.");
            TestHttpResponse("HTTP/1.0", HttpVersion.Version10);
            TestHttpResponse("HTTP/1.0 ", HttpVersion.Version10);
            TestHttpResponse("HTTP/1.0 A", HttpVersion.Version10);
            TestHttpResponse("HTTP/1.0 200", HttpVersion.Version10, 200);
            TestHttpResponse("HTTP/1.0 200 ", HttpVersion.Version10, 200, "");
            TestHttpResponse("HTTP/1.0 200 OK", HttpVersion.Version10, 200, "OK");
            TestHttpResponse("HTTP/1.1 200 OK", HttpVersion.Version11, 200, "OK");
            TestHttpResponse("HTTP/1.1  200 OK", HttpVersion.Version11);
            TestHttpResponse("HTTP/1.1 200  OK", HttpVersion.Version11, 200, "OK");

            // Response Header

            TestHttpResponse("HTTP/1.1 200 OK\r\n" +
                             "Cache-Control: no-cache\r\n",
                             HttpVersion.Version11, 200, "OK",
                             new HttpHeader(
                                 HttpField.CreateField("Cache-Control", "no-cache")));

            TestHttpResponse("HTTP/1.1 200 OK\r\n" +
                             "Transfer-Encoding: chunked,a,   b   , c\r\n\t,d   , e;f=g;h=\"ijk lmn\"\r\n",
                             HttpVersion.Version11, 200, "OK",
                             new HttpHeader(
                                 new HttpTransferEncodingField("chunked", "a", "b", "c", "d", "e;f=g;h=\"ijk lmn\"")));

            // Illegal byte in double quotes.
            TestHttpResponse("HTTP/1.1 200 OK\r\n" +
                             "Transfer-Encoding: chunked,a,   b   , c\r\n\t,d   , e;f=g;h=\"\x1Fjk lmn\"\r\n",
                             HttpVersion.Version11, 200, "OK",
                             new HttpHeader());

            // Respone Body

            TestHttpResponse("HTTP/1.1 200 OK\r\n" +
                             "\r\n" +
                             "Body",
                             HttpVersion.Version11, 200, "OK", HttpHeader.Empty,
                             "Body");

            TestHttpResponse("HTTP/1.1 200 OK\r\n" +
                             "Transfer-Encoding: chunked\r\n" +
                             "\r\n" +
                             "5\r\n" +
                             "This \r\n" +
                             "3;Extension\r\n" +
                             "is \r\n" +
                             "a;Extension=Value\r\n" +
                             "the 123456\r\n" +
                             "A;Extension=\"Quoted \\\" Value\"\r\n" +
                             "body 12345\r\n" +
                             "0\r\n",
                             HttpVersion.Version11, 200, "OK", new HttpHeader(new HttpTransferEncodingField("chunked")),
                             "5\r\n" +
                             "This \r\n" +
                             "3;Extension\r\n" +
                             "is \r\n" +
                             "a;Extension=Value\r\n" +
                             "the 123456\r\n" +
                             "A;Extension=\"Quoted \\\" Value\"\r\n" +
                             "body 12345\r\n" +
                             "0\r\n");

            TestHttpResponse("HTTP/1.1 200 OK\r\n" +
                             "Transfer-Encoding: chunked\r\n" +
                             "\r\n" +
                             "g\r\n" +
                             "12345678901234567890\r\n" +
                             "0\r\n",
                             HttpVersion.Version11, 200, "OK", new HttpHeader(new HttpTransferEncodingField("chunked")),
                             string.Empty);

            TestHttpResponse("HTTP/1.1 200 OK\r\n" +
                             "Content-Length: 16\r\n" +
                             "\r\n" +
                             "This is the body",
                             HttpVersion.Version11, 200, "OK", new HttpHeader(new HttpContentLengthField(16)),
                             "This is the body");

            TestHttpResponse("HTTP/1.1 206 Partial content\r\n" +
                             "Date: Wed, 15 Nov 1995 06:25:24 GMT\r\n" +
                             "Last-modified: Wed, 15 Nov 1995 04:58:08 GMT\r\n" +
                             "Content-type: multipart/byteranges; boundary=THIS_STRING_SEPARATES\r\n" +
                             "\r\n" +
                             "--THIS_STRING_SEPARATES\r\n" +
                             "Content-type: application/pdf\r\n" +
                             "Content-range: bytes 500-999/8000\r\n" +
                             "\r\n" +
                             "...the first range...\r\n" +
                             "--THIS_STRING_SEPARATES\r\n" +
                             "Content-type: application/pdf\r\n" +
                             "Content-range: bytes 7000-7999/8000\r\n" +
                             "\r\n" +
                             "...the second range\r\n" +
                             "--THIS_STRING_SEPARATES--",
                             HttpVersion.Version11, 206, "Partial content",
                             new HttpHeader(
                                 HttpField.CreateField("Date", "Wed, 15 Nov 1995 06:25:24 GMT"),
                                 HttpField.CreateField("Last-modified", "Wed, 15 Nov 1995 04:58:08 GMT"),
                                 new HttpContentTypeField("multipart", "byteranges",
                                                          new HttpFieldParameters(new KeyValuePair <string, string>("boundary", "THIS_STRING_SEPARATES")))),
                             "--THIS_STRING_SEPARATES\r\n" +
                             "Content-type: application/pdf\r\n" +
                             "Content-range: bytes 500-999/8000\r\n" +
                             "\r\n" +
                             "...the first range...\r\n" +
                             "--THIS_STRING_SEPARATES\r\n" +
                             "Content-type: application/pdf\r\n" +
                             "Content-range: bytes 7000-7999/8000\r\n" +
                             "\r\n" +
                             "...the second range\r\n" +
                             "--THIS_STRING_SEPARATES--");
        }