This is an automated email from the ASF dual-hosted git repository.

markt-asf pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/9.0.x by this push:
     new 169d725788 Fix WebSocket + proxy + DIGEST auth on proxy
169d725788 is described below

commit 169d725788ea6aec217ecac70fe4161c837ba423
Author: Mark Thomas <[email protected]>
AuthorDate: Mon Apr 27 22:59:51 2026 +0100

    Fix WebSocket + proxy + DIGEST auth on proxy
---
 .../org/apache/tomcat/websocket/Authenticator.java | 30 ++++++-
 .../tomcat/websocket/BasicAuthenticator.java       |  4 +-
 .../tomcat/websocket/DigestAuthenticator.java      | 18 +++--
 .../tomcat/websocket/WsWebSocketContainer.java     | 93 +++++++++++++---------
 .../websocket/TesterWebSocketClientProxy.java      | 61 ++++++++++----
 webapps/docs/changelog.xml                         |  8 ++
 6 files changed, 148 insertions(+), 66 deletions(-)

diff --git a/java/org/apache/tomcat/websocket/Authenticator.java 
b/java/org/apache/tomcat/websocket/Authenticator.java
index d2e53b078b..8bf71b180c 100644
--- a/java/org/apache/tomcat/websocket/Authenticator.java
+++ b/java/org/apache/tomcat/websocket/Authenticator.java
@@ -21,6 +21,7 @@ import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import org.apache.tomcat.util.http.Method;
 import org.apache.tomcat.util.res.StringManager;
 
 /**
@@ -69,9 +70,34 @@ public abstract class Authenticator {
      * @return The generated authorization header value
      *
      * @throws AuthenticationException When an error occurs
+     *
+     * @deprecated Unused. Will be remove in Tomcat 12. Use
+     *                 {@link #getAuthorization(String, String, String, 
String, String, String)}
+     */
+    @Deprecated
+    public String getAuthorization(String requestUri, String 
authenticateHeader, String userName, String userPassword,
+            String userRealm) throws AuthenticationException {
+        return getAuthorization(Method.GET, requestUri, authenticateHeader, 
userName, userPassword, userRealm);
+    }
+
+
+    /**
+     * Generate the authorization header value that will be sent to the server.
+     *
+     * @param method             The request method
+     * @param requestUri         The request URI
+     * @param authenticateHeader The server authentication header received
+     * @param userName           The username
+     * @param userPassword       The user password
+     * @param userRealm          The realm for which the provided username and 
password are valid. {@code null} to
+     *                               indicate all realms.
+     *
+     * @return The generated authorization header value
+     *
+     * @throws AuthenticationException When an error occurs
      */
