### Eclipse Workspace Patch 1.0 #P httpclient Index: pom.xml =================================================================== --- pom.xml (revision 943129) +++ pom.xml (working copy) @@ -70,6 +70,12 @@ ${junit.version} test + + org.mockito + mockito-all + 1.8.4 + test + Index: src/test/java/org/apache/http/impl/client/TestNegotiateDefaultClientRequestDirector.java =================================================================== --- src/test/java/org/apache/http/impl/client/TestNegotiateDefaultClientRequestDirector.java (revision 0) +++ src/test/java/org/apache/http/impl/client/TestNegotiateDefaultClientRequestDirector.java (revision 0) @@ -0,0 +1,183 @@ +package org.apache.http.impl.client; + +import static org.mockito.Matchers.*; +import static org.mockito.Mockito.*; + +import java.io.IOException; +import java.security.Principal; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpException; +import org.apache.http.HttpHost; +import org.apache.http.HttpRequest; +import org.apache.http.HttpResponse; +import org.apache.http.auth.AuthScheme; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.Credentials; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.params.AuthPolicy; +import org.apache.http.client.params.ClientPNames; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.auth.NegotiateScheme; +import org.apache.http.impl.auth.NegotiateSchemeFactory; +import org.apache.http.localserver.BasicServerTestBase; +import org.apache.http.localserver.LocalTestServer; +import org.apache.http.message.BasicHeader; +import org.apache.http.params.HttpParams; +import org.apache.http.protocol.HttpContext; +import org.apache.http.protocol.HttpRequestHandler; +import org.ietf.jgss.GSSContext; +import org.ietf.jgss.GSSCredential; +import org.ietf.jgss.GSSManager; +import org.ietf.jgss.GSSName; +import org.ietf.jgss.Oid; +import org.junit.Before; +import org.junit.Test; + + +/** + * Tests for {@link NegotiateScheme}. + * Inspired from {@link TestDefaultClientRequestDirector} + * @author frigault + */ +public class TestNegotiateDefaultClientRequestDirector extends BasicServerTestBase { + + @Before + public void setUp() throws Exception { + localServer = new LocalTestServer(null, null); + + localServer.registerDefaultHandlers(); + localServer.start(); + } + + + /** + * This service will continue to ask for authentication. + * + */ + private static class PleaseNegotiateService implements HttpRequestHandler { + public void handle(final HttpRequest request, + final HttpResponse response, + final HttpContext context) throws HttpException, IOException { + response.setStatusCode(401); + response.addHeader(new BasicHeader("WWW-Authenticate", "Negotiate blablabla")); + response.setEntity(new StringEntity("auth required ")); + response.addHeader(new BasicHeader("Connection", "Keep-Alive")); + } + } + + + /** + * NegotatieScheme with a custom GSSManager that does not require any Jaas or + * Kerberos configuration. + * + */ + private static class NegotiateSchemeWithMockGssManager extends NegotiateScheme { + GSSManager manager = mock(GSSManager.class); + GSSName name = mock(GSSName.class); + GSSContext context = mock(GSSContext.class); + + NegotiateSchemeWithMockGssManager() throws Exception { + super(null, true); + + when(context.initSecContext(any(byte[].class), anyInt(), anyInt())) + .thenReturn("12345678".getBytes()); + when(manager.createName(any(String.class), any(Oid.class))) + .thenReturn(name); + when(manager.createContext(any(GSSName.class), any(Oid.class), any(GSSCredential.class), anyInt())) + .thenReturn(context); + + } + + @Override + protected GSSManager getManager() { + return manager; + } + } + + + /** + * Credentials as they are set in the examples. + * + */ + private static class UseJaasCredentials implements Credentials { + public String getPassword() { + return null; + } + + public Principal getUserPrincipal() { + return null; + } + } + + + private static class NegotiateSchemeFactoryWithMockGssManager extends NegotiateSchemeFactory { + NegotiateSchemeWithMockGssManager scheme; + NegotiateSchemeFactoryWithMockGssManager() throws Exception { + scheme = new NegotiateSchemeWithMockGssManager(); + } + @Override + public AuthScheme newInstance(HttpParams params) { + return scheme; + } + } + + + /** + * Tests that the client will stop connecting to the server if + * the server still keep asking for a valid ticket. + */ + @Test(timeout=5000) + public void testDontTryToAuthenticateEndlessly() throws Exception { + int port = this.localServer.getServiceAddress().getPort(); + this.localServer.register("*", new PleaseNegotiateService()); + + HttpHost target = new HttpHost("localhost", port); + DefaultHttpClient client = new DefaultHttpClient(); + NegotiateSchemeFactory nsf = new NegotiateSchemeFactoryWithMockGssManager(); + client.getAuthSchemes().register(AuthPolicy.SPNEGO, nsf); + + Credentials use_jaas_creds = new UseJaasCredentials(); + client.getCredentialsProvider().setCredentials( + new AuthScope(null, -1, null), use_jaas_creds); + client.getParams().setParameter(ClientPNames.DEFAULT_HOST, target); + + String s = "/path"; + HttpGet httpget = new HttpGet(s); + HttpResponse response = client.execute(httpget); + HttpEntity e = response.getEntity(); + e.consumeContent(); + } + + + /** + * Javadoc specifies that {@link GSSContext#initSecContext(byte[], int, int)} can return null + * if no token is generated. Client should be able to deal with this response. + * + */ + @Test + public void testNoTokenGeneratedGenerateAnError() throws Exception { + int port = this.localServer.getServiceAddress().getPort(); + this.localServer.register("*", new PleaseNegotiateService()); + + HttpHost target = new HttpHost("localhost", port); + DefaultHttpClient client = new DefaultHttpClient(); + NegotiateSchemeFactoryWithMockGssManager nsf = new NegotiateSchemeFactoryWithMockGssManager(); + when(nsf.scheme.context.initSecContext(any(byte[].class), anyInt(), anyInt())).thenReturn(null); + client.getAuthSchemes().register(AuthPolicy.SPNEGO, nsf); + + Credentials use_jaas_creds = new UseJaasCredentials(); + client.getCredentialsProvider().setCredentials( + new AuthScope(null, -1, null), use_jaas_creds); + client.getParams().setParameter(ClientPNames.DEFAULT_HOST, target); + + String s = "/path"; + HttpGet httpget = new HttpGet(s); + HttpResponse response = client.execute(httpget); + HttpEntity e = response.getEntity(); + e.consumeContent(); + } + + + +}