package io.vertx.core.http.impl;
import io.netty.handler.codec.http.DefaultFullHttpRequest;
import io.netty.handler.codec.http.DefaultHttpRequest;
import io.netty.handler.codec.http.EmptyHttpHeaders;
import io.netty.handler.codec.http.HttpRequest;
import io.vertx.core.Handler;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.spi.metrics.HttpServerMetrics;
import static io.vertx.core.http.HttpHeaders.UPGRADE;
import static io.vertx.core.http.HttpHeaders.WEBSOCKET;
import static io.vertx.core.http.impl.HttpUtils.SC_SWITCHING_PROTOCOLS;
public class WebSocketRequestHandler implements Handler<HttpServerRequest> {
private final HttpServerMetrics metrics;
private final HttpHandlers handlers;
WebSocketRequestHandler(HttpServerMetrics metrics, HttpHandlers handlers) {
this.metrics = metrics;
this.handlers = handlers;
}
@Override
public void handle(HttpServerRequest req) {
if (req.headers()
.contains(UPGRADE, WEBSOCKET, true)
|| handlers.requestHandler == null) {
handle((HttpServerRequestImpl) req);
} else {
handlers.requestHandler.handle(req);
}
}
private void handle(HttpServerRequestImpl req) {
Buffer body = Buffer.buffer();
boolean[] failed = new boolean[1];
req.handler(buff -> {
if (!failed[0]) {
body.appendBuffer(buff);
if (body.length() > 8192) {
failed[0] = true;
HttpServerResponseImpl resp = req.response();
resp.setStatusCode(413).end();
resp.close();
}
}
});
req.endHandler(v -> {
if (!failed[0]) {
handle(req, body);
}
});
}
private void handle(HttpServerRequestImpl req, Buffer body) {
HttpRequest nettyReq = req.nettyRequest();
nettyReq = new DefaultFullHttpRequest(
nettyReq.protocolVersion(),
nettyReq.method(),
nettyReq.uri(),
body.getByteBuf(),
nettyReq.headers(),
EmptyHttpHeaders.INSTANCE
);
req.setRequest(nettyReq);
if (handlers.wsHandler != null) {
ServerWebSocketImpl ws = ((Http1xServerConnection)req.connection()).createWebSocket(req);
if (ws == null) {
return;
}
handlers.wsHandler.handle(ws);
ws.tryHandshake(SC_SWITCHING_PROTOCOLS);
} else {
handlers.requestHandler.handle(req);
}
}
}