You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wink.apache.org by ro...@apache.org on 2010/07/26 20:29:58 UTC

svn commit: r979403 - in /incubator/wink/trunk: wink-client-apache-httpclient/src/test/java/org/apache/wink/client/ wink-client/src/main/java/org/apache/wink/client/handlers/ wink-client/src/test/java/org/apache/wink/client/ wink-client/src/test/java/o...

Author: rott
Date: Mon Jul 26 18:29:58 2010
New Revision: 979403

URL: http://svn.apache.org/viewvc?rev=979403&view=rev
Log:
WINK-292: add ProxyAuthSecurityHandler, refactor auth code, refactor MockHttpServer, add several tests

Added:
    incubator/wink/trunk/wink-client/src/main/java/org/apache/wink/client/handlers/AbstractAuthSecurityHandler.java
    incubator/wink/trunk/wink-client/src/main/java/org/apache/wink/client/handlers/ProxyAuthSecurityHandler.java
    incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/handlers/
    incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/handlers/AuthSecurityHandlerTest.java
Modified:
    incubator/wink/trunk/wink-client-apache-httpclient/src/test/java/org/apache/wink/client/ApacheClientTest.java
    incubator/wink/trunk/wink-client/src/main/java/org/apache/wink/client/handlers/BasicAuthSecurityHandler.java
    incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/ClientAtomTest.java
    incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/ClientTest.java
    incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/ConfigurationTest.java
    incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/EmptyContentTypeTest.java
    incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/HandlersTest.java
    incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/ProvidersTest.java
    incubator/wink/trunk/wink-common/src/main/resources/org/apache/wink/common/internal/i18n/resource.properties
    incubator/wink/trunk/wink-component-test-support/src/main/java/org/apache/wink/client/BaseTest.java
    incubator/wink/trunk/wink-component-test-support/src/main/java/org/apache/wink/client/MockHttpServer.java

Modified: incubator/wink/trunk/wink-client-apache-httpclient/src/test/java/org/apache/wink/client/ApacheClientTest.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-client-apache-httpclient/src/test/java/org/apache/wink/client/ApacheClientTest.java?rev=979403&r1=979402&r2=979403&view=diff
==============================================================================
--- incubator/wink/trunk/wink-client-apache-httpclient/src/test/java/org/apache/wink/client/ApacheClientTest.java (original)
+++ incubator/wink/trunk/wink-client-apache-httpclient/src/test/java/org/apache/wink/client/ApacheClientTest.java Mon Jul 26 18:29:58 2010
@@ -38,6 +38,7 @@ import javax.ws.rs.ext.MessageBodyReader
 import javax.ws.rs.ext.MessageBodyWriter;
 import javax.ws.rs.ext.Provider;
 
+import org.apache.wink.client.MockHttpServer.MockHttpServerResponse;
 import org.apache.wink.common.RuntimeContext;
 import org.apache.wink.common.internal.WinkConfiguration;
 import org.apache.wink.common.internal.runtime.RuntimeContextTLS;
