//
//  ========================================================================
//  Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

/*
 * Created on 9/01/2004
 *
 * To change the template for this generated file go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */
package org.eclipse.jetty.server;

import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringReader;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.jetty.http.HttpCompliance;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpParser;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.handler.ErrorHandler;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.log.StacklessLogging;
import org.hamcrest.Matchers;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

public class HttpConnectionTest
{
    private Server server;
    private LocalConnector connector;

    @Before
    public void init() throws Exception
    {
        server = new Server();

        HttpConfiguration config = new HttpConfiguration();
        config.setRequestHeaderSize(1024);
        config.setResponseHeaderSize(1024);
        config.setSendDateHeader(true);
        HttpConnectionFactory http = new HttpConnectionFactory(config);

        connector = new LocalConnector(server,http,null);
        connector.setIdleTimeout(5000);
        server.addConnector(connector);
        server.setHandler(new DumpHandler());
        ErrorHandler eh=new ErrorHandler();
        eh.setServer(server);
        server.addBean(eh);
        server.start();
    }

    @After
    public void destroy() throws Exception
    {
        server.stop();
        server.join();
    }

    @Test
    public void testFragmentedChunk() throws Exception
    {
        String response=null;
        try
        {
            int offset=0;

            // Chunk last
            response=connector.getResponses("GET /R1 HTTP/1.1\r\n"+
                                           "Host: localhost\r\n"+
                                           "Transfer-Encoding: chunked\r\n"+
                                           "Content-Type: text/plain\r\n"+
                                           "Connection: close\r\n"+
                                           "\r\n"+
                                           "5;\r\n"+
                                           "12345\r\n"+
                                           "0;\r\n" +
                                           "\r\n");
            offset = checkContains(response,offset,"HTTP/1.1 200");
            offset = checkContains(response,offset,"/R1");
            checkContains(response,offset,"12345");

            offset = 0;
            response=connector.getResponses("GET /R2 HTTP/1.1\r\n"+
                                           "Host: localhost\r\n"+
                                           "Transfer-Encoding: chunked\r\n"+
                                           "Content-Type: text/plain\r\n"+
                                           "Connection: close\r\n"+
                                           "\r\n"+
                                           "5;\r\n"+
                                           "ABCDE\r\n"+
                                           "0;\r\n" +
                                           "\r\n");
            offset = checkContains(response,offset,"HTTP/1.1 200");
            offset = checkContains(response,offset,"/R2");
            checkContains(response,offset,"ABCDE");
        }
        catch(Exception e)
        {
            if(response != null)
                System.err.println(response);
            throw e;
        }
    }

    @Test
    public void testNoPath() throws Exception
    {
        String response=connector.getResponses("GET http://localhost:80 HTTP/1.1\r\n"+
                "Host: localhost:80\r\n"+
                "Connection: close\r\n"+
                "\r\n");

        int offset=0;
        offset = checkContains(response,offset,"HTTP/1.1 200");
        checkContains(response,offset,"pathInfo=/");
    }

    @Test
    public void testDate() throws Exception
    {
        String response=connector.getResponse("GET / HTTP/1.1\r\n"+
                "Host: localhost:80\r\n"+
                "Connection: close\r\n"+
                "\r\n");

        int offset=0;
        offset = checkContains(response,offset,"HTTP/1.1 200");
        offset = checkContains(response,offset,"Date: ");
        checkContains(response,offset,"pathInfo=/");
    }

    @Test
    public void testSetDate() throws Exception
    {
        String response=connector.getResponses("GET /?date=1+Jan+1970 HTTP/1.1\r\n"+
                "Host: localhost:80\r\n"+
                "Connection: close\r\n"+
                "\r\n");

        int offset=0;
        offset = checkContains(response,offset,"HTTP/1.1 200");
        offset = checkContains(response,offset,"Date: 1 Jan 1970");
        checkContains(response,offset,"pathInfo=/");
    }

    @Test
    public void testBadNoPath() throws Exception
    {
        String response=connector.getResponses("GET http://localhost:80/../cheat HTTP/1.1\r\n"+
                "Host: localhost:80\r\n"+
                "\r\n");
        checkContains(response,0,"HTTP/1.1 400");
    }

    @Test
    public void testOKPathDotDotPath() throws Exception
    {
        String response=connector.getResponses("GET /ooops/../path HTTP/1.0\r\nHost: localhost:80\r\n\n");
        checkContains(response,0,"HTTP/1.1 200 OK");
        checkContains(response,0,"pathInfo=/path");
    }

