Пример #1
0
            public void PrefetchedBytes_ReadHeaderAndSkipBody()
            {
                using (MessageSample sample = CreateMessageSample()) {
                    // ARRANGE
                    sample.AppendHeader(
                        "GET / HTTP/1.1",
                        "Host: www.example.org",
                        "Content-Length: 3",
                        ""
                        );
                    sample.AppendBody("ABC");

                    // insert 0-length body message in the middle of sequence
                    // In prefetched bytes processing, 0-length body handling is mistakable.
                    sample.AppendHeader(
                        "HEAD / HTTP/1.1",
                        "Host: www.example.org",
                        ""
                        );
                    sample.AppendBody(MessageSample.EmptyBody);

                    sample.AppendHeader(
                        "CONNECT www.example.org:443 HTTP/1.1",
                        "Host: www.example.org",
                        ""
                        );
                    sample.AppendBody(MessageSample.EmptyBody);

                    // The body length should be in range of 'tiny' length.
                    // "prefetched bytes" occurs when the body is 'tiny' length for simple body.
                    // In this case, whole three messages are on one memory block.
                    Debug.Assert(sample.SampleWriterPosition < ComponentFactory.MemoryBlockCache.MemoryBlockSize);

                    // ACT & ASSERT
                    int counter            = 0;
                    int actualMessageCount = TestReadHeaderAndSkipBody(sample, (request) => {
                        switch (counter)
                        {
                        case 0:
                            Assert.Equal("GET", request.Method);
                            Assert.Equal(3, request.ContentLength);
                            break;

                        case 1:
                            Assert.Equal("HEAD", request.Method);
                            Assert.Equal(0, request.ContentLength);
                            break;

                        case 2:
                            Assert.Equal("CONNECT", request.Method);
                            Assert.Equal(0, request.ContentLength);
                            break;
                        }
                        ++counter;
                    });
                    Assert.Equal(3, actualMessageCount);
                    sample.AssertAllSampleBytesRead();
                }
            }
Пример #2
0
            public void PrefetchedBytes_ReadHeaderAndSkipBody()
            {
                using (MessageSample sample = CreateMessageSample()) {
                    // ARRANGE
                    sample.AppendHeader(
                        "HTTP/1.1 200 OK",
                        "Content-Length: 7",
                        ""
                        );
                    sample.AppendBody("1234567");

                    // insert 0-length body message in the middle of sequence
                    // In prefetched bytes processing, 0-length body handling is mistakable.
                    sample.AppendHeader(
                        "HTTP/1.1 302 Found",
                        ""
                        );
                    sample.AppendBody(MessageSample.EmptyBody);

                    sample.AppendHeader(
                        "HTTP/1.1 404 Not Found",
                        "Content-Length: 0",
                        ""
                        );
                    sample.AppendBody(MessageSample.EmptyBody);

                    // The body length should be in range of 'tiny' length.
                    // "prefetched bytes" occurs when the body is 'tiny' length for simple body.
                    // In this case, whole three messages are on one memory block.
                    Debug.Assert(sample.SampleWriterPosition < ComponentFactory.MemoryBlockCache.MemoryBlockSize);

                    // ACT & ASSERT
                    int counter            = 0;
                    int actualMessageCount = TestReadHeaderAndSkipBody(sample, (response) => {
                        switch (counter)
                        {
                        case 0:
                            Assert.Equal(200, response.StatusCode);
                            Assert.Equal(7, response.ContentLength);
                            break;

                        case 1:
                            Assert.Equal(302, response.StatusCode);
                            Assert.Equal(0, response.ContentLength);
                            break;

                        case 2:
                            Assert.Equal(404, response.StatusCode);
                            Assert.Equal(0, response.ContentLength);
                            break;
                        }
                        ++counter;
                    });
                    Assert.Equal(3, actualMessageCount);
                    sample.AssertAllSampleBytesRead();
                }
            }
