Skip to content
This repository was archived by the owner on Feb 14, 2020. It is now read-only.

Convert to HttpURLConnection/OkHttp #12

Merged
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,26 @@ public class DefaultOAuthProvider extends AbstractOAuthProvider {

private static final long serialVersionUID = 1L;

private transient HttpURLConnectionClient httpURLConnectionClient;

public DefaultOAuthProvider(String requestTokenEndpointUrl, String accessTokenEndpointUrl,
String authorizationWebsiteUrl) {
super(requestTokenEndpointUrl, accessTokenEndpointUrl, authorizationWebsiteUrl);
this.httpURLConnectionClient = HttpURLConnectionClient.create();
}

public DefaultOAuthProvider(String requestTokenEndpointUrl, String accessTokenEndpointUrl,
String authorizationWebsiteUrl, HttpURLConnectionClient httpURLConnectionClient) {
super(requestTokenEndpointUrl, accessTokenEndpointUrl, authorizationWebsiteUrl);
this.httpURLConnectionClient = httpURLConnectionClient;
}

public void setHttpURLConnectionClient(HttpURLConnectionClient httpURLConnectionClient) {
this.httpURLConnectionClient = httpURLConnectionClient;
}

protected HttpRequest createRequest(String endpointUrl) throws MalformedURLException,
IOException {
HttpURLConnection connection = (HttpURLConnection) new URL(endpointUrl).openConnection();
protected HttpRequest createRequest(String endpointUrl) throws Exception {
HttpURLConnection connection = httpURLConnectionClient.open(new URL(endpointUrl));
connection.setRequestMethod("POST");
connection.setAllowUserInteraction(false);
connection.setRequestProperty("Content-Length", "0");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.parse.internal.signpost.basic;

import java.io.IOException;
import java.lang.reflect.Method;
import java.net.HttpURLConnection;
import java.net.URL;

/**
* Adapter class to provide HttpURLConnection, using android HttpURLConnection or OkHttp
*/
public final class HttpURLConnectionClient {
private final boolean isUsingOkHttp;
private final Object okUrlFactory;
private final Method okUrlFactoryOpen;

private HttpURLConnectionClient(boolean isUsingOkHttp, Object okUrlFactory, Method okUrlFactoryOpen) {
this.isUsingOkHttp = isUsingOkHttp;
this.okUrlFactory = okUrlFactory;
this.okUrlFactoryOpen = okUrlFactoryOpen;
}

public static HttpURLConnectionClient create() {
try {
final Class okHttpClientClass = Class.forName("com.squareup.okhttp.OkHttpClient");
final Object okHttpClient = okHttpClientClass.getConstructor().newInstance();
final Class okUrlFactoryClass = Class.forName("com.squareup.okhttp.OkUrlFactory");
final Object okUrlFactory = okUrlFactoryClass.getConstructor(okHttpClientClass).newInstance(okHttpClient);
final Method okUrlFactoryOpen = okUrlFactoryClass.getMethod("open", URL.class);
return new HttpURLConnectionClient(true, okUrlFactory, okUrlFactoryOpen);
} catch (Exception e) {
return new HttpURLConnectionClient(true, null, null);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're not the biggest fans of static globals, could you move the reference to a instance on Twitter that get's passed into DefaultOAuthProvider? I'm ok with removing the global reference, but using a static factory newInstance() instead of getInstance().


public HttpURLConnection open(URL url) throws Exception {
if (isUsingOkHttp) {
return (HttpURLConnection) okUrlFactoryOpen.invoke(okUrlFactory, url);
} else {
return (HttpURLConnection) url.openConnection();
}
}
}
31 changes: 21 additions & 10 deletions library/src/main/java/com/parse/twitter/Twitter.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@
*/
package com.parse.twitter;

import com.parse.internal.signpost.basic.DefaultOAuthConsumer;
import com.parse.internal.signpost.basic.DefaultOAuthProvider;
import com.parse.internal.signpost.basic.HttpURLConnectionClient;
import org.apache.http.client.methods.HttpUriRequest;

import android.app.ProgressDialog;
import android.content.Context;
import android.net.Uri;
import android.net.http.AndroidHttpClient;
import android.os.AsyncTask;
import android.webkit.CookieSyncManager;

Expand All @@ -23,9 +25,10 @@
import com.parse.internal.signpost.OAuthConsumer;
import com.parse.internal.signpost.OAuthProvider;
import com.parse.internal.signpost.commonshttp.CommonsHttpOAuthConsumer;
import com.parse.internal.signpost.commonshttp.CommonsHttpOAuthProvider;
import com.parse.internal.signpost.http.HttpParameters;

import java.net.HttpURLConnection;

public class Twitter {
private static final String USER_AGENT = "Parse Android SDK";

Expand All @@ -49,6 +52,8 @@ public class Twitter {
private String userId;
private String screenName;

private final HttpURLConnectionClient httpURLConnectionClient = HttpURLConnectionClient.create();

public Twitter(String consumerKey, String consumerSecret) {
this.consumerKey = consumerKey;
this.consumerSecret = consumerSecret;
Expand Down Expand Up @@ -114,21 +119,27 @@ public void signRequest(HttpUriRequest request) {
}
}

public void signRequest(HttpURLConnection request) {
OAuthConsumer consumer = new DefaultOAuthConsumer(getConsumerKey(), getConsumerSecret());
consumer.setTokenWithSecret(getAuthToken(), getAuthTokenSecret());
try {
consumer.sign(request);
} catch (Exception e) {
throw new RuntimeException(e);
}
}

public void authorize(final Context context, final AsyncCallback callback) {
if (getConsumerKey() == null || getConsumerKey().length() == 0 || getConsumerSecret() == null
|| getConsumerSecret().length() == 0) {
throw new IllegalStateException(
"Twitter must be initialized with a consumer key and secret before authorization.");
}

final OAuthProvider provider = new CommonsHttpOAuthProvider(
REQUEST_TOKEN_URL, ACCESS_TOKEN_URL, AUTHORIZE_URL,
// Use AndroidHttpClient due to a MITM vulnerability with Apache's default
// HostnameVerifier through HttpClient.
//TODO (grantland): Re-use same HttpClient everywhere. We can't do this now due to packaging.
AndroidHttpClient.newInstance(USER_AGENT, context));
final OAuthConsumer consumer = new CommonsHttpOAuthConsumer(getConsumerKey(),
getConsumerSecret());
final OAuthProvider provider = new DefaultOAuthProvider(REQUEST_TOKEN_URL, ACCESS_TOKEN_URL, AUTHORIZE_URL,
httpURLConnectionClient);
provider.setRequestHeader("User-Agent", USER_AGENT);
final OAuthConsumer consumer = new DefaultOAuthConsumer(getConsumerKey(), getConsumerSecret());

final ProgressDialog progress = new ProgressDialog(context);
progress.setMessage("Loading...");
Expand Down