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/webui/url_data_manager_backend.h" | 5 #include "content/browser/webui/url_data_manager_backend.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 void URLToRequestPath(const GURL& url, std::string* path) { | 83 void URLToRequestPath(const GURL& url, std::string* path) { |
84 const std::string& spec = url.possibly_invalid_spec(); | 84 const std::string& spec = url.possibly_invalid_spec(); |
85 const url::Parsed& parsed = url.parsed_for_possibly_invalid_spec(); | 85 const url::Parsed& parsed = url.parsed_for_possibly_invalid_spec(); |
86 // + 1 to skip the slash at the beginning of the path. | 86 // + 1 to skip the slash at the beginning of the path. |
87 int offset = parsed.CountCharactersBefore(url::Parsed::PATH, false) + 1; | 87 int offset = parsed.CountCharactersBefore(url::Parsed::PATH, false) + 1; |
88 | 88 |
89 if (offset < static_cast<int>(spec.size())) | 89 if (offset < static_cast<int>(spec.size())) |
90 path->assign(spec.substr(offset)); | 90 path->assign(spec.substr(offset)); |
91 } | 91 } |
92 | 92 |
| 93 // Returns a value of 'Origin:' header for the |request| if the header is set. |
| 94 // Otherwise returns an empty string. |
| 95 std::string GetOriginHeaderValue(const net::URLRequest* request) { |
| 96 std::string result; |
| 97 if (request->extra_request_headers().GetHeader( |
| 98 net::HttpRequestHeaders::kOrigin, &result)) |
| 99 return result; |
| 100 net::HttpRequestHeaders headers; |
| 101 if (request->GetFullRequestHeaders(&headers)) |
| 102 headers.GetHeader(net::HttpRequestHeaders::kOrigin, &result); |
| 103 return result; |
| 104 } |
| 105 |
93 } // namespace | 106 } // namespace |
94 | 107 |
95 // URLRequestChromeJob is a net::URLRequestJob that manages running | 108 // URLRequestChromeJob is a net::URLRequestJob that manages running |
96 // chrome-internal resource requests asynchronously. | 109 // chrome-internal resource requests asynchronously. |
97 // It hands off URL requests to ChromeURLDataManager, which asynchronously | 110 // It hands off URL requests to ChromeURLDataManager, which asynchronously |
98 // calls back once the data is available. | 111 // calls back once the data is available. |
99 class URLRequestChromeJob : public net::URLRequestJob, | 112 class URLRequestChromeJob : public net::URLRequestJob, |
100 public base::SupportsWeakPtr<URLRequestChromeJob> { | 113 public base::SupportsWeakPtr<URLRequestChromeJob> { |
101 public: | 114 public: |
102 // |is_incognito| set when job is generated from an incognito profile. | 115 // |is_incognito| set when job is generated from an incognito profile. |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 } | 158 } |
146 | 159 |
147 void set_deny_xframe_options(bool deny_xframe_options) { | 160 void set_deny_xframe_options(bool deny_xframe_options) { |
148 deny_xframe_options_ = deny_xframe_options; | 161 deny_xframe_options_ = deny_xframe_options; |
149 } | 162 } |
150 | 163 |
151 void set_send_content_type_header(bool send_content_type_header) { | 164 void set_send_content_type_header(bool send_content_type_header) { |
152 send_content_type_header_ = send_content_type_header; | 165 send_content_type_header_ = send_content_type_header; |
153 } | 166 } |
154 | 167 |
| 168 void set_access_control_allow_origin(const std::string& value) { |
| 169 access_control_allow_origin_ = value; |
| 170 } |
| 171 |
155 // Returns true when job was generated from an incognito profile. | 172 // Returns true when job was generated from an incognito profile. |
156 bool is_incognito() const { | 173 bool is_incognito() const { |
157 return is_incognito_; | 174 return is_incognito_; |
158 } | 175 } |
159 | 176 |
160 private: | 177 private: |
161 virtual ~URLRequestChromeJob(); | 178 virtual ~URLRequestChromeJob(); |
162 | 179 |
163 // Helper for Start(), to let us start asynchronously. | 180 // Helper for Start(), to let us start asynchronously. |
164 // (This pattern is shared by most net::URLRequestJob implementations.) | 181 // (This pattern is shared by most net::URLRequestJob implementations.) |
(...skipping 30 matching lines...) Expand all Loading... |
195 // These are used with the CSP. | 212 // These are used with the CSP. |
196 std::string content_security_policy_object_source_; | 213 std::string content_security_policy_object_source_; |
197 std::string content_security_policy_frame_source_; | 214 std::string content_security_policy_frame_source_; |
198 | 215 |
199 // If true, sets the "X-Frame-Options: DENY" header. | 216 // If true, sets the "X-Frame-Options: DENY" header. |
200 bool deny_xframe_options_; | 217 bool deny_xframe_options_; |
201 | 218 |
202 // If true, sets the "Content-Type: <mime-type>" header. | 219 // If true, sets the "Content-Type: <mime-type>" header. |
203 bool send_content_type_header_; | 220 bool send_content_type_header_; |
204 | 221 |
| 222 // If not empty, "Access-Control-Allow-Origin:" is set to the value of this |
| 223 // string. |
| 224 std::string access_control_allow_origin_; |
| 225 |
205 // True when job is generated from an incognito profile. | 226 // True when job is generated from an incognito profile. |
206 const bool is_incognito_; | 227 const bool is_incognito_; |
207 | 228 |
208 // The backend is owned by net::URLRequestContext and always outlives us. | 229 // The backend is owned by net::URLRequestContext and always outlives us. |
209 URLDataManagerBackend* backend_; | 230 URLDataManagerBackend* backend_; |
210 | 231 |
211 base::WeakPtrFactory<URLRequestChromeJob> weak_factory_; | 232 base::WeakPtrFactory<URLRequestChromeJob> weak_factory_; |
212 | 233 |
213 DISALLOW_COPY_AND_ASSIGN(URLRequestChromeJob); | 234 DISALLOW_COPY_AND_ASSIGN(URLRequestChromeJob); |
214 }; | 235 }; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 | 307 |
287 if (!allow_caching_) | 308 if (!allow_caching_) |
288 info->headers->AddHeader("Cache-Control: no-cache"); | 309 info->headers->AddHeader("Cache-Control: no-cache"); |
289 | 310 |
290 if (send_content_type_header_ && !mime_type_.empty()) { | 311 if (send_content_type_header_ && !mime_type_.empty()) { |
291 std::string content_type = | 312 std::string content_type = |
292 base::StringPrintf("%s:%s", net::HttpRequestHeaders::kContentType, | 313 base::StringPrintf("%s:%s", net::HttpRequestHeaders::kContentType, |
293 mime_type_.c_str()); | 314 mime_type_.c_str()); |
294 info->headers->AddHeader(content_type); | 315 info->headers->AddHeader(content_type); |
295 } | 316 } |
| 317 |
| 318 if (!access_control_allow_origin_.empty()) { |
| 319 info->headers->AddHeader("Access-Control-Allow-Origin: " + |
| 320 access_control_allow_origin_); |
| 321 info->headers->AddHeader("Vary: Origin"); |
| 322 } |
296 } | 323 } |
297 | 324 |
298 void URLRequestChromeJob::MimeTypeAvailable(const std::string& mime_type) { | 325 void URLRequestChromeJob::MimeTypeAvailable(const std::string& mime_type) { |
299 set_mime_type(mime_type); | 326 set_mime_type(mime_type); |
300 NotifyHeadersComplete(); | 327 NotifyHeadersComplete(); |
301 } | 328 } |
302 | 329 |
303 void URLRequestChromeJob::DataAvailable(base::RefCountedMemory* bytes) { | 330 void URLRequestChromeJob::DataAvailable(base::RefCountedMemory* bytes) { |
304 TRACE_EVENT_ASYNC_END0("browser", "DataManager:Request", this); | 331 TRACE_EVENT_ASYNC_END0("browser", "DataManager:Request", this); |
305 if (bytes) { | 332 if (bytes) { |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
571 source->source()->ShouldAddContentSecurityPolicy()); | 598 source->source()->ShouldAddContentSecurityPolicy()); |
572 job->set_content_security_policy_object_source( | 599 job->set_content_security_policy_object_source( |
573 source->source()->GetContentSecurityPolicyObjectSrc()); | 600 source->source()->GetContentSecurityPolicyObjectSrc()); |
574 job->set_content_security_policy_frame_source( | 601 job->set_content_security_policy_frame_source( |
575 source->source()->GetContentSecurityPolicyFrameSrc()); | 602 source->source()->GetContentSecurityPolicyFrameSrc()); |
576 job->set_deny_xframe_options( | 603 job->set_deny_xframe_options( |
577 source->source()->ShouldDenyXFrameOptions()); | 604 source->source()->ShouldDenyXFrameOptions()); |
578 job->set_send_content_type_header( | 605 job->set_send_content_type_header( |
579 source->source()->ShouldServeMimeTypeAsContentTypeHeader()); | 606 source->source()->ShouldServeMimeTypeAsContentTypeHeader()); |
580 | 607 |
| 608 std::string origin = GetOriginHeaderValue(request); |
| 609 if (!origin.empty()) { |
| 610 std::string header = |
| 611 source->source()->GetAccessControlAllowOriginForOrigin(origin); |
| 612 DCHECK(header.empty() || header == origin || header == "*" || |
| 613 header == "null"); |
| 614 job->set_access_control_allow_origin(header); |
| 615 } |
| 616 |
581 // Look up additional request info to pass down. | 617 // Look up additional request info to pass down. |
582 int render_process_id = -1; | 618 int render_process_id = -1; |
583 int render_frame_id = -1; | 619 int render_frame_id = -1; |
584 ResourceRequestInfo::GetRenderFrameForRequest(request, | 620 ResourceRequestInfo::GetRenderFrameForRequest(request, |
585 &render_process_id, | 621 &render_process_id, |
586 &render_frame_id); | 622 &render_frame_id); |
587 | 623 |
588 // Forward along the request to the data source. | 624 // Forward along the request to the data source. |
589 base::MessageLoop* target_message_loop = | 625 base::MessageLoop* target_message_loop = |
590 source->source()->MessageLoopForRequestPath(path); | 626 source->source()->MessageLoopForRequestPath(path); |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
730 | 766 |
731 } // namespace | 767 } // namespace |
732 | 768 |
733 net::URLRequestJobFactory::ProtocolHandler* | 769 net::URLRequestJobFactory::ProtocolHandler* |
734 CreateDevToolsProtocolHandler(content::ResourceContext* resource_context, | 770 CreateDevToolsProtocolHandler(content::ResourceContext* resource_context, |
735 bool is_incognito) { | 771 bool is_incognito) { |
736 return new DevToolsJobFactory(resource_context, is_incognito); | 772 return new DevToolsJobFactory(resource_context, is_incognito); |
737 } | 773 } |
738 | 774 |
739 } // namespace content | 775 } // namespace content |
OLD | NEW |