Пример #3
0
            public void Modification_remove()
            {
                using (MessageSample sample = CreateMessageSample()) {
                    // ARRANGE
                    sample.AppendHeader(
                        "GET / HTTP/1.1",
                        "Host: www.example.org",
                        "Proxy-Authorization: dXNlcjpwYXNz",
                        ""
                        );
                    sample.AppendBody(MessageSample.EmptyBody);

                    string expectedOutput = string.Join(
                        MessageSample.CRLF,                           // separator
                        "GET / HTTP/1.1",
                        "Host: www.example.org",
                        "",
                        MessageSample.EmptyBody
                        );

                    // ACT & ASSERT
                    int actualMessageCount = TestReadAndWrite(sample, (request) => {
                        // remove the existing field
                        request.AddModification(
                            request.ProxyAuthorizationSpan,
                            (modifier) => true                                          // remove
                            );
                    });
                    Assert.Equal(1, actualMessageCount);
                    sample.AssertOutputEqualTo(expectedOutput);
                }
            }
Пример #4
0
            public void Modification_append()
            {
                using (MessageSample sample = CreateMessageSample()) {
                    // ARRANGE
                    sample.AppendHeader(
                        "GET / HTTP/1.1",
                        "Host: www.example.org",
                        ""
                        );
                    sample.AppendBody(MessageSample.EmptyBody);

                    string expectedOutput = string.Join(
                        MessageSample.CRLF,                             // separator
                        "GET / HTTP/1.1",
                        "Host: www.example.org",
                        "X-Test: dummy",
                        "",
                        MessageSample.EmptyBody
                        );

                    Func <Modifier, bool> handler = (modifier) => {
                        modifier.WriteASCIIString("X-Test: dummy", appendCRLF: true);
                        return(true);
                    };

                    // ACT & ASSERT
                    int actualMessageCount = TestReadAndWrite(sample, (request) => {
                        // append a field
                        request.AddModification(request.EndOfHeaderFields, handler);
                    });
                    Assert.Equal(1, actualMessageCount);
                    sample.AssertOutputEqualTo(expectedOutput);
                }
            }
Пример #5
0
            public void Body_Tiny()
            {
                using (MessageSample sample = CreateMessageSample()) {
                    // ARRANGE
                    sample.AppendHeader(
                        "PUT / HTTP/1.1",
                        "Host: www.example.org:80",
                        "Content-Length: 5",
                        ""
                        );
                    sample.AppendBody("12345");

                    // The body length should be in range of 'tiny' length.
                    // That is, the whole message must be stored in one memory block.
                    // In a Request object, 'tiny' length body is stored in the rest of header's memory block.
                    Debug.Assert(sample.SampleWriterPosition < ComponentFactory.MemoryBlockCache.MemoryBlockSize);

                    // ACT & ASSERT
                    int actualMessageCount = TestReadAndWrite(sample, (request) => {
                        Assert.Equal(5, request.ContentLength);
                    });
                    Assert.Equal(1, actualMessageCount);
                    sample.AssertOutputEqualToSample();
                }
            }
Пример #6
0
            public void Modification_suppressModification()
            {
                using (MessageSample sample = CreateMessageSample()) {
                    // ARRANGE
                    sample.AppendHeader(
                        "GET http://www.example.org/test/index.html?abc=def HTTP/1.1",
                        "Host: www.example.org",
                        ""
                        );
                    sample.AppendBody(MessageSample.EmptyBody);

                    // ACT & ASSERT
                    int actualMessageCount = TestReadAndWrite(sample, (request) => {
                        request.AddModification(
                            request.RequestTargetSpan,
                            (modifier) => {
                            modifier.WriteASCIIString(request.TargetUri.PathAndQuery);
                            return(true);
                        }
                            );
                    }, request: null, suppressModification: true);                      // suppressModification!
                    Assert.Equal(1, actualMessageCount);
                    sample.AssertOutputEqualToSample();
                }
            }
