}
}
@Override
public void handle(Channel channel, NettyResponseFuture<?> future, Object e) throws Exception {
WebSocketUpgradeHandler handler = WebSocketUpgradeHandler.class.cast(future.getAsyncHandler());
Request request = future.getRequest();
if (e instanceof HttpResponse) {
HttpResponse response = (HttpResponse) e;
// we buffer the response until we get the LastHttpContent
future.setPendingResponse(response);
} else if (e instanceof LastHttpContent) {
HttpResponse response = future.getPendingResponse();
future.setPendingResponse(null);
HttpResponseStatus status = new NettyResponseStatus(future.getUri(), config, response);
HttpResponseHeaders responseHeaders = new NettyResponseHeaders(response.headers());
if (exitAfterProcessingFilters(channel, future, handler, status, responseHeaders)) {
return;
}
future.setHttpHeaders(response.headers());
if (exitAfterHandlingRedirect(channel, future, response, request, response.getStatus().code()))
return;
boolean validStatus = response.getStatus().equals(SWITCHING_PROTOCOLS);
boolean validUpgrade = response.headers().get(HttpHeaders.Names.UPGRADE) != null;
String connection = response.headers().get(HttpHeaders.Names.CONNECTION);
if (connection == null)
connection = response.headers().get(HttpHeaders.Names.CONNECTION.toLowerCase(Locale.ENGLISH));
boolean validConnection = HttpHeaders.Values.UPGRADE.equalsIgnoreCase(connection);
status = new NettyResponseStatus(future.getUri(), config, response);
final boolean statusReceived = handler.onStatusReceived(status) == STATE.UPGRADE;
if (!statusReceived) {
try {
handler.onCompleted();
} finally {
future.done();
}
return;
}
final boolean headerOK = handler.onHeadersReceived(responseHeaders) == STATE.CONTINUE;
if (!headerOK || !validStatus || !validUpgrade || !validConnection) {
requestSender.abort(channel, future, new IOException("Invalid handshake response"));
return;
}
String accept = response.headers().get(HttpHeaders.Names.SEC_WEBSOCKET_ACCEPT);
String key = getAcceptKey(future.getNettyRequest().getHttpRequest().headers().get(HttpHeaders.Names.SEC_WEBSOCKET_KEY));
if (accept == null || !accept.equals(key)) {
requestSender.abort(channel, future, new IOException(String.format("Invalid challenge. Actual: %s. Expected: %s", accept, key)));
}
channelManager.upgradePipelineForWebSockets(channel.pipeline());
invokeOnSucces(channel, handler);
future.done();
} else if (e instanceof WebSocketFrame) {
final WebSocketFrame frame = (WebSocketFrame) e;
NettyWebSocket webSocket = NettyWebSocket.class.cast(handler.onCompleted());
invokeOnSucces(channel, handler);
if (webSocket != null) {
if (frame instanceof CloseWebSocketFrame) {
Channels.setDiscard(channel);
CloseWebSocketFrame closeFrame = CloseWebSocketFrame.class.cast(frame);
webSocket.onClose(closeFrame.statusCode(), closeFrame.reasonText());
} else {
ByteBuf buf = frame.content();
if (buf != null && buf.readableBytes() > 0) {
try {
NettyResponseBodyPart part = nettyConfig.getBodyPartFactory().newResponseBodyPart(buf, frame.isFinalFragment());
handler.onBodyPartReceived(part);
if (frame instanceof BinaryWebSocketFrame) {
webSocket.onBinaryFragment(part);
} else if (frame instanceof TextWebSocketFrame) {
webSocket.onTextFragment(part);