    @Test
    public void testBadPathDotDotPath() throws Exception
    {
        String response=connector.getResponses("GET /ooops/../../path HTTP/1.0\r\nHost: localhost:80\r\n\n");
        checkContains(response,0,"HTTP/1.1 400 Bad URI");
    }

    @Test
    public void testOKPathEncodedDotDotPath() throws Exception
    {
        String response=connector.getResponses("GET /ooops/%2e%2e/path HTTP/1.0\r\nHost: localhost:80\r\n\n");
        checkContains(response,0,"HTTP/1.1 200 OK");
        checkContains(response,0,"pathInfo=/path");
    }

    @Test
    public void testBadPathEncodedDotDotPath() throws Exception
    {
        String response=connector.getResponses("GET /ooops/%2e%2e/%2e%2e/path HTTP/1.0\r\nHost: localhost:80\r\n\n");
        checkContains(response,0,"HTTP/1.1 400 Bad URI");
    }

    @Test
    public void testBadDotDotPath() throws Exception
    {
        String response=connector.getResponses("GET ../path HTTP/1.0\r\nHost: localhost:80\r\n\n");
        checkContains(response,0,"HTTP/1.1 400 Bad URI");
    }

    @Test
    public void testBadSlashDotDotPath() throws Exception
    {
        String response=connector.getResponses("GET /../path HTTP/1.0\r\nHost: localhost:80\r\n\n");
        checkContains(response,0,"HTTP/1.1 400 Bad URI");
    }

    @Test
    public void testEncodedBadDotDotPath() throws Exception
    {
        String response=connector.getResponses("GET %2e%2e/path HTTP/1.0\r\nHost: localhost:80\r\n\n");
        checkContains(response,0,"HTTP/1.1 400 Bad URI");
    }

    @Test
    public void test_0_9() throws Exception
    {
        connector.getConnectionFactory(HttpConnectionFactory.class).setHttpCompliance(HttpCompliance.RFC2616);
        String response=connector.getResponses("GET /R1\n");

        int offset=0;
        checkNotContained(response,offset,"HTTP/1.1");
        checkNotContained(response,offset,"200");
        checkContains(response,offset,"pathInfo=/R1");
    }
    
    @Test
    public void testSimple() throws Exception
    {
        String response=connector.getResponses("GET /R1 HTTP/1.1\r\n"+
                "Host: localhost\r\n"+
                "Connection: close\r\n"+
                "\r\n");

        int offset=0;
        offset = checkContains(response,offset,"HTTP/1.1 200");
        checkContains(response,offset,"/R1");
    }

    @Test
    public void testEmptyChunk() throws Exception
    {
        String response=connector.getResponse("GET /R1 HTTP/1.1\r\n"+
                "Host: localhost\r\n"+
                "Transfer-Encoding: chunked\r\n"+
                "Content-Type: text/plain\r\n"+
                "Connection: close\r\n"+
                "\r\n"+
                "0\r\n" +
                "\r\n");

        int offset=0;
        offset = checkContains(response,offset,"HTTP/1.1 200");
        checkContains(response,offset,"/R1");
    }

    @Test
    public void testChunk() throws Exception
    {
        String response=connector.getResponse("GET /R1 HTTP/1.1\r\n"+
                "Host: localhost\r\n"+
                "Transfer-Encoding: chunked\r\n"+
                "Content-Type: text/plain\r\n"+
                "Connection: close\r\n"+
                "\r\n"+
                "A\r\n" +
                "0123456789\r\n"+
                "0\r\n" +
                "\r\n");

        int offset=0;
        offset = checkContains(response,offset,"HTTP/1.1 200");
        offset = checkContains(response,offset,"/R1");
        checkContains(response,offset,"0123456789");
    }

    @Test
    public void testChunkTrailer() throws Exception
    {
        String response=connector.getResponse("GET /R1 HTTP/1.1\r\n"+
                "Host: localhost\r\n"+
                "Transfer-Encoding: chunked\r\n"+
                "Content-Type: text/plain\r\n"+
                "Connection: close\r\n"+
                "\r\n"+
                "A\r\n" +
                "0123456789\r\n"+
                "0\r\n" +
                "Trailer: ignored\r\n" +
                "\r\n");

        int offset=0;
        offset = checkContains(response,offset,"HTTP/1.1 200");
        offset = checkContains(response,offset,"/R1");
        checkContains(response,offset,"0123456789");
    }

