Search in sources :

Example 1 with ChannelExceptionHandler

use of org.xnio.ChannelExceptionHandler in project undertow by undertow-io.

the class HttpClientConnection method initiateRequest.

private void initiateRequest(HttpClientExchange httpClientExchange) {
    this.requestCount++;
    currentRequest = httpClientExchange;
    pendingResponse = new HttpResponseBuilder();
    ClientRequest request = httpClientExchange.getRequest();
    String connectionString = request.getRequestHeaders().getFirst(Headers.CONNECTION);
    if (connectionString != null) {
        if (Headers.CLOSE.equalToString(connectionString)) {
            state |= CLOSE_REQ;
        } else if (Headers.UPGRADE.equalToString(connectionString)) {
            state |= UPGRADE_REQUESTED;
        }
    } else if (request.getProtocol() != Protocols.HTTP_1_1) {
        state |= CLOSE_REQ;
    }
    if (request.getRequestHeaders().contains(Headers.UPGRADE)) {
        state |= UPGRADE_REQUESTED;
    }
    if (request.getMethod().equals(Methods.CONNECT)) {
        // we treat CONNECT like upgrade requests
        state |= UPGRADE_REQUESTED;
    }
    // setup the client request conduits
    final ConduitStreamSourceChannel sourceChannel = connection.getSourceChannel();
    sourceChannel.setReadListener(clientReadListener);
    sourceChannel.resumeReads();
    ConduitStreamSinkChannel sinkChannel = connection.getSinkChannel();
    StreamSinkConduit conduit = originalSinkConduit;
    HttpRequestConduit httpRequestConduit = new HttpRequestConduit(conduit, bufferPool, request);
    httpClientExchange.setRequestConduit(httpRequestConduit);
    conduit = httpRequestConduit;
    String fixedLengthString = request.getRequestHeaders().getFirst(Headers.CONTENT_LENGTH);
    String transferEncodingString = request.getRequestHeaders().getLast(Headers.TRANSFER_ENCODING);
    boolean hasContent = true;
    if (fixedLengthString != null) {
        try {
            long length = Long.parseLong(fixedLengthString);
            conduit = new ClientFixedLengthStreamSinkConduit(conduit, length, false, false, currentRequest);
            hasContent = length != 0;
        } catch (NumberFormatException e) {
            handleError(e);
            return;
        }
    } else if (transferEncodingString != null) {
        if (!transferEncodingString.toLowerCase(Locale.ENGLISH).contains(Headers.CHUNKED.toString())) {
            handleError(UndertowClientMessages.MESSAGES.unknownTransferEncoding(transferEncodingString));
            return;
        }
        conduit = new ChunkedStreamSinkConduit(conduit, httpClientExchange.getConnection().getBufferPool(), false, false, httpClientExchange.getRequest().getRequestHeaders(), requestFinishListener, httpClientExchange);
    } else {
        conduit = new ClientFixedLengthStreamSinkConduit(conduit, 0, false, false, currentRequest);
        hasContent = false;
    }
    sinkChannel.setConduit(conduit);
    httpClientExchange.invokeReadReadyCallback();
    if (!hasContent) {
        // otherwise it is up to the user
        try {
            sinkChannel.shutdownWrites();
            if (!sinkChannel.flush()) {
                sinkChannel.setWriteListener(ChannelListeners.flushingChannelListener(null, new ChannelExceptionHandler<ConduitStreamSinkChannel>() {

                    @Override
                    public void handleException(ConduitStreamSinkChannel channel, IOException exception) {
                        handleError(exception);
                    }
                }));
                sinkChannel.resumeWrites();
            }
        } catch (Throwable t) {
            handleError(t);
        }
    }
}
Also used : ChunkedStreamSinkConduit(io.undertow.conduits.ChunkedStreamSinkConduit) HttpString(io.undertow.util.HttpString) IOException(java.io.IOException) StreamSinkConduit(org.xnio.conduits.StreamSinkConduit) WriteTimeoutStreamSinkConduit(io.undertow.conduits.WriteTimeoutStreamSinkConduit) BytesSentStreamSinkConduit(io.undertow.conduits.BytesSentStreamSinkConduit) ChunkedStreamSinkConduit(io.undertow.conduits.ChunkedStreamSinkConduit) ChannelExceptionHandler(org.xnio.ChannelExceptionHandler) ConduitStreamSourceChannel(org.xnio.conduits.ConduitStreamSourceChannel) ClientRequest(io.undertow.client.ClientRequest) ConduitStreamSinkChannel(org.xnio.conduits.ConduitStreamSinkChannel)

