use of io.undertow.protocols.http2.Http2Channel in project undertow by undertow-io.
the class Http2ReceiveListener method handleRequests.
private void handleRequests(Http2Channel channel, Http2StreamSourceChannel frame) {
//we have a request
final Http2StreamSourceChannel dataChannel = frame;
final Http2ServerConnection connection = new Http2ServerConnection(channel, dataChannel, undertowOptions, bufferSize, rootHandler);
// Check request headers.
if (!checkRequestHeaders(dataChannel.getHeaders())) {
channel.sendRstStream(frame.getStreamId(), Http2Channel.ERROR_PROTOCOL_ERROR);
try {
Channels.drain(frame, Long.MAX_VALUE);
} catch (IOException e) {
// ignore, this is expected because of the RST
}
return;
}
final HttpServerExchange exchange = new HttpServerExchange(connection, dataChannel.getHeaders(), dataChannel.getResponseChannel().getHeaders(), maxEntitySize);
connection.setExchange(exchange);
dataChannel.setMaxStreamSize(maxEntitySize);
exchange.setRequestScheme(exchange.getRequestHeaders().getFirst(SCHEME));
exchange.setProtocol(Protocols.HTTP_2_0);
exchange.setRequestMethod(Methods.fromString(exchange.getRequestHeaders().getFirst(METHOD)));
exchange.getRequestHeaders().put(Headers.HOST, exchange.getRequestHeaders().getFirst(AUTHORITY));
final String path = exchange.getRequestHeaders().getFirst(PATH);
if (path == null || path.isEmpty()) {
UndertowLogger.REQUEST_IO_LOGGER.debugf("No :path header sent in HTTP/2 request, closing connection. Remote peer %s", connection.getPeerAddress());
channel.sendGoAway(Http2Channel.ERROR_PROTOCOL_ERROR);
return;
}
try {
Connectors.setExchangeRequestPath(exchange, path, encoding, decode, allowEncodingSlash, decodeBuffer, maxParameters);
} catch (ParameterLimitException e) {
//this can happen if max parameters is exceeded
UndertowLogger.REQUEST_IO_LOGGER.debug("Failed to set request path", e);
exchange.setStatusCode(StatusCodes.BAD_REQUEST);
exchange.endExchange();
return;
}
SSLSession session = channel.getSslSession();
if (session != null) {
connection.setSslSessionInfo(new Http2SslSessionInfo(channel));
}
dataChannel.getResponseChannel().setCompletionListener(new ChannelListener<Http2DataStreamSinkChannel>() {
@Override
public void handleEvent(Http2DataStreamSinkChannel channel) {
Connectors.terminateResponse(exchange);
}
});
if (!dataChannel.isOpen()) {
Connectors.terminateRequest(exchange);
} else {
dataChannel.setCompletionListener(new ChannelListener<Http2StreamSourceChannel>() {
@Override
public void handleEvent(Http2StreamSourceChannel channel) {
Connectors.terminateRequest(exchange);
}
});
}
if (connectorStatistics != null) {
connectorStatistics.setup(exchange);
}
//TODO: we should never actually put these into the map in the first place
exchange.getRequestHeaders().remove(AUTHORITY);
exchange.getRequestHeaders().remove(PATH);
exchange.getRequestHeaders().remove(SCHEME);
exchange.getRequestHeaders().remove(METHOD);
Connectors.executeRootHandler(rootHandler, exchange);
}
use of io.undertow.protocols.http2.Http2Channel in project undertow by undertow-io.
the class Http2UpgradeHandler method handleRequest.
@Override
public void handleRequest(HttpServerExchange exchange) throws Exception {
final String upgrade = exchange.getRequestHeaders().getFirst(Headers.UPGRADE);
if (upgrade != null && upgradeStrings.contains(upgrade)) {
String settings = exchange.getRequestHeaders().getFirst("HTTP2-Settings");
if (settings != null) {
//required by spec
final ByteBuffer settingsFrame = FlexBase64.decodeURL(settings);
exchange.getResponseHeaders().put(Headers.UPGRADE, upgrade);
exchange.upgradeChannel(new HttpUpgradeListener() {
@Override
public void handleUpgrade(StreamConnection streamConnection, HttpServerExchange exchange) {
OptionMap undertowOptions = exchange.getConnection().getUndertowOptions();
Http2Channel channel = new Http2Channel(streamConnection, upgrade, exchange.getConnection().getByteBufferPool(), null, false, true, true, settingsFrame, undertowOptions);
Http2ReceiveListener receiveListener = new Http2ReceiveListener(new HttpHandler() {
@Override
public void handleRequest(HttpServerExchange exchange) throws Exception {
//as the request was only to create the initial request
if (exchange.getRequestHeaders().contains("X-HTTP2-connect-only")) {
exchange.endExchange();
return;
}
exchange.setProtocol(Protocols.HTTP_2_0);
next.handleRequest(exchange);
}
}, undertowOptions, exchange.getConnection().getBufferSize(), null);
channel.getReceiveSetter().set(receiveListener);
receiveListener.handleInitialRequest(exchange, channel);
channel.resumeReceives();
}
});
return;
}
}
next.handleRequest(exchange);
}
use of io.undertow.protocols.http2.Http2Channel in project undertow by undertow-io.
the class HttpReadListener method doHttp2PriRead.
private boolean doHttp2PriRead(StreamConnection connection, ByteBuffer buffer, HttpServerConnection serverConnection, PooledByteBuffer extraData) throws IOException {
if (buffer.hasRemaining()) {
int res = connection.getSourceChannel().read(buffer);
if (res == -1) {
//fail
return true;
}
if (buffer.hasRemaining()) {
return false;
}
}
buffer.flip();
for (int i = 0; i < PRI_EXPECTED.length; ++i) {
if (buffer.get() != PRI_EXPECTED[i]) {
throw UndertowMessages.MESSAGES.http2PriRequestFailed();
}
}
Http2Channel channel = new Http2Channel(connection, null, serverConnection.getByteBufferPool(), extraData, false, false, false, serverConnection.getUndertowOptions());
Http2ReceiveListener receiveListener = new Http2ReceiveListener(serverConnection.getRootHandler(), serverConnection.getUndertowOptions(), serverConnection.getBufferSize(), null);
channel.getReceiveSetter().set(receiveListener);
channel.resumeReceives();
return true;
}
Aggregations