public static final class ResponseStatusCodes { public static final int CONTINUE_100 = HttpResponseStatus.CONTINUE.code(); public static final int SWITCHING_PROTOCOLS_101 = HttpResponseStatus.SWITCHING_PROTOCOLS.code(); public static final int OK_200 = HttpResponseStatus.OK.code(); public static final int MOVED_PERMANENTLY_301 = HttpResponseStatus.MOVED_PERMANENTLY.code(); public static final int FOUND_302 = HttpResponseStatus.FOUND.code(); public static final int SEE_OTHER_303 = HttpResponseStatus.SEE_OTHER.code(); public static final int NOT_MODIFIED_304 = HttpResponseStatus.NOT_MODIFIED.code(); public static final int TEMPORARY_REDIRECT_307 = HttpResponseStatus.TEMPORARY_REDIRECT.code(); public static final int UNAUTHORIZED_401 = HttpResponseStatus.UNAUTHORIZED.code(); public static final int PROXY_AUTHENTICATION_REQUIRED_407 = HttpResponseStatus.PROXY_AUTHENTICATION_REQUIRED.code(); private ResponseStatusCodes() {} }
/** * An {@link AsyncHandler} which is able to execute WebSocket upgrade. Use the Builder for * configuring WebSocket options. */ public class WebSocketUpgradeHandler implements UpgradeHandler<WebSocket>, AsyncHandler<WebSocket> { private static final int SWITCHING_PROTOCOLS = io.netty.handler.codec.http.HttpResponseStatus.SWITCHING_PROTOCOLS.code(); private WebSocket webSocket; private final List<WebSocketListener> listeners; private final AtomicBoolean ok = new AtomicBoolean(false); private boolean onSuccessCalled; private int status; private List<Runnable> bufferedFrames; public WebSocketUpgradeHandler(List<WebSocketListener> listeners) { this.listeners = listeners; } public void bufferFrame(Runnable bufferedFrame) { if (bufferedFrames == null) { bufferedFrames = new ArrayList<>(1); } bufferedFrames.add(bufferedFrame); } /** {@inheritDoc} */ @Override public final void onThrowable(Throwable t) { onFailure(t); } public boolean touchSuccess() { boolean prev = onSuccessCalled; onSuccessCalled = true; return prev; } /** {@inheritDoc} */ @Override public final State onBodyPartReceived(HttpResponseBodyPart bodyPart) throws Exception { return State.CONTINUE; } /** {@inheritDoc} */ @Override public final State onStatusReceived(HttpResponseStatus responseStatus) throws Exception { status = responseStatus.getStatusCode(); return status == SWITCHING_PROTOCOLS ? State.UPGRADE : State.ABORT; } /** {@inheritDoc} */ @Override public final State onHeadersReceived(HttpResponseHeaders headers) throws Exception { return State.CONTINUE; } /** {@inheritDoc} */ @Override public final WebSocket onCompleted() throws Exception { if (status != SWITCHING_PROTOCOLS) { IllegalStateException e = new IllegalStateException("Invalid Status Code " + status); for (WebSocketListener listener : listeners) { listener.onError(e); } throw e; } return webSocket; } /** {@inheritDoc} */ @Override public final void onSuccess(WebSocket webSocket) { this.webSocket = webSocket; for (WebSocketListener listener : listeners) { webSocket.addWebSocketListener(listener); listener.onOpen(webSocket); } if (isNonEmpty(bufferedFrames)) { for (Runnable bufferedFrame : bufferedFrames) { bufferedFrame.run(); } bufferedFrames = null; } ok.set(true); } /** {@inheritDoc} */ @Override public final void onFailure(Throwable t) { for (WebSocketListener listener : listeners) { if (!ok.get() && webSocket != null) { webSocket.addWebSocketListener(listener); } listener.onError(t); } } public final void onClose(WebSocket webSocket, int status, String reasonPhrase) { // Connect failure if (this.webSocket == null) this.webSocket = webSocket; for (WebSocketListener listener : listeners) { if (webSocket != null) { webSocket.addWebSocketListener(listener); } listener.onClose(webSocket); if (listener instanceof WebSocketCloseCodeReasonListener) { WebSocketCloseCodeReasonListener.class .cast(listener) .onClose(webSocket, status, reasonPhrase); } } } /** Build a {@link WebSocketUpgradeHandler} */ public static final class Builder { private List<WebSocketListener> listeners = new ArrayList<>(1); /** * Add a {@link WebSocketListener} that will be added to the {@link WebSocket} * * @param listener a {@link WebSocketListener} * @return this */ public Builder addWebSocketListener(WebSocketListener listener) { listeners.add(listener); return this; } /** * Remove a {@link WebSocketListener} * * @param listener a {@link WebSocketListener} * @return this */ public Builder removeWebSocketListener(WebSocketListener listener) { listeners.remove(listener); return this; } /** * Build a {@link WebSocketUpgradeHandler} * * @return a {@link WebSocketUpgradeHandler} */ public WebSocketUpgradeHandler build() { return new WebSocketUpgradeHandler(listeners); } } }