diff --git a/google-api-client/src/main/java/com/google/api/client/googleapis/media/MediaHttpDownloader.java b/google-api-client/src/main/java/com/google/api/client/googleapis/media/MediaHttpDownloader.java index 19c9267f5..7e67bc036 100644 --- a/google-api-client/src/main/java/com/google/api/client/googleapis/media/MediaHttpDownloader.java +++ b/google-api-client/src/main/java/com/google/api/client/googleapis/media/MediaHttpDownloader.java @@ -14,6 +14,8 @@ package com.google.api.client.googleapis.media; +import static com.google.common.base.MoreObjects.firstNonNull; + import com.google.api.client.http.GenericUrl; import com.google.api.client.http.HttpBackOffIOExceptionHandler; import com.google.api.client.http.HttpBackOffUnsuccessfulResponseHandler; @@ -182,7 +184,8 @@ public void download(GenericUrl requestUrl, HttpHeaders requestHeaders, OutputSt HttpResponse response = executeCurrentRequest(lastBytePos, requestUrl, requestHeaders, outputStream); // All required bytes have been downloaded from the server. - mediaContentLength = response.getHeaders().getContentLength(); + mediaContentLength = + firstNonNull(response.getHeaders().getContentLength(), mediaContentLength); bytesDownloaded = mediaContentLength; updateStateAndNotifyListener(DownloadState.MEDIA_COMPLETE); return; diff --git a/google-api-client/src/test/java/com/google/api/client/googleapis/media/MediaHttpDownloaderTest.java b/google-api-client/src/test/java/com/google/api/client/googleapis/media/MediaHttpDownloaderTest.java index 59d4b0d67..17d7eb343 100644 --- a/google-api-client/src/test/java/com/google/api/client/googleapis/media/MediaHttpDownloaderTest.java +++ b/google-api-client/src/test/java/com/google/api/client/googleapis/media/MediaHttpDownloaderTest.java @@ -44,9 +44,16 @@ private static class MediaTransport extends MockHttpTransport { boolean testServerError; boolean testClientError; boolean directDownloadEnabled; + boolean contentLengthIncluded; protected MediaTransport(int contentLength) { this.contentLength = contentLength; + this.contentLengthIncluded = true; + } + + protected MediaTransport(int contentLength, boolean contentLengthIncluded) { + this.contentLength = contentLength; + this.contentLengthIncluded = contentLengthIncluded; } @Override @@ -74,7 +81,9 @@ public LowLevelHttpResponse execute() { return response; } response.setStatusCode(200); - response.addHeader("Content-Length", String.valueOf(contentLength)); + if (contentLengthIncluded) { + response.addHeader("Content-Length", String.valueOf(contentLength)); + } response.setContent( new ByteArrayInputStream(new byte[contentLength - bytesDownloaded])); return response; @@ -327,7 +336,22 @@ public void testSetBytesDownloadedWithDirectDownload() throws Exception { MediaHttpDownloader downloader = new MediaHttpDownloader(fakeTransport, null); downloader.setDirectDownloadEnabled(true); downloader.setBytesDownloaded(contentLength - 10000); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + downloader.download(new GenericUrl(TEST_REQUEST_URL), outputStream); + assertEquals(10000, outputStream.size()); + // There should be 1 download call made. + assertEquals(1, fakeTransport.lowLevelExecCalls); + } + + public void testSetBytesDownloadedWithDirectDownloadAndContentLengthNull() throws Exception { + int contentLength = MediaHttpDownloader.MAXIMUM_CHUNK_SIZE; + MediaTransport fakeTransport = new MediaTransport(contentLength,false); + fakeTransport.directDownloadEnabled = true; + fakeTransport.bytesDownloaded = contentLength - 10000; + MediaHttpDownloader downloader = new MediaHttpDownloader(fakeTransport, null); + downloader.setDirectDownloadEnabled(true); + downloader.setBytesDownloaded(contentLength - 10000); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); downloader.download(new GenericUrl(TEST_REQUEST_URL), outputStream); assertEquals(10000, outputStream.size());