OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "content/child/web_url_loader_impl.h" | 7 #include "content/child/web_url_loader_impl.h" |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
59 using blink::WebURLResponse; | 59 using blink::WebURLResponse; |
60 using webkit_glue::MultipartResponseDelegate; | 60 using webkit_glue::MultipartResponseDelegate; |
61 using webkit_glue::ResourceDevToolsInfo; | 61 using webkit_glue::ResourceDevToolsInfo; |
62 using webkit_glue::ResourceLoaderBridge; | 62 using webkit_glue::ResourceLoaderBridge; |
63 using webkit_glue::WebURLResponseExtraDataImpl; | 63 using webkit_glue::WebURLResponseExtraDataImpl; |
64 | 64 |
65 namespace content { | 65 namespace content { |
66 | 66 |
67 // Utilities ------------------------------------------------------------------ | 67 // Utilities ------------------------------------------------------------------ |
68 | 68 |
69 int GetInfoFromDataURL(const GURL& url, | |
70 ResourceResponseInfo* info, | |
71 std::string* data) { | |
72 std::string mime_type; | |
73 std::string charset; | |
74 if (!net::DataURL::Parse(url, &mime_type, &charset, data)) | |
darin (slow to review)
2014/06/02 16:49:25
Keep in mind that for navigations to data: URL, we
tyoshino (SeeGerritForStatus)
2014/06/03 13:04:38
Thanks for the pointer, Darin.
Once IsToken check
| |
75 return net::ERR_INVALID_URL; | |
76 | |
77 DCHECK(!mime_type.empty()); | |
78 DCHECK(!charset.empty()); | |
79 | |
80 // mime_type set by net::DataURL::Parse() is guaranteed to be in | |
81 // token "/" token | |
82 // form. Now just ensure charset is token. The grammar for charset is not | |
83 // specially defined in RFC2045 and RFC2397. It just need to be token or | |
84 // quoted-string since it's an attribute value of media type. But charset in | |
85 // Content-Type header is specified explicitly to follow token ABNF in | |
86 // httpbis spec. | |
87 if (!net::HttpUtil::IsToken(charset)) | |
darin (slow to review)
2014/06/02 16:49:25
perhaps this check should be performed by net::Dat
tyoshino (SeeGerritForStatus)
2014/06/03 13:04:38
It's worth doing for spec compliance. However, it
| |
88 return net::ERR_INVALID_URL; | |
89 | |
90 // Assure same time for all time fields of data: URLs. | |
91 Time now = Time::Now(); | |
92 info->load_timing.request_start = TimeTicks::Now(); | |
93 info->load_timing.request_start_time = now; | |
94 info->request_time = now; | |
95 info->response_time = now; | |
96 | |
97 scoped_refptr<net::HttpResponseHeaders> headers( | |
98 new net::HttpResponseHeaders(std::string())); | |
99 headers->ReplaceStatusLine("HTTP/1.1 200 OK"); | |
100 std::string content_type_header = | |
101 "Content-Type: " + mime_type + ";charset=" + charset; | |
102 headers->AddHeader(content_type_header); | |
103 headers->AddHeader("Access-Control-Allow-Origin: *"); | |
104 info->headers = headers; | |
105 | |
106 info->mime_type.swap(mime_type); | |
107 info->charset.swap(charset); | |
108 info->security_info.clear(); | |
109 info->content_length = data->length(); | |
110 info->encoded_data_length = 0; | |
111 | |
112 return net::OK; | |
113 } | |
114 | |
69 namespace { | 115 namespace { |
70 | 116 |
71 const char kThrottledErrorDescription[] = | 117 const char kThrottledErrorDescription[] = |
72 "Request throttled. Visit http://dev.chromium.org/throttling for more " | 118 "Request throttled. Visit http://dev.chromium.org/throttling for more " |
73 "information."; | 119 "information."; |
74 | 120 |
75 class HeaderFlattener : public WebHTTPHeaderVisitor { | 121 class HeaderFlattener : public WebHTTPHeaderVisitor { |
76 public: | 122 public: |
77 explicit HeaderFlattener(int load_flags) | 123 explicit HeaderFlattener(int load_flags) |
78 : load_flags_(load_flags), | 124 : load_flags_(load_flags), |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
118 } | 164 } |
119 return buffer_; | 165 return buffer_; |
120 } | 166 } |
121 | 167 |
122 private: | 168 private: |
123 int load_flags_; | 169 int load_flags_; |
124 std::string buffer_; | 170 std::string buffer_; |
125 bool has_accept_header_; | 171 bool has_accept_header_; |
126 }; | 172 }; |
127 | 173 |
128 // Extracts the information from a data: url. | |
129 bool GetInfoFromDataURL(const GURL& url, | |
130 ResourceResponseInfo* info, | |
131 std::string* data, | |
132 int* error_code) { | |
133 std::string mime_type; | |
134 std::string charset; | |
135 if (net::DataURL::Parse(url, &mime_type, &charset, data)) { | |
136 *error_code = net::OK; | |
137 // Assure same time for all time fields of data: URLs. | |
138 Time now = Time::Now(); | |
139 info->load_timing.request_start = TimeTicks::Now(); | |
140 info->load_timing.request_start_time = now; | |
141 info->request_time = now; | |
142 info->response_time = now; | |
143 info->headers = NULL; | |
144 info->mime_type.swap(mime_type); | |
145 info->charset.swap(charset); | |
146 info->security_info.clear(); | |
147 info->content_length = data->length(); | |
148 info->encoded_data_length = 0; | |
149 | |
150 return true; | |
151 } | |
152 | |
153 *error_code = net::ERR_INVALID_URL; | |
154 return false; | |
155 } | |
156 | |
157 typedef ResourceDevToolsInfo::HeadersVector HeadersVector; | 174 typedef ResourceDevToolsInfo::HeadersVector HeadersVector; |
158 | 175 |
159 // Converts timing data from |load_timing| to the format used by WebKit. | 176 // Converts timing data from |load_timing| to the format used by WebKit. |
160 void PopulateURLLoadTiming(const net::LoadTimingInfo& load_timing, | 177 void PopulateURLLoadTiming(const net::LoadTimingInfo& load_timing, |
161 WebURLLoadTiming* url_timing) { | 178 WebURLLoadTiming* url_timing) { |
162 DCHECK(!load_timing.request_start.is_null()); | 179 DCHECK(!load_timing.request_start.is_null()); |
163 | 180 |
164 const TimeTicks kNullTicks; | 181 const TimeTicks kNullTicks; |
165 url_timing->initialize(); | 182 url_timing->initialize(); |
166 url_timing->setRequestTime( | 183 url_timing->setRequestTime( |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
315 DCHECK(!bridge_.get()); | 332 DCHECK(!bridge_.get()); |
316 | 333 |
317 request_ = request; // Save the request. | 334 request_ = request; // Save the request. |
318 | 335 |
319 GURL url = request.url(); | 336 GURL url = request.url(); |
320 if (url.SchemeIs("data") && CanHandleDataURL(url)) { | 337 if (url.SchemeIs("data") && CanHandleDataURL(url)) { |
321 if (sync_load_response) { | 338 if (sync_load_response) { |
322 // This is a sync load. Do the work now. | 339 // This is a sync load. Do the work now. |
323 sync_load_response->url = url; | 340 sync_load_response->url = url; |
324 std::string data; | 341 std::string data; |
325 GetInfoFromDataURL(sync_load_response->url, sync_load_response, | 342 sync_load_response->error_code = |
326 &sync_load_response->data, | 343 GetInfoFromDataURL(sync_load_response->url, sync_load_response, |
327 &sync_load_response->error_code); | 344 &sync_load_response->data); |
328 } else { | 345 } else { |
329 AddRef(); // Balanced in OnCompletedRequest | 346 AddRef(); // Balanced in OnCompletedRequest |
330 base::MessageLoop::current()->PostTask( | 347 base::MessageLoop::current()->PostTask( |
331 FROM_HERE, base::Bind(&Context::HandleDataURL, this)); | 348 FROM_HERE, base::Bind(&Context::HandleDataURL, this)); |
332 } | 349 } |
333 return; | 350 return; |
334 } | 351 } |
335 | 352 |
336 GURL referrer_url( | 353 GURL referrer_url( |
337 request.httpHeaderField(WebString::fromUTF8("Referer")).latin1()); | 354 request.httpHeaderField(WebString::fromUTF8("Referer")).latin1()); |
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
673 std::string mime_type, unused_charset; | 690 std::string mime_type, unused_charset; |
674 if (net::DataURL::Parse(url, &mime_type, &unused_charset, NULL) && | 691 if (net::DataURL::Parse(url, &mime_type, &unused_charset, NULL) && |
675 net::IsSupportedMimeType(mime_type)) | 692 net::IsSupportedMimeType(mime_type)) |
676 return true; | 693 return true; |
677 | 694 |
678 return false; | 695 return false; |
679 } | 696 } |
680 | 697 |
681 void WebURLLoaderImpl::Context::HandleDataURL() { | 698 void WebURLLoaderImpl::Context::HandleDataURL() { |
682 ResourceResponseInfo info; | 699 ResourceResponseInfo info; |
683 int error_code; | |
684 std::string data; | 700 std::string data; |
685 | 701 |
686 if (GetInfoFromDataURL(request_.url(), &info, &data, &error_code)) { | 702 int error_code = GetInfoFromDataURL(request_.url(), &info, &data); |
703 if (error_code == net::OK) { | |
687 OnReceivedResponse(info); | 704 OnReceivedResponse(info); |
688 if (!data.empty()) | 705 if (!data.empty()) |
689 OnReceivedData(data.data(), data.size(), 0); | 706 OnReceivedData(data.data(), data.size(), 0); |
690 } | 707 } |
691 | 708 |
692 OnCompletedRequest(error_code, false, false, info.security_info, | 709 OnCompletedRequest(error_code, false, false, info.security_info, |
693 base::TimeTicks::Now(), 0); | 710 base::TimeTicks::Now(), 0); |
694 } | 711 } |
695 | 712 |
696 // WebURLLoaderImpl ----------------------------------------------------------- | 713 // WebURLLoaderImpl ----------------------------------------------------------- |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
872 void WebURLLoaderImpl::setDefersLoading(bool value) { | 889 void WebURLLoaderImpl::setDefersLoading(bool value) { |
873 context_->SetDefersLoading(value); | 890 context_->SetDefersLoading(value); |
874 } | 891 } |
875 | 892 |
876 void WebURLLoaderImpl::didChangePriority(WebURLRequest::Priority new_priority, | 893 void WebURLLoaderImpl::didChangePriority(WebURLRequest::Priority new_priority, |
877 int intra_priority_value) { | 894 int intra_priority_value) { |
878 context_->DidChangePriority(new_priority, intra_priority_value); | 895 context_->DidChangePriority(new_priority, intra_priority_value); |
879 } | 896 } |
880 | 897 |
881 } // namespace content | 898 } // namespace content |
OLD | NEW |