| /* |
| * Copyright (C) 2010 Google, Inc. All Rights Reserved. |
| * Copyright (C) 2014-2021 Apple, 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 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 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. |
| */ |
| |
| #pragma once |
| |
| #include "HTTPHeaderMap.h" |
| #include <wtf/Box.h> |
| #include <wtf/MonotonicTime.h> |
| #include <wtf/persistence/PersistentCoder.h> |
| #include <wtf/text/WTFString.h> |
| |
| #if PLATFORM(COCOA) |
| OBJC_CLASS NSURLConnection; |
| OBJC_CLASS NSURLSessionTaskMetrics; |
| #endif |
| |
| namespace WebCore { |
| |
| class ResourceHandle; |
| |
| enum class NetworkLoadPriority : uint8_t { |
| Low, |
| Medium, |
| High, |
| Unknown, |
| }; |
| |
| enum class PrivacyStance : uint8_t { |
| Unknown, |
| NotEligible, |
| Proxied, |
| Failed, |
| Direct, |
| }; |
| |
| constexpr MonotonicTime reusedTLSConnectionSentinel { MonotonicTime::fromRawSeconds(-1) }; |
| |
| struct AdditionalNetworkLoadMetricsForWebInspector; |
| |
| class NetworkLoadMetrics { |
| WTF_MAKE_FAST_ALLOCATED(NetworkLoadMetrics); |
| public: |
| WEBCORE_EXPORT NetworkLoadMetrics(); |
| |
| static const NetworkLoadMetrics& emptyMetrics(); |
| |
| NetworkLoadMetrics isolatedCopy() const; |
| |
| template<class Encoder> void encode(Encoder&) const; |
| template<class Decoder> static std::optional<NetworkLoadMetrics> decode(Decoder&); |
| |
| bool isComplete() const { return complete; } |
| void markComplete() { complete = true; } |
| |
| // https://www.w3.org/TR/resource-timing-2/#attribute-descriptions |
| MonotonicTime redirectStart; |
| MonotonicTime fetchStart; |
| MonotonicTime domainLookupStart; |
| MonotonicTime domainLookupEnd; |
| MonotonicTime connectStart; |
| MonotonicTime secureConnectionStart; |
| MonotonicTime connectEnd; |
| MonotonicTime requestStart; |
| MonotonicTime responseStart; |
| MonotonicTime responseEnd; |
| |
| // ALPN Protocol ID: https://w3c.github.io/resource-timing/#bib-RFC7301 |
| String protocol; |
| |
| uint16_t redirectCount { 0 }; |
| |
| bool complete : 1; |
| bool cellular : 1; |
| bool expensive : 1; |
| bool constrained : 1; |
| bool multipath : 1; |
| bool isReusedConnection : 1; |
| bool failsTAOCheck : 1; |
| bool hasCrossOriginRedirect : 1; |
| |
| PrivacyStance privacyStance { PrivacyStance::Unknown }; |
| |
| uint64_t responseBodyBytesReceived { std::numeric_limits<uint64_t>::max() }; |
| uint64_t responseBodyDecodedSize { std::numeric_limits<uint64_t>::max() }; |
| |
| RefPtr<AdditionalNetworkLoadMetricsForWebInspector> additionalNetworkLoadMetricsForWebInspector; |
| }; |
| |
| struct AdditionalNetworkLoadMetricsForWebInspector : public RefCounted<AdditionalNetworkLoadMetricsForWebInspector> { |
| |
| static Ref<AdditionalNetworkLoadMetricsForWebInspector> create() { return adoptRef(*new AdditionalNetworkLoadMetricsForWebInspector()); } |
| Ref<AdditionalNetworkLoadMetricsForWebInspector> isolatedCopy() const; |
| |
| template<class Encoder> void encode(Encoder&) const; |
| template<class Decoder> static RefPtr<AdditionalNetworkLoadMetricsForWebInspector> decode(Decoder&); |
| Ref<AdditionalNetworkLoadMetricsForWebInspector> isolatedCopy(); |
| |
| NetworkLoadPriority priority { NetworkLoadPriority::Unknown }; |
| |
| String remoteAddress; |
| String connectionIdentifier; |
| |
| String tlsProtocol; |
| String tlsCipher; |
| |
| HTTPHeaderMap requestHeaders; |
| |
| uint64_t requestHeaderBytesSent { std::numeric_limits<uint64_t>::max() }; |
| uint64_t responseHeaderBytesReceived { std::numeric_limits<uint64_t>::max() }; |
| uint64_t requestBodyBytesSent { std::numeric_limits<uint64_t>::max() }; |
| private: |
| AdditionalNetworkLoadMetricsForWebInspector() { } |
| }; |
| |
| #if PLATFORM(COCOA) |
| Box<NetworkLoadMetrics> copyTimingData(NSURLConnection *, const ResourceHandle&); |
| WEBCORE_EXPORT Box<NetworkLoadMetrics> copyTimingData(NSURLSessionTaskMetrics *incompleteMetrics, const NetworkLoadMetrics&); |
| #endif |
| |
| template<class Encoder> |
| void NetworkLoadMetrics::encode(Encoder& encoder) const |
| { |
| static_assert(Encoder::isIPCEncoder, "NetworkLoadMetrics should not be stored by the WTF::Persistence::Encoder"); |
| |
| encoder << redirectStart; |
| encoder << fetchStart; |
| encoder << domainLookupStart; |
| encoder << domainLookupEnd; |
| encoder << connectStart; |
| encoder << secureConnectionStart; |
| encoder << connectEnd; |
| encoder << requestStart; |
| encoder << responseStart; |
| encoder << responseEnd; |
| |
| encoder << protocol; |
| |
| encoder << redirectCount; |
| |
| encoder << complete; |
| encoder << cellular; |
| encoder << expensive; |
| encoder << constrained; |
| encoder << multipath; |
| encoder << isReusedConnection; |
| encoder << failsTAOCheck; |
| encoder << hasCrossOriginRedirect; |
| |
| encoder << privacyStance; |
| |
| encoder << responseBodyBytesReceived; |
| encoder << responseBodyDecodedSize; |
| |
| if (additionalNetworkLoadMetricsForWebInspector) { |
| encoder << true; |
| encoder << *additionalNetworkLoadMetricsForWebInspector; |
| } else |
| encoder << false; |
| } |
| |
| template<class Decoder> |
| std::optional<NetworkLoadMetrics> NetworkLoadMetrics::decode(Decoder& decoder) |
| { |
| static_assert(Decoder::isIPCDecoder, "NetworkLoadMetrics should not be stored by the WTF::Persistence::Encoder"); |
| |
| NetworkLoadMetrics metrics; |
| if (!(decoder.decode(metrics.redirectStart) |
| && decoder.decode(metrics.fetchStart) |
| && decoder.decode(metrics.domainLookupStart) |
| && decoder.decode(metrics.domainLookupEnd) |
| && decoder.decode(metrics.connectStart) |
| && decoder.decode(metrics.secureConnectionStart) |
| && decoder.decode(metrics.connectEnd) |
| && decoder.decode(metrics.requestStart) |
| && decoder.decode(metrics.responseStart) |
| && decoder.decode(metrics.responseEnd) |
| && decoder.decode(metrics.protocol) |
| && decoder.decode(metrics.redirectCount))) |
| return std::nullopt; |
| |
| std::optional<bool> complete; |
| decoder >> complete; |
| if (!complete) |
| return std::nullopt; |
| metrics.complete = WTFMove(*complete); |
| |
| std::optional<bool> cellular; |
| decoder >> cellular; |
| if (!cellular) |
| return std::nullopt; |
| metrics.cellular = WTFMove(*cellular); |
| |
| std::optional<bool> expensive; |
| decoder >> expensive; |
| if (!expensive) |
| return std::nullopt; |
| metrics.expensive = WTFMove(*expensive); |
| |
| std::optional<bool> constrained; |
| decoder >> constrained; |
| if (!constrained) |
| return std::nullopt; |
| metrics.constrained = WTFMove(*constrained); |
| |
| std::optional<bool> multipath; |
| decoder >> multipath; |
| if (!multipath) |
| return std::nullopt; |
| metrics.multipath = WTFMove(*multipath); |
| |
| std::optional<bool> isReusedConnection; |
| decoder >> isReusedConnection; |
| if (!isReusedConnection) |
| return std::nullopt; |
| metrics.isReusedConnection = WTFMove(*isReusedConnection); |
| |
| std::optional<bool> failsTAOCheck; |
| decoder >> failsTAOCheck; |
| if (!failsTAOCheck) |
| return std::nullopt; |
| metrics.failsTAOCheck = WTFMove(*failsTAOCheck); |
| |
| std::optional<bool> hasCrossOriginRedirect; |
| decoder >> hasCrossOriginRedirect; |
| if (!hasCrossOriginRedirect) |
| return std::nullopt; |
| metrics.hasCrossOriginRedirect = WTFMove(*hasCrossOriginRedirect); |
| |
| if (!(decoder.decode(metrics.privacyStance) |
| && decoder.decode(metrics.responseBodyBytesReceived) |
| && decoder.decode(metrics.responseBodyDecodedSize))) |
| return std::nullopt; |
| |
| std::optional<bool> hasAdditionalNetworkLoadMetricsForWebInspector; |
| decoder >> hasAdditionalNetworkLoadMetricsForWebInspector; |
| if (!hasAdditionalNetworkLoadMetricsForWebInspector) |
| return std::nullopt; |
| if (*hasAdditionalNetworkLoadMetricsForWebInspector) { |
| metrics.additionalNetworkLoadMetricsForWebInspector = AdditionalNetworkLoadMetricsForWebInspector::decode(decoder); |
| if (!metrics.additionalNetworkLoadMetricsForWebInspector) |
| return std::nullopt; |
| } |
| return metrics; |
| } |
| |
| template<class Encoder> |
| void AdditionalNetworkLoadMetricsForWebInspector::encode(Encoder& encoder) const |
| { |
| encoder << priority; |
| encoder << remoteAddress; |
| encoder << connectionIdentifier; |
| |
| encoder << tlsProtocol; |
| encoder << tlsCipher; |
| |
| encoder << requestHeaders; |
| |
| encoder << requestHeaderBytesSent; |
| encoder << responseHeaderBytesReceived; |
| encoder << requestBodyBytesSent; |
| } |
| |
| template<class Decoder> |
| RefPtr<AdditionalNetworkLoadMetricsForWebInspector> AdditionalNetworkLoadMetricsForWebInspector::decode(Decoder& decoder) |
| { |
| std::optional<NetworkLoadPriority> priority; |
| decoder >> priority; |
| if (!priority) |
| return nullptr; |
| |
| std::optional<String> remoteAddress; |
| decoder >> remoteAddress; |
| if (!remoteAddress) |
| return nullptr; |
| |
| std::optional<String> connectionIdentifier; |
| decoder >> connectionIdentifier; |
| if (!connectionIdentifier) |
| return nullptr; |
| |
| std::optional<String> tlsProtocol; |
| decoder >> tlsProtocol; |
| if (!tlsProtocol) |
| return nullptr; |
| |
| std::optional<String> tlsCipher; |
| decoder >> tlsCipher; |
| if (!tlsCipher) |
| return nullptr; |
| |
| std::optional<HTTPHeaderMap> requestHeaders; |
| decoder >> requestHeaders; |
| if (!requestHeaders) |
| return nullptr; |
| |
| std::optional<uint64_t> requestHeaderBytesSent; |
| decoder >> requestHeaderBytesSent; |
| if (!requestHeaderBytesSent) |
| return nullptr; |
| |
| std::optional<uint64_t> responseHeaderBytesReceived; |
| decoder >> responseHeaderBytesReceived; |
| if (!responseHeaderBytesReceived) |
| return nullptr; |
| |
| std::optional<uint64_t> requestBodyBytesSent; |
| decoder >> requestBodyBytesSent; |
| if (!requestBodyBytesSent) |
| return nullptr; |
| |
| auto decoded = AdditionalNetworkLoadMetricsForWebInspector::create(); |
| decoded->priority = WTFMove(*priority); |
| decoded->remoteAddress = WTFMove(*remoteAddress); |
| decoded->connectionIdentifier = WTFMove(*connectionIdentifier); |
| decoded->tlsProtocol = WTFMove(*tlsProtocol); |
| decoded->tlsCipher = WTFMove(*tlsCipher); |
| decoded->requestHeaders = WTFMove(*requestHeaders); |
| decoded->requestHeaderBytesSent = WTFMove(*requestHeaderBytesSent); |
| decoded->responseHeaderBytesReceived = WTFMove(*responseHeaderBytesReceived); |
| decoded->requestBodyBytesSent = WTFMove(*requestBodyBytesSent); |
| return decoded; |
| } |
| |
| } // namespace WebCore |
| |
| namespace WTF { |
| |
| template<> struct EnumTraits<WebCore::PrivacyStance> { |
| using values = EnumValues< |
| WebCore::PrivacyStance, |
| WebCore::PrivacyStance::Unknown, |
| WebCore::PrivacyStance::NotEligible, |
| WebCore::PrivacyStance::Proxied, |
| WebCore::PrivacyStance::Failed, |
| WebCore::PrivacyStance::Direct |
| >; |
| }; |
| |
| template<> struct EnumTraits<WebCore::NetworkLoadPriority> { |
| using values = EnumValues< |
| WebCore::NetworkLoadPriority, |
| WebCore::NetworkLoadPriority::Low, |
| WebCore::NetworkLoadPriority::Medium, |
| WebCore::NetworkLoadPriority::High, |
| WebCore::NetworkLoadPriority::Unknown |
| >; |
| }; |
| |
| } |