Search in sources :

Example 11 with MappedByteBufferPool

use of org.eclipse.jetty.io.MappedByteBufferPool in project jetty.project by eclipse.

the class HTTP2CServerTest method testHTTP_2_0_Direct.

@Test
public void testHTTP_2_0_Direct() throws Exception {
    final CountDownLatch latch = new CountDownLatch(3);
    byteBufferPool = new MappedByteBufferPool();
    generator = new Generator(byteBufferPool);
    ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
    generator.control(lease, new PrefaceFrame());
    generator.control(lease, new SettingsFrame(new HashMap<>(), false));
    MetaData.Request metaData = new MetaData.Request("GET", HttpScheme.HTTP, new HostPortHttpField("localhost:" + connector.getLocalPort()), "/test", HttpVersion.HTTP_2, new HttpFields());
    generator.control(lease, new HeadersFrame(1, metaData, null, true));
    try (Socket client = new Socket("localhost", connector.getLocalPort())) {
        OutputStream output = client.getOutputStream();
        for (ByteBuffer buffer : lease.getByteBuffers()) {
            output.write(BufferUtil.toArray(buffer));
        }
        final AtomicReference<HeadersFrame> headersRef = new AtomicReference<>();
        final AtomicReference<DataFrame> dataRef = new AtomicReference<>();
        Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() {

            @Override
            public void onSettings(SettingsFrame frame) {
                latch.countDown();
            }

            @Override
            public void onHeaders(HeadersFrame frame) {
                headersRef.set(frame);
                latch.countDown();
            }

            @Override
            public void onData(DataFrame frame) {
                dataRef.set(frame);
                latch.countDown();
            }
        }, 4096, 8192);
        parseResponse(client, parser);
        Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
        HeadersFrame response = headersRef.get();
        Assert.assertNotNull(response);
        MetaData.Response responseMetaData = (MetaData.Response) response.getMetaData();
        Assert.assertEquals(200, responseMetaData.getStatus());
        DataFrame responseData = dataRef.get();
        Assert.assertNotNull(responseData);
        String s = BufferUtil.toString(responseData.getData());
        assertThat(s, containsString("Hello from Jetty using HTTP/2.0"));
        assertThat(s, containsString("uri=/test"));
    }
}
Also used : ByteBufferPool(org.eclipse.jetty.io.ByteBufferPool) MappedByteBufferPool(org.eclipse.jetty.io.MappedByteBufferPool) HashMap(java.util.HashMap) OutputStream(java.io.OutputStream) Matchers.containsString(org.hamcrest.Matchers.containsString) HeadersFrame(org.eclipse.jetty.http2.frames.HeadersFrame) SettingsFrame(org.eclipse.jetty.http2.frames.SettingsFrame) MetaData(org.eclipse.jetty.http.MetaData) HttpFields(org.eclipse.jetty.http.HttpFields) HostPortHttpField(org.eclipse.jetty.http.HostPortHttpField) AtomicReference(java.util.concurrent.atomic.AtomicReference) DataFrame(org.eclipse.jetty.http2.frames.DataFrame) CountDownLatch(java.util.concurrent.CountDownLatch) ByteBuffer(java.nio.ByteBuffer) Parser(org.eclipse.jetty.http2.parser.Parser) MappedByteBufferPool(org.eclipse.jetty.io.MappedByteBufferPool) PrefaceFrame(org.eclipse.jetty.http2.frames.PrefaceFrame) Socket(java.net.Socket) Generator(org.eclipse.jetty.http2.generator.Generator) Test(org.junit.Test)

Example 12 with MappedByteBufferPool

use of org.eclipse.jetty.io.MappedByteBufferPool in project jetty.project by eclipse.

the class HTTP2CServerTest method testHTTP_1_1_Upgrade.

