101101import org .glassfish .grizzly .websockets .DataFrame ;
102102import org .glassfish .grizzly .websockets .DefaultWebSocket ;
103103import org .glassfish .grizzly .websockets .HandShake ;
104+ import org .glassfish .grizzly .websockets .HandshakeException ;
104105import org .glassfish .grizzly .websockets .ProtocolHandler ;
105106import org .glassfish .grizzly .websockets .Version ;
106107import org .glassfish .grizzly .websockets .WebSocketEngine ;
@@ -147,7 +148,7 @@ public class GrizzlyAsyncHttpProvider implements AsyncHttpProvider {
147148 private final static Logger LOGGER = LoggerFactory .getLogger (GrizzlyAsyncHttpProvider .class );
148149 private static final boolean SEND_FILE_SUPPORT ;
149150 static {
150- SEND_FILE_SUPPORT = configSendFileSupport ();
151+ SEND_FILE_SUPPORT = /* configSendFileSupport()*/ false ;
151152 }
152153 private final Attribute <HttpTransactionContext > REQUEST_STATE_ATTR =
153154 Grizzly .DEFAULT_ATTRIBUTE_BUILDER .createAttribute (HttpTransactionContext .class .getName ());
@@ -619,6 +620,7 @@ final class HttpTransactionContext {
619620 HandShake handshake ;
620621 ProtocolHandler protocolHandler ;
621622 WebSocket webSocket ;
623+ boolean establishingTunnel ;
622624
623625
624626 // -------------------------------------------------------- Constructors
@@ -677,6 +679,15 @@ void result(Object result) {
677679 }
678680 }
679681
682+ boolean isTunnelEstablished (final Connection c ) {
683+ return c .getAttributes ().getAttribute ("tunnel-established" ) != null ;
684+ }
685+
686+
687+ void tunnelEstablished (final Connection c ) {
688+ c .getAttributes ().setAttribute ("tunnel-established" , Boolean .TRUE );
689+ }
690+
680691
681692 } // END HttpTransactionContext
682693
@@ -844,7 +855,9 @@ private boolean sendAsGrizzlyRequest(final Request request,
844855 final ProxyServer proxy = getProxyServer (request );
845856 final boolean useProxy = (proxy != null );
846857 if (useProxy ) {
847- if (secure ) {
858+ if ((secure || httpCtx .isWSRequest ) && !httpCtx .isTunnelEstablished (ctx .getConnection ())) {
859+ secure = false ;
860+ httpCtx .establishingTunnel = true ;
848861 builder .method (Method .CONNECT );
849862 builder .uri (AsyncHttpProviderUtils .getAuthority (uri ));
850863 } else {
@@ -864,7 +877,7 @@ private boolean sendAsGrizzlyRequest(final Request request,
864877 }
865878
866879 HttpRequestPacket requestPacket ;
867- if (httpCtx .isWSRequest ) {
880+ if (httpCtx .isWSRequest && ! httpCtx . establishingTunnel ) {
868881 try {
869882 final URI wsURI = new URI (httpCtx .wsRequestURI );
870883 httpCtx .protocolHandler = Version .DRAFT17 .createHandler (true );
@@ -877,7 +890,10 @@ private boolean sendAsGrizzlyRequest(final Request request,
877890 } else {
878891 requestPacket = builder .build ();
879892 }
880- requestPacket .setSecure (true );
893+ requestPacket .setSecure (secure );
894+ if (secure ) {
895+ ctx .notifyDownstream (new SwitchingSSLFilter .SSLSwitchingEvent (true , ctx .getConnection ()));
896+ }
881897 if (!useProxy && !httpCtx .isWSRequest ) {
882898 addQueryString (request , requestPacket );
883899 }
@@ -1139,14 +1155,19 @@ protected void onInitialLineParsed(HttpHeader httpHeader,
11391155 if (httpHeader .isSkipRemainder ()) {
11401156 return ;
11411157 }
1158+ final Connection connection = ctx .getConnection ();
11421159 final HttpTransactionContext context =
1143- provider .getHttpTransactionContext (ctx . getConnection () );
1160+ provider .getHttpTransactionContext (connection );
11441161 final int status = ((HttpResponsePacket ) httpHeader ).getStatus ();
1162+ if (context .establishingTunnel && HttpStatus .OK_200 .statusMatches (status )) {
1163+ return ;
1164+ }
11451165 if (HttpStatus .CONINTUE_100 .statusMatches (status )) {
11461166 ctx .notifyUpstream (new ContinueEvent (context ));
11471167 return ;
11481168 }
11491169
1170+
11501171 if (context .statusHandler != null && !context .statusHandler .handlesStatus (status )) {
11511172 context .statusHandler = null ;
11521173 context .invocationStatus = StatusHandler .InvocationStatus .CONTINUE ;
@@ -1180,9 +1201,9 @@ protected void onInitialLineParsed(HttpHeader httpHeader,
11801201 }
11811202 }
11821203 final GrizzlyResponseStatus responseStatus =
1183- new GrizzlyResponseStatus ((HttpResponsePacket ) httpHeader ,
1184- getURI (context .requestUrl ),
1185- provider );
1204+ new GrizzlyResponseStatus ((HttpResponsePacket ) httpHeader ,
1205+ getURI (context .requestUrl ),
1206+ provider );
11861207 context .responseStatus = responseStatus ;
11871208 if (context .statusHandler != null ) {
11881209 return ;
@@ -1193,6 +1214,10 @@ protected void onInitialLineParsed(HttpHeader httpHeader,
11931214 final AsyncHandler handler = context .handler ;
11941215 if (handler != null ) {
11951216 context .currentState = handler .onStatusReceived (responseStatus );
1217+ if (context .isWSRequest && context .currentState == AsyncHandler .STATE .ABORT ) {
1218+ httpHeader .setSkipRemainder (true );
1219+ context .abort (new HandshakeException ("Upgrade failed" ));
1220+ }
11961221 }
11971222 } catch (Exception e ) {
11981223 httpHeader .setSkipRemainder (true );
@@ -1221,24 +1246,23 @@ protected void onHttpHeadersParsed(HttpHeader httpHeader,
12211246 FilterChainContext ctx ) {
12221247
12231248 super .onHttpHeadersParsed (httpHeader , ctx );
1224- if (LOGGER .isDebugEnabled ()) {
1225- LOGGER .debug ("RESPONSE: " + httpHeader .toString ());
1226- }
1249+ LOGGER .debug ("RESPONSE: {}" , httpHeader );
12271250 if (httpHeader .containsHeader (Header .Connection )) {
12281251 if ("close" .equals (httpHeader .getHeader (Header .Connection ))) {
12291252 ConnectionManager .markConnectionAsDoNotCache (ctx .getConnection ());
12301253 }
12311254 }
1232- if (httpHeader .isSkipRemainder ()) {
1233- return ;
1234- }
12351255 final HttpTransactionContext context =
12361256 provider .getHttpTransactionContext (ctx .getConnection ());
1257+ if (httpHeader .isSkipRemainder () || context .establishingTunnel ) {
1258+ return ;
1259+ }
1260+
12371261 final AsyncHandler handler = context .handler ;
12381262 final List <ResponseFilter > filters = context .provider .clientConfig .getResponseFilters ();
12391263 final GrizzlyResponseHeaders responseHeaders = new GrizzlyResponseHeaders ((HttpResponsePacket ) httpHeader ,
1240- null ,
1241- provider );
1264+ null ,
1265+ provider );
12421266 if (!filters .isEmpty ()) {
12431267 FilterContext fc = new FilterContext .FilterContextBuilder ()
12441268 .asyncHandler (handler ).request (context .request )
@@ -1260,16 +1284,16 @@ protected void onHttpHeadersParsed(HttpHeader httpHeader,
12601284 context .provider .connectionManager ;
12611285 final Connection c =
12621286 m .obtainConnection (newRequest ,
1263- context .future );
1287+ context .future );
12641288 final HttpTransactionContext newContext =
12651289 context .copy ();
12661290 context .future = null ;
12671291 provider .setHttpTransactionContext (c , newContext );
12681292 try {
12691293 context .provider .execute (c ,
1270- newRequest ,
1271- newHandler ,
1272- context .future );
1294+ newRequest ,
1295+ newHandler ,
1296+ context .future );
12731297 } catch (IOException ioe ) {
12741298 newContext .abort (ioe );
12751299 }
@@ -1281,8 +1305,8 @@ protected void onHttpHeadersParsed(HttpHeader httpHeader,
12811305 }
12821306 if (context .statusHandler != null && context .invocationStatus == StatusHandler .InvocationStatus .CONTINUE ) {
12831307 final boolean result = context .statusHandler .handleStatus (((HttpResponsePacket ) httpHeader ),
1284- context ,
1285- ctx );
1308+ context ,
1309+ ctx );
12861310 if (!result ) {
12871311 httpHeader .setSkipRemainder (true );
12881312 return ;
@@ -1347,20 +1371,38 @@ protected boolean onHttpPacketParsed(HttpHeader httpHeader, FilterChainContext c
13471371
13481372 result = super .onHttpPacketParsed (httpHeader , ctx );
13491373
1350- final HttpTransactionContext context = cleanup (ctx , provider );
1351-
1352- final AsyncHandler handler = context .handler ;
1353- if (handler != null ) {
1374+ final HttpTransactionContext context = provider .getHttpTransactionContext (ctx .getConnection ());
1375+ if (context .establishingTunnel
1376+ && HttpStatus .OK_200 .statusMatches (
1377+ ((HttpResponsePacket ) httpHeader ).getStatus ())) {
1378+ context .establishingTunnel = false ;
1379+ final Connection c = ctx .getConnection ();
1380+ context .tunnelEstablished (c );
13541381 try {
1355- context .result (handler .onCompleted ());
1356- } catch (Exception e ) {
1382+ context .provider .execute (c ,
1383+ context .request ,
1384+ context .handler ,
1385+ context .future );
1386+ return result ;
1387+ } catch (IOException e ) {
13571388 context .abort (e );
1389+ return result ;
13581390 }
13591391 } else {
1360- context .done (null );
1361- }
1392+ cleanup (ctx , provider );
1393+ final AsyncHandler handler = context .handler ;
1394+ if (handler != null ) {
1395+ try {
1396+ context .result (handler .onCompleted ());
1397+ } catch (Exception e ) {
1398+ context .abort (e );
1399+ }
1400+ } else {
1401+ context .done (null );
1402+ }
13621403
1363- return result ;
1404+ return result ;
1405+ }
13641406 }
13651407
13661408
@@ -1389,7 +1431,7 @@ private static HttpTransactionContext cleanup(final FilterChainContext ctx,
13891431 context .abort (new IOException ("Maximum pooled connections exceeded" ));
13901432 } else {
13911433 if (!context .provider .connectionManager .returnConnection (context .requestUrl , c )) {
1392- ctx .getConnection ().close (). markForRecycle ( true ) ;
1434+ ctx .getConnection ().close ();
13931435 }
13941436 }
13951437
0 commit comments