use of io.undertow.server.HttpServerExchange in project undertow by undertow-io.
the class DebugExtensionsHeaderHandler method handleRequest.
@Override
public void handleRequest(HttpServerExchange exchange) throws Exception {
final StringBuilder sb = new StringBuilder();
requestExtensions = exchange.getRequestHeaders().get(Headers.SEC_WEB_SOCKET_EXTENSIONS_STRING);
if (requestExtensions != null) {
for (String value : requestExtensions) {
sb.append("\n").append("--- REQUEST ---").append("\n").append(Headers.SEC_WEB_SOCKET_EXTENSIONS_STRING).append(": ").append(value).append("\n");
}
exchange.addExchangeCompleteListener(new ExchangeCompletionListener() {
@Override
public void exchangeEvent(HttpServerExchange exchange, NextListener nextListener) {
responseExtensions = exchange.getResponseHeaders().get(Headers.SEC_WEB_SOCKET_EXTENSIONS_STRING);
if (responseExtensions != null) {
for (String value : responseExtensions) {
sb.append("\n").append("--- RESPONSE ---").append("\n").append(Headers.SEC_WEB_SOCKET_EXTENSIONS_STRING).append(": ").append(value).append("\n");
}
}
nextListener.proceed();
UndertowLogger.REQUEST_DUMPER_LOGGER.info(sb.toString());
}
});
}
next.handleRequest(exchange);
}
use of io.undertow.server.HttpServerExchange in project undertow by undertow-io.
the class SimpleBenchmarkState method before.
@Setup
public final void before() {
Undertow.Builder builder = Undertow.builder().setIoThreads(4).setWorkerThreads(64).setServerOption(UndertowOptions.SHUTDOWN_TIMEOUT, 10000).setSocketOption(Options.SSL_CLIENT_AUTH_MODE, SslClientAuthMode.NOT_REQUESTED).setHandler(Handlers.routing().get("/blocking", new BlockingHandler(new HttpHandler() {
@Override
public void handleRequest(HttpServerExchange exchange) throws Exception {
String value = exchange.getQueryParameters().get("size").getFirst();
int bytes = Integer.parseInt(value);
exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "application/octet-stream").put(Headers.CONTENT_LENGTH, value);
OutputStream out = exchange.getOutputStream();
for (int i = 0; i < bytes; i++) {
out.write(1);
}
}
})).post("/blocking", new BlockingHandler(new HttpHandler() {
@Override
public void handleRequest(HttpServerExchange exchange) throws Exception {
InputStream stream = exchange.getInputStream();
long length = BenchmarkUtils.length(stream);
String stringValue = Long.toString(length);
exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "text/plain").put(Headers.CONTENT_LENGTH, stringValue.length());
exchange.getResponseSender().send(stringValue);
}
})));
switch(listenerType) {
case HTTP:
builder.addHttpListener(PORT, "0.0.0.0");
break;
case HTTPS:
builder.addHttpsListener(PORT, "0.0.0.0", TLSUtils.newServerContext());
break;
default:
throw new IllegalStateException("Unknown protocol: " + listenerType);
}
undertow = builder.build();
undertow.start();
client = HttpClients.custom().disableConnectionState().disableAutomaticRetries().setSSLContext(TLSUtils.newClientContext()).setMaxConnPerRoute(100).setMaxConnTotal(100).build();
baseUri = (listenerType == ListenerType.HTTP ? "http" : "https") + "://localhost:" + PORT;
}
use of io.undertow.server.HttpServerExchange in project undertow by undertow-io.
the class HttpContinue method sendContinueResponseBlocking.
/**
* Sends a continue response using blocking IO
*
* @param exchange The exchange
*/
public static void sendContinueResponseBlocking(final HttpServerExchange exchange) throws IOException {
if (!exchange.isResponseChannelAvailable()) {
throw UndertowMessages.MESSAGES.cannotSendContinueResponse();
}
if (exchange.getAttachment(ALREADY_SENT) != null) {
return;
}
HttpServerExchange newExchange = exchange.getConnection().sendOutOfBandResponse(exchange);
exchange.putAttachment(ALREADY_SENT, true);
newExchange.setStatusCode(StatusCodes.CONTINUE);
newExchange.getResponseHeaders().put(Headers.CONTENT_LENGTH, 0);
newExchange.startBlocking();
newExchange.getOutputStream().close();
newExchange.getInputStream().close();
}
use of io.undertow.server.HttpServerExchange in project undertow by undertow-io.
the class HttpContinue method createResponseSender.
/**
* Creates a response sender that can be used to send a HTTP 100-continue response.
*
* @param exchange The exchange
* @return The response sender
*/
public static ContinueResponseSender createResponseSender(final HttpServerExchange exchange) throws IOException {
if (!exchange.isResponseChannelAvailable()) {
throw UndertowMessages.MESSAGES.cannotSendContinueResponse();
}
if (exchange.getAttachment(ALREADY_SENT) != null) {
return new ContinueResponseSender() {
@Override
public boolean send() throws IOException {
return true;
}
@Override
public void awaitWritable() throws IOException {
}
@Override
public void awaitWritable(long time, TimeUnit timeUnit) throws IOException {
}
};
}
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();
return new ContinueResponseSender() {
boolean shutdown = false;
@Override
public boolean send() throws IOException {
if (!shutdown) {
shutdown = true;
responseChannel.shutdownWrites();
}
return responseChannel.flush();
}
@Override
public void awaitWritable() throws IOException {
responseChannel.awaitWritable();
}
@Override
public void awaitWritable(final long time, final TimeUnit timeUnit) throws IOException {
responseChannel.awaitWritable(time, timeUnit);
}
};
}
use of io.undertow.server.HttpServerExchange in project undertow by undertow-io.
the class HttpReadListener method handleEventWithNoRunningRequest.
public void handleEventWithNoRunningRequest(final ConduitStreamSourceChannel channel) {
PooledByteBuffer existing = connection.getExtraBytes();
if ((existing == null && connection.getOriginalSourceConduit().isReadShutdown()) || connection.getOriginalSinkConduit().isWriteShutdown()) {
IoUtils.safeClose(connection);
channel.suspendReads();
return;
}
final PooledByteBuffer pooled = existing == null ? connection.getByteBufferPool().allocate() : existing;
final ByteBuffer buffer = pooled.getBuffer();
boolean free = true;
try {
int res;
boolean bytesRead = false;
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 (bytesRead && parseTimeoutUpdater != null) {
parseTimeoutUpdater.failedParse();
}
handleFailedRead(channel, res);
return;
} else {
bytesRead = true;
}
if (existing != null) {
existing = null;
connection.setExtraBytes(null);
} else {
buffer.flip();
}
int begin = buffer.remaining();
if (httpServerExchange == null) {
httpServerExchange = new HttpServerExchange(connection, maxEntitySize);
}
parser.handle(buffer, state, httpServerExchange);
if (buffer.hasRemaining()) {
free = false;
connection.setExtraBytes(pooled);
}
int total = read + (begin - buffer.remaining());
read = total;
if (read > maxRequestSize) {
UndertowLogger.REQUEST_LOGGER.requestHeaderWasTooLarge(connection.getPeerAddress(), maxRequestSize);
sendBadRequestAndClose(connection.getChannel(), null);
return;
}
} while (!state.isComplete());
if (parseTimeoutUpdater != null) {
parseTimeoutUpdater.requestStarted();
}
connection.getOriginalSourceConduit().suspendReads();
final HttpServerExchange httpServerExchange = this.httpServerExchange;
httpServerExchange.setRequestScheme(connection.getSslSession() != null ? "https" : "http");
this.httpServerExchange = null;
requestStateUpdater.set(this, 1);
if (recordRequestStartTime) {
Connectors.setRequestStartTime(httpServerExchange);
}
if (httpServerExchange.getProtocol() == Protocols.HTTP_2_0) {
free = handleHttp2PriorKnowledge(pooled, httpServerExchange);
return;
}
if (!allowUnknownProtocols) {
HttpString protocol = httpServerExchange.getProtocol();
if (protocol != Protocols.HTTP_1_1 && protocol != Protocols.HTTP_1_0 && protocol != Protocols.HTTP_0_9) {
UndertowLogger.REQUEST_IO_LOGGER.debugf("Closing connection from %s due to unknown protocol %s", connection.getChannel().getPeerAddress(), protocol);
sendBadRequestAndClose(connection.getChannel(), new IOException());
return;
}
}
HttpTransferEncoding.setupRequest(httpServerExchange);
connection.setCurrentExchange(httpServerExchange);
if (connectorStatistics != null) {
connectorStatistics.setup(httpServerExchange);
}
if (connection.getSslSession() != null) {
// TODO: figure out a better solution for this
// in order to improve performance we do not generally suspend reads, instead we a CAS to detect when
// data arrives while a request is running and suspend lazily, as suspend/resume is relatively expensive
// however this approach does not work for SSL, as the underlying channel is not thread safe
// so we just suspend every time (the overhead is likely much less than the general SSL overhead anyway)
channel.suspendReads();
}
HeaderValues host = httpServerExchange.getRequestHeaders().get(Headers.HOST);
if (host != null && host.size() > 1) {
sendBadRequestAndClose(connection.getChannel(), UndertowMessages.MESSAGES.moreThanOneHostHeader());
return;
}
if (requireHostHeader && httpServerExchange.getProtocol().equals(Protocols.HTTP_1_1)) {
if (host == null || host.size() == 0 || host.getFirst().isEmpty()) {
sendBadRequestAndClose(connection.getChannel(), UndertowMessages.MESSAGES.noHostInHttp11Request());
return;
}
}
if (!Connectors.areRequestHeadersValid(httpServerExchange.getRequestHeaders())) {
sendBadRequestAndClose(connection.getChannel(), UndertowMessages.MESSAGES.invalidHeaders());
return;
}
Connectors.executeRootHandler(connection.getRootHandler(), httpServerExchange);
} catch (Throwable t) {
sendBadRequestAndClose(connection.getChannel(), t);
return;
} finally {
if (free)
pooled.close();
}
}
Aggregations