@@ -149,7 +150,13 @@ public class ApacheClientTest extends Ba
     }
 
     public void testResourceGet() {
-        server.setMockResponseCode(200);
+        MockHttpServerResponse response1 = new MockHttpServerResponse();
+        response1.setMockResponseCode(200);
+        MockHttpServerResponse response2 = new MockHttpServerResponse();
+        response2.setMockResponseCode(200);
+        MockHttpServerResponse response3 = new MockHttpServerResponse();
+        response3.setMockResponseCode(200);
+        server.setMockHttpServerResponses(response1, response2, response3);
         RestClient client = getRestClient();
         Resource resource = client.resource(serviceURL);
 
@@ -167,7 +174,13 @@ public class ApacheClientTest extends Ba
     }
 
     public void testResourcePut() throws IOException {
-        server.setMockResponseCode(200);
+        MockHttpServerResponse response1 = new MockHttpServerResponse();
+        response1.setMockResponseCode(200);
+        MockHttpServerResponse response2 = new MockHttpServerResponse();
+        response2.setMockResponseCode(200);
+        MockHttpServerResponse response3 = new MockHttpServerResponse();
+        response3.setMockResponseCode(200);
+        server.setMockHttpServerResponses(response1, response2, response3);
         RestClient client = getRestClient();
         Resource resource = client.resource(serviceURL + "/testResourcePut");
         String response =
@@ -187,7 +200,13 @@ public class ApacheClientTest extends Ba
     }
 
     public void testResourcePost() throws IOException {
-        server.setMockResponseCode(200);
+        MockHttpServerResponse response1 = new MockHttpServerResponse();
+        response1.setMockResponseCode(200);
+        MockHttpServerResponse response2 = new MockHttpServerResponse();
+        response2.setMockResponseCode(200);
+        MockHttpServerResponse response3 = new MockHttpServerResponse();
+        response3.setMockResponseCode(200);
+        server.setMockHttpServerResponses(response1, response2, response3);
         RestClient client = getRestClient();
         Resource resource = client.resource(serviceURL + "/testResourcePost");
         String response =
@@ -207,7 +226,13 @@ public class ApacheClientTest extends Ba
     }
 
     public void testResourceDelete() {
-        server.setMockResponseCode(200);
+        MockHttpServerResponse response1 = new MockHttpServerResponse();
+        response1.setMockResponseCode(200);
+        MockHttpServerResponse response2 = new MockHttpServerResponse();
+        response2.setMockResponseCode(200);
+        MockHttpServerResponse response3 = new MockHttpServerResponse();
+        response3.setMockResponseCode(200);
+        server.setMockHttpServerResponses(response1, response2, response3);
         RestClient client = getRestClient();
         Resource resource = client.resource(serviceURL);
         String response = resource.accept(MediaType.TEXT_PLAIN_TYPE).delete(String.class);
@@ -224,7 +249,11 @@ public class ApacheClientTest extends Ba
     }
 
     public void testInvoke() {
-        server.setMockResponseCode(200);
+        MockHttpServerResponse response1 = new MockHttpServerResponse();
+        response1.setMockResponseCode(200);
+        MockHttpServerResponse response2 = new MockHttpServerResponse();
+        response2.setMockResponseCode(200);
+        server.setMockHttpServerResponses(response1, response2);
         RestClient client = getRestClient();
         Resource resource = client.resource(serviceURL);
 
@@ -238,7 +267,7 @@ public class ApacheClientTest extends Ba
     }
 
     public void testHttpErrorNoResponse() throws IOException {
-        server.setMockResponseCode(400);
+        server.getMockHttpServerResponses().get(0).setMockResponseCode(400);
         RestClient client = getRestClient();
         Resource resource = client.resource(serviceURL);
         try {
@@ -250,7 +279,7 @@ public class ApacheClientTest extends Ba
     }
 
     public void testHttpErrorWithResponse() throws IOException {
-        server.setMockResponseCode(400);
+        server.getMockHttpServerResponses().get(0).setMockResponseCode(400);
         RestClient client = getRestClient();
         Resource resource = client.resource(serviceURL);
         try {
@@ -264,9 +293,9 @@ public class ApacheClientTest extends Ba
     public void testResponseCharset() throws IOException {
 
         MockHttpServer server = new MockHttpServer(34567);
-        server.setMockResponseCode(200);
-        server.setMockResponseContent("REQUEST".getBytes("UTF-16"));
-        server.setMockResponseContentType("text/plain; charset=UTF-16");
+        server.getMockHttpServerResponses().get(0).setMockResponseCode(200);
+        server.getMockHttpServerResponses().get(0).setMockResponseContent("REQUEST".getBytes("UTF-16"));
+        server.getMockHttpServerResponses().get(0).setMockResponseContentType("text/plain; charset=UTF-16");
 
         server.startServer();
         try {

Added: incubator/wink/trunk/wink-client/src/main/java/org/apache/wink/client/handlers/AbstractAuthSecurityHandler.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-client/src/main/java/org/apache/wink/client/handlers/AbstractAuthSecurityHandler.java?rev=979403&view=auto
==============================================================================
--- incubator/wink/trunk/wink-client/src/main/java/org/apache/wink/client/handlers/AbstractAuthSecurityHandler.java (added)
+++ incubator/wink/trunk/wink-client/src/main/java/org/apache/wink/client/handlers/AbstractAuthSecurityHandler.java Mon Jul 26 18:29:58 2010
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *  
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *  
+ */
+package org.apache.wink.client.handlers;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Properties;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class AbstractAuthSecurityHandler {
+
+    private static Logger    logger          =
+        LoggerFactory
+            .getLogger(AbstractAuthSecurityHandler.class);
+    
+    protected volatile String  handlerUsername = null;
+    protected volatile String  handlerPassword = null;
+
+    public AbstractAuthSecurityHandler() {
+        super();
+    }
+    
+    /**
+     * Sets the username to use.
+     * 
+     * @param aUserName the user name
+     */
+    public void setUserName(String aUserName) {
+        logger.trace("Setting the username to {}", aUserName); //$NON-NLS-1$
+        this.handlerUsername = aUserName;
+    }
+
+    /**
+     * Sets the password to use.
+     * 
+     * @param aPassword the password to use
+     */
+    public void setPassword(String aPassword) {
+        logger.trace("Setting the password"); //$NON-NLS-1$
+        this.handlerPassword = aPassword;
+    }
+    
+    protected static String getEncodedString(String userid, String password) {
+        String credential = userid + ":" + password; //$NON-NLS-1$
+        byte[] credBytes = credential.getBytes();
+        byte[] encodedCredBytes =
+            org.apache.commons.codec.binary.Base64.encodeBase64(credBytes, false);
+        // id and password needs to be base64 encoded
+        String credEncodedString = "Basic " + new String(encodedCredBytes); //$NON-NLS-1$
+        return credEncodedString;
+    }
+
+}
\ No newline at end of file

Modified: incubator/wink/trunk/wink-client/src/main/java/org/apache/wink/client/handlers/BasicAuthSecurityHandler.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-client/src/main/java/org/apache/wink/client/handlers/BasicAuthSecurityHandler.java?rev=979403&r1=979402&r2=979403&view=diff
==============================================================================
--- incubator/wink/trunk/wink-client/src/main/java/org/apache/wink/client/handlers/BasicAuthSecurityHandler.java (original)
+++ incubator/wink/trunk/wink-client/src/main/java/org/apache/wink/client/handlers/BasicAuthSecurityHandler.java Mon Jul 26 18:29:58 2010
@@ -19,9 +19,6 @@
  */
 package org.apache.wink.client.handlers;
 
-import javax.ws.rs.core.HttpHeaders;
-
-import org.apache.commons.codec.binary.Base64;
 import org.apache.wink.client.ClientAuthenticationException;
 import org.apache.wink.client.ClientRequest;
 import org.apache.wink.client.ClientResponse;
@@ -30,52 +27,30 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * SecurityHandler for a client to perform http basic auth:
+ * SecurityHandler for a client to perform http basic auth and http proxy auth:
  * <p/>
  * <code>
  * Usage:<br/>
  * ClientConfig config = new ClientConfig();<br/>
- * BasicAuthSecurityHandler basicAuth = new BasicAuthSecurityHandler();<br/>
- * basicAuth.setUserName("user1");<br/>
- * basicAuth.setPassword("password2");<br/>
- * config.handlers(basicAuth);<br/>
+ * BasicAuthSecurityHandler basicAuthSecHandler = new BasicAuthSecurityHandler();
+ * basicAuthSecHandler.setUserName("username");
+ * basicAuthSecHandler.setPassword("password");
+ * config.handlers(basicAuthSecurityHandler);<br/>
  * // create the rest client instance<br/>
  * RestClient client = new RestClient(config);<br/>
  * // create the resource instance to interact with Resource<br/>
  * resource = client.resource("https://localhost:8080/path/to/resource");<br/>
  * </code>
  */
-public class BasicAuthSecurityHandler implements ClientHandler {
+public class BasicAuthSecurityHandler extends AbstractAuthSecurityHandler implements ClientHandler {
 
     private static Logger   logger          =
-                                                LoggerFactory
-                                                    .getLogger(BasicAuthSecurityHandler.class);
-
-    private volatile String handlerUsername = null;
-    private volatile String handlerPassword = null;
-
-    /**
-     * Sets the username to use.
-     * 
-     * @param aUserName the user name
-     */
-    public void setUserName(String aUserName) {
-        logger.trace("Setting the username to {}", aUserName); //$NON-NLS-1$
-        this.handlerUsername = aUserName;
-    }
-
-    /**
-     * Sets the password to use.
-     * 
-     * @param aPassword the password to use
-     */
-    public void setPassword(String aPassword) {
-        logger.trace("Setting the password"); //$NON-NLS-1$
-        this.handlerPassword = aPassword;
-    }
+        LoggerFactory
+        .getLogger(BasicAuthSecurityHandler.class);
 
+    
     /**
-     * Performs basic HTTP authentication.
+     * Performs basic HTTP authentication and proxy authentication, if necessary.
      * 
      * @param client request object
      * @param handler context object
@@ -85,49 +60,35 @@ public class BasicAuthSecurityHandler im
     public ClientResponse handle(ClientRequest request, HandlerContext context) throws Exception {
         logger.trace("Entering BasicAuthSecurityHandler.doChain()"); //$NON-NLS-1$
         ClientResponse response = context.doChain(request);
-
-        int statusCode = response.getStatusCode();
-        logger.trace("Response status code was {}", statusCode); //$NON-NLS-1$
-        if (statusCode != 401) {
-            logger.trace("Status code was not 401 so no need to re-issue request."); //$NON-NLS-1$
-            return response;
-        } else {
-            String userid = handlerUsername;
-            String password = handlerPassword;
-            if (logger.isTraceEnabled()) {
-                logger.trace("The 'username' property was set to: {}", userid); //$NON-NLS-1$
-                logger.trace("Was the 'password' property set: {}", password != null); //$NON-NLS-1$
-            }
-
-            if (!(userid == null || userid.equals("") || password == null || password.equals(""))) { //$NON-NLS-1$ //$NON-NLS-2$
+        if (response.getStatusCode() == 401) {
+            
+            if (!(handlerUsername == null || handlerUsername.equals("") || handlerPassword == null || handlerPassword.equals(""))) { //$NON-NLS-1$ //$NON-NLS-2$
                 logger.trace("userid and password set so setting Authorization header"); //$NON-NLS-1$
                 // we have a user credential
-                String credential = userid + ":" + password; //$NON-NLS-1$
-                byte[] credBytes = credential.getBytes();
-                byte[] encodedCredBytes = Base64.encodeBase64(credBytes, false);
-                // id and password needs to be base64 encoded
-                String credEncodedString = "Basic " + new String(encodedCredBytes); //$NON-NLS-1$
-                request.getHeaders().putSingle(HttpHeaders.AUTHORIZATION, credEncodedString);
+                request.getHeaders().putSingle("Authorization", getEncodedString(handlerUsername, handlerPassword)); //$NON-NLS-1$
                 logger.trace("Issuing request again with Authorization header"); //$NON-NLS-1$
                 response = context.doChain(request);
                 if (response.getStatusCode() == 401) {
                     logger
-                        .trace("After sending request with Authorization header, still got 401 response"); //$NON-NLS-1$
+                    .trace("After sending request with Authorization header, still got 401 response"); //$NON-NLS-1$
                     throw new ClientAuthenticationException(Messages
-                        .getMessage("serviceFailedToAuthenticateUser", userid)); //$NON-NLS-1$
+                            .getMessage("serviceFailedToAuthenticateUser", handlerUsername)); //$NON-NLS-1$
                 } else {
                     logger.trace("Got a non-401 response, so returning response"); //$NON-NLS-1$
                     return response;
                 }
             } else {
-                logger.trace("userid and/or password were not set so throwing exception"); //$NON-NLS-1$
+                logger.trace("user and/or password were not set so throwing exception"); //$NON-NLS-1$
                 // no user credential available
                 throw new ClientAuthenticationException(Messages
-                    .getMessage("missingClientAuthenticationCredentialForUser", userid)); //$NON-NLS-1$
+                        .getMessage("missingClientAuthenticationCredentialForUser", handlerUsername)); //$NON-NLS-1$
             }
+        } else {
+            logger.trace("Status code was not 401 so no need to re-issue request."); //$NON-NLS-1$
+            return response;
+        }
 
-        } // end if block
-    } // end handle
+    }
 
-} // end class SecurityHandler
+}
 

Added: incubator/wink/trunk/wink-client/src/main/java/org/apache/wink/client/handlers/ProxyAuthSecurityHandler.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-client/src/main/java/org/apache/wink/client/handlers/ProxyAuthSecurityHandler.java?rev=979403&view=auto
==============================================================================
--- incubator/wink/trunk/wink-client/src/main/java/org/apache/wink/client/handlers/ProxyAuthSecurityHandler.java (added)
+++ incubator/wink/trunk/wink-client/src/main/java/org/apache/wink/client/handlers/ProxyAuthSecurityHandler.java Mon Jul 26 18:29:58 2010
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *  
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *  
+ */
+package org.apache.wink.client.handlers;
+
+import org.apache.wink.client.ClientAuthenticationException;
+import org.apache.wink.client.ClientRequest;
+import org.apache.wink.client.ClientResponse;
+import org.apache.wink.common.internal.i18n.Messages;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * SecurityHandler for a client to perform http proxy auth:
+ * <p/>
+ * <code>
+ * Usage:<br/>
+ * ClientConfig config = new ClientConfig();<br/>
+ * ProxyAuthSecurityHandler proxyAuthSecHandler = new ProxyAuthSecurityHandler();
+ * proxyAuthSecHandler.setProxyUserName("username");
+ * proxyAuthSecHandler.setProxyPassword("password");
+ * config.handlers(proxyAuthSecurityHandler);<br/>
+ * // create the rest client instance<br/>
+ * RestClient client = new RestClient(config);<br/>
+ * // create the resource instance to interact with Resource<br/>
+ * resource = client.resource("http://localhost:8080/path/to/resource");<br/>
+ * </code>
+ */
+public class ProxyAuthSecurityHandler extends AbstractAuthSecurityHandler implements ClientHandler {
+
+    private static Logger    logger          =
+                                                 LoggerFactory
+                                                     .getLogger(ProxyAuthSecurityHandler.class);
+
+    
+    /**
+     * Performs basic HTTP authentication and proxy authentication, if necessary.
+     * 
+     * @param client request object
+     * @param handler context object
+     * @return a client response object that may contain an HTTP Authorization
+     *         header
+     */
+    public ClientResponse handle(ClientRequest request, HandlerContext context) throws Exception {
+        logger.trace("Entering ProxyAuthSecurityHandler.doChain()"); //$NON-NLS-1$
+        ClientResponse response = context.doChain(request);
+        if (response.getStatusCode() == 407) {  // got a proxy auth challenge
+            
+            if (!(handlerUsername == null || handlerUsername.equals("") || handlerPassword == null || handlerPassword.equals(""))) { //$NON-NLS-1$ //$NON-NLS-2$
+                logger.trace("userid and password set so setting Proxy-Authorization header"); //$NON-NLS-1$
+                // we have a user credential
+                request.getHeaders().putSingle("Proxy-Connection", "Keep-Alive"); //$NON-NLS-1$ $NON-NLS-2$
+                request.getHeaders().putSingle("Proxy-Authorization", getEncodedString(handlerUsername, handlerPassword)); //$NON-NLS-1$
+                logger.trace("Issuing request again with Proxy-Authorization header"); //$NON-NLS-1$
+                response = context.doChain(request);
+                if (response.getStatusCode() == 407) {
+                    logger
+                    .trace("After sending request with Proxy-Authorization header, still got 407 response"); //$NON-NLS-1$
+                    throw new ClientAuthenticationException(Messages
+                            .getMessage("serviceFailedToAuthenticateProxyUser", handlerUsername)); //$NON-NLS-1$
+                } else {
+                    logger.trace("Got a non-407 response, so returning response"); //$NON-NLS-1$
+                    return response;
+                }
+            } else {
+                logger.trace("proxy user and/or proxy password were not set so throwing exception"); //$NON-NLS-1$
+                // no proxy user credential available
+                throw new ClientAuthenticationException(Messages
+                        .getMessage("missingClientAuthenticationCredentialForProxyUser", handlerUsername)); //$NON-NLS-1$
+            }
+        } else {  // did NOT get a proxy auth challenge
+            logger.trace("Status code was not 407 so no need to re-issue request."); //$NON-NLS-1$
+            return response;
+        }
+
+    }
+
+    
+}
+

Modified: incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/ClientAtomTest.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/ClientAtomTest.java?rev=979403&r1=979402&r2=979403&view=diff
==============================================================================
--- incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/ClientAtomTest.java (original)
+++ incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/ClientAtomTest.java Mon Jul 26 18:29:58 2010
@@ -113,9 +113,9 @@ public class ClientAtomTest extends Base
     "</entry>";
     
     public void testAtomContentRetrievalFromAtomEntry() {
-        server.setMockResponseCode(200);
-        server.setMockResponseContentType(MediaType.APPLICATION_ATOM_XML);
-        server.setMockResponseContent(responseString);
+        server.getMockHttpServerResponses().get(0).setMockResponseCode(200);
+        server.getMockHttpServerResponses().get(0).setMockResponseContentType(MediaType.APPLICATION_ATOM_XML);
+        server.getMockHttpServerResponses().get(0).setMockResponseContent(responseString);
         RestClient client = getRestClient();
         Resource resource = client.resource(serviceURL + "/atomresource/entry");
         
@@ -134,9 +134,9 @@ public class ClientAtomTest extends Base
     }
     
     public void testAtomContentRetrievalFromSyndEntry() {
-        server.setMockResponseCode(200);
-        server.setMockResponseContentType(MediaType.APPLICATION_ATOM_XML);
-        server.setMockResponseContent(responseString);
+        server.getMockHttpServerResponses().get(0).setMockResponseCode(200);
+        server.getMockHttpServerResponses().get(0).setMockResponseContentType(MediaType.APPLICATION_ATOM_XML);
+        server.getMockHttpServerResponses().get(0).setMockResponseContent(responseString);
         RestClient client = getRestClient();
         Resource resource = client.resource(serviceURL + "/atomresource/entry");
         

Modified: incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/ClientTest.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/ClientTest.java?rev=979403&r1=979402&r2=979403&view=diff
==============================================================================
--- incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/ClientTest.java (original)
+++ incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/ClientTest.java Mon Jul 26 18:29:58 2010
@@ -39,6 +39,7 @@ import javax.ws.rs.ext.MessageBodyReader
 import javax.ws.rs.ext.MessageBodyWriter;
 import javax.ws.rs.ext.Provider;
 
+import org.apache.wink.client.MockHttpServer.MockHttpServerResponse;
 import org.apache.wink.common.utils.ProviderUtils;
 
 public class ClientTest extends BaseTest {
@@ -57,6 +58,7 @@ public class ClientTest extends BaseTest
             this.t = t;
         }
     }
+    
 
     @Provider
     public static class TestGenericsProvider implements MessageBodyWriter<TestGenerics<String>>,
@@ -128,7 +130,13 @@ public class ClientTest extends BaseTest
     }
 
     public void testResourceGet() {
-        server.setMockResponseCode(200);
+        MockHttpServerResponse response1 = new MockHttpServerResponse();
+        response1.setMockResponseCode(200);
+        MockHttpServerResponse response2 = new MockHttpServerResponse();
+        response2.setMockResponseCode(200);
+        MockHttpServerResponse response3 = new MockHttpServerResponse();
+        response3.setMockResponseCode(200);
+        server.setMockHttpServerResponses(response1, response2, response3);
         RestClient client = getRestClient();
         Resource resource = client.resource(serviceURL);
 
@@ -149,7 +157,13 @@ public class ClientTest extends BaseTest
     }
 
     public void testResourcePut() throws IOException {
-        server.setMockResponseCode(200);
+        MockHttpServerResponse response1 = new MockHttpServerResponse();
+        response1.setMockResponseCode(200);
+        MockHttpServerResponse response2 = new MockHttpServerResponse();
+        response2.setMockResponseCode(200);
+        MockHttpServerResponse response3 = new MockHttpServerResponse();
+        response3.setMockResponseCode(200);
+        server.setMockHttpServerResponses(response1, response2, response3);
         RestClient client = getRestClient();
         Resource resource = client.resource(serviceURL + "/testResourcePut");
         String response =
@@ -172,7 +186,13 @@ public class ClientTest extends BaseTest
     }
 
     public void testResourcePost() throws IOException {
-        server.setMockResponseCode(200);
+        MockHttpServerResponse response1 = new MockHttpServerResponse();
+        response1.setMockResponseCode(200);
+        MockHttpServerResponse response2 = new MockHttpServerResponse();
+        response2.setMockResponseCode(200);
+        MockHttpServerResponse response3 = new MockHttpServerResponse();
+        response3.setMockResponseCode(200);
+        server.setMockHttpServerResponses(response1, response2, response3);
         RestClient client = getRestClient();
         Resource resource = client.resource(serviceURL + "/testResourcePost");
         String response =
@@ -196,7 +216,13 @@ public class ClientTest extends BaseTest
     }
 
     public void testResourceDelete() {
-        server.setMockResponseCode(200);
+        MockHttpServerResponse response1 = new MockHttpServerResponse();
+        response1.setMockResponseCode(200);
+        MockHttpServerResponse response2 = new MockHttpServerResponse();
+        response2.setMockResponseCode(200);
+        MockHttpServerResponse response3 = new MockHttpServerResponse();
+        response3.setMockResponseCode(200);
+        server.setMockHttpServerResponses(response1, response2, response3);
         RestClient client = getRestClient();
         Resource resource = client.resource(serviceURL);
         String response = resource.accept(MediaType.TEXT_PLAIN_TYPE).delete(String.class);
@@ -217,7 +243,11 @@ public class ClientTest extends BaseTest
     }
 
     public void testInvoke() {
-        server.setMockResponseCode(200);
+        MockHttpServerResponse response1 = new MockHttpServerResponse();
+        response1.setMockResponseCode(200);
+        MockHttpServerResponse response2 = new MockHttpServerResponse();
+        response2.setMockResponseCode(200);
+        server.setMockHttpServerResponses(response1, response2);
         RestClient client = getRestClient();
         Resource resource = client.resource(serviceURL);
 
@@ -231,7 +261,7 @@ public class ClientTest extends BaseTest
     }
 
     public void testHttpErrorNoResponse() throws IOException {
-        server.setMockResponseCode(400);
+        server.getMockHttpServerResponses().get(0).setMockResponseCode(400);
         RestClient client = getRestClient();
         Resource resource = client.resource(serviceURL);
         try {
@@ -243,7 +273,7 @@ public class ClientTest extends BaseTest
     }
 
     public void testHttpErrorWithResponse() throws IOException {
-        server.setMockResponseCode(400);
+        server.getMockHttpServerResponses().get(0).setMockResponseCode(400);
         RestClient client = getRestClient();
         Resource resource = client.resource(serviceURL);
         try {
@@ -261,9 +291,9 @@ public class ClientTest extends BaseTest
     public void testResponseCharset() throws IOException {
 
         MockHttpServer server = new MockHttpServer(34567);
-        server.setMockResponseCode(200);
-        server.setMockResponseContent("REQUEST".getBytes("UTF-16"));
-        server.setMockResponseContentType("text/plain; charset=UTF-16");
+        server.getMockHttpServerResponses().get(0).setMockResponseCode(200);
+        server.getMockHttpServerResponses().get(0).setMockResponseContent("REQUEST".getBytes("UTF-16"));
+        server.getMockHttpServerResponses().get(0).setMockResponseContentType("text/plain; charset=UTF-16");
 
         server.startServer();
         try {
@@ -281,9 +311,9 @@ public class ClientTest extends BaseTest
 
     public void testResponseEmptyContentType() throws IOException {
         MockHttpServer server = new MockHttpServer(34567);
-        server.setMockResponseCode(200);
-        server.setMockResponseContent("REQUEST".getBytes("UTF-8"));
-        server.setMockResponseContentType("");
+        server.getMockHttpServerResponses().get(0).setMockResponseCode(200);
+        server.getMockHttpServerResponses().get(0).setMockResponseContent("REQUEST".getBytes("UTF-8"));
+        server.getMockHttpServerResponses().get(0).setMockResponseContentType("");
 
         server.startServer();
         try {
@@ -297,4 +327,5 @@ public class ClientTest extends BaseTest
             server.stopServer();
         }
     }
+    
 }

Modified: incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/ConfigurationTest.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/ConfigurationTest.java?rev=979403&r1=979402&r2=979403&view=diff
==============================================================================
--- incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/ConfigurationTest.java (original)
+++ incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/ConfigurationTest.java Mon Jul 26 18:29:58 2010
@@ -126,7 +126,7 @@ public class ConfigurationTest extends B
         // if we specify the server port as the proxy port, we in essence test
         // that the connection is going through the proxy, because we
         // specify a different port for the server in the resource URL
-        server.setMockResponseCode(200);
+        server.getMockHttpServerResponses().get(0).setMockResponseCode(200);
         ClientConfig config = new ClientConfig();
         config.proxyHost("localhost").proxyPort(serverPort);
         RestClient client = new RestClient(config);
@@ -165,7 +165,7 @@ public class ConfigurationTest extends B
     }
 
     public void testReadTimeout() {
-        server.setMockResponseCode(200);
+        server.getMockHttpServerResponses().get(0).setMockResponseCode(200);
         // set the server to delay the response by 5 seconds.
         server.setDelayResponse(5000);
 
@@ -197,7 +197,7 @@ public class ConfigurationTest extends B
     }
 
     public void testApplication() {
-        server.setMockResponseCode(200);
+        server.getMockHttpServerResponses().get(0).setMockResponseCode(200);
         server.setDelayResponse(0);
         ClientConfig conf = new ClientConfig();
 

Modified: incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/EmptyContentTypeTest.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/EmptyContentTypeTest.java?rev=979403&r1=979402&r2=979403&view=diff
==============================================================================
--- incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/EmptyContentTypeTest.java (original)
+++ incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/EmptyContentTypeTest.java Mon Jul 26 18:29:58 2010
@@ -91,7 +91,7 @@ public class EmptyContentTypeTest extend
     }
     
     public void testEmptyContentType() throws Exception {
-        server.setMockResponseCode(200);
+        server.getMockHttpServerResponses().get(0).setMockResponseCode(200);
         RestClient client = getRestClient();
         client.resource(serviceURL + "/integer").put(123);
         byte[] b = server.getRequestContent();

Modified: incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/HandlersTest.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/HandlersTest.java?rev=979403&r1=979402&r2=979403&view=diff
==============================================================================
--- incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/HandlersTest.java (original)
+++ incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/HandlersTest.java Mon Jul 26 18:29:58 2010
@@ -38,8 +38,8 @@ public class HandlersTest extends BaseTe
     private static final String DUMMY_RESPONSE_HEADER = "Dummy-Response-Header";
 
     public void testHandlers() {
-        server.setMockResponseCode(200);
-        server.setMockResponseContent(SENT_MESSAGE);
+        server.getMockHttpServerResponses().get(0).setMockResponseCode(200);
+        server.getMockHttpServerResponses().get(0).setMockResponseContent(SENT_MESSAGE);
 
         ClientConfig config = new ClientConfig();
         config.handlers(new DummyHandler());

Modified: incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/ProvidersTest.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/ProvidersTest.java?rev=979403&r1=979402&r2=979403&view=diff
==============================================================================
--- incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/ProvidersTest.java (original)
+++ incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/ProvidersTest.java Mon Jul 26 18:29:58 2010
@@ -126,9 +126,9 @@ public class ProvidersTest extends TestC
 
     public void testAtomFeedReadWrite() throws Exception {
         MockHttpServer server = new MockHttpServer(SERVER_PORT);
-        server.setMockResponseCode(200);
-        server.setMockResponseContentEchoRequest(true);
-        server.setMockResponseContentType(MediaType.APPLICATION_ATOM_XML);
+        server.getMockHttpServerResponses().get(0).setMockResponseCode(200);
+        server.getMockHttpServerResponses().get(0).setMockResponseContentEchoRequest(true);
+        server.getMockHttpServerResponses().get(0).setMockResponseContentType(MediaType.APPLICATION_ATOM_XML);
         server.startServer();
         try {
             RestClient client = new RestClient();

Added: incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/handlers/AuthSecurityHandlerTest.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/handlers/AuthSecurityHandlerTest.java?rev=979403&view=auto
==============================================================================
--- incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/handlers/AuthSecurityHandlerTest.java (added)
+++ incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/handlers/AuthSecurityHandlerTest.java Mon Jul 26 18:29:58 2010
@@ -0,0 +1,301 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *  
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *  
+ */
+package org.apache.wink.client.handlers;
+
+import org.apache.wink.client.BaseTest;
+import org.apache.wink.client.ClientAuthenticationException;
+import org.apache.wink.client.ClientConfig;
+import org.apache.wink.client.ClientResponse;
+import org.apache.wink.client.MockHttpServer;
+import org.apache.wink.client.Resource;
+import org.apache.wink.client.RestClient;
+
+public class AuthSecurityHandlerTest extends BaseTest {
+    
+    /*
+     * API TESTS
+     */
+    
+    // basic auth handler should throw exception when challenged but no username is set
+    public void testNoUserNameBasicAuthFailure() throws Exception {
+        server.getMockHttpServerResponses().get(0).setMockResponseCode(401);
+        ClientConfig config = new ClientConfig();
+        BasicAuthSecurityHandler basicAuthSecurityHandler = new BasicAuthSecurityHandler();
+        // oops, forgot to set username!
+        basicAuthSecurityHandler.setPassword("password");
+        config.handlers(basicAuthSecurityHandler);
+        RestClient client = new RestClient(config);
+        Resource resource = client.resource(serviceURL);
+        try {
+            @SuppressWarnings("unused")
+            ClientResponse response = resource.get();
+            fail("should have got a ClientAuthenticationException");
+        } catch (ClientAuthenticationException e) {
+            // do nothing
+        }
+    }
+    
+    // basic auth handler should throw exception when challenged but no password is set
+    public void testNoPasswordBasicAuthFailure() throws Exception {
+        server.getMockHttpServerResponses().get(0).setMockResponseCode(401);
+        ClientConfig config = new ClientConfig();
+        BasicAuthSecurityHandler basicAuthSecurityHandler = new BasicAuthSecurityHandler();
+        basicAuthSecurityHandler.setUserName("username");
+        // oops, forgot to set password!
+        config.handlers(basicAuthSecurityHandler);
+        RestClient client = new RestClient(config);
+        Resource resource = client.resource(serviceURL);
+        try {
+            @SuppressWarnings("unused")
+            ClientResponse response = resource.get();
+            fail("should have got a ClientAuthenticationException");
+        } catch (ClientAuthenticationException e) {
+            // do nothing
+        }
+    }
+    
+    // basic auth handler should flow through when NOT challenged but no username is set
+    public void testNoUserNameBasicAuthAllowed() throws Exception {
+        server.getMockHttpServerResponses().get(0).setMockResponseCode(200);
+        ClientConfig config = new ClientConfig();
+        BasicAuthSecurityHandler basicAuthSecurityHandler = new BasicAuthSecurityHandler();
+        // oops, forgot to set username!
+        basicAuthSecurityHandler.setPassword("password");
+        config.handlers(basicAuthSecurityHandler);
+        RestClient client = new RestClient(config);
+        Resource resource = client.resource(serviceURL);
+        ClientResponse response = resource.get();
+        assertEquals(200, response.getStatusCode());
+    }
+    
+    // proxy auth handler should throw exception when challenged but no username is set
+    public void testNoUserNameProxyAuthFailure() throws Exception {
+        server.getMockHttpServerResponses().get(0).setMockResponseCode(407);
+        ClientConfig config = new ClientConfig();
+        ProxyAuthSecurityHandler proxyAuthSecurityHandler = new ProxyAuthSecurityHandler();
+        // oops, forgot to set username!
+        proxyAuthSecurityHandler.setPassword("password");
+        config.handlers(proxyAuthSecurityHandler);
+        RestClient client = new RestClient(config);
+        Resource resource = client.resource(serviceURL);
+        try {
+            @SuppressWarnings("unused")
+            ClientResponse response = resource.get();
+            fail("should have got a ClientAuthenticationException");
+        } catch (ClientAuthenticationException e) {
+            // do nothing
+        }
+    }
+    
+    // proxy auth handler should throw exception when challenged but no password is set
+    public void testNoPasswordProxyAuthFailure() throws Exception {
+        server.getMockHttpServerResponses().get(0).setMockResponseCode(407);
+        ClientConfig config = new ClientConfig();
+        ProxyAuthSecurityHandler proxyAuthSecurityHandler = new ProxyAuthSecurityHandler();
+        proxyAuthSecurityHandler.setUserName("username");
+        // oops, forgot to set password!
+        config.handlers(proxyAuthSecurityHandler);
+        RestClient client = new RestClient(config);
+        Resource resource = client.resource(serviceURL);
+        try {
+            @SuppressWarnings("unused")
+            ClientResponse response = resource.get();
+            fail("should have got a ClientAuthenticationException");
+        } catch (ClientAuthenticationException e) {
+            // do nothing
+        }
+    }
+    
+    // proxy auth handler should flow through when NOT challenged but no username is set
+    public void testNoUserNameProxyAuthAllowed() throws Exception {
+        server.getMockHttpServerResponses().get(0).setMockResponseCode(200);
+        ClientConfig config = new ClientConfig();
+        ProxyAuthSecurityHandler proxyAuthSecurityHandler = new ProxyAuthSecurityHandler();
+        // oops, forgot to set username!
+        proxyAuthSecurityHandler.setPassword("password");
+        config.handlers(proxyAuthSecurityHandler);
+        RestClient client = new RestClient(config);
+        Resource resource = client.resource(serviceURL);
+        ClientResponse response = resource.get();
+        assertEquals(200, response.getStatusCode());
+    }
+    
+    /*
+     * BASIC AUTH
+     */
+    
+    public void testNoBasicAuthHandler() throws Exception {
+        server.getMockHttpServerResponses().get(0).setMockResponseCode(401);
+        RestClient client = new RestClient(new ClientConfig());
+        Resource resource = client.resource(serviceURL);
+        ClientResponse response = resource.get();
+        assertEquals(401, response.getStatusCode());  // should have challenged us due to lack of credentials
+    }
+    
+    public void testBasicAuthHandlerNoAuthRequired() throws Exception {
+        // try with BasicAuthSecurityHandler, but return 200 from server for first response; BasicAuthSecurityHandler should allow flow through
+        server.getMockHttpServerResponses().get(0).setMockResponseCode(200);
+        ClientConfig config = new ClientConfig();
+        BasicAuthSecurityHandler basicAuthSecurityHandler = new BasicAuthSecurityHandler();
+        basicAuthSecurityHandler.setUserName("username");
+        basicAuthSecurityHandler.setPassword("password");
+        config.handlers(basicAuthSecurityHandler);
+        RestClient client = new RestClient(config);
+        Resource resource = client.resource(serviceURL);
+        ClientResponse response = resource.get();
+        assertEquals(200, response.getStatusCode());
+    }
+
+    public void testBasicAuthHandlerAuthDenied() throws Exception {
+        // try with BasicAuthSecurityHandler, but still return 401 from server for both first and second responses
+        MockHttpServer.MockHttpServerResponse response1 = new MockHttpServer.MockHttpServerResponse();
+        response1.setMockResponseCode(401);
+        MockHttpServer.MockHttpServerResponse response2 = new MockHttpServer.MockHttpServerResponse();
+        response2.setMockResponseCode(401);
+        server.setMockHttpServerResponses(response1, response2);
+        ClientConfig config = new ClientConfig();
+        BasicAuthSecurityHandler basicAuthSecurityHandler = new BasicAuthSecurityHandler();
+        basicAuthSecurityHandler.setUserName("username");
+        basicAuthSecurityHandler.setPassword("password");
+        config.handlers(basicAuthSecurityHandler);
+        RestClient client = new RestClient(config);
+        Resource resource = client.resource(serviceURL);
+        try {
+            @SuppressWarnings("unused")
+            ClientResponse response = resource.get();
+            fail("should have got a ClientAuthenticationException");
+        } catch (ClientAuthenticationException e) {
+            // do nothing
+        }
+    }
+    
+    public void testBasicAuthHandlerAuthGranted() throws Exception {
+        // try again with BasicAuthSecurityHandler, but now return 200 from server on the second response
+        MockHttpServer.MockHttpServerResponse response1 = new MockHttpServer.MockHttpServerResponse();
+        response1.setMockResponseCode(401);
+        MockHttpServer.MockHttpServerResponse response2 = new MockHttpServer.MockHttpServerResponse();
+        response2.setMockResponseCode(200);
+        server.setMockHttpServerResponses(response1, response2);
+        ClientConfig config = new ClientConfig();
+        BasicAuthSecurityHandler basicAuthSecurityHandler = new BasicAuthSecurityHandler();
+        basicAuthSecurityHandler.setUserName("username");
+        basicAuthSecurityHandler.setPassword("password");
+        config.handlers(basicAuthSecurityHandler);
+        RestClient client = new RestClient(config);
+        Resource resource = client.resource(serviceURL);
+        ClientResponse response = resource.get();
+        assertEquals(200, response.getStatusCode());
+    }
+    
+    /*
+     * PROXY AUTH
+     */
+    
+    public void testNoProxyAuthHandler() throws Exception {
+        server.getMockHttpServerResponses().get(0).setMockResponseCode(407);
+        RestClient client = new RestClient(new ClientConfig());
+        Resource resource = client.resource(serviceURL);
+        ClientResponse response = resource.get();
+        assertEquals(407, response.getStatusCode());  // should have challenged us due to lack of credentials
+    }
+    
+    public void testProxyAuthHandlerNoAuthRequired() throws Exception {
+        // try with ProxyAuthSecurityHandler, but return 200 from server for first response; ProxyAuthSecurityHandler should allow flow through
+        server.getMockHttpServerResponses().get(0).setMockResponseCode(200);
+        ClientConfig config = new ClientConfig();
+        ProxyAuthSecurityHandler proxyAuthSecurityHandler = new ProxyAuthSecurityHandler();
+        proxyAuthSecurityHandler.setUserName("username");
+        proxyAuthSecurityHandler.setPassword("password");
+        config.handlers(proxyAuthSecurityHandler);
+        RestClient client = new RestClient(config);
+        Resource resource = client.resource(serviceURL);
+        ClientResponse response = resource.get();
+        assertEquals(200, response.getStatusCode());
+    }
+
+    public void testProxyAuthHandlerAuthDenied() throws Exception {
+        // try with ProxyAuthSecurityHandler, but still return 407 from server for both first and second responses
+        MockHttpServer.MockHttpServerResponse response1 = new MockHttpServer.MockHttpServerResponse();
+        response1.setMockResponseCode(407);
+        MockHttpServer.MockHttpServerResponse response2 = new MockHttpServer.MockHttpServerResponse();
+        response2.setMockResponseCode(407);
+        server.setMockHttpServerResponses(response1, response2);
+        ClientConfig config = new ClientConfig();
+        ProxyAuthSecurityHandler proxyAuthSecurityHandler = new ProxyAuthSecurityHandler();
+        proxyAuthSecurityHandler.setUserName("username");
+        proxyAuthSecurityHandler.setPassword("password");
+        config.handlers(proxyAuthSecurityHandler);
+        RestClient client = new RestClient(config);
+        Resource resource = client.resource(serviceURL);
+        try {
+            @SuppressWarnings("unused")
+            ClientResponse response = resource.get();
+            fail("should have got a ClientAuthenticationException");
+        } catch (ClientAuthenticationException e) {
+            // do nothing
+        }
+    }
+    
+    public void testProxyAuthHandlerAuthGranted() throws Exception {
+        // try again with ProxyAuthSecurityHandler, but now return 200 from server on the second response
+        MockHttpServer.MockHttpServerResponse response1 = new MockHttpServer.MockHttpServerResponse();
+        response1.setMockResponseCode(407);
+        MockHttpServer.MockHttpServerResponse response2 = new MockHttpServer.MockHttpServerResponse();
+        response2.setMockResponseCode(200);
+        server.setMockHttpServerResponses(response1, response2);
+        ClientConfig config = new ClientConfig();
+        ProxyAuthSecurityHandler proxyAuthSecurityHandler = new ProxyAuthSecurityHandler();
+        proxyAuthSecurityHandler.setUserName("username");
+        proxyAuthSecurityHandler.setPassword("password");
+        config.handlers(proxyAuthSecurityHandler);
+        RestClient client = new RestClient(config);
+        Resource resource = client.resource(serviceURL);
+        ClientResponse response = resource.get();
+        assertEquals(200, response.getStatusCode());
+    }
+    
+    /*
+     * BOTH PROXY AND BASIC
+     */
+    
+    public void testProxyAndBasicAuthHandlerAuthGranted() throws Exception {
+        // try again with ProxyAuthSecurityHandler and BasicAuthSecurityHandler, return 407, then 401, then 200
+        MockHttpServer.MockHttpServerResponse response1 = new MockHttpServer.MockHttpServerResponse();
+        response1.setMockResponseCode(407);
+        MockHttpServer.MockHttpServerResponse response2 = new MockHttpServer.MockHttpServerResponse();
+        response2.setMockResponseCode(401);
+        MockHttpServer.MockHttpServerResponse response3 = new MockHttpServer.MockHttpServerResponse();
+        response3.setMockResponseCode(200);
+        server.setMockHttpServerResponses(response1, response2, response3);
+        ClientConfig config = new ClientConfig();
+        BasicAuthSecurityHandler basicAuthSecurityHandler = new BasicAuthSecurityHandler();
+        basicAuthSecurityHandler.setUserName("basicuser");
+        basicAuthSecurityHandler.setPassword("basicpassword");
+        ProxyAuthSecurityHandler proxyAuthSecurityHandler = new ProxyAuthSecurityHandler();
+        proxyAuthSecurityHandler.setUserName("username");
+        proxyAuthSecurityHandler.setPassword("password");
+        config.handlers(proxyAuthSecurityHandler, basicAuthSecurityHandler);  // proxy first, then basic, of course
+        RestClient client = new RestClient(config);
+        Resource resource = client.resource(serviceURL);
+        ClientResponse response = resource.get();
+        assertEquals(200, response.getStatusCode());
+    }
+    
+}

Modified: incubator/wink/trunk/wink-common/src/main/resources/org/apache/wink/common/internal/i18n/resource.properties
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/resources/org/apache/wink/common/internal/i18n/resource.properties?rev=979403&r1=979402&r2=979403&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/resources/org/apache/wink/common/internal/i18n/resource.properties (original)
+++ incubator/wink/trunk/wink-common/src/main/resources/org/apache/wink/common/internal/i18n/resource.properties Mon Jul 26 18:29:58 2010
@@ -204,7 +204,9 @@ listOperatorMustHaveOnlyOneVariable=The 
 suffixOperatorMustOnlyHaveOneVariable=The suffix operator must have only one variable.
 prefixOperatorMustHaveOnlyOneVariable=The prefix operator must have only one variable.
 missingClientAuthenticationCredentialForUser=The client authentication is missing a credential for user: {0}
+missingClientAuthenticationCredentialForProxyUser=The client authentication is missing a credential for proxy user: {0}
 serviceFailedToAuthenticateUser=The service failed to authenticate user: {0}
+serviceFailedToAuthenticateProxyUser=The proxy failed to authenticate proxy user: {0}
 providerShouldBeAnnotatedDirectly=The @javax.ws.rs.ext.Provider annotation was found on a superclass or interface on the {0} class.  Annotate @javax.ws.rs.ext.Provider on the provider class directly to ensure portability between environments.
 rootResourceShouldBeAnnotatedDirectly=The @javax.ws.rs.Path annotation was found on a superclass or interface on the {0} class.  Annotate @javax.ws.rs.Path on the root resource class directly to ensure portability between environments.
 providerIsInterfaceOrAbstract=A @javax.ws.rs.ext.Provider annotation was found on {0} which is an interface or an abstract class and is being ignored. Annotate @javax.ws.rs.ext.Provider on the provider implementation or base class directly and return that in your javax.ws.rs.core.Application subclass.

Modified: incubator/wink/trunk/wink-component-test-support/src/main/java/org/apache/wink/client/BaseTest.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-component-test-support/src/main/java/org/apache/wink/client/BaseTest.java?rev=979403&r1=979402&r2=979403&view=diff
==============================================================================
--- incubator/wink/trunk/wink-component-test-support/src/main/java/org/apache/wink/client/BaseTest.java (original)
+++ incubator/wink/trunk/wink-component-test-support/src/main/java/org/apache/wink/client/BaseTest.java Mon Jul 26 18:29:58 2010
@@ -24,6 +24,8 @@ import java.util.Map;
 
 import junit.framework.TestCase;
 
+import org.apache.wink.client.MockHttpServer.MockHttpServerResponse;
+
 public abstract class BaseTest extends TestCase {
 
     public static String  SERVICE_URL      = "http://localhost:{0}/some/service";
@@ -51,8 +53,11 @@ public abstract class BaseTest extends T
     private MockHttpServer startMockHttpServer() {
         MockHttpServer server = new MockHttpServer(34567);
         serverPort = server.getServerPort();
-        server.setMockResponseContent(RECEIVED_MESSAGE);
-        server.setMockResponseHeaders(getMockResponseHeaders());
+        // set a default response, which can be overridden by client test code using setHttpServerResponses method
+        MockHttpServerResponse defaultResponse = new MockHttpServerResponse();
+        defaultResponse.setMockResponseContent(RECEIVED_MESSAGE);
+        defaultResponse.setMockResponseHeaders(getMockResponseHeaders());
+        server.setMockHttpServerResponses(defaultResponse);
         server.startServer();
         return server;
     }

Modified: incubator/wink/trunk/wink-component-test-support/src/main/java/org/apache/wink/client/MockHttpServer.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-component-test-support/src/main/java/org/apache/wink/client/MockHttpServer.java?rev=979403&r1=979402&r2=979403&view=diff
==============================================================================
--- incubator/wink/trunk/wink-component-test-support/src/main/java/org/apache/wink/client/MockHttpServer.java (original)
+++ incubator/wink/trunk/wink-component-test-support/src/main/java/org/apache/wink/client/MockHttpServer.java Mon Jul 26 18:29:58 2010
@@ -30,7 +30,9 @@ import java.net.BindException;
 import java.net.ServerSocket;
 import java.net.Socket;
 import java.net.SocketException;
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import javax.net.ServerSocketFactory;
@@ -40,35 +42,88 @@ import javax.ws.rs.core.Response.Status;
 
 public class MockHttpServer extends Thread {
 
-    private static byte[]         NEW_LINE                = "\r\n".getBytes();
+    public static class MockHttpServerResponse {
+
+        // mock response data
+        private int                   mockResponseCode        = 200;
+        private Map<String, String>   mockResponseHeaders     = new HashMap<String, String>();
+        private byte[]                mockResponseContent     = BaseTest.RECEIVED_MESSAGE.getBytes();
+        private String                mockResponseContentType = "text/plain;charset=utf-8";
+        private boolean               mockResponseContentEchoRequest;
+        
+        public void setMockResponseHeaders(Map<String, String> headers) {
+            mockResponseHeaders.clear();
+            mockResponseHeaders.putAll(headers);
+        }
+
+        public void setMockResponseHeader(String name, String value) {
+            mockResponseHeaders.put(name, value);
+        }
+        
+        public Map<String, String> getMockResponseHeaders() {
+            return mockResponseHeaders;
+        }
 
+        public void setMockResponseCode(int responseCode) {
+            this.mockResponseCode = responseCode;
+        }
+        
+        public int getMockResponseCode() {
+            return mockResponseCode;
+        }
+
+        public void setMockResponseContent(String content) {
+            mockResponseContent = content.getBytes();
+        }
+
+        public void setMockResponseContent(byte[] content) {
+            mockResponseContent = content;
+        }
+        
+        public byte[] getMockResponseContent() {
+            return mockResponseContent;
+        }
+
+        public void setMockResponseContentType(String type) {
+            mockResponseContentType = type;
+        }
+        
+        public String getMockResponseContentType() {
+            return mockResponseContentType;
+        }
+
+        public void setMockResponseContentEchoRequest(boolean echo) {
+            mockResponseContentEchoRequest = echo;
+        }
+        
+        public boolean getMockResponseContentEchoRequest() {
+            return mockResponseContentEchoRequest;
+        }
+    }
+    
     private Thread                serverThread            = null;
     private ServerSocket          serverSocket            = null;
     private boolean               serverStarted           = false;
     private ServerSocketFactory   serverSocketFactory     = null;
+    private int                   serverPort;
     private int                   readTimeOut             = 5000;                         // 5
-                                                                                           // seconds
+    // seconds
     private int                   delayResponseTime       = 0;
-
+    private static byte[]         NEW_LINE                = "\r\n".getBytes();
     // request data
     private String                requestMethod           = null;
     private String                requestUrl              = null;
     private Map<String, String>   requestHeaders          = new HashMap<String, String>();
     private ByteArrayOutputStream requestContent          = new ByteArrayOutputStream();
-
-    // mock response data
-    private int                   mockResponseCode        = 200;
-    private Map<String, String>   mockResponseHeaders     = new HashMap<String, String>();
-    private byte[]                mockResponseContent     = "".getBytes();
-    private String                mockResponseContentType = "text/plain;charset=utf-8";
-    private boolean               mockResponseContentEchoRequest;
-    private int                   serverPort;
+    private List<MockHttpServerResponse> mockHttpServerResponses = new ArrayList<MockHttpServerResponse>();
+    private int responseCounter = 0;
 
     public MockHttpServer(int serverPort) {
         this(serverPort, false);
     }
 
     public MockHttpServer(int serverPort, boolean ssl) {
+        mockHttpServerResponses.add(new MockHttpServerResponse());  // set a default response
         this.serverPort = serverPort;
         try {
             serverSocketFactory = ServerSocketFactory.getDefault();
@@ -251,10 +306,11 @@ public class MockHttpServer extends Thre
             } else {
                 processRegularContent(is);
             }
-
-            if (mockResponseContentEchoRequest) {
-                mockResponseContent = requestContent.toByteArray();
+            
+            if (mockHttpServerResponses.get(responseCounter).getMockResponseContentEchoRequest()) {
+                mockHttpServerResponses.get(responseCounter).setMockResponseContent(requestContent.toByteArray());
             }
+
         }
 
         private void processRegularContent(InputStream is) throws IOException {
@@ -360,15 +416,16 @@ public class MockHttpServer extends Thre
             OutputStream sos = socket.getOutputStream();
             BufferedOutputStream os = new BufferedOutputStream(sos);
             String reason = "";
-            Status statusCode = Response.Status.fromStatusCode(mockResponseCode);
+            Status statusCode = Response.Status.fromStatusCode(mockHttpServerResponses.get(responseCounter).getMockResponseCode());
             if (statusCode != null) {
                 reason = statusCode.toString();
             }
-            os.write(("HTTP/1.1 " + mockResponseCode + " " + reason).getBytes());
+            os.write(("HTTP/1.1 " + mockHttpServerResponses.get(responseCounter).getMockResponseCode() + " " + reason).getBytes());
             os.write(NEW_LINE);
             processResponseHeaders(os);
             processResponseContent(os);
             os.flush();
+            responseCounter++;
         }
 
         // return:
@@ -388,59 +445,31 @@ public class MockHttpServer extends Thre
         }
 
         private void processResponseContent(OutputStream os) throws IOException {
-            if (mockResponseContent == null) {
+            if (mockHttpServerResponses.get(responseCounter).getMockResponseContent() == null) {
                 return;
             }
 
-            os.write(mockResponseContent);
+            os.write(mockHttpServerResponses.get(responseCounter).getMockResponseContent());
         }
 
         private void processResponseHeaders(OutputStream os) throws IOException {
             addServerResponseHeaders();
-            for (String header : mockResponseHeaders.keySet()) {
-                os.write((header + ": " + mockResponseHeaders.get(header)).getBytes());
+            for (String header : mockHttpServerResponses.get(responseCounter).getMockResponseHeaders().keySet()) {
+                os.write((header + ": " + mockHttpServerResponses.get(responseCounter).getMockResponseHeaders().get(header)).getBytes());
                 os.write(NEW_LINE);
             }
             os.write(NEW_LINE);
         }
 
         private void addServerResponseHeaders() {
-            mockResponseHeaders.put("Content-Type", mockResponseContentType);
-            mockResponseHeaders.put("Content-Length", mockResponseContent.length + "");
+            Map<String, String> mockResponseHeaders = mockHttpServerResponses.get(responseCounter).getMockResponseHeaders();
+            mockResponseHeaders.put("Content-Type", mockHttpServerResponses.get(responseCounter).getMockResponseContentType());
+            mockResponseHeaders.put("Content-Length", mockHttpServerResponses.get(responseCounter).getMockResponseContent().length + "");
             mockResponseHeaders.put("Server", "Mock HTTP Server v1.0");
             mockResponseHeaders.put("Connection", "closed");
         }
     }
 
-    public void setMockResponseHeaders(Map<String, String> headers) {
-        mockResponseHeaders.clear();
-        mockResponseHeaders.putAll(headers);
-    }
-
-    public void setMockResponseHeader(String name, String value) {
-        mockResponseHeaders.put(name, value);
-    }
-
-    public void setMockResponseCode(int responseCode) {
-        this.mockResponseCode = responseCode;
-    }
-
-    public void setMockResponseContent(String content) {
-        mockResponseContent = content.getBytes();
-    }
-
-    public void setMockResponseContent(byte[] content) {
-        mockResponseContent = content;
-    }
-
-    public void setMockResponseContentType(String type) {
-        mockResponseContentType = type;
-    }
-
-    public void setMockResponseContentEchoRequest(boolean echo) {
-        mockResponseContentEchoRequest = echo;
-    }
-
     public void setReadTimeout(int milliseconds) {
         readTimeOut = milliseconds;
     }
@@ -530,6 +559,17 @@ public class MockHttpServer extends Thre
             }
         }
     }
+    
+    public void setMockHttpServerResponses(MockHttpServerResponse... responses) {
+        mockHttpServerResponses.clear();
+        for(int i = 0;i < responses.length; i++) {
+            mockHttpServerResponses.add(responses[i]);
+        }
+    }
+
+    public List<MockHttpServerResponse> getMockHttpServerResponses() {
+        return mockHttpServerResponses;
+    }
 
     public void setServerPort(int serverPort) {
         this.serverPort = serverPort;