Search in sources :

Example 36 with RawFrame

use of org.apache.hc.core5.http2.frame.RawFrame in project httpcomponents-core by apache.

the class H2FileServerExample method main.

public static void main(final String[] args) throws Exception {
    if (args.length < 1) {
        System.err.println("Please specify document root directory");
        System.exit(1);
    }
    // Document root directory
    final File docRoot = new File(args[0]);
    int port = 8080;
    if (args.length >= 2) {
        port = Integer.parseInt(args[1]);
    }
    final IOReactorConfig config = IOReactorConfig.custom().setSoTimeout(15, TimeUnit.SECONDS).setTcpNoDelay(true).build();
    final HttpAsyncServer server = H2ServerBootstrap.bootstrap().setIOReactorConfig(config).setVersionPolicy(HttpVersionPolicy.FORCE_HTTP_2).setStreamListener(new H2StreamListener() {

        @Override
        public void onHeaderInput(final HttpConnection connection, final int streamId, final List<? extends Header> headers) {
            for (int i = 0; i < headers.size(); i++) {
                System.out.println(connection.getRemoteAddress() + " (" + streamId + ") << " + headers.get(i));
            }
        }

        @Override
        public void onHeaderOutput(final HttpConnection connection, final int streamId, final List<? extends Header> headers) {
            for (int i = 0; i < headers.size(); i++) {
                System.out.println(connection.getRemoteAddress() + " (" + streamId + ") >> " + headers.get(i));
            }
        }

        @Override
        public void onFrameInput(final HttpConnection connection, final int streamId, final RawFrame frame) {
        }

        @Override
        public void onFrameOutput(final HttpConnection connection, final int streamId, final RawFrame frame) {
        }

        @Override
        public void onInputFlowControl(final HttpConnection connection, final int streamId, final int delta, final int actualSize) {
        }

        @Override
        public void onOutputFlowControl(final HttpConnection connection, final int streamId, final int delta, final int actualSize) {
        }
    }).register("*", new AsyncServerRequestHandler<Message<HttpRequest, Void>>() {

        @Override
        public AsyncRequestConsumer<Message<HttpRequest, Void>> prepare(final HttpRequest request, final EntityDetails entityDetails, final HttpContext context) throws HttpException {
            return new BasicRequestConsumer<>(entityDetails != null ? new DiscardingEntityConsumer<>() : null);
        }

        @Override
        public void handle(final Message<HttpRequest, Void> message, final ResponseTrigger responseTrigger, final HttpContext context) throws HttpException, IOException {
            final HttpRequest request = message.getHead();
            final URI requestUri;
            try {
                requestUri = request.getUri();
            } catch (final URISyntaxException ex) {
                throw new ProtocolException(ex.getMessage(), ex);
            }
            final String path = requestUri.getPath();
            final File file = new File(docRoot, path);
            if (!file.exists()) {
                System.out.println("File " + file.getPath() + " not found");
                responseTrigger.submitResponse(AsyncResponseBuilder.create(HttpStatus.SC_NOT_FOUND).setEntity("<html><body><h1>File" + file.getPath() + " not found</h1></body></html>", ContentType.TEXT_HTML).build(), context);
            } else if (!file.canRead() || file.isDirectory()) {
                System.out.println("Cannot read file " + file.getPath());
                responseTrigger.submitResponse(AsyncResponseBuilder.create(HttpStatus.SC_FORBIDDEN).setEntity("<html><body><h1>Access denied</h1></body></html>", ContentType.TEXT_HTML).build(), context);
            } else {
                final ContentType contentType;
                final String filename = TextUtils.toLowerCase(file.getName());
                if (filename.endsWith(".txt")) {
                    contentType = ContentType.TEXT_PLAIN;
                } else if (filename.endsWith(".html") || filename.endsWith(".htm")) {
                    contentType = ContentType.TEXT_HTML;
                } else if (filename.endsWith(".xml")) {
                    contentType = ContentType.TEXT_XML;
                } else {
                    contentType = ContentType.DEFAULT_BINARY;
                }
                final HttpCoreContext coreContext = HttpCoreContext.adapt(context);
                final EndpointDetails endpoint = coreContext.getEndpointDetails();
                System.out.println(endpoint + ": serving file " + file.getPath());
                responseTrigger.submitResponse(AsyncResponseBuilder.create(HttpStatus.SC_OK).setEntity(AsyncEntityProducers.create(file, contentType)).build(), context);
            }
        }
    }).create();
    Runtime.getRuntime().addShutdownHook(new Thread(() -> {
        System.out.println("HTTP server shutting down");
        server.close(CloseMode.GRACEFUL);
    }));
    server.start();
    final Future<ListenerEndpoint> future = server.listen(new InetSocketAddress(port), URIScheme.HTTP);
    final ListenerEndpoint listenerEndpoint = future.get();
    System.out.print("Listening on " + listenerEndpoint.getAddress());
    server.awaitShutdown(TimeValue.ofDays(Long.MAX_VALUE));
}
Also used : Message(org.apache.hc.core5.http.Message) ContentType(org.apache.hc.core5.http.ContentType) HttpConnection(org.apache.hc.core5.http.HttpConnection) BasicRequestConsumer(org.apache.hc.core5.http.nio.support.BasicRequestConsumer) InetSocketAddress(java.net.InetSocketAddress) URISyntaxException(java.net.URISyntaxException) URI(java.net.URI) IOReactorConfig(org.apache.hc.core5.reactor.IOReactorConfig) H2StreamListener(org.apache.hc.core5.http2.impl.nio.H2StreamListener) EntityDetails(org.apache.hc.core5.http.EntityDetails) HttpRequest(org.apache.hc.core5.http.HttpRequest) ProtocolException(org.apache.hc.core5.http.ProtocolException) HttpContext(org.apache.hc.core5.http.protocol.HttpContext) EndpointDetails(org.apache.hc.core5.http.EndpointDetails) ListenerEndpoint(org.apache.hc.core5.reactor.ListenerEndpoint) AsyncServerRequestHandler(org.apache.hc.core5.http.nio.AsyncServerRequestHandler) DiscardingEntityConsumer(org.apache.hc.core5.http.nio.entity.DiscardingEntityConsumer) HttpAsyncServer(org.apache.hc.core5.http.impl.bootstrap.HttpAsyncServer) ListenerEndpoint(org.apache.hc.core5.reactor.ListenerEndpoint) HttpCoreContext(org.apache.hc.core5.http.protocol.HttpCoreContext) RawFrame(org.apache.hc.core5.http2.frame.RawFrame) File(java.io.File)