Пример #7
0
            public void RequestTarget_AuthorityForm_without_port()
            {
                using (MessageSample sample = CreateMessageSample()) {
                    // ARRANGE
                    sample.AppendHeader(
                        "CONNECT www.example.org HTTP/1.1",
                        "Host: www.example.org:400",                            // dare to give different value from request-target for test
                        ""
                        );
                    sample.AppendBody(MessageSample.EmptyBody);

                    // ACT & ASSERT
                    int actualMessageCount = TestReadAndWrite(sample, (request) => {
                        // HostEndPoint and Host are derived from the request-target.
                        Assert.Equal(new DnsEndPoint("www.example.org", 443), request.HostEndPoint);
                        Assert.Equal("www.example.org:443", request.Host);

                        // HostSpan is the span of the actual Host field.
                        Assert.Equal(new Span(34, 61), request.HostSpan);

                        // TargetUri is null for request-target of authority-form
                        Assert.Equal(null, request.TargetUri);
                    });
                    Assert.Equal(1, actualMessageCount);
                    sample.AssertOutputEqualToSample();
                }
            }
Пример #8
0
            public void RequestTarget_AbsoluteForm()
            {
                using (MessageSample sample = CreateMessageSample()) {
                    // ARRANGE
                    sample.AppendHeader(
                        "GET http://www.example.org/abc/def?ghij=kl HTTP/1.1",
                        "Host: test.example.org:123",                           // dare to give different value from request-target for test
                        ""
                        );
                    sample.AppendBody(MessageSample.EmptyBody);

                    // ACT & ASSERT
                    int actualMessageCount = TestReadAndWrite(sample, (request) => {
                        // HostEndPoint and Host are derived from the request-target.
                        Assert.Equal(new DnsEndPoint("www.example.org", 80), request.HostEndPoint);
                        Assert.Equal("www.example.org:80", request.Host);

                        // HostSpan is the span of the actual Host field.
                        Assert.Equal(new Span(53, 81), request.HostSpan);

                        Assert.Equal(new Uri("http://www.example.org/abc/def?ghij=kl"), request.TargetUri);
                    });
                    Assert.Equal(1, actualMessageCount);
                    sample.AssertOutputEqualToSample();
                }
            }
Пример #9
0
            public void Modification_change()
            {
                using (MessageSample sample = CreateMessageSample()) {
                    // ARRANGE
                    sample.AppendHeader(
                        "GET http://www.example.org/test/index.html?abc=def HTTP/1.1",
                        "Host: www.example.org",
                        ""
                        );
                    sample.AppendBody(MessageSample.EmptyBody);

                    string expectedOutput = string.Join(
                        MessageSample.CRLF,                           // separator
                        "GET /test/index.html?abc=def HTTP/1.1",
                        "Host: www.example.org",
                        "",
                        MessageSample.EmptyBody
                        );

                    // ACT & ASSERT
                    int actualMessageCount = TestReadAndWrite(sample, (request) => {
                        // change the existing field
                        request.AddModification(
                            request.RequestTargetSpan,
                            (modifier) => {
                            modifier.WriteASCIIString(request.TargetUri.PathAndQuery);
                            return(true);
                        }
                            );
                    });
                    Assert.Equal(1, actualMessageCount);
                    sample.AssertOutputEqualTo(expectedOutput);
                }
            }
Пример #10
0
            public void Header_Large()
            {
                using (MessageSample sample = CreateMessageSample()) {
                    // ARRANGE
                    sample.AppendHeader(
                        "HTTP/1.1 200 OK"
                        );
                    for (int i = 0; i < 50; ++i)
                    {
                        sample.AppendText($"X-Test-{i}: 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789", appendCRLF: true);
                    }
                    sample.AppendHeader(
                        ""
                        );
                    // This sample header to be tested must consume more than two memory blocks.
                    Debug.Assert(ComponentFactory.MemoryBlockCache.MemoryBlockSize < sample.SampleWriterPosition);
                    sample.AppendBody(MessageSample.EmptyBody);

                    // ACT & ASSERT
                    int actualMessageCount = TestReadAndWrite(sample, (response) => {
                        Assert.Equal(200, response.StatusCode);
                    });
                    Assert.Equal(1, actualMessageCount);
                    sample.AssertOutputEqualToSample();
                }
            }
