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 // An implementation of WebURLLoader in terms of ResourceLoaderBridge. | 5 // An implementation of WebURLLoader in terms of ResourceLoaderBridge. |
6 | 6 |
7 #include "webkit/glue/weburlloader_impl.h" | 7 #include "webkit/glue/weburlloader_impl.h" |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/file_path.h" | 10 #include "base/file_path.h" |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 private: | 116 private: |
117 int load_flags_; | 117 int load_flags_; |
118 std::string buffer_; | 118 std::string buffer_; |
119 bool has_accept_header_; | 119 bool has_accept_header_; |
120 }; | 120 }; |
121 | 121 |
122 // Extracts the information from a data: url. | 122 // Extracts the information from a data: url. |
123 bool GetInfoFromDataURL(const GURL& url, | 123 bool GetInfoFromDataURL(const GURL& url, |
124 ResourceResponseInfo* info, | 124 ResourceResponseInfo* info, |
125 std::string* data, | 125 std::string* data, |
126 net::URLRequestStatus* status) { | 126 int* error_code) { |
127 std::string mime_type; | 127 std::string mime_type; |
128 std::string charset; | 128 std::string charset; |
129 if (net::DataURL::Parse(url, &mime_type, &charset, data)) { | 129 if (net::DataURL::Parse(url, &mime_type, &charset, data)) { |
130 *status = net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0); | 130 *error_code = net::OK; |
131 // Assure same time for all time fields of data: URLs. | 131 // Assure same time for all time fields of data: URLs. |
132 Time now = Time::Now(); | 132 Time now = Time::Now(); |
133 info->load_timing.base_time = now; | 133 info->load_timing.base_time = now; |
134 info->load_timing.base_ticks = TimeTicks::Now(); | 134 info->load_timing.base_ticks = TimeTicks::Now(); |
135 info->request_time = now; | 135 info->request_time = now; |
136 info->response_time = now; | 136 info->response_time = now; |
137 info->headers = NULL; | 137 info->headers = NULL; |
138 info->mime_type.swap(mime_type); | 138 info->mime_type.swap(mime_type); |
139 info->charset.swap(charset); | 139 info->charset.swap(charset); |
140 info->security_info.clear(); | 140 info->security_info.clear(); |
141 info->content_length = data->length(); | 141 info->content_length = data->length(); |
142 info->encoded_data_length = 0; | 142 info->encoded_data_length = 0; |
143 | 143 |
144 return true; | 144 return true; |
145 } | 145 } |
146 | 146 |
147 *status = net::URLRequestStatus(net::URLRequestStatus::FAILED, | 147 *error_code = net::ERR_INVALID_URL; |
148 net::ERR_INVALID_URL); | |
149 return false; | 148 return false; |
150 } | 149 } |
151 | 150 |
152 typedef ResourceDevToolsInfo::HeadersVector HeadersVector; | 151 typedef ResourceDevToolsInfo::HeadersVector HeadersVector; |
153 | 152 |
154 void PopulateURLResponse( | 153 void PopulateURLResponse( |
155 const GURL& url, | 154 const GURL& url, |
156 const ResourceResponseInfo& info, | 155 const ResourceResponseInfo& info, |
157 WebURLResponse* response) { | 156 WebURLResponse* response) { |
158 response->setURL(url); | 157 response->setURL(url); |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 const GURL& new_url, | 291 const GURL& new_url, |
293 const ResourceResponseInfo& info, | 292 const ResourceResponseInfo& info, |
294 bool* has_new_first_party_for_cookies, | 293 bool* has_new_first_party_for_cookies, |
295 GURL* new_first_party_for_cookies); | 294 GURL* new_first_party_for_cookies); |
296 virtual void OnReceivedResponse(const ResourceResponseInfo& info); | 295 virtual void OnReceivedResponse(const ResourceResponseInfo& info); |
297 virtual void OnDownloadedData(int len); | 296 virtual void OnDownloadedData(int len); |
298 virtual void OnReceivedData(const char* data, | 297 virtual void OnReceivedData(const char* data, |
299 int data_length, | 298 int data_length, |
300 int encoded_data_length); | 299 int encoded_data_length); |
301 virtual void OnReceivedCachedMetadata(const char* data, int len); | 300 virtual void OnReceivedCachedMetadata(const char* data, int len); |
302 virtual void OnCompletedRequest(const net::URLRequestStatus& status, | 301 virtual void OnCompletedRequest(int error_code, |
| 302 bool was_ignored_by_handler, |
303 const std::string& security_info, | 303 const std::string& security_info, |
304 const base::TimeTicks& completion_time); | 304 const base::TimeTicks& completion_time); |
305 | 305 |
306 private: | 306 private: |
307 friend class base::RefCounted<Context>; | 307 friend class base::RefCounted<Context>; |
308 ~Context() {} | 308 ~Context() {} |
309 | 309 |
310 // We can optimize the handling of data URLs in most cases. | 310 // We can optimize the handling of data URLs in most cases. |
311 bool CanHandleDataURL(const GURL& url) const; | 311 bool CanHandleDataURL(const GURL& url) const; |
312 void HandleDataURL(); | 312 void HandleDataURL(); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 request_ = request; // Save the request. | 357 request_ = request; // Save the request. |
358 | 358 |
359 GURL url = request.url(); | 359 GURL url = request.url(); |
360 if (url.SchemeIs("data") && CanHandleDataURL(url)) { | 360 if (url.SchemeIs("data") && CanHandleDataURL(url)) { |
361 if (sync_load_response) { | 361 if (sync_load_response) { |
362 // This is a sync load. Do the work now. | 362 // This is a sync load. Do the work now. |
363 sync_load_response->url = url; | 363 sync_load_response->url = url; |
364 std::string data; | 364 std::string data; |
365 GetInfoFromDataURL(sync_load_response->url, sync_load_response, | 365 GetInfoFromDataURL(sync_load_response->url, sync_load_response, |
366 &sync_load_response->data, | 366 &sync_load_response->data, |
367 &sync_load_response->status); | 367 &sync_load_response->error_code); |
368 } else { | 368 } else { |
369 AddRef(); // Balanced in OnCompletedRequest | 369 AddRef(); // Balanced in OnCompletedRequest |
370 MessageLoop::current()->PostTask(FROM_HERE, | 370 MessageLoop::current()->PostTask(FROM_HERE, |
371 base::Bind(&Context::HandleDataURL, this)); | 371 base::Bind(&Context::HandleDataURL, this)); |
372 } | 372 } |
373 return; | 373 return; |
374 } | 374 } |
375 | 375 |
376 GURL referrer_url( | 376 GURL referrer_url( |
377 request.httpHeaderField(WebString::fromUTF8("Referer")).utf8()); | 377 request.httpHeaderField(WebString::fromUTF8("Referer")).utf8()); |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
630 } | 630 } |
631 } | 631 } |
632 | 632 |
633 void WebURLLoaderImpl::Context::OnReceivedCachedMetadata( | 633 void WebURLLoaderImpl::Context::OnReceivedCachedMetadata( |
634 const char* data, int len) { | 634 const char* data, int len) { |
635 if (client_) | 635 if (client_) |
636 client_->didReceiveCachedMetadata(loader_, data, len); | 636 client_->didReceiveCachedMetadata(loader_, data, len); |
637 } | 637 } |
638 | 638 |
639 void WebURLLoaderImpl::Context::OnCompletedRequest( | 639 void WebURLLoaderImpl::Context::OnCompletedRequest( |
640 const net::URLRequestStatus& status, | 640 int error_code, |
| 641 bool was_ignored_by_handler, |
641 const std::string& security_info, | 642 const std::string& security_info, |
642 const base::TimeTicks& completion_time) { | 643 const base::TimeTicks& completion_time) { |
643 if (ftp_listing_delegate_.get()) { | 644 if (ftp_listing_delegate_.get()) { |
644 ftp_listing_delegate_->OnCompletedRequest(); | 645 ftp_listing_delegate_->OnCompletedRequest(); |
645 ftp_listing_delegate_.reset(NULL); | 646 ftp_listing_delegate_.reset(NULL); |
646 } else if (multipart_delegate_.get()) { | 647 } else if (multipart_delegate_.get()) { |
647 multipart_delegate_->OnCompletedRequest(); | 648 multipart_delegate_->OnCompletedRequest(); |
648 multipart_delegate_.reset(NULL); | 649 multipart_delegate_.reset(NULL); |
649 } | 650 } |
650 | 651 |
651 // Prevent any further IPC to the browser now that we're complete, but | 652 // Prevent any further IPC to the browser now that we're complete, but |
652 // don't delete it to keep any downloaded temp files alive. | 653 // don't delete it to keep any downloaded temp files alive. |
653 DCHECK(!completed_bridge_.get()); | 654 DCHECK(!completed_bridge_.get()); |
654 completed_bridge_.swap(bridge_); | 655 completed_bridge_.swap(bridge_); |
655 | 656 |
656 if (client_) { | 657 if (client_) { |
657 if (status.status() != net::URLRequestStatus::SUCCESS) { | 658 if (error_code != net::OK) { |
658 int error_code; | |
659 if (status.status() == net::URLRequestStatus::HANDLED_EXTERNALLY) { | |
660 // By marking this request as aborted we insure that we don't navigate | |
661 // to an error page. | |
662 error_code = net::ERR_ABORTED; | |
663 } else { | |
664 error_code = status.error(); | |
665 } | |
666 WebURLError error; | 659 WebURLError error; |
667 if (error_code == net::ERR_ABORTED) { | 660 if (error_code == net::ERR_ABORTED) { |
668 error.isCancellation = true; | 661 error.isCancellation = true; |
669 } else if (error_code == net::ERR_TEMPORARILY_THROTTLED) { | 662 } else if (error_code == net::ERR_TEMPORARILY_THROTTLED) { |
670 error.localizedDescription = WebString::fromUTF8( | 663 error.localizedDescription = WebString::fromUTF8( |
671 kThrottledErrorDescription); | 664 kThrottledErrorDescription); |
672 } | 665 } |
673 error.domain = WebString::fromUTF8(net::kErrorDomain); | 666 error.domain = WebString::fromUTF8(net::kErrorDomain); |
674 error.reason = error_code; | 667 error.reason = error_code; |
675 error.unreachableURL = request_.url(); | 668 error.unreachableURL = request_.url(); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
711 std::string mime_type, unused_charset; | 704 std::string mime_type, unused_charset; |
712 if (net::DataURL::Parse(url, &mime_type, &unused_charset, NULL) && | 705 if (net::DataURL::Parse(url, &mime_type, &unused_charset, NULL) && |
713 net::IsSupportedMimeType(mime_type)) | 706 net::IsSupportedMimeType(mime_type)) |
714 return true; | 707 return true; |
715 | 708 |
716 return false; | 709 return false; |
717 } | 710 } |
718 | 711 |
719 void WebURLLoaderImpl::Context::HandleDataURL() { | 712 void WebURLLoaderImpl::Context::HandleDataURL() { |
720 ResourceResponseInfo info; | 713 ResourceResponseInfo info; |
721 net::URLRequestStatus status; | 714 int error_code; |
722 std::string data; | 715 std::string data; |
723 | 716 |
724 if (GetInfoFromDataURL(request_.url(), &info, &data, &status)) { | 717 if (GetInfoFromDataURL(request_.url(), &info, &data, &error_code)) { |
725 OnReceivedResponse(info); | 718 OnReceivedResponse(info); |
726 if (!data.empty()) | 719 if (!data.empty()) |
727 OnReceivedData(data.data(), data.size(), 0); | 720 OnReceivedData(data.data(), data.size(), 0); |
728 } | 721 } |
729 | 722 |
730 OnCompletedRequest(status, info.security_info, base::TimeTicks::Now()); | 723 OnCompletedRequest(error_code, false, info.security_info, |
| 724 base::TimeTicks::Now()); |
731 } | 725 } |
732 | 726 |
733 // WebURLLoaderImpl ----------------------------------------------------------- | 727 // WebURLLoaderImpl ----------------------------------------------------------- |
734 | 728 |
735 WebURLLoaderImpl::WebURLLoaderImpl(WebKitPlatformSupportImpl* platform) | 729 WebURLLoaderImpl::WebURLLoaderImpl(WebKitPlatformSupportImpl* platform) |
736 : ALLOW_THIS_IN_INITIALIZER_LIST(context_(new Context(this))), | 730 : ALLOW_THIS_IN_INITIALIZER_LIST(context_(new Context(this))), |
737 platform_(platform) { | 731 platform_(platform) { |
738 } | 732 } |
739 | 733 |
740 WebURLLoaderImpl::~WebURLLoaderImpl() { | 734 WebURLLoaderImpl::~WebURLLoaderImpl() { |
741 cancel(); | 735 cancel(); |
742 } | 736 } |
743 | 737 |
744 void WebURLLoaderImpl::loadSynchronously(const WebURLRequest& request, | 738 void WebURLLoaderImpl::loadSynchronously(const WebURLRequest& request, |
745 WebURLResponse& response, | 739 WebURLResponse& response, |
746 WebURLError& error, | 740 WebURLError& error, |
747 WebData& data) { | 741 WebData& data) { |
748 ResourceLoaderBridge::SyncLoadResponse sync_load_response; | 742 ResourceLoaderBridge::SyncLoadResponse sync_load_response; |
749 context_->Start(request, &sync_load_response, platform_); | 743 context_->Start(request, &sync_load_response, platform_); |
750 | 744 |
751 const GURL& final_url = sync_load_response.url; | 745 const GURL& final_url = sync_load_response.url; |
752 | 746 |
753 // TODO(tc): For file loads, we may want to include a more descriptive | 747 // TODO(tc): For file loads, we may want to include a more descriptive |
754 // status code or status text. | 748 // status code or status text. |
755 const net::URLRequestStatus::Status& status = | 749 int error_code = sync_load_response.error_code; |
756 sync_load_response.status.status(); | 750 if (error_code != net::OK) { |
757 if (status != net::URLRequestStatus::SUCCESS && | |
758 status != net::URLRequestStatus::HANDLED_EXTERNALLY) { | |
759 response.setURL(final_url); | 751 response.setURL(final_url); |
760 error.domain = WebString::fromUTF8(net::kErrorDomain); | 752 error.domain = WebString::fromUTF8(net::kErrorDomain); |
761 error.reason = sync_load_response.status.error(); | 753 error.reason = error_code; |
762 error.unreachableURL = final_url; | 754 error.unreachableURL = final_url; |
763 return; | 755 return; |
764 } | 756 } |
765 | 757 |
766 PopulateURLResponse(final_url, sync_load_response, &response); | 758 PopulateURLResponse(final_url, sync_load_response, &response); |
767 | 759 |
768 data.assign(sync_load_response.data.data(), | 760 data.assign(sync_load_response.data.data(), |
769 sync_load_response.data.size()); | 761 sync_load_response.data.size()); |
770 } | 762 } |
771 | 763 |
772 void WebURLLoaderImpl::loadAsynchronously(const WebURLRequest& request, | 764 void WebURLLoaderImpl::loadAsynchronously(const WebURLRequest& request, |
773 WebURLLoaderClient* client) { | 765 WebURLLoaderClient* client) { |
774 DCHECK(!context_->client()); | 766 DCHECK(!context_->client()); |
775 | 767 |
776 context_->set_client(client); | 768 context_->set_client(client); |
777 context_->Start(request, NULL, platform_); | 769 context_->Start(request, NULL, platform_); |
778 } | 770 } |
779 | 771 |
780 void WebURLLoaderImpl::cancel() { | 772 void WebURLLoaderImpl::cancel() { |
781 context_->Cancel(); | 773 context_->Cancel(); |
782 } | 774 } |
783 | 775 |
784 void WebURLLoaderImpl::setDefersLoading(bool value) { | 776 void WebURLLoaderImpl::setDefersLoading(bool value) { |
785 context_->SetDefersLoading(value); | 777 context_->SetDefersLoading(value); |
786 } | 778 } |
787 | 779 |
788 } // namespace webkit_glue | 780 } // namespace webkit_glue |
OLD | NEW |