2525import io .jooby .StatusCode ;
2626import io .jooby .Value ;
2727import io .jooby .ValueNode ;
28+ import io .jooby .WebSocket ;
2829import io .netty .buffer .ByteBuf ;
2930import io .netty .buffer .Unpooled ;
3031import io .netty .channel .ChannelFuture ;
3132import io .netty .channel .ChannelFutureListener ;
3233import io .netty .channel .ChannelHandlerContext ;
3334import io .netty .channel .ChannelPipeline ;
3435import io .netty .channel .DefaultFileRegion ;
36+ import io .netty .handler .codec .http .DefaultFullHttpRequest ;
3537import io .netty .handler .codec .http .DefaultFullHttpResponse ;
3638import io .netty .handler .codec .http .DefaultHttpHeaders ;
3739import io .netty .handler .codec .http .DefaultHttpResponse ;
4749import io .netty .handler .codec .http .multipart .HttpPostRequestDecoder ;
4850import io .netty .handler .codec .http .multipart .InterfaceHttpData ;
4951import io .netty .handler .codec .http .multipart .InterfaceHttpPostRequestDecoder ;
52+ import io .netty .handler .codec .http .websocketx .WebSocketDecoderConfig ;
53+ import io .netty .handler .codec .http .websocketx .WebSocketServerHandshaker ;
54+ import io .netty .handler .codec .http .websocketx .WebSocketServerHandshakerFactory ;
5055import io .netty .handler .stream .ChunkedNioStream ;
5156import io .netty .handler .stream .ChunkedStream ;
5257import io .netty .handler .stream .ChunkedWriteHandler ;
5358import io .netty .util .ReferenceCounted ;
59+ import io .netty .util .concurrent .EventExecutorGroup ;
60+ import io .netty .util .concurrent .Future ;
61+ import io .netty .util .concurrent .GenericFutureListener ;
5462
5563import javax .annotation .Nonnull ;
5664import java .io .FileInputStream ;
@@ -94,7 +102,7 @@ public class NettyContext implements DefaultContext, ChannelFutureListener {
94102 InterfaceHttpPostRequestDecoder decoder ;
95103 private Router router ;
96104 private Route route ;
97- private ChannelHandlerContext ctx ;
105+ ChannelHandlerContext ctx ;
98106 private HttpRequest req ;
99107 private String path ;
100108 private HttpResponseStatus status = HttpResponseStatus .OK ;
@@ -112,6 +120,7 @@ public class NettyContext implements DefaultContext, ChannelFutureListener {
112120 private Map <String , String > cookies ;
113121 private Map <String , String > responseCookies ;
114122 private Boolean resetHeadersOnError ;
123+ NettyWebSocket webSocket ;
115124
116125 public NettyContext (ChannelHandlerContext ctx , HttpRequest req , Router router , String path ,
117126 int bufferSize ) {
@@ -261,6 +270,35 @@ public NettyContext(ChannelHandlerContext ctx, HttpRequest req, Router router, S
261270 return this .cookies ;
262271 }
263272
273+ @ Nonnull @ Override public Context upgrade (WebSocket .Handler handler ) {
274+ try {
275+ String webSocketURL = getProtocol () + "://" + req .headers ().get (HttpHeaderNames .HOST ) + path ;
276+ WebSocketDecoderConfig config = WebSocketDecoderConfig .newBuilder ()
277+ .allowExtensions (true )
278+ .allowMaskMismatch (false )
279+ .withUTF8Validator (false )
280+ .maxFramePayloadLength (131072 )
281+ .build ();
282+ responseStarted = true ;
283+ webSocket = new NettyWebSocket (this );
284+ handler .apply (this );
285+ DefaultFullHttpRequest fullHttpRequest = new DefaultFullHttpRequest (req .protocolVersion (),
286+ req .method (), req .uri (), Unpooled .EMPTY_BUFFER , req .headers (), EmptyHttpHeaders .INSTANCE );
287+ WebSocketServerHandshakerFactory factory = new WebSocketServerHandshakerFactory (webSocketURL ,
288+ null , config );
289+ WebSocketServerHandshaker handshaker = factory .newHandshaker (fullHttpRequest );
290+ handshaker .handshake (ctx .channel (), fullHttpRequest , setHeaders , ctx .newPromise ())
291+ .addListener (future -> {
292+ if (future .isSuccess ()) {
293+ webSocket .fireConnect (this );
294+ }
295+ });
296+ } catch (Throwable x ) {
297+ sendError (x );
298+ }
299+ return this ;
300+ }
301+
264302 /* **********************************************************************************************
265303 * Response methods:
266304 * **********************************************************************************************
0 commit comments