Example 37 with RawFrame

use of org.apache.hc.core5.http2.frame.RawFrame in project httpcomponents-core by apache.

the class H2MultiStreamExecutionExample method main.

public static void main(final String[] args) throws Exception {
    // Create and start requester
    final IOReactorConfig ioReactorConfig = IOReactorConfig.custom().setSoTimeout(5, TimeUnit.SECONDS).build();
    final H2Config h2Config = H2Config.custom().setPushEnabled(false).setMaxConcurrentStreams(100).build();
    final HttpAsyncRequester requester = H2RequesterBootstrap.bootstrap().setIOReactorConfig(ioReactorConfig).setVersionPolicy(HttpVersionPolicy.FORCE_HTTP_2).setH2Config(h2Config).setStreamListener(new H2StreamListener() {

        @Override
        public void onHeaderInput(final HttpConnection connection, final int streamId, final List<? extends Header> headers) {
            for (int i = 0; i < headers.size(); i++) {
                System.out.println(connection.getRemoteAddress() + " (" + streamId + ") << " + headers.get(i));
            }
        }

        @Override
        public void onHeaderOutput(final HttpConnection connection, final int streamId, final List<? extends Header> headers) {
            for (int i = 0; i < headers.size(); i++) {
                System.out.println(connection.getRemoteAddress() + " (" + streamId + ") >> " + headers.get(i));
            }
        }

        @Override
        public void onFrameInput(final HttpConnection connection, final int streamId, final RawFrame frame) {
        }

        @Override
        public void onFrameOutput(final HttpConnection connection, final int streamId, final RawFrame frame) {
        }

        @Override
        public void onInputFlowControl(final HttpConnection connection, final int streamId, final int delta, final int actualSize) {
        }

        @Override
        public void onOutputFlowControl(final HttpConnection connection, final int streamId, final int delta, final int actualSize) {
        }
    }).create();
    Runtime.getRuntime().addShutdownHook(new Thread(() -> {
        System.out.println("HTTP requester shutting down");
        requester.close(CloseMode.GRACEFUL);
    }));
    requester.start();
    final HttpHost target = new HttpHost("nghttp2.org");
    final String[] requestUris = new String[] { "/httpbin/ip", "/httpbin/user-agent", "/httpbin/headers" };
    final Future<AsyncClientEndpoint> future = requester.connect(target, Timeout.ofSeconds(5));
    final AsyncClientEndpoint clientEndpoint = future.get();
    final CountDownLatch latch = new CountDownLatch(requestUris.length);
    for (final String requestUri : requestUris) {
        clientEndpoint.execute(AsyncRequestBuilder.get().setHttpHost(target).setPath(requestUri).build(), new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), new FutureCallback<Message<HttpResponse, String>>() {

            @Override
            public void completed(final Message<HttpResponse, String> message) {
                latch.countDown();
                final HttpResponse response = message.getHead();
                final String body = message.getBody();
                System.out.println(requestUri + "->" + response.getCode());
                System.out.println(body);
            }

            @Override
            public void failed(final Exception ex) {
                latch.countDown();
                System.out.println(requestUri + "->" + ex);
            }

            @Override
            public void cancelled() {
                latch.countDown();
                System.out.println(requestUri + " cancelled");
            }
        });
    }
    latch.await();
    // Manually release client endpoint when done !!!
    clientEndpoint.releaseAndDiscard();
    System.out.println("Shutting down I/O reactor");
    requester.initiateShutdown();
}
Also used : StringAsyncEntityConsumer(org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer) Message(org.apache.hc.core5.http.Message) HttpConnection(org.apache.hc.core5.http.HttpConnection) AsyncClientEndpoint(org.apache.hc.core5.http.nio.AsyncClientEndpoint) HttpResponse(org.apache.hc.core5.http.HttpResponse) CountDownLatch(java.util.concurrent.CountDownLatch) AsyncClientEndpoint(org.apache.hc.core5.http.nio.AsyncClientEndpoint) IOReactorConfig(org.apache.hc.core5.reactor.IOReactorConfig) H2StreamListener(org.apache.hc.core5.http2.impl.nio.H2StreamListener) Header(org.apache.hc.core5.http.Header) HttpHost(org.apache.hc.core5.http.HttpHost) RawFrame(org.apache.hc.core5.http2.frame.RawFrame) List(java.util.List) H2Config(org.apache.hc.core5.http2.config.H2Config) HttpAsyncRequester(org.apache.hc.core5.http.impl.bootstrap.HttpAsyncRequester)

