Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 81 additions & 7 deletions src/main/java/org/scribe/model/Request.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.io.*;
import java.net.*;
import java.nio.charset.Charset;
import java.util.*;
import java.util.concurrent.TimeUnit;

Expand All @@ -16,13 +17,14 @@
class Request
{
private static final String CONTENT_LENGTH = "Content-Length";
private static final String CONTENT_TYPE = "Content-Type";

private String url;
private String url;
private Verb verb;
private Map<String, String> querystringParams;
private Map<String, String> bodyParams;
private Map<String, String> headers;
private String payload = null;
private byte[] payload = null;
private HttpURLConnection connection;

/**
Expand Down Expand Up @@ -83,13 +85,16 @@ void addHeaders(HttpURLConnection conn)
{
for (String key : headers.keySet())
conn.setRequestProperty(key, headers.get(key));
if (!headers.containsKey(CONTENT_TYPE)) {
conn.setRequestProperty(CONTENT_TYPE, "application/x-www-form-urlencoded");
}
}

void addBody(HttpURLConnection conn, String content) throws IOException
void addBody(HttpURLConnection conn, byte[] content) throws IOException
{
conn.setRequestProperty(CONTENT_LENGTH, String.valueOf(content.getBytes().length));
conn.setRequestProperty(CONTENT_LENGTH, String.valueOf(content.length));
conn.setDoOutput(true);
conn.getOutputStream().write(content.getBytes());
conn.getOutputStream().write(content);
}

/**
Expand Down Expand Up @@ -136,10 +141,79 @@ public void addQuerystringParameter(String key, String value)
* @param payload the body of the request
*/
public void addPayload(String payload)
{
this.payload = payload.getBytes();
}

/**
* Add body payload.
*
* This method is used when the HTTP body is not a form-url-encoded string,
* but another thing. Like for example XML.
*
* Note: The contents are not part of the OAuth signature
*
* @param payload the body of the request
*/
public void addPayload(byte[] payload)
{
this.payload = payload;
}

/**
* Add body payload and set the content type header.
*
* This method is used when the HTTP body is not a form-url-encoded string,
* but another thing, like for example {@code text/xml}.
*
* @param payload The payload.
* @param contentType The content type of the payload (if the content type starts with {@code text/} and does not
* include the charset, it will be added automatically.
* @param charset The charset to encode the payload as.
*/
public void addPayload(String payload, String contentType, Charset charset) {
payload.getClass(); // throw NPE if null
contentType.getClass(); // throw NPE if null
charset.getClass(); // throw NPE if null
contentType = contentType.trim();
if (contentType.startsWith("text/")) {
if (!contentType.contains("charset=")) {
contentType = contentType + "; charset=" + charset.name();
}
}
addPayload(payload.getBytes(charset),contentType);
}

/**
* Add body payload and set the content type header.
*
* This method is used when the HTTP body is not a form-url-encoded string,
* but another thing, like for example {@code text/xml}.
*
* @param payload The payload (which will be encoded using the system default charset).
* @param contentType The content type of the payload (if the content type starts with {@code text/} and does not
* include the charset, it will be added automatically.
*/
public void addPayload(String payload, String contentType) {
addPayload(payload, contentType, Charset.defaultCharset());
}

/**
* Add body payload and set the content type header.
*
* This method is used when the HTTP body is not a form-url-encoded string,
* but another thing, like for example {@code text/xml}.
*
* @param payload The payload
* @param contentType The content type of the payload.
*/
public void addPayload(byte[] payload, String contentType) {
payload.getClass(); // throw NPE if null
contentType.getClass(); // throw NPE if null
addHeader(CONTENT_TYPE, contentType);
addPayload(payload);
}

/**
* Get a {@link Map} of the query string parameters.
*
Expand Down Expand Up @@ -203,9 +277,9 @@ public String getSanitizedUrl()
*
* @return form encoded string
*/
public String getBodyContents()
public byte[] getBodyContents()
{
return (payload != null) ? payload : URLUtils.formURLEncodeMap(bodyParams);
return (payload != null) ? payload : URLUtils.formURLEncodeMap(bodyParams).getBytes();
}

/**
Expand Down
20 changes: 17 additions & 3 deletions src/main/java/org/scribe/model/Response.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@
*/
public class Response
{
private static final String EMPTY = "";
private static final byte[] EMPTY = new byte[0];

private int code;
private String body;
private byte[] body;
private String bodyUTF8;
private InputStream stream;
private Map<String, String> headers;

Expand All @@ -35,7 +36,7 @@ public class Response
}
}

