@@ -915,9 +915,9 @@ private boolean sendAsGrizzlyRequest(final Request request,
915
915
}
916
916
917
917
if (proxy .getPrincipal () != null ) {
918
- requestPacket .setHeader (Header .ProxyAuthorization ,
919
- AuthenticatorUtils .computeBasicAuthentication (proxy ));
918
+ requestPacket .setHeader (Header .ProxyAuthorization , AuthenticatorUtils .computeBasicAuthentication (proxy ));
920
919
}
920
+
921
921
}
922
922
}
923
923
final AsyncHandler h = httpCtx .handler ;
@@ -1091,6 +1091,8 @@ private static final class AsyncHttpClientEventFilter extends HttpClientFilter {
1091
1091
this .provider = provider ;
1092
1092
HANDLER_MAP .put (HttpStatus .UNAUTHORIZED_401 .getStatusCode (),
1093
1093
AuthorizationHandler .INSTANCE );
1094
+ HANDLER_MAP .put (HttpStatus .PROXY_AUTHENTICATION_REQUIRED_407 .getStatusCode (),
1095
+ ProxyAuthorizationHandler .INSTANCE );
1094
1096
HANDLER_MAP .put (HttpStatus .MOVED_PERMANENTLY_301 .getStatusCode (),
1095
1097
RedirectHandler .INSTANCE );
1096
1098
HANDLER_MAP .put (HttpStatus .FOUND_302 .getStatusCode (),
@@ -1265,9 +1267,9 @@ protected void onHttpHeadersParsed(HttpHeader httpHeader,
1265
1267
ConnectionManager .markConnectionAsDoNotCache (ctx .getConnection ());
1266
1268
}
1267
1269
}
1268
- final HttpTransactionContext context =
1269
- provider . getHttpTransactionContext ( ctx . getConnection ());
1270
- if (httpHeader .isSkipRemainder () || context .establishingTunnel ) {
1270
+ final HttpTransactionContext context = provider . getHttpTransactionContext ( ctx . getConnection ());
1271
+
1272
+ if (httpHeader .isSkipRemainder () || ( context .establishingTunnel && context . statusHandler == null ) ) {
1271
1273
return ;
1272
1274
}
1273
1275
@@ -1327,6 +1329,14 @@ protected void onHttpHeadersParsed(HttpHeader httpHeader,
1327
1329
}
1328
1330
if (context .isWSRequest ) {
1329
1331
try {
1332
+ //in case of DIGEST auth protocol handler is null and just returning here is working
1333
+ if (context .protocolHandler == null )
1334
+ {
1335
+ return ;
1336
+ //context.protocolHandler = Version.DRAFT17.createHandler(true);
1337
+ //context.currentState = AsyncHandler.STATE.UPGRADE;
1338
+ }
1339
+
1330
1340
context .protocolHandler .setConnection (ctx .getConnection ());
1331
1341
DefaultWebSocket ws = new DefaultWebSocket (context .protocolHandler );
1332
1342
context .webSocket = new GrizzlyWebSocketAdapter (ws );
@@ -1569,6 +1579,90 @@ public boolean handleStatus(final HttpResponsePacket responsePacket,
1569
1579
1570
1580
} // END AuthorizationHandler
1571
1581
1582
+ private static final class ProxyAuthorizationHandler implements StatusHandler {
1583
+
1584
+ private static final ProxyAuthorizationHandler INSTANCE =
1585
+ new ProxyAuthorizationHandler ();
1586
+
1587
+ // -------------------------------------- Methods from StatusHandler
1588
+
1589
+
1590
+ public boolean handlesStatus (int statusCode ) {
1591
+ return (HttpStatus .PROXY_AUTHENTICATION_REQUIRED_407 .statusMatches (statusCode ));
1592
+ }
1593
+
1594
+ @ SuppressWarnings ({"unchecked" })
1595
+ public boolean handleStatus (final HttpResponsePacket responsePacket ,
1596
+ final HttpTransactionContext httpTransactionContext ,
1597
+ final FilterChainContext ctx ) {
1598
+
1599
+ final String proxy_auth = responsePacket .getHeader (Header .ProxyAuthenticate );
1600
+ if (proxy_auth == null ) {
1601
+ throw new IllegalStateException ("407 response received, but no Proxy Authenticate header was present" );
1602
+ }
1603
+
1604
+ final Request req = httpTransactionContext .request ;
1605
+ ProxyServer proxyServer = httpTransactionContext .provider .clientConfig .getProxyServer ();
1606
+ String principal = proxyServer .getPrincipal ();
1607
+ String password = proxyServer .getPassword ();
1608
+ Realm realm = new Realm .RealmBuilder ().setPrincipal (principal )
1609
+ .setPassword (password )
1610
+ .setUri ("/" )
1611
+ .setMethodName ("CONNECT" )
1612
+ .setUsePreemptiveAuth (true )
1613
+ .parseProxyAuthenticateHeader (proxy_auth )
1614
+ .build ();
1615
+ if (proxy_auth .toLowerCase ().startsWith ("basic" )) {
1616
+ req .getHeaders ().remove (Header .ProxyAuthenticate .toString ());
1617
+ req .getHeaders ().remove (Header .ProxyAuthorization .toString ());
1618
+ try {
1619
+ req .getHeaders ().add (Header .ProxyAuthorization .toString (),
1620
+ AuthenticatorUtils .computeBasicAuthentication (realm ));
1621
+ } catch (UnsupportedEncodingException ignored ) {
1622
+ }
1623
+ } else if (proxy_auth .toLowerCase ().startsWith ("digest" )) {
1624
+ req .getHeaders ().remove (Header .ProxyAuthenticate .toString ());
1625
+ req .getHeaders ().remove (Header .ProxyAuthorization .toString ());
1626
+ try {
1627
+ req .getHeaders ().add (Header .ProxyAuthorization .toString (),
1628
+ AuthenticatorUtils .computeDigestAuthentication (realm ));
1629
+ } catch (NoSuchAlgorithmException e ) {
1630
+ throw new IllegalStateException ("Digest authentication not supported" , e );
1631
+ } catch (UnsupportedEncodingException e ) {
1632
+ throw new IllegalStateException ("Unsupported encoding." , e );
1633
+ }
1634
+ } else {
1635
+ throw new IllegalStateException ("Unsupported authorization method: " + proxy_auth );
1636
+ }
1637
+
1638
+ final ConnectionManager m = httpTransactionContext .provider .connectionManager ;
1639
+ try {
1640
+ final Connection c = m .obtainConnection (req ,
1641
+ httpTransactionContext .future );
1642
+ final HttpTransactionContext newContext =
1643
+ httpTransactionContext .copy ();
1644
+ httpTransactionContext .future = null ;
1645
+ httpTransactionContext .provider .setHttpTransactionContext (c , newContext );
1646
+ newContext .invocationStatus = InvocationStatus .STOP ;
1647
+ try {
1648
+ httpTransactionContext .provider .execute (c ,
1649
+ req ,
1650
+ httpTransactionContext .handler ,
1651
+ httpTransactionContext .future );
1652
+ return false ;
1653
+ } catch (IOException ioe ) {
1654
+ newContext .abort (ioe );
1655
+ return false ;
1656
+ }
1657
+ } catch (Exception e ) {
1658
+ httpTransactionContext .abort (e );
1659
+ }
1660
+ httpTransactionContext .invocationStatus = InvocationStatus .STOP ;
1661
+ return false ;
1662
+ }
1663
+
1664
+ } // END AuthorizationHandler
1665
+
1572
1666
1573
1667
private static final class RedirectHandler implements StatusHandler {
1574
1668
0 commit comments