-    public abstract String getAuthorization(String requestUri, String 
authenticateHeader, String userName,
-            String userPassword, String userRealm) throws 
AuthenticationException;
+    public abstract String getAuthorization(String method, String requestUri, 
String authenticateHeader,
+            String userName, String userPassword, String userRealm) throws 
AuthenticationException;
 
 
     /**
diff --git a/java/org/apache/tomcat/websocket/BasicAuthenticator.java 
b/java/org/apache/tomcat/websocket/BasicAuthenticator.java
index b669d2eb94..cf11d72031 100644
--- a/java/org/apache/tomcat/websocket/BasicAuthenticator.java
+++ b/java/org/apache/tomcat/websocket/BasicAuthenticator.java
@@ -30,8 +30,8 @@ public class BasicAuthenticator extends Authenticator {
     public static final String charsetparam = "charset";
 
     @Override
-    public String getAuthorization(String requestUri, String 
authenticateHeader, String userName, String userPassword,
-            String userRealm) throws AuthenticationException {
+    public String getAuthorization(String method, String requestUri, String 
authenticateHeader, String userName,
+            String userPassword, String userRealm) throws 
AuthenticationException {
 
         validateUsername(userName);
         validatePassword(userPassword);
diff --git a/java/org/apache/tomcat/websocket/DigestAuthenticator.java 
b/java/org/apache/tomcat/websocket/DigestAuthenticator.java
index 9f018a7a5e..e68b33fab6 100644
--- a/java/org/apache/tomcat/websocket/DigestAuthenticator.java
+++ b/java/org/apache/tomcat/websocket/DigestAuthenticator.java
@@ -40,8 +40,8 @@ public class DigestAuthenticator extends Authenticator {
     private long cNonce;
 
     @Override
-    public String getAuthorization(String requestUri, String 
authenticateHeader, String userName, String userPassword,
-            String userRealm) throws AuthenticationException {
+    public String getAuthorization(String method, String requestUri, String 
authenticateHeader, String userName,
+            String userPassword, String userRealm) throws 
AuthenticationException {
 
         validateUsername(userName);
         validatePassword(userPassword);
@@ -79,8 +79,8 @@ public class DigestAuthenticator extends Authenticator {
 
         try {
             challenge.append("response=\"");
-            challenge.append(
-                    calculateRequestDigest(requestUri, userName, userPassword, 
realm, nonce, messageQop, algorithm));
+            challenge.append(calculateRequestDigest(method, requestUri, 
userName, userPassword, realm, nonce,
+                    messageQop, algorithm));
             challenge.append("\",");
         }
 
@@ -89,7 +89,9 @@ public class DigestAuthenticator extends Authenticator {
         }
 
         challenge.append("algorithm=").append(algorithm).append(",");
-        challenge.append("opaque=\"").append(opaque).append("\",");
+        if (opaque != null) {
+            challenge.append("opaque=\"").append(opaque).append("\",");
+        }
 
         if (!messageQop.isEmpty()) {
             challenge.append("qop=\"").append(messageQop).append("\"");
@@ -101,8 +103,8 @@ public class DigestAuthenticator extends Authenticator {
 
     }
 
-    private String calculateRequestDigest(String requestUri, String userName, 
String password, String realm,
-            String nonce, String qop, String algorithm) throws 
NoSuchAlgorithmException {
+    private String calculateRequestDigest(String method, String requestUri, 
String userName, String password,
+            String realm, String nonce, String qop, String algorithm) throws 
NoSuchAlgorithmException {
 
         boolean session = false;
         if (algorithm.endsWith("-sess")) {
@@ -123,7 +125,7 @@ public class DigestAuthenticator extends Authenticator {
          * If the "qop" value is "auth-int", then A2 is: A2 = Method ":" 
digest-uri-value ":" H(entity-body) since we do
          * not have an entity-body, A2 = Method ":" digest-uri-value for auth 
and auth_int
          */
-        String A2 = "GET:" + requestUri;
+        String A2 = method + ":" + requestUri;
 
         preDigest.append(encode(algorithm, A1));
         preDigest.append(':');
diff --git a/java/org/apache/tomcat/websocket/WsWebSocketContainer.java 
b/java/org/apache/tomcat/websocket/WsWebSocketContainer.java
index 7df17239be..ce04b743c4 100644
--- a/java/org/apache/tomcat/websocket/WsWebSocketContainer.java
+++ b/java/org/apache/tomcat/websocket/WsWebSocketContainer.java
@@ -72,6 +72,7 @@ import org.apache.tomcat.InstanceManager;
 import org.apache.tomcat.InstanceManagerBindings;
 import org.apache.tomcat.util.buf.StringUtils;
 import org.apache.tomcat.util.collections.CaseInsensitiveKeyMap;
+import org.apache.tomcat.util.http.Method;
 import org.apache.tomcat.util.res.StringManager;
 import org.apache.tomcat.util.security.KeyStoreUtil;
 