Пример #11
0
            public void Modification_append_samepoint()
            {
                using (MessageSample sample = CreateMessageSample()) {
                    // ARRANGE
                    sample.AppendHeader(
                        "GET / HTTP/1.1",
                        "Host: www.example.org",
                        ""
                        );
                    sample.AppendBody(MessageSample.EmptyBody);

                    // keep the order of X-Test-1, X-Test-2 and X-Test-3.
                    string expectedOutput = string.Join(
                        MessageSample.CRLF,                           // separator
                        "GET / HTTP/1.1",
                        "Host: www.example.org",
                        "X-Test-1: dummy",
                        "X-Test-2: dummy",
                        "X-Test-3: dummy",
                        "",
                        MessageSample.EmptyBody
                        );

                    Func <Modifier, bool> handler1 = (modifier) => {
                        modifier.WriteASCIIString("X-Test-1: dummy", appendCRLF: true);
                        return(true);
                    };
                    Func <Modifier, bool> handler2 = (modifier) => {
                        modifier.WriteASCIIString("X-Test-2: dummy", appendCRLF: true);
                        return(true);
                    };
                    Func <Modifier, bool> handler3 = (modifier) => {
                        modifier.WriteASCIIString("X-Test-3: dummy", appendCRLF: true);
                        return(true);
                    };

                    // ACT & ASSERT
                    int actualMessageCount = TestReadAndWrite(sample, (request) => {
                        Span span = request.EndOfHeaderFields;
                        Debug.Assert(span.Length == 0);

                        // add at the same point
                        request.AddModification(span, handler1);
                        request.AddModification(span, handler2);
                        request.AddModification(span, handler3);
                    });
                    Assert.Equal(1, actualMessageCount);
                    sample.AssertOutputEqualTo(expectedOutput);
                }
            }
Пример #12
0
            public void StatusCode_TooShortDigits()
            {
                using (MessageSample sample = CreateMessageSample()) {
                    // ARRANGE
                    sample.AppendHeader(
                        "HTTP/1.1 20 Invalid Status Code",                              // status-code: too short digits!
                        ""
                        );
                    sample.AppendBody(MessageSample.EmptyBody);

                    // ACT & ASSERT
                    HttpException exception = Assert.Throws <HttpException>(
                        () => TestReadAndWrite(sample)
                        );
                    Assert.Equal(HttpStatusCode.BadGateway, exception.HttpStatusCode);
                }
            }
Пример #13
0
            public void Version_LowerCaseHTTPName()
            {
                using (MessageSample sample = CreateMessageSample()) {
                    // ARRANGE
                    sample.AppendHeader(
                        "http/1.1 200 OK",                          //  HTTP-version: invalid!
                        ""
                        );
                    sample.AppendBody(MessageSample.EmptyBody);

                    // ACT & ASSERT
                    HttpException exception = Assert.Throws <HttpException>(
                        () => TestReadAndWrite(sample)
                        );
                    Assert.Equal(HttpStatusCode.BadGateway, exception.HttpStatusCode);
                }
            }
Пример #14
0
            public void Version_InvalidDigits()
            {
                using (MessageSample sample = CreateMessageSample()) {
                    // ARRANGE
                    sample.AppendHeader(
                        "GET / HTTP/1.1.2",                         // HTTP-version: invalid!
                        "Host: www.example.org",
                        ""
                        );
                    sample.AppendBody(MessageSample.EmptyBody);

                    // ACT & ASSERT
                    HttpException actual = Assert.Throws <HttpException>(
                        () => TestReadAndWrite(sample)
                        );
                    Assert.Equal(HttpStatusCode.BadRequest, actual.HttpStatusCode);
                }
            }
