/** Notification that the current request is finished */ public void requestDone() { connection.getSinkChannel().setConduit(originalSinkConduit); connection.getSourceChannel().setConduit(pushBackStreamSourceConduit); connection.getSinkChannel().suspendWrites(); connection.getSinkChannel().setWriteListener(null); if (anyAreSet(state, CLOSE_REQ)) { currentRequest = null; this.state |= CLOSED; IoUtils.safeClose(connection); } else if (anyAreSet(state, UPGRADE_REQUESTED)) { connection.getSourceChannel().suspendReads(); currentRequest = null; return; } currentRequest = null; HttpClientExchange next = pendingQueue.poll(); if (next == null) { // we resume reads, so if the target goes away we get notified connection.getSourceChannel().setReadListener(clientReadListener); connection.getSourceChannel().resumeReads(); } else { initiateRequest(next); } }
@Override public void exchangeEvent( final HttpServerExchange exchange, final ExchangeCompletionListener.NextListener nextListener) { connection.resetChannel(); final HttpServerConnection connection = this.connection; if (exchange.isPersistent() && !exchange.isUpgrade()) { newRequest(); StreamConnection channel = connection.getChannel(); if (connection.getExtraBytes() == null) { // if we are not pipelining we just register a listener channel.getSourceChannel().getReadSetter().set(this); channel.getSourceChannel().resumeReads(); } else { if (channel.getSourceChannel().isReadResumed()) { channel.getSourceChannel().suspendReads(); } if (exchange.isInIoThread()) { channel.getIoThread().execute(this); } else { Executor executor = exchange.getDispatchExecutor(); if (executor == null) { executor = exchange.getConnection().getWorker(); } executor.execute(this); } } } nextListener.proceed(); }
@Override protected void doClose() throws Exception { closed = true; StreamConnection conn = connection(); if (conn != null) { conn.close(); } }
@Override protected SocketAddress localAddress0() { StreamConnection conn = connection(); if (conn == null) { return null; } return conn.getLocalAddress(); }
@Override protected SocketAddress remoteAddress0() { StreamConnection conn = connection(); if (conn == null) { return null; } return conn.getPeerAddress(); }
/** * Resets the channel to its original state, effectively disabling all current conduit wrappers. * The current state is encapsulated inside a {@link ConduitState} object that can be used the * restore the channel. * * @return An opaque representation of the previous channel state */ public ConduitState resetChannel() { ConduitState ret = new ConduitState( channel.getSinkChannel().getConduit(), channel.getSourceChannel().getConduit()); channel.getSinkChannel().setConduit(originalSinkConduit); channel.getSourceChannel().setConduit(originalSourceConduit); return ret; }
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 protected void doBeginRead() throws Exception { StreamConnection conn = connection(); if (conn == null) { return; } ConduitStreamSourceChannel source = conn.getSourceChannel(); if (!source.isReadResumed()) { source.resumeReads(); } }
@Override public void run() { handle = null; if (expireTime == -1) { return; } long current = System.currentTimeMillis(); if (current < expireTime) { // timeout has been bumped, re-schedule handle = WorkerUtils.executeAfter( connection.getIoThread(), timeoutCommand, (expireTime - current) + FUZZ_FACTOR, TimeUnit.MILLISECONDS); return; } UndertowLogger.REQUEST_LOGGER.tracef( "Timing out channel %s due to inactivity", connection.getSourceChannel()); IoUtils.safeClose(connection); if (connection.getSourceChannel().isReadResumed()) { ChannelListeners.invokeChannelListener( connection.getSourceChannel(), connection.getSourceChannel().getReadListener()); } if (connection.getSinkChannel().isWriteResumed()) { ChannelListeners.invokeChannelListener( connection.getSinkChannel(), connection.getSinkChannel().getWriteListener()); } }
public HttpServerConnection( StreamConnection channel, final Pool<ByteBuffer> bufferPool, final HttpHandler rootHandler, final OptionMap undertowOptions, final int bufferSize) { this.channel = channel; this.bufferPool = bufferPool; this.rootHandler = rootHandler; this.undertowOptions = undertowOptions; this.bufferSize = bufferSize; closeSetter = ChannelListeners.getDelegatingSetter(channel.getCloseSetter(), this); this.originalSinkConduit = channel.getSinkChannel().getConduit(); this.originalSourceConduit = channel.getSourceChannel().getConduit(); }
public void close() throws IOException { if (anyAreSet(state, CLOSED)) { return; } state |= CLOSED | CLOSE_REQ; connection.close(); }
public ReadTimeoutStreamSourceConduit( final StreamSourceConduit delegate, StreamConnection connection, OpenListener openListener) { super(delegate); this.connection = connection; this.openListener = openListener; final ReadReadyHandler handler = new ReadReadyHandler.ChannelListenerHandler<>(connection.getSourceChannel()); delegate.setReadReadyHandler( new ReadReadyHandler() { @Override public void readReady() { handler.readReady(); } @Override public void forceTermination() { cleanup(); handler.forceTermination(); } @Override public void terminated() { cleanup(); handler.terminated(); } }); }
/** * Construct a new instance. * * @param delegate the underlying connection */ UndertowSslConnection(StreamConnection delegate, SSLEngine engine, ByteBufferPool bufferPool) { super(delegate.getIoThread()); this.delegate = delegate; this.engine = engine; sslConduit = new SslConduit(this, delegate, engine, bufferPool, new HandshakeCallback()); setSourceConduit(sslConduit); setSinkConduit(sslConduit); }
@Override public void awaitWritable() throws IOException { Integer timeout = connection.getOption(Options.WRITE_TIMEOUT); if (timeout != null && timeout > 0) { super.awaitWritable(timeout + FUZZ_FACTOR, TimeUnit.MILLISECONDS); } else { super.awaitWritable(); } }
@Override public void awaitWritable(long time, TimeUnit timeUnit) throws IOException { Integer timeout = connection.getOption(Options.WRITE_TIMEOUT); if (timeout != null && timeout > 0) { long millis = timeUnit.toMillis(time); super.awaitWritable(Math.min(millis, timeout + FUZZ_FACTOR), TimeUnit.MILLISECONDS); } else { super.awaitWritable(time, timeUnit); } }
public AjpServerConnection( StreamConnection channel, Pool<ByteBuffer> bufferPool, HttpHandler rootHandler, OptionMap undertowOptions, int bufferSize) { super(channel, bufferPool, rootHandler, undertowOptions, bufferSize); this.writeReadyHandler = new WriteReadyHandler.ChannelListenerHandler<ConduitStreamSinkChannel>( channel.getSinkChannel()); }
private void handleWriteTimeout(final long ret) throws IOException { Integer writeTimout = connection.getOption(Options.WRITE_TIMEOUT); if (writeTimout != null && writeTimout > 0) { if (ret == 0 && handle == null) { handle = super.getWriteThread() .executeAfter(timeoutCommand, writeTimout + FUZZ_FACTOR, TimeUnit.MILLISECONDS); } else if (ret > 0 && handle != null) { handle.remove(); } } }
private void handleResumeTimeout() { Integer timeout = getTimeout(); if (timeout == null || timeout <= 0) { return; } long currentTime = System.currentTimeMillis(); expireTime = currentTime + timeout; XnioExecutor.Key key = handle; if (key == null) { handle = connection.getIoThread().executeAfter(timeoutCommand, timeout, TimeUnit.MILLISECONDS); } }
/** {@inheritDoc} */ @Override public <T> T getOption(final Option<T> option) throws IOException { if (option == Options.SSL_CLIENT_AUTH_MODE) { return option.cast( engine.getNeedClientAuth() ? SslClientAuthMode.REQUIRED : engine.getWantClientAuth() ? SslClientAuthMode.REQUESTED : SslClientAuthMode.NOT_REQUESTED); } else { return option == Options.SECURE ? (T) Boolean.TRUE : delegate.getOption(option); } }
@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); } } }); }
HttpClientConnection( final StreamConnection connection, final OptionMap options, final Pool<ByteBuffer> bufferPool) { this.options = options; this.connection = connection; this.pushBackStreamSourceConduit = new PushBackStreamSourceConduit(connection.getSourceChannel().getConduit()); this.connection.getSourceChannel().setConduit(pushBackStreamSourceConduit); this.bufferPool = bufferPool; this.originalSinkConduit = connection.getSinkChannel().getConduit(); connection .getCloseSetter() .set( new ChannelListener<StreamConnection>() { public void handleEvent(StreamConnection channel) { HttpClientConnection.this.state |= CLOSED; ChannelListeners.invokeChannelListener( HttpClientConnection.this, closeSetter.get()); } }); }
private Integer getTimeout() { Integer timeout = 0; try { timeout = connection.getSourceChannel().getOption(Options.READ_TIMEOUT); } catch (IOException ignore) { // should never happen } Integer idleTimeout = openListener.getUndertowOptions().get(UndertowOptions.IDLE_TIMEOUT); if ((timeout == null || timeout <= 0) && idleTimeout != null) { timeout = idleTimeout; } else if (timeout != null && idleTimeout != null && idleTimeout > 0) { timeout = Math.min(timeout, idleTimeout); } return timeout; }
private void prepareResponseChannel(ClientResponse response, ClientExchange exchange) { String encoding = response.getResponseHeaders().getLast(TRANSFER_ENCODING); boolean chunked = encoding != null && Headers.CHUNKED.equals(new HttpString(encoding)); String length = response.getResponseHeaders().getFirst(CONTENT_LENGTH); if (exchange.getRequest().getMethod().equals(Methods.HEAD)) { connection .getSourceChannel() .setConduit( new FixedLengthStreamSourceConduit( connection.getSourceChannel().getConduit(), 0, responseFinishedListener)); } else if (chunked) { connection .getSourceChannel() .setConduit( new ChunkedStreamSourceConduit( connection.getSourceChannel().getConduit(), pushBackStreamSourceConduit, bufferPool, responseFinishedListener, exchange)); } else if (length != null) { try { long contentLength = Long.parseLong(length); connection .getSourceChannel() .setConduit( new FixedLengthStreamSourceConduit( connection.getSourceChannel().getConduit(), contentLength, responseFinishedListener)); } catch (NumberFormatException e) { handleError(new IOException(e)); throw e; } } else if (response.getProtocol().equals(Protocols.HTTP_1_1)) { connection .getSourceChannel() .setConduit( new FixedLengthStreamSourceConduit( connection.getSourceChannel().getConduit(), 0, responseFinishedListener)); } else { state |= CLOSE_REQ; } }
@Override public void run() { UndertowLogger.REQUEST_LOGGER.tracef("Timing out channel %s due to inactivity"); IoUtils.safeClose(connection); if (connection.getSourceChannel().isReadResumed()) { ChannelListeners.invokeChannelListener( connection.getSourceChannel(), connection.getSourceChannel().getReadListener()); } if (connection.getSinkChannel().isWriteResumed()) { ChannelListeners.invokeChannelListener( connection.getSinkChannel(), connection.getSinkChannel().getWriteListener()); } }
/** {@inheritDoc} */ @Override public <T> T setOption(final Option<T> option, final T value) throws IllegalArgumentException, IOException { if (option == Options.SSL_CLIENT_AUTH_MODE) { try { return option.cast( engine.getNeedClientAuth() ? SslClientAuthMode.REQUIRED : engine.getWantClientAuth() ? SslClientAuthMode.REQUESTED : SslClientAuthMode.NOT_REQUESTED); } finally { engine.setNeedClientAuth(value == SslClientAuthMode.REQUIRED); engine.setWantClientAuth(value == SslClientAuthMode.REQUESTED); } } else if (option == Options.SECURE) { throw new IllegalArgumentException(); } else { return delegate.setOption(option, value); } }
private void handleReadTimeout(final long ret) throws IOException { if (!connection.isOpen()) { cleanup(); return; } if (ret == -1) { cleanup(); return; } if (ret == 0 && handle != null) { return; } Integer timeout = getTimeout(); if (timeout == null || timeout <= 0) { return; } long currentTime = System.currentTimeMillis(); long expireTimeVar = expireTime; if (expireTimeVar != -1 && currentTime > expireTimeVar) { IoUtils.safeClose(connection); throw new ClosedChannelException(); } expireTime = currentTime + timeout; }
/** * Resores the channel conduits to a previous state. * * @see #resetChannel() * @param state The original state */ public void restoreChannel(final ConduitState state) { channel.getSinkChannel().setConduit(state.sink); channel.getSourceChannel().setConduit(state.source); }
public <A extends SocketAddress> A getLocalAddress(final Class<A> type) { return channel.getLocalAddress(type); }
public SocketAddress getLocalAddress() { return channel.getLocalAddress(); }
public SocketAddress getPeerAddress() { return channel.getPeerAddress(); }