Example 2 with ChannelExceptionHandler

use of org.xnio.ChannelExceptionHandler in project undertow by undertow-io.

the class Http2ClientConnection method sendRequest.

@Override
public void sendRequest(ClientRequest request, ClientCallback<ClientExchange> clientCallback) {
    if (!http2Channel.isOpen()) {
        clientCallback.failed(new ClosedChannelException());
        return;
    }
    request.getRequestHeaders().put(METHOD, request.getMethod().toString());
    boolean connectRequest = request.getMethod().equals(Methods.CONNECT);
    if (!connectRequest) {
        request.getRequestHeaders().put(PATH, request.getPath());
        request.getRequestHeaders().put(SCHEME, secure ? "https" : "http");
    }
    final String host = request.getRequestHeaders().getFirst(Headers.HOST);
    if (host != null) {
        request.getRequestHeaders().put(AUTHORITY, host);
    } else {
        request.getRequestHeaders().put(AUTHORITY, defaultHost);
    }
    request.getRequestHeaders().remove(Headers.HOST);
    boolean hasContent = true;
    String fixedLengthString = request.getRequestHeaders().getFirst(CONTENT_LENGTH);
    String transferEncodingString = request.getRequestHeaders().getLast(TRANSFER_ENCODING);
    if (fixedLengthString != null) {
        try {
            long length = Long.parseLong(fixedLengthString);
            hasContent = length != 0;
        } catch (NumberFormatException e) {
            handleError(new IOException(e));
            return;
        }
    } else if (transferEncodingString == null && !connectRequest) {
        hasContent = false;
    }
    request.getRequestHeaders().remove(Headers.CONNECTION);
    request.getRequestHeaders().remove(Headers.KEEP_ALIVE);
    request.getRequestHeaders().remove(Headers.TRANSFER_ENCODING);
    Http2HeadersStreamSinkChannel sinkChannel;
    try {
        sinkChannel = http2Channel.createStream(request.getRequestHeaders());
    } catch (Throwable t) {
        IOException e = t instanceof IOException ? (IOException) t : new IOException(t);
        clientCallback.failed(e);
        return;
    }
    Http2ClientExchange exchange = new Http2ClientExchange(this, sinkChannel, request);
    currentExchanges.put(sinkChannel.getStreamId(), exchange);
    sinkChannel.setTrailersProducer(new Http2DataStreamSinkChannel.TrailersProducer() {

        @Override
        public HeaderMap getTrailers() {
            HeaderMap attachment = exchange.getAttachment(HttpAttachments.RESPONSE_TRAILERS);
            Supplier<HeaderMap> supplier = exchange.getAttachment(HttpAttachments.RESPONSE_TRAILER_SUPPLIER);
            if (attachment != null && supplier == null) {
                return attachment;
            } else if (attachment == null && supplier != null) {
                return supplier.get();
            } else if (attachment != null) {
                HeaderMap supplied = supplier.get();
                for (HeaderValues k : supplied) {
                    attachment.putAll(k.getHeaderName(), k);
                }
                return attachment;
            } else {
                return null;
            }
        }
    });
    if (clientCallback != null) {
        clientCallback.completed(exchange);
    }
    if (!hasContent) {
        // otherwise it is up to the user
        try {
            sinkChannel.shutdownWrites();
            if (!sinkChannel.flush()) {
                sinkChannel.getWriteSetter().set(ChannelListeners.flushingChannelListener(null, new ChannelExceptionHandler<StreamSinkChannel>() {

                    @Override
                    public void handleException(StreamSinkChannel channel, IOException exception) {
                        handleError(exception);
                    }
                }));
                sinkChannel.resumeWrites();
            }
        } catch (Throwable e) {
            handleError(e);
        }
    }
}
Also used : ClosedChannelException(java.nio.channels.ClosedChannelException) Http2HeadersStreamSinkChannel(io.undertow.protocols.http2.Http2HeadersStreamSinkChannel) HeaderValues(io.undertow.util.HeaderValues) Http2DataStreamSinkChannel(io.undertow.protocols.http2.Http2DataStreamSinkChannel) StreamSinkChannel(org.xnio.channels.StreamSinkChannel) Http2HeadersStreamSinkChannel(io.undertow.protocols.http2.Http2HeadersStreamSinkChannel) HttpString(io.undertow.util.HttpString) IOException(java.io.IOException) Http2DataStreamSinkChannel(io.undertow.protocols.http2.Http2DataStreamSinkChannel) HeaderMap(io.undertow.util.HeaderMap) ChannelExceptionHandler(org.xnio.ChannelExceptionHandler) Supplier(java.util.function.Supplier)

