Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to enable/disable HTTP/2 and/or IPv6 for OkHttp clients #771

Merged
merged 4 commits into from
Mar 10, 2020
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 @@ -18,12 +18,15 @@

import android.net.ConnectivityManager;

import androidx.annotation.NonNull;

import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;
import com.github.adamantcheese.chan.BuildConfig;
import com.github.adamantcheese.chan.core.cache.CacheHandler;
import com.github.adamantcheese.chan.core.cache.FileCacheV2;
import com.github.adamantcheese.chan.core.cache.stream.WebmStreamingSource;
import com.github.adamantcheese.chan.core.net.DnsSelector;
import com.github.adamantcheese.chan.core.net.ProxiedHurlStack;
import com.github.adamantcheese.chan.core.settings.ChanSettings;
import com.github.adamantcheese.chan.core.site.SiteResolver;
Expand All @@ -35,11 +38,16 @@
import org.codejargon.feather.Provides;

import java.io.File;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import javax.inject.Named;
import javax.inject.Singleton;

import okhttp3.Dns;
import okhttp3.OkHttpClient;
import okhttp3.Protocol;

import static com.github.adamantcheese.chan.core.di.AppModule.getCacheDir;
import static com.github.adamantcheese.chan.utils.AndroidUtils.getAppContext;
Expand Down Expand Up @@ -123,9 +131,12 @@ public ProxiedOkHttpClient provideProxiedOkHttpClient() {
public OkHttpClient provideOkHttpClient() {
Logger.d(AppModule.DI_TAG, "DownloaderOkHttp client");

return new OkHttpClient.Builder().connectTimeout(30, SECONDS)
return new OkHttpClient.Builder()
.connectTimeout(30, SECONDS)
.readTimeout(30, SECONDS)
.writeTimeout(30, SECONDS)
.protocols(getOkHttpProtocols())
.dns(getOkHttpDnsSelector())
.build();
}

Expand All @@ -142,9 +153,32 @@ public OkHttpClient provideOkHttpClientForThreadSaveManager() {
.connectTimeout(30, SECONDS)
.writeTimeout(30, SECONDS)
.readTimeout(30, SECONDS)
.protocols(getOkHttpProtocols())
.dns(getOkHttpDnsSelector())
.build();
}

private Dns getOkHttpDnsSelector() {
if (ChanSettings.okHttpAllowIpv6.get()) {
Logger.d(AppModule.DI_TAG, "Using DnsSelector.Mode.SYSTEM");
return new DnsSelector(DnsSelector.Mode.SYSTEM);
K1rakishou marked this conversation as resolved.
Show resolved Hide resolved
}

Logger.d(AppModule.DI_TAG, "Using DnsSelector.Mode.IPV4_ONLY");
return new DnsSelector(DnsSelector.Mode.IPV4_ONLY);
}

@NonNull
private List<Protocol> getOkHttpProtocols() {
if (ChanSettings.okHttpAllowHttp2.get()) {
Logger.d(AppModule.DI_TAG, "Using HTTP_2 and HTTP_1_1");
return Arrays.asList(Protocol.HTTP_2, Protocol.HTTP_1_1);
}

Logger.d(AppModule.DI_TAG, "Using HTTP_1_1");
return Collections.singletonList(Protocol.HTTP_1_1);
}

//this is basically the same as OkHttpClient, but with a singleton for a proxy instance
public class ProxiedOkHttpClient
extends OkHttpClient {
Expand All @@ -158,6 +192,8 @@ public OkHttpClient getProxiedClient() {
.connectTimeout(30, SECONDS)
.readTimeout(30, SECONDS)
.writeTimeout(30, SECONDS)
.protocols(getOkHttpProtocols())
.dns(getOkHttpDnsSelector())
.build();
}
return proxiedClient;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@ class ReportManager(
appendln("Saved files base dir info: ${getFilesLocationInfo()}")
appendln("Local threads base dir info: ${getLocalThreadsLocationInfo()}")
appendln("Phone layout mode: ${ChanSettings.layoutMode.get().name}")
appendln("OkHttp IPv6 support enabled: ${ChanSettings.okHttpAllowIpv6.get()}")
appendln("OkHttp HTTP/2 support enabled: ${ChanSettings.okHttpAllowHttp2.get()}")
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.github.adamantcheese.chan.core.net;

import androidx.annotation.NonNull;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

import okhttp3.Dns;

public class DnsSelector implements Dns {
private Mode mode;

public DnsSelector(Mode mode) {
this.mode = mode;
}

@NonNull
@Override public List<InetAddress> lookup(@NonNull String hostname) throws UnknownHostException {
List<InetAddress> addresses = Dns.SYSTEM.lookup(hostname);
if (mode == Mode.SYSTEM) {
return addresses;
}

List<InetAddress> resultAddresses = new ArrayList<>();
for (InetAddress address : addresses) {
if (address instanceof Inet4Address) {
resultAddresses.add(address);
}
}

return resultAddresses;
}

public enum Mode {
SYSTEM,
IPV4_ONLY
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,8 @@ public String getKey() {
public static final BooleanSetting captchaOnBottom;
public static final BooleanSetting showCopyApkUpdateDialog;
public static final BooleanSetting crashOnSafeThrow;
public static final BooleanSetting okHttpAllowHttp2;
public static final BooleanSetting okHttpAllowIpv6;

static {
try {
Expand Down Expand Up @@ -417,6 +419,8 @@ public String getKey() {
captchaOnBottom = new BooleanSetting(p, "captcha_on_bottom", true);
showCopyApkUpdateDialog = new BooleanSetting(p, "show_copy_apk_update_dialog", true);
crashOnSafeThrow = new BooleanSetting(p, "crash_on_safe_throw", true);
okHttpAllowHttp2 = new BooleanSetting(p, "ok_http_allow_http_2", true);
okHttpAllowIpv6 = new BooleanSetting(p, "ok_http_allow_ipv6", true);
} catch (Throwable error) {
// If something crashes while the settings are initializing we at least will have the
// stacktrace. Otherwise we won't because of the Feather.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,24 @@ private void populatePreferences() {
R.string.setting_image_viewer_gestures_description
));

requiresRestart.add(
group.add(new BooleanSettingView(
this,
ChanSettings.okHttpAllowHttp2,
R.string.setting_allow_okhttp_http2,
R.string.setting_allow_okhttp_http2_ipv6_description
))
);

requiresRestart.add(
group.add(new BooleanSettingView(
this,
ChanSettings.okHttpAllowIpv6,
R.string.setting_allow_okhttp_ipv6,
R.string.setting_allow_okhttp_http2_ipv6_description
))
);

groups.add(group);
}

Expand Down
5 changes: 4 additions & 1 deletion Kuroba/app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -809,9 +809,12 @@ Don't have a 4chan Pass?<br>
<string name="update_manager_apk_copied">Apk successfully copied</string>
<string name="settings_show_copy_apk_dialog_title">Show copy apk dialog when downloading an update</string>
<string name="settings_show_copy_apk_dialog_message">Every time you download a new update a dialog with suggestion to copy that apk to some other directory will be shown</string>

<string name="could_not_initialized_captcha">Couldn\'t initialize captcha, reason: %1$s</string>
<string name="fail_reason_webview_is_not_installed">WebView is not installed</string>
<string name="fail_reason_some_part_of_webview_not_initialized">Some part of WebViewChromium couldn\'t get initialized: (%1$s)</string>
<string name="thread_load_failed_local_thread_parsing">Error while trying to parse local thread json file. Try deleting and the re-downloading the thread to fix this error.</string>
<string name="setting_allow_okhttp_http2">Allow OkHttp to use HTTP/2 protocol</string>
<string name="setting_allow_okhttp_ipv6">Allow OkHttp to use IPv6</string>
<string name="setting_allow_okhttp_http2_ipv6_description">Disabling this setting may resolve issues with images not loading whatsoever in some rare cases. Try disabling this setting if images refuse to start loading.</string>
</resources>