2828import io .netty .handler .codec .http .HttpResponse ;
2929import io .netty .handler .codec .http .HttpResponseStatus ;
3030
31+ import java .util .ArrayDeque ;
3132import java .util .ArrayList ;
3233import java .util .Arrays ;
34+ import java .util .Collections ;
3335import java .util .Iterator ;
3436import java .util .List ;
37+ import java .util .Queue ;
3538
3639/**
3740 * This handler negotiates and initializes the WebSocket Extensions.
@@ -47,7 +50,8 @@ public class WebSocketServerExtensionHandler extends ChannelDuplexHandler {
4750
4851 private final List <WebSocketServerExtensionHandshaker > extensionHandshakers ;
4952
50- private List <WebSocketServerExtension > validExtensions ;
53+ private final Queue <List <WebSocketServerExtension >> validExtensions =
54+ new ArrayDeque <List <WebSocketServerExtension >>(4 );
5155
5256 /**
5357 * Constructor
@@ -63,6 +67,7 @@ public WebSocketServerExtensionHandler(WebSocketServerExtensionHandshaker... ext
6367 @ Override
6468 public void channelRead (ChannelHandlerContext ctx , Object msg ) throws Exception {
6569 if (msg instanceof HttpRequest ) {
70+ List <WebSocketServerExtension > validExtensionsList = null ;
6671 HttpRequest request = (HttpRequest ) msg ;
6772
6873 if (WebSocketExtensionUtil .isWebsocketUpgrade (request .headers ())) {
@@ -85,15 +90,20 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
8590 }
8691
8792 if (validExtension != null && ((validExtension .rsv () & rsv ) == 0 )) {
88- if (validExtensions == null ) {
89- validExtensions = new ArrayList <WebSocketServerExtension >(1 );
93+ if (validExtensionsList == null ) {
94+ validExtensionsList = new ArrayList <WebSocketServerExtension >(1 );
9095 }
9196 rsv = rsv | validExtension .rsv ();
92- validExtensions .add (validExtension );
97+ validExtensionsList .add (validExtension );
9398 }
9499 }
95100 }
96101 }
102+
103+ if (validExtensionsList == null ) {
104+ validExtensionsList = Collections .emptyList ();
105+ }
106+ validExtensions .offer (validExtensionsList );
97107 }
98108
99109 super .channelRead (ctx , msg );
@@ -102,28 +112,29 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
102112 @ Override
103113 public void write (final ChannelHandlerContext ctx , Object msg , ChannelPromise promise ) throws Exception {
104114 if (msg instanceof HttpResponse ) {
115+ List <WebSocketServerExtension > validExtensionsList = validExtensions .poll ();
105116 HttpResponse httpResponse = (HttpResponse ) msg ;
106117 //checking the status is faster than looking at headers
107118 //so we do this first
108119 if (HttpResponseStatus .SWITCHING_PROTOCOLS .equals (httpResponse .status ())) {
109- handlePotentialUpgrade (ctx , promise , httpResponse );
120+ handlePotentialUpgrade (ctx , promise , httpResponse , validExtensionsList );
110121 }
111122 }
112123
113124 super .write (ctx , msg , promise );
114125 }
115126
116127 private void handlePotentialUpgrade (final ChannelHandlerContext ctx ,
117- ChannelPromise promise , HttpResponse httpResponse ) {
128+ ChannelPromise promise , HttpResponse httpResponse ,
129+ final List <WebSocketServerExtension > validExtensionsList ) {
118130 HttpHeaders headers = httpResponse .headers ();
119131
120132 if (WebSocketExtensionUtil .isWebsocketUpgrade (headers )) {
121-
122- if (validExtensions != null ) {
133+ if (validExtensionsList != null && !validExtensionsList .isEmpty ()) {
123134 String headerValue = headers .getAsString (HttpHeaderNames .SEC_WEBSOCKET_EXTENSIONS );
124135 List <WebSocketExtensionData > extraExtensions =
125136 new ArrayList <WebSocketExtensionData >(extensionHandshakers .size ());
126- for (WebSocketServerExtension extension : validExtensions ) {
137+ for (WebSocketServerExtension extension : validExtensionsList ) {
127138 extraExtensions .add (extension .newReponseData ());
128139 }
129140 String newHeaderValue = WebSocketExtensionUtil
@@ -132,7 +143,7 @@ private void handlePotentialUpgrade(final ChannelHandlerContext ctx,
132143 @ Override
133144 public void operationComplete (ChannelFuture future ) {
134145 if (future .isSuccess ()) {
135- for (WebSocketServerExtension extension : validExtensions ) {
146+ for (WebSocketServerExtension extension : validExtensionsList ) {
136147 WebSocketExtensionDecoder decoder = extension .newExtensionDecoder ();
137148 WebSocketExtensionEncoder encoder = extension .newExtensionEncoder ();
138149 String name = ctx .name ();
0 commit comments