@@ -177,40 +178,41 @@ public class WsWebSocketContainer implements 
WebSocketContainer, BackgroundProce
 
 
     private Session connectToServerRecursive(ClientEndpointHolder 
clientEndpointHolder,
-            ClientEndpointConfig clientEndpointConfiguration, URI path, 
Set<URI> redirectSet)
+            ClientEndpointConfig clientEndpointConfiguration, URI 
serverEndpointUri, Set<URI> redirectSet)
             throws DeploymentException {
 
         if (log.isTraceEnabled()) {
-            log.trace(sm.getString("wsWebSocketContainer.connect.entry", 
clientEndpointHolder.getClassName(), path));
+            log.trace(sm.getString("wsWebSocketContainer.connect.entry", 
clientEndpointHolder.getClassName(),
+                    serverEndpointUri));
         }
 
         boolean secure = false;
         ByteBuffer proxyConnect = null;
-        URI proxyPath;
+        URI proxyUri;
 
         // Validate scheme (and build proxyPath)
-        String scheme = path.getScheme();
+        String scheme = serverEndpointUri.getScheme();
         if ("ws".equalsIgnoreCase(scheme)) {
-            proxyPath = URI.create("http" + path.toString().substring(2));
+            proxyUri = URI.create("http" + 
serverEndpointUri.toString().substring(2));
         } else if ("wss".equalsIgnoreCase(scheme)) {
-            proxyPath = URI.create("https" + path.toString().substring(3));
+            proxyUri = URI.create("https" + 
serverEndpointUri.toString().substring(3));
             secure = true;
         } else {
             throw new 
DeploymentException(sm.getString("wsWebSocketContainer.pathWrongScheme", 
scheme));
         }
 
-        // Validate host
-        String host = path.getHost();
-        if (host == null) {
+        // Validate server endpoint host
+        String serverEndpointHost = serverEndpointUri.getHost();
+        if (serverEndpointHost == null) {
             throw new 
DeploymentException(sm.getString("wsWebSocketContainer.pathNoHost"));
         }
-        int port = path.getPort();
+        int serverEndpointPort = serverEndpointUri.getPort();
 
         SocketAddress sa = null;
 
         // Check to see if a proxy is configured. Javadoc indicates return 
value
         // will never be null
-        List<Proxy> proxies = ProxySelector.getDefault().select(proxyPath);
+        List<Proxy> proxies = ProxySelector.getDefault().select(proxyUri);
         Proxy selectedProxy = null;
         for (Proxy proxy : proxies) {
             if (proxy.type().equals(Proxy.Type.HTTP)) {
@@ -228,12 +230,12 @@ public class WsWebSocketContainer implements 
WebSocketContainer, BackgroundProce
 
         // If the port is not explicitly specified, compute it based on the
         // scheme
-        if (port == -1) {
+        if (serverEndpointPort == -1) {
             if ("ws".equalsIgnoreCase(scheme)) {
-                port = 80;
+                serverEndpointPort = 80;
             } else {
                 // Must be wss due to scheme validation above
-                port = 443;
+                serverEndpointPort = 443;
             }
         }
 
@@ -241,21 +243,23 @@ public class WsWebSocketContainer implements 
WebSocketContainer, BackgroundProce
 
         // If sa is null, no proxy is configured so need to create sa
         if (sa == null) {
-            sa = new InetSocketAddress(host, port);
+            sa = new InetSocketAddress(serverEndpointHost, serverEndpointPort);
         } else {
-            proxyConnect = createProxyRequest(host, port,
+            proxyConnect = createProxyRequest(serverEndpointHost, 
serverEndpointPort,
                     (String) 
userProperties.get(Constants.PROXY_AUTHORIZATION_HEADER_NAME));
         }
 
         // Create the initial HTTP request to open the WebSocket connection
-        Map<String,List<String>> reqHeaders = createRequestHeaders(host, port, 
secure, clientEndpointConfiguration);
-        
clientEndpointConfiguration.getConfigurator().beforeRequest(reqHeaders);
-        if (Constants.DEFAULT_ORIGIN_HEADER_VALUE != null && 
!reqHeaders.containsKey(Constants.ORIGIN_HEADER_NAME)) {
+        Map<String,List<String>> upgradeRequestHeaders =
+                createRequestHeaders(serverEndpointHost, serverEndpointPort, 
secure, clientEndpointConfiguration);
+        
clientEndpointConfiguration.getConfigurator().beforeRequest(upgradeRequestHeaders);
+        if (Constants.DEFAULT_ORIGIN_HEADER_VALUE != null &&
+                
!upgradeRequestHeaders.containsKey(Constants.ORIGIN_HEADER_NAME)) {
             List<String> originValues = new ArrayList<>(1);
             originValues.add(Constants.DEFAULT_ORIGIN_HEADER_VALUE);
-            reqHeaders.put(Constants.ORIGIN_HEADER_NAME, originValues);
+            upgradeRequestHeaders.put(Constants.ORIGIN_HEADER_NAME, 
originValues);
         }
-        ByteBuffer request = createRequest(path, reqHeaders);
+        ByteBuffer upgradeRequest = createRequest(serverEndpointUri, 
upgradeRequestHeaders);
 
         // Get the connection timeout
         long timeout = Constants.IO_TIMEOUT_MS_DEFAULT;
@@ -291,19 +295,23 @@ public class WsWebSocketContainer implements 
WebSocketContainer, BackgroundProce
                 writeRequest(channel, proxyConnect, timeout);
                 HttpResponse httpResponse = processResponse(response, channel, 
timeout);
                 if (httpResponse.status == 
Constants.PROXY_AUTHENTICATION_REQUIRED) {
-                    return 
processAuthenticationChallenge(clientEndpointHolder, 
clientEndpointConfiguration, path,
-                            redirectSet, userProperties, request, 
httpResponse, AuthenticationType.PROXY);
+                    return 
processAuthenticationChallenge(clientEndpointHolder, 
clientEndpointConfiguration,
+                            serverEndpointUri, redirectSet, userProperties, 
Method.CONNECT,
+                            serverEndpointHost + ":" + serverEndpointPort, 
httpResponse, AuthenticationType.PROXY);
                 } else if (httpResponse.getStatus() != 200) {
                     throw new 
DeploymentException(sm.getString("wsWebSocketContainer.proxyConnectFail", 
selectedProxy,
                             Integer.toString(httpResponse.getStatus())));
                 }
+                // Proxy authentication either successful or not required.
+                
userProperties.remove(Constants.PROXY_AUTHORIZATION_HEADER_NAME);
             }
 
             if (secure) {
                 // Regardless of whether a non-secure wrapper was created for a
                 // proxy CONNECT, need to use TLS from this point on so wrap 
the
                 // original AsynchronousSocketChannel
-                SSLEngine sslEngine = 
createSSLEngine(clientEndpointConfiguration, host, port);
+                SSLEngine sslEngine =
+                        createSSLEngine(clientEndpointConfiguration, 
serverEndpointHost, serverEndpointPort);
                 channel = new AsyncChannelWrapperSecure(socketChannel, 
sslEngine);
             } else if (channel == null) {
                 // Only need to wrap as this point if it wasn't wrapped to 
process a
@@ -323,10 +331,10 @@ public class WsWebSocketContainer implements 
WebSocketContainer, BackgroundProce
                 } catch (IOException ioe) {
                     // Ignore
                 }
-                log.trace(sm.getString("wsWebSocketContainer.connect.write", 
Integer.valueOf(request.position()),
-                        Integer.valueOf(request.limit()), localAddress));
+                log.trace(sm.getString("wsWebSocketContainer.connect.write", 
Integer.valueOf(upgradeRequest.position()),
+                        Integer.valueOf(upgradeRequest.limit()), 
localAddress));
             }
-            writeRequest(channel, request, timeout);
+            writeRequest(channel, upgradeRequest, timeout);
 
             HttpResponse httpResponse = processResponse(response, channel, 
timeout);
 
@@ -339,6 +347,9 @@ public class WsWebSocketContainer implements 
WebSocketContainer, BackgroundProce
 
             if (httpResponse.status != 101) {
                 if (isRedirectStatus(httpResponse.status)) {
+                    // HTTP redirect. Authentication either successful or not 
required.
+                    userProperties.remove(Constants.AUTHORIZATION_HEADER_NAME);
+
                     List<String> locationHeader =
                             
httpResponse.getHandshakeResponse().getHeaders().get(Constants.LOCATION_HEADER_NAME);
 
@@ -351,7 +362,7 @@ public class WsWebSocketContainer implements 
WebSocketContainer, BackgroundProce
                     URI redirectLocation = 
URI.create(locationHeader.get(0)).normalize();
 
                     if (!redirectLocation.isAbsolute()) {
-                        redirectLocation = path.resolve(redirectLocation);
+                        redirectLocation = 
serverEndpointUri.resolve(redirectLocation);
                     }
 
                     String redirectScheme = 
redirectLocation.getScheme().toLowerCase(Locale.ENGLISH);
@@ -372,14 +383,20 @@ public class WsWebSocketContainer implements 
WebSocketContainer, BackgroundProce
                             redirectSet);
 
                 } else if (httpResponse.status == Constants.UNAUTHORIZED) {
-                    return 
processAuthenticationChallenge(clientEndpointHolder, 
clientEndpointConfiguration, path,
-                            redirectSet, userProperties, request, 
httpResponse, AuthenticationType.WWW);
+                    String authenticationUri =
+                            new String(upgradeRequest.array(), 
StandardCharsets.ISO_8859_1).split("\\s", 3)[1];
+                    return 
processAuthenticationChallenge(clientEndpointHolder, 
clientEndpointConfiguration,
+                            serverEndpointUri, redirectSet, userProperties, 
Method.GET, authenticationUri, httpResponse,
+                            AuthenticationType.WWW);
 
                 } else {
                     throw new DeploymentException(
                             sm.getString("wsWebSocketContainer.invalidStatus", 
Integer.toString(httpResponse.status)));
                 }
             }
+            // HTTP upgrade successful. Authentication either successful or 
not required.
+            userProperties.remove(Constants.AUTHORIZATION_HEADER_NAME);
+
             HandshakeResponse handshakeResponse = 
httpResponse.getHandshakeResponse();
             
clientEndpointConfiguration.getConfigurator().afterResponse(handshakeResponse);
 
@@ -422,7 +439,7 @@ public class WsWebSocketContainer implements 
WebSocketContainer, BackgroundProce
             success = true;
         } catch (ExecutionException | InterruptedException | SSLException | 
EOFException | TimeoutException |
                 URISyntaxException | AuthenticationException e) {
-            throw new 
DeploymentException(sm.getString("wsWebSocketContainer.httpRequestFailed", 
path), e);
+            throw new 
DeploymentException(sm.getString("wsWebSocketContainer.httpRequestFailed", 
serverEndpointUri), e);
         } finally {
             if (!success) {
                 if (channel != null) {
@@ -466,9 +483,10 @@ public class WsWebSocketContainer implements 
WebSocketContainer, BackgroundProce
 
 
     private Session processAuthenticationChallenge(ClientEndpointHolder 
clientEndpointHolder,
-            ClientEndpointConfig clientEndpointConfiguration, URI path, 
Set<URI> redirectSet,
-            Map<String,Object> userProperties, ByteBuffer request, 
HttpResponse httpResponse,
-            AuthenticationType authenticationType) throws DeploymentException, 
AuthenticationException {
+            ClientEndpointConfig clientEndpointConfiguration, URI 
serverEndpointUri, Set<URI> redirectSet,
+            Map<String,Object> userProperties, String authenticationMethod, 
String authenticationUri,
+            HttpResponse httpResponse, AuthenticationType authenticationType)
+            throws DeploymentException, AuthenticationException {
 
         if 
(userProperties.get(authenticationType.getAuthorizationHeaderName()) != null) {
             throw new 
DeploymentException(sm.getString("wsWebSocketContainer.failedAuthentication",
@@ -493,15 +511,14 @@ public class WsWebSocketContainer implements 
WebSocketContainer, BackgroundProce
                     Integer.valueOf(httpResponse.status), authScheme));
         }
 
-        String requestUri = new String(request.array(), 
StandardCharsets.ISO_8859_1).split("\\s", 3)[1];
-
         userProperties.put(authenticationType.getAuthorizationHeaderName(),
-                auth.getAuthorization(requestUri, authenticateHeaders.get(0),
+                auth.getAuthorization(authenticationMethod, authenticationUri, 
authenticateHeaders.get(0),
                         (String) 
userProperties.get(authenticationType.getUserNameProperty()),
                         (String) 
userProperties.get(authenticationType.getUserPasswordProperty()),
                         (String) 
userProperties.get(authenticationType.getUserRealmProperty())));
 
-        return connectToServerRecursive(clientEndpointHolder, 
clientEndpointConfiguration, path, redirectSet);
+        return connectToServerRecursive(clientEndpointHolder, 
clientEndpointConfiguration, serverEndpointUri,
+                redirectSet);
     }
 
 
diff --git a/test/org/apache/tomcat/websocket/TesterWebSocketClientProxy.java 
b/test/org/apache/tomcat/websocket/TesterWebSocketClientProxy.java
index 08e6aca012..3e7b4f1e4e 100644
--- a/test/org/apache/tomcat/websocket/TesterWebSocketClientProxy.java
+++ b/test/org/apache/tomcat/websocket/TesterWebSocketClientProxy.java
@@ -58,11 +58,22 @@ import 
org.apache.tomcat.websocket.TesterMessageCountClient.TesterProgrammaticEn
  *     ProxyVia On
  *     AllowCONNECT 0-65535
  *     <Proxy *>
- *         Order deny,allow
- *         Allow from all
  *         AuthType Basic
  *         AuthName "Proxy Password Required"
- *         AuthUserFile password.file
+ *         AuthUserFile "/etc/apache2/password.file"
+ *         Require valid-user
+ *     </Proxy>
+ * </VirtualHost>
+ *
+ * Listen 8890
+ * <VirtualHost *:8890>
+ *     ProxyRequests On
+ *     ProxyVia On
+ *     AllowCONNECT 0-65535
+ *     <Proxy *>
+ *         AuthType Digest
+ *         AuthName "Proxy Password Required"
+ *         AuthUserFile "/etc/apache2/password-digest.file"
  *         Require valid-user
  *     </Proxy>
  * </VirtualHost>
@@ -71,16 +82,20 @@ import 
org.apache.tomcat.websocket.TesterMessageCountClient.TesterProgrammaticEn
  * # htpasswd -c password.file proxy
  * New Password: proxy-pass
  *
+ * # htdigest -c password-digest.file proxy
+ * New Password: proxy-pass
+ *
  */
 public class TesterWebSocketClientProxy extends WebSocketBaseTest {
 
     private static final String MESSAGE_STRING = "proxy-test-message";
 
-    private static final String PROXY_ADDRESS = "192.168.0.200";
+    private static final String PROXY_ADDRESS = "192.168.23.32";
     private static final String PROXY_PORT_NO_AUTH = "8888";
-    private static final String PROXY_PORT_AUTH = "8889";
+    private static final String PROXY_PORT_BASIC_AUTH = "8889";
+    private static final String PROXY_PORT_DIGEST_AUTH = "8890";
     // The IP address of the test instance that is reachable from the proxy
-    private static final String TOMCAT_ADDRESS = "192.168.0.100";
+    private static final String TOMCAT_ADDRESS = "192.168.23.12";
 
     private static final String TOMCAT_USER = "tomcat";
     private static final String TOMCAT_PASSWORD = "tomcat-pass";
@@ -91,35 +106,49 @@ public class TesterWebSocketClientProxy extends 
WebSocketBaseTest {
 
     @Test
     public void testConnectToServerViaProxyWithNoAuthentication() throws 
Exception {
-        doTestConnectToServerViaProxy(false, false);
+        doTestConnectToServerViaProxy(false, null);
     }
 
 
     @Test
     public void testConnectToServerViaProxyWithServerAuthentication() throws 
Exception {
-        doTestConnectToServerViaProxy(true, false);
+        doTestConnectToServerViaProxy(true, null);
+    }
+
+
+    @Test
+    public void testConnectToServerViaProxyWithProxyBasicAuthentication() 
throws Exception {
+        doTestConnectToServerViaProxy(false, "basic");
+    }
+
+
+    @Test
+    public void 
testConnectToServerViaProxyWithServerAndProxyBasicAuthentication() throws 
Exception {
+        doTestConnectToServerViaProxy(true, "basic");
     }
 
 
     @Test
-    public void testConnectToServerViaProxyWithProxyAuthentication() throws 
Exception {
-        doTestConnectToServerViaProxy(false, true);
+    public void testConnectToServerViaProxyWithProxyDigestAuthentication() 
throws Exception {
+        doTestConnectToServerViaProxy(false, "digest");
     }
 
 
     @Test
-    public void testConnectToServerViaProxyWithServerAndProxyAuthentication() 
throws Exception {
-        doTestConnectToServerViaProxy(true, true);
+    public void 
testConnectToServerViaProxyWithServerAndProxyDigestAuthentication() throws 
Exception {
+        doTestConnectToServerViaProxy(true, "digest");
     }
 
 
-    private void doTestConnectToServerViaProxy(boolean serverAuthentication, 
boolean proxyAuthentication)
+    private void doTestConnectToServerViaProxy(boolean serverAuthentication, 
String proxyAuthentication)
             throws Exception {
 
         // Configure the proxy
         System.setProperty("http.proxyHost", PROXY_ADDRESS);
-        if (proxyAuthentication) {
-            System.setProperty("http.proxyPort", PROXY_PORT_AUTH);
+        if ("basic".equalsIgnoreCase(proxyAuthentication)) {
+            System.setProperty("http.proxyPort", PROXY_PORT_BASIC_AUTH);
+        } else if ("digest".equalsIgnoreCase(proxyAuthentication)) {
+            System.setProperty("http.proxyPort", PROXY_PORT_DIGEST_AUTH);
         } else {
             System.setProperty("http.proxyPort", PROXY_PORT_NO_AUTH);
         }
@@ -166,7 +195,7 @@ public class TesterWebSocketClientProxy extends 
WebSocketBaseTest {
             
clientEndpointConfig.getUserProperties().put(Constants.WS_AUTHENTICATION_USER_NAME,
 TOMCAT_USER);
             
clientEndpointConfig.getUserProperties().put(Constants.WS_AUTHENTICATION_PASSWORD,
 TOMCAT_PASSWORD);
         }
-        if (proxyAuthentication) {
+        if (proxyAuthentication != null) {
             
clientEndpointConfig.getUserProperties().put(Constants.WS_AUTHENTICATION_PROXY_USER_NAME,
 PROXY_USER);
             
clientEndpointConfig.getUserProperties().put(Constants.WS_AUTHENTICATION_PROXY_PASSWORD,
 PROXY_PASSWORD);
         }
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 238e8396f3..f203794787 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -233,6 +233,14 @@
       </fix>
     </changelog>
   </subsection>
+  <subsection name="WebSocket">
+    <changelog>
+      <fix>
+        Fix the initial connection to a WebSocket end point where the 
connection
+        is made via a proxy that requires DIGEST authentication. (markt)
+      </fix>
+    </changelog>
+  </subsection>
   <subsection name="Other">
     <changelog>
       <fix>


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to