Index: content/browser/download/download_browsertest.cc |
diff --git a/content/browser/download/download_browsertest.cc b/content/browser/download/download_browsertest.cc |
index aaa6dbd3992831ffa52b325e3d1e2ddb00ddc437..18af2c4df788bb6fe316db01c8ab445beda154b4 100644 |
--- a/content/browser/download/download_browsertest.cc |
+++ b/content/browser/download/download_browsertest.cc |
@@ -1194,6 +1194,67 @@ IN_PROC_BROWSER_TEST_P(DownloadResumptionContentTest, RedirectBeforeResume) { |
download->GetTargetFilePath())); |
} |
+// If a resumption request results in a redirect, the response should be ignored |
+// and the download should be marked as interrupted again. |
+IN_PROC_BROWSER_TEST_P(DownloadResumptionContentTest, RedirectWhileResume) { |
+ TestDownloadRequestHandler request_handler( |
+ GURL("http://example.com/first-url")); |
+ TestDownloadRequestHandler::Parameters parameters = |
+ TestDownloadRequestHandler::Parameters::WithSingleInterruption(); |
+ ++parameters.pattern_generator_seed; |
+ request_handler.StartServing(parameters); |
+ |
+ // We should never send a request to the decoy. If we do, the request will |
+ // always succeed, which results in behavior that diverges from what we want, |
+ // which is for the download to return to being interrupted. |
+ TestDownloadRequestHandler decoy_request_handler( |
+ GURL("http://example.com/decoy")); |
+ decoy_request_handler.StartServing(TestDownloadRequestHandler::Parameters()); |
+ |
+ DownloadItem* download = StartDownloadAndReturnItem( |
+ initiator_shell_for_resumption(), request_handler.url()); |
+ WaitForInterrupt(download); |
+ |
+ // Upon resumption, the server starts responding with a redirect. This |
+ // response should not be accepted. |
+ request_handler.StartServingStaticResponse( |
+ "HTTP/1.1 302 Redirect\r\n" |
+ "Location: http://example.com/decoy\r\n" |
+ "\r\n"); |
+ PrepareToResume(); |
+ download->Resume(); |
+ WaitForInterrupt(download); |
+ EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_SERVER_UNREACHABLE, |
+ download->GetLastReason()); |
+ |
+ // Back to the original request handler. Resumption should now succeed, and |
+ // use the partial data it had prior to the first interruption. |
+ request_handler.StartServing(parameters); |
+ download->Resume(); |
+ WaitForCompletion(download); |
+ |
+ ASSERT_EQ(parameters.size, download->GetReceivedBytes()); |
+ ASSERT_EQ(parameters.size, download->GetTotalBytes()); |
+ ASSERT_NO_FATAL_FAILURE(ReadAndVerifyFileContents( |
+ parameters.pattern_generator_seed, parameters.size, |
+ download->GetTargetFilePath())); |
+ |
+ // Characterization risk: The next portion of the test examines the requests |
+ // that were sent out while downloading our resource. These requests |
+ // correspond to the requests that were generated by the browser and the |
+ // downloads system and may change as implementation details change. |
+ TestDownloadRequestHandler::CompletedRequests requests; |
+ request_handler.GetCompletedRequestInfo(&requests); |
+ |
+ ASSERT_EQ(3u, requests.size()); |
+ |
+ // None of the request should have transferred the entire resource. The |
+ // redirect response shows up as a response with 0 bytes transferred. |
+ EXPECT_GT(parameters.size, requests[0].transferred_byte_count); |
+ EXPECT_EQ(0, requests[1].transferred_byte_count); |
+ EXPECT_GT(parameters.size, requests[2].transferred_byte_count); |
+} |
+ |
// If the server response for the resumption request specifies a bad range (i.e. |
// not the range that was requested or an invalid or missing Content-Range |
// header), then the download should be marked as interrupted again without |