Example 38 with RawFrame

use of org.apache.hc.core5.http2.frame.RawFrame in project httpcomponents-core by apache.

the class AbstractH2StreamMultiplexer method maximizeConnWindow.

private void maximizeConnWindow(final int connWinSize) throws IOException {
    final int delta = Integer.MAX_VALUE - connWinSize;
    if (delta > 0) {
        final RawFrame windowUpdateFrame = frameFactory.createWindowUpdate(0, delta);
        commitFrame(windowUpdateFrame);
        updateInputWindow(0, connInputWindow, delta);
    }
}
Also used : RawFrame(org.apache.hc.core5.http2.frame.RawFrame)

Example 39 with RawFrame

use of org.apache.hc.core5.http2.frame.RawFrame in project httpcomponents-core by apache.

the class AbstractH2StreamMultiplexer method onException.

public final void onException(final Exception cause) {
    try {
        for (; ; ) {
            final AsyncPingHandler pingHandler = pingHandlers.poll();
            if (pingHandler != null) {
                pingHandler.failed(cause);
            } else {
                break;
            }
        }
        for (; ; ) {
            final Command command = ioSession.poll();
            if (command != null) {
                if (command instanceof ExecutableCommand) {
                    ((ExecutableCommand) command).failed(new ConnectionClosedException());
                } else {
                    command.cancel();
                }
            } else {
                break;
            }
        }
        for (final Iterator<Map.Entry<Integer, H2Stream>> it = streamMap.entrySet().iterator(); it.hasNext(); ) {
            final Map.Entry<Integer, H2Stream> entry = it.next();
            final H2Stream stream = entry.getValue();
            stream.reset(cause);
        }
        streamMap.clear();
        if (!(cause instanceof ConnectionClosedException)) {
            if (connState.compareTo(ConnectionHandshake.GRACEFUL_SHUTDOWN) <= 0) {
                final H2Error errorCode;
                if (cause instanceof H2ConnectionException) {
                    errorCode = H2Error.getByCode(((H2ConnectionException) cause).getCode());
                } else if (cause instanceof ProtocolException) {
                    errorCode = H2Error.PROTOCOL_ERROR;
                } else {
                    errorCode = H2Error.INTERNAL_ERROR;
                }
                final RawFrame goAway = frameFactory.createGoAway(processedRemoteStreamId, errorCode, cause.getMessage());
                commitFrame(goAway);
            }
        }
    } catch (final IOException ignore) {
    } finally {
        connState = ConnectionHandshake.SHUTDOWN;
        final CloseMode closeMode;
        if (cause instanceof ConnectionClosedException) {
            closeMode = CloseMode.GRACEFUL;
        } else if (cause instanceof IOException) {
            closeMode = CloseMode.IMMEDIATE;
        } else {
            closeMode = CloseMode.GRACEFUL;
        }
        ioSession.close(closeMode);
    }
}
Also used : ProtocolException(org.apache.hc.core5.http.ProtocolException) H2ConnectionException(org.apache.hc.core5.http2.H2ConnectionException) ConnectionClosedException(org.apache.hc.core5.http.ConnectionClosedException) H2Error(org.apache.hc.core5.http2.H2Error) IOException(java.io.IOException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) PingCommand(org.apache.hc.core5.http2.nio.command.PingCommand) ExecutableCommand(org.apache.hc.core5.http.nio.command.ExecutableCommand) Command(org.apache.hc.core5.reactor.Command) ShutdownCommand(org.apache.hc.core5.http.nio.command.ShutdownCommand) AsyncPingHandler(org.apache.hc.core5.http2.nio.AsyncPingHandler) CloseMode(org.apache.hc.core5.io.CloseMode) RawFrame(org.apache.hc.core5.http2.frame.RawFrame) ExecutableCommand(org.apache.hc.core5.http.nio.command.ExecutableCommand) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap)

