You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@oltu.apache.org by st...@apache.org on 2016/03/01 07:25:50 UTC

svn commit: r1733000 - in /oltu/trunk/oauth-2.0: client/ client/src/main/java/org/apache/oltu/oauth2/client/ client/src/main/java/org/apache/oltu/oauth2/client/response/ client/src/test/java/org/apache/oltu/oauth2/client/response/ httpclient4/src/main/...

Author: stein
Date: Tue Mar  1 06:25:49 2016
New Revision: 1733000

URL: http://svn.apache.org/viewvc?rev=1733000&view=rev
Log:
OLTU-174 Add support for binary response bodies. Thanks to Julian Sedding for the patch!

Added:
    oltu/trunk/oauth-2.0/client/src/test/java/org/apache/oltu/oauth2/client/response/OAuthResourceResponseTest.java
Modified:
    oltu/trunk/oauth-2.0/client/pom.xml
    oltu/trunk/oauth-2.0/client/src/main/java/org/apache/oltu/oauth2/client/URLConnectionClient.java
    oltu/trunk/oauth-2.0/client/src/main/java/org/apache/oltu/oauth2/client/response/OAuthClientResponse.java
    oltu/trunk/oauth-2.0/client/src/main/java/org/apache/oltu/oauth2/client/response/OAuthClientResponseFactory.java
    oltu/trunk/oauth-2.0/client/src/main/java/org/apache/oltu/oauth2/client/response/OAuthResourceResponse.java
    oltu/trunk/oauth-2.0/httpclient4/src/main/java/org/apache/oltu/oauth2/httpclient4/HttpClient4.java

Modified: oltu/trunk/oauth-2.0/client/pom.xml
URL: http://svn.apache.org/viewvc/oltu/trunk/oauth-2.0/client/pom.xml?rev=1733000&r1=1732999&r2=1733000&view=diff
==============================================================================
--- oltu/trunk/oauth-2.0/client/pom.xml (original)
+++ oltu/trunk/oauth-2.0/client/pom.xml Tue Mar  1 06:25:49 2016
@@ -35,6 +35,13 @@
       <artifactId>org.apache.oltu.oauth2.common</artifactId>
       <version>${project.version}</version>
     </dependency>
+
+    <dependency>
+      <groupId>commons-io</groupId>
+      <artifactId>commons-io</artifactId>
+      <version>2.4</version>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 
   <build>

Modified: oltu/trunk/oauth-2.0/client/src/main/java/org/apache/oltu/oauth2/client/URLConnectionClient.java
URL: http://svn.apache.org/viewvc/oltu/trunk/oauth-2.0/client/src/main/java/org/apache/oltu/oauth2/client/URLConnectionClient.java?rev=1733000&r1=1732999&r2=1733000&view=diff
==============================================================================
--- oltu/trunk/oauth-2.0/client/src/main/java/org/apache/oltu/oauth2/client/URLConnectionClient.java (original)
+++ oltu/trunk/oauth-2.0/client/src/main/java/org/apache/oltu/oauth2/client/URLConnectionClient.java Tue Mar  1 06:25:49 2016
@@ -57,7 +57,7 @@ public class URLConnectionClient impleme
                                                      String requestMethod, Class<T> responseClass)
             throws OAuthSystemException, OAuthProblemException {
 
-        String responseBody = null;
+        InputStream responseBody = null;
         URLConnection c = null;
         Map<String, List<String>> responseHeaders = new HashMap<String, List<String>>();
         int responseCode = 0;
@@ -106,7 +106,7 @@ public class URLConnectionClient impleme
                 }
 
                 responseHeaders = httpURLConnection.getHeaderFields();
-                responseBody = OAuthUtils.saveStreamAsString(inputStream);
+                responseBody = inputStream;
             }
         } catch (IOException e) {
             throw new OAuthSystemException(e);

Modified: oltu/trunk/oauth-2.0/client/src/main/java/org/apache/oltu/oauth2/client/response/OAuthClientResponse.java
URL: http://svn.apache.org/viewvc/oltu/trunk/oauth-2.0/client/src/main/java/org/apache/oltu/oauth2/client/response/OAuthClientResponse.java?rev=1733000&r1=1732999&r2=1733000&view=diff
==============================================================================
--- oltu/trunk/oauth-2.0/client/src/main/java/org/apache/oltu/oauth2/client/response/OAuthClientResponse.java (original)
+++ oltu/trunk/oauth-2.0/client/src/main/java/org/apache/oltu/oauth2/client/response/OAuthClientResponse.java Tue Mar  1 06:25:49 2016
@@ -23,7 +23,10 @@ package org.apache.oltu.oauth2.client.re
 
 import org.apache.oltu.oauth2.client.validator.OAuthClientValidator;
 import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
+import org.apache.oltu.oauth2.common.utils.OAuthUtils;
 
+import java.io.IOException;
+import java.io.InputStream;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -56,7 +59,29 @@ public abstract class OAuthClientRespons
         this.headers = headers;
     }
 
