use of io.undertow.conduits.ReadDataStreamSourceConduit in project undertow by undertow-io.
the class HttpReadListener method exchangeComplete.
public void exchangeComplete(final HttpServerExchange exchange) {
connection.clearChannel();
final HttpServerConnection connection = this.connection;
if (exchange.isPersistent() && !isUpgradeOrConnect(exchange)) {
final StreamConnection channel = connection.getChannel();
if (connection.getExtraBytes() == null) {
//we have to resume from with the io thread
if (exchange.isInIoThread()) {
//no need for CAS, we are in the IO thread
newRequest();
channel.getSourceChannel().setReadListener(HttpReadListener.this);
channel.getSourceChannel().resumeReads();
requestStateUpdater.set(this, 0);
} else {
while (true) {
if (connection.getOriginalSourceConduit().isReadShutdown() || connection.getOriginalSinkConduit().isWriteShutdown()) {
channel.getSourceChannel().suspendReads();
channel.getSinkChannel().suspendWrites();
IoUtils.safeClose(connection);
return;
} else {
if (requestStateUpdater.compareAndSet(this, 1, 2)) {
try {
newRequest();
channel.getSourceChannel().setReadListener(HttpReadListener.this);
channel.getSourceChannel().resumeReads();
} finally {
requestStateUpdater.set(this, 0);
}
break;
}
}
}
}
} else {
if (exchange.isInIoThread()) {
//no need to CAS, as we don't actually resume
requestStateUpdater.set(this, 0);
newRequest();
//no need to suspend reads here, the task will always run before the read listener anyway
channel.getIoThread().execute(this);
} else {
while (true) {
if (connection.getOriginalSinkConduit().isWriteShutdown()) {
channel.getSourceChannel().suspendReads();
channel.getSinkChannel().suspendWrites();
IoUtils.safeClose(connection);
return;
} else if (requestStateUpdater.compareAndSet(this, 1, 2)) {
try {
newRequest();
channel.getSourceChannel().suspendReads();
} finally {
requestStateUpdater.set(this, 0);
}
break;
}
}
Executor executor = exchange.getDispatchExecutor();
if (executor == null) {
executor = exchange.getConnection().getWorker();
}
executor.execute(this);
}
}
} else if (!exchange.isPersistent()) {
ConnectionUtils.cleanClose(connection.getChannel(), connection);
} else {
//upgrade or connect handling
if (connection.getExtraBytes() != null) {
connection.getChannel().getSourceChannel().setConduit(new ReadDataStreamSourceConduit(connection.getChannel().getSourceChannel().getConduit(), connection));
}
try {
if (!connection.getChannel().getSinkChannel().flush()) {
connection.getChannel().getSinkChannel().setWriteListener(ChannelListeners.flushingChannelListener(new ChannelListener<ConduitStreamSinkChannel>() {
@Override
public void handleEvent(ConduitStreamSinkChannel conduitStreamSinkChannel) {
connection.getUpgradeListener().handleUpgrade(connection.getChannel(), exchange);
}
}, new ClosingChannelExceptionHandler<ConduitStreamSinkChannel>(connection)));
connection.getChannel().getSinkChannel().resumeWrites();
return;
}
connection.getUpgradeListener().handleUpgrade(connection.getChannel(), exchange);
} catch (IOException e) {
UndertowLogger.REQUEST_IO_LOGGER.ioException(e);
IoUtils.safeClose(connection);
}
}
}
use of io.undertow.conduits.ReadDataStreamSourceConduit in project undertow by undertow-io.
the class AjpReadListener method createSourceConduit.
private StreamSourceConduit createSourceConduit(StreamSourceConduit underlyingConduit, AjpServerResponseConduit responseConduit, final HttpServerExchange exchange) {
ReadDataStreamSourceConduit conduit = new ReadDataStreamSourceConduit(underlyingConduit, (AbstractServerConnection) exchange.getConnection());
final HeaderMap requestHeaders = exchange.getRequestHeaders();
HttpString transferEncoding = Headers.IDENTITY;
Long length;
final String teHeader = requestHeaders.getLast(Headers.TRANSFER_ENCODING);
boolean hasTransferEncoding = teHeader != null;
if (hasTransferEncoding) {
transferEncoding = new HttpString(teHeader);
}
final String requestContentLength = requestHeaders.getFirst(Headers.CONTENT_LENGTH);
if (hasTransferEncoding && !transferEncoding.equals(Headers.IDENTITY)) {
//unknown length
length = null;
} else if (requestContentLength != null) {
final long contentLength = Long.parseLong(requestContentLength);
if (contentLength == 0L) {
UndertowLogger.REQUEST_LOGGER.trace("No content, starting next request");
// no content - immediately start the next request, returning an empty stream for this one
Connectors.terminateRequest(httpServerExchange);
return new EmptyStreamSourceConduit(conduit.getReadThread());
} else {
length = contentLength;
}
} else {
UndertowLogger.REQUEST_LOGGER.trace("No content length or transfer coding, starting next request");
// no content - immediately start the next request, returning an empty stream for this one
Connectors.terminateRequest(exchange);
return new EmptyStreamSourceConduit(conduit.getReadThread());
}
return new AjpServerRequestConduit(conduit, exchange, responseConduit, length, new ConduitListener<AjpServerRequestConduit>() {
@Override
public void handleEvent(AjpServerRequestConduit channel) {
Connectors.terminateRequest(exchange);
}
});
}
Aggregations