NetworkLoadMetrics.h [plain text]
#pragma once
#include "HTTPHeaderMap.h"
#include <wtf/Optional.h>
#include <wtf/Seconds.h>
#include <wtf/persistence/Decoder.h>
#include <wtf/persistence/Encoder.h>
#include <wtf/text/WTFString.h>
#if PLATFORM(COCOA)
OBJC_CLASS NSDictionary;
#endif
namespace WebCore {
enum class NetworkLoadPriority {
Low,
Medium,
High,
};
class NetworkLoadMetrics {
public:
NetworkLoadMetrics()
{
reset();
}
NetworkLoadMetrics isolatedCopy() const
{
NetworkLoadMetrics copy;
copy.domainLookupStart = domainLookupStart;
copy.domainLookupEnd = domainLookupEnd;
copy.connectStart = connectStart;
copy.secureConnectionStart = secureConnectionStart;
copy.connectEnd = connectEnd;
copy.requestStart = requestStart;
copy.responseStart = responseStart;
copy.responseEnd = responseEnd;
copy.complete = complete;
copy.protocol = protocol.isolatedCopy();
if (remoteAddress)
copy.remoteAddress = remoteAddress.value().isolatedCopy();
if (connectionIdentifier)
copy.connectionIdentifier = connectionIdentifier.value().isolatedCopy();
if (priority)
copy.priority = *priority;
if (requestHeaders)
copy.requestHeaders = requestHeaders.value().isolatedCopy();
copy.requestHeaderBytesSent = requestHeaderBytesSent;
copy.requestBodyBytesSent = requestBodyBytesSent;
copy.responseHeaderBytesReceived = responseHeaderBytesReceived;
copy.responseBodyBytesReceived = responseBodyBytesReceived;
copy.responseBodyDecodedSize = responseBodyDecodedSize;
return copy;
}
void reset()
{
domainLookupStart = Seconds(-1);
domainLookupEnd = Seconds(-1);
connectStart = Seconds(-1);
secureConnectionStart = Seconds(-1);
connectEnd = Seconds(-1);
requestStart = Seconds(0);
responseStart = Seconds(0);
responseEnd = Seconds(0);
complete = false;
protocol = String();
remoteAddress = std::nullopt;
connectionIdentifier = std::nullopt;
priority = std::nullopt;
requestHeaders = std::nullopt;
requestHeaderBytesSent = std::nullopt;
requestBodyBytesSent = std::nullopt;
responseHeaderBytesReceived = std::nullopt;
responseBodyBytesReceived = std::nullopt;
responseBodyDecodedSize = std::nullopt;
}
void clearNonTimingData()
{
remoteAddress = std::nullopt;
connectionIdentifier = std::nullopt;
priority = std::nullopt;
requestHeaders = std::nullopt;
requestHeaderBytesSent = std::nullopt;
requestBodyBytesSent = std::nullopt;
responseHeaderBytesReceived = std::nullopt;
responseBodyBytesReceived = std::nullopt;
responseBodyDecodedSize = std::nullopt;
}
bool operator==(const NetworkLoadMetrics& other) const
{
return domainLookupStart == other.domainLookupStart
&& domainLookupEnd == other.domainLookupEnd
&& connectStart == other.connectStart
&& secureConnectionStart == other.secureConnectionStart
&& connectEnd == other.connectEnd
&& requestStart == other.requestStart
&& responseStart == other.responseStart
&& responseEnd == other.responseEnd
&& complete == other.complete
&& protocol == other.protocol
&& remoteAddress == other.remoteAddress
&& connectionIdentifier == other.connectionIdentifier
&& priority == other.priority
&& requestHeaders == other.requestHeaders
&& requestHeaderBytesSent == other.requestHeaderBytesSent
&& requestBodyBytesSent == other.requestBodyBytesSent
&& responseHeaderBytesReceived == other.responseHeaderBytesReceived
&& responseBodyBytesReceived == other.responseBodyBytesReceived
&& responseBodyDecodedSize == other.responseBodyDecodedSize;
}
bool operator!=(const NetworkLoadMetrics& other) const
{
return !(*this == other);
}
bool isComplete() const { return complete; }
void markComplete() { complete = true; }
template<class Encoder> void encode(Encoder&) const;
template<class Decoder> static bool decode(Decoder&, NetworkLoadMetrics&);
Seconds domainLookupStart; Seconds domainLookupEnd; Seconds connectStart; Seconds secureConnectionStart; Seconds connectEnd; Seconds requestStart;
Seconds responseStart;
Seconds responseEnd;
bool complete { false };
String protocol;
std::optional<String> remoteAddress;
std::optional<String> connectionIdentifier;
std::optional<NetworkLoadPriority> priority;
std::optional<HTTPHeaderMap> requestHeaders;
std::optional<uint64_t> requestHeaderBytesSent;
std::optional<uint64_t> requestBodyBytesSent;
std::optional<uint64_t> responseHeaderBytesReceived;
std::optional<uint64_t> responseBodyBytesReceived;
std::optional<uint64_t> responseBodyDecodedSize;
};
#if PLATFORM(COCOA)
WEBCORE_EXPORT void copyTimingData(NSDictionary *timingData, NetworkLoadMetrics&);
#endif
#if PLATFORM(COCOA) && !HAVE(TIMINGDATAOPTIONS)
WEBCORE_EXPORT void setCollectsTimingData();
#endif
template<class Encoder>
void NetworkLoadMetrics::encode(Encoder& encoder) const
{
encoder << domainLookupStart;
encoder << domainLookupEnd;
encoder << connectStart;
encoder << secureConnectionStart;
encoder << connectEnd;
encoder << requestStart;
encoder << responseStart;
encoder << responseEnd;
encoder << complete;
encoder << protocol;
encoder << remoteAddress;
encoder << connectionIdentifier;
encoder << priority;
encoder << requestHeaders;
encoder << requestHeaderBytesSent;
encoder << requestBodyBytesSent;
encoder << responseHeaderBytesReceived;
encoder << responseBodyBytesReceived;
encoder << responseBodyDecodedSize;
}
template<class Decoder>
bool NetworkLoadMetrics::decode(Decoder& decoder, NetworkLoadMetrics& metrics)
{
return 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.complete)
&& decoder.decode(metrics.protocol)
&& decoder.decode(metrics.remoteAddress)
&& decoder.decode(metrics.connectionIdentifier)
&& decoder.decode(metrics.priority)
&& decoder.decode(metrics.requestHeaders)
&& decoder.decode(metrics.requestHeaderBytesSent)
&& decoder.decode(metrics.requestBodyBytesSent)
&& decoder.decode(metrics.responseHeaderBytesReceived)
&& decoder.decode(metrics.responseBodyBytesReceived)
&& decoder.decode(metrics.responseBodyDecodedSize);
}
}
namespace WTF {
namespace Persistence {
template<> struct Coder<std::optional<WebCore::NetworkLoadPriority>> {
static NO_RETURN_DUE_TO_ASSERT void encode(Encoder&, const std::optional<WebCore::NetworkLoadPriority>&)
{
ASSERT_NOT_REACHED();
}
static bool decode(Decoder&, std::optional<WebCore::NetworkLoadPriority>&)
{
ASSERT_NOT_REACHED();
return false;
}
};
}}