| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/download/download_item_impl.h" | 5 #include "content/browser/download/download_item_impl.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <deque> | 9 #include <deque> |
| 10 #include <iterator> | 10 #include <iterator> |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 #include "content/browser/download/mock_download_file.h" | 29 #include "content/browser/download/mock_download_file.h" |
| 30 #include "content/public/browser/browser_thread.h" | 30 #include "content/public/browser/browser_thread.h" |
| 31 #include "content/public/browser/download_interrupt_reasons.h" | 31 #include "content/public/browser/download_interrupt_reasons.h" |
| 32 #include "content/public/browser/download_url_parameters.h" | 32 #include "content/public/browser/download_url_parameters.h" |
| 33 #include "content/public/common/content_features.h" | 33 #include "content/public/common/content_features.h" |
| 34 #include "content/public/test/mock_download_item.h" | 34 #include "content/public/test/mock_download_item.h" |
| 35 #include "content/public/test/test_browser_context.h" | 35 #include "content/public/test/test_browser_context.h" |
| 36 #include "content/public/test/test_browser_thread_bundle.h" | 36 #include "content/public/test/test_browser_thread_bundle.h" |
| 37 #include "content/public/test/web_contents_tester.h" | 37 #include "content/public/test/web_contents_tester.h" |
| 38 #include "crypto/secure_hash.h" | 38 #include "crypto/secure_hash.h" |
| 39 #include "net/http/http_response_headers.h" |
| 39 #include "testing/gmock/include/gmock/gmock.h" | 40 #include "testing/gmock/include/gmock/gmock.h" |
| 40 #include "testing/gtest/include/gtest/gtest.h" | 41 #include "testing/gtest/include/gtest/gtest.h" |
| 41 | 42 |
| 42 using ::testing::DoAll; | 43 using ::testing::DoAll; |
| 43 using ::testing::Invoke; | 44 using ::testing::Invoke; |
| 44 using ::testing::InvokeWithoutArgs; | 45 using ::testing::InvokeWithoutArgs; |
| 45 using ::testing::NiceMock; | 46 using ::testing::NiceMock; |
| 46 using ::testing::Property; | 47 using ::testing::Property; |
| 47 using ::testing::Return; | 48 using ::testing::Return; |
| 48 using ::testing::ReturnRefOfCopy; | 49 using ::testing::ReturnRefOfCopy; |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 270 | 271 |
| 271 DownloadItemImpl* CreateDownloadItemWithCreateInfo( | 272 DownloadItemImpl* CreateDownloadItemWithCreateInfo( |
| 272 std::unique_ptr<DownloadCreateInfo> info) { | 273 std::unique_ptr<DownloadCreateInfo> info) { |
| 273 DownloadItemImpl* download = | 274 DownloadItemImpl* download = |
| 274 new DownloadItemImpl(&delegate_, next_download_id_++, *(info.get()), | 275 new DownloadItemImpl(&delegate_, next_download_id_++, *(info.get()), |
| 275 net::NetLogWithSource()); | 276 net::NetLogWithSource()); |
| 276 allocated_downloads_[download] = base::WrapUnique(download); | 277 allocated_downloads_[download] = base::WrapUnique(download); |
| 277 return download; | 278 return download; |
| 278 } | 279 } |
| 279 | 280 |
| 281 // Creates a new net::HttpResponseHeaders object for the |response_code|. |
| 282 scoped_refptr<const net::HttpResponseHeaders> CreateResponseHeaders( |
| 283 int response_code) { |
| 284 return make_scoped_refptr(new net::HttpResponseHeaders( |
| 285 "HTTP/1.1 " + std::to_string(response_code))); |
| 286 } |
| 287 |
| 280 // This class keeps ownership of the created download item; it will | 288 // This class keeps ownership of the created download item; it will |
| 281 // be torn down at the end of the test unless DestroyDownloadItem is | 289 // be torn down at the end of the test unless DestroyDownloadItem is |
| 282 // called. | 290 // called. |
| 283 DownloadItemImpl* CreateDownloadItem() { | 291 DownloadItemImpl* CreateDownloadItem() { |
| 284 create_info_->download_id = ++next_download_id_; | 292 create_info_->download_id = ++next_download_id_; |
| 285 DownloadItemImpl* download = | 293 DownloadItemImpl* download = |
| 286 new DownloadItemImpl(&delegate_, create_info_->download_id, | 294 new DownloadItemImpl(&delegate_, create_info_->download_id, |
| 287 *create_info_, net::NetLogWithSource()); | 295 *create_info_, net::NetLogWithSource()); |
| 288 allocated_downloads_[download] = base::WrapUnique(download); | 296 allocated_downloads_[download] = base::WrapUnique(download); |
| 289 return download; | 297 return download; |
| (...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 809 | 817 |
| 810 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); | 818 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); |
| 811 EXPECT_EQ(1, observer.interrupt_count()); | 819 EXPECT_EQ(1, observer.interrupt_count()); |
| 812 CleanupItem(item, nullptr, DownloadItem::INTERRUPTED); | 820 CleanupItem(item, nullptr, DownloadItem::INTERRUPTED); |
| 813 } | 821 } |
| 814 | 822 |
| 815 // If the download attempts to resume and the resumption request fails, the | 823 // If the download attempts to resume and the resumption request fails, the |
| 816 // subsequent Start() call shouldn't update the origin state (URL redirect | 824 // subsequent Start() call shouldn't update the origin state (URL redirect |
| 817 // chains, Content-Disposition, download URL, etc..) | 825 // chains, Content-Disposition, download URL, etc..) |
| 818 TEST_F(DownloadItemTest, FailedResumptionDoesntUpdateOriginState) { | 826 TEST_F(DownloadItemTest, FailedResumptionDoesntUpdateOriginState) { |
| 827 constexpr int kFirstResponseCode = 200; |
| 819 const char kContentDisposition[] = "attachment; filename=foo"; | 828 const char kContentDisposition[] = "attachment; filename=foo"; |
| 820 const char kFirstETag[] = "ABC"; | 829 const char kFirstETag[] = "ABC"; |
| 821 const char kFirstLastModified[] = "Yesterday"; | 830 const char kFirstLastModified[] = "Yesterday"; |
| 822 const char kFirstURL[] = "http://www.example.com/download"; | 831 const char kFirstURL[] = "http://www.example.com/download"; |
| 823 const char kMimeType[] = "text/css"; | 832 const char kMimeType[] = "text/css"; |
| 833 create_info()->response_headers = CreateResponseHeaders(kFirstResponseCode); |
| 824 create_info()->content_disposition = kContentDisposition; | 834 create_info()->content_disposition = kContentDisposition; |
| 825 create_info()->etag = kFirstETag; | 835 create_info()->etag = kFirstETag; |
| 826 create_info()->last_modified = kFirstLastModified; | 836 create_info()->last_modified = kFirstLastModified; |
| 827 create_info()->url_chain.push_back(GURL(kFirstURL)); | 837 create_info()->url_chain.push_back(GURL(kFirstURL)); |
| 828 create_info()->mime_type = kMimeType; | 838 create_info()->mime_type = kMimeType; |
| 829 | 839 |
| 830 DownloadItemImpl* item = CreateDownloadItem(); | 840 DownloadItemImpl* item = CreateDownloadItem(); |
| 831 MockDownloadFile* download_file = | 841 MockDownloadFile* download_file = |
| 832 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); | 842 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); |
| 843 ASSERT_TRUE(item->GetResponseHeaders()); |
| 844 EXPECT_EQ(kFirstResponseCode, item->GetResponseHeaders()->response_code()); |
| 833 EXPECT_EQ(kContentDisposition, item->GetContentDisposition()); | 845 EXPECT_EQ(kContentDisposition, item->GetContentDisposition()); |
| 834 EXPECT_EQ(kFirstETag, item->GetETag()); | 846 EXPECT_EQ(kFirstETag, item->GetETag()); |
| 835 EXPECT_EQ(kFirstLastModified, item->GetLastModifiedTime()); | 847 EXPECT_EQ(kFirstLastModified, item->GetLastModifiedTime()); |
| 836 EXPECT_EQ(kFirstURL, item->GetURL().spec()); | 848 EXPECT_EQ(kFirstURL, item->GetURL().spec()); |
| 837 EXPECT_EQ(kMimeType, item->GetMimeType()); | 849 EXPECT_EQ(kMimeType, item->GetMimeType()); |
| 838 | 850 |
| 839 EXPECT_CALL(*mock_delegate(), | 851 EXPECT_CALL(*mock_delegate(), |
| 840 MockResumeInterruptedDownload( | 852 MockResumeInterruptedDownload( |
| 841 AllOf(Property(&DownloadUrlParameters::file_path, | 853 AllOf(Property(&DownloadUrlParameters::file_path, |
| 842 Property(&base::FilePath::value, | 854 Property(&base::FilePath::value, |
| 843 kDummyIntermediatePath)), | 855 kDummyIntermediatePath)), |
| 844 Property(&DownloadUrlParameters::offset, 1)), | 856 Property(&DownloadUrlParameters::offset, 1)), |
| 845 _)); | 857 _)); |
| 846 EXPECT_CALL(*download_file, Detach()); | 858 EXPECT_CALL(*download_file, Detach()); |
| 847 item->DestinationObserverAsWeakPtr()->DestinationError( | 859 item->DestinationObserverAsWeakPtr()->DestinationError( |
| 848 DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR, 1, | 860 DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR, 1, |
| 849 std::unique_ptr<crypto::SecureHash>()); | 861 std::unique_ptr<crypto::SecureHash>()); |
| 850 RunAllPendingInMessageLoops(); | 862 RunAllPendingInMessageLoops(); |
| 851 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); | 863 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); |
| 852 | 864 |
| 853 // Now change the create info. The changes should not cause the DownloadItem | 865 // Now change the create info. The changes should not cause the DownloadItem |
| 854 // to be updated. | 866 // to be updated. |
| 867 constexpr int kSecondResponseCode = 418; |
| 855 const char kSecondContentDisposition[] = "attachment; filename=bar"; | 868 const char kSecondContentDisposition[] = "attachment; filename=bar"; |
| 856 const char kSecondETag[] = "123"; | 869 const char kSecondETag[] = "123"; |
| 857 const char kSecondLastModified[] = "Today"; | 870 const char kSecondLastModified[] = "Today"; |
| 858 const char kSecondURL[] = "http://example.com/another-download"; | 871 const char kSecondURL[] = "http://example.com/another-download"; |
| 859 const char kSecondMimeType[] = "text/html"; | 872 const char kSecondMimeType[] = "text/html"; |
| 873 create_info()->response_headers = CreateResponseHeaders(kSecondResponseCode); |
| 860 create_info()->content_disposition = kSecondContentDisposition; | 874 create_info()->content_disposition = kSecondContentDisposition; |
| 861 create_info()->etag = kSecondETag; | 875 create_info()->etag = kSecondETag; |
| 862 create_info()->last_modified = kSecondLastModified; | 876 create_info()->last_modified = kSecondLastModified; |
| 863 create_info()->url_chain.clear(); | 877 create_info()->url_chain.clear(); |
| 864 create_info()->url_chain.push_back(GURL(kSecondURL)); | 878 create_info()->url_chain.push_back(GURL(kSecondURL)); |
| 865 create_info()->mime_type = kSecondMimeType; | 879 create_info()->mime_type = kSecondMimeType; |
| 866 create_info()->result = DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED; | 880 create_info()->result = DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED; |
| 867 create_info()->save_info->file_path = base::FilePath(kDummyIntermediatePath); | 881 create_info()->save_info->file_path = base::FilePath(kDummyIntermediatePath); |
| 868 create_info()->save_info->offset = 1; | 882 create_info()->save_info->offset = 1; |
| 869 | 883 |
| 870 // Calling Start() with a response indicating failure shouldn't cause a target | 884 // Calling Start() with a response indicating failure shouldn't cause a target |
| 871 // update, nor should it result in discarding the intermediate file. | 885 // update, nor should it result in discarding the intermediate file. |
| 872 DownloadTargetCallback target_callback; | 886 DownloadTargetCallback target_callback; |
| 873 download_file = CallDownloadItemStart(item, &target_callback); | 887 download_file = CallDownloadItemStart(item, &target_callback); |
| 874 ASSERT_FALSE(target_callback.is_null()); | 888 ASSERT_FALSE(target_callback.is_null()); |
| 875 target_callback.Run(base::FilePath(kDummyTargetPath), | 889 target_callback.Run(base::FilePath(kDummyTargetPath), |
| 876 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | 890 DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
| 877 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | 891 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, |
| 878 base::FilePath(kDummyIntermediatePath), | 892 base::FilePath(kDummyIntermediatePath), |
| 879 DOWNLOAD_INTERRUPT_REASON_NONE); | 893 DOWNLOAD_INTERRUPT_REASON_NONE); |
| 880 RunAllPendingInMessageLoops(); | 894 RunAllPendingInMessageLoops(); |
| 881 | 895 |
| 896 ASSERT_TRUE(item->GetResponseHeaders()); |
| 897 EXPECT_EQ(kFirstResponseCode, item->GetResponseHeaders()->response_code()); |
| 882 EXPECT_EQ(kContentDisposition, item->GetContentDisposition()); | 898 EXPECT_EQ(kContentDisposition, item->GetContentDisposition()); |
| 883 EXPECT_EQ(kFirstETag, item->GetETag()); | 899 EXPECT_EQ(kFirstETag, item->GetETag()); |
| 884 EXPECT_EQ(kFirstLastModified, item->GetLastModifiedTime()); | 900 EXPECT_EQ(kFirstLastModified, item->GetLastModifiedTime()); |
| 885 EXPECT_EQ(kFirstURL, item->GetURL().spec()); | 901 EXPECT_EQ(kFirstURL, item->GetURL().spec()); |
| 886 EXPECT_EQ(kMimeType, item->GetMimeType()); | 902 EXPECT_EQ(kMimeType, item->GetMimeType()); |
| 887 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); | 903 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); |
| 888 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, item->GetLastReason()); | 904 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, item->GetLastReason()); |
| 889 EXPECT_EQ(kDummyIntermediatePath, item->GetFullPath().value()); | 905 EXPECT_EQ(kDummyIntermediatePath, item->GetFullPath().value()); |
| 890 EXPECT_EQ(1, item->GetReceivedBytes()); | 906 EXPECT_EQ(1, item->GetReceivedBytes()); |
| 891 } | 907 } |
| 892 | 908 |
| 893 // If the download resumption request succeeds, the origin state should be | 909 // If the download resumption request succeeds, the origin state should be |
| 894 // updated. | 910 // updated. |
| 895 TEST_F(DownloadItemTest, SucceededResumptionUpdatesOriginState) { | 911 TEST_F(DownloadItemTest, SucceededResumptionUpdatesOriginState) { |
| 912 constexpr int kFirstResponseCode = 200; |
| 896 const char kContentDisposition[] = "attachment; filename=foo"; | 913 const char kContentDisposition[] = "attachment; filename=foo"; |
| 897 const char kFirstETag[] = "ABC"; | 914 const char kFirstETag[] = "ABC"; |
| 898 const char kFirstLastModified[] = "Yesterday"; | 915 const char kFirstLastModified[] = "Yesterday"; |
| 899 const char kFirstURL[] = "http://www.example.com/download"; | 916 const char kFirstURL[] = "http://www.example.com/download"; |
| 900 const char kMimeType[] = "text/css"; | 917 const char kMimeType[] = "text/css"; |
| 918 create_info()->response_headers = CreateResponseHeaders(kFirstResponseCode); |
| 901 create_info()->content_disposition = kContentDisposition; | 919 create_info()->content_disposition = kContentDisposition; |
| 902 create_info()->etag = kFirstETag; | 920 create_info()->etag = kFirstETag; |
| 903 create_info()->last_modified = kFirstLastModified; | 921 create_info()->last_modified = kFirstLastModified; |
| 904 create_info()->url_chain.push_back(GURL(kFirstURL)); | 922 create_info()->url_chain.push_back(GURL(kFirstURL)); |
| 905 create_info()->mime_type = kMimeType; | 923 create_info()->mime_type = kMimeType; |
| 906 | 924 |
| 907 DownloadItemImpl* item = CreateDownloadItem(); | 925 DownloadItemImpl* item = CreateDownloadItem(); |
| 908 MockDownloadFile* download_file = | 926 MockDownloadFile* download_file = |
| 909 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); | 927 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); |
| 910 EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _)); | 928 EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _)); |
| 911 EXPECT_CALL(*download_file, Detach()); | 929 EXPECT_CALL(*download_file, Detach()); |
| 912 item->DestinationObserverAsWeakPtr()->DestinationError( | 930 item->DestinationObserverAsWeakPtr()->DestinationError( |
| 913 DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR, 0, | 931 DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR, 0, |
| 914 std::unique_ptr<crypto::SecureHash>()); | 932 std::unique_ptr<crypto::SecureHash>()); |
| 915 RunAllPendingInMessageLoops(); | 933 RunAllPendingInMessageLoops(); |
| 916 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); | 934 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); |
| 917 | 935 |
| 918 // Now change the create info. The changes should not cause the DownloadItem | 936 // Now change the create info. The changes should not cause the DownloadItem |
| 919 // to be updated. | 937 // to be updated. |
| 938 constexpr int kSecondResponseCode = 201; |
| 920 const char kSecondContentDisposition[] = "attachment; filename=bar"; | 939 const char kSecondContentDisposition[] = "attachment; filename=bar"; |
| 921 const char kSecondETag[] = "123"; | 940 const char kSecondETag[] = "123"; |
| 922 const char kSecondLastModified[] = "Today"; | 941 const char kSecondLastModified[] = "Today"; |
| 923 const char kSecondURL[] = "http://example.com/another-download"; | 942 const char kSecondURL[] = "http://example.com/another-download"; |
| 924 const char kSecondMimeType[] = "text/html"; | 943 const char kSecondMimeType[] = "text/html"; |
| 944 create_info()->response_headers = CreateResponseHeaders(kSecondResponseCode); |
| 925 create_info()->content_disposition = kSecondContentDisposition; | 945 create_info()->content_disposition = kSecondContentDisposition; |
| 926 create_info()->etag = kSecondETag; | 946 create_info()->etag = kSecondETag; |
| 927 create_info()->last_modified = kSecondLastModified; | 947 create_info()->last_modified = kSecondLastModified; |
| 928 create_info()->url_chain.clear(); | 948 create_info()->url_chain.clear(); |
| 929 create_info()->url_chain.push_back(GURL(kSecondURL)); | 949 create_info()->url_chain.push_back(GURL(kSecondURL)); |
| 930 create_info()->mime_type = kSecondMimeType; | 950 create_info()->mime_type = kSecondMimeType; |
| 931 | 951 |
| 932 DownloadTargetCallback target_callback; | 952 DownloadTargetCallback target_callback; |
| 933 download_file = CallDownloadItemStart(item, &target_callback); | 953 download_file = CallDownloadItemStart(item, &target_callback); |
| 934 | 954 |
| 955 ASSERT_TRUE(item->GetResponseHeaders()); |
| 956 EXPECT_EQ(kSecondResponseCode, item->GetResponseHeaders()->response_code()); |
| 935 EXPECT_EQ(kSecondContentDisposition, item->GetContentDisposition()); | 957 EXPECT_EQ(kSecondContentDisposition, item->GetContentDisposition()); |
| 936 EXPECT_EQ(kSecondETag, item->GetETag()); | 958 EXPECT_EQ(kSecondETag, item->GetETag()); |
| 937 EXPECT_EQ(kSecondLastModified, item->GetLastModifiedTime()); | 959 EXPECT_EQ(kSecondLastModified, item->GetLastModifiedTime()); |
| 938 EXPECT_EQ(kSecondURL, item->GetURL().spec()); | 960 EXPECT_EQ(kSecondURL, item->GetURL().spec()); |
| 939 EXPECT_EQ(kSecondMimeType, item->GetMimeType()); | 961 EXPECT_EQ(kSecondMimeType, item->GetMimeType()); |
| 940 | 962 |
| 941 CleanupItem(item, download_file, DownloadItem::IN_PROGRESS); | 963 CleanupItem(item, download_file, DownloadItem::IN_PROGRESS); |
| 942 } | 964 } |
| 943 | 965 |
| 944 // Ensure when strong validators changed on resumption, the received | 966 // Ensure when strong validators changed on resumption, the received |
| (...skipping 1326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2271 | 2293 |
| 2272 item_->Cancel(true); | 2294 item_->Cancel(true); |
| 2273 RunAllPendingInMessageLoops(); | 2295 RunAllPendingInMessageLoops(); |
| 2274 } | 2296 } |
| 2275 | 2297 |
| 2276 TEST(MockDownloadItem, Compiles) { | 2298 TEST(MockDownloadItem, Compiles) { |
| 2277 MockDownloadItem mock_item; | 2299 MockDownloadItem mock_item; |
| 2278 } | 2300 } |
| 2279 | 2301 |
| 2280 } // namespace content | 2302 } // namespace content |
| OLD | NEW |