    @Test
    public void testChunkNoTrailer() throws Exception
    {
        String response=connector.getResponse("GET /R1 HTTP/1.1\r\n"+
                "Host: localhost\r\n"+
                "Transfer-Encoding: chunked\r\n"+
                "Content-Type: text/plain\r\n"+
                "Connection: close\r\n"+
                "\r\n"+
                "A\r\n" +
                "0123456789\r\n"+
                "0\r\n");

        int offset=0;
        offset = checkContains(response,offset,"HTTP/1.1 200");
        offset = checkContains(response,offset,"/R1");
        checkContains(response,offset,"0123456789");
    }

    @Test
    public void testHead() throws Exception
    {
        String responsePOST=connector.getResponses("POST /R1 HTTP/1.1\r\n"+
            "Host: localhost\r\n"+
            "Connection: close\r\n"+
            "\r\n");

        String responseHEAD=connector.getResponses("HEAD /R1 HTTP/1.1\r\n"+
            "Host: localhost\r\n"+
            "Connection: close\r\n"+
            "\r\n");

        String postLine;
        boolean postDate=false;
        Set<String> postHeaders = new HashSet<>();
        try(BufferedReader in = new BufferedReader(new StringReader(responsePOST)))
        {
            postLine = in.readLine();
            String line=in.readLine();
            while (line!=null && line.length()>0)
            {
                if (line.startsWith("Date:"))
                    postDate=true;
                else
                    postHeaders.add(line);
                line=in.readLine();
            }
        }
        String headLine;
        boolean headDate=false;
        Set<String> headHeaders = new HashSet<>();
        try(BufferedReader in = new BufferedReader(new StringReader(responseHEAD)))
        {
            headLine = in.readLine();
            String line=in.readLine();
            while (line!=null && line.length()>0)
            {
                if (line.startsWith("Date:"))
                    headDate=true;
                else
                    headHeaders.add(line);
                line=in.readLine();
            }
        }

        assertThat(postLine,equalTo(headLine));
        assertThat(postDate,equalTo(headDate));
        assertTrue(postHeaders.equals(headHeaders));
    }

    @Test
    public void testHeadChunked() throws Exception
    {
        String responsePOST=connector.getResponse("POST /R1?no-content-length=true HTTP/1.1\r\n"+
                "Host: localhost\r\n"+
                "\r\n",false,1,TimeUnit.SECONDS);

        String responseHEAD=connector.getResponse("HEAD /R1?no-content-length=true HTTP/1.1\r\n"+
            "Host: localhost\r\n"+
            "\r\n",true,1,TimeUnit.SECONDS);

        String postLine;
        boolean postDate=false;
        Set<String> postHeaders = new HashSet<>();
        try(BufferedReader in = new BufferedReader(new StringReader(responsePOST)))
        {
            postLine = in.readLine();
            String line=in.readLine();
            while (line!=null && line.length()>0)
            {
                if (line.startsWith("Date:"))
                    postDate=true;
                else
                    postHeaders.add(line);
                line=in.readLine();
            }
        }
        String headLine;
        boolean headDate=false;
        Set<String> headHeaders = new HashSet<>();
        try(BufferedReader in = new BufferedReader(new StringReader(responseHEAD)))
        {
            headLine = in.readLine();
            String line=in.readLine();
            while (line!=null && line.length()>0)
            {
                if (line.startsWith("Date:"))
                    headDate=true;
                else
                    headHeaders.add(line);
                line=in.readLine();
            }
        }

        assertThat(postLine,equalTo(headLine));
        assertThat(postDate,equalTo(headDate));
        assertTrue(postHeaders.equals(headHeaders));
    }

    @Test
    public void testBadHostPort() throws Exception
    {
        Log.getLogger(HttpParser.class).info("badMessage: Number formate exception expected ...");
        String response;

        response=connector.getResponses("GET http://localhost:EXPECTED_NUMBER_FORMAT_EXCEPTION/ HTTP/1.1\r\n"+
            "Host: localhost\r\n"+
            "Connection: close\r\n"+
            "\r\n");
        checkContains(response,0,"HTTP/1.1 400");
    }

