Search in sources :

Example 11 with SocketChannel

use of java.nio.channels.SocketChannel in project jetty.project by eclipse.

the class ConnectHandlerTest method testCONNECTAndPOSTWithContext.

@Test
public void testCONNECTAndPOSTWithContext() throws Exception {
    final String contextKey = "contextKey";
    final String contextValue = "contextValue";
    // Replace the default ProxyHandler with a subclass to test context information passing
    disposeProxy();
    proxy.setHandler(new ConnectHandler() {

        @Override
        protected boolean handleAuthentication(HttpServletRequest request, HttpServletResponse response, String address) {
            request.setAttribute(contextKey, contextValue);
            return super.handleAuthentication(request, response, address);
        }

        @Override
        protected void connectToServer(HttpServletRequest request, String host, int port, Promise<SocketChannel> promise) {
            Assert.assertEquals(contextValue, request.getAttribute(contextKey));
            super.connectToServer(request, host, port, promise);
        }

        @Override
        protected void prepareContext(HttpServletRequest request, ConcurrentMap<String, Object> context) {
            // Transfer data from the HTTP request to the connection context
            Assert.assertEquals(contextValue, request.getAttribute(contextKey));
            context.put(contextKey, request.getAttribute(contextKey));
        }

        @Override
        protected int read(EndPoint endPoint, ByteBuffer buffer, ConcurrentMap<String, Object> context) throws IOException {
            Assert.assertEquals(contextValue, context.get(contextKey));
            return super.read(endPoint, buffer, context);
        }

        @Override
        protected void write(EndPoint endPoint, ByteBuffer buffer, Callback callback, ConcurrentMap<String, Object> context) {
            Assert.assertEquals(contextValue, context.get(contextKey));
            super.write(endPoint, buffer, callback, context);
        }
    });
    proxy.start();
    String hostPort = "localhost:" + serverConnector.getLocalPort();
    String request = "" + "CONNECT " + hostPort + " HTTP/1.1\r\n" + "Host: " + hostPort + "\r\n" + "\r\n";
    try (Socket socket = newSocket()) {
        OutputStream output = socket.getOutputStream();
        InputStream input = socket.getInputStream();
        output.write(request.getBytes(StandardCharsets.UTF_8));
        output.flush();
        // Expect 200 OK from the CONNECT request
        HttpTester.Response response = readResponse(input);
        Assert.assertEquals(HttpStatus.OK_200, response.getStatus());
        String body = "0123456789ABCDEF";
        request = "" + "POST /echo HTTP/1.1\r\n" + "Host: " + hostPort + "\r\n" + "Content-Length: " + body.length() + "\r\n" + "\r\n" + body;
        output.write(request.getBytes(StandardCharsets.UTF_8));
        output.flush();
        response = readResponse(input);
        Assert.assertEquals(HttpStatus.OK_200, response.getStatus());
        Assert.assertEquals("POST /echo\r\n" + body, response.getContent());
    }
}
Also used : SocketChannel(java.nio.channels.SocketChannel) InputStream(java.io.InputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) ServletOutputStream(javax.servlet.ServletOutputStream) OutputStream(java.io.OutputStream) HttpServletResponse(javax.servlet.http.HttpServletResponse) EndPoint(org.eclipse.jetty.io.EndPoint) IOException(java.io.IOException) ByteBuffer(java.nio.ByteBuffer) EndPoint(org.eclipse.jetty.io.EndPoint) HttpTester(org.eclipse.jetty.http.HttpTester) HttpServletRequest(javax.servlet.http.HttpServletRequest) Callback(org.eclipse.jetty.util.Callback) Socket(java.net.Socket) Test(org.junit.Test)

Example 12 with SocketChannel

use of java.nio.channels.SocketChannel in project jetty.project by eclipse.

the class ConnectHandler method connectToServer.

protected void connectToServer(HttpServletRequest request, String host, int port, Promise<SocketChannel> promise) {
    SocketChannel channel = null;
    try {
        channel = SocketChannel.open();
        channel.socket().setTcpNoDelay(true);
        channel.configureBlocking(false);
        InetSocketAddress address = newConnectAddress(host, port);
        channel.connect(address);
        promise.succeeded(channel);
    } catch (Throwable x) {
        close(channel);
        promise.failed(x);
    }
}
Also used : SocketChannel(java.nio.channels.SocketChannel) InetSocketAddress(java.net.InetSocketAddress)

Example 13 with SocketChannel

