Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

merge from upstream

  • Loading branch information...
commit 228b7ace8422d5e1965a18eea5a6ea9925625826 2 parents 794663b + 611c646
@tbruyelle tbruyelle authored
Showing with 859 additions and 95 deletions.
  1. +5 −0 .gitignore
  2. +3 −1 README.textile
  3. +17 −3 changelog.txt
  4. +5 −5 pom.xml
  5. +40 −0 src/main/java/org/scribe/builder/api/KaixinApi.java
  6. +43 −0 src/main/java/org/scribe/builder/api/LiveApi.java
  7. +47 −0 src/main/java/org/scribe/builder/api/NeteaseWeibooApi.java
  8. +39 −0 src/main/java/org/scribe/builder/api/PlurkApi.java
  9. +28 −0 src/main/java/org/scribe/builder/api/QWeiboApi.java
  10. +40 −0 src/main/java/org/scribe/builder/api/SapoApi.java
  11. +29 −0 src/main/java/org/scribe/builder/api/SimpleGeoApi.java
  12. +28 −0 src/main/java/org/scribe/builder/api/SinaWeiboApi.java
  13. +28 −0 src/main/java/org/scribe/builder/api/SohuWeiboApi.java
  14. +23 −0 src/main/java/org/scribe/builder/api/TwitterApi.java
  15. +1 −1  src/main/java/org/scribe/extractors/BaseStringExtractorImpl.java
  16. +1 −1  src/main/java/org/scribe/extractors/JsonTokenExtractor.java
  17. +2 −2 src/main/java/org/scribe/extractors/TokenExtractor20Impl.java
  18. +109 −33 src/main/java/org/scribe/model/Request.java
  19. +7 −7 src/main/java/org/scribe/model/Response.java
  20. +43 −0 src/main/java/org/scribe/utils/MapUtils.java
  21. +0 −41 src/main/java/org/scribe/utils/URLUtils.java
  22. +64 −0 src/test/java/org/scribe/examples/LiveExample.java
  23. +68 −0 src/test/java/org/scribe/examples/NeteaseWeiboExample.java
  24. +68 −0 src/test/java/org/scribe/examples/SinaWeiboExample.java
  25. +68 −0 src/test/java/org/scribe/examples/SohuWeiboExample.java
  26. +9 −0 src/test/java/org/scribe/extractors/TokenExtractor20Test.java
  27. +6 −0 src/test/java/org/scribe/model/ConnectionStub.java
  28. +38 −1 src/test/java/org/scribe/model/RequestTest.java