Example 3 with ChannelExceptionHandler

use of org.xnio.ChannelExceptionHandler in project undertow by undertow-io.

the class AsyncSenderImpl method close.

@Override
public void close(final IoCallback callback) {
    try {
        StreamSinkChannel channel = this.channel;
        if (channel == null) {
            if (exchange.getResponseContentLength() == -1 && !exchange.getResponseHeaders().contains(Headers.TRANSFER_ENCODING)) {
                exchange.setResponseContentLength(0);
            }
            this.channel = channel = exchange.getResponseChannel();
            if (channel == null) {
                throw UndertowMessages.MESSAGES.responseChannelAlreadyProvided();
            }
        }
        channel.shutdownWrites();
        if (!channel.flush()) {
            channel.getWriteSetter().set(ChannelListeners.flushingChannelListener(new ChannelListener<StreamSinkChannel>() {

                @Override
                public void handleEvent(final StreamSinkChannel channel) {
                    if (callback != null) {
                        callback.onComplete(exchange, AsyncSenderImpl.this);
                    }
                }
            }, new ChannelExceptionHandler<StreamSinkChannel>() {

                @Override
                public void handleException(final StreamSinkChannel channel, final IOException exception) {
                    try {
                        if (callback != null) {
                            invokeOnException(callback, exception);
                        }
                    } finally {
                        IoUtils.safeClose(channel);
                    }
                }
            }));
            channel.resumeWrites();
        } else {
            if (callback != null) {
                callback.onComplete(exchange, this);
            }
        }
    } catch (IOException e) {
        if (callback != null) {
            invokeOnException(callback, e);
        }
    }
}
Also used : ChannelListener(org.xnio.ChannelListener) StreamSinkChannel(org.xnio.channels.StreamSinkChannel) ChannelExceptionHandler(org.xnio.ChannelExceptionHandler) IOException(java.io.IOException)

Example 4 with ChannelExceptionHandler

use of org.xnio.ChannelExceptionHandler in project undertow by undertow-io.

the class ServerSentEventHandler method handleRequest.

@Override
public void handleRequest(final HttpServerExchange exchange) throws Exception {
    exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "text/event-stream; charset=UTF-8");
    exchange.setPersistent(false);
    final StreamSinkChannel sink = exchange.getResponseChannel();
    if (!sink.flush()) {
        sink.getWriteSetter().set(ChannelListeners.flushingChannelListener(new ChannelListener<StreamSinkChannel>() {

            @Override
            public void handleEvent(StreamSinkChannel channel) {
                handleConnect(channel, exchange);
            }
        }, new ChannelExceptionHandler<StreamSinkChannel>() {

            @Override
            public void handleException(StreamSinkChannel channel, IOException exception) {
                IoUtils.safeClose(exchange.getConnection());
            }
        }));
        sink.resumeWrites();
    } else {
        exchange.dispatch(exchange.getIoThread(), new Runnable() {

            @Override
            public void run() {
                handleConnect(sink, exchange);
            }
        });
    }
}
Also used : ChannelListener(org.xnio.ChannelListener) StreamSinkChannel(org.xnio.channels.StreamSinkChannel) ChannelExceptionHandler(org.xnio.ChannelExceptionHandler) IOException(java.io.IOException)

