diff --git a/build.gradle b/build.gradle index 813e537b..e1517fb3 100644 --- a/build.gradle +++ b/build.gradle @@ -49,6 +49,7 @@ dependencies { testCompile "org.mockito:mockito-all:1.8.5" testCompile "org.powermock:powermock-module-junit4:1.4.11" testCompile "org.powermock:powermock-api-mockito:1.4.11" + testImplementation "org.mock-server:mockserver-netty:5.10.0" testImplementation "com.google.truth:truth:1.0.1" } diff --git a/src/main/java/com/pusher/client/util/HttpAuthorizer.java b/src/main/java/com/pusher/client/util/HttpAuthorizer.java index 5558667b..df9002f6 100644 --- a/src/main/java/com/pusher/client/util/HttpAuthorizer.java +++ b/src/main/java/com/pusher/client/util/HttpAuthorizer.java @@ -14,6 +14,8 @@ import java.util.Map; import javax.net.ssl.HttpsURLConnection; +import static java.net.HttpURLConnection.HTTP_BAD_REQUEST; + /** * Used to authenticate a {@link com.pusher.client.channel.PrivateChannel * private} or {@link com.pusher.client.channel.PresenceChannel presence} @@ -110,7 +112,7 @@ public String authorize(final String channelName, final String socketId) throws defaultHeaders.putAll(mHeaders); // Add in the Content-Length, so it can't be overwritten by mHeaders defaultHeaders.put("Content-Length","" + Integer.toString(body.getBytes().length)); - + for (final String headerName : defaultHeaders.keySet()) { final String headerValue = defaultHeaders.get(headerName); connection.setRequestProperty(headerName, headerValue); @@ -125,7 +127,7 @@ public String authorize(final String channelName, final String socketId) throws wr.close(); // Read response - final InputStream is = connection.getInputStream(); + final InputStream is = getResponseInputStream(connection); final BufferedReader rd = new BufferedReader(new InputStreamReader(is)); String line; final StringBuffer response = new StringBuffer(); @@ -146,4 +148,11 @@ public String authorize(final String channelName, final String socketId) throws throw new AuthorizationFailureException(e); } } + + private InputStream getResponseInputStream(HttpURLConnection connection) throws IOException { + if (connection.getResponseCode() >= HTTP_BAD_REQUEST) { + return connection.getErrorStream(); + } + return connection.getInputStream(); + } } diff --git a/src/test/java/com/pusher/client/util/HttpAuthorizerTest.java b/src/test/java/com/pusher/client/util/HttpAuthorizerTest.java index de222574..19610a80 100644 --- a/src/test/java/com/pusher/client/util/HttpAuthorizerTest.java +++ b/src/test/java/com/pusher/client/util/HttpAuthorizerTest.java @@ -1,13 +1,28 @@ package com.pusher.client.util; +import com.pusher.client.AuthorizationFailureException; import junit.framework.Assert; - +import org.junit.AfterClass; +import org.junit.BeforeClass; import org.junit.Test; +import org.mockserver.integration.ClientAndServer; -import com.pusher.client.AuthorizationFailureException; +import static com.google.common.truth.Truth.assertThat; +import static java.net.HttpURLConnection.HTTP_FORBIDDEN; +import static java.net.HttpURLConnection.HTTP_OK; +import static org.mockserver.integration.ClientAndServer.startClientAndServer; +import static org.mockserver.model.HttpRequest.request; +import static org.mockserver.model.HttpResponse.response; public class HttpAuthorizerTest { + private static ClientAndServer mockServer; + + @BeforeClass + public static void startMockServer() { + mockServer = startClientAndServer(1080); + } + @Test(expected = IllegalArgumentException.class) public void testConstructWithMalformedURLThrowsRuntimeException() { new HttpAuthorizer("bad url"); @@ -30,4 +45,40 @@ public void testNon200ResponseThrowsAuthorizationFailureException() { final HttpAuthorizer auth = new HttpAuthorizer("https://127.0.0.1/no-way-this-is-a-valid-url"); auth.authorize("private-fish", "some socket id"); } + + @Test + public void testResponseStatusHttpBadRequestOrAboveThrowsAuthorizationExceptionWithDetailedErrorMessage() { + String errorResponseMessage = "No cats allowed"; + mockServer.when(request().withPath("/no-way-this-is-a-valid-url/wanna-bet")) + .respond(response() + .withStatusCode(HTTP_FORBIDDEN) + .withBody(errorResponseMessage) + ); + final HttpAuthorizer auth = new HttpAuthorizer("http://127.0.0.1:1080/no-way-this-is-a-valid-url/wanna-bet"); + + try { + auth.authorize("private-dog", "barking"); + } catch (AuthorizationFailureException e) { + assertThat(e).hasMessageThat().isEqualTo(errorResponseMessage); + } + } + + @Test + public void testResponseStatusLowerThanHttpBadRequestReturnsSuccessResponse() { + String expectedResponseMessage = "Keep on purring"; + mockServer.when(request().withPath("/no-way-this-is-a-valid-url/wanna-bet")) + .respond(response() + .withStatusCode(HTTP_OK) + .withBody(expectedResponseMessage) + ); + final HttpAuthorizer auth = new HttpAuthorizer("http://127.0.0.1:1080/no-way-this-is-a-valid-url/wanna-bet"); + + String responseMessage = auth.authorize("private-cat", "purring"); + assertThat(responseMessage).isEqualTo(expectedResponseMessage); + } + + @AfterClass + public static void stopMockServer() { + mockServer.stop(); + } }