Example 40 with RawFrame

use of org.apache.hc.core5.http2.frame.RawFrame in project httpcomponents-core by apache.

the class AbstractH2StreamMultiplexer method onOutput.

public final void onOutput() throws HttpException, IOException {
    ioSession.getLock().lock();
    try {
        if (!outputBuffer.isEmpty()) {
            outputBuffer.flush(ioSession);
        }
        while (outputBuffer.isEmpty()) {
            final RawFrame frame = outputQueue.poll();
            if (frame != null) {
                if (streamListener != null) {
                    streamListener.onFrameOutput(this, frame.getStreamId(), frame);
                }
                outputBuffer.write(frame, ioSession);
            } else {
                break;
            }
        }
    } finally {
        ioSession.getLock().unlock();
    }
    if (connState.compareTo(ConnectionHandshake.SHUTDOWN) < 0) {
        if (connOutputWindow.get() > 0 && remoteSettingState == SettingsHandshake.ACKED) {
            produceOutput();
        }
        final int pendingOutputRequests = outputRequests.get();
        boolean outputPending = false;
        if (!streamMap.isEmpty() && connOutputWindow.get() > 0) {
            for (final Iterator<Map.Entry<Integer, H2Stream>> it = streamMap.entrySet().iterator(); it.hasNext(); ) {
                final Map.Entry<Integer, H2Stream> entry = it.next();
                final H2Stream stream = entry.getValue();
                if (!stream.isLocalClosed() && stream.getOutputWindow().get() > 0 && stream.isOutputReady()) {
                    outputPending = true;
                    break;
                }
            }
        }
        ioSession.getLock().lock();
        try {
            if (!outputPending && outputBuffer.isEmpty() && outputQueue.isEmpty() && outputRequests.compareAndSet(pendingOutputRequests, 0)) {
                ioSession.clearEvent(SelectionKey.OP_WRITE);
            } else {
                outputRequests.addAndGet(-pendingOutputRequests);
            }
        } finally {
            ioSession.getLock().unlock();
        }
    }
    if (connState.compareTo(ConnectionHandshake.ACTIVE) <= 0 && remoteSettingState == SettingsHandshake.ACKED) {
        processPendingCommands();
    }
    if (connState.compareTo(ConnectionHandshake.GRACEFUL_SHUTDOWN) == 0) {
        int liveStreams = 0;
        for (final Iterator<Map.Entry<Integer, H2Stream>> it = streamMap.entrySet().iterator(); it.hasNext(); ) {
            final Map.Entry<Integer, H2Stream> entry = it.next();
            final H2Stream stream = entry.getValue();
            if (stream.isLocalClosed() && stream.isRemoteClosed()) {
                stream.releaseResources();
                it.remove();
            } else {
                if (idGenerator.isSameSide(stream.getId()) || stream.getId() <= processedRemoteStreamId) {
                    liveStreams++;
                }
            }
        }
        if (liveStreams == 0) {
            connState = ConnectionHandshake.SHUTDOWN;
        }
    }
    if (connState.compareTo(ConnectionHandshake.SHUTDOWN) >= 0) {
        if (!streamMap.isEmpty()) {
            for (final H2Stream stream : streamMap.values()) {
                stream.releaseResources();
            }
            streamMap.clear();
        }
        ioSession.getLock().lock();
        try {
            if (outputBuffer.isEmpty() && outputQueue.isEmpty()) {
                ioSession.close();
            }
        } finally {
            ioSession.getLock().unlock();
        }
    }
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) RawFrame(org.apache.hc.core5.http2.frame.RawFrame) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap)

Aggregations

RawFrame (org.apache.hc.core5.http2.frame.RawFrame)38 ByteBuffer (java.nio.ByteBuffer)24 Test (org.junit.jupiter.api.Test)15 Header (org.apache.hc.core5.http.Header)10 HttpConnection (org.apache.hc.core5.http.HttpConnection)9 H2StreamListener (org.apache.hc.core5.http2.impl.nio.H2StreamListener)9 HttpResponse (org.apache.hc.core5.http.HttpResponse)8 List (java.util.List)7 HttpAsyncRequester (org.apache.hc.core5.http.impl.bootstrap.HttpAsyncRequester)7 H2Config (org.apache.hc.core5.http2.config.H2Config)7 CountDownLatch (java.util.concurrent.CountDownLatch)6 Message (org.apache.hc.core5.http.Message)6 StringAsyncEntityConsumer (org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer)6 H2ConnectionException (org.apache.hc.core5.http2.H2ConnectionException)6 Map (java.util.Map)5 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)5 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)5 HttpHost (org.apache.hc.core5.http.HttpHost)5 AsyncClientEndpoint (org.apache.hc.core5.http.nio.AsyncClientEndpoint)5 H2StreamResetException (org.apache.hc.core5.http2.H2StreamResetException)5