From b025265f91efad3e288a00b285f5341a6e21e251 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 16 May 2021 16:17:06 +0200 Subject: [PATCH] execute status code check on HEAD --- .../http/HttpDownloadConnection.java | 84 ++++++++++--------- 1 file changed, 46 insertions(+), 38 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java index b41962d78..fca5cc705 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java @@ -318,6 +318,7 @@ public class HttpDownloadConnection implements Transferable { mostRecentCall = client.newCall(request); try { final Response response = mostRecentCall.execute(); + throwOnInvalidCode(response); final String contentLength = response.header("Content-Length"); final String contentType = response.header("Content-Type"); final AbstractConnectionManager.Extension extension = AbstractConnectionManager.Extension.of(mUrl.encodedPath()); @@ -332,7 +333,11 @@ public class HttpDownloadConnection implements Transferable { if (Strings.isNullOrEmpty(contentLength)) { throw new IOException("no content-length found in HEAD response"); } - return Long.parseLong(contentLength, 10); + final long size = Long.parseLong(contentLength, 10); + if (size < 0) { + throw new IOException("Server reported negative file size"); + } + return size; } catch (IOException e) { Log.d(Config.LOGTAG, "io exception during HEAD " + e.getMessage()); throw e; @@ -395,45 +400,41 @@ public class HttpDownloadConnection implements Transferable { final Request request = requestBuilder.build(); mostRecentCall = client.newCall(request); final Response response = mostRecentCall.execute(); - final int code = response.code(); - if (code >= 200 && code <= 299) { - final String contentRange = response.header("Content-Range"); - final boolean serverResumed = tryResume && contentRange != null && contentRange.startsWith("bytes " + resumeSize + "-"); - final InputStream inputStream = response.body().byteStream(); - final OutputStream outputStream; - long transmitted = 0; - if (tryResume && serverResumed) { - Log.d(Config.LOGTAG, "server resumed"); - transmitted = file.getSize(); - updateProgress(Math.round(((double) transmitted / expected) * 100)); - outputStream = AbstractConnectionManager.createOutputStream(file, true, false); - } else { - final String contentLength = response.header("Content-Length"); - final long size = Strings.isNullOrEmpty(contentLength) ? 0 : Longs.tryParse(contentLength); - if (expected != size) { - Log.d(Config.LOGTAG, "content-length reported on GET (" + size + ") did not match Content-Length reported on HEAD (" + expected + ")"); - } - file.getParentFile().mkdirs(); - if (!file.exists() && !file.createNewFile()) { - throw new FileWriterException(); - } - outputStream = AbstractConnectionManager.createOutputStream(file, false, false); - } - int count; - final byte[] buffer = new byte[4096]; - while ((count = inputStream.read(buffer)) != -1) { - transmitted += count; - try { - outputStream.write(buffer, 0, count); - } catch (IOException e) { - throw new FileWriterException(); - } - updateProgress(Math.round(((double) transmitted / expected) * 100)); - } - outputStream.flush(); + throwOnInvalidCode(response); + final String contentRange = response.header("Content-Range"); + final boolean serverResumed = tryResume && contentRange != null && contentRange.startsWith("bytes " + resumeSize + "-"); + final InputStream inputStream = response.body().byteStream(); + final OutputStream outputStream; + long transmitted = 0; + if (tryResume && serverResumed) { + Log.d(Config.LOGTAG, "server resumed"); + transmitted = file.getSize(); + updateProgress(Math.round(((double) transmitted / expected) * 100)); + outputStream = AbstractConnectionManager.createOutputStream(file, true, false); } else { - throw new IOException(String.format(Locale.ENGLISH, "HTTP Status code was %d", code)); + final String contentLength = response.header("Content-Length"); + final long size = Strings.isNullOrEmpty(contentLength) ? 0 : Longs.tryParse(contentLength); + if (expected != size) { + Log.d(Config.LOGTAG, "content-length reported on GET (" + size + ") did not match Content-Length reported on HEAD (" + expected + ")"); + } + file.getParentFile().mkdirs(); + if (!file.exists() && !file.createNewFile()) { + throw new FileWriterException(); + } + outputStream = AbstractConnectionManager.createOutputStream(file, false, false); } + int count; + final byte[] buffer = new byte[4096]; + while ((count = inputStream.read(buffer)) != -1) { + transmitted += count; + try { + outputStream.write(buffer, 0, count); + } catch (IOException e) { + throw new FileWriterException(); + } + updateProgress(Math.round(((double) transmitted / expected) * 100)); + } + outputStream.flush(); } private void updateImageBounds() { @@ -451,4 +452,11 @@ public class HttpDownloadConnection implements Transferable { } } + + private static void throwOnInvalidCode(final Response response) throws IOException { + final int code = response.code(); + if (code < 200 || code >= 300) { + throw new IOException(String.format(Locale.ENGLISH, "HTTP Status code was %d", code)); + } + } }