Пример #15
0
            public void StatusCode_407()
            {
                using (MessageSample sample = CreateMessageSample()) {
                    // ARRANGE
                    sample.AppendHeader(
                        "HTTP/1.1 407 Proxy Authentication Required",
                        ""
                        );
                    sample.AppendBody(MessageSample.EmptyBody);

                    // ACT & ASSERT
                    int actualMessageCount = TestReadAndWrite(sample, (response) => {
                        Assert.Equal(407, response.StatusCode);
                    });
                    Assert.Equal(1, actualMessageCount);
                    sample.AssertOutputEqualToSample();
                }
            }
Пример #16
0
            public void SkipBody()
            {
                using (MessageSample sample = CreateMessageSample()) {
                    // ARRANGE
                    sample.AppendHeader(
                        "HTTP/1.1 200 OK",
                        "Content-Length: 7",
                        ""
                        );
                    sample.AppendBody("ABCDEFG");

                    // ACT & ASSERT
                    int actualMessageCount = TestReadHeaderAndSkipBody(sample, (response) => {
                        Assert.Equal(7, response.ContentLength);
                    });
                    Assert.Equal(1, actualMessageCount);
                    sample.AssertAllSampleBytesRead();
                }
            }
Пример #17
0
            public void Version_10()
            {
                using (MessageSample sample = CreateMessageSample()) {
                    // ARRANGE
                    sample.AppendHeader(
                        "HTTP/1.0 200 OK",
                        ""
                        );
                    sample.AppendBody(MessageSample.EmptyBody);

                    // ACT & ASSERT
                    int actualMessageCount = TestReadAndWrite(sample, (response) => {
                        Assert.Equal(new Version(1, 0), response.Version);
                        Assert.Equal(200, response.StatusCode);
                    });
                    Assert.Equal(1, actualMessageCount);
                    sample.AssertOutputEqualToSample();
                }
            }
Пример #18
0
            public void Method_CONNECT()
            {
                using (MessageSample sample = CreateMessageSample()) {
                    // ARRANGE
                    sample.AppendHeader(
                        "CONNECT www.example.org:443 HTTP/1.1",
                        "Host: www.example.org:443",
                        ""
                        );
                    sample.AppendBody(MessageSample.EmptyBody);

                    // ACT & ASSERT
                    int actualMessageCount = TestReadAndWrite(sample, (request) => {
                        Assert.Equal("CONNECT", request.Method);
                        Assert.Equal(true, request.IsConnectMethod);
                    });
                    Assert.Equal(1, actualMessageCount);
                    sample.AssertOutputEqualToSample();
                }
            }
Пример #19
0
            public void Simple()
            {
                using (MessageSample sample = CreateMessageSample()) {
                    // ARRANGE
                    sample.AppendHeader(
                        "GET / HTTP/1.1",
                        "Host: www.example.org",
                        ""
                        );
                    sample.AppendBody(MessageSample.EmptyBody);

                    // ACT & ASSERT
                    int actualMessageCount = TestReadAndWrite(sample, (request) => {
                        Assert.Equal("GET", request.Method);
                        Assert.Equal(new Version(1, 1), request.Version);
                        Assert.Equal("www.example.org:80", request.Host);
                    });
                    Assert.Equal(1, actualMessageCount);
                    sample.AssertOutputEqualToSample();
                }
            }
Пример #20
0
            public void Method_POST()
            {
                using (MessageSample sample = CreateMessageSample()) {
                    // ARRANGE
                    sample.AppendHeader(
                        "POST / HTTP/1.1",
                        "Host: www.example.org",
                        "Content-Length: 3",
                        ""
                        );
                    sample.AppendBody("123");

                    // ACT & ASSERT
                    int actualMessageCount = TestReadAndWrite(sample, (request) => {
                        Assert.Equal("POST", request.Method);
                        Assert.Equal("www.example.org:80", request.Host);
                        Assert.Equal(3, request.ContentLength);
                    });
                    Assert.Equal(1, actualMessageCount);
                    sample.AssertOutputEqualToSample();
                }
            }