    @Test
    public void testNoHost() throws Exception
    {
        String response;

        response=connector.getResponse("GET / HTTP/1.1\r\n"+
            "\r\n");
        checkContains(response,0,"HTTP/1.1 400");
    }

    @Test
    public void testEmptyHost() throws Exception
    {
        String response;

        response=connector.getResponse("GET / HTTP/1.1\r\n"+
            "Host:\r\n"+
            "\r\n");
        checkContains(response,0,"HTTP/1.1 200");
    }

    @Test
    public void testBadURIencoding() throws Exception
    {
        Log.getLogger(HttpParser.class).info("badMessage: bad encoding expected ...");
        String response;

        try(StacklessLogging stackless = new StacklessLogging(HttpParser.class))
        {
            response=connector.getResponse("GET /bad/encoding%1 HTTP/1.1\r\n"+
                    "Host: localhost\r\n"+
                    "Connection: close\r\n"+
                    "\r\n");
            checkContains(response,0,"HTTP/1.1 400");
        }
    }

    @Test
    public void testBadUTF8FallsbackTo8859() throws Exception
    {
        Log.getLogger(HttpParser.class).info("badMessage: bad encoding expected ...");
        String response;

        response=connector.getResponses("GET /foo/bar%c0%00 HTTP/1.1\r\n"+
            "Host: localhost\r\n"+
            "Connection: close\r\n"+
            "\r\n");
        checkContains(response,0,"HTTP/1.1 200"); //now fallback to iso-8859-1

        response=connector.getResponses("GET /bad/utf8%c1 HTTP/1.1\r\n"+
            "Host: localhost\r\n"+
            "Connection: close\r\n"+
            "\r\n");
        checkContains(response,0,"HTTP/1.1 200"); //now fallback to iso-8859-1
    }

    @Test
    public void testAutoFlush() throws Exception
    {
        int offset=0;

        String response = connector.getResponses("GET /R1 HTTP/1.1\r\n" +
                "Host: localhost\r\n" +
                "Transfer-Encoding: chunked\r\n" +
                "Content-Type: text/plain\r\n" +
                "Connection: close\r\n" +
                "\r\n" +
                "5;\r\n" +
                "12345\r\n" +
                "0;\r\n" +
                "\r\n");
        offset = checkContains(response,offset,"HTTP/1.1 200");
        checkNotContained(response,offset,"IgnoreMe");
        offset = checkContains(response,offset,"/R1");
        checkContains(response,offset,"12345");
    }

    @Test
    public void testEmptyFlush() throws Exception
    {
        server.stop();
        server.setHandler(new AbstractHandler()
        {
            @Override
            public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
            {
                response.setStatus(200);
                OutputStream out =response.getOutputStream();
                out.flush();
                out.flush();
            }
        });
        server.start();

        String response=connector.getResponses("GET / HTTP/1.1\r\n"+
            "Host: localhost\r\n"+
            "Connection: close\r\n"+
            "\r\n");

        assertThat(response, Matchers.containsString("200 OK"));
    }

    @Test
    public void testCharset() throws Exception
    {
        String response=null;
        try
        {
            int offset=0;
            response=connector.getResponses("GET /R1 HTTP/1.1\r\n"+
                                           "Host: localhost\r\n"+
                                           "Transfer-Encoding: chunked\r\n"+
                                           "Content-Type: text/plain; charset=utf-8\r\n"+
                                           "Connection: close\r\n"+
                                           "\r\n"+
                                           "5;\r\n"+
                                           "12345\r\n"+
                                           "0;\r\n" +
                                           "\r\n");
            offset = checkContains(response,offset,"HTTP/1.1 200");
            offset = checkContains(response,offset,"/R1");
            offset = checkContains(response,offset,"encoding=UTF-8");
            checkContains(response,offset,"12345");

            offset=0;
            response=connector.getResponses("GET /R1 HTTP/1.1\r\n"+
                                           "Host: localhost\r\n"+
                                           "Transfer-Encoding: chunked\r\n"+
                                           "Content-Type: text/plain; charset =  iso-8859-1 ; other=value\r\n"+
                                           "Connection: close\r\n"+
                                           "\r\n"+
                                           "5;\r\n"+
                                           "12345\r\n"+
                                           "0;\r\n" +
                                           "\r\n");
            offset = checkContains(response,offset,"HTTP/1.1 200");
            offset = checkContains(response,offset,"encoding=iso-8859-1");
            offset = checkContains(response,offset,"/R1");
            checkContains(response,offset,"12345");

            offset=0;
            response=connector.getResponses("GET /R1 HTTP/1.1\r\n"+
                                           "Host: localhost\r\n"+
                                           "Transfer-Encoding: chunked\r\n"+
                                           "Content-Type: text/plain; charset=unknown\r\n"+
                                           "Connection: close\r\n"+
                                           "\r\n"+
                                           "5;\r\n"+
                                           "12345\r\n"+
                                           "0;\r\n" +
                                           "\r\n");
            offset = checkContains(response,offset,"HTTP/1.1 200");
            offset = checkContains(response,offset,"encoding=unknown");
            offset = checkContains(response,offset,"/R1");
            checkContains(response,offset,"UnsupportedEncodingException");
        }
        catch(Exception e)
        {
            if(response != null)
                System.err.println(response);
            throw e;
        }
    }