@Test
public void testHTTP_1_1_Upgrade() throws Exception {
    try (Socket client = new Socket("localhost", connector.getLocalPort())) {
        OutputStream output = client.getOutputStream();
        output.write(("" + "GET /one HTTP/1.1\r\n" + "Host: localhost\r\n" + "Connection: something, else, upgrade, HTTP2-Settings\r\n" + "Upgrade: h2c\r\n" + "HTTP2-Settings: \r\n" + "\r\n").getBytes(StandardCharsets.ISO_8859_1));
        output.flush();
        InputStream input = client.getInputStream();
        Utf8StringBuilder upgrade = new Utf8StringBuilder();
        int crlfs = 0;
        while (true) {
            int read = input.read();
            if (read == '\r' || read == '\n')
                ++crlfs;
            else
                crlfs = 0;
            upgrade.append((byte) read);
            if (crlfs == 4)
                break;
        }
        assertTrue(upgrade.toString().startsWith("HTTP/1.1 101 "));
        byteBufferPool = new MappedByteBufferPool();
        generator = new Generator(byteBufferPool);
        final AtomicReference<HeadersFrame> headersRef = new AtomicReference<>();
        final AtomicReference<DataFrame> dataRef = new AtomicReference<>();
        final AtomicReference<CountDownLatch> latchRef = new AtomicReference<>(new CountDownLatch(2));
        Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() {

            @Override
            public void onHeaders(HeadersFrame frame) {
                headersRef.set(frame);
                latchRef.get().countDown();
            }

            @Override
            public void onData(DataFrame frame) {
                dataRef.set(frame);
                latchRef.get().countDown();
            }
        }, 4096, 8192);
        parseResponse(client, parser);
        Assert.assertTrue(latchRef.get().await(5, TimeUnit.SECONDS));
        HeadersFrame response = headersRef.get();
        Assert.assertNotNull(response);
        MetaData.Response responseMetaData = (MetaData.Response) response.getMetaData();
        Assert.assertEquals(200, responseMetaData.getStatus());
        DataFrame responseData = dataRef.get();
        Assert.assertNotNull(responseData);
        String content = BufferUtil.toString(responseData.getData());
        // The upgrade request is seen as HTTP/1.1.
        assertThat(content, containsString("Hello from Jetty using HTTP/1.1"));
        assertThat(content, containsString("uri=/one"));
        // Send a HTTP/2 request.
        headersRef.set(null);
        dataRef.set(null);
        latchRef.set(new CountDownLatch(2));
        ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
        generator.control(lease, new PrefaceFrame());
        generator.control(lease, new SettingsFrame(new HashMap<>(), false));
        MetaData.Request metaData = new MetaData.Request("GET", HttpScheme.HTTP, new HostPortHttpField("localhost:" + connector.getLocalPort()), "/two", HttpVersion.HTTP_2, new HttpFields());
        generator.control(lease, new HeadersFrame(3, metaData, null, true));
        for (ByteBuffer buffer : lease.getByteBuffers()) output.write(BufferUtil.toArray(buffer));
        output.flush();
        parseResponse(client, parser);
        Assert.assertTrue(latchRef.get().await(5, TimeUnit.SECONDS));
        response = headersRef.get();
        Assert.assertNotNull(response);
        responseMetaData = (MetaData.Response) response.getMetaData();
        Assert.assertEquals(200, responseMetaData.getStatus());
        responseData = dataRef.get();
        Assert.assertNotNull(responseData);
        content = BufferUtil.toString(responseData.getData());
        assertThat(content, containsString("Hello from Jetty using HTTP/2.0"));
        assertThat(content, containsString("uri=/two"));
    }
}
Also used : ByteBufferPool(org.eclipse.jetty.io.ByteBufferPool) MappedByteBufferPool(org.eclipse.jetty.io.MappedByteBufferPool) HashMap(java.util.HashMap) OutputStream(java.io.OutputStream) Matchers.containsString(org.hamcrest.Matchers.containsString) HeadersFrame(org.eclipse.jetty.http2.frames.HeadersFrame) SettingsFrame(org.eclipse.jetty.http2.frames.SettingsFrame) MetaData(org.eclipse.jetty.http.MetaData) HttpFields(org.eclipse.jetty.http.HttpFields) HostPortHttpField(org.eclipse.jetty.http.HostPortHttpField) InputStream(java.io.InputStream) Utf8StringBuilder(org.eclipse.jetty.util.Utf8StringBuilder) AtomicReference(java.util.concurrent.atomic.AtomicReference) DataFrame(org.eclipse.jetty.http2.frames.DataFrame) CountDownLatch(java.util.concurrent.CountDownLatch) ByteBuffer(java.nio.ByteBuffer) EndPoint(org.eclipse.jetty.io.EndPoint) Parser(org.eclipse.jetty.http2.parser.Parser) MappedByteBufferPool(org.eclipse.jetty.io.MappedByteBufferPool) PrefaceFrame(org.eclipse.jetty.http2.frames.PrefaceFrame) Socket(java.net.Socket) Generator(org.eclipse.jetty.http2.generator.Generator) Test(org.junit.Test)

Example 13 with MappedByteBufferPool

use of org.eclipse.jetty.io.MappedByteBufferPool in project jetty.project by eclipse.

the class ContinuationParseTest method testParseOneByteAtATime.

