1fe1961e39809c90a76422332e91af67a5c65c31cSleekWeaselpackage fi.iki.elonen;
2fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel
3fe1961e39809c90a76422332e91af67a5c65c31cSleekWeaselimport java.io.ByteArrayOutputStream;
4fe1961e39809c90a76422332e91af67a5c65c31cSleekWeaselimport java.io.IOException;
5fe1961e39809c90a76422332e91af67a5c65c31cSleekWeaselimport java.io.PipedInputStream;
6fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel
7fe1961e39809c90a76422332e91af67a5c65c31cSleekWeaselimport static fi.iki.elonen.NanoHTTPD.Response.Status.OK;
8fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel
9fe1961e39809c90a76422332e91af67a5c65c31cSleekWeaselpublic class HttpChunkedResponseTest extends HttpServerTest {
10fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel    @org.junit.Test
11fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel    public void thatChunkedContentIsChunked() throws Exception {
12fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel        PipedInputStream pipedInputStream = new ChunkedInputStream(new String[]{
13fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel                "some",
14fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel                "thing which is longer than sixteen characters",
15fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel                "whee!",
16fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel                ""
17fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel        });
18fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel        String[] expected = {
19fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel                "HTTP/1.1 200 OK",
20fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel                "Content-Type: what/ever",
21fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel                "Date: .*",
22fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel                "Connection: keep-alive",
23fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel                "Transfer-Encoding: chunked",
24fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel                "",
25fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel                "4",
26fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel                "some",
27fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel                "2d",
28fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel                "thing which is longer than sixteen characters",
29fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel                "5",
30fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel                "whee!",
31fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel                "0",
32fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel                ""
33fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel        };
34fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel        testServer.response = new NanoHTTPD.Response(OK, "what/ever", pipedInputStream);
35517987ff0fe07af253c4cf6163ee5b9da17faf64SleekWeasel        testServer.response.setChunkedTransfer(true);
36fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel
37fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel        ByteArrayOutputStream byteArrayOutputStream = invokeServer("GET / HTTP/1.0");
38fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel
39fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel        assertResponse(byteArrayOutputStream, expected);
40fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel    }
41fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel
42fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel    private static class ChunkedInputStream extends PipedInputStream {
43fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel        int chunk = 0;
44fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel        String[] chunks;
45fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel
46fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel        private ChunkedInputStream(String[] chunks) {
47fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel            this.chunks = chunks;
48fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel        }
49fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel
50fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel        @Override
51fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel        public synchronized int read(byte[] buffer) throws IOException {
52fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel            // Too implementation-linked, but...
53fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel            for (int i = 0; i < chunks[chunk].length(); ++i) {
54fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel                buffer[i] = (byte) chunks[chunk].charAt(i);
55fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel            }
56fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel            return chunks[chunk++].length();
57fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel        }
58fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel    }
59fe1961e39809c90a76422332e91af67a5c65c31cSleekWeasel}
60