    @Test
    public void testUnconsumed() throws Exception
    {
        int offset=0;
        String requests =
        "GET /R1?read=4 HTTP/1.1\r\n" +
        "Host: localhost\r\n" +
        "Transfer-Encoding: chunked\r\n" +
        "Content-Type: text/plain; charset=utf-8\r\n" +
        "\r\n" +
        "5;\r\n" +
        "12345\r\n" +
        "5;\r\n" +
        "67890\r\n" +
        "0;\r\n" +
        "\r\n" +
        "GET /R2 HTTP/1.1\r\n" +
        "Host: localhost\r\n" +
        "Content-Type: text/plain; charset=utf-8\r\n" +
        "Content-Length: 10\r\n" +
        "Connection: close\r\n" +
        "\r\n" +
        "abcdefghij\r\n";

        String response = connector.getResponses(requests);

        offset = checkContains(response,offset,"HTTP/1.1 200");
        offset = checkContains(response,offset,"pathInfo=/R1");
        offset = checkContains(response,offset,"1234");
        checkNotContained(response,offset,"56789");
        offset = checkContains(response,offset,"HTTP/1.1 200");
        offset = checkContains(response,offset,"pathInfo=/R2");
        offset = checkContains(response,offset,"encoding=UTF-8");
        checkContains(response,offset,"abcdefghij");
    }

    @Test
    public void testUnconsumedTimeout() throws Exception
    {
        connector.setIdleTimeout(500);
        int offset=0;
        String requests=
        "GET /R1?read=4 HTTP/1.1\r\n"+
        "Host: localhost\r\n"+
        "Transfer-Encoding: chunked\r\n"+
        "Content-Type: text/plain; charset=utf-8\r\n"+
        "\r\n"+
        "5;\r\n"+
        "12345\r\n";

        long start=System.currentTimeMillis();
        String response = connector.getResponses(requests, 2000, TimeUnit.MILLISECONDS);
        if ((System.currentTimeMillis()-start)>=2000)
            Assert.fail();

        offset = checkContains(response,offset,"HTTP/1.1 200");
        offset = checkContains(response,offset,"pathInfo=/R1");
        offset = checkContains(response,offset,"1234");
        checkNotContained(response,offset,"56789");
    }

    @Test
    public void testUnconsumedErrorRead() throws Exception
    {
        int offset=0;
        String requests=
        "GET /R1?read=1&error=499 HTTP/1.1\r\n"+
        "Host: localhost\r\n"+
        "Transfer-Encoding: chunked\r\n"+
        "Content-Type: text/plain; charset=utf-8\r\n"+
        "\r\n"+
        "5;\r\n"+
        "12345\r\n"+
        "5;\r\n"+
        "67890\r\n"+
        "0;\r\n" +
        "\r\n"+
        "GET /R2 HTTP/1.1\r\n"+
        "Host: localhost\r\n"+
        "Content-Type: text/plain; charset=utf-8\r\n"+
        "Content-Length: 10\r\n"+
        "Connection: close\r\n"+
        "\r\n"+
        "abcdefghij\r\n";

        String response = connector.getResponses(requests);

        offset = checkContains(response,offset,"HTTP/1.1 499");
        offset = checkContains(response,offset,"HTTP/1.1 200");
        offset = checkContains(response,offset,"/R2");
        offset = checkContains(response,offset,"encoding=UTF-8");
        checkContains(response,offset,"abcdefghij");
    }