private String parseBodyContents()
private byte[] parseBodyContents()
{
body = StreamUtils.getStreamContents(getStream());
return body;
Expand All @@ -62,6 +63,19 @@ private boolean wasSuccessful()
* @return response body
*/
public String getBody()
{
if (bodyUTF8 == null) {
bodyUTF8 = new String(getBodyAsByteArray());
}
return bodyUTF8;
}

/**
* Obtains the HTTP Response body
*
* @return response body
*/
public byte[] getBodyAsByteArray()
{
return body != null ? body : parseBodyContents();
}
Expand Down
47 changes: 30 additions & 17 deletions src/main/java/org/scribe/utils/StreamUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,31 +12,44 @@ public class StreamUtils
/**
* Returns the stream contents as an UTF-8 encoded string
*
* @param is input stream
* @return string contents
* @param in input stream
* @return stream contents
*/
public static String getStreamContents(InputStream is)
public static byte[] getStreamContents(InputStream in)
{
Preconditions.checkNotNull(is, "Cannot get String from a null object");
Preconditions.checkNotNull(in, "Cannot get String from a null object");
ByteArrayOutputStream out = null;
try
{
final char[] buffer = new char[0x10000];
StringBuilder out = new StringBuilder();
Reader in = new InputStreamReader(is, "UTF-8");
final byte[] buffer = new byte[0x10000];
out = new ByteArrayOutputStream();
int read;
do
{
read = in.read(buffer, 0, buffer.length);
if (read > 0)
{
out.append(buffer, 0, read);
}
} while (read >= 0);
in.close();
return out.toString();
while (0 < (read = in.read(buffer, 0, buffer.length)))
out.write(buffer, 0, read);
return out.toByteArray();
} catch (IOException ioe)
{
throw new IllegalStateException("Error while reading response body", ioe);
} finally {
close(in);
close(out);
}
}

/**
* Closes any {@link Closeable} while quashing any exceptions.
* @param closeable the {@link Closeable} to close (may be {@code null}).
*/
public static void close(Closeable closeable) {
if (closeable != null)
{
try
{
closeable.close();
} catch (IOException e)
{
// ignore
}
}
}
}
39 changes: 35 additions & 4 deletions src/test/java/org/scribe/model/RequestTest.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
package org.scribe.model;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.*;

import org.junit.*;

import java.nio.charset.Charset;
import java.util.AbstractMap;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;

public class RequestTest
{

Expand Down Expand Up @@ -42,8 +49,21 @@ public void shouldAddRequestHeaders()
getRequest.addHeader("Header", "1");
getRequest.addHeader("Header2", "2");
getRequest.send();
assertEquals(2, getRequest.getHeaders().size());
assertEquals(2, connection.getHeaders().size());
assertThat(getRequest.getHeaders(), is(map(entry("Header", "1"), entry("Header2", "2"))));
assertThat(connection.getHeaders(), is(map(entry("Header", "1"), entry("Header2", "2"),
entry("Content-Type", "application/x-www-form-urlencoded"))));
}

public static <K,V> Map.Entry<K,V> entry(K k,V v) {
return new AbstractMap.SimpleEntry<K, V>(k,v);
}

public static <K,V> Map<K,V> map(Map.Entry<K,V>... entries) {
Map<K,V> result = new LinkedHashMap<K, V>();
for (Map.Entry<K,V> entry: entries) {
result.put(entry.getKey(), entry.getValue());
}
return result;
}

@Test
Expand All @@ -52,7 +72,7 @@ public void shouldSetBodyParamsAndHeaders()
postRequest.addBodyParameter("param", "value");
postRequest.addBodyParameter("param two", "value with spaces");
postRequest.send();
assertEquals("param%20two=value%20with%20spaces&param=value", postRequest.getBodyContents());
assertEquals("param%20two=value%20with%20spaces&param=value", new String(postRequest.getBodyContents()));
assertTrue(connection.getHeaders().containsKey("Content-Length"));
}

Expand All @@ -61,8 +81,19 @@ public void shouldSetPayloadAndHeaders()
{
postRequest.addPayload("PAYLOAD");
postRequest.send();
assertEquals("PAYLOAD", postRequest.getBodyContents());
assertEquals("PAYLOAD", new String(postRequest.getBodyContents()));
assertTrue(connection.getHeaders().containsKey("Content-Length"));
}

@Test
public void shouldSetPayloadContentTypeAndHeaders()
{
postRequest.addPayload("PAYLOAD", "text/plain", Charset.forName("UTF-8"));
postRequest.send();
assertEquals("PAYLOAD", new String(postRequest.getBodyContents()));
assertTrue(connection.getHeaders().containsKey("Content-Length"));
assertTrue(connection.getHeaders().containsKey("Content-Type"));
assertThat(connection.getHeaders().get("Content-Type").toLowerCase(), is("text/plain; charset=utf-8"));
}

@Test
Expand Down
2 changes: 1 addition & 1 deletion src/test/java/org/scribe/utils/StreamUtilsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public void shouldCorrectlyDecodeAStream()
{
String value = "expected";
InputStream is = new ByteArrayInputStream(value.getBytes());
String decoded = StreamUtils.getStreamContents(is);
String decoded = new String(StreamUtils.getStreamContents(is));
assertEquals("expected", decoded);
}

Expand Down