diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/AuthenticationProtocolHandler.java b/jetty-client/src/main/java/org/eclipse/jetty/client/AuthenticationProtocolHandler.java index d690013005f..9d7c297774e 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/AuthenticationProtocolHandler.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/AuthenticationProtocolHandler.java @@ -135,27 +135,36 @@ public abstract class AuthenticationProtocolHandler implements ProtocolHandler return; } - final Authentication.Result authnResult = authentication.authenticate(request, response, headerInfo, conversation); - if (LOG.isDebugEnabled()) - LOG.debug("Authentication result {}", authnResult); - if (authnResult == null) + try { - forwardSuccessComplete(request, response); - return; - } - - conversation.setAttribute(AUTHENTICATION_ATTRIBUTE, true); - - Request newRequest = client.copyRequest(request, request.getURI()); - authnResult.apply(newRequest); - newRequest.onResponseSuccess(new Response.SuccessListener() - { - @Override - public void onSuccess(Response response) + final Authentication.Result authnResult = authentication.authenticate(request, response, headerInfo, conversation); + if (LOG.isDebugEnabled()) + LOG.debug("Authentication result {}", authnResult); + if (authnResult == null) { - client.getAuthenticationStore().addAuthenticationResult(authnResult); + forwardSuccessComplete(request, response); + return; } - }).send(null); + + conversation.setAttribute(AUTHENTICATION_ATTRIBUTE, true); + + Request newRequest = client.copyRequest(request, request.getURI()); + authnResult.apply(newRequest); + newRequest.onResponseSuccess(new Response.SuccessListener() + { + @Override + public void onSuccess(Response response) + { + client.getAuthenticationStore().addAuthenticationResult(authnResult); + } + }).send(null); + } + catch (Throwable x) + { + if (LOG.isDebugEnabled()) + LOG.debug("Authentication failed", x); + forwardFailureComplete(request, null, response, x); + } } private void forwardSuccessComplete(HttpRequest request, Response response) diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAuthenticationTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAuthenticationTest.java index aa897174e31..f14f0562ed5 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAuthenticationTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAuthenticationTest.java @@ -34,6 +34,8 @@ import org.eclipse.jetty.client.api.Authentication; import org.eclipse.jetty.client.api.AuthenticationStore; import org.eclipse.jetty.client.api.ContentResponse; import org.eclipse.jetty.client.api.Request; +import org.eclipse.jetty.client.api.Response; +import org.eclipse.jetty.client.api.Result; import org.eclipse.jetty.client.util.BasicAuthentication; import org.eclipse.jetty.client.util.DigestAuthentication; import org.eclipse.jetty.security.Authenticator; @@ -47,6 +49,7 @@ import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.eclipse.jetty.util.Attributes; import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.util.security.Constraint; import org.eclipse.jetty.util.ssl.SslContextFactory; @@ -320,4 +323,47 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest Assert.assertNotNull(response); Assert.assertEquals(401, response.getStatus()); } + + @Test + public void test_Authentication_ThrowsException() throws Exception + { + startBasic(new EmptyServerHandler()); + + // Request without Authentication would cause a 401, + // but the client will throw an exception trying to + // send the credentials to the server. + final String cause = "thrown_explicitly_by_test"; + client.getAuthenticationStore().addAuthentication(new Authentication() + { + @Override + public boolean matches(String type, URI uri, String realm) + { + return true; + } + + @Override + public Result authenticate(Request request, ContentResponse response, HeaderInfo headerInfo, Attributes context) + { + throw new RuntimeException(cause); + } + }); + + final CountDownLatch latch = new CountDownLatch(1); + client.newRequest("localhost", connector.getLocalPort()) + .scheme(scheme) + .path("/secure") + .timeout(5, TimeUnit.SECONDS) + .send(new Response.CompleteListener() + { + @Override + public void onComplete(Result result) + { + Assert.assertTrue(result.isFailed()); + Assert.assertEquals(cause, result.getFailure().getMessage()); + latch.countDown(); + } + }); + + Assert.assertTrue(latch.await(5, TimeUnit.SECONDS)); + } } diff --git a/jetty-osgi/jetty-osgi-httpservice/contexts/httpservice.xml b/jetty-osgi/jetty-osgi-httpservice/contexts/httpservice.xml index e1044c88bcd..98c00314b90 100644 --- a/jetty-osgi/jetty-osgi-httpservice/contexts/httpservice.xml +++ b/jetty-osgi/jetty-osgi-httpservice/contexts/httpservice.xml @@ -1,31 +1,17 @@ - - + - + org.eclipse.equinox.http.servlet.HttpServiceServlet /* 1 - + diff --git a/pom.xml b/pom.xml index e472ef21ff7..89d2996ca12 100644 --- a/pom.xml +++ b/pom.xml @@ -330,7 +330,7 @@ Eclipse Jetty Project . ${bundle-symbolic-name}.*;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}" - Copyright (c) 2008-2015 Mort Bay Consulting Pty. Ltd. + Copyright (c) 2008-2016 Mort Bay Consulting Pty. Ltd. javax.servlet*;version="[2.6.0,3.2)",javax.transaction*;version="[1.1,1.3)",org.eclipse.jetty*;version="[$(version;===;${parsedVersion.osgiVersion}),$(version;==+;${parsedVersion.osgiVersion}))",*