From 78eec5ecb56d06df053396a9e583d1d66f810342 Mon Sep 17 00:00:00 2001 From: M66B Date: Fri, 14 May 2021 11:47:14 +0200 Subject: [PATCH] User agent for all connections --- .../java/eu/faircode/email/ActivityView.java | 1 + .../java/eu/faircode/email/ContactInfo.java | 17 ++++---- .../faircode/email/DisconnectBlacklist.java | 1 + .../java/eu/faircode/email/EmailProvider.java | 1 + .../eu/faircode/email/FragmentMessages.java | 1 + .../java/eu/faircode/email/FragmentOAuth.java | 1 + .../email/FragmentOptionsPrivacy.java | 4 +- .../main/java/eu/faircode/email/IPInfo.java | 7 ++-- .../java/eu/faircode/email/ImageHelper.java | 9 +---- .../java/eu/faircode/email/WebViewEx.java | 40 +++++++++++++------ 10 files changed, 50 insertions(+), 32 deletions(-) diff --git a/app/src/main/java/eu/faircode/email/ActivityView.java b/app/src/main/java/eu/faircode/email/ActivityView.java index 11eb3b77fe..afb98313fd 100644 --- a/app/src/main/java/eu/faircode/email/ActivityView.java +++ b/app/src/main/java/eu/faircode/email/ActivityView.java @@ -956,6 +956,7 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB urlConnection.setReadTimeout(UPDATE_TIMEOUT); urlConnection.setConnectTimeout(UPDATE_TIMEOUT); urlConnection.setDoOutput(false); + urlConnection.setRequestProperty("User-Agent", WebViewEx.getUserAgent(context)); urlConnection.connect(); int status = urlConnection.getResponseCode(); diff --git a/app/src/main/java/eu/faircode/email/ContactInfo.java b/app/src/main/java/eu/faircode/email/ContactInfo.java index f8489a3211..b775fcc5f3 100644 --- a/app/src/main/java/eu/faircode/email/ContactInfo.java +++ b/app/src/main/java/eu/faircode/email/ContactInfo.java @@ -301,6 +301,7 @@ public class ContactInfo { urlConnection.setDoOutput(false); urlConnection.setReadTimeout(GRAVATAR_TIMEOUT); urlConnection.setConnectTimeout(GRAVATAR_TIMEOUT); + urlConnection.setRequestProperty("User-Agent", WebViewEx.getUserAgent(context)); urlConnection.connect(); int status = urlConnection.getResponseCode(); @@ -363,28 +364,28 @@ public class ContactInfo { futures.add(executorFavicon.submit(new Callable() { @Override public Bitmap call() throws Exception { - return parseFavicon(base, scaleToPixels); + return parseFavicon(base, scaleToPixels, context); } })); futures.add(executorFavicon.submit(new Callable() { @Override public Bitmap call() throws Exception { - return parseFavicon(www, scaleToPixels); + return parseFavicon(www, scaleToPixels, context); } })); futures.add(executorFavicon.submit(new Callable() { @Override public Bitmap call() throws Exception { - return getFavicon(new URL(base, "favicon.ico"), scaleToPixels); + return getFavicon(new URL(base, "favicon.ico"), scaleToPixels, context); } })); futures.add(executorFavicon.submit(new Callable() { @Override public Bitmap call() throws Exception { - return getFavicon(new URL(www, "favicon.ico"), scaleToPixels); + return getFavicon(new URL(www, "favicon.ico"), scaleToPixels, context); } })); @@ -466,7 +467,7 @@ public class ContactInfo { return info; } - private static Bitmap parseFavicon(URL base, int scaleToPixels) throws IOException { + private static Bitmap parseFavicon(URL base, int scaleToPixels, Context context) throws IOException { Log.i("GET favicon " + base); HttpsURLConnection connection = (HttpsURLConnection) base.openConnection(); connection.setRequestMethod("GET"); @@ -479,6 +480,7 @@ public class ContactInfo { return true; } }); + connection.setRequestProperty("User-Agent", WebViewEx.getUserAgent(context)); connection.connect(); String response; @@ -551,7 +553,7 @@ public class ContactInfo { futures.add(executorFavicon.submit(new Callable() { @Override public Bitmap call() throws Exception { - return getFavicon(url, scaleToPixels); + return getFavicon(url, scaleToPixels, context); } })); } @@ -571,7 +573,7 @@ public class ContactInfo { } @NonNull - private static Bitmap getFavicon(URL url, int scaleToPixels) throws IOException { + private static Bitmap getFavicon(URL url, int scaleToPixels, Context context) throws IOException { Log.i("GET favicon " + url); if (!"https".equals(url.getProtocol())) @@ -588,6 +590,7 @@ public class ContactInfo { return true; } }); + connection.setRequestProperty("User-Agent", WebViewEx.getUserAgent(context)); connection.connect(); try { diff --git a/app/src/main/java/eu/faircode/email/DisconnectBlacklist.java b/app/src/main/java/eu/faircode/email/DisconnectBlacklist.java index 3b66a214c9..8bdac2753c 100644 --- a/app/src/main/java/eu/faircode/email/DisconnectBlacklist.java +++ b/app/src/main/java/eu/faircode/email/DisconnectBlacklist.java @@ -116,6 +116,7 @@ public class DisconnectBlacklist { connection.setRequestMethod("GET"); connection.setReadTimeout(FETCH_TIMEOUT); connection.setConnectTimeout(FETCH_TIMEOUT); + connection.setRequestProperty("User-Agent", WebViewEx.getUserAgent(context)); connection.connect(); try { diff --git a/app/src/main/java/eu/faircode/email/EmailProvider.java b/app/src/main/java/eu/faircode/email/EmailProvider.java index e659c9f21a..f518539755 100644 --- a/app/src/main/java/eu/faircode/email/EmailProvider.java +++ b/app/src/main/java/eu/faircode/email/EmailProvider.java @@ -352,6 +352,7 @@ public class EmailProvider { request.setReadTimeout(ISPDB_TIMEOUT); request.setConnectTimeout(ISPDB_TIMEOUT); request.setDoInput(true); + request.setRequestProperty("User-Agent", WebViewEx.getUserAgent(context)); request.connect(); // https://developer.android.com/reference/org/xmlpull/v1/XmlPullParser diff --git a/app/src/main/java/eu/faircode/email/FragmentMessages.java b/app/src/main/java/eu/faircode/email/FragmentMessages.java index a04ddb1d31..ccac67399f 100644 --- a/app/src/main/java/eu/faircode/email/FragmentMessages.java +++ b/app/src/main/java/eu/faircode/email/FragmentMessages.java @@ -7760,6 +7760,7 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences. connection.setReadTimeout(timeout); connection.setConnectTimeout(timeout); connection.setInstanceFollowRedirects(true); + connection.setRequestProperty("User-Agent", WebViewEx.getUserAgent(context)); connection.connect(); try { diff --git a/app/src/main/java/eu/faircode/email/FragmentOAuth.java b/app/src/main/java/eu/faircode/email/FragmentOAuth.java index bb91621cdf..73d6647f59 100644 --- a/app/src/main/java/eu/faircode/email/FragmentOAuth.java +++ b/app/src/main/java/eu/faircode/email/FragmentOAuth.java @@ -479,6 +479,7 @@ public class FragmentOAuth extends FragmentBase { connection.setRequestMethod("GET"); connection.setReadTimeout(MAILRU_TIMEOUT); connection.setConnectTimeout(MAILRU_TIMEOUT); + connection.setRequestProperty("User-Agent", WebViewEx.getUserAgent(context)); connection.connect(); try { diff --git a/app/src/main/java/eu/faircode/email/FragmentOptionsPrivacy.java b/app/src/main/java/eu/faircode/email/FragmentOptionsPrivacy.java index e950e337d0..42378636d2 100644 --- a/app/src/main/java/eu/faircode/email/FragmentOptionsPrivacy.java +++ b/app/src/main/java/eu/faircode/email/FragmentOptionsPrivacy.java @@ -419,8 +419,8 @@ public class FragmentOptionsPrivacy extends FragmentBase implements SharedPrefer swIncognitoKeyboard.setChecked(prefs.getBoolean("incognito_keyboard", false)); swSecure.setChecked(prefs.getBoolean("secure", false)); - tvGenericUserAgent.setText(WebViewEx.getUserAgent(getContext(), null)); - swGenericUserAgent.setChecked(prefs.getBoolean("generic_ua", false)); + tvGenericUserAgent.setText(WebViewEx.getUserAgent(getContext())); + swGenericUserAgent.setChecked(prefs.getBoolean("generic_ua", true)); swSafeBrowsing.setChecked(prefs.getBoolean("safe_browsing", false)); long time = prefs.getLong("disconnect_last", -1); diff --git a/app/src/main/java/eu/faircode/email/IPInfo.java b/app/src/main/java/eu/faircode/email/IPInfo.java index b2354e2977..a45ebd935f 100644 --- a/app/src/main/java/eu/faircode/email/IPInfo.java +++ b/app/src/main/java/eu/faircode/email/IPInfo.java @@ -51,17 +51,17 @@ public class IPInfo { InetAddress address = DnsHelper.lookupMx(context, domain); if (address == null) throw new UnknownHostException(); - return new Pair<>(domain, getOrganization(address)); + return new Pair<>(domain, getOrganization(address, context)); } else { String host = uri.getHost(); if (host == null) throw new UnknownHostException(); InetAddress address = InetAddress.getByName(host); - return new Pair<>(host, getOrganization(address)); + return new Pair<>(host, getOrganization(address, context)); } } - private static Organization getOrganization(InetAddress address) throws IOException { + private static Organization getOrganization(InetAddress address, Context context) throws IOException { synchronized (addressOrganization) { if (addressOrganization.containsKey(address)) return addressOrganization.get(address); @@ -74,6 +74,7 @@ public class IPInfo { connection.setRequestMethod("GET"); connection.setReadTimeout(FETCH_TIMEOUT); connection.setConnectTimeout(FETCH_TIMEOUT); + connection.setRequestProperty("User-Agent", WebViewEx.getUserAgent(context)); connection.connect(); Organization organization = new Organization(); diff --git a/app/src/main/java/eu/faircode/email/ImageHelper.java b/app/src/main/java/eu/faircode/email/ImageHelper.java index 884709904e..858c7ec608 100644 --- a/app/src/main/java/eu/faircode/email/ImageHelper.java +++ b/app/src/main/java/eu/faircode/email/ImageHelper.java @@ -605,20 +605,13 @@ class ImageHelper { int redirects = 0; URL url = new URL(source); while (true) { - // https://developer.chrome.com/multidevice/user-agent - String ua = "Mozilla/5.0 (Linux; Android 5.1.1; Nexus 5 Build/LMY48B; wv)" + - " AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0" + - " Chrome/43.0.2357.65" + - " Mobile Safari/537.36"; - urlConnection = (HttpURLConnection) url.openConnection(); urlConnection.setRequestMethod("GET"); urlConnection.setDoOutput(false); urlConnection.setReadTimeout(timeout); urlConnection.setConnectTimeout(timeout); urlConnection.setInstanceFollowRedirects(true); - if (BuildConfig.DEBUG) - urlConnection.setRequestProperty("User-Agent", ua); + urlConnection.setRequestProperty("User-Agent", WebViewEx.getUserAgent(context)); urlConnection.connect(); int status = urlConnection.getResponseCode(); diff --git a/app/src/main/java/eu/faircode/email/WebViewEx.java b/app/src/main/java/eu/faircode/email/WebViewEx.java index 67384e9c02..0b8316cbe7 100644 --- a/app/src/main/java/eu/faircode/email/WebViewEx.java +++ b/app/src/main/java/eu/faircode/email/WebViewEx.java @@ -35,6 +35,7 @@ import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; +import androidx.annotation.NonNull; import androidx.preference.PreferenceManager; import androidx.webkit.WebSettingsCompat; import androidx.webkit.WebViewFeature; @@ -47,6 +48,8 @@ public class WebViewEx extends WebView implements DownloadListener, View.OnLongC private IWebView intf; private Runnable onPageLoaded; + private static String userAgent = null; + private static final long PAGE_LOADED_FALLBACK_DELAY = 1500L; // milliseconds public WebViewEx(Context context) { @@ -352,24 +355,37 @@ public class WebViewEx extends WebView implements DownloadListener, View.OnLongC } } + @NonNull + static String getUserAgent(Context context) { + return getUserAgent(context, null); + } + + @NonNull static String getUserAgent(Context context, WebView webView) { // https://developer.chrome.com/docs/multidevice/user-agent/#chrome-for-android SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - boolean generic_ua = prefs.getBoolean("generic_ua", false); - - if (generic_ua) { - boolean large = context.getResources().getConfiguration() - .isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE); - return (large ? "Mozilla/5.0" : "Mozilla/5.0 (Mobile)"); - } else - try { + boolean generic_ua = prefs.getBoolean("generic_ua", true); + if (generic_ua) + return getGenericUserAgent(context); + + try { + if (userAgent == null) { if (webView == null) webView = new WebView(context); - return webView.getSettings().getUserAgentString(); - } catch (Throwable ex) { - Log.e(ex); - return null; + userAgent = webView.getSettings().getUserAgentString(); } + return userAgent; + } catch (Throwable ex) { + Log.w(ex); + return getGenericUserAgent(context); + } + } + + @NonNull + private static String getGenericUserAgent(Context context) { + boolean large = context.getResources().getConfiguration() + .isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE); + return (large ? "Mozilla/5.0" : "Mozilla/5.0 (Mobile)"); } interface IWebView {