    @Test
    public void testUnconsumedErrorStream() throws Exception
    {
        int offset=0;
        String requests=
        "GET /R1?error=599 HTTP/1.1\r\n"+
        "Host: localhost\r\n"+
        "Transfer-Encoding: chunked\r\n"+
        "Content-Type: application/data; charset=utf-8\r\n"+
        "\r\n"+
        "5;\r\n"+
        "12345\r\n"+
        "5;\r\n"+
        "67890\r\n"+
        "0;\r\n" +
        "\r\n"+
        "GET /R2 HTTP/1.1\r\n"+
        "Host: localhost\r\n"+
        "Content-Type: text/plain; charset=utf-8\r\n"+
        "Content-Length: 10\r\n"+
        "Connection: close\r\n"+
        "\r\n"+
        "abcdefghij\r\n";

        String response = connector.getResponses(requests);

        offset = checkContains(response,offset,"HTTP/1.1 599");
        offset = checkContains(response,offset,"HTTP/1.1 200");
        offset = checkContains(response,offset,"/R2");
        offset = checkContains(response,offset,"encoding=UTF-8");
        checkContains(response,offset,"abcdefghij");
    }

    @Test
    public void testUnconsumedException() throws Exception
    {
        int offset=0;
        String requests="GET /R1?read=1&ISE=true HTTP/1.1\r\n"+
        "Host: localhost\r\n"+
        "Transfer-Encoding: chunked\r\n"+
        "Content-Type: text/plain; charset=utf-8\r\n"+
        "\r\n"+
        "5;\r\n"+
        "12345\r\n"+
        "5;\r\n"+
        "67890\r\n"+
        "0;\r\n" +
        "\r\n"+
        "GET /R2 HTTP/1.1\r\n"+
        "Host: localhost\r\n"+
        "Content-Type: text/plain; charset=utf-8\r\n"+
        "Content-Length: 10\r\n"+
        "\r\n"+
        "abcdefghij\r\n";

        Logger logger = Log.getLogger(HttpChannel.class);
        try (StacklessLogging stackless = new StacklessLogging(logger))
        {
            logger.info("EXPECTING: java.lang.IllegalStateException...");
            String response = connector.getResponses(requests);
            offset = checkContains(response,offset,"HTTP/1.1 500");
            offset = checkContains(response,offset,"Connection: close");
            checkNotContained(response,offset,"HTTP/1.1 200");
        }
    }

    @Test
    public void testConnection() throws Exception
    {
        String response=null;
        try
        {
            int offset=0;
            response=connector.getResponse("GET /R1 HTTP/1.1\r\n"+
                                           "Host: localhost\r\n"+
                                           "Connection: TE, close\r\n"+
                                           "Transfer-Encoding: chunked\r\n"+
                                           "Content-Type: text/plain; charset=utf-8\r\n"+
                                           "\r\n"+
                                           "5;\r\n"+
                                           "12345\r\n"+
                                           "0;\r\n" +
                                           "\r\n");
            checkContains(response,offset,"Connection: close");
        }
        catch (Exception e)
        {
            if(response != null)
                System.err.println(response);
            throw e;
        }
    }

    /**
     * Creates a request header over 1k in size, by creating a single header entry with an huge value.
     * @throws Exception if test failure
     */
    @Test
    public void testOversizedBuffer() throws Exception
    {
        String response = null;
        try
        {
            int offset = 0;
            String cookie = "thisisastringthatshouldreachover1kbytes";
            for (int i=0;i<100;i++)
                cookie+="xxxxxxxxxxxx";
            response = connector.getResponses("GET / HTTP/1.1\r\n"+
                "Host: localhost\r\n" +
                "Cookie: "+cookie+"\r\n"+
                "\r\n"
             );
            checkContains(response, offset, "HTTP/1.1 431");
        }
        catch(Exception e)
        {
            if(response != null)
                System.err.println(response);
            throw e;
        }
    }

    /**
     * Creates a request header with over 1000 entries.
     * @throws Exception if test failure
     */
    @Test
    public void testExcessiveHeader() throws Exception
    {
        int offset = 0;

        StringBuilder request = new StringBuilder();
        request.append("GET / HTTP/1.1\r\n");
        request.append("Host: localhost\r\n");
        request.append("Cookie: thisisastring\r\n");
        for(int i=0; i<1000; i++) {
            request.append(String.format("X-Header-%04d: %08x\r\n", i, i));
        }
        request.append("\r\n");

        String response = connector.getResponses(request.toString());
        offset = checkContains(response, offset, "HTTP/1.1 431");
        checkContains(response, offset, "<h1>Bad Message 431</h1>");
    }

