| /* |
| * Copyright (C) 2006, 2008 Apple Inc. All rights reserved. |
| * Copyright (C) 2009 Google Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY |
| * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR |
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #include "third_party/blink/renderer/platform/loader/fetch/resource_response.h" |
| |
| #include <algorithm> |
| #include <limits> |
| #include <memory> |
| #include <string> |
| |
| #include "third_party/blink/public/platform/web_url_response.h" |
| #include "third_party/blink/renderer/platform/network/http_names.h" |
| #include "third_party/blink/renderer/platform/network/http_parsers.h" |
| #include "third_party/blink/renderer/platform/wtf/assertions.h" |
| #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" |
| #include "third_party/blink/renderer/platform/wtf/time.h" |
| |
| namespace blink { |
| |
| namespace { |
| |
| template <typename Interface> |
| Vector<Interface> IsolatedCopy(const Vector<Interface>& src) { |
| Vector<Interface> result; |
| result.ReserveCapacity(src.size()); |
| for (const auto& timestamp : src) { |
| result.push_back(timestamp.IsolatedCopy()); |
| } |
| return result; |
| } |
| |
| static const char kCacheControlHeader[] = "cache-control"; |
| static const char kPragmaHeader[] = "pragma"; |
| |
| } // namespace |
| |
| ResourceResponse::SignedCertificateTimestamp::SignedCertificateTimestamp( |
| const blink::WebURLResponse::SignedCertificateTimestamp& sct) |
| : status_(sct.status), |
| origin_(sct.origin), |
| log_description_(sct.log_description), |
| log_id_(sct.log_id), |
| timestamp_(sct.timestamp), |
| hash_algorithm_(sct.hash_algorithm), |
| signature_algorithm_(sct.signature_algorithm), |
| signature_data_(sct.signature_data) {} |
| |
| ResourceResponse::SignedCertificateTimestamp |
| ResourceResponse::SignedCertificateTimestamp::IsolatedCopy() const { |
| return SignedCertificateTimestamp( |
| status_.IsolatedCopy(), origin_.IsolatedCopy(), |
| log_description_.IsolatedCopy(), log_id_.IsolatedCopy(), timestamp_, |
| hash_algorithm_.IsolatedCopy(), signature_algorithm_.IsolatedCopy(), |
| signature_data_.IsolatedCopy()); |
| } |
| |
| ResourceResponse::ResourceResponse() |
| : expected_content_length_(0), is_null_(true) {} |
| |
| ResourceResponse::ResourceResponse(const KURL& url, |
| const AtomicString& mime_type, |
| long long expected_length, |
| const AtomicString& text_encoding_name) |
| : url_(url), |
| mime_type_(mime_type), |
| expected_content_length_(expected_length), |
| text_encoding_name_(text_encoding_name), |
| is_null_(false) {} |
| |
| ResourceResponse::ResourceResponse(CrossThreadResourceResponseData* data) |
| : ResourceResponse() { |
| SetURL(data->url_); |
| SetMimeType(AtomicString(data->mime_type_)); |
| SetExpectedContentLength(data->expected_content_length_); |
| SetTextEncodingName(AtomicString(data->text_encoding_name_)); |
| |
| SetHTTPStatusCode(data->http_status_code_); |
| SetHTTPStatusText(AtomicString(data->http_status_text_)); |
| |
| http_header_fields_.Adopt(std::move(data->http_headers_)); |
| SetResourceLoadTiming(std::move(data->resource_load_timing_)); |
| remote_ip_address_ = AtomicString(data->remote_ip_address_); |
| remote_port_ = data->remote_port_; |
| has_major_certificate_errors_ = data->has_major_certificate_errors_; |
| ct_policy_compliance_ = data->ct_policy_compliance_; |
| is_legacy_symantec_cert_ = data->is_legacy_symantec_cert_; |
| cert_validity_start_ = data->cert_validity_start_; |
| was_fetched_via_spdy_ = data->was_fetched_via_spdy_; |
| was_fetched_via_proxy_ = data->was_fetched_via_proxy_; |
| was_fetched_via_service_worker_ = data->was_fetched_via_service_worker_; |
| was_fallback_required_by_service_worker_ = |
| data->was_fallback_required_by_service_worker_; |
| did_service_worker_navigation_preload_ = |
| data->did_service_worker_navigation_preload_; |
| async_revalidation_requested_ = data->async_revalidation_requested_; |
| response_type_via_service_worker_ = data->response_type_via_service_worker_; |
| security_style_ = data->security_style_; |
| security_details_.protocol = data->security_details_.protocol; |
| security_details_.cipher = data->security_details_.cipher; |
| security_details_.key_exchange = data->security_details_.key_exchange; |
| security_details_.key_exchange_group = |
| data->security_details_.key_exchange_group; |
| security_details_.mac = data->security_details_.mac; |
| security_details_.subject_name = data->security_details_.subject_name; |
| security_details_.san_list = data->security_details_.san_list; |
| security_details_.issuer = data->security_details_.issuer; |
| security_details_.valid_from = data->security_details_.valid_from; |
| security_details_.valid_to = data->security_details_.valid_to; |
| for (auto& cert : data->certificate_) |
| security_details_.certificate.push_back(AtomicString(cert)); |
| security_details_.sct_list = data->security_details_.sct_list; |
| http_version_ = data->http_version_; |
| app_cache_id_ = data->app_cache_id_; |
| app_cache_manifest_url_ = data->app_cache_manifest_url_.Copy(); |
| multipart_boundary_ = data->multipart_boundary_; |
| url_list_via_service_worker_ = data->url_list_via_service_worker_; |
| cache_storage_cache_name_ = data->cache_storage_cache_name_; |
| response_time_ = data->response_time_; |
| encoded_data_length_ = data->encoded_data_length_; |
| encoded_body_length_ = data->encoded_body_length_; |
| decoded_body_length_ = data->decoded_body_length_; |
| |
| // Bug https://bugs.webkit.org/show_bug.cgi?id=60397 this doesn't support |
| // whatever values may be present in the opaque m_extraData structure. |
| } |
| |
| ResourceResponse::ResourceResponse(const ResourceResponse&) = default; |
| ResourceResponse& ResourceResponse::operator=(const ResourceResponse&) = |
| default; |
| |
| std::unique_ptr<CrossThreadResourceResponseData> ResourceResponse::CopyData() |
| const { |
| std::unique_ptr<CrossThreadResourceResponseData> data = |
| std::make_unique<CrossThreadResourceResponseData>(); |
| data->url_ = Url().Copy(); |
| data->mime_type_ = MimeType().GetString().IsolatedCopy(); |
| data->expected_content_length_ = ExpectedContentLength(); |
| data->text_encoding_name_ = TextEncodingName().GetString().IsolatedCopy(); |
| data->http_status_code_ = HttpStatusCode(); |
| data->http_status_text_ = HttpStatusText().GetString().IsolatedCopy(); |
| data->http_headers_ = HttpHeaderFields().CopyData(); |
| if (resource_load_timing_) |
| data->resource_load_timing_ = resource_load_timing_->DeepCopy(); |
| data->remote_ip_address_ = remote_ip_address_.GetString().IsolatedCopy(); |
| data->remote_port_ = remote_port_; |
| data->has_major_certificate_errors_ = has_major_certificate_errors_; |
| data->ct_policy_compliance_ = ct_policy_compliance_; |
| data->is_legacy_symantec_cert_ = is_legacy_symantec_cert_; |
| data->cert_validity_start_ = cert_validity_start_; |
| data->was_fetched_via_spdy_ = was_fetched_via_spdy_; |
| data->was_fetched_via_proxy_ = was_fetched_via_proxy_; |
| data->was_fetched_via_service_worker_ = was_fetched_via_service_worker_; |
| data->was_fallback_required_by_service_worker_ = |
| was_fallback_required_by_service_worker_; |
| data->did_service_worker_navigation_preload_ = |
| did_service_worker_navigation_preload_; |
| data->async_revalidation_requested_ = async_revalidation_requested_; |
| data->response_type_via_service_worker_ = response_type_via_service_worker_; |
| data->security_style_ = security_style_; |
| data->security_details_.protocol = security_details_.protocol.IsolatedCopy(); |
| data->security_details_.cipher = security_details_.cipher.IsolatedCopy(); |
| data->security_details_.key_exchange = |
| security_details_.key_exchange.IsolatedCopy(); |
| data->security_details_.key_exchange_group = |
| security_details_.key_exchange_group.IsolatedCopy(); |
| data->security_details_.mac = security_details_.mac.IsolatedCopy(); |
| data->security_details_.subject_name = |
| security_details_.subject_name.IsolatedCopy(); |
| data->security_details_.san_list = IsolatedCopy(security_details_.san_list); |
| data->security_details_.issuer = security_details_.issuer.IsolatedCopy(); |
| data->security_details_.valid_from = security_details_.valid_from; |
| data->security_details_.valid_to = security_details_.valid_to; |
| for (auto& cert : security_details_.certificate) |
| data->certificate_.push_back(cert.GetString().IsolatedCopy()); |
| data->security_details_.sct_list = IsolatedCopy(security_details_.sct_list); |
| data->http_version_ = http_version_; |
| data->app_cache_id_ = app_cache_id_; |
| data->app_cache_manifest_url_ = app_cache_manifest_url_.Copy(); |
| data->multipart_boundary_ = multipart_boundary_; |
| data->url_list_via_service_worker_.resize( |
| url_list_via_service_worker_.size()); |
| std::transform(url_list_via_service_worker_.begin(), |
| url_list_via_service_worker_.end(), |
| data->url_list_via_service_worker_.begin(), |
| [](const KURL& url) { return url.Copy(); }); |
| data->cache_storage_cache_name_ = CacheStorageCacheName().IsolatedCopy(); |
| data->response_time_ = response_time_; |
| data->encoded_data_length_ = encoded_data_length_; |
| data->encoded_body_length_ = encoded_body_length_; |
| data->decoded_body_length_ = decoded_body_length_; |
| |
| // Bug https://bugs.webkit.org/show_bug.cgi?id=60397 this doesn't support |
| // whatever values may be present in the opaque m_extraData structure. |
| |
| return data; |
| } |
| |
| bool ResourceResponse::IsHTTP() const { |
| return url_.ProtocolIsInHTTPFamily(); |
| } |
| |
| const KURL& ResourceResponse::Url() const { |
| return url_; |
| } |
| |
| void ResourceResponse::SetURL(const KURL& url) { |
| is_null_ = false; |
| |
| url_ = url; |
| } |
| |
| const AtomicString& ResourceResponse::MimeType() const { |
| return mime_type_; |
| } |
| |
| void ResourceResponse::SetMimeType(const AtomicString& mime_type) { |
| is_null_ = false; |
| |
| // FIXME: MIME type is determined by HTTP Content-Type header. We should |
| // update the header, so that it doesn't disagree with m_mimeType. |
| mime_type_ = mime_type; |
| } |
| |
| long long ResourceResponse::ExpectedContentLength() const { |
| return expected_content_length_; |
| } |
| |
| void ResourceResponse::SetExpectedContentLength( |
| long long expected_content_length) { |
| is_null_ = false; |
| |
| // FIXME: Content length is determined by HTTP Content-Length header. We |
| // should update the header, so that it doesn't disagree with |
| // m_expectedContentLength. |
| expected_content_length_ = expected_content_length; |
| } |
| |
| const AtomicString& ResourceResponse::TextEncodingName() const { |
| return text_encoding_name_; |
| } |
| |
| void ResourceResponse::SetTextEncodingName(const AtomicString& encoding_name) { |
| is_null_ = false; |
| |
| // FIXME: Text encoding is determined by HTTP Content-Type header. We should |
| // update the header, so that it doesn't disagree with m_textEncodingName. |
| text_encoding_name_ = encoding_name; |
| } |
| |
| int ResourceResponse::HttpStatusCode() const { |
| return http_status_code_; |
| } |
| |
| void ResourceResponse::SetHTTPStatusCode(int status_code) { |
| http_status_code_ = status_code; |
| } |
| |
| const AtomicString& ResourceResponse::HttpStatusText() const { |
| return http_status_text_; |
| } |
| |
| void ResourceResponse::SetHTTPStatusText(const AtomicString& status_text) { |
| http_status_text_ = status_text; |
| } |
| |
| const AtomicString& ResourceResponse::HttpHeaderField( |
| const AtomicString& name) const { |
| return http_header_fields_.Get(name); |
| } |
| |
| void ResourceResponse::UpdateHeaderParsedState(const AtomicString& name) { |
| static const char kAgeHeader[] = "age"; |
| static const char kDateHeader[] = "date"; |
| static const char kExpiresHeader[] = "expires"; |
| static const char kLastModifiedHeader[] = "last-modified"; |
| |
| if (DeprecatedEqualIgnoringCase(name, kAgeHeader)) |
| have_parsed_age_header_ = false; |
| else if (DeprecatedEqualIgnoringCase(name, kCacheControlHeader) || |
| DeprecatedEqualIgnoringCase(name, kPragmaHeader)) |
| cache_control_header_ = CacheControlHeader(); |
| else if (DeprecatedEqualIgnoringCase(name, kDateHeader)) |
| have_parsed_date_header_ = false; |
| else if (DeprecatedEqualIgnoringCase(name, kExpiresHeader)) |
| have_parsed_expires_header_ = false; |
| else if (DeprecatedEqualIgnoringCase(name, kLastModifiedHeader)) |
| have_parsed_last_modified_header_ = false; |
| } |
| |
| void ResourceResponse::SetSecurityDetails( |
| const String& protocol, |
| const String& key_exchange, |
| const String& key_exchange_group, |
| const String& cipher, |
| const String& mac, |
| const String& subject_name, |
| const Vector<String>& san_list, |
| const String& issuer, |
| time_t valid_from, |
| time_t valid_to, |
| const Vector<AtomicString>& certificate, |
| const SignedCertificateTimestampList& sct_list) { |
| security_details_.protocol = protocol; |
| security_details_.key_exchange = key_exchange; |
| security_details_.key_exchange_group = key_exchange_group; |
| security_details_.cipher = cipher; |
| security_details_.mac = mac; |
| security_details_.subject_name = subject_name; |
| security_details_.san_list = san_list; |
| security_details_.issuer = issuer; |
| security_details_.valid_from = valid_from; |
| security_details_.valid_to = valid_to; |
| security_details_.certificate = certificate; |
| security_details_.sct_list = sct_list; |
| } |
| |
| void ResourceResponse::SetHTTPHeaderField(const AtomicString& name, |
| const AtomicString& value) { |
| UpdateHeaderParsedState(name); |
| |
| http_header_fields_.Set(name, value); |
| } |
| |
| void ResourceResponse::AddHTTPHeaderField(const AtomicString& name, |
| const AtomicString& value) { |
| UpdateHeaderParsedState(name); |
| |
| HTTPHeaderMap::AddResult result = http_header_fields_.Add(name, value); |
| if (!result.is_new_entry) |
| result.stored_value->value = result.stored_value->value + ", " + value; |
| } |
| |
| void ResourceResponse::ClearHTTPHeaderField(const AtomicString& name) { |
| http_header_fields_.Remove(name); |
| } |
| |
| const HTTPHeaderMap& ResourceResponse::HttpHeaderFields() const { |
| return http_header_fields_; |
| } |
| |
| bool ResourceResponse::CacheControlContainsNoCache() const { |
| if (!cache_control_header_.parsed) { |
| cache_control_header_ = ParseCacheControlDirectives( |
| http_header_fields_.Get(kCacheControlHeader), |
| http_header_fields_.Get(kPragmaHeader)); |
| } |
| return cache_control_header_.contains_no_cache; |
| } |
| |
| bool ResourceResponse::CacheControlContainsNoStore() const { |
| if (!cache_control_header_.parsed) { |
| cache_control_header_ = ParseCacheControlDirectives( |
| http_header_fields_.Get(kCacheControlHeader), |
| http_header_fields_.Get(kPragmaHeader)); |
| } |
| return cache_control_header_.contains_no_store; |
| } |
| |
| bool ResourceResponse::CacheControlContainsMustRevalidate() const { |
| if (!cache_control_header_.parsed) { |
| cache_control_header_ = ParseCacheControlDirectives( |
| http_header_fields_.Get(kCacheControlHeader), |
| http_header_fields_.Get(kPragmaHeader)); |
| } |
| return cache_control_header_.contains_must_revalidate; |
| } |
| |
| bool ResourceResponse::HasCacheValidatorFields() const { |
| static const char kLastModifiedHeader[] = "last-modified"; |
| static const char kETagHeader[] = "etag"; |
| return !http_header_fields_.Get(kLastModifiedHeader).IsEmpty() || |
| !http_header_fields_.Get(kETagHeader).IsEmpty(); |
| } |
| |
| double ResourceResponse::CacheControlMaxAge() const { |
| if (!cache_control_header_.parsed) { |
| cache_control_header_ = ParseCacheControlDirectives( |
| http_header_fields_.Get(kCacheControlHeader), |
| http_header_fields_.Get(kPragmaHeader)); |
| } |
| return cache_control_header_.max_age; |
| } |
| |
| double ResourceResponse::CacheControlStaleWhileRevalidate() const { |
| if (!cache_control_header_.parsed) { |
| cache_control_header_ = ParseCacheControlDirectives( |
| http_header_fields_.Get(kCacheControlHeader), |
| http_header_fields_.Get(kPragmaHeader)); |
| } |
| if (!std::isfinite(cache_control_header_.stale_while_revalidate) || |
| cache_control_header_.stale_while_revalidate < 0) { |
| return 0; |
| } |
| return cache_control_header_.stale_while_revalidate; |
| } |
| |
| static double ParseDateValueInHeader(const HTTPHeaderMap& headers, |
| const AtomicString& header_name) { |
| const AtomicString& header_value = headers.Get(header_name); |
| if (header_value.IsEmpty()) |
| return std::numeric_limits<double>::quiet_NaN(); |
| // This handles all date formats required by RFC2616: |
| // Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123 |
| // Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036 |
| // Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format |
| double date_in_milliseconds = ParseDate(header_value); |
| if (!std::isfinite(date_in_milliseconds)) |
| return std::numeric_limits<double>::quiet_NaN(); |
| return date_in_milliseconds / 1000; |
| } |
| |
| double ResourceResponse::Date() const { |
| if (!have_parsed_date_header_) { |
| static const char kHeaderName[] = "date"; |
| date_ = ParseDateValueInHeader(http_header_fields_, kHeaderName); |
| have_parsed_date_header_ = true; |
| } |
| return date_; |
| } |
| |
| double ResourceResponse::Age() const { |
| if (!have_parsed_age_header_) { |
| static const char kHeaderName[] = "age"; |
| const AtomicString& header_value = http_header_fields_.Get(kHeaderName); |
| bool ok; |
| age_ = header_value.ToDouble(&ok); |
| if (!ok) |
| age_ = std::numeric_limits<double>::quiet_NaN(); |
| have_parsed_age_header_ = true; |
| } |
| return age_; |
| } |
| |
| double ResourceResponse::Expires() const { |
| if (!have_parsed_expires_header_) { |
| static const char kHeaderName[] = "expires"; |
| expires_ = ParseDateValueInHeader(http_header_fields_, kHeaderName); |
| have_parsed_expires_header_ = true; |
| } |
| return expires_; |
| } |
| |
| double ResourceResponse::LastModified() const { |
| if (!have_parsed_last_modified_header_) { |
| static const char kHeaderName[] = "last-modified"; |
| last_modified_ = ParseDateValueInHeader(http_header_fields_, kHeaderName); |
| have_parsed_last_modified_header_ = true; |
| } |
| return last_modified_; |
| } |
| |
| bool ResourceResponse::IsAttachment() const { |
| static const char kAttachmentString[] = "attachment"; |
| String value = http_header_fields_.Get(HTTPNames::Content_Disposition); |
| size_t loc = value.find(';'); |
| if (loc != kNotFound) |
| value = value.Left(loc); |
| value = value.StripWhiteSpace(); |
| return DeprecatedEqualIgnoringCase(value, kAttachmentString); |
| } |
| |
| AtomicString ResourceResponse::HttpContentType() const { |
| return ExtractMIMETypeFromMediaType( |
| HttpHeaderField(HTTPNames::Content_Type).DeprecatedLower()); |
| } |
| |
| bool ResourceResponse::WasCached() const { |
| return was_cached_; |
| } |
| |
| void ResourceResponse::SetWasCached(bool value) { |
| was_cached_ = value; |
| } |
| |
| bool ResourceResponse::ConnectionReused() const { |
| return connection_reused_; |
| } |
| |
| void ResourceResponse::SetConnectionReused(bool connection_reused) { |
| connection_reused_ = connection_reused; |
| } |
| |
| unsigned ResourceResponse::ConnectionID() const { |
| return connection_id_; |
| } |
| |
| void ResourceResponse::SetConnectionID(unsigned connection_id) { |
| connection_id_ = connection_id; |
| } |
| |
| ResourceLoadTiming* ResourceResponse::GetResourceLoadTiming() const { |
| return resource_load_timing_.get(); |
| } |
| |
| void ResourceResponse::SetResourceLoadTiming( |
| scoped_refptr<ResourceLoadTiming> resource_load_timing) { |
| resource_load_timing_ = std::move(resource_load_timing); |
| } |
| |
| scoped_refptr<ResourceLoadInfo> ResourceResponse::GetResourceLoadInfo() const { |
| return resource_load_info_.get(); |
| } |
| |
| void ResourceResponse::SetResourceLoadInfo( |
| scoped_refptr<ResourceLoadInfo> load_info) { |
| resource_load_info_ = std::move(load_info); |
| } |
| |
| void ResourceResponse::SetCTPolicyCompliance(CTPolicyCompliance compliance) { |
| ct_policy_compliance_ = compliance; |
| } |
| |
| bool ResourceResponse::IsOpaqueResponseFromServiceWorker() const { |
| switch (response_type_via_service_worker_) { |
| case network::mojom::FetchResponseType::kBasic: |
| case network::mojom::FetchResponseType::kCORS: |
| case network::mojom::FetchResponseType::kDefault: |
| case network::mojom::FetchResponseType::kError: |
| return false; |
| case network::mojom::FetchResponseType::kOpaque: |
| case network::mojom::FetchResponseType::kOpaqueRedirect: |
| return true; |
| } |
| NOTREACHED(); |
| return false; |
| } |
| |
| KURL ResourceResponse::OriginalURLViaServiceWorker() const { |
| if (url_list_via_service_worker_.IsEmpty()) |
| return KURL(); |
| return url_list_via_service_worker_.back(); |
| } |
| |
| AtomicString ResourceResponse::ConnectionInfoString() const { |
| std::string connection_info_string = |
| net::HttpResponseInfo::ConnectionInfoToString(connection_info_); |
| return AtomicString( |
| reinterpret_cast<const LChar*>(connection_info_string.data()), |
| connection_info_string.length()); |
| } |
| |
| void ResourceResponse::SetEncodedDataLength(long long value) { |
| encoded_data_length_ = value; |
| } |
| |
| void ResourceResponse::SetEncodedBodyLength(long long value) { |
| encoded_body_length_ = value; |
| } |
| |
| void ResourceResponse::SetDecodedBodyLength(long long value) { |
| decoded_body_length_ = value; |
| } |
| |
| void ResourceResponse::AppendRedirectResponse( |
| const ResourceResponse& response) { |
| redirect_responses_.push_back(response); |
| } |
| |
| bool ResourceResponse::Compare(const ResourceResponse& a, |
| const ResourceResponse& b) { |
| if (a.IsNull() != b.IsNull()) |
| return false; |
| if (a.Url() != b.Url()) |
| return false; |
| if (a.MimeType() != b.MimeType()) |
| return false; |
| if (a.ExpectedContentLength() != b.ExpectedContentLength()) |
| return false; |
| if (a.TextEncodingName() != b.TextEncodingName()) |
| return false; |
| if (a.HttpStatusCode() != b.HttpStatusCode()) |
| return false; |
| if (a.HttpStatusText() != b.HttpStatusText()) |
| return false; |
| if (a.HttpHeaderFields() != b.HttpHeaderFields()) |
| return false; |
| if (a.GetResourceLoadTiming() && b.GetResourceLoadTiming() && |
| *a.GetResourceLoadTiming() == *b.GetResourceLoadTiming()) |
| return true; |
| if (a.GetResourceLoadTiming() != b.GetResourceLoadTiming()) |
| return false; |
| if (a.EncodedBodyLength() != b.EncodedBodyLength()) |
| return false; |
| if (a.DecodedBodyLength() != b.DecodedBodyLength()) |
| return false; |
| return true; |
| } |
| |
| STATIC_ASSERT_ENUM(WebURLResponse::kHTTPVersionUnknown, |
| ResourceResponse::kHTTPVersionUnknown); |
| STATIC_ASSERT_ENUM(WebURLResponse::kHTTPVersion_0_9, |
| ResourceResponse::kHTTPVersion_0_9); |
| STATIC_ASSERT_ENUM(WebURLResponse::kHTTPVersion_1_0, |
| ResourceResponse::kHTTPVersion_1_0); |
| STATIC_ASSERT_ENUM(WebURLResponse::kHTTPVersion_1_1, |
| ResourceResponse::kHTTPVersion_1_1); |
| STATIC_ASSERT_ENUM(WebURLResponse::kHTTPVersion_2_0, |
| ResourceResponse::kHTTPVersion_2_0); |
| } // namespace blink |