diff --git a/app/src/main/java/eu/faircode/email/Helper.java b/app/src/main/java/eu/faircode/email/Helper.java index 6949486814..1a315cedb9 100644 --- a/app/src/main/java/eu/faircode/email/Helper.java +++ b/app/src/main/java/eu/faircode/email/Helper.java @@ -103,6 +103,7 @@ import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.bottomnavigation.BottomNavigationView; +import org.jsoup.helper.HttpConnection; import org.openintents.openpgp.util.OpenPgpApi; import java.io.ByteArrayOutputStream; @@ -113,6 +114,9 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLDecoder; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; @@ -150,6 +154,7 @@ public class Helper { static final int BUFFER_SIZE = 8192; // Same as in Files class static final long MIN_REQUIRED_SPACE = 250 * 1024L * 1024L; + static final int MAX_REDIRECTS = 5; // https://www.freesoft.org/CIE/RFC/1945/46.htm static final String PGP_BEGIN_MESSAGE = "-----BEGIN PGP MESSAGE-----"; static final String PGP_END_MESSAGE = "-----END PGP MESSAGE-----"; @@ -1619,6 +1624,53 @@ public class Helper { //intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, Uri.fromFile(initial)); } + static HttpURLConnection openUrlRedirect(Context context, String source, int timeout) throws IOException { + int redirects = 0; + URL url = new URL(source); + while (true) { + HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); + urlConnection.setRequestMethod("GET"); + urlConnection.setDoOutput(false); + urlConnection.setReadTimeout(timeout); + urlConnection.setConnectTimeout(timeout); + urlConnection.setInstanceFollowRedirects(true); + urlConnection.setRequestProperty("User-Agent", WebViewEx.getUserAgent(context)); + urlConnection.connect(); + + try { + int status = urlConnection.getResponseCode(); + + if (status == HttpURLConnection.HTTP_MOVED_PERM || + status == HttpURLConnection.HTTP_MOVED_TEMP || + status == HttpURLConnection.HTTP_SEE_OTHER || + status == 307 /* Temporary redirect */ || + status == 308 /* Permanent redirect */) { + if (++redirects > MAX_REDIRECTS) + throw new IOException("Too many redirects"); + + String header = urlConnection.getHeaderField("Location"); + if (header == null) + throw new IOException("Location header missing"); + + String location = URLDecoder.decode(header, StandardCharsets.UTF_8.name()); + url = new URL(url, location); + Log.i("Redirect #" + redirects + " to " + url); + + urlConnection.disconnect(); + continue; + } + + if (status != HttpURLConnection.HTTP_OK) + throw new IOException("Error " + status + ": " + urlConnection.getResponseMessage()); + + return urlConnection; + } catch (IOException ex) { + urlConnection.disconnect(); + throw ex; + } + } + } + // Cryptography static String sha256(String data) throws NoSuchAlgorithmException { diff --git a/app/src/main/java/eu/faircode/email/ImageHelper.java b/app/src/main/java/eu/faircode/email/ImageHelper.java index 25dcba9348..59b3078324 100644 --- a/app/src/main/java/eu/faircode/email/ImageHelper.java +++ b/app/src/main/java/eu/faircode/email/ImageHelper.java @@ -70,9 +70,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; -import java.net.URL; -import java.net.URLDecoder; -import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; @@ -90,7 +87,6 @@ class ImageHelper { Helper.getBackgroundExecutor(0, "image_n"); static final int DOWNLOAD_TIMEOUT = 15; // seconds - private static final int MAX_REDIRECTS = 5; // https://www.freesoft.org/CIE/RFC/1945/46.htm private static final int MAX_PROBE = 64 * 1024; // bytes private static final int SLOW_CONNECTION = 2 * 1024; // Kbps @@ -670,50 +666,7 @@ class ImageHelper { Bitmap bm; HttpURLConnection urlConnection = null; try { - int redirects = 0; - URL url = new URL(source); - while (true) { - urlConnection = (HttpURLConnection) url.openConnection(); - urlConnection.setRequestMethod("GET"); - urlConnection.setDoOutput(false); - urlConnection.setReadTimeout(timeout); - urlConnection.setConnectTimeout(timeout); - urlConnection.setInstanceFollowRedirects(true); - urlConnection.setRequestProperty("User-Agent", WebViewEx.getUserAgent(context)); - urlConnection.connect(); - - try { - int status = urlConnection.getResponseCode(); - - if (status == HttpURLConnection.HTTP_MOVED_PERM || - status == HttpURLConnection.HTTP_MOVED_TEMP || - status == HttpURLConnection.HTTP_SEE_OTHER || - status == 307 /* Temporary redirect */ || - status == 308 /* Permanent redirect */) { - if (++redirects > MAX_REDIRECTS) - throw new IOException("Too many redirects"); - - String header = urlConnection.getHeaderField("Location"); - if (header == null) - throw new IOException("Location header missing"); - - String location = URLDecoder.decode(header, StandardCharsets.UTF_8.name()); - url = new URL(url, location); - Log.i("Redirect #" + redirects + " to " + url); - - urlConnection.disconnect(); - continue; - } - - if (status != HttpURLConnection.HTTP_OK) - throw new IOException("Error " + status + ": " + urlConnection.getResponseMessage()); - } catch (IOException ex) { - urlConnection.disconnect(); - throw ex; - } - - break; - } + urlConnection = Helper.openUrlRedirect(context, source, timeout); if (id > 0 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { File file = getCacheFile(context, id, source, ".blob");