@Test
public void testParseOneByteAtATime() throws Exception {
    ByteBufferPool byteBufferPool = new MappedByteBufferPool();
    HeadersGenerator generator = new HeadersGenerator(new HeaderGenerator(), new HpackEncoder());
    final List<HeadersFrame> frames = new ArrayList<>();
    Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() {

        @Override
        public void onHeaders(HeadersFrame frame) {
            frames.add(frame);
        }

        @Override
        public void onConnectionFailure(int error, String reason) {
            frames.add(new HeadersFrame(null, null, false));
        }
    }, 4096, 8192);
    // Iterate a few times to be sure the parser is properly reset.
    for (int i = 0; i < 2; ++i) {
        int streamId = 13;
        HttpFields fields = new HttpFields();
        fields.put("Accept", "text/html");
        fields.put("User-Agent", "Jetty");
        MetaData.Request metaData = new MetaData.Request("GET", HttpScheme.HTTP, new HostPortHttpField("localhost:8080"), "/path", HttpVersion.HTTP_2, fields);
        ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
        generator.generateHeaders(lease, streamId, metaData, null, true);
        List<ByteBuffer> byteBuffers = lease.getByteBuffers();
        Assert.assertEquals(2, byteBuffers.size());
        ByteBuffer headersBody = byteBuffers.remove(1);
        int start = headersBody.position();
        int length = headersBody.remaining();
        int oneThird = length / 3;
        int lastThird = length - 2 * oneThird;
        // Adjust the length of the HEADERS frame.
        ByteBuffer headersHeader = byteBuffers.get(0);
        headersHeader.put(0, (byte) ((oneThird >>> 16) & 0xFF));
        headersHeader.put(1, (byte) ((oneThird >>> 8) & 0xFF));
        headersHeader.put(2, (byte) (oneThird & 0xFF));
        // Remove the END_HEADERS flag from the HEADERS header.
        headersHeader.put(4, (byte) (headersHeader.get(4) & ~Flags.END_HEADERS));
        // New HEADERS body.
        headersBody.position(start);
        headersBody.limit(start + oneThird);
        byteBuffers.add(headersBody.slice());
        // Split the rest of the HEADERS body into CONTINUATION frames.
        // First CONTINUATION header.
        byte[] continuationHeader1 = new byte[9];
        continuationHeader1[0] = (byte) ((oneThird >>> 16) & 0xFF);
        continuationHeader1[1] = (byte) ((oneThird >>> 8) & 0xFF);
        continuationHeader1[2] = (byte) (oneThird & 0xFF);
        continuationHeader1[3] = (byte) FrameType.CONTINUATION.getType();
        continuationHeader1[4] = Flags.NONE;
        continuationHeader1[5] = 0x00;
        continuationHeader1[6] = 0x00;
        continuationHeader1[7] = 0x00;
        continuationHeader1[8] = (byte) streamId;
        byteBuffers.add(ByteBuffer.wrap(continuationHeader1));
        // First CONTINUATION body.
        headersBody.position(start + oneThird);
        headersBody.limit(start + 2 * oneThird);
        byteBuffers.add(headersBody.slice());
        // Second CONTINUATION header.
        byte[] continuationHeader2 = new byte[9];
        continuationHeader2[0] = (byte) ((lastThird >>> 16) & 0xFF);
        continuationHeader2[1] = (byte) ((lastThird >>> 8) & 0xFF);
        continuationHeader2[2] = (byte) (lastThird & 0xFF);
        continuationHeader2[3] = (byte) FrameType.CONTINUATION.getType();
        continuationHeader2[4] = Flags.END_HEADERS;
        continuationHeader2[5] = 0x00;
        continuationHeader2[6] = 0x00;
        continuationHeader2[7] = 0x00;
        continuationHeader2[8] = (byte) streamId;
        byteBuffers.add(ByteBuffer.wrap(continuationHeader2));
        headersBody.position(start + 2 * oneThird);
        headersBody.limit(start + length);
        byteBuffers.add(headersBody.slice());
        frames.clear();
        for (ByteBuffer buffer : lease.getByteBuffers()) {
            while (buffer.hasRemaining()) {
                parser.parse(ByteBuffer.wrap(new byte[] { buffer.get() }));
            }
        }
        Assert.assertEquals(1, frames.size());
        HeadersFrame frame = frames.get(0);
        Assert.assertEquals(streamId, frame.getStreamId());
        Assert.assertTrue(frame.isEndStream());
        MetaData.Request request = (MetaData.Request) frame.getMetaData();
        Assert.assertEquals(metaData.getMethod(), request.getMethod());
        Assert.assertEquals(metaData.getURI(), request.getURI());
        for (int j = 0; j < fields.size(); ++j) {
            HttpField field = fields.getField(j);
            Assert.assertTrue(request.getFields().contains(field));
        }
        PriorityFrame priority = frame.getPriority();
        Assert.assertNull(priority);
    }
}
Also used : ByteBufferPool(org.eclipse.jetty.io.ByteBufferPool) MappedByteBufferPool(org.eclipse.jetty.io.MappedByteBufferPool) ArrayList(java.util.ArrayList) HeadersGenerator(org.eclipse.jetty.http2.generator.HeadersGenerator) MetaData(org.eclipse.jetty.http.MetaData) HttpFields(org.eclipse.jetty.http.HttpFields) HeaderGenerator(org.eclipse.jetty.http2.generator.HeaderGenerator) HostPortHttpField(org.eclipse.jetty.http.HostPortHttpField) HpackEncoder(org.eclipse.jetty.http2.hpack.HpackEncoder) ByteBuffer(java.nio.ByteBuffer) Parser(org.eclipse.jetty.http2.parser.Parser) MappedByteBufferPool(org.eclipse.jetty.io.MappedByteBufferPool) HostPortHttpField(org.eclipse.jetty.http.HostPortHttpField) HttpField(org.eclipse.jetty.http.HttpField) Test(org.junit.Test)

