1 /*
2 * Copyright (C) 2009 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "third_party/blink/public/platform/web_url_response.h"
32
33 #include <algorithm>
34 #include <memory>
35 #include <utility>
36
37 #include "base/memory/ptr_util.h"
38 #include "base/memory/scoped_refptr.h"
39 #include "services/network/public/mojom/load_timing_info.mojom.h"
40 #include "third_party/blink/public/platform/web_http_header_visitor.h"
41 #include "third_party/blink/public/platform/web_http_load_info.h"
42 #include "third_party/blink/public/platform/web_string.h"
43 #include "third_party/blink/public/platform/web_url.h"
44 #include "third_party/blink/renderer/platform/loader/fetch/resource_load_info.h"
45 #include "third_party/blink/renderer/platform/loader/fetch/resource_load_timing.h"
46 #include "third_party/blink/renderer/platform/loader/fetch/resource_response.h"
47 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
48 #include "third_party/blink/renderer/platform/wtf/assertions.h"
49
50 namespace blink {
51
52 WebURLResponse::~WebURLResponse() = default;
53
WebURLResponse()54 WebURLResponse::WebURLResponse()
55 : owned_resource_response_(std::make_unique<ResourceResponse>()),
56 resource_response_(owned_resource_response_.get()) {}
57
WebURLResponse(const WebURLResponse & r)58 WebURLResponse::WebURLResponse(const WebURLResponse& r)
59 : owned_resource_response_(
60 std::make_unique<ResourceResponse>(*r.resource_response_)),
61 resource_response_(owned_resource_response_.get()) {}
62
WebURLResponse(const WebURL & current_request_url)63 WebURLResponse::WebURLResponse(const WebURL& current_request_url)
64 : WebURLResponse() {
65 SetCurrentRequestUrl(current_request_url);
66 }
67
operator =(const WebURLResponse & r)68 WebURLResponse& WebURLResponse::operator=(const WebURLResponse& r) {
69 // Copying subclasses that have different m_resourceResponse ownership
70 // semantics via this operator is just not supported.
71 DCHECK(owned_resource_response_);
72 DCHECK(resource_response_);
73 if (&r != this)
74 *resource_response_ = *r.resource_response_;
75 return *this;
76 }
77
IsNull() const78 bool WebURLResponse::IsNull() const {
79 return resource_response_->IsNull();
80 }
81
CurrentRequestUrl() const82 WebURL WebURLResponse::CurrentRequestUrl() const {
83 return resource_response_->CurrentRequestUrl();
84 }
85
SetCurrentRequestUrl(const WebURL & url)86 void WebURLResponse::SetCurrentRequestUrl(const WebURL& url) {
87 resource_response_->SetCurrentRequestUrl(url);
88 }
89
ResponseUrl() const90 WebURL WebURLResponse::ResponseUrl() const {
91 return resource_response_->ResponseUrl();
92 }
93
SetConnectionID(unsigned connection_id)94 void WebURLResponse::SetConnectionID(unsigned connection_id) {
95 resource_response_->SetConnectionID(connection_id);
96 }
97
SetConnectionReused(bool connection_reused)98 void WebURLResponse::SetConnectionReused(bool connection_reused) {
99 resource_response_->SetConnectionReused(connection_reused);
100 }
101
SetLoadTiming(const network::mojom::LoadTimingInfo & mojo_timing)102 void WebURLResponse::SetLoadTiming(
103 const network::mojom::LoadTimingInfo& mojo_timing) {
104 auto timing = ResourceLoadTiming::Create();
105 timing->SetRequestTime(mojo_timing.request_start);
106 timing->SetProxyStart(mojo_timing.proxy_resolve_start);
107 timing->SetProxyEnd(mojo_timing.proxy_resolve_end);
108 timing->SetDnsStart(mojo_timing.connect_timing.dns_start);
109 timing->SetDnsEnd(mojo_timing.connect_timing.dns_end);
110 timing->SetConnectStart(mojo_timing.connect_timing.connect_start);
111 timing->SetConnectEnd(mojo_timing.connect_timing.connect_end);
112 timing->SetWorkerStart(mojo_timing.service_worker_start_time);
113 timing->SetWorkerReady(mojo_timing.service_worker_ready_time);
114 timing->SetSendStart(mojo_timing.send_start);
115 timing->SetSendEnd(mojo_timing.send_end);
116 timing->SetReceiveHeadersStart(mojo_timing.receive_headers_start);
117 timing->SetReceiveHeadersEnd(mojo_timing.receive_headers_end);
118 timing->SetSslStart(mojo_timing.connect_timing.ssl_start);
119 timing->SetSslEnd(mojo_timing.connect_timing.ssl_end);
120 timing->SetPushStart(mojo_timing.push_start);
121 timing->SetPushEnd(mojo_timing.push_end);
122 resource_response_->SetResourceLoadTiming(std::move(timing));
123 }
124
SetHTTPLoadInfo(const WebHTTPLoadInfo & value)125 void WebURLResponse::SetHTTPLoadInfo(const WebHTTPLoadInfo& value) {
126 resource_response_->SetResourceLoadInfo(value);
127 }
128
SetResponseTime(base::Time response_time)129 void WebURLResponse::SetResponseTime(base::Time response_time) {
130 resource_response_->SetResponseTime(response_time);
131 }
132
MimeType() const133 WebString WebURLResponse::MimeType() const {
134 return resource_response_->MimeType();
135 }
136
SetMimeType(const WebString & mime_type)137 void WebURLResponse::SetMimeType(const WebString& mime_type) {
138 resource_response_->SetMimeType(mime_type);
139 }
140
ExpectedContentLength() const141 int64_t WebURLResponse::ExpectedContentLength() const {
142 return resource_response_->ExpectedContentLength();
143 }
144
SetExpectedContentLength(int64_t expected_content_length)145 void WebURLResponse::SetExpectedContentLength(int64_t expected_content_length) {
146 resource_response_->SetExpectedContentLength(expected_content_length);
147 }
148
SetTextEncodingName(const WebString & text_encoding_name)149 void WebURLResponse::SetTextEncodingName(const WebString& text_encoding_name) {
150 resource_response_->SetTextEncodingName(text_encoding_name);
151 }
152
HttpVersion() const153 WebURLResponse::HTTPVersion WebURLResponse::HttpVersion() const {
154 return static_cast<HTTPVersion>(resource_response_->HttpVersion());
155 }
156
SetHttpVersion(HTTPVersion version)157 void WebURLResponse::SetHttpVersion(HTTPVersion version) {
158 resource_response_->SetHttpVersion(
159 static_cast<ResourceResponse::HTTPVersion>(version));
160 }
161
RequestId() const162 int WebURLResponse::RequestId() const {
163 return resource_response_->RequestId();
164 }
165
SetRequestId(int request_id)166 void WebURLResponse::SetRequestId(int request_id) {
167 resource_response_->SetRequestId(request_id);
168 }
169
HttpStatusCode() const170 int WebURLResponse::HttpStatusCode() const {
171 return resource_response_->HttpStatusCode();
172 }
173
SetHttpStatusCode(int http_status_code)174 void WebURLResponse::SetHttpStatusCode(int http_status_code) {
175 resource_response_->SetHttpStatusCode(http_status_code);
176 }
177
HttpStatusText() const178 WebString WebURLResponse::HttpStatusText() const {
179 return resource_response_->HttpStatusText();
180 }
181
SetHttpStatusText(const WebString & http_status_text)182 void WebURLResponse::SetHttpStatusText(const WebString& http_status_text) {
183 resource_response_->SetHttpStatusText(http_status_text);
184 }
185
HttpHeaderField(const WebString & name) const186 WebString WebURLResponse::HttpHeaderField(const WebString& name) const {
187 return resource_response_->HttpHeaderField(name);
188 }
189
SetHttpHeaderField(const WebString & name,const WebString & value)190 void WebURLResponse::SetHttpHeaderField(const WebString& name,
191 const WebString& value) {
192 resource_response_->SetHttpHeaderField(name, value);
193 }
194
AddHttpHeaderField(const WebString & name,const WebString & value)195 void WebURLResponse::AddHttpHeaderField(const WebString& name,
196 const WebString& value) {
197 if (name.IsNull() || value.IsNull())
198 return;
199
200 resource_response_->AddHttpHeaderField(name, value);
201 }
202
ClearHttpHeaderField(const WebString & name)203 void WebURLResponse::ClearHttpHeaderField(const WebString& name) {
204 resource_response_->ClearHttpHeaderField(name);
205 }
206
VisitHttpHeaderFields(WebHTTPHeaderVisitor * visitor) const207 void WebURLResponse::VisitHttpHeaderFields(
208 WebHTTPHeaderVisitor* visitor) const {
209 const HTTPHeaderMap& map = resource_response_->HttpHeaderFields();
210 for (HTTPHeaderMap::const_iterator it = map.begin(); it != map.end(); ++it)
211 visitor->VisitHeader(it->key, it->value);
212 }
213
AppCacheID() const214 int64_t WebURLResponse::AppCacheID() const {
215 return resource_response_->AppCacheID();
216 }
217
SetAppCacheID(int64_t app_cache_id)218 void WebURLResponse::SetAppCacheID(int64_t app_cache_id) {
219 resource_response_->SetAppCacheID(app_cache_id);
220 }
221
AppCacheManifestURL() const222 WebURL WebURLResponse::AppCacheManifestURL() const {
223 return resource_response_->AppCacheManifestURL();
224 }
225
SetAppCacheManifestURL(const WebURL & url)226 void WebURLResponse::SetAppCacheManifestURL(const WebURL& url) {
227 resource_response_->SetAppCacheManifestURL(url);
228 }
229
SetHasMajorCertificateErrors(bool value)230 void WebURLResponse::SetHasMajorCertificateErrors(bool value) {
231 resource_response_->SetHasMajorCertificateErrors(value);
232 }
233
SetCTPolicyCompliance(net::ct::CTPolicyCompliance compliance)234 void WebURLResponse::SetCTPolicyCompliance(
235 net::ct::CTPolicyCompliance compliance) {
236 switch (compliance) {
237 case net::ct::CTPolicyCompliance::
238 CT_POLICY_COMPLIANCE_DETAILS_NOT_AVAILABLE:
239 case net::ct::CTPolicyCompliance::CT_POLICY_BUILD_NOT_TIMELY:
240 resource_response_->SetCTPolicyCompliance(
241 ResourceResponse::kCTPolicyComplianceDetailsNotAvailable);
242 break;
243 case net::ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS:
244 case net::ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS:
245 resource_response_->SetCTPolicyCompliance(
246 ResourceResponse::kCTPolicyDoesNotComply);
247 break;
248 case net::ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS:
249 resource_response_->SetCTPolicyCompliance(
250 ResourceResponse::kCTPolicyComplies);
251 break;
252 case net::ct::CTPolicyCompliance::CT_POLICY_COUNT:
253 NOTREACHED();
254 resource_response_->SetCTPolicyCompliance(
255 ResourceResponse::kCTPolicyComplianceDetailsNotAvailable);
256 break;
257 };
258 }
259
SetIsLegacyTLSVersion(bool value)260 void WebURLResponse::SetIsLegacyTLSVersion(bool value) {
261 resource_response_->SetIsLegacyTLSVersion(value);
262 }
263
SetTimingAllowPassed(bool value)264 void WebURLResponse::SetTimingAllowPassed(bool value) {
265 resource_response_->SetTimingAllowPassed(value);
266 }
267
SetSecurityStyle(SecurityStyle security_style)268 void WebURLResponse::SetSecurityStyle(SecurityStyle security_style) {
269 resource_response_->SetSecurityStyle(security_style);
270 }
271
SetSecurityDetails(const WebSecurityDetails & web_security_details)272 void WebURLResponse::SetSecurityDetails(
273 const WebSecurityDetails& web_security_details) {
274 ResourceResponse::SignedCertificateTimestampList sct_list;
275 for (const auto& iter : web_security_details.sct_list) {
276 sct_list.push_back(
277 static_cast<ResourceResponse::SignedCertificateTimestamp>(iter));
278 }
279 Vector<String> san_list;
280 san_list.Append(web_security_details.san_list.Data(),
281 web_security_details.san_list.size());
282 Vector<AtomicString> certificate;
283 for (const auto& iter : web_security_details.certificate) {
284 AtomicString cert = iter;
285 certificate.push_back(cert);
286 }
287 resource_response_->SetSecurityDetails(
288 web_security_details.protocol, web_security_details.key_exchange,
289 web_security_details.key_exchange_group, web_security_details.cipher,
290 web_security_details.mac, web_security_details.subject_name, san_list,
291 web_security_details.issuer,
292 static_cast<time_t>(web_security_details.valid_from),
293 static_cast<time_t>(web_security_details.valid_to), certificate,
294 sct_list);
295 }
296
297 base::Optional<WebURLResponse::WebSecurityDetails>
SecurityDetailsForTesting()298 WebURLResponse::SecurityDetailsForTesting() {
299 const base::Optional<ResourceResponse::SecurityDetails>& security_details =
300 resource_response_->GetSecurityDetails();
301 if (!security_details.has_value())
302 return base::nullopt;
303 SignedCertificateTimestampList sct_list;
304 for (const auto& iter : security_details->sct_list) {
305 sct_list.emplace_back(SignedCertificateTimestamp(
306 iter.status_, iter.origin_, iter.log_description_, iter.log_id_,
307 iter.timestamp_, iter.hash_algorithm_, iter.signature_algorithm_,
308 iter.signature_data_));
309 }
310 return WebSecurityDetails(
311 security_details->protocol, security_details->key_exchange,
312 security_details->key_exchange_group, security_details->cipher,
313 security_details->mac, security_details->subject_name,
314 security_details->san_list, security_details->issuer,
315 security_details->valid_from, security_details->valid_to,
316 security_details->certificate, sct_list);
317 }
318
ToResourceResponse() const319 const ResourceResponse& WebURLResponse::ToResourceResponse() const {
320 return *resource_response_;
321 }
322
SetWasCached(bool value)323 void WebURLResponse::SetWasCached(bool value) {
324 resource_response_->SetWasCached(value);
325 }
326
WasFetchedViaSPDY() const327 bool WebURLResponse::WasFetchedViaSPDY() const {
328 return resource_response_->WasFetchedViaSPDY();
329 }
330
SetWasFetchedViaSPDY(bool value)331 void WebURLResponse::SetWasFetchedViaSPDY(bool value) {
332 resource_response_->SetWasFetchedViaSPDY(value);
333 }
334
WasFetchedViaServiceWorker() const335 bool WebURLResponse::WasFetchedViaServiceWorker() const {
336 return resource_response_->WasFetchedViaServiceWorker();
337 }
338
SetWasFetchedViaServiceWorker(bool value)339 void WebURLResponse::SetWasFetchedViaServiceWorker(bool value) {
340 resource_response_->SetWasFetchedViaServiceWorker(value);
341 }
342
SetWasFallbackRequiredByServiceWorker(bool value)343 void WebURLResponse::SetWasFallbackRequiredByServiceWorker(bool value) {
344 resource_response_->SetWasFallbackRequiredByServiceWorker(value);
345 }
346
SetType(network::mojom::FetchResponseType value)347 void WebURLResponse::SetType(network::mojom::FetchResponseType value) {
348 resource_response_->SetType(value);
349 }
350
GetType() const351 network::mojom::FetchResponseType WebURLResponse::GetType() const {
352 return resource_response_->GetType();
353 }
354
SetUrlListViaServiceWorker(const WebVector<WebURL> & url_list_via_service_worker)355 void WebURLResponse::SetUrlListViaServiceWorker(
356 const WebVector<WebURL>& url_list_via_service_worker) {
357 Vector<KURL> url_list(url_list_via_service_worker.size());
358 std::transform(url_list_via_service_worker.begin(),
359 url_list_via_service_worker.end(), url_list.begin(),
360 [](const WebURL& url) { return url; });
361 resource_response_->SetUrlListViaServiceWorker(url_list);
362 }
363
HasUrlListViaServiceWorker() const364 bool WebURLResponse::HasUrlListViaServiceWorker() const {
365 DCHECK(resource_response_->UrlListViaServiceWorker().size() == 0 ||
366 WasFetchedViaServiceWorker());
367 return resource_response_->UrlListViaServiceWorker().size() > 0;
368 }
369
SetCacheStorageCacheName(const WebString & cache_storage_cache_name)370 void WebURLResponse::SetCacheStorageCacheName(
371 const WebString& cache_storage_cache_name) {
372 resource_response_->SetCacheStorageCacheName(cache_storage_cache_name);
373 }
374
CorsExposedHeaderNames() const375 WebVector<WebString> WebURLResponse::CorsExposedHeaderNames() const {
376 return resource_response_->CorsExposedHeaderNames();
377 }
378
SetCorsExposedHeaderNames(const WebVector<WebString> & header_names)379 void WebURLResponse::SetCorsExposedHeaderNames(
380 const WebVector<WebString>& header_names) {
381 Vector<String> exposed_header_names;
382 exposed_header_names.Append(header_names.Data(), header_names.size());
383 resource_response_->SetCorsExposedHeaderNames(exposed_header_names);
384 }
385
SetDidServiceWorkerNavigationPreload(bool value)386 void WebURLResponse::SetDidServiceWorkerNavigationPreload(bool value) {
387 resource_response_->SetDidServiceWorkerNavigationPreload(value);
388 }
389
RemoteIPAddress() const390 WebString WebURLResponse::RemoteIPAddress() const {
391 return resource_response_->RemoteIPAddress();
392 }
393
SetRemoteIPAddress(const WebString & remote_ip_address)394 void WebURLResponse::SetRemoteIPAddress(const WebString& remote_ip_address) {
395 resource_response_->SetRemoteIPAddress(remote_ip_address);
396 }
397
RemotePort() const398 uint16_t WebURLResponse::RemotePort() const {
399 return resource_response_->RemotePort();
400 }
401
SetRemotePort(uint16_t remote_port)402 void WebURLResponse::SetRemotePort(uint16_t remote_port) {
403 resource_response_->SetRemotePort(remote_port);
404 }
405
SetEncodedDataLength(int64_t length)406 void WebURLResponse::SetEncodedDataLength(int64_t length) {
407 resource_response_->SetEncodedDataLength(length);
408 }
409
EncodedBodyLength() const410 int64_t WebURLResponse::EncodedBodyLength() const {
411 return resource_response_->EncodedBodyLength();
412 }
413
SetEncodedBodyLength(int64_t length)414 void WebURLResponse::SetEncodedBodyLength(int64_t length) {
415 resource_response_->SetEncodedBodyLength(length);
416 }
417
SetIsSignedExchangeInnerResponse(bool is_signed_exchange_inner_response)418 void WebURLResponse::SetIsSignedExchangeInnerResponse(
419 bool is_signed_exchange_inner_response) {
420 resource_response_->SetIsSignedExchangeInnerResponse(
421 is_signed_exchange_inner_response);
422 }
423
SetWasInPrefetchCache(bool was_in_prefetch_cache)424 void WebURLResponse::SetWasInPrefetchCache(bool was_in_prefetch_cache) {
425 resource_response_->SetWasInPrefetchCache(was_in_prefetch_cache);
426 }
427
SetRecursivePrefetchToken(const base::Optional<base::UnguessableToken> & token)428 void WebURLResponse::SetRecursivePrefetchToken(
429 const base::Optional<base::UnguessableToken>& token) {
430 resource_response_->SetRecursivePrefetchToken(token);
431 }
432
WasAlpnNegotiated() const433 bool WebURLResponse::WasAlpnNegotiated() const {
434 return resource_response_->WasAlpnNegotiated();
435 }
436
SetWasAlpnNegotiated(bool was_alpn_negotiated)437 void WebURLResponse::SetWasAlpnNegotiated(bool was_alpn_negotiated) {
438 resource_response_->SetWasAlpnNegotiated(was_alpn_negotiated);
439 }
440
AlpnNegotiatedProtocol() const441 WebString WebURLResponse::AlpnNegotiatedProtocol() const {
442 return resource_response_->AlpnNegotiatedProtocol();
443 }
444
SetAlpnNegotiatedProtocol(const WebString & alpn_negotiated_protocol)445 void WebURLResponse::SetAlpnNegotiatedProtocol(
446 const WebString& alpn_negotiated_protocol) {
447 resource_response_->SetAlpnNegotiatedProtocol(alpn_negotiated_protocol);
448 }
449
WasAlternateProtocolAvailable() const450 bool WebURLResponse::WasAlternateProtocolAvailable() const {
451 return resource_response_->WasAlternateProtocolAvailable();
452 }
453
SetWasAlternateProtocolAvailable(bool was_alternate_protocol_available)454 void WebURLResponse::SetWasAlternateProtocolAvailable(
455 bool was_alternate_protocol_available) {
456 resource_response_->SetWasAlternateProtocolAvailable(
457 was_alternate_protocol_available);
458 }
459
ConnectionInfo() const460 net::HttpResponseInfo::ConnectionInfo WebURLResponse::ConnectionInfo() const {
461 return resource_response_->ConnectionInfo();
462 }
463
SetConnectionInfo(net::HttpResponseInfo::ConnectionInfo connection_info)464 void WebURLResponse::SetConnectionInfo(
465 net::HttpResponseInfo::ConnectionInfo connection_info) {
466 resource_response_->SetConnectionInfo(connection_info);
467 }
468
SetAsyncRevalidationRequested(bool requested)469 void WebURLResponse::SetAsyncRevalidationRequested(bool requested) {
470 resource_response_->SetAsyncRevalidationRequested(requested);
471 }
472
SetNetworkAccessed(bool network_accessed)473 void WebURLResponse::SetNetworkAccessed(bool network_accessed) {
474 resource_response_->SetNetworkAccessed(network_accessed);
475 }
476
FromArchive() const477 bool WebURLResponse::FromArchive() const {
478 return resource_response_->FromArchive();
479 }
480
WebURLResponse(ResourceResponse & r)481 WebURLResponse::WebURLResponse(ResourceResponse& r) : resource_response_(&r) {}
482
483 } // namespace blink
484