    @Test
    public void testOversizedResponse() throws Exception
    {
        String str = "thisisastringthatshouldreachover1kbytes-";
        for (int i=0;i<500;i++)
            str+="xxxxxxxxxxxx";
        final String longstr = str;
        final CountDownLatch checkError = new CountDownLatch(1);
        String response = null;
        server.stop();
        server.setHandler(new DumpHandler()
        {
            @Override
            public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
            {
                baseRequest.setHandled(true);
                response.setHeader(HttpHeader.CONTENT_TYPE.toString(),MimeTypes.Type.TEXT_HTML.toString());
                response.setHeader("LongStr", longstr);
                PrintWriter writer = response.getWriter();
                writer.write("<html><h1>FOO</h1></html>");
                writer.flush();
                if (writer.checkError())
                    checkError.countDown();
                response.flushBuffer();
            }
        });
        server.start();

        Logger logger = Log.getLogger(HttpChannel.class);
        try (StacklessLogging stackless = new StacklessLogging(logger))
        {
            logger.info("Expect IOException: Response header too large...");
            response = connector.getResponses("GET / HTTP/1.1\r\n"+
                "Host: localhost\r\n" +
                "\r\n"
             );

            checkContains(response, 0, "HTTP/1.1 500");
            assertTrue(checkError.await(1,TimeUnit.SECONDS));
        }
        catch(Exception e)
        {
            if(response != null)
                System.err.println(response);
            throw e;
        }
    }

    @Test
    public void testAsterisk() throws Exception
    {
        String response = null;
        try (StacklessLogging stackless = new StacklessLogging(HttpParser.LOG))
        {
            int offset=0;

            response=connector.getResponses("OPTIONS * HTTP/1.1\r\n"+
                                           "Host: localhost\r\n"+
                                           "Transfer-Encoding: chunked\r\n"+
                                           "Content-Type: text/plain; charset=utf-8\r\n"+
                                           "Connection: close\r\n"+
                                           "\r\n"+
                                           "5;\r\n"+
                                           "12345\r\n"+
                                           "0;\r\n" +
                                           "\r\n");
            checkContains(response,offset,"HTTP/1.1 200");

            offset=0;
            response=connector.getResponses("GET * HTTP/1.1\r\n"+
                                           "Host: localhost\r\n"+
                                           "Transfer-Encoding: chunked\r\n"+
                                           "Content-Type: text/plain; charset=utf-8\r\n"+
                                           "Connection: close\r\n"+
                                           "\r\n"+
                                           "5;\r\n"+
                                           "12345\r\n"+
                                           "0;\r\n" +
                                           "\r\n");
            checkContains(response,offset,"HTTP/1.1 400");

            offset=0;
            response=connector.getResponses("GET ** HTTP/1.1\r\n"+
                                           "Host: localhost\r\n"+
                                           "Transfer-Encoding: chunked\r\n"+
                                           "Content-Type: text/plain; charset=utf-8\r\n"+
                                           "Connection: close\r\n"+
                                           "\r\n"+
                                           "5;\r\n"+
                                           "12345\r\n"+
                                           "0;\r\n" +
                                           "\r\n");
            checkContains(response,offset,"HTTP/1.1 400 Bad Request");
        }
        catch (Exception e)
        {
            if(response != null)
                System.err.println(response);
            throw e;
        }
    }

    @Test
    public void testCONNECT() throws Exception
    {
        String response = null;
        try
        {
            int offset=0;

            response=connector.getResponses("CONNECT www.webtide.com:8080 HTTP/1.1\r\n"+
                                           "Host: myproxy:8888\r\n"+
                                           "\r\n",200,TimeUnit.MILLISECONDS);
            checkContains(response,offset,"HTTP/1.1 200");
        }
        catch (Exception e)
        {
            if(response != null)
                System.err.println(response);
            throw e;
        }
    }

    private int checkContains(String s,int offset,String c)
    {
        Assert.assertThat(s.substring(offset),Matchers.containsString(c));
        return s.indexOf(c,offset);
    }

    private void checkNotContained(String s,int offset,String c)
    {
        Assert.assertThat(s.substring(offset),Matchers.not(Matchers.containsString(c)));
    }
}
