diff --git a/app/src/main/java/eu/faircode/email/ContactInfo.java b/app/src/main/java/eu/faircode/email/ContactInfo.java index 552b480a1d..fc4de7d17c 100644 --- a/app/src/main/java/eu/faircode/email/ContactInfo.java +++ b/app/src/main/java/eu/faircode/email/ContactInfo.java @@ -87,6 +87,7 @@ public class ContactInfo { private static final int GRAVATAR_TIMEOUT = 5 * 1000; // milliseconds private static final int FAVICON_CONNECT_TIMEOUT = 5 * 1000; // milliseconds private static final int FAVICON_READ_TIMEOUT = 10 * 1000; // milliseconds + private static final int FAVICON_READ_BYTES = 2048; private static final long CACHE_CONTACT_DURATION = 2 * 60 * 1000L; // milliseconds private static final long CACHE_GRAVATAR_DURATION = 2 * 60 * 60 * 1000L; // milliseconds @@ -288,7 +289,7 @@ public class ContactInfo { String domain = (at < 0 ? null : info.email.substring(at + 1).toLowerCase(Locale.ROOT)); if (domain != null) { - if ("gmail.com".equals(domain)) + if ("gmail.com".equals(domain) || "googlemail.com".equals(domain)) domain = "google.com"; File dir = new File(context.getCacheDir(), "favicons"); @@ -308,30 +309,36 @@ public class ContactInfo { try { info.bitmap = getFavicon(new URL(base, "favicon.ico")); } catch (IOException ex) { - if (isTransient(ex)) - throw ex; - Log.i("Favicon ex=" + ex.getClass().getName() + " " + ex.getMessage()); - } - try { - info.bitmap = parseFavicon(base); - } catch (IOException ex) { - if (isTransient(ex)) + if (ex instanceof SocketTimeoutException) throw ex; Log.i("Favicon ex=" + ex.getClass().getName() + " " + ex.getMessage()); } + if (info.bitmap == null) + try { + info.bitmap = parseFavicon(base); + } catch (IOException ex) { + if (ex instanceof SocketTimeoutException) + throw ex; + Log.i("Favicon ex=" + ex.getClass().getName() + " " + ex.getMessage()); + } + URL www = new URL("https://www." + domain); - try { - info.bitmap = getFavicon(new URL(www, "favicon.ico")); - } catch (IOException ex) { - if (isTransient(ex)) - throw ex; - Log.i("Favicon ex=" + ex.getClass().getName() + " " + ex.getMessage()); - } - info.bitmap = parseFavicon(www); + if (info.bitmap == null) + try { + info.bitmap = getFavicon(new URL(www, "favicon.ico")); + } catch (IOException ex) { + if (ex instanceof SocketTimeoutException) + throw ex; + Log.i("Favicon ex=" + ex.getClass().getName() + " " + ex.getMessage()); + } + if (info.bitmap == null) + info.bitmap = parseFavicon(www); // Add to cache - if (info.bitmap != null) + if (info.bitmap == null) + throw new FileNotFoundException("decode"); + else try (OutputStream os = new BufferedOutputStream(new FileOutputStream(file))) { info.bitmap.compress(Bitmap.CompressFormat.PNG, 90, os); } @@ -397,8 +404,11 @@ public class ContactInfo { String response; try { - // TODO limit read - response = Helper.readStream(connection.getInputStream(), StandardCharsets.UTF_8.name()); + byte[] buffer = new byte[FAVICON_READ_BYTES]; + int len = connection.getInputStream().read(buffer); + if (len < 0) + throw new IOException("length"); + response = new String(buffer, 0, len, StandardCharsets.UTF_8.name()); } finally { connection.disconnect(); } @@ -439,14 +449,11 @@ public class ContactInfo { } } - private static boolean isTransient(Throwable ex) { - return (ex instanceof UnknownHostException || - ex instanceof SocketTimeoutException); - } - private static boolean isRecoverable(Throwable ex) { - return !(ex instanceof SocketTimeoutException || - ex instanceof ConnectException || + return !(ex instanceof ConnectException || + (ex instanceof UnknownHostException && + ex.getMessage() != null && + ex.getMessage().contains("No address associated with hostname")) || ex instanceof FileNotFoundException || ex instanceof SSLPeerUnverifiedException || (ex instanceof SSLException &&