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

Conversation

zefei
Copy link

@zefei zefei commented Nov 3, 2015

Fix #9

  • overloaded Twitter.signRequest to accept HttpURLConnection
  • use OkHttp instead of HttpURLConnection if OkHttp exists in user's classpath

Test:

  • Logged all changed code paths to see see that DefaultOAuthConsumer/Provider work,
    HttpURLConnection and OkHttp both work in different dependency settings
  • Logs were removed afterwards

@facebook-github-bot
Copy link

By analyzing the blame information on this pull request, we identified @wangmengyan95 to be a potential reviewer.

@grantland
Copy link
Contributor

This looks super good! Just a few nits 😄

It also looks like you've resolved #7 with this as well!

@@ -38,7 +38,7 @@ public DefaultOAuthProvider(String requestTokenEndpointUrl, String accessTokenEn

protected HttpRequest createRequest(String endpointUrl) throws MalformedURLException,
IOException {
HttpURLConnection connection = (HttpURLConnection) new URL(endpointUrl).openConnection();
HttpURLConnection connection = HttpURLConnectionProvider.getInstance().open(new URL(endpointUrl));
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's pass in a HttpURLConnectionProvider instance through the constructor to match the CommonsHttpOAuthProvider.

@facebook-github-bot
Copy link

@zefei updated the pull request.

private Object okUrlFactory = null;
private Method okUrlFactoryOpen = null;

protected HttpURLConnectionClient() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Might as well make this private

@grantland
Copy link
Contributor

Passing back for revision. I'm ok with the 4 spaces in that file since it matches the rest of that package.

@facebook-github-bot
Copy link

@zefei updated the pull request.

@grantland
Copy link
Contributor

Everything looks good! Could you also remove this line since we won't be needing org.apache.http anymore: https://github.com/ParsePlatform/ParseTwitterUtils-Android/blob/master/library/build.gradle#L22

Lastly, it'd be great if we didn't use reflection to utilize OkHttp, so we can rely on compiler errors if any OkHttp APIs change (they shouldn't, but just in case). We have an example on how we did it in our SDK that you can follow and you'll also want to add provided dependency as well. This totally slipped my mind earlier so feel free to skip this part if you're too busy since I remembered it a bit late.

@zefei
Copy link
Author

zefei commented Nov 5, 2015

I don't think we can remove apache because Twitter.signRequest is public and allows apache request to be passed.

@zefei
Copy link
Author

zefei commented Nov 5, 2015

When I was trying to use provided scope, I found that this might not be ideal. Since we don't have explicit dependency on OkHttp, wouldn't compile/runtime error confuse users if they or their dependencies use an imcompatible OkHttp?

@grantland
Copy link
Contributor

I don't think we can remove apache because Twitter.signRequest is public and allows apache request to be passed.

Good call!

When I was trying to use provided scope, I found that this might not be ideal. Since we don't have explicit dependency on OkHttp, wouldn't compile/runtime error confuse users if they or their dependencies use an imcompatible OkHttp?

As long as we don't pull any classes into the runtime that directly import anything from OkHttp before we know OkHttp exists in the runtime, we should be fine. The link I sent you is an example of this and you should be able to test a working implementation by adding/removing OkHttp from your application that depends on ParseTwitterUtils.

If you don't have time for this part, feel free to just squash your commits and I can merge.

@zefei
Copy link
Author

zefei commented Nov 5, 2015

I'm still not sure that this is safe, please see this: http://stackoverflow.com/questions/31319953/error-parse-1-9-3-and-okhttp-2-0-0

Even though OkHttp exists in runtime, it could be an incompatible version that satisfies the symbol lookup, but still fails actual signature matching/lookup. Since this is basically runtime dispatching, I can't think of any ways to avoid runtime error without reflection.

@grantland
Copy link
Contributor

I agree that your solution is safer in the sense that it'll "work" regardless of a breaking change in OkHttp as this library will fall back to HttpURLConnection, however "working" is relative. It won't crash when there's a version mismatch between ParseTwitterUtils and OkHttp, but it won't work as intended either. It would silently fail the SDK would go on unnoticed incorrectly using HttpURLConnection instead of OkHttp even if it existed in the runtime.

If we were to fail hard in the case of a breaking OkHttp change, a developer might be burdened to using a older version of OkHttp until this library has been updated but they wouldn't release a "bad" build.

There might be an odd case where a developer requires an older version of a library, but we can add some specific checking for the newer API in hasOkHttpOnClassPath() if that issue ever occurs.

I'd love to hear your thoughts if you still feel strongly about your opinion on this.

@zefei
Copy link
Author

zefei commented Nov 5, 2015

I agree that falling back silently is bad, I will change how it's handled. But I'm still in favor of reflection. I don't have a strong opinion though as this is a trade off.

My thinking is: the nature of this is dynamic dispatching, which is hard to handle at compile time. If we use provided and OkHttp changes its API, we will be forced to choose one version of OkHttp to import, and thus force users to go with one version. This couples our version with OkHttp version, but we gain compile time checks. Going reflection loses compile checks, but also looses coupling.

- use DefaultOAuthConsumer/Provider instead of CommonsHttpOauthConsumer/Provider
- overloaded Twitter.signRequest to accept HttpURLConnection
- use OkHttp instead of HttpURLConnection if OkHttp exists in user's classpath
@zefei zefei force-pushed the convert_to_httpurlconnection_okhttp branch from 7c61e40 to 5cd3788 Compare November 5, 2015 19:56
@facebook-github-bot
Copy link

@zefei updated the pull request.

@grantland
Copy link
Contributor

Yeah, there's no silver bullet here with regards to working with other APIs. Thanks for putting in the effort for implementing this functionality!

grantland added a commit that referenced this pull request Nov 5, 2015
@grantland grantland merged commit 3fe89c3 into parse-community:master Nov 5, 2015
@grantland grantland mentioned this pull request Nov 5, 2015
@zefei
Copy link
Author

zefei commented Nov 5, 2015

Thank you for the very detailed reviews and guidance!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants