private void handleError(StreamSinkChannel c, String m, Throwable t) { if (t instanceof IOException) UndertowLogger.REQUEST_IO_LOGGER.ioException((IOException) t); else UndertowLogger.REQUEST_IO_LOGGER.error(m, t); cleanup(); c.getWriteSetter().set(null); IoUtils.safeClose(c); }
private void handleError(IOException e) { UndertowLogger.REQUEST_IO_LOGGER.ioException(e); IoUtils.safeClose(SpdyClientConnection.this); for (Map.Entry<Integer, SpdyClientExchange> entry : currentExchanges.entrySet()) { try { entry.getValue().failed(e); } catch (Exception ex) { UndertowLogger.REQUEST_IO_LOGGER.ioException(new IOException(ex)); } } }
@Override public void handleEvent(SpdyChannel channel) { try { SpdyStreamSourceChannel result = channel.receive(); if (result instanceof SpdySynReplyStreamSourceChannel) { final int streamId = ((SpdySynReplyStreamSourceChannel) result).getStreamId(); SpdyClientExchange request = currentExchanges.get(streamId); result.addCloseTask( new ChannelListener<SpdyStreamSourceChannel>() { @Override public void handleEvent(SpdyStreamSourceChannel channel) { currentExchanges.remove(streamId); } }); if (request == null) { // server side initiated stream, we can't deal with that at the moment // just fail // TODO: either handle this properly or at the very least send RST_STREAM channel.sendGoAway(SpdyChannel.CLOSE_PROTOCOL_ERROR); IoUtils.safeClose(SpdyClientConnection.this); return; } request.responseReady((SpdySynReplyStreamSourceChannel) result); } else if (result instanceof SpdyPingStreamSourceChannel) { handlePing((SpdyPingStreamSourceChannel) result); } else if (result instanceof SpdyRstStreamStreamSourceChannel) { int stream = ((SpdyRstStreamStreamSourceChannel) result).getStreamId(); UndertowLogger.REQUEST_LOGGER.debugf("Client received RST_STREAM for stream %s", stream); SpdyClientExchange exchange = currentExchanges.get(stream); if (exchange != null) { exchange.failed(UndertowMessages.MESSAGES.spdyStreamWasReset()); } } else if (!channel.isOpen()) { throw UndertowMessages.MESSAGES.channelIsClosed(); } } catch (IOException e) { UndertowLogger.REQUEST_IO_LOGGER.ioException(e); IoUtils.safeClose(SpdyClientConnection.this); for (Map.Entry<Integer, SpdyClientExchange> entry : currentExchanges.entrySet()) { try { entry.getValue().failed(e); } catch (Exception ex) { UndertowLogger.REQUEST_IO_LOGGER.ioException(new IOException(ex)); } } } }
@Override public void handleEvent(final StreamSinkChannel channel) { HeaderMap trailers = source.getAttachment(HttpAttachments.REQUEST_TRAILERS); if (trailers != null) { target.putAttachment(HttpAttachments.RESPONSE_TRAILERS, trailers); } try { channel.shutdownWrites(); if (!channel.flush()) { channel .getWriteSetter() .set( ChannelListeners.flushingChannelListener( new ChannelListener<StreamSinkChannel>() { @Override public void handleEvent(StreamSinkChannel channel) { channel.suspendWrites(); channel.getWriteSetter().set(null); } }, ChannelListeners.closingChannelExceptionHandler())); channel.resumeWrites(); } else { channel.getWriteSetter().set(null); channel.shutdownWrites(); } } catch (IOException e) { UndertowLogger.REQUEST_IO_LOGGER.ioException(e); IoUtils.safeClose(channel); } }
@Override public void handleException(Channel channel, IOException exception) { IoUtils.safeClose(channel); IoUtils.safeClose(clientConnection); if (exchange.isResponseStarted()) { UndertowLogger.REQUEST_IO_LOGGER.debug("Exception reading from target server", exception); if (!exchange.isResponseStarted()) { exchange.setStatusCode(StatusCodes.INTERNAL_SERVER_ERROR); exchange.endExchange(); } else { IoUtils.safeClose(exchange.getConnection()); } } else { UndertowLogger.REQUEST_IO_LOGGER.ioException(exception); exchange.setStatusCode(StatusCodes.INTERNAL_SERVER_ERROR); exchange.endExchange(); } }
@Override public void handleEvent(StreamConnection channel) { // set read and write timeouts try { Integer readTimeout = channel.getOption(Options.READ_TIMEOUT); Integer idleTimeout = undertowOptions.get(UndertowOptions.IDLE_TIMEOUT); if ((readTimeout == null || readTimeout <= 0) && idleTimeout != null) { readTimeout = idleTimeout; } else if (readTimeout != null && idleTimeout != null && idleTimeout > 0) { readTimeout = Math.min(readTimeout, idleTimeout); } if (readTimeout != null && readTimeout > 0) { channel .getSourceChannel() .setConduit( new ReadTimeoutStreamSourceConduit( channel.getSourceChannel().getConduit(), channel, this)); } Integer writeTimeout = channel.getOption(Options.WRITE_TIMEOUT); if ((writeTimeout == null || writeTimeout <= 0) && idleTimeout != null) { writeTimeout = idleTimeout; } else if (writeTimeout != null && idleTimeout != null && idleTimeout > 0) { writeTimeout = Math.min(writeTimeout, idleTimeout); } if (writeTimeout != null && writeTimeout > 0) { channel .getSinkChannel() .setConduit( new WriteTimeoutStreamSinkConduit( channel.getSinkChannel().getConduit(), channel, this)); } } catch (IOException e) { IoUtils.safeClose(channel); UndertowLogger.REQUEST_IO_LOGGER.ioException(e); } final PortForwardServerConnection connection = new PortForwardServerConnection(channel, bufferPool, undertowOptions, bufferSize); connection .getWorker() .execute( new Runnable() { @Override public void run() { try { connection.startForwarding( masterPortForwardConnection, urlPath, targetPort, requestId.getAndIncrement()); } catch (IOException e) { } finally { IoUtils.safeClose(connection); } } }); }
private void sendBadRequestAndClose(final StreamConnection channel, final Exception exception) { UndertowLogger.REQUEST_IO_LOGGER.failedToParseRequest(exception); channel.getSourceChannel().suspendReads(); new StringWriteChannelListener(BAD_REQUEST) { @Override protected void writeDone(final StreamSinkChannel c) { IoUtils.safeClose(channel); } }.setup(channel.getSinkChannel()); }
@Override public void handleEvent(final StreamSourceChannel channel) { if (anyAreClear(state, FLAG_FINISHED)) { try { state |= FLAG_READY; channel.suspendReads(); listener.onDataAvailable(); } catch (IOException e) { UndertowLogger.REQUEST_IO_LOGGER.ioException(e); IoUtils.safeClose(channel); } } if (anyAreSet(state, FLAG_FINISHED) && anyAreClear(state, FLAG_ON_DATA_READ_CALLED)) { state |= FLAG_ON_DATA_READ_CALLED; try { channel.shutdownReads(); listener.onAllDataRead(); } catch (IOException e) { IoUtils.safeClose(channel); } } else if (allAreClear(state, FLAG_FINISHED)) { channel.resumeReads(); } }
public void handleEvent(final StreamSourceChannel channel) { Pooled<ByteBuffer> existing = connection.getExtraBytes(); final Pooled<ByteBuffer> pooled = existing == null ? connection.getBufferPool().allocate() : existing; final ByteBuffer buffer = pooled.getResource(); boolean free = true; try { int res; do { if (existing == null) { buffer.clear(); try { res = channel.read(buffer); } catch (IOException e) { UndertowLogger.REQUEST_IO_LOGGER.debug("Error reading request", e); IoUtils.safeClose(connection); return; } } else { res = buffer.remaining(); } if (res == 0) { if (!channel.isReadResumed()) { channel.getReadSetter().set(this); channel.resumeReads(); } return; } else if (res == -1) { try { channel.suspendReads(); channel.shutdownReads(); final StreamSinkChannel responseChannel = this.connection.getChannel().getSinkChannel(); responseChannel.shutdownWrites(); // will return false if there's a response queued ahead of this one, so we'll set up a // listener then if (!responseChannel.flush()) { responseChannel .getWriteSetter() .set(ChannelListeners.flushingChannelListener(null, null)); responseChannel.resumeWrites(); } } catch (IOException e) { UndertowLogger.REQUEST_IO_LOGGER.debug("Error reading request", e); // f**k it, it's all ruined IoUtils.safeClose(channel); return; } return; } if (existing != null) { existing = null; connection.setExtraBytes(null); } else { buffer.flip(); } parser.handle(buffer, state, httpServerExchange); if (buffer.hasRemaining()) { free = false; connection.setExtraBytes(pooled); } int total = read + res; read = total; if (read > maxRequestSize) { UndertowLogger.REQUEST_LOGGER.requestHeaderWasTooLarge( connection.getPeerAddress(), maxRequestSize); IoUtils.safeClose(connection); return; } } while (!state.isComplete()); // we remove ourselves as the read listener from the channel; // if the http handler doesn't set any then reads will suspend, which is the right thing to do channel.getReadSetter().set(null); channel.suspendReads(); final HttpServerExchange httpServerExchange = this.httpServerExchange; httpServerExchange.putAttachment( UndertowOptions.ATTACHMENT_KEY, connection.getUndertowOptions()); httpServerExchange.setRequestScheme(connection.getSslSession() != null ? "https" : "http"); this.httpServerExchange = null; HttpTransferEncoding.setupRequest(httpServerExchange); HttpHandlers.executeRootHandler( connection.getRootHandler(), httpServerExchange, Thread.currentThread() instanceof XnioExecutor); } catch (Exception e) { sendBadRequestAndClose(connection.getChannel(), e); return; } finally { if (free) pooled.free(); } }