use of java.nio.channels.SocketChannel in project jetty.project by eclipse.

the class HttpVersionCustomizerTest method testCustomizeHttpVersion.

@Test
public void testCustomizeHttpVersion() throws Exception {
    Server server = new Server();
    HttpConfiguration httpConfig = new HttpConfiguration();
    httpConfig.addCustomizer((connector, config, request) -> request.setHttpVersion(HttpVersion.HTTP_1_1));
    ServerConnector connector = new ServerConnector(server, new HttpConnectionFactory(httpConfig));
    server.addConnector(connector);
    server.setHandler(new AbstractHandler() {

        @Override
        public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
            baseRequest.setHandled(true);
            response.setStatus(500);
            Assert.assertEquals(HttpVersion.HTTP_1_1.asString(), request.getProtocol());
            response.setStatus(200);
            response.getWriter().println("OK");
        }
    });
    server.start();
    try {
        try (SocketChannel socket = SocketChannel.open(new InetSocketAddress("localhost", connector.getLocalPort()))) {
            HttpTester.Request request = HttpTester.newRequest();
            request.setVersion(HttpVersion.HTTP_1_0);
            socket.write(request.generate());
            HttpTester.Response response = HttpTester.parseResponse(HttpTester.from(socket));
            Assert.assertNotNull(response);
            Assert.assertThat(response.getStatus(), Matchers.equalTo(HttpStatus.OK_200));
        }
    } finally {
        server.stop();
    }
}
Also used : SocketChannel(java.nio.channels.SocketChannel) InetSocketAddress(java.net.InetSocketAddress) HttpServletRequest(javax.servlet.http.HttpServletRequest) HttpServletResponse(javax.servlet.http.HttpServletResponse) IOException(java.io.IOException) AbstractHandler(org.eclipse.jetty.server.handler.AbstractHandler) HttpTester(org.eclipse.jetty.http.HttpTester) HttpServletRequest(javax.servlet.http.HttpServletRequest) ServletException(javax.servlet.ServletException) Test(org.junit.Test)

Example 14 with SocketChannel

use of java.nio.channels.SocketChannel in project jetty.project by eclipse.

the class PrefaceTest method testClientPrefaceReplySentAfterServerPreface.

@Test
public void testClientPrefaceReplySentAfterServerPreface() throws Exception {
    start(new ServerSessionListener.Adapter() {

        @Override
        public Map<Integer, Integer> onPreface(Session session) {
            Map<Integer, Integer> settings = new HashMap<>();
            settings.put(SettingsFrame.MAX_CONCURRENT_STREAMS, 128);
            return settings;
        }

        @Override
        public void onPing(Session session, PingFrame frame) {
            session.close(ErrorCode.NO_ERROR.code, null, Callback.NOOP);
        }
    });
    ByteBufferPool byteBufferPool = client.getByteBufferPool();
    try (SocketChannel socket = SocketChannel.open()) {
        socket.connect(new InetSocketAddress("localhost", connector.getLocalPort()));
        Generator generator = new Generator(byteBufferPool);
        ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
        generator.control(lease, new PrefaceFrame());
        Map<Integer, Integer> clientSettings = new HashMap<>();
        clientSettings.put(SettingsFrame.ENABLE_PUSH, 0);
        generator.control(lease, new SettingsFrame(clientSettings, false));
        // The PING frame just to make sure the client stops reading.
        generator.control(lease, new PingFrame(true));
        List<ByteBuffer> buffers = lease.getByteBuffers();
        socket.write(buffers.toArray(new ByteBuffer[buffers.size()]));
        Queue<SettingsFrame> settings = new ArrayDeque<>();
        Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() {

            @Override
            public void onSettings(SettingsFrame frame) {
                settings.offer(frame);
            }
        }, 4096, 8192);
        ByteBuffer buffer = byteBufferPool.acquire(1024, true);
        while (true) {
            BufferUtil.clearToFill(buffer);
            int read = socket.read(buffer);
            BufferUtil.flipToFlush(buffer, 0);
            if (read < 0)
                break;
            parser.parse(buffer);
        }
        Assert.assertEquals(2, settings.size());
        SettingsFrame frame1 = settings.poll();
        Assert.assertFalse(frame1.isReply());
        SettingsFrame frame2 = settings.poll();
        Assert.assertTrue(frame2.isReply());
    }
}
Also used : ByteBufferPool(org.eclipse.jetty.io.ByteBufferPool) MappedByteBufferPool(org.eclipse.jetty.io.MappedByteBufferPool) SocketChannel(java.nio.channels.SocketChannel) ServerSessionListener(org.eclipse.jetty.http2.api.server.ServerSessionListener) PingFrame(org.eclipse.jetty.http2.frames.PingFrame) HashMap(java.util.HashMap) InetSocketAddress(java.net.InetSocketAddress) SettingsFrame(org.eclipse.jetty.http2.frames.SettingsFrame) ByteBuffer(java.nio.ByteBuffer) ArrayDeque(java.util.ArrayDeque) EndPoint(org.eclipse.jetty.io.EndPoint) Parser(org.eclipse.jetty.http2.parser.Parser) PrefaceFrame(org.eclipse.jetty.http2.frames.PrefaceFrame) HashMap(java.util.HashMap) Map(java.util.Map) ServerSessionListener(org.eclipse.jetty.http2.api.server.ServerSessionListener) Session(org.eclipse.jetty.http2.api.Session) Generator(org.eclipse.jetty.http2.generator.Generator) Test(org.junit.Test)