Example 14 with MappedByteBufferPool

use of org.eclipse.jetty.io.MappedByteBufferPool in project jetty.project by eclipse.

the class ClientGeneratorTest method testGenerateRequestHeaders.

@Test
public void testGenerateRequestHeaders() throws Exception {
    HttpFields fields = new HttpFields();
    // Short name, short value
    final String shortShortName = "REQUEST_METHOD";
    final String shortShortValue = "GET";
    fields.put(new HttpField(shortShortName, shortShortValue));
    // Short name, long value
    final String shortLongName = "REQUEST_URI";
    // Be sure it's longer than 127 chars to test the large value
    final String shortLongValue = "/api/0.6/map?bbox=-64.217736,-31.456810,-64.187736,-31.432322,filler=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
    fields.put(new HttpField(shortLongName, shortLongValue));
    // Long name, short value
    // Be sure it's longer than 127 chars to test the large name
    final String longShortName = "FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210";
    final String longShortValue = "api.openstreetmap.org";
    fields.put(new HttpField(longShortName, longShortValue));
    // Long name, long value
    char[] chars = new char[ClientGenerator.MAX_PARAM_LENGTH];
    Arrays.fill(chars, 'z');
    final String longLongName = new String(chars);
    final String longLongValue = new String(chars);
    fields.put(new HttpField(longLongName, longLongValue));
    ByteBufferPool byteBufferPool = new MappedByteBufferPool();
    ClientGenerator generator = new ClientGenerator(byteBufferPool);
    final int id = 13;
    Generator.Result result = generator.generateRequestHeaders(id, fields, null);
    // Use the fundamental theorem of arithmetic to test the results.
    // This way we know onHeader() has been called the right number of
    // times with the right arguments, and so onHeaders().
    final int[] primes = new int[] { 2, 3, 5, 7, 11 };
    int value = 1;
    for (int prime : primes) value *= prime;
    final AtomicInteger params = new AtomicInteger(1);
    ServerParser parser = new ServerParser(new ServerParser.Listener.Adapter() {

        @Override
        public void onHeader(int request, HttpField field) {
            Assert.assertEquals(id, request);
            switch(field.getName()) {
                case shortShortName:
                    Assert.assertEquals(shortShortValue, field.getValue());
                    params.set(params.get() * primes[0]);
                    break;
                case shortLongName:
                    Assert.assertEquals(shortLongValue, field.getValue());
                    params.set(params.get() * primes[1]);
                    break;
                case longShortName:
                    Assert.assertEquals(longShortValue, field.getValue());
                    params.set(params.get() * primes[2]);
                    break;
                default:
                    Assert.assertEquals(longLongName, field.getName());
                    Assert.assertEquals(longLongValue, field.getValue());
                    params.set(params.get() * primes[3]);
                    break;
            }
        }

        @Override
        public void onHeaders(int request) {
            Assert.assertEquals(id, request);
            params.set(params.get() * primes[4]);
        }
    });
    for (ByteBuffer buffer : result.getByteBuffers()) {
        parser.parse(buffer);
        Assert.assertFalse(buffer.hasRemaining());
    }
    Assert.assertEquals(value, params.get());
    // Parse again byte by byte
    params.set(1);
    for (ByteBuffer buffer : result.getByteBuffers()) {
        buffer.flip();
        while (buffer.hasRemaining()) parser.parse(ByteBuffer.wrap(new byte[] { buffer.get() }));
        Assert.assertFalse(buffer.hasRemaining());
    }
    Assert.assertEquals(value, params.get());
}
Also used : MappedByteBufferPool(org.eclipse.jetty.io.MappedByteBufferPool) ByteBufferPool(org.eclipse.jetty.io.ByteBufferPool) ByteBuffer(java.nio.ByteBuffer) MappedByteBufferPool(org.eclipse.jetty.io.MappedByteBufferPool) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) HttpField(org.eclipse.jetty.http.HttpField) HttpFields(org.eclipse.jetty.http.HttpFields) ServerParser(org.eclipse.jetty.fcgi.parser.ServerParser) Test(org.junit.Test)