-    protected abstract void setBody(String body) throws OAuthProblemException;
+    /**
+     * Allows setting the response body to a String value.
+     *
+     * @param body A String representing the response body.
+     * @throws OAuthProblemException
+     * @throws UnsupportedOperationException for subclasses that only
+     *         support InputStream as body
+     */
+    protected void setBody(String body) throws OAuthProblemException {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Allows setting the response body to an InputStream value.
+     *
+     * @param body An InputStream representing the response body.
+     * @throws OAuthProblemException
+     * @throws UnsupportedOperationException for subclasses that only
+     *         support String as body
+     */
+    protected void setBody(InputStream body) throws OAuthProblemException {
+        throw new UnsupportedOperationException();
+    }
 
     protected abstract void setContentType(String contentType);
 
@@ -76,6 +101,28 @@ public abstract class OAuthClientRespons
         init(body, contentType, responseCode, new HashMap<String, List<String>>());
     }
 
+    /**
+     * Default implementation that converts the body InputStream to a String and delegates
+     * to {@link #init(String, String, int)}.
+     * <br/>
+     * This implementation ensures backwards compatibility, as many subclasses expect String
+     * type bodies. At the same time it can be overridden to also deal with binary InputStreams.
+     *
+     * @param body an InputStream representing the response body
+     * @param contentType the content type of the response.
+     * @param responseCode the HTTP response code of the response.
+     * @param headers The HTTP response headers
+     * @throws OAuthProblemException
+     */
+    protected void init(InputStream body, String contentType, int responseCode, Map<String, List<String>> headers)
+            throws OAuthProblemException {
+        try {
+            init(OAuthUtils.saveStreamAsString(body), contentType, responseCode);
+        } catch (final IOException e) {
+            throw OAuthProblemException.error(e.getMessage());
+        }
+    }
+
     protected void validate() throws OAuthProblemException {
         validator.validate(this);
     }

Modified: oltu/trunk/oauth-2.0/client/src/main/java/org/apache/oltu/oauth2/client/response/OAuthClientResponseFactory.java
URL: http://svn.apache.org/viewvc/oltu/trunk/oauth-2.0/client/src/main/java/org/apache/oltu/oauth2/client/response/OAuthClientResponseFactory.java?rev=1733000&r1=1732999&r2=1733000&view=diff
==============================================================================
--- oltu/trunk/oauth-2.0/client/src/main/java/org/apache/oltu/oauth2/client/response/OAuthClientResponseFactory.java (original)
+++ oltu/trunk/oauth-2.0/client/src/main/java/org/apache/oltu/oauth2/client/response/OAuthClientResponseFactory.java Tue Mar  1 06:25:49 2016
@@ -21,7 +21,6 @@
 
 package org.apache.oltu.oauth2.client.response;
 
-
 import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
 import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
 import org.apache.oltu.oauth2.common.utils.OAuthUtils;
