| 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_manager_impl.h" | 5 #include "content/browser/download/download_manager_impl.h" |
| 6 | 6 |
| 7 #include <iterator> | 7 #include <iterator> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/callback.h" | 10 #include "base/callback.h" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 #include "content/browser/download/download_stats.h" | 23 #include "content/browser/download/download_stats.h" |
| 24 #include "content/browser/renderer_host/render_view_host_impl.h" | 24 #include "content/browser/renderer_host/render_view_host_impl.h" |
| 25 #include "content/browser/renderer_host/resource_dispatcher_host_impl.h" | 25 #include "content/browser/renderer_host/resource_dispatcher_host_impl.h" |
| 26 #include "content/browser/web_contents/web_contents_impl.h" | 26 #include "content/browser/web_contents/web_contents_impl.h" |
| 27 #include "content/public/browser/browser_context.h" | 27 #include "content/public/browser/browser_context.h" |
| 28 #include "content/public/browser/browser_thread.h" | 28 #include "content/public/browser/browser_thread.h" |
| 29 #include "content/public/browser/content_browser_client.h" | 29 #include "content/public/browser/content_browser_client.h" |
| 30 #include "content/public/browser/download_interrupt_reasons.h" | 30 #include "content/public/browser/download_interrupt_reasons.h" |
| 31 #include "content/public/browser/download_manager_delegate.h" | 31 #include "content/public/browser/download_manager_delegate.h" |
| 32 #include "content/public/browser/download_persistent_store_info.h" | 32 #include "content/public/browser/download_persistent_store_info.h" |
| 33 #include "content/public/browser/download_url_parameters.h" |
| 33 #include "content/public/browser/notification_service.h" | 34 #include "content/public/browser/notification_service.h" |
| 34 #include "content/public/browser/notification_types.h" | 35 #include "content/public/browser/notification_types.h" |
| 35 #include "content/public/browser/render_process_host.h" | 36 #include "content/public/browser/render_process_host.h" |
| 36 #include "content/public/browser/web_contents_delegate.h" | 37 #include "content/public/browser/web_contents_delegate.h" |
| 38 #include "net/base/load_flags.h" |
| 37 #include "net/base/upload_data.h" | 39 #include "net/base/upload_data.h" |
| 38 | 40 |
| 39 using content::BrowserThread; | 41 using content::BrowserThread; |
| 40 using content::DownloadId; | 42 using content::DownloadId; |
| 41 using content::DownloadItem; | 43 using content::DownloadItem; |
| 42 using content::DownloadPersistentStoreInfo; | 44 using content::DownloadPersistentStoreInfo; |
| 43 using content::ResourceDispatcherHostImpl; | 45 using content::ResourceDispatcherHostImpl; |
| 44 using content::WebContents; | 46 using content::WebContents; |
| 45 | 47 |
| 46 namespace { | 48 namespace { |
| 47 | 49 |
| 48 // Param structs exist because base::Bind can only handle 6 args. | 50 void BeginDownload(content::DownloadUrlParameters* params) { |
| 49 struct URLParams { | 51 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 50 URLParams(const GURL& url, const GURL& referrer, int64 post_id, bool cache) | 52 // ResourceDispatcherHost{Base} is-not-a URLRequest::Delegate, and |
| 51 : url_(url), referrer_(referrer), post_id_(post_id), prefer_cache_(cache) {} | 53 // DownloadUrlParameters can-not include resource_dispatcher_host_impl.h, so |
| 52 GURL url_; | 54 // we must down cast. RDHI is the only subclass of RDH as of 2012 May 4. |
| 53 GURL referrer_; | 55 content::ResourceDispatcherHostImpl* resource_dispatcher_host = |
| 54 int64 post_id_; | 56 static_cast<content::ResourceDispatcherHostImpl*>( |
| 55 bool prefer_cache_; | 57 params->resource_dispatcher_host()); |
| 56 }; | 58 scoped_ptr<net::URLRequest> request(new net::URLRequest( |
| 57 | 59 params->url(), resource_dispatcher_host)); |
| 58 struct RenderParams { | 60 request->set_referrer(params->referrer().spec()); |
| 59 RenderParams(int rpi, int rvi) | 61 request->set_load_flags(request->load_flags() | params->load_flags()); |
| 60 : render_process_id_(rpi), render_view_id_(rvi) {} | 62 request->set_method(params->method()); |
| 61 int render_process_id_; | 63 if (!params->post_body().empty()) |
| 62 int render_view_id_; | 64 request->AppendBytesToUpload(params->post_body().data(), |
| 63 }; | 65 params->post_body().size()); |
| 64 | 66 if (params->post_id() >= 0) { |
| 65 void BeginDownload( | |
| 66 const URLParams& url_params, | |
| 67 const content::DownloadSaveInfo& save_info, | |
| 68 ResourceDispatcherHostImpl* resource_dispatcher_host, | |
| 69 const RenderParams& render_params, | |
| 70 content::ResourceContext* context, | |
| 71 const content::DownloadManager::OnStartedCallback& callback) { | |
| 72 scoped_ptr<net::URLRequest> request( | |
| 73 new net::URLRequest(url_params.url_, resource_dispatcher_host)); | |
| 74 request->set_referrer(url_params.referrer_.spec()); | |
| 75 if (url_params.post_id_ >= 0) { | |
| 76 // The POST in this case does not have an actual body, and only works | 67 // The POST in this case does not have an actual body, and only works |
| 77 // when retrieving data from cache. This is done because we don't want | 68 // when retrieving data from cache. This is done because we don't want |
| 78 // to do a re-POST without user consent, and currently don't have a good | 69 // to do a re-POST without user consent, and currently don't have a good |
| 79 // plan on how to display the UI for that. | 70 // plan on how to display the UI for that. |
| 80 DCHECK(url_params.prefer_cache_); | 71 DCHECK(params->prefer_cache()); |
| 81 request->set_method("POST"); | 72 DCHECK(params->method() == "POST"); |
| 82 scoped_refptr<net::UploadData> upload_data = new net::UploadData(); | 73 scoped_refptr<net::UploadData> upload_data = new net::UploadData(); |
| 83 upload_data->set_identifier(url_params.post_id_); | 74 upload_data->set_identifier(params->post_id()); |
| 84 request->set_upload(upload_data); | 75 request->set_upload(upload_data); |
| 85 } | 76 } |
| 77 for (content::DownloadUrlParameters::RequestHeadersType::const_iterator iter |
| 78 = params->request_headers_begin(); |
| 79 iter != params->request_headers_end(); |
| 80 ++iter) { |
| 81 request->SetExtraRequestHeaderByName( |
| 82 iter->first, iter->second, false/*overwrite*/); |
| 83 } |
| 86 resource_dispatcher_host->BeginDownload( | 84 resource_dispatcher_host->BeginDownload( |
| 87 request.Pass(), | 85 request.Pass(), |
| 88 context, | 86 params->resource_context(), |
| 89 render_params.render_process_id_, | 87 params->render_process_host_id(), |
| 90 render_params.render_view_id_, | 88 params->render_view_host_routing_id(), |
| 91 url_params.prefer_cache_, | 89 params->prefer_cache(), |
| 92 save_info, | 90 params->save_info(), |
| 93 callback); | 91 params->callback()); |
| 94 } | 92 } |
| 95 | 93 |
| 96 class MapValueIteratorAdapter { | 94 class MapValueIteratorAdapter { |
| 97 public: | 95 public: |
| 98 explicit MapValueIteratorAdapter( | 96 explicit MapValueIteratorAdapter( |
| 99 base::hash_map<int64, DownloadItem*>::const_iterator iter) | 97 base::hash_map<int64, DownloadItem*>::const_iterator iter) |
| 100 : iter_(iter) { | 98 : iter_(iter) { |
| 101 } | 99 } |
| 102 ~MapValueIteratorAdapter() {} | 100 ~MapValueIteratorAdapter() {} |
| 103 | 101 |
| (...skipping 727 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 831 int DownloadManagerImpl::RemoveDownloads(base::Time remove_begin) { | 829 int DownloadManagerImpl::RemoveDownloads(base::Time remove_begin) { |
| 832 return RemoveDownloadsBetween(remove_begin, base::Time()); | 830 return RemoveDownloadsBetween(remove_begin, base::Time()); |
| 833 } | 831 } |
| 834 | 832 |
| 835 int DownloadManagerImpl::RemoveAllDownloads() { | 833 int DownloadManagerImpl::RemoveAllDownloads() { |
| 836 download_stats::RecordClearAllSize(history_downloads_.size()); | 834 download_stats::RecordClearAllSize(history_downloads_.size()); |
| 837 // The null times make the date range unbounded. | 835 // The null times make the date range unbounded. |
| 838 return RemoveDownloadsBetween(base::Time(), base::Time()); | 836 return RemoveDownloadsBetween(base::Time(), base::Time()); |
| 839 } | 837 } |
| 840 | 838 |
| 841 // Initiate a download of a specific URL. We send the request to the | |
| 842 // ResourceDispatcherHost, and let it send us responses like a regular | |
| 843 // download. | |
| 844 void DownloadManagerImpl::DownloadUrl( | 839 void DownloadManagerImpl::DownloadUrl( |
| 845 const GURL& url, | 840 scoped_ptr<content::DownloadUrlParameters> params) { |
| 846 const GURL& referrer, | 841 if (params->post_id() >= 0) { |
| 847 const std::string& referrer_charset, | 842 // Check this here so that the traceback is more useful. |
| 848 bool prefer_cache, | 843 DCHECK(params->prefer_cache()); |
| 849 int64 post_id, | 844 DCHECK(params->method() == "POST"); |
| 850 const content::DownloadSaveInfo& save_info, | 845 } |
| 851 WebContents* web_contents, | 846 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( |
| 852 const OnStartedCallback& callback) { | 847 &BeginDownload, base::Owned(params.release()))); |
| 853 ResourceDispatcherHostImpl* resource_dispatcher_host = | |
| 854 ResourceDispatcherHostImpl::Get(); | |
| 855 DCHECK(resource_dispatcher_host); | |
| 856 | |
| 857 // We send a pointer to content::ResourceContext, instead of the usual | |
| 858 // reference, so that a copy of the object isn't made. | |
| 859 // base::Bind can't handle 7 args, so we use URLParams and RenderParams. | |
| 860 BrowserThread::PostTask( | |
| 861 BrowserThread::IO, FROM_HERE, | |
| 862 base::Bind( | |
| 863 &BeginDownload, | |
| 864 URLParams(url, referrer, post_id, prefer_cache), | |
| 865 save_info, | |
| 866 resource_dispatcher_host, | |
| 867 RenderParams(web_contents->GetRenderProcessHost()->GetID(), | |
| 868 web_contents->GetRenderViewHost()->GetRoutingID()), | |
| 869 web_contents->GetBrowserContext()->GetResourceContext(), | |
| 870 callback)); | |
| 871 } | 848 } |
| 872 | 849 |
| 873 void DownloadManagerImpl::AddObserver(Observer* observer) { | 850 void DownloadManagerImpl::AddObserver(Observer* observer) { |
| 874 observers_.AddObserver(observer); | 851 observers_.AddObserver(observer); |
| 875 // TODO: It is the responsibility of the observers to query the | 852 // TODO: It is the responsibility of the observers to query the |
| 876 // DownloadManager. Remove the following call from here and update all | 853 // DownloadManager. Remove the following call from here and update all |
| 877 // observers. | 854 // observers. |
| 878 observer->ModelChanged(this); | 855 observer->ModelChanged(this); |
| 879 } | 856 } |
| 880 | 857 |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1175 if (it->second->IsComplete() && !it->second->GetOpened()) | 1152 if (it->second->IsComplete() && !it->second->GetOpened()) |
| 1176 ++num_unopened; | 1153 ++num_unopened; |
| 1177 } | 1154 } |
| 1178 download_stats::RecordOpensOutstanding(num_unopened); | 1155 download_stats::RecordOpensOutstanding(num_unopened); |
| 1179 } | 1156 } |
| 1180 | 1157 |
| 1181 void DownloadManagerImpl::SetFileManagerForTesting( | 1158 void DownloadManagerImpl::SetFileManagerForTesting( |
| 1182 DownloadFileManager* file_manager) { | 1159 DownloadFileManager* file_manager) { |
| 1183 file_manager_ = file_manager; | 1160 file_manager_ = file_manager; |
| 1184 } | 1161 } |
| OLD | NEW |