Example 15 with MappedByteBufferPool

use of org.eclipse.jetty.io.MappedByteBufferPool in project jetty.project by eclipse.

the class ClientParserTest method testParseLargeResponseContent.

@Test
public void testParseLargeResponseContent() throws Exception {
    final int id = 13;
    HttpFields fields = new HttpFields();
    ByteBuffer content = ByteBuffer.wrap(new byte[128 * 1024]);
    final int contentLength = content.remaining();
    final int code = 200;
    final String contentTypeName = "Content-Length";
    final String contentTypeValue = String.valueOf(contentLength);
    fields.put(contentTypeName, contentTypeValue);
    ByteBufferPool byteBufferPool = new MappedByteBufferPool();
    ServerGenerator generator = new ServerGenerator(byteBufferPool);
    Generator.Result result1 = generator.generateResponseHeaders(id, code, "OK", fields, null);
    Generator.Result result2 = generator.generateResponseContent(id, content, true, false, null);
    final AtomicInteger totalLength = new AtomicInteger();
    final AtomicBoolean verifier = new AtomicBoolean();
    ClientParser parser = new ClientParser(new ClientParser.Listener.Adapter() {

        @Override
        public boolean onContent(int request, FCGI.StreamType stream, ByteBuffer buffer) {
            Assert.assertEquals(id, request);
            totalLength.addAndGet(buffer.remaining());
            return false;
        }

        @Override
        public void onEnd(int request) {
            Assert.assertEquals(id, request);
            Assert.assertEquals(contentLength, totalLength.get());
            verifier.set(true);
        }
    });
    for (ByteBuffer buffer : result1.getByteBuffers()) {
        parser.parse(buffer);
        Assert.assertFalse(buffer.hasRemaining());
    }
    for (ByteBuffer buffer : result2.getByteBuffers()) {
        parser.parse(buffer);
        Assert.assertFalse(buffer.hasRemaining());
    }
    Assert.assertTrue(verifier.get());
}
Also used : MappedByteBufferPool(org.eclipse.jetty.io.MappedByteBufferPool) ByteBufferPool(org.eclipse.jetty.io.ByteBufferPool) ServerGenerator(org.eclipse.jetty.fcgi.generator.ServerGenerator) ByteBuffer(java.nio.ByteBuffer) MappedByteBufferPool(org.eclipse.jetty.io.MappedByteBufferPool) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) HttpFields(org.eclipse.jetty.http.HttpFields) Generator(org.eclipse.jetty.fcgi.generator.Generator) ServerGenerator(org.eclipse.jetty.fcgi.generator.ServerGenerator) FCGI(org.eclipse.jetty.fcgi.FCGI) Test(org.junit.Test)

Aggregations

MappedByteBufferPool (org.eclipse.jetty.io.MappedByteBufferPool)17 ByteBufferPool (org.eclipse.jetty.io.ByteBufferPool)13 ByteBuffer (java.nio.ByteBuffer)12 Test (org.junit.Test)12 HttpFields (org.eclipse.jetty.http.HttpFields)10 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)6 Generator (org.eclipse.jetty.http2.generator.Generator)6 MetaData (org.eclipse.jetty.http.MetaData)5 OutputStream (java.io.OutputStream)4 Socket (java.net.Socket)4 CountDownLatch (java.util.concurrent.CountDownLatch)4 FCGI (org.eclipse.jetty.fcgi.FCGI)4 Generator (org.eclipse.jetty.fcgi.generator.Generator)4 ServerGenerator (org.eclipse.jetty.fcgi.generator.ServerGenerator)4 HeadersFrame (org.eclipse.jetty.http2.frames.HeadersFrame)4 PrefaceFrame (org.eclipse.jetty.http2.frames.PrefaceFrame)4 SettingsFrame (org.eclipse.jetty.http2.frames.SettingsFrame)4 EndPoint (org.eclipse.jetty.io.EndPoint)4 QueuedThreadPool (org.eclipse.jetty.util.thread.QueuedThreadPool)4 InputStream (java.io.InputStream)3