Пример #21
0
            public void Modification_cancel()
            {
                using (MessageSample sample = CreateMessageSample()) {
                    // ARRANGE
                    sample.AppendHeader(
                        "GET / HTTP/1.1",
                        "Host: www.example.org",
                        ""
                        );
                    sample.AppendBody(MessageSample.EmptyBody);

                    // ACT & ASSERT
                    int actualMessageCount = TestReadAndWrite(sample, (request) => {
                        request.AddModification(
                            request.HostSpan,
                            (modifier) => false                                         // cancel modification!
                            );
                    });
                    Assert.Equal(1, actualMessageCount);
                    sample.AssertOutputEqualToSample();
                }
            }
Пример #22
0
            public void RequestTarget_AsteriskForm()
            {
                using (MessageSample sample = CreateMessageSample()) {
                    // ARRANGE
                    sample.AppendHeader(
                        "OPTIONS * HTTP/1.1",
                        "Host: www.example.org:80",
                        ""
                        );
                    sample.AppendBody(MessageSample.EmptyBody);

                    // ACT & ASSERT
                    int actualMessageCount = TestReadAndWrite(sample, (request) => {
                        Assert.Equal(new DnsEndPoint("www.example.org", 80), request.HostEndPoint);
                        Assert.Equal("www.example.org:80", request.Host);
                        Assert.Equal(new Span(20, 46), request.HostSpan);

                        // TargetUri is null for request-target of asterisk-form
                        Assert.Equal(null, request.TargetUri);
                    });
                    Assert.Equal(1, actualMessageCount);
                    sample.AssertOutputEqualToSample();
                }
            }
Пример #23
0
            public void RequestTarget_OriginForm()
            {
                using (MessageSample sample = CreateMessageSample()) {
                    // ARRANGE
                    sample.AppendHeader(
                        "GET /abc/def?ghi=kl HTTP/1.1",                         // origin-form
                        "Host: www.example.org:81",
                        ""
                        );
                    sample.AppendBody(MessageSample.EmptyBody);

                    // ACT & ASSERT
                    int actualMessageCount = TestReadAndWrite(sample, (request) => {
                        Assert.Equal(new DnsEndPoint("www.example.org", 81), request.HostEndPoint);
                        Assert.Equal("www.example.org:81", request.Host);
                        Assert.Equal(new Span(30, 56), request.HostSpan);

                        // TargetUri is null for request-target of origin-form
                        Assert.Equal(null, request.TargetUri);
                    });
                    Assert.Equal(1, actualMessageCount);
                    sample.AssertOutputEqualToSample();
                }
            }
Пример #24
0
            public void Redirect_Tiny()
            {
                using (MessageSample sample = CreateMessageSample()) {
                    // ARRANGE
                    sample.AppendHeader(
                        "HTTP/1.1 200 OK",
                        "Content-Length: 10",
                        ""
                        );
                    sample.AppendBody("0123456789");

                    // The body length should be in range of 'tiny' length.
                    // That is, the whole message must be stored in one memory block.
                    // In a Response object, 'tiny' length body is stored in the rest of header's memory block.
                    Debug.Assert(sample.SampleWriterPosition < ComponentFactory.MemoryBlockCache.MemoryBlockSize);

                    // ACT & ASSERT
                    int actualMessageCount = TestReadHeaderAndRedirect(sample, (response) => {
                        Assert.Equal(10, response.ContentLength);
                    });
                    Assert.Equal(1, actualMessageCount);
                    sample.AssertOutputEqualToSample();
                }
            }
