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
final PooledByteBuffer pooled = existing == null ? connection.getByteBufferPool().allocate() : existing; final ByteBuffer buffer = pooled.getBuffer(); boolean free = true; parseTimeoutUpdater.failedParse(); if (!channel.isReadResumed()) { channel.getReadSetter().set(this); httpServerExchange = new HttpServerExchange(connection, maxEntitySize); UndertowLogger.REQUEST_LOGGER.requestHeaderWasTooLarge(connection.getPeerAddress(), maxRequestSize); channel.getReadSetter().set(this); channel.getReadSetter().set(null); Connectors.terminateResponse(httpServerExchange); }, httpServerExchange.getRequestMethod().equals(Methods.HEAD)); connection.getChannel().getSinkChannel().setConduit(responseConduit); connection.getChannel().getSourceChannel().setConduit(createSourceConduit(connection.getChannel().getSourceChannel().getConduit(), responseConduit, httpServerExchange)); httpServerExchange.setSourceAddress(state.createPeerAddress());
@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); } }); } }
throw UndertowMessages.MESSAGES.argumentCannotBeNull("callback"); if (exchange.isRequestComplete()) { callback.handle(exchange, ""); return; String contentLengthString = exchange.getRequestHeaders().getFirst(Headers.CONTENT_LENGTH); long contentLength; final ByteArrayOutputStream sb; PooledByteBuffer pooled = exchange.getConnection().getByteBufferPool().allocate(); final ByteBuffer buffer = pooled.getBuffer(); try { return; } else if (res == 0) { channel.getReadSetter().set(new ChannelListener<StreamSourceChannel>() { @Override public void handleEvent(StreamSourceChannel channel) { channel.resumeReads(); return; } else {
PooledByteBuffer pooled = exchange.getConnection().getByteBufferPool().allocate(); try { while (true) { int c = requestChannel.read(pooled.getBuffer()); if(c == 0) { requestChannel.getReadSetter().set(new ChannelListener<StreamSourceChannel>() { @Override public void handleEvent(StreamSourceChannel channel) { requestChannel.resumeReads(); return; } else if (c == -1) { exchange.dispatch(SameThreadExecutor.INSTANCE, handler); } else { UndertowLogger.REQUEST_IO_LOGGER.ioException(UndertowMessages.MESSAGES.connectionTerminatedReadingMultiPartData()); exchange.setStatusCode(StatusCodes.INTERNAL_SERVER_ERROR); exchange.endExchange(); UndertowLogger.REQUEST_IO_LOGGER.ioException(e); exchange.setStatusCode(StatusCodes.INTERNAL_SERVER_ERROR); exchange.endExchange(); UndertowLogger.REQUEST_IO_LOGGER.debug("Exception parsing data", e); exchange.setStatusCode(StatusCodes.INTERNAL_SERVER_ERROR); exchange.endExchange();
private void closeAndFlushResponse() { if(!connection.isOpen()) { invokeExchangeCompleteListeners(); return; if (isResponseChannelAvailable()) { if(!getRequestMethod().equals(Methods.CONNECT) && !(getRequestMethod().equals(Methods.HEAD) && getResponseHeaders().contains(Headers.CONTENT_LENGTH)) && Connectors.isEntityBodyAllowed(this)) { getResponseHeaders().put(Headers.CONTENT_LENGTH, "0"); getResponseChannel(); responseChannel.getWriteSetter().set(ChannelListeners.flushingChannelListener( new ChannelListener<StreamSinkChannel>() { @Override UndertowLogger.ROOT_LOGGER.responseWasNotTerminated(connection, this); IoUtils.safeClose(connection); UndertowLogger.REQUEST_IO_LOGGER.ioException((IOException) t); } else { UndertowLogger.REQUEST_IO_LOGGER.handleUnexpectedFailure(t); invokeExchangeCompleteListeners(); IoUtils.safeClose(connection);
throw UndertowMessages.MESSAGES.argumentCannotBeNull("callback"); if(!exchange.getConnection().isOpen()) { invokeOnException(callback, new ClosedChannelException()); return; if(exchange.isResponseComplete()) { invokeOnException(callback, new IOException(UndertowMessages.MESSAGES.responseComplete())); throw UndertowMessages.MESSAGES.dataAlreadyQueued(); long responseContentLength = exchange.getResponseContentLength(); if(responseContentLength > 0 && buffer.remaining() > responseContentLength) { invokeOnException(callback, UndertowLogger.ROOT_LOGGER.dataLargerThanContentLength(buffer.remaining(), responseContentLength)); return; return; int res = channel.write(buffer); if (res == 0) { this.buffer = new ByteBuffer[]{buffer}; initWriteListener(); channel.getWriteSetter().set(writeListener); channel.resumeWrites(); return;
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(); channel.shutdownWrites(); if (!channel.flush()) { channel.getWriteSetter().set(ChannelListeners.flushingChannelListener( new ChannelListener<StreamSinkChannel>() { @Override
channel.getReadSetter().set(null); channel.suspendReads(); Connectors.executeRootHandler(next, exchange); return; Connectors.ungetRequestBytes(exchange, bufferedData); Connectors.resetRequestChannel(exchange); channel.getReadSetter().set(null); channel.suspendReads(); Connectors.executeRootHandler(next, exchange); return; buffer = exchange.getConnection().getByteBufferPool().allocate(); UndertowLogger.REQUEST_IO_LOGGER.ioException((IOException) t); } else { UndertowLogger.REQUEST_IO_LOGGER.handleUnexpectedFailure(t); IoUtils.safeClose(bufferedData[i]); IoUtils.safeClose(buffer); exchange.endExchange();
@Override public void handleRequest(final HttpServerExchange exchange) throws Exception { final PooledByteBuffer finalBuffer = buffer; final int finalReadBuffers = readBuffers; channel.getReadSetter().set(new ChannelListener<StreamSourceChannel>() { channel.resumeReads(); return; } else if (!b.hasRemaining()) { break; buffer = exchange.getConnection().getByteBufferPool().allocate(); } catch (Exception | Error e) { for (int i = 0; i < bufferedData.length; ++i) { IoUtils.safeClose(bufferedData[i]); IoUtils.safeClose(buffer);
@Override public void parse(HttpHandler handler) throws Exception { if (exchange.getAttachment(FORM_DATA) != null) { handler.handleRequest(exchange); return; } this.handler = handler; StreamSourceChannel channel = exchange.getRequestChannel(); if (channel == null) { throw new IOException(UndertowMessages.MESSAGES.requestChannelAlreadyProvided()); } else { doParse(channel); if (state != 4) { channel.getReadSetter().set(this); channel.resumeReads(); } else { exchange.dispatch(SameThreadExecutor.INSTANCE, handler); } } }
private void flushChannel(StreamSinkChannel stream) throws IOException { stream.shutdownWrites(); if (!stream.flush()) { stream.getWriteSetter().set(ChannelListeners.flushingChannelListener(null, writeExceptionHandler())); stream.resumeWrites(); } }
public void handleEvent(StreamSourceChannel channel) { final PooledByteBuffer pooled = bufferPool.allocate(); final ByteBuffer buffer = pooled.getBuffer(); boolean free = true; if (UndertowLogger.CLIENT_LOGGER.isDebugEnabled()) { safeClose(connection); buffer.clear(); try { res = channel.read(buffer); if (!channel.isReadResumed()) { channel.getReadSetter().set(this); String connectionString = response.getResponseHeaders().getFirst(Headers.CONNECTION); if ((connectionString == null || !Headers.UPGRADE.equalToString(connectionString)) && !response.getResponseHeaders().contains(Headers.UPGRADE)) { if(!currentRequest.getRequest().getMethod().equals(Methods.CONNECT) || response.getResponseCode() != 200) { //make sure it was not actually a connect request if(response.getResponseCode() == StatusCodes.SWITCHING_PROTOCOLS && Http2Channel.CLEARTEXT_UPGRADE_STRING.equals(response.getResponseHeaders().getFirst(Headers.UPGRADE))) { } else { prepareResponseChannel(response, currentRequest); channel.getReadSetter().set(null);
if (dest == null) { if (callback == IoCallback.END_EXCHANGE) { if (exchange.getResponseContentLength() == -1 && !exchange.getResponseHeaders().contains(Headers.TRANSFER_ENCODING)) { exchange.setResponseContentLength(size); long ret = dest.transferFrom(source, pos, size - pos); pos += ret; if (ret == 0) { source.position(pos); dest.getWriteSetter().set(this); dest.resumeWrites(); return false;
public void setup(final StreamSourceChannel channel) { PooledByteBuffer resource = bufferPool.allocate(); ByteBuffer buffer = resource.getBuffer(); try { int r = 0; do { r = channel.read(buffer); if (r == 0) { channel.getReadSetter().set(this); channel.resumeReads(); } else if (r == -1) { stringDone(string.extract()); IoUtils.safeClose(channel); } else { buffer.flip(); string.write(buffer); } } while (r > 0); } catch (IOException e) { error(e); } finally { resource.close(); } }
protected void doHttp2Upgrade() { try { StreamConnection connectedStreamChannel = this.performUpgrade(); Http2Channel http2Channel = new Http2Channel(connectedStreamChannel, null, bufferPool, null, true, true, options); Http2ClientConnection http2ClientConnection = new Http2ClientConnection(http2Channel, currentRequest.getResponseCallback(), currentRequest.getRequest(), currentRequest.getRequest().getRequestHeaders().getFirst(Headers.HOST), clientStatistics, false); http2ClientConnection.getCloseSetter().set(new ChannelListener<ClientConnection>() { @Override public void handleEvent(ClientConnection channel) { ChannelListeners.invokeChannelListener(HttpClientConnection.this, HttpClientConnection.this.closeSetter.get()); } }); http2Delegate = http2ClientConnection; connectedStreamChannel.getSourceChannel().wakeupReads(); //make sure the read listener is immediately invoked, as it may not happen if data is pushed back currentRequest = null; pendingResponse = null; } catch (IOException e) { UndertowLogger.REQUEST_IO_LOGGER.ioException(e); safeClose(this); } }
@Override public void handleEvent(final StreamSinkChannel channel) { channel.suspendWrites(); channel.getWriteSetter().set(null); //defensive programming, should never happen if (anyAreClear(state, FLAG_RESPONSE_TERMINATED)) { UndertowLogger.ROOT_LOGGER.responseWasNotTerminated(connection, HttpServerExchange.this); IoUtils.safeClose(connection); } } }, new ChannelExceptionHandler<Channel>() {
if(blockingHttpExchange != null) { IoUtils.safeClose(blockingHttpExchange); UndertowLogger.REQUEST_LOGGER.debug("Exception running default response listener", e); connection.terminateRequestChannel(this); UndertowLogger.REQUEST_IO_LOGGER.ioException(e); IoUtils.safeClose(connection); } catch (Throwable t) { UndertowLogger.REQUEST_IO_LOGGER.handleUnexpectedFailure(t); IoUtils.safeClose(connection); getRequestChannel(); if (getStatusCode() != StatusCodes.EXPECTATION_FAILED || totalRead > 0) { requestChannel.getReadSetter().set(ChannelListeners.drainListener(Long.MAX_VALUE, new ChannelListener<StreamSourceChannel>() { @Override UndertowLogger.REQUEST_IO_LOGGER.handleUnexpectedFailure(t); invokeExchangeCompleteListeners(); IoUtils.safeClose(connection); return this;
for(;;) { try { transferred = source.transferTo(count, buffer, sink); } catch (IOException e) { invokeChannelExceptionHandler(source, readExceptionHandler, e); return; Channels.setReadListener(source, sourceListener); if (sourceListener == null) { source.suspendReads(); } else { source.wakeupReads(); sink.suspendWrites(); } else { sink.wakeupWrites(); sink.suspendWrites(); invokeChannelExceptionHandler(source, readExceptionHandler, new EOFException()); invokeChannelExceptionHandler(sink, writeExceptionHandler, e); return; source.getReadSetter().set(listener); sink.getWriteSetter().set(listener); sink.getWriteSetter().set(listener); source.getReadSetter().set(listener);
if(exchange.getConnection().isPushSupported() && result.getConnection().isPushSupported()) { result.setPushHandler(new PushCallback() { @Override if(requiresContinueResponse) { try { if(!result.getRequestChannel().flush()) { result.getRequestChannel().getWriteSetter().set(ChannelListeners.flushingChannelListener(new ChannelListener<StreamSinkChannel>() { @Override public void handleEvent(StreamSinkChannel channel) { result.getRequestChannel().resumeWrites(); return; if(!exchange.isRequestComplete()) { Transfer.initiateTransfer(exchange.getRequestChannel(), result.getRequestChannel(), ChannelListeners.closingChannelListener(), trailerListener, handler, handler, exchange.getConnection().getByteBufferPool()); } else { trailerListener.handleEvent(result.getRequestChannel());