View
5 .gitignore
@@ -6,6 +6,11 @@
.settings
*.iml
+# IntelliJ Idea settings
+
+.idea
+scribe.iml
+
# Binaries
target
View
4 README.textile
@@ -38,6 +38,8 @@ h3. Supports all major 1.0a and 2.0 OAuth APIs out-of-the-box
* Yammer
+* Windows Live
+
* and many more! check the "examples folder":http://github.com/fernandezpablo85/scribe-java/tree/master/src/test/java/org/scribe/examples
h3. Small and modular
@@ -61,7 +63,7 @@ You can pull scribe from a maven repository, just add this to your __pom.xml__ f
@<dependency>@
@<groupId>org.scribe</groupId>@
@<artifactId>scribe</artifactId>@
- @<version>1.1.3</version>@
+ @<version>1.2.3</version>@
@</dependency>@
h1. Getting started in less than 2 minutes
View
20 changelog.txt
@@ -48,12 +48,26 @@
[1.2]
* REFACTOR: Moved scope inside OAuthConfig (breaks backwards compatibility)
* FEATURE: Added scopes to Facebook 2.0 Api
-<<<<<<< HEAD
* FEATURE: Added Plaintext signature for Yammer
* FEATURE: Added Twitter SSL endpoints (use TwitterApi.SSL.class)
[1.2.1]
* FEATURE: Added custom charset support to Request (thanks Eric Genet)
* FEATURE: Added support for Vkontakte (thanks dotbg)
-=======
->>>>>>> parent of 97f45d7... bounced version numbers for release
+ * FEATURE: Added Sohu Weibo, Netease Weibo & Sina Weibo Apis (thanks Arthur Wang)
+ * FEATURE: Added support for persistent Http Connections (thanks Craig Minton)
+
+[1.2.2]
+ * FIX: Added support for JDK 1.5. Issue #146 (thanks Sripathi Krishnan)
+ * FIX: Invalid character constant error message. Issue #137 (thanks Scott Scoble)
+ * FEATURE: Added a Api class to handle windows live authentication. Issue #135 (thanks Tomas Lin)
+ * FEATURE: Added refresh token feature for Yahoo! API. Issue #134 (thanks Aaron Foltz)
+ * FEATURE: Added support for Plurk API. Issue #130 (thanks Chia-Wei Li)
+ * FIX: Request.setConnectTimeout() and setReadTimeout() throw NPE. Issue #123 (thanks thepizzle)
+
+[1.2.3]
+ * FEATURE: Added default Content-Type header
+ * FEATURE: Sapo Api
+ * FEATURE: Plurk Mobile Api
+ * FEATURE: Kaixin and QWeibo Apis
+ * FEATURE: SimpleGeo Api
View
10 pom.xml
@@ -4,7 +4,7 @@
<groupId>org.scribe</groupId>
<artifactId>scribe</artifactId>
<packaging>jar</packaging>
- <version>1.2.0-patched</version>
+ <version>1.2.3</version>
<name>Scribe OAuth Library</name>
<description>The best OAuth library out there</description>
<url>http://github.com/fernandezpablo85/scribe-java</url>
@@ -63,11 +63,11 @@
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
- <source>1.6</source>
- <target>1.6</target>
+ <source>1.5</source>
+ <target>1.5</target>
</configuration>
</plugin>
- <!--plugin>
+ <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<executions>
@@ -79,7 +79,7 @@
</goals>
</execution>
</executions>
- </plugin-->
+ </plugin>
</plugins>
</build>
</project>
View
40 src/main/java/org/scribe/builder/api/KaixinApi.java
@@ -0,0 +1,40 @@
+package org.scribe.builder.api;
+
+import org.scribe.model.*;
+
+public class KaixinApi extends DefaultApi10a
+{
+ private static final String REQUEST_TOKEN_URL = "http://api.kaixin001.com/oauth/request_token";
+ private static final String ACCESS_TOKEN_URL = "http://api.kaixin001.com/oauth/access_token";
+ private static final String AUTHORIZE_URL = "http://api.kaixin001.com/oauth/authorize?oauth_token=%s";
+
+ @Override
+ public String getRequestTokenEndpoint()
+ {
+ return REQUEST_TOKEN_URL;
+ }
+
+ @Override
+ public String getAccessTokenEndpoint()
+ {
+ return ACCESS_TOKEN_URL;
+ }
+
+ @Override
+ public String getAuthorizationUrl(Token requestToken)
+ {
+ return String.format(AUTHORIZE_URL, requestToken.getToken());
+ }
+
+ @Override
+ public Verb getRequestTokenVerb()
+ {
+ return Verb.GET;
+ }
+
+ @Override
+ public Verb getAccessTokenVerb()
+ {
+ return Verb.GET;
+ }
+}
View
43 src/main/java/org/scribe/builder/api/LiveApi.java
@@ -0,0 +1,43 @@
+package org.scribe.builder.api;
+
+import org.scribe.extractors.*;
+
+import org.scribe.model.*;
+
+import org.scribe.utils.*;
+
+import static org.scribe.utils.URLUtils.*;
+
+public class LiveApi extends DefaultApi20
+{
+
+ private static final String AUTHORIZE_URL = "https://oauth.live.com/authorize?client_id=%s&redirect_uri=%s&response_type=code";
+ private static final String SCOPED_AUTHORIZE_URL = AUTHORIZE_URL + "&scope=%s";
+
+ @Override
+ public String getAccessTokenEndpoint()
+ {
+ return "https://oauth.live.com/token?grant_type=authorization_code";
+ }
+
+ @Override
+ public String getAuthorizationUrl(OAuthConfig config)
+ {
+ Preconditions.checkValidUrl(config.getCallback(), "Must provide a valid url as callback. Live does not support OOB");
+
+ // Append scope if present
+ if (config.hasScope())
+ {
+ return String.format(SCOPED_AUTHORIZE_URL, config.getApiKey(), formURLEncode(config.getCallback()), formURLEncode(config.getScope()));
+ } else
+ {
+ return String.format(AUTHORIZE_URL, config.getApiKey(), formURLEncode(config.getCallback()));
+ }
+ }
+
+ @Override
+ public AccessTokenExtractor getAccessTokenExtractor()
+ {
+ return new JsonTokenExtractor();
+ }
+}
View
47 src/main/java/org/scribe/builder/api/NeteaseWeibooApi.java
@@ -0,0 +1,47 @@
+package org.scribe.builder.api;
+
+import org.scribe.model.*;
+
+public class NeteaseWeibooApi extends DefaultApi10a
+{
+ private static final String REQUEST_TOKEN_URL = "http://api.t.163.com/oauth/request_token";
+ private static final String ACCESS_TOKEN_URL = "http://api.t.163.com/oauth/access_token";
+ private static final String AUTHORIZE_URL = "http://api.t.163.com/oauth/authorize?oauth_token=%s";
+ private static final String AUTHENTICATE_URL = "http://api.t.163.com/oauth/authenticate?oauth_token=%s";
+
+ @Override
+ public String getRequestTokenEndpoint()
+ {
+ return REQUEST_TOKEN_URL;
+ }
+
+ @Override
+ public String getAccessTokenEndpoint()
+ {
+ return ACCESS_TOKEN_URL;
+ }
+
+ @Override
+ /**
+ * this method will ignore your callback
+ * if you're creating a desktop client please choose this url
+ * else your can call getAuthenticateUrl
+ *
+ * via http://open.t.163.com/wiki/index.php?title=%E8%AF%B7%E6%B1%82%E7%94%A8%E6%88%B7%E6%8E%88%E6%9D%83Token(oauth/authorize)
+ */
+ public String getAuthorizationUrl(Token requestToken)
+ {
+ return String.format(AUTHORIZE_URL, requestToken.getToken());
+ }
+
+ /**
+ * this method is for web client with callback url
+ * if you're creating a desktop client please call getAuthorizationUrl
+ *
+ * via http://open.t.163.com/wiki/index.php?title=%E8%AF%B7%E6%B1%82%E7%94%A8%E6%88%B7%E6%8E%88%E6%9D%83Token(oauth/authenticate)
+ */
+ public String getAuthenticateUrl(Token requestToken)
+ {
+ return String.format(AUTHENTICATE_URL, requestToken.getToken());
+ }
+}
View
39 src/main/java/org/scribe/builder/api/PlurkApi.java
@@ -0,0 +1,39 @@
+package org.scribe.builder.api;
+
+import org.scribe.model.Token;
+
+public class PlurkApi extends DefaultApi10a
+{
+ private static final String REQUEST_TOKEN_URL = "http://www.plurk.com/OAuth/request_token";
+ private static final String AUTHORIZATION_URL = "http://www.plurk.com/OAuth/authorize?oauth_token=%s";
+ private static final String ACCESS_TOKEN_URL = "http://www.plurk.com/OAuth/access_token";
+
+ @Override
+ public String getRequestTokenEndpoint()
+ {
+ return REQUEST_TOKEN_URL;
+ }
+
+ @Override
+ public String getAuthorizationUrl(Token requestToken)
+ {
+ return String.format(AUTHORIZATION_URL, requestToken.getToken());
+ }
+
+ @Override
+ public String getAccessTokenEndpoint()
+ {
+ return ACCESS_TOKEN_URL;
+ }
+
+ public class Mobile extends PlurkApi
+ {
+ private static final String AUTHORIZATION_URL = "http://www.plurk.com/m/authorize?oauth_token=%s";
+
+ @Override
+ public String getAuthorizationUrl(Token requestToken)
+ {
+ return String.format(AUTHORIZATION_URL, requestToken.getToken());
+ }
+ }
+}
View
28 src/main/java/org/scribe/builder/api/QWeiboApi.java
@@ -0,0 +1,28 @@
+package org.scribe.builder.api;
+
+import org.scribe.model.*;
+
+public class QWeiboApi extends DefaultApi10a
+{
+ private static final String REQUEST_TOKEN_URL = "https://open.t.qq.com/cgi-bin/request_token";
+ private static final String ACCESS_TOKEN_URL = "https://open.t.qq.com/cgi-bin/access_token";
+ private static final String AUTHORIZE_URL = "https://open.t.qq.com/cgi-bin/authorize?oauth_token=%s";
+
+ @Override
+ public String getRequestTokenEndpoint()
+ {
+ return REQUEST_TOKEN_URL;
+ }
+
+ @Override
+ public String getAccessTokenEndpoint()
+ {
+ return ACCESS_TOKEN_URL;
+ }
+
+ @Override
+ public String getAuthorizationUrl(Token requestToken)
+ {
+ return String.format(AUTHORIZE_URL, requestToken.getToken());
+ }
+}
View
40 src/main/java/org/scribe/builder/api/SapoApi.java
@@ -0,0 +1,40 @@
+package org.scribe.builder.api;
+
+import org.scribe.model.*;
+
+public class SapoApi extends DefaultApi10a
+{
+ private static final String AUTHORIZE_URL = "https://id.sapo.pt/oauth/authorize?oauth_token=%s";
+ private static final String ACCESS_URL = "https://id.sapo.pt/oauth/access_token";
+ private static final String REQUEST_URL = "https://id.sapo.pt/oauth/request_token";
+
+ @Override
+ public String getAccessTokenEndpoint()
+ {
+ return ACCESS_URL;
+ }
+
+ @Override
+ public String getRequestTokenEndpoint()
+ {
+ return REQUEST_URL;
+ }
+
+ @Override
+ public String getAuthorizationUrl(Token requestToken)
+ {
+ return String.format(AUTHORIZE_URL, requestToken.getToken());
+ }
+
+ @Override
+ public Verb getRequestTokenVerb()
+ {
+ return Verb.GET;
+ }
+
+ @Override
+ public Verb getAccessTokenVerb()
+ {
+ return Verb.GET;
+ }
+}
View
29 src/main/java/org/scribe/builder/api/SimpleGeoApi.java
@@ -0,0 +1,29 @@
+package org.scribe.builder.api;
+
+import org.scribe.model.Token;
+
+/**
+ * @author: Pablo Fernandez
+ */
+public class SimpleGeoApi extends DefaultApi10a
+{
+ private static final String ENDPOINT = "these are not used since SimpleGeo uses 2 legged OAuth";
+
+ @Override
+ public String getRequestTokenEndpoint()
+ {
+ return ENDPOINT;
+ }
+
+ @Override
+ public String getAccessTokenEndpoint()
+ {
+ return ENDPOINT;
+ }
+
+ @Override
+ public String getAuthorizationUrl(Token requestToken)
+ {
+ return ENDPOINT;
+ }
+}
View
28 src/main/java/org/scribe/builder/api/SinaWeiboApi.java
@@ -0,0 +1,28 @@
+package org.scribe.builder.api;
+
+import org.scribe.model.*;
+
+public class SinaWeiboApi extends DefaultApi10a
+{
+ private static final String REQUEST_TOKEN_URL = "http://api.t.sina.com.cn/oauth/request_token";
+ private static final String ACCESS_TOKEN_URL = "http://api.t.sina.com.cn/oauth/access_token";
+ private static final String AUTHORIZE_URL = "http://api.t.sina.com.cn/oauth/authorize?oauth_token=%s";
+
+ @Override
+ public String getRequestTokenEndpoint()
+ {
+ return REQUEST_TOKEN_URL;
+ }
+
+ @Override
+ public String getAccessTokenEndpoint()
+ {
+ return ACCESS_TOKEN_URL;
+ }
+
+ @Override
+ public String getAuthorizationUrl(Token requestToken)
+ {
+ return String.format(AUTHORIZE_URL, requestToken.getToken());
+ }
+}
View
28 src/main/java/org/scribe/builder/api/SohuWeiboApi.java
@@ -0,0 +1,28 @@
+package org.scribe.builder.api;
+
+import org.scribe.model.*;
+
+public class SohuWeiboApi extends DefaultApi10a
+{
+ private static final String REQUEST_TOKEN_URL = "http://api.t.sohu.com/oauth/request_token";
+ private static final String ACCESS_TOKEN_URL = "http://api.t.sohu.com/oauth/access_token";
+ private static final String AUTHORIZE_URL = "http://api.t.sohu.com/oauth/authorize?oauth_token=%s";
+
+ @Override
+ public String getRequestTokenEndpoint()
+ {
+ return REQUEST_TOKEN_URL;
+ }
+
+ @Override
+ public String getAccessTokenEndpoint()
+ {
+ return ACCESS_TOKEN_URL;
+ }
+
+ @Override
+ public String getAuthorizationUrl(Token requestToken)
+ {
+ return String.format(AUTHORIZE_URL, requestToken.getToken());
+ }
+}
View
23 src/main/java/org/scribe/builder/api/TwitterApi.java
@@ -40,4 +40,27 @@ public String getRequestTokenEndpoint()
return "https://" + REQUEST_TOKEN_RESOURCE;
}
}
+
+ /**
+ * Twitter 'friendlier' authorization endpoint for OAuth.
+ *
+ * Uses SSL.
+ */
+ public static class Authenticate extends SSL
+ {
+ private static final String AUTHENTICATE_URL = "https://api.twitter.com/oauth/authenticate?oauth_token=%s";
+
+ @Override
+ public String getAuthorizationUrl(Token requestToken)
+ {
+ return String.format(AUTHENTICATE_URL, requestToken.getToken());
+ }
+ }
+
+ /**
+ * Just an alias to the default (SSL) authorization endpoint.
+ *
+ * Need to include this for symmetry with 'Authenticate' only.
+ */
+ public static class Authorize extends SSL{}
}
View
2  src/main/java/org/scribe/extractors/BaseStringExtractorImpl.java
@@ -36,7 +36,7 @@ private String getSortedAndEncodedParams(OAuthRequest request)
MapUtils.decodeAndAppendEntries(request.getBodyParams(), params);
MapUtils.decodeAndAppendEntries(request.getOauthParameters(), params);
params = MapUtils.sort(params);
- return URLUtils.percentEncode(URLUtils.concatSortedPercentEncodedParams(params));
+ return URLUtils.percentEncode(MapUtils.concatSortedPercentEncodedParams(params));
}
private void checkPreconditions(OAuthRequest request)
View
2  src/main/java/org/scribe/extractors/JsonTokenExtractor.java
@@ -8,7 +8,7 @@
public class JsonTokenExtractor implements AccessTokenExtractor
{
- private Pattern accessTokenPattern = Pattern.compile("\"access_token\":\"(\\S*?)\"");
+ private Pattern accessTokenPattern = Pattern.compile("\"access_token\":\\s*\"(\\S*?)\"");
@Override
public Token extract(String response)
View
4 src/main/java/org/scribe/extractors/TokenExtractor20Impl.java
@@ -12,7 +12,7 @@
*/
public class TokenExtractor20Impl implements AccessTokenExtractor
{
- private static final String TOKEN_REGEX = "access_token=(\\S*?)(&(\\S*))?";
+ private static final String TOKEN_REGEX = "access_token=([^&]+)";
private static final String EMPTY_SECRET = "";
/**
@@ -23,7 +23,7 @@ public Token extract(String response)
Preconditions.checkEmptyString(response, "Response body is incorrect. Can't extract a token from an empty string");
Matcher matcher = Pattern.compile(TOKEN_REGEX).matcher(response);
- if (matcher.matches())
+ if (matcher.find())
{
String token = URLUtils.formURLDecode(matcher.group(1));
return new Token(token, EMPTY_SECRET, response);
View
142 src/main/java/org/scribe/model/Request.java
@@ -11,12 +11,14 @@
/**
* Represents an HTTP Request object
- *
+ *
* @author Pablo Fernandez
*/
class Request
{
private static final String CONTENT_LENGTH = "Content-Length";
+ private static final String CONTENT_TYPE = "Content-Type";
+ public static final String DEFAULT_CONTENT_TYPE = "application/x-www-form-urlencoded";
private String url;
private Verb verb;
@@ -26,10 +28,14 @@
private String payload = null;
private HttpURLConnection connection;
private String charset;
+ private byte[] bytePayload = null;
+ private boolean connectionKeepAlive = false;
+ private Long connectTimeout = null;
+ private Long readTimeout = null;
/**
* Creates a new Http Request
- *
+ *
* @param verb Http Verb (GET, POST, etc)
* @param url url with optional querystring parameters.
*/
@@ -44,7 +50,7 @@ public Request(Verb verb, String url)
/**
* Execute the request and return a {@link Response}
- *
+ *
* @return Http Response
* @throws RuntimeException
* if the connection cannot be created.
@@ -55,9 +61,14 @@ public Response send()
{
createConnection();
return doSend();
- } catch (IOException ioe)
+ }
+ catch (UnknownHostException uhe)
+ {
+ throw new OAuthException("Could not reach the desired host. Check your network connection.", uhe);
+ }
+ catch (IOException ioe)
{
- throw new OAuthException("Problems while creating connection", ioe);
+ throw new OAuthException("Problems while creating connection.", ioe);
}
}
@@ -68,7 +79,7 @@ private void createConnection() throws IOException
URLUtils.appendParametersToQueryString(url, querystringParams) : url;
if (connection == null)
{
- System.setProperty("http.keepAlive", "false");
+ System.setProperty("http.keepAlive", connectionKeepAlive ? "true" : "false");
connection = (HttpURLConnection) new URL(effectiveUrl).openConnection();
}
}
@@ -76,10 +87,18 @@ private void createConnection() throws IOException
Response doSend() throws IOException
{
connection.setRequestMethod(this.verb.name());
+ if (connectTimeout != null)
+ {
+ connection.setConnectTimeout(connectTimeout.intValue());
+ }
+ if (readTimeout != null)
+ {
+ connection.setReadTimeout(readTimeout.intValue());
+ }
addHeaders(connection);
if (verb.equals(Verb.PUT) || verb.equals(Verb.POST))
{
- addBody(connection, getBodyContents());
+ addBody(connection, getByteBodyContents());
}
return new Response(connection);
}
@@ -90,13 +109,17 @@ void addHeaders(HttpURLConnection conn)
conn.setRequestProperty(key, headers.get(key));
}
- void addBody(HttpURLConnection conn, String content) throws IOException
+ void addBody(HttpURLConnection conn, byte[] content) throws IOException
{
- if (this.charset == null)
- this.charset = Charset.defaultCharset().name();
- conn.setRequestProperty(CONTENT_LENGTH, String.valueOf(content.getBytes(charset).length));
+ conn.setRequestProperty(CONTENT_LENGTH, String.valueOf(content.length));
+
+ // Set default content type if none is set.
+ if (conn.getRequestProperty(CONTENT_TYPE) == null)
+ {
+ conn.setRequestProperty(CONTENT_TYPE, DEFAULT_CONTENT_TYPE);
+ }
conn.setDoOutput(true);
- conn.getOutputStream().write(content.getBytes(charset));
+ conn.getOutputStream().write( content );
if ( getVerb().equals( Verb.POST ) )
{
OutputStreamWriter wr = new OutputStreamWriter( conn.getOutputStream() );
@@ -107,7 +130,7 @@ void addBody(HttpURLConnection conn, String content) throws IOException
/**
* Add an HTTP Header to the Request
- *
+ *
* @param key the header name
* @param value the header value
*/
@@ -118,7 +141,7 @@ public void addHeader(String key, String value)
/**
* Add a body Parameter (for POST/ PUT Requests)
- *
+ *
* @param key the parameter name
* @param value the parameter value
*/
@@ -140,12 +163,12 @@ public void addQuerystringParameter(String key, String value)
/**
* 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(String payload)
@@ -154,8 +177,18 @@ public void addPayload(String payload)
}
/**
+ * Overloaded version for byte arrays
+ *
+ * @param payload
+ */
+ public void addPayload(byte[] payload)
+ {
+ this.bytePayload = payload;
+ }
+
+ /**
* Get a {@link Map} of the query string parameters.
- *
+ *
* @return a map containing the query string parameters
* @throws OAuthException if the URL is not valid
*/
@@ -165,7 +198,7 @@ public void addPayload(String payload)
{
Map<String, String> params = new HashMap<String, String>();
String queryString = new URL(url).getQuery();
- params.putAll(URLUtils.queryStringToMap(queryString));
+ params.putAll(MapUtils.queryStringToMap(queryString));
params.putAll(this.querystringParams);
return params;
}
@@ -177,7 +210,7 @@ public void addPayload(String payload)
/**
* Obtains a {@link Map} of the body parameters.
- *
+ *
* @return a map containing the body parameters.
*/
public Map<String, String> getBodyParams()
@@ -187,7 +220,7 @@ public void addPayload(String payload)
/**
* Obtains the URL of the HTTP Request.
- *
+ *
* @return the original URL of the HTTP Request
*/
public String getUrl()
@@ -197,7 +230,7 @@ public String getUrl()
/**
* Returns the URL without the port and the query string part.
- *
+ *
* @return the OAuth-sanitized URL
*/
public String getSanitizedUrl()
@@ -207,27 +240,49 @@ public String getSanitizedUrl()
/**
* Returns the body of the request
- *
+ *
* @return form encoded string
+ * @throws OAuthException if the charset chosen is not supported
*/
public String getBodyContents()
{
- return (payload != null) ? payload : URLUtils.formURLEncodeMap(bodyParams);
+ try
+ {
+ return new String(getByteBodyContents(),getCharset());
+ }
+ catch(UnsupportedEncodingException uee)
+ {
+ throw new OAuthException("Unsupported Charset: "+charset, uee);
+ }
+ }
+
+ byte[] getByteBodyContents()
+ {
+ if (bytePayload != null) return bytePayload;
+ String body = (payload != null) ? payload : URLUtils.formURLEncodeMap(bodyParams);
+ try
+ {
+ return body.getBytes(getCharset());
+ }
+ catch(UnsupportedEncodingException uee)
+ {
+ throw new OAuthException("Unsupported Charset: "+getCharset(), uee);
+ }
}
/**
* Returns the HTTP Verb
- *
+ *
* @return the verb
*/
public Verb getVerb()
{
return verb;
}
-
+
/**
* Returns the connection headers as a {@link Map}
- *
+ *
* @return map of headers
*/
public Map<String, String> getHeaders()
@@ -236,27 +291,37 @@ public Verb getVerb()
}
/**
+ * Returns the connection charset. Defaults to {@link Charset} defaultCharset if not set
+ *
+ * @return charset
+ */
+ public String getCharset()
+ {
+ return charset == null ? Charset.defaultCharset().name() : charset;
+ }
+
+ /**
* Sets the connect timeout for the underlying {@link HttpURLConnection}
- *
+ *
* @param duration duration of the timeout
- *
+ *
* @param unit unit of time (milliseconds, seconds, etc)
*/
public void setConnectTimeout(int duration, TimeUnit unit)
{
- this.connection.setConnectTimeout((int) unit.toMillis(duration));
+ this.connectTimeout = unit.toMillis(duration);
}
/**
* Sets the read timeout for the underlying {@link HttpURLConnection}
- *
+ *
* @param duration duration of the timeout
- *
+ *
* @param unit unit of time (milliseconds, seconds, etc)
*/
public void setReadTimeout(int duration, TimeUnit unit)
{
- this.connection.setReadTimeout((int) unit.toMillis(duration));
+ this.readTimeout = unit.toMillis(duration);
}
/**
@@ -269,6 +334,17 @@ public void setCharset(String charsetName)
this.charset = charsetName;
}
+ /**
+ * Sets wether the underlying Http Connection is persistent or not.
+ *
+ * @see http://download.oracle.com/javase/1.5.0/docs/guide/net/http-keepalive.html
+ * @param connectionKeepAlive
+ */
+ public void setConnectionKeepAlive(boolean connectionKeepAlive)
+ {
+ this.connectionKeepAlive = connectionKeepAlive;
+ }
+
/*
* We need this in order to stub the connection object for test cases
*/
View
14 src/main/java/org/scribe/model/Response.java
@@ -27,11 +27,12 @@
connection.connect();
code = connection.getResponseCode();
headers = parseHeaders(connection);
- stream = wasSuccessful() ? connection.getInputStream() : connection.getErrorStream();
- } catch (UnknownHostException e)
+ stream = isSuccessful() ? connection.getInputStream() : connection.getErrorStream();
+ }
+ catch (UnknownHostException e)
{
code = 404;
- body = EMPTY;
+ body = Response.EMPTY;
}
}
@@ -56,7 +57,7 @@ private String parseBodyContents()
return headers;
}
- private boolean wasSuccessful()
+ public boolean isSuccessful()
{
return getCode() >= 200 && getCode() < 400;
}
@@ -105,10 +106,9 @@ public int getCode()
/**
* Obtains a single HTTP Header value, or null if undefined
*
- * @param header
- * name
+ * @param name the header name.
*
- * @return header value or null
+ * @return header value or null.
*/
public String getHeader(String name)
{
View
43 src/main/java/org/scribe/utils/MapUtils.java
@@ -9,6 +9,10 @@
*/
public class MapUtils
{
+ private static final String EMPTY_STRING = "";
+ private static final String PAIR_SEPARATOR = "=";
+ private static final String PARAM_SEPARATOR = "&";
+
/**
* Sorts a Map
*
@@ -48,4 +52,43 @@ public static void decodeAndAppendEntries(Map<String, String> source, Map<String
target.put(URLUtils.percentEncode(key), URLUtils.percentEncode(source.get(key)));
}
}
+
+ /**
+ * Concats a key-value map into a querystring-like String
+ *
+ * @param params key-value map
+ * @return querystring-like String
+ */
+ public static String concatSortedPercentEncodedParams(Map<String, String> params)
+ {
+ StringBuilder result = new StringBuilder();
+ for (String key : params.keySet())
+ {
+ result.append(key).append(PAIR_SEPARATOR);
+ result.append(params.get(key)).append(PARAM_SEPARATOR);
+ }
+ return result.toString().substring(0, result.length() - 1);
+ }
+
+ /**
+ * Parses and form-urldecodes a querystring-like string into a map
+ *
+ * @param queryString querystring-like String
+ * @return a map with the form-urldecoded parameters
+ */
+ public static Map<String, String> queryStringToMap(String queryString)
+ {
+ Map<String, String> result = new HashMap<String, String>();
+ if (queryString != null && queryString.length() > 0)
+ {
+ for (String param : queryString.split(PARAM_SEPARATOR))
+ {
+ String pair[] = param.split(PAIR_SEPARATOR);
+ String key = URLUtils.formURLDecode(pair[0]);
+ String value = pair.length > 1 ? URLUtils.formURLDecode(pair[1]) : EMPTY_STRING;
+ result.put(key, value);
+ }
+ }
+ return result;
+ }
}
View
41 src/main/java/org/scribe/utils/URLUtils.java
@@ -133,47 +133,6 @@ public static String appendParametersToQueryString(String url, Map<String, Strin
}
}
- /**
- * Concats a key-value map into a querystring-like String
- *
- * @param params key-value map
- * @return querystring-like String
- */
- // TODO Move to MapUtils
- public static String concatSortedPercentEncodedParams(Map<String, String> params)
- {
- StringBuilder result = new StringBuilder();
- for (String key : params.keySet())
- {
- result.append(key).append(PAIR_SEPARATOR);
- result.append(params.get(key)).append(PARAM_SEPARATOR);
- }
- return result.toString().substring(0, result.length() - 1);
- }
-
- /**
- * Parses and form-urldecodes a querystring-like string into a map
- *
- * @param queryString querystring-like String
- * @return a map with the form-urldecoded parameters
- */
- // TODO Move to MapUtils
- public static Map<String, String> queryStringToMap(String queryString)
- {
- Map<String, String> result = new HashMap<String, String>();
- if (queryString != null && queryString.length() > 0)
- {
- for (String param : queryString.split(PARAM_SEPARATOR))
- {
- String pair[] = param.split(PAIR_SEPARATOR);
- String key = formURLDecode(pair[0]);
- String value = pair.length > 1 ? formURLDecode(pair[1]) : EMPTY_STRING;
- result.put(key, value);
- }
- }
- return result;
- }
-
private static final class EncodingRule
{
private final String ch;
View
64 src/test/java/org/scribe/examples/LiveExample.java
@@ -0,0 +1,64 @@
+package org.scribe.examples;
+
+import java.util.*;
+
+import org.scribe.builder.*;
+import org.scribe.builder.api.*;
+import org.scribe.model.*;
+import org.scribe.oauth.*;
+
+public class LiveExample
+{
+ private static final String PROTECTED_RESOURCE_URL = "https://api.foursquare.com/v2/users/self/friends?oauth_token=";
+ private static final Token EMPTY_TOKEN = null;
+
+ public static void main(String[] args)
+ {
+ // Replace these with your own api key and secret
+ String apiKey = "";
+ String apiSecret = "";
+ OAuthService service = new ServiceBuilder()
+ .provider(LiveApi.class)
+ .apiKey(apiKey)
+ .apiSecret(apiSecret)
+ .scope("wl.basic")
+ .callback("http://localhost:9000/")
+ .build();
+ Scanner in = new Scanner(System.in);
+
+ System.out.println("=== Windows Live's OAuth Workflow ===");
+ System.out.println();
+
+ // Obtain the Authorization URL
+ System.out.println("Fetching the Authorization URL...");
+ String authorizationUrl = service.getAuthorizationUrl(EMPTY_TOKEN);
+ System.out.println("Got the Authorization URL!");
+ System.out.println("Now go and authorize Scribe here:");
+ System.out.println(authorizationUrl);
+ System.out.println("And paste the authorization code here");
+ System.out.print(">>");
+ Verifier verifier = new Verifier(in.nextLine());
+ System.out.println();
+
+ // Trade the Request Token and Verfier for the Access Token
+ System.out.println("Trading the Request Token for an Access Token...");
+ Token accessToken = service.getAccessToken(EMPTY_TOKEN, verifier);
+ System.out.println("Got the Access Token!");
+ System.out.println("(if your curious it looks like this: " + accessToken + " )");
+ System.out.println();
+
+ // Now let's go and ask for a protected resource!
+ System.out.println("Now we're going to access a protected resource...");
+ OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL + accessToken.getToken());
+ service.signRequest(accessToken, request);
+ Response response = request.send();
+ System.out.println("Got it! Lets see what we found...");
+ System.out.println();
+ System.out.println(response.getCode());
+ System.out.println(response.getBody());
+
+ System.out.println();
+ System.out.println("Thats it man! Go and build something awesome with Scribe! :)");
+
+ }
+}
View
68 src/test/java/org/scribe/examples/NeteaseWeiboExample.java
@@ -0,0 +1,68 @@
+package org.scribe.examples;
+
+import java.util.*;
+
+import org.scribe.builder.*;
+import org.scribe.builder.api.*;
+import org.scribe.model.*;
+import org.scribe.oauth.*;
+
+public class NeteaseWeiboExample
+{
+ private static final String NETWORK_NAME = "NetEase(163.com) Weibo";
+ private static final String PROTECTED_RESOURCE_URL = "http://api.t.163.com/account/verify_credentials.json";
+
+ public static void main(String[] args)
+ {
+ // Replace these with your own api key and secret
+ String apiKey = "your key";
+ String apiSecret = "your secret";
+ OAuthService service = new ServiceBuilder()
+ .provider(NeteaseWeibooApi.class)
+ .apiKey(apiKey)
+ .apiSecret(apiSecret)
+ .build();
+ Scanner in = new Scanner(System.in);
+
+ System.out.println("=== " + NETWORK_NAME + "'s OAuth Workflow ===");
+ System.out.println();
+
+ // Grab a request token.
+ System.out.println("Fetching request token.");
+ Token requestToken = service.getRequestToken();
+ System.out.println("Got it ... ");
+ System.out.println(requestToken.getToken());
+
+ // Obtain the Authorization URL
+ System.out.println("Fetching the Authorization URL...");
+ String authorizationUrl = service.getAuthorizationUrl(requestToken);
+ System.out.println("Got the Authorization URL!");
+ System.out.println("Now go and authorize Scribe here:");
+ System.out.println(authorizationUrl);
+ System.out.println("And paste the authorization code here");
+ System.out.print(">>");
+ Verifier verifier = new Verifier(in.nextLine());
+ System.out.println();
+
+ // Trade the Request Token and Verfier for the Access Token
+ System.out.println("Trading the Request Token for an Access Token...");
+ Token accessToken = service.getAccessToken(requestToken, verifier);
+ System.out.println("Got the Access Token!");
+ System.out.println("(if your curious it looks like this: "
+ + accessToken + " )");
+ System.out.println();
+
+ // Now let's go and ask for a protected resource!
+ System.out.println("Now we're going to access a protected resource...");
+ OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL);
+ service.signRequest(accessToken, request);
+ Response response = request.send();
+ System.out.println("Got it! Lets see what we found...");
+ System.out.println();
+ System.out.println(response.getCode());
+ System.out.println(response.getBody());
+
+ System.out.println();
+ System.out.println("Thats it man! Go and build something awesome with Scribe! :)");
+ }
+}
View
68 src/test/java/org/scribe/examples/SinaWeiboExample.java
@@ -0,0 +1,68 @@
+package org.scribe.examples;
+
+import java.util.*;
+
+import org.scribe.builder.*;
+import org.scribe.builder.api.*;
+import org.scribe.model.*;
+import org.scribe.oauth.*;
+
+public class SinaWeiboExample
+{
+ private static final String NETWORK_NAME = "SinaWeibo";
+ private static final String PROTECTED_RESOURCE_URL = "http://api.t.sina.com.cn/account/verify_credentials.json";
+
+ public static void main(String[] args)
+ {
+ // Replace these with your own api key and secret
+ String apiKey = "your key";
+ String apiSecret = "your secret";
+ OAuthService service = new ServiceBuilder()
+ .provider(SinaWeiboApi.class)
+ .apiKey(apiKey)
+ .apiSecret(apiSecret)
+ .build();
+ Scanner in = new Scanner(System.in);
+
+ System.out.println("=== " + NETWORK_NAME + "'s OAuth Workflow ===");
+ System.out.println();
+
+ // Grab a request token.
+ System.out.println("Fetching request token.");
+ Token requestToken = service.getRequestToken();
+ System.out.println("Got it ... ");
+ System.out.println(requestToken.getToken());
+
+ // Obtain the Authorization URL
+ System.out.println("Fetching the Authorization URL...");
+ String authorizationUrl = service.getAuthorizationUrl(requestToken);
+ System.out.println("Got the Authorization URL!");
+ System.out.println("Now go and authorize Scribe here:");
+ System.out.println(authorizationUrl);
+ System.out.println("And paste the authorization code here");
+ System.out.print(">>");
+ Verifier verifier = new Verifier(in.nextLine());
+ System.out.println();
+
+ // Trade the Request Token and Verfier for the Access Token
+ System.out.println("Trading the Request Token for an Access Token...");
+ Token accessToken = service.getAccessToken(requestToken, verifier);
+ System.out.println("Got the Access Token!");
+ System.out.println("(if your curious it looks like this: "
+ + accessToken + " )");
+ System.out.println();
+
+ // Now let's go and ask for a protected resource!
+ System.out.println("Now we're going to access a protected resource...");
+ OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL);
+ service.signRequest(accessToken, request);
+ Response response = request.send();
+ System.out.println("Got it! Lets see what we found...");
+ System.out.println();
+ System.out.println(response.getCode());
+ System.out.println(response.getBody());
+
+ System.out.println();
+ System.out.println("Thats it man! Go and build something awesome with Scribe! :)");
+ }
+}
View
68 src/test/java/org/scribe/examples/SohuWeiboExample.java
@@ -0,0 +1,68 @@
+package org.scribe.examples;
+
+import java.util.*;
+
+import org.scribe.builder.*;
+import org.scribe.builder.api.*;
+import org.scribe.model.*;
+import org.scribe.oauth.*;
+
+public class SohuWeiboExample
+{
+ private static final String NETWORK_NAME = "SohuWeibo";
+ private static final String PROTECTED_RESOURCE_URL = "http://api.t.sohu.com/account/verify_credentials.json";
+
+ public static void main(String[] args)
+ {
+ // Replace these with your own api key and secret
+ String apiKey = "your_key";
+ String apiSecret = "your_secret";
+ OAuthService service = new ServiceBuilder()
+ .provider(SohuWeiboApi.class)
+ .apiKey(apiKey)
+ .apiSecret(apiSecret)
+ .build();
+ Scanner in = new Scanner(System.in);
+
+ System.out.println("=== " + NETWORK_NAME + "'s OAuth Workflow ===");
+ System.out.println();
+
+ // Grab a request token.
+ System.out.println("Fetching request token.");
+ Token requestToken = service.getRequestToken();
+ System.out.println("Got it ... ");
+ System.out.println(requestToken.getToken());
+
+ // Obtain the Authorization URL
+ System.out.println("Fetching the Authorization URL...");
+ String authorizationUrl = service.getAuthorizationUrl(requestToken);
+ System.out.println("Got the Authorization URL!");
+ System.out.println("Now go and authorize Scribe here:");
+ System.out.println(authorizationUrl);
+ System.out.println("And paste the authorization code here");
+ System.out.print(">>");
+ Verifier verifier = new Verifier(in.nextLine());
+ System.out.println();
+
+ // Trade the Request Token and Verfier for the Access Token
+ System.out.println("Trading the Request Token for an Access Token...");
+ Token accessToken = service.getAccessToken(requestToken, verifier);
+ System.out.println("Got the Access Token!");
+ System.out.println("(if your curious it looks like this: "
+ + accessToken + " )");
+ System.out.println();
+
+ // Now let's go and ask for a protected resource!
+ System.out.println("Now we're going to access a protected resource...");
+ OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL);
+ service.signRequest(accessToken, request);
+ Response response = request.send();
+ System.out.println("Got it! Lets see what we found...");
+ System.out.println();
+ System.out.println(response.getCode());
+ System.out.println(response.getBody());
+
+ System.out.println();
+ System.out.println("Thats it man! Go and build something awesome with Scribe! :)");
+ }
+}
View
9 src/test/java/org/scribe/extractors/TokenExtractor20Test.java
@@ -35,6 +35,15 @@ public void shouldExtractTokenFromResponseWithExpiresParam()
assertEquals("", extracted.getSecret());
}
+ @Test
+ public void shouldExtractTokenFromResponseWithManyParameters()
+ {
+ String response = "access_token=foo1234&other_stuff=yeah_we_have_this_too&number=42";
+ Token extracted = extractor.extract(response);
+ assertEquals("foo1234", extracted.getToken());
+ assertEquals("", extracted.getSecret());
+ }
+
@Test(expected = OAuthException.class)
public void shouldThrowExceptionIfTokenIsAbsent()
{
View
6 src/test/java/org/scribe/model/ConnectionStub.java
@@ -22,6 +22,12 @@ public void setRequestProperty(String key, String value)
headers.put(key, value);
}
+ @Override
+ public String getRequestProperty(String s)
+ {
+ return headers.get(s);
+ }
+
public Map<String, String> getHeaders()
{
return headers;
View
39 src/test/java/org/scribe/model/RequestTest.java
@@ -6,7 +6,6 @@
public class RequestTest
{
-
private Request getRequest;
private Request postRequest;
private ConnectionStub connection;
@@ -80,4 +79,42 @@ public void shouldHandleQueryStringSpaceEncodingProperly()
{
assertTrue(getRequest.getQueryStringParams().get("other param").equals("value with spaces"));
}
+
+ @Test
+ public void shouldAutomaticallyAddContentTypeForPostRequestsWithBytePayload()
+ {
+ postRequest.addPayload("PAYLOAD".getBytes());
+ postRequest.send();
+ assertEquals(Request.DEFAULT_CONTENT_TYPE, connection.getHeaders().get("Content-Type"));
+ }
+
+ @Test
+ public void shouldAutomaticallyAddContentTypeForPostRequestsWithStringPayload()
+ {
+ postRequest.addPayload("PAYLOAD");
+ postRequest.send();
+ assertEquals(Request.DEFAULT_CONTENT_TYPE, connection.getHeaders().get("Content-Type"));
+ }
+
+ @Test
+ public void shouldAutomaticallyAddContentTypeForPostRequestsWithBodyParameters()
+ {
+ postRequest.send();
+ assertEquals(Request.DEFAULT_CONTENT_TYPE, connection.getHeaders().get("Content-Type"));
+ }
+
+ @Test
+ public void shouldBeAbleToOverrideItsContentType()
+ {
+ postRequest.addHeader("Content-Type", "my-content-type");
+ postRequest.send();
+ assertEquals("my-content-type", connection.getHeaders().get("Content-Type"));
+ }
+
+ @Test
+ public void shouldNotAddContentTypeForGetRequests()
+ {
+ getRequest.send();
+ assertFalse(connection.getHeaders().containsKey("Content-Type"));
+ }
}
Please sign in to comment.
Something went wrong with that request. Please try again.