Пример #25
0
            public void PrefetchedBytes_InputReconnect()
            {
                using (MessageSample sample = CreateMessageSample()) {
                    // ARRANGE
                    sample.AppendHeader(
                        "GET / HTTP/1.1",
                        "Host: www.example.org",
                        "Content-Length: 3",
                        ""
                        );
                    sample.AppendBody("ABC");

                    sample.AppendHeader(
                        "HEAD / HTTP/1.1",
                        "Host: www.example.org",
                        ""
                        );
                    sample.AppendBody(MessageSample.EmptyBody);

                    long thirdMessageOffset = sample.SampleWriterPosition;
                    sample.AppendHeader(
                        "CONNECT www.example.org:443 HTTP/1.1",
                        "Host: www.example.org",
                        ""
                        );
                    sample.AppendBody(MessageSample.EmptyBody);

                    // The body length should be in range of 'tiny' length.
                    // "prefetched bytes" occurs when the body is 'tiny' length for simple body.
                    // In this case, whole three messages are on one memory block.
                    Debug.Assert(sample.SampleWriterPosition < ComponentFactory.MemoryBlockCache.MemoryBlockSize);

                    // the second message will be skipped
                    string expectedOutput = string.Join(
                        MessageSample.CRLF,                           // separator
                        "GET / HTTP/1.1",
                        "Host: www.example.org",
                        "Content-Length: 3",
                        "",
                        "ABCCONNECT www.example.org:443 HTTP/1.1",                              // Note no CRLF at the end of the body
                        "Host: www.example.org",
                        "",
                        MessageSample.EmptyBody
                        );

                    // ACT & ASSERT
                    int counter            = 0;
                    int actualMessageCount = TestReadAndWrite(sample, (request) => {
                        switch (counter)
                        {
                        case 0:
                            Assert.Equal("GET", request.Method);
                            Assert.Equal(3, request.ContentLength);
                            // move to the third message
                            // It causes InputReconnected event.
                            sample.ChangeSampleReaderPosition(thirdMessageOffset);
                            break;

                        case 1:
                            // the third message instead of the second message
                            Assert.Equal("CONNECT", request.Method);
                            Assert.Equal(0, request.ContentLength);
                            break;
                        }
                        ++counter;
                    });
                    Assert.Equal(2, actualMessageCount);
                    sample.AssertOutputEqualTo(expectedOutput);
                }
            }
Пример #26
0
            public void PrefetchedBytes_InputReconnect()
            {
                using (MessageSample sample = CreateMessageSample()) {
                    // ARRANGE
                    sample.AppendHeader(
                        "HTTP/1.1 200 OK",
                        "Content-Length: 7",
                        ""
                        );
                    sample.AppendBody("1234567");

                    sample.AppendHeader(
                        "HTTP/1.1 302 Found",
                        ""
                        );
                    sample.AppendBody(MessageSample.EmptyBody);

                    long thirdMessageOffset = sample.SampleWriterPosition;
                    sample.AppendHeader(
                        "HTTP/1.1 404 Not Found",
                        "Content-Length: 0",
                        ""
                        );
                    sample.AppendBody(MessageSample.EmptyBody);

                    // The body length should be in range of 'tiny' length.
                    // "prefetched bytes" occurs when the body is 'tiny' length for simple body.
                    // In this case, whole three messages are on one memory block.
                    Debug.Assert(sample.SampleWriterPosition < ComponentFactory.MemoryBlockCache.MemoryBlockSize);

                    // the second message will be skipped
                    string expectedOutput = string.Join(
                        MessageSample.CRLF,                           // separator
                        "HTTP/1.1 200 OK",
                        "Content-Length: 7",
                        "",
                        "1234567HTTP/1.1 404 Not Found",                          // Note no CRLF at the end of the body
                        "Content-Length: 0",
                        "",
                        MessageSample.EmptyBody
                        );

                    // ACT & ASSERT
                    int counter            = 0;
                    int actualMessageCount = TestReadAndWrite(sample, (response) => {
                        switch (counter)
                        {
                        case 0:
                            Assert.Equal(200, response.StatusCode);
                            Assert.Equal(7, response.ContentLength);
                            // move to the third message
                            // It causes InputReconnected event.
                            sample.ChangeSampleReaderPosition(thirdMessageOffset);
                            break;

                        case 1:
                            // the third message instead of the second message
                            Assert.Equal(404, response.StatusCode);
                            Assert.Equal(0, response.ContentLength);
                            break;
                        }
                        ++counter;
                    });
                    Assert.Equal(2, actualMessageCount);
                    sample.AssertOutputEqualTo(expectedOutput);
                }
            }