@@ -29,6 +28,9 @@ import org.apache.oltu.oauth2.common.uti
 import java.util.List;
 import java.util.Map;
 
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
 /**
  *
  *
@@ -38,7 +40,7 @@ public class OAuthClientResponseFactory
 
     public static OAuthClientResponse createGitHubTokenResponse(String body, String contentType,
                                                                 int responseCode)
-        throws OAuthProblemException {
+            throws OAuthProblemException {
         GitHubTokenResponse resp = new GitHubTokenResponse();
         resp.init(body, contentType, responseCode);
         return resp;
@@ -46,7 +48,7 @@ public class OAuthClientResponseFactory
 
     public static OAuthClientResponse createJSONTokenResponse(String body, String contentType,
                                                               int responseCode)
-        throws OAuthProblemException {
+            throws OAuthProblemException {
         OAuthJSONAccessTokenResponse resp = new OAuthJSONAccessTokenResponse();
         resp.init(body, contentType, responseCode);
         return resp;
@@ -54,16 +56,31 @@ public class OAuthClientResponseFactory
 
     public static <T extends OAuthClientResponse> T createCustomResponse(String body, String contentType,
                                                                          int responseCode,
-                                                                         Map<String, List<String>> headers, Class<T> clazz)
-        throws OAuthSystemException, OAuthProblemException {
+                                                                         Map<String, List<String>> headers,
+                                                                         Class<T> clazz)
+            throws OAuthSystemException, OAuthProblemException {
 
         OAuthClientResponse resp = OAuthUtils
-            .instantiateClassWithParameters(clazz, null, null);
+                .instantiateClassWithParameters(clazz, null, null);
 
         resp.init(body, contentType, responseCode, headers);
 
-        return (T)resp;
+        return (T) resp;
     }
 
+    public static <T extends OAuthClientResponse> T createCustomResponse(InputStream body, String contentType,
+                                                                         int responseCode,
+                                                                         Map<String, List<String>> headers,
+                                                                         Class<T> clazz)
+            throws OAuthSystemException, OAuthProblemException {
+
+        T resp = OAuthUtils.instantiateClassWithParameters(clazz, null, null);
+
+        if (body == null) {
+            body = new ByteArrayInputStream(new byte[0]);
+        }
+        resp.init(body, contentType, responseCode, headers);
 
+        return resp;
+    }
 }

Modified: oltu/trunk/oauth-2.0/client/src/main/java/org/apache/oltu/oauth2/client/response/OAuthResourceResponse.java
URL: http://svn.apache.org/viewvc/oltu/trunk/oauth-2.0/client/src/main/java/org/apache/oltu/oauth2/client/response/OAuthResourceResponse.java?rev=1733000&r1=1732999&r2=1733000&view=diff
==============================================================================
--- oltu/trunk/oauth-2.0/client/src/main/java/org/apache/oltu/oauth2/client/response/OAuthResourceResponse.java (original)
+++ oltu/trunk/oauth-2.0/client/src/main/java/org/apache/oltu/oauth2/client/response/OAuthResourceResponse.java Tue Mar  1 06:25:49 2016
@@ -18,17 +18,40 @@ package org.apache.oltu.oauth2.client.re
 
 import org.apache.oltu.oauth2.client.validator.ResourceValidator;
 import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
+import org.apache.oltu.oauth2.common.utils.OAuthUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
+import java.io.IOException;
+import java.io.InputStream;
 import java.util.List;
 import java.util.Map;
 
-public class OAuthResourceResponse extends OAuthClientResponse {
+public class OAuthResourceResponse  extends OAuthClientResponse {
+
+    private static final Logger LOG = LoggerFactory.getLogger(OAuthResourceResponse.class);
+
+    private InputStream inputStream;
+
+    private boolean bodyRetrieved = false;
 
     public OAuthResourceResponse() {
         this.validator = new ResourceValidator();
     }
 
     public String getBody() {
+        if (bodyRetrieved && body == null) {
+            throw new IllegalStateException("Cannot call getBody() after getBodyAsInputStream()");
+        }
+
+        if (body == null) {
+            try {
+                body = OAuthUtils.saveStreamAsString(getBodyAsInputStream());
+                inputStream = null;
+            } catch (IOException e) {
+                LOG.error("Failed to convert InputStream to String", e);
+            }
+        }
         return body;
     }
 
@@ -40,8 +63,9 @@ public class OAuthResourceResponse exten
         return contentType;
     }
 
-    public Map<String, List<String>> getHeaders() {
-        return headers;
+    @Override
+    protected void setBody(InputStream body) throws OAuthProblemException {
+        this.inputStream = body;
     }
 
     @Override
@@ -49,7 +73,18 @@ public class OAuthResourceResponse exten
         this.body = body;
     }
 
-    @Override
+    public Map<String, List<String>> getHeaders() {
+        return headers;
+    }
+
+    public InputStream getBodyAsInputStream() {
+        if (bodyRetrieved && inputStream == null) {
+            throw new IllegalStateException("Cannot call getBodyAsInputStream() after getBody()");
+        }
+        bodyRetrieved = true;
+        return inputStream;
+    }
+
     protected void setContentType(String contentType) {
         this.contentType = contentType;
     }
@@ -60,10 +95,10 @@ public class OAuthResourceResponse exten
     }
 
     @Override
-    protected void init(String body, String contentType, int responseCode) throws OAuthProblemException {
+    protected void init(InputStream body, String contentType, int responseCode, Map<String, List<String>> headers) throws OAuthProblemException {
         this.setBody(body);
         this.setContentType(contentType);
         this.setResponseCode(responseCode);
+        this.setHeaders(headers);
     }
-
 }

Added: oltu/trunk/oauth-2.0/client/src/test/java/org/apache/oltu/oauth2/client/response/OAuthResourceResponseTest.java
URL: http://svn.apache.org/viewvc/oltu/trunk/oauth-2.0/client/src/test/java/org/apache/oltu/oauth2/client/response/OAuthResourceResponseTest.java?rev=1733000&view=auto
==============================================================================
--- oltu/trunk/oauth-2.0/client/src/test/java/org/apache/oltu/oauth2/client/response/OAuthResourceResponseTest.java (added)
+++ oltu/trunk/oauth-2.0/client/src/test/java/org/apache/oltu/oauth2/client/response/OAuthResourceResponseTest.java Tue Mar  1 06:25:49 2016
@@ -0,0 +1,97 @@
+/**
+ *       Copyright 2010 Newcastle University
+ *
+ *          http://research.ncl.ac.uk/smart/
+ *
+ * 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.oltu.oauth2.client.response;
+
+import org.apache.commons.codec.Charsets;
+import org.apache.commons.io.IOUtils;
+import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
+import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+/**
+ *
+ *
+ *
+ */
+public class OAuthResourceResponseTest {
+
+    private static final byte[] BINARY = new byte[]{ 0, 1, 2, 3, 4, 5 };
+
+    public static final String STRING = "roundtrip";
+
+    private static final byte[] STRING_BYTES = STRING.getBytes(Charsets.UTF_8);
+
+    @Rule
+    public ExpectedException expectedException = ExpectedException.none();
+
+    @Test
+    public void allowBinaryResponseBody() throws OAuthProblemException, OAuthSystemException, IOException {
+        final OAuthResourceResponse resp = createBinaryResponse(BINARY);
+        final byte[] bytes = IOUtils.toByteArray(resp.getBodyAsInputStream());
+        assertArrayEquals(BINARY, bytes);
+    }
+
+    @Test
+    public void allowStringAsBinaryResponseBody() throws OAuthProblemException, OAuthSystemException, IOException {
+        final OAuthResourceResponse resp = createBinaryResponse(STRING_BYTES);
+        final byte[] bytes = IOUtils.toByteArray(resp.getBodyAsInputStream());
+        assertArrayEquals(STRING_BYTES, bytes);
+    }
+
+    @Test
+    public void allowStringResponseBody() throws OAuthProblemException, OAuthSystemException, IOException {
+        final OAuthResourceResponse resp = createBinaryResponse(STRING_BYTES);
+        assertEquals("getBody() should return correct string", STRING, resp.getBody());
+    }
+
+    @Test
+    public void errorRetrievingBodyAfterStream() throws OAuthProblemException, OAuthSystemException, IOException {
+        final OAuthResourceResponse resp = createBinaryResponse(STRING_BYTES);
+        resp.getBodyAsInputStream();
+        expectedException.expect(IllegalStateException.class);
+        resp.getBody();
+    }
+
+    @Test
+    public void errorRetrievingStreamAfterBody() throws OAuthProblemException, OAuthSystemException, IOException {
+        final OAuthResourceResponse resp = createBinaryResponse(STRING_BYTES);
+        resp.getBody();
+        expectedException.expect(IllegalStateException.class);
+        resp.getBodyAsInputStream();
+    }
+
+    private OAuthResourceResponse createBinaryResponse(byte[] bytes) throws OAuthSystemException, OAuthProblemException {
+        final ByteArrayInputStream binaryStream = new ByteArrayInputStream(bytes);
+        return OAuthClientResponseFactory.createCustomResponse(binaryStream, null, 200, new HashMap<String, List<String>>(), OAuthResourceResponse.class);
+    }
+
+}