Example 5 with ChannelExceptionHandler

use of org.xnio.ChannelExceptionHandler in project undertow by undertow-io.

the class HttpContinue method internalSendContinueResponse.

private static void internalSendContinueResponse(final HttpServerExchange exchange, final IoCallback callback) {
    if (exchange.getAttachment(ALREADY_SENT) != null) {
        callback.onComplete(exchange, null);
        return;
    }
    HttpServerExchange newExchange = exchange.getConnection().sendOutOfBandResponse(exchange);
    exchange.putAttachment(ALREADY_SENT, true);
    newExchange.setStatusCode(StatusCodes.CONTINUE);
    newExchange.getResponseHeaders().put(Headers.CONTENT_LENGTH, 0);
    final StreamSinkChannel responseChannel = newExchange.getResponseChannel();
    try {
        responseChannel.shutdownWrites();
        if (!responseChannel.flush()) {
            responseChannel.getWriteSetter().set(ChannelListeners.flushingChannelListener(new ChannelListener<StreamSinkChannel>() {

                @Override
                public void handleEvent(StreamSinkChannel channel) {
                    channel.suspendWrites();
                    exchange.dispatch(new HttpHandler() {

                        @Override
                        public void handleRequest(HttpServerExchange exchange) throws Exception {
                            callback.onComplete(exchange, null);
                        }
                    });
                }
            }, new ChannelExceptionHandler<Channel>() {

                @Override
                public void handleException(Channel channel, final IOException e) {
                    exchange.dispatch(new HttpHandler() {

                        @Override
                        public void handleRequest(HttpServerExchange exchange) throws Exception {
                            callback.onException(exchange, null, e);
                        }
                    });
                }
            }));
            responseChannel.resumeWrites();
            exchange.dispatch();
        } else {
            callback.onComplete(exchange, null);
        }
    } catch (IOException e) {
        callback.onException(exchange, null, e);
    }
}
Also used : HttpServerExchange(io.undertow.server.HttpServerExchange) HttpHandler(io.undertow.server.HttpHandler) ChannelListener(org.xnio.ChannelListener) StreamSinkChannel(org.xnio.channels.StreamSinkChannel) Channel(java.nio.channels.Channel) StreamSinkChannel(org.xnio.channels.StreamSinkChannel) ChannelExceptionHandler(org.xnio.ChannelExceptionHandler) IOException(java.io.IOException) IOException(java.io.IOException)

Aggregations

IOException (java.io.IOException)5 ChannelExceptionHandler (org.xnio.ChannelExceptionHandler)5 StreamSinkChannel (org.xnio.channels.StreamSinkChannel)4 ChannelListener (org.xnio.ChannelListener)3 HttpString (io.undertow.util.HttpString)2 ClientRequest (io.undertow.client.ClientRequest)1 BytesSentStreamSinkConduit (io.undertow.conduits.BytesSentStreamSinkConduit)1 ChunkedStreamSinkConduit (io.undertow.conduits.ChunkedStreamSinkConduit)1 WriteTimeoutStreamSinkConduit (io.undertow.conduits.WriteTimeoutStreamSinkConduit)1 Http2DataStreamSinkChannel (io.undertow.protocols.http2.Http2DataStreamSinkChannel)1 Http2HeadersStreamSinkChannel (io.undertow.protocols.http2.Http2HeadersStreamSinkChannel)1 HttpHandler (io.undertow.server.HttpHandler)1 HttpServerExchange (io.undertow.server.HttpServerExchange)1 HeaderMap (io.undertow.util.HeaderMap)1 HeaderValues (io.undertow.util.HeaderValues)1 Channel (java.nio.channels.Channel)1 ClosedChannelException (java.nio.channels.ClosedChannelException)1 Supplier (java.util.function.Supplier)1 ConduitStreamSinkChannel (org.xnio.conduits.ConduitStreamSinkChannel)1 ConduitStreamSourceChannel (org.xnio.conduits.ConduitStreamSourceChannel)1