diff --git a/twidere.component.common/build.gradle b/twidere.component.common/build.gradle index 1fab1f6e2..8b5bc12a4 100644 --- a/twidere.component.common/build.gradle +++ b/twidere.component.common/build.gradle @@ -43,7 +43,7 @@ dependencies { compile 'com.android.support:support-v4:23.1.1' compile 'com.bluelinelabs:logansquare:1.3.4' compile 'org.apache.commons:commons-lang3:3.4' - compile 'com.github.mariotaku.RestFu:library:0.9.16' + compile 'com.github.mariotaku.RestFu:library:0.9.17' compile 'com.hannesdorfmann.parcelableplease:annotation:1.0.2' compile 'com.github.mariotaku.SQLiteQB:library:0.9.4' compile 'com.github.mariotaku.ObjectCursor:core:0.9.3' diff --git a/twidere/build.gradle b/twidere/build.gradle index 20d10f719..8aca775c9 100644 --- a/twidere/build.gradle +++ b/twidere/build.gradle @@ -89,7 +89,7 @@ dependencies { compile 'com.commonsware.cwac:layouts:0.4.2' compile 'com.rengwuxian.materialedittext:library:2.1.4' compile 'com.pnikosis:materialish-progress:1.7' - compile 'com.squareup.okhttp:okhttp:2.7.0' + compile 'com.squareup.okhttp3:okhttp:3.0.1' compile 'pl.droidsonroids.gif:android-gif-drawable:1.1.7' compile 'com.github.johnpersano:supertoasts:1.3.4.1@aar' compile 'com.github.mariotaku:MessageBubbleView:1.2' @@ -108,22 +108,22 @@ dependencies { compile 'com.soundcloud.android:android-crop:1.0.1@aar' compile 'com.hannesdorfmann.parcelableplease:annotation:1.0.2' compile 'com.github.mariotaku:PickNCrop:0.9.2' - compile 'com.github.mariotaku.RestFu:library:0.9.16' - compile 'com.github.mariotaku.RestFu:okhttp:0.9.16' + compile 'com.github.mariotaku.RestFu:library:0.9.17' + compile 'com.github.mariotaku.RestFu:okhttp3:0.9.17' compile 'com.github.mariotaku:InetAddressJni:0.9.1' compile 'com.lnikkila:extendedtouchview:0.1.0' compile 'com.google.dagger:dagger:2.0.2' compile 'org.attoparser:attoparser:1.4.0.RELEASE' compile 'com.j256.simplemagic:simplemagic:1.6' - compile 'com.github.mariotaku.MediaViewerLibrary:base:0.9.5' - compile 'com.github.mariotaku.MediaViewerLibrary:subsample-image-view:0.9.5' + compile 'com.github.mariotaku.MediaViewerLibrary:base:0.9.6' + compile 'com.github.mariotaku.MediaViewerLibrary:subsample-image-view:0.9.6' googleCompile 'com.google.android.gms:play-services-maps:8.4.0' // googleCompile 'com.google.maps.android:android-maps-utils:0.4' googleCompile('com.crashlytics.sdk.android:crashlytics:2.5.5@aar') { transitive = true } googleCompile ':YouTubeAndroidPlayerApi:1.2.2@jar' fdroidCompile 'org.osmdroid:osmdroid-android:5.0.1' debugCompile 'com.facebook.stetho:stetho:1.2.0' - debugCompile 'com.facebook.stetho:stetho-okhttp:1.2.0' +// debugCompile 'com.facebook.stetho:stetho-okhttp:1.2.0' debugCompile 'com.squareup.leakcanary:leakcanary-android:1.4-beta1' compile project(':twidere.component.common') compile project(':twidere.component.nyan') diff --git a/twidere/src/androidTest/java/org/mariotaku/twidere/test/okhttp3/OkHttpClientTest.java b/twidere/src/androidTest/java/org/mariotaku/twidere/test/okhttp3/OkHttpClientTest.java new file mode 100644 index 000000000..591886b2a --- /dev/null +++ b/twidere/src/androidTest/java/org/mariotaku/twidere/test/okhttp3/OkHttpClientTest.java @@ -0,0 +1,30 @@ +package org.mariotaku.twidere.test.okhttp3; + +import org.junit.Test; + +import java.net.InetSocketAddress; +import java.net.Proxy; + +import okhttp3.OkHttpClient; +import okhttp3.Request; + +import static org.junit.Assert.assertTrue; + +/** + * Created by mariotaku on 16/2/5. + */ +public class OkHttpClientTest { + + @Test + public void testSocksFunctionality() throws Exception { + final Proxy proxy = new Proxy(Proxy.Type.SOCKS, InetSocketAddress.createUnresolved("127.0.0.1", 1080)); + final OkHttpClient client = new OkHttpClient.Builder() + .proxy(proxy) + .build(); + final Request request = new Request.Builder() + .url("https://www.google.com/") + .build(); + assertTrue(client.newCall(request).execute().isSuccessful()); + } + +} diff --git a/twidere/src/debug/java/org/mariotaku/twidere/util/DebugModeUtils.java b/twidere/src/debug/java/org/mariotaku/twidere/util/DebugModeUtils.java index 71dd6fc3b..ab336c3a0 100644 --- a/twidere/src/debug/java/org/mariotaku/twidere/util/DebugModeUtils.java +++ b/twidere/src/debug/java/org/mariotaku/twidere/util/DebugModeUtils.java @@ -22,13 +22,10 @@ package org.mariotaku.twidere.util; import android.app.Application; import com.facebook.stetho.Stetho; -import com.facebook.stetho.okhttp.StethoInterceptor; import com.squareup.leakcanary.LeakCanary; import com.squareup.leakcanary.RefWatcher; -import com.squareup.okhttp.Interceptor; -import com.squareup.okhttp.OkHttpClient; -import java.util.List; +import okhttp3.OkHttpClient; /** * Created by mariotaku on 15/5/27. @@ -37,9 +34,7 @@ public class DebugModeUtils { private static RefWatcher sRefWatcher; - public static void initForHttpClient(final OkHttpClient client) { - final List interceptors = client.networkInterceptors(); - interceptors.add(new StethoInterceptor()); + public static void initForHttpClient(final OkHttpClient.Builder client) { } public static void initForApplication(final Application application) { diff --git a/twidere/src/main/java/edu/tsinghua/hotmobi/UploadLogsTask.java b/twidere/src/main/java/edu/tsinghua/hotmobi/UploadLogsTask.java index 668cdf546..4c1ddbdb4 100644 --- a/twidere/src/main/java/edu/tsinghua/hotmobi/UploadLogsTask.java +++ b/twidere/src/main/java/edu/tsinghua/hotmobi/UploadLogsTask.java @@ -23,11 +23,6 @@ import android.content.Context; import android.content.SharedPreferences; import android.util.Log; -import com.squareup.okhttp.MediaType; -import com.squareup.okhttp.OkHttpClient; -import com.squareup.okhttp.Request; -import com.squareup.okhttp.RequestBody; -import com.squareup.okhttp.Response; import org.apache.commons.lang3.ArrayUtils; import org.mariotaku.twidere.BuildConfig; @@ -40,6 +35,11 @@ import java.util.Date; import java.util.Locale; import edu.tsinghua.hotmobi.model.UploadLogEvent; +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; /** * Upload logs to target server diff --git a/twidere/src/main/java/edu/tsinghua/hotmobi/model/UploadLogEvent.java b/twidere/src/main/java/edu/tsinghua/hotmobi/model/UploadLogEvent.java index 2b04eb8c0..6100cf3d1 100644 --- a/twidere/src/main/java/edu/tsinghua/hotmobi/model/UploadLogEvent.java +++ b/twidere/src/main/java/edu/tsinghua/hotmobi/model/UploadLogEvent.java @@ -11,16 +11,16 @@ import com.hannesdorfmann.parcelableplease.ParcelBagger; import com.hannesdorfmann.parcelableplease.annotation.Bagger; import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease; import com.hannesdorfmann.parcelableplease.annotation.ParcelableThisPlease; -import com.squareup.okhttp.Headers; -import com.squareup.okhttp.Response; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.builder.ToStringBuilder; import java.io.File; import java.util.HashMap; import java.util.Map; +import okhttp3.Headers; +import okhttp3.Response; + /** * Created by mariotaku on 16/1/2. */ diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/support/MediaViewerActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/support/MediaViewerActivity.java index fdda446fd..4f0f0d46e 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/support/MediaViewerActivity.java +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/support/MediaViewerActivity.java @@ -92,6 +92,7 @@ import org.mariotaku.twidere.util.PermissionUtils; import org.mariotaku.twidere.util.ThemeUtils; import org.mariotaku.twidere.util.Utils; import org.mariotaku.twidere.util.dagger.GeneralComponentHelper; +import org.mariotaku.twidere.util.media.MediaExtra; import java.io.File; import java.util.concurrent.TimeUnit; @@ -308,7 +309,10 @@ public final class MediaViewerActivity extends AbsMediaViewerActivity implements switch (item.getItemId()) { case R.id.refresh: { if (object instanceof CacheDownloadMediaViewerFragment) { - ((CacheDownloadMediaViewerFragment) object).startLoading(true); + final CacheDownloadMediaViewerFragment fragment = (CacheDownloadMediaViewerFragment) object; + fragment.startLoading(true); + fragment.showProgress(true, 0); + fragment.setMediaViewVisible(false); } return true; } @@ -811,13 +815,13 @@ public final class MediaViewerActivity extends AbsMediaViewerActivity implements } @Override - protected void hideProgress() { + public void hideProgress() { super.hideProgress(); getActivity().supportInvalidateOptionsMenu(); } @Override - protected void showProgress(boolean indeterminate, float progress) { + public void showProgress(boolean indeterminate, float progress) { super.showProgress(indeterminate, progress); getActivity().supportInvalidateOptionsMenu(); } @@ -851,7 +855,9 @@ public final class MediaViewerActivity extends AbsMediaViewerActivity implements @Override protected Object getDownloadExtra() { - return null; + final MediaExtra extra = new MediaExtra(); + extra.setUseThumbor(false); + return extra; } public boolean isLoopEnabled() { @@ -859,19 +865,19 @@ public final class MediaViewerActivity extends AbsMediaViewerActivity implements } @Override - protected void hideProgress() { + public void hideProgress() { super.hideProgress(); getActivity().supportInvalidateOptionsMenu(); } @Override - protected void showProgress(boolean indeterminate, float progress) { + public void showProgress(boolean indeterminate, float progress) { super.showProgress(indeterminate, progress); getActivity().supportInvalidateOptionsMenu(); } @Override - protected void setMediaViewVisible(boolean visible) { + public void setMediaViewVisible(boolean visible) { super.setMediaViewVisible(visible); getActivity().supportInvalidateOptionsMenu(); } @@ -1062,10 +1068,13 @@ public final class MediaViewerActivity extends AbsMediaViewerActivity implements break; } case R.id.video_view_overlay: { + final MediaViewerActivity activity = (MediaViewerActivity) getActivity(); if (mVideoControl.getVisibility() == View.VISIBLE) { mVideoControl.setVisibility(View.GONE); + activity.setBarVisibility(false); } else { mVideoControl.setVisibility(View.VISIBLE); + activity.setBarVisibility(true); } break; } diff --git a/twidere/src/main/java/org/mariotaku/twidere/app/TwidereApplication.java b/twidere/src/main/java/org/mariotaku/twidere/app/TwidereApplication.java index 542bc4431..08af44173 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/app/TwidereApplication.java +++ b/twidere/src/main/java/org/mariotaku/twidere/app/TwidereApplication.java @@ -35,8 +35,6 @@ import android.os.Handler; import android.support.annotation.NonNull; import android.support.multidex.MultiDexApplication; -import com.squareup.okhttp.Dns; - import org.apache.commons.lang3.ArrayUtils; import org.mariotaku.restfu.http.RestHttpClient; import org.mariotaku.restfu.okhttp.OkHttpRestClient; @@ -58,6 +56,9 @@ import org.mariotaku.twidere.util.dagger.ApplicationModule; import org.mariotaku.twidere.util.dagger.DependencyHolder; import org.mariotaku.twidere.util.net.TwidereDns; +import okhttp3.Dns; +import okhttp3.OkHttpClient; + import static org.mariotaku.twidere.util.Utils.initAccountColor; import static org.mariotaku.twidere.util.Utils.startRefreshServiceIfNeeded; @@ -257,8 +258,10 @@ public class TwidereApplication extends MultiDexApplication implements Constants DependencyHolder holder = DependencyHolder.get(this); final RestHttpClient client = holder.getRestHttpClient(); if (client instanceof OkHttpRestClient) { - HttpClientFactory.initDefaultHttpClient(this, holder.getPreferences(), - ((OkHttpRestClient) client).getClient(), holder.getDns()); + final OkHttpClient.Builder builder = new OkHttpClient.Builder(); + HttpClientFactory.initDefaultHttpClient(this, holder.getPreferences(), builder, + holder.getDns()); + ((OkHttpRestClient) client).setClient(builder.build()); } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsContentRecyclerViewFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsContentRecyclerViewFragment.java index 973c10141..0840e0d57 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsContentRecyclerViewFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsContentRecyclerViewFragment.java @@ -185,7 +185,7 @@ public abstract class AbsContentRecyclerViewFragment addresses = mNetwork.lookup(host); + final List addresses = mDns.lookup(host); for (InetAddress address : addresses) { c.addRow(new String[]{host, address.getHostAddress()}); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/AsyncTwitterWrapper.java b/twidere/src/main/java/org/mariotaku/twidere/util/AsyncTwitterWrapper.java index 466b420ba..f376f739e 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/AsyncTwitterWrapper.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/AsyncTwitterWrapper.java @@ -952,7 +952,9 @@ public class AsyncTwitterWrapper extends TwitterWrapper { } return SingleResponse.getInstance(status); } catch (final TwitterException e) { - Log.w(LOGTAG, e); + if (BuildConfig.DEBUG) { + Log.w(LOGTAG, e); + } return SingleResponse.getInstance(e); } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/HttpClientFactory.java b/twidere/src/main/java/org/mariotaku/twidere/util/HttpClientFactory.java index 7a3aae462..6afeef867 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/HttpClientFactory.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/HttpClientFactory.java @@ -7,23 +7,26 @@ import android.net.SSLCertificateSocketFactory; import android.net.SSLSessionCache; import android.text.TextUtils; -import com.squareup.okhttp.Authenticator; -import com.squareup.okhttp.Credentials; -import com.squareup.okhttp.Dns; -import com.squareup.okhttp.OkHttpClient; -import com.squareup.okhttp.Request; -import com.squareup.okhttp.Response; - import org.apache.commons.lang3.math.NumberUtils; +import org.mariotaku.inetaddrjni.library.InetAddressUtils; import org.mariotaku.restfu.http.RestHttpClient; import org.mariotaku.restfu.okhttp.OkHttpRestClient; import org.mariotaku.twidere.Constants; import org.mariotaku.twidere.util.net.TwidereProxySelector; import java.io.IOException; +import java.net.InetSocketAddress; import java.net.Proxy; import java.util.concurrent.TimeUnit; +import okhttp3.Authenticator; +import okhttp3.Credentials; +import okhttp3.Dns; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.Route; + import static android.text.TextUtils.isEmpty; /** @@ -36,33 +39,31 @@ public class HttpClientFactory implements Constants { } public static RestHttpClient createHttpClient(final Context context, final SharedPreferences prefs, Dns dns) { - final OkHttpClient client = new OkHttpClient(); - initDefaultHttpClient(context, prefs, client, dns); - return new OkHttpRestClient(client); + final OkHttpClient.Builder builder = new OkHttpClient.Builder(); + initDefaultHttpClient(context, prefs, builder, dns); + return new OkHttpRestClient(builder.build()); } - public static void initDefaultHttpClient(Context context, SharedPreferences prefs, OkHttpClient client, Dns dns) { - updateHttpClientConfiguration(context, prefs, dns, client); - DebugModeUtils.initForHttpClient(client); + public static void initDefaultHttpClient(Context context, SharedPreferences prefs, OkHttpClient.Builder builder, Dns dns) { + updateHttpClientConfiguration(context, prefs, dns, builder); + DebugModeUtils.initForHttpClient(builder); } @SuppressLint("SSLCertificateSocketFactoryGetInsecure") public static void updateHttpClientConfiguration(final Context context, final SharedPreferences prefs, - Dns dns, final OkHttpClient client) { + Dns dns, final OkHttpClient.Builder builder) { final int connectionTimeoutSeconds = prefs.getInt(KEY_CONNECTION_TIMEOUT, 10); final boolean ignoreSslError = prefs.getBoolean(KEY_IGNORE_SSL_ERROR, false); final boolean enableProxy = prefs.getBoolean(KEY_ENABLE_PROXY, false); - client.setConnectTimeout(connectionTimeoutSeconds, TimeUnit.SECONDS); + builder.connectTimeout(connectionTimeoutSeconds, TimeUnit.SECONDS); if (ignoreSslError) { // We use insecure connections intentionally - client.setSslSocketFactory(SSLCertificateSocketFactory.getInsecure((int) - TimeUnit.SECONDS.toMillis(connectionTimeoutSeconds), + final int sslConnectTimeout = ((int) TimeUnit.SECONDS.toMillis(connectionTimeoutSeconds)); + builder.sslSocketFactory(SSLCertificateSocketFactory.getInsecure(sslConnectTimeout, new SSLSessionCache(context))); - } else { - client.setSslSocketFactory(null); } if (enableProxy) { final String proxyType = prefs.getString(KEY_PROXY_TYPE, null); @@ -70,35 +71,33 @@ public class HttpClientFactory implements Constants { final int proxyPort = NumberUtils.toInt(prefs.getString(KEY_PROXY_PORT, null), -1); if (!isEmpty(proxyHost) && TwidereMathUtils.inRange(proxyPort, 0, 65535, TwidereMathUtils.RANGE_INCLUSIVE_INCLUSIVE)) { - client.setProxy(null); - client.setProxySelector(new TwidereProxySelector(context, getProxyType(proxyType), - proxyHost, proxyPort)); + final Proxy.Type type = getProxyType(proxyType); + if (InetAddressUtils.getInetAddressType(proxyHost) != 0) { +// final InetAddress host = InetAddressUtils.getResolvedIPAddress(proxyHost, proxyHost); + builder.proxy(new Proxy(type, InetSocketAddress.createUnresolved(proxyHost, proxyPort))); + } else { + builder.proxySelector(new TwidereProxySelector(context, type, proxyHost, proxyPort)); + } } final String username = prefs.getString(KEY_PROXY_USERNAME, null); final String password = prefs.getString(KEY_PROXY_PASSWORD, null); - client.setAuthenticator(new Authenticator() { + builder.authenticator(new Authenticator() { @Override - public Request authenticate(Proxy proxy, Response response) throws IOException { - return null; - } - - @Override - public Request authenticateProxy(Proxy proxy, Response response) throws IOException { + public Request authenticate(Route route, Response response) throws IOException { final Request.Builder builder = response.request().newBuilder(); - if (!TextUtils.isEmpty(username) && !TextUtils.isEmpty(password)) { - final String credential = Credentials.basic(username, password); - builder.header("Proxy-Authorization", credential); + if (response.code() == 407) { + if (!TextUtils.isEmpty(username) && !TextUtils.isEmpty(password)) { + final String credential = Credentials.basic(username, password); + builder.header("Proxy-Authorization", credential); + } } return builder.build(); } + }); - } else { - client.setProxy(null); - client.setProxySelector(null); - client.setAuthenticator(null); } if (dns != null) { - client.setDns(dns); + builder.dns(dns); } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/OAuthPasswordAuthenticator.java b/twidere/src/main/java/org/mariotaku/twidere/util/OAuthPasswordAuthenticator.java index e84103a95..7999095ef 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/OAuthPasswordAuthenticator.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/OAuthPasswordAuthenticator.java @@ -22,10 +22,6 @@ package org.mariotaku.twidere.util; import android.support.annotation.Nullable; import android.text.TextUtils; -import com.squareup.okhttp.HttpUrl; -import com.squareup.okhttp.Interceptor; -import com.squareup.okhttp.OkHttpClient; -import com.squareup.okhttp.Response; import org.attoparser.AttoParseException; import org.attoparser.IAttoHandler; @@ -50,6 +46,7 @@ import org.mariotaku.twidere.api.twitter.TwitterException; import org.mariotaku.twidere.api.twitter.TwitterOAuth; import org.mariotaku.twidere.api.twitter.auth.OAuthToken; import org.mariotaku.twidere.model.RequestType; +import org.mariotaku.twidere.util.net.JavaNetCookieJar; import java.io.IOException; import java.io.Reader; @@ -57,6 +54,11 @@ import java.net.CookieManager; import java.net.URI; import java.util.Map; +import okhttp3.HttpUrl; +import okhttp3.Interceptor; +import okhttp3.OkHttpClient; +import okhttp3.Response; + public class OAuthPasswordAuthenticator implements Constants { private static final IAttoParser PARSER = new MarkupAttoParser(); @@ -73,9 +75,9 @@ public class OAuthPasswordAuthenticator implements Constants { final RestClient restClient = RestAPIFactory.getRestClient(oauth); this.oauth = oauth; this.client = (OkHttpRestClient) restClient.getRestClient(); - final OkHttpClient okhttp = client.getClient(); - okhttp.setCookieHandler(new CookieManager()); - okhttp.networkInterceptors().add(new Interceptor() { + final OkHttpClient.Builder builder = client.getClient().newBuilder(); + builder.cookieJar(new JavaNetCookieJar(new CookieManager())); + builder.addNetworkInterceptor(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { final Response response = chain.proceed(chain.request()); diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/dagger/ApplicationModule.java b/twidere/src/main/java/org/mariotaku/twidere/util/dagger/ApplicationModule.java index a974a3eb7..815eaef5c 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/dagger/ApplicationModule.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/dagger/ApplicationModule.java @@ -30,7 +30,6 @@ import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; import com.nostra13.universalimageloader.core.assist.QueueProcessingType; import com.nostra13.universalimageloader.utils.L; -import com.squareup.okhttp.Dns; import com.squareup.otto.Bus; import com.squareup.otto.ThreadEnforcer; import com.twitter.Extractor; @@ -73,6 +72,7 @@ import javax.inject.Singleton; import dagger.Module; import dagger.Provides; import edu.tsinghua.hotmobi.HotMobiLogger; +import okhttp3.Dns; import static org.mariotaku.twidere.util.Utils.getInternalCacheDir; diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/dagger/DependencyHolder.java b/twidere/src/main/java/org/mariotaku/twidere/util/dagger/DependencyHolder.java index 340244438..10af3fb29 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/dagger/DependencyHolder.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/dagger/DependencyHolder.java @@ -21,8 +21,6 @@ package org.mariotaku.twidere.util.dagger; import android.content.Context; -import com.squareup.okhttp.Dns; - import org.mariotaku.restfu.http.RestHttpClient; import org.mariotaku.twidere.util.ActivityTracker; import org.mariotaku.twidere.util.ExternalThemeManager; @@ -33,6 +31,7 @@ import org.mariotaku.twidere.util.TwidereValidator; import javax.inject.Inject; import edu.tsinghua.hotmobi.HotMobiLogger; +import okhttp3.Dns; /** * Created by mariotaku on 15/12/31. diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/net/JavaNetCookieJar.java b/twidere/src/main/java/org/mariotaku/twidere/util/net/JavaNetCookieJar.java new file mode 100644 index 000000000..520fc2d88 --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/twidere/util/net/JavaNetCookieJar.java @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2015 Square, Inc. + * + * Licensed 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.mariotaku.twidere.util.net; + +import java.io.IOException; +import java.net.CookieHandler; +import java.net.HttpCookie; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import okhttp3.Cookie; +import okhttp3.CookieJar; +import okhttp3.HttpUrl; +import okhttp3.internal.Internal; + +import static java.util.logging.Level.WARNING; +import static okhttp3.internal.Util.delimiterOffset; +import static okhttp3.internal.Util.trimSubstring; + +/** A cookie jar that delegates to a {@link java.net.CookieHandler}. */ +public final class JavaNetCookieJar implements CookieJar { + private final CookieHandler cookieHandler; + + public JavaNetCookieJar(CookieHandler cookieHandler) { + this.cookieHandler = cookieHandler; + } + + @Override public void saveFromResponse(HttpUrl url, List cookies) { + if (cookieHandler != null) { + List cookieStrings = new ArrayList<>(); + for (Cookie cookie : cookies) { + cookieStrings.add(cookie.toString()); + } + Map> multimap = Collections.singletonMap("Set-Cookie", cookieStrings); + try { + cookieHandler.put(url.uri(), multimap); + } catch (IOException e) { + Internal.logger.log(WARNING, "Saving cookies failed for " + url.resolve("/..."), e); + } + } + } + + @Override public List loadForRequest(HttpUrl url) { + // The RI passes all headers. We don't have 'em, so we don't pass 'em! + Map> headers = Collections.emptyMap(); + Map> cookieHeaders; + try { + cookieHeaders = cookieHandler.get(url.uri(), headers); + } catch (IOException e) { + Internal.logger.log(WARNING, "Loading cookies failed for " + url.resolve("/..."), e); + return Collections.emptyList(); + } + + List cookies = null; + for (Map.Entry> entry : cookieHeaders.entrySet()) { + String key = entry.getKey(); + if (("Cookie".equalsIgnoreCase(key) || "Cookie2".equalsIgnoreCase(key)) + && !entry.getValue().isEmpty()) { + for (String header : entry.getValue()) { + if (cookies == null) cookies = new ArrayList<>(); + cookies.addAll(decodeHeaderAsJavaNetCookies(url, header)); + } + } + } + + return cookies != null + ? Collections.unmodifiableList(cookies) + : Collections.emptyList(); + } + + /** + * Convert a request header to OkHttp's cookies via {@link HttpCookie}. That extra step handles + * multiple cookies in a single request header, which {@link Cookie#parse} doesn't support. + */ + private List decodeHeaderAsJavaNetCookies(HttpUrl url, String header) { + List result = new ArrayList<>(); + for (int pos = 0, limit = header.length(), pairEnd; pos < limit; pos = pairEnd + 1) { + pairEnd = delimiterOffset(header, pos, limit, ";,"); + int equalsSign = delimiterOffset(header, pos, pairEnd, '='); + String name = trimSubstring(header, pos, equalsSign); + if (name.startsWith("$")) continue; + + // We have either name=value or just a name. + String value = equalsSign < pairEnd + ? trimSubstring(header, equalsSign + 1, pairEnd) + : ""; + + // If the value is "quoted", drop the quotes. + if (value.startsWith("\"") && value.endsWith("\"")) { + value = value.substring(1, value.length() - 1); + } + + result.add(new Cookie.Builder() + .name(name) + .value(value) + .domain(url.host()) + .build()); + } + return result; + } +} \ No newline at end of file diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/net/TwidereDns.java b/twidere/src/main/java/org/mariotaku/twidere/util/net/TwidereDns.java index edd3d7db8..a690c6206 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/net/TwidereDns.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/net/TwidereDns.java @@ -29,8 +29,6 @@ import android.util.Log; import android.util.LruCache; import android.util.TimingLogger; -import com.squareup.okhttp.Dns; - import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.mariotaku.inetaddrjni.library.InetAddressUtils; @@ -59,6 +57,8 @@ import java.util.concurrent.TimeUnit; import javax.inject.Singleton; +import okhttp3.Dns; + @Singleton public class TwidereDns implements Constants, Dns { diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/net/TwidereProxySelector.java b/twidere/src/main/java/org/mariotaku/twidere/util/net/TwidereProxySelector.java index a909742cd..6150c8b49 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/net/TwidereProxySelector.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/net/TwidereProxySelector.java @@ -23,8 +23,7 @@ import android.content.Context; import android.os.Looper; import android.util.Log; -import com.squareup.okhttp.Dns; - +import org.mariotaku.inetaddrjni.library.InetAddressUtils; import org.mariotaku.twidere.BuildConfig; import org.mariotaku.twidere.util.dagger.GeneralComponentHelper; @@ -40,6 +39,8 @@ import java.util.List; import javax.inject.Inject; +import okhttp3.Dns; + /** * Created by mariotaku on 15/12/31. */ @@ -61,13 +62,19 @@ public class TwidereProxySelector extends ProxySelector { @Override public List select(URI uri) { if (proxy != null) return proxy; - final InetSocketAddress unresolved; + final InetSocketAddress address; if (Looper.myLooper() != Looper.getMainLooper()) { - unresolved = createResolved(host, port); + address = createResolved(host, port); } else { - unresolved = InetSocketAddress.createUnresolved(host, port); + // If proxy host is an IP address, create unresolved directly. + if (InetAddressUtils.getInetAddressType(host) != 0) { + address = new InetSocketAddress(InetAddressUtils.getResolvedIPAddress(host, host), + port); + } else { + address = new InetSocketAddress(host, port); + } } - return proxy = Collections.singletonList(new Proxy(type, unresolved)); + return proxy = Collections.singletonList(new Proxy(type, address)); } private InetSocketAddress createResolved(String host, int port) {