Modified: oltu/trunk/oauth-2.0/httpclient4/src/main/java/org/apache/oltu/oauth2/httpclient4/HttpClient4.java
URL: http://svn.apache.org/viewvc/oltu/trunk/oauth-2.0/httpclient4/src/main/java/org/apache/oltu/oauth2/httpclient4/HttpClient4.java?rev=1733000&r1=1732999&r2=1733000&view=diff
==============================================================================
--- oltu/trunk/oauth-2.0/httpclient4/src/main/java/org/apache/oltu/oauth2/httpclient4/HttpClient4.java (original)
+++ oltu/trunk/oauth-2.0/httpclient4/src/main/java/org/apache/oltu/oauth2/httpclient4/HttpClient4.java Tue Mar  1 06:25:49 2016
@@ -21,6 +21,8 @@
 
 package org.apache.oltu.oauth2.httpclient4;
 
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
 import java.net.URI;
 import java.util.ArrayList;
 import java.util.List;
@@ -84,7 +86,7 @@ public class HttpClient4 implements Http
         try {
             URI location = new URI(request.getLocationUri());
             HttpRequestBase req = null;
-            String responseBody = "";
+            InputStream responseBody = new ByteArrayInputStream(new byte[0]);
 
             if (!OAuthUtils.isEmpty(requestMethod) && OAuth.HttpMethod.POST.equals(requestMethod)) {
                 req = new HttpPost(location);
@@ -108,7 +110,7 @@ public class HttpClient4 implements Http
 
             HttpEntity entity = response.getEntity();
             if (entity != null) {
-                responseBody = EntityUtils.toString(entity);
+                responseBody = entity.getContent();
                 contentTypeHeader = entity.getContentType();
             }
             String contentType = null;