Example 15 with SocketChannel

use of java.nio.channels.SocketChannel in project jetty.project by eclipse.

the class PrefaceTest method testOnPrefaceNotifiedForStandardUpgrade.

@Test
public void testOnPrefaceNotifiedForStandardUpgrade() throws Exception {
    Integer maxConcurrentStreams = 128;
    AtomicReference<CountDownLatch> serverPrefaceLatch = new AtomicReference<>(new CountDownLatch(1));
    AtomicReference<CountDownLatch> serverSettingsLatch = new AtomicReference<>(new CountDownLatch(1));
    HttpConfiguration config = new HttpConfiguration();
    prepareServer(new HttpConnectionFactory(config), new HTTP2CServerConnectionFactory(config) {

        @Override
        protected ServerSessionListener newSessionListener(Connector connector, EndPoint endPoint) {
            return new ServerSessionListener.Adapter() {

                @Override
                public Map<Integer, Integer> onPreface(Session session) {
                    Map<Integer, Integer> serverSettings = new HashMap<>();
                    serverSettings.put(SettingsFrame.MAX_CONCURRENT_STREAMS, maxConcurrentStreams);
                    serverPrefaceLatch.get().countDown();
                    return serverSettings;
                }

                @Override
                public void onSettings(Session session, SettingsFrame frame) {
                    serverSettingsLatch.get().countDown();
                }

                @Override
                public Stream.Listener onNewStream(Stream stream, HeadersFrame frame) {
                    MetaData.Response response = new MetaData.Response(HttpVersion.HTTP_2, HttpStatus.OK_200, new HttpFields());
                    stream.headers(new HeadersFrame(stream.getId(), response, null, true), Callback.NOOP);
                    return null;
                }
            };
        }
    });
    server.start();
    ByteBufferPool byteBufferPool = new MappedByteBufferPool();
    try (SocketChannel socket = SocketChannel.open()) {
        socket.connect(new InetSocketAddress("localhost", connector.getLocalPort()));
        String upgradeRequest = "" + "GET /one HTTP/1.1\r\n" + "Host: localhost\r\n" + "Connection: Upgrade, HTTP2-Settings\r\n" + "Upgrade: h2c\r\n" + "HTTP2-Settings: \r\n" + "\r\n";
        ByteBuffer upgradeBuffer = ByteBuffer.wrap(upgradeRequest.getBytes(StandardCharsets.ISO_8859_1));
        socket.write(upgradeBuffer);
        // Make sure onPreface() is called on server.
        Assert.assertTrue(serverPrefaceLatch.get().await(5, TimeUnit.SECONDS));
        Assert.assertTrue(serverSettingsLatch.get().await(5, TimeUnit.SECONDS));
        // The 101 response is the reply to the client preface SETTINGS frame.
        ByteBuffer buffer = byteBufferPool.acquire(1024, true);
        http1: while (true) {
            BufferUtil.clearToFill(buffer);
            int read = socket.read(buffer);
            BufferUtil.flipToFlush(buffer, 0);
            if (read < 0)
                Assert.fail();
            int crlfs = 0;
            while (buffer.hasRemaining()) {
                byte b = buffer.get();
                if (b == '\r' || b == '\n')
                    ++crlfs;
                else
                    crlfs = 0;
                if (crlfs == 4)
                    break http1;
            }
        }
        // Reset the latches on server.
        serverPrefaceLatch.set(new CountDownLatch(1));
        serverSettingsLatch.set(new CountDownLatch(1));
        // After the 101, the client must send the connection preface.
        Generator generator = new Generator(byteBufferPool);
        ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
        generator.control(lease, new PrefaceFrame());
        Map<Integer, Integer> clientSettings = new HashMap<>();
        clientSettings.put(SettingsFrame.ENABLE_PUSH, 1);
        generator.control(lease, new SettingsFrame(clientSettings, false));
        List<ByteBuffer> buffers = lease.getByteBuffers();
        socket.write(buffers.toArray(new ByteBuffer[buffers.size()]));
        // However, we should not call onPreface() again.
        Assert.assertFalse(serverPrefaceLatch.get().await(1, TimeUnit.SECONDS));
        // Although we should notify of the SETTINGS frame.
        Assert.assertTrue(serverSettingsLatch.get().await(5, TimeUnit.SECONDS));
        CountDownLatch clientSettingsLatch = new CountDownLatch(1);
        AtomicBoolean responded = new AtomicBoolean();
        Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() {

            @Override
            public void onSettings(SettingsFrame frame) {
                if (frame.isReply())
                    return;
                Assert.assertEquals(maxConcurrentStreams, frame.getSettings().get(SettingsFrame.MAX_CONCURRENT_STREAMS));
                clientSettingsLatch.countDown();
            }

            @Override
            public void onHeaders(HeadersFrame frame) {
                if (frame.isEndStream())
                    responded.set(true);
            }
        }, 4096, 8192);
        // HTTP/2 parsing.
        while (true) {
            parser.parse(buffer);
            if (responded.get())
                break;
            BufferUtil.clearToFill(buffer);
            int read = socket.read(buffer);
            BufferUtil.flipToFlush(buffer, 0);
            if (read < 0)
                Assert.fail();
        }
        Assert.assertTrue(clientSettingsLatch.await(5, TimeUnit.SECONDS));
    }
}
Also used : ByteBufferPool(org.eclipse.jetty.io.ByteBufferPool) MappedByteBufferPool(org.eclipse.jetty.io.MappedByteBufferPool) Connector(org.eclipse.jetty.server.Connector) SocketChannel(java.nio.channels.SocketChannel) ServerSessionListener(org.eclipse.jetty.http2.api.server.ServerSessionListener) HashMap(java.util.HashMap) InetSocketAddress(java.net.InetSocketAddress) HttpConfiguration(org.eclipse.jetty.server.HttpConfiguration) EndPoint(org.eclipse.jetty.io.EndPoint) HeadersFrame(org.eclipse.jetty.http2.frames.HeadersFrame) SettingsFrame(org.eclipse.jetty.http2.frames.SettingsFrame) HTTP2CServerConnectionFactory(org.eclipse.jetty.http2.server.HTTP2CServerConnectionFactory) MetaData(org.eclipse.jetty.http.MetaData) HttpFields(org.eclipse.jetty.http.HttpFields) Stream(org.eclipse.jetty.http2.api.Stream) HttpConnectionFactory(org.eclipse.jetty.server.HttpConnectionFactory) AtomicReference(java.util.concurrent.atomic.AtomicReference) 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) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) Map(java.util.Map) ServerSessionListener(org.eclipse.jetty.http2.api.server.ServerSessionListener) Session(org.eclipse.jetty.http2.api.Session) Generator(org.eclipse.jetty.http2.generator.Generator) Test(org.junit.Test)

Aggregations

SocketChannel (java.nio.channels.SocketChannel)759 ServerSocketChannel (java.nio.channels.ServerSocketChannel)337 IOException (java.io.IOException)321 InetSocketAddress (java.net.InetSocketAddress)228 ByteBuffer (java.nio.ByteBuffer)188 SelectionKey (java.nio.channels.SelectionKey)126 Socket (java.net.Socket)101 Test (org.junit.Test)87 ClosedChannelException (java.nio.channels.ClosedChannelException)63 ServerSocket (java.net.ServerSocket)49 Selector (java.nio.channels.Selector)48 SocketAddress (java.net.SocketAddress)36 ClosedSelectorException (java.nio.channels.ClosedSelectorException)33 ConnectException (java.net.ConnectException)27 CancelledKeyException (java.nio.channels.CancelledKeyException)27 ArrayList (java.util.ArrayList)27 SocketTimeoutException (java.net.SocketTimeoutException)25 SelectableChannel (java.nio.channels.SelectableChannel)23 HashMap (java.util.HashMap)23 OutputStream (java.io.OutputStream)22