diff options
Diffstat (limited to 'netwerk/protocol/http/NetworkMarker.cpp')
-rw-r--r-- | netwerk/protocol/http/NetworkMarker.cpp | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/netwerk/protocol/http/NetworkMarker.cpp b/netwerk/protocol/http/NetworkMarker.cpp new file mode 100644 index 0000000000..ece1845fef --- /dev/null +++ b/netwerk/protocol/http/NetworkMarker.cpp @@ -0,0 +1,188 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set expandtab ts=4 sw=2 sts=2 cin: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "NetworkMarker.h" + +#include "HttpBaseChannel.h" +#include "nsIChannelEventSink.h" + +namespace mozilla { +namespace net { + +static constexpr net::TimingStruct scEmptyNetTimingStruct; + +void profiler_add_network_marker( + nsIURI* aURI, const nsACString& aRequestMethod, int32_t aPriority, + uint64_t aChannelId, NetworkLoadType aType, mozilla::TimeStamp aStart, + mozilla::TimeStamp aEnd, int64_t aCount, + mozilla::net::CacheDisposition aCacheDisposition, uint64_t aInnerWindowID, + bool aIsPrivateBrowsing, const mozilla::net::TimingStruct* aTimings, + UniquePtr<ProfileChunkedBuffer> aSource, + const Maybe<nsDependentCString>& aContentType, nsIURI* aRedirectURI, + uint32_t aRedirectFlags, uint64_t aRedirectChannelId) { + if (!profiler_thread_is_being_profiled_for_markers()) { + return; + } + + nsAutoCStringN<2048> name; + name.AppendASCII("Load "); + // top 32 bits are process id of the load + name.AppendInt(aChannelId & 0xFFFFFFFFu); + + // These can do allocations/frees/etc; avoid if not active + nsAutoCStringN<2048> spec; + if (aURI) { + aURI->GetAsciiSpec(spec); + name.AppendASCII(": "); + name.Append(spec); + } + + nsAutoCString redirect_spec; + if (aRedirectURI) { + aRedirectURI->GetAsciiSpec(redirect_spec); + } + + struct NetworkMarker { + static constexpr Span<const char> MarkerTypeName() { + return MakeStringSpan("Network"); + } + static void StreamJSONMarkerData( + baseprofiler::SpliceableJSONWriter& aWriter, mozilla::TimeStamp aStart, + mozilla::TimeStamp aEnd, int64_t aID, const ProfilerString8View& aURI, + const ProfilerString8View& aRequestMethod, NetworkLoadType aType, + int32_t aPri, int64_t aCount, net::CacheDisposition aCacheDisposition, + bool aIsPrivateBrowsing, const net::TimingStruct& aTimings, + const ProfilerString8View& aRedirectURI, + const ProfilerString8View& aContentType, uint32_t aRedirectFlags, + int64_t aRedirectChannelId) { + // This payload still streams a startTime and endTime property because it + // made the migration to MarkerTiming on the front-end easier. + aWriter.TimeProperty("startTime", aStart); + aWriter.TimeProperty("endTime", aEnd); + + aWriter.IntProperty("id", aID); + aWriter.StringProperty("status", GetNetworkState(aType)); + if (Span<const char> cacheString = GetCacheState(aCacheDisposition); + !cacheString.IsEmpty()) { + aWriter.StringProperty("cache", cacheString); + } + aWriter.IntProperty("pri", aPri); + if (aCount > 0) { + aWriter.IntProperty("count", aCount); + } + if (aURI.Length() != 0) { + aWriter.StringProperty("URI", aURI); + } + if (aRedirectURI.Length() != 0) { + aWriter.StringProperty("RedirectURI", aRedirectURI); + aWriter.StringProperty("redirectType", getRedirectType(aRedirectFlags)); + aWriter.BoolProperty( + "isHttpToHttpsRedirect", + aRedirectFlags & nsIChannelEventSink::REDIRECT_STS_UPGRADE); + + if (aRedirectChannelId != 0) { + aWriter.IntProperty("redirectId", aRedirectChannelId); + } + } + + aWriter.StringProperty("requestMethod", aRequestMethod); + + if (aContentType.Length() != 0) { + aWriter.StringProperty("contentType", aContentType); + } else { + aWriter.NullProperty("contentType"); + } + + if (aIsPrivateBrowsing) { + aWriter.BoolProperty("isPrivateBrowsing", aIsPrivateBrowsing); + } + + if (aType != NetworkLoadType::LOAD_START) { + aWriter.TimeProperty("domainLookupStart", aTimings.domainLookupStart); + aWriter.TimeProperty("domainLookupEnd", aTimings.domainLookupEnd); + aWriter.TimeProperty("connectStart", aTimings.connectStart); + aWriter.TimeProperty("tcpConnectEnd", aTimings.tcpConnectEnd); + aWriter.TimeProperty("secureConnectionStart", + aTimings.secureConnectionStart); + aWriter.TimeProperty("connectEnd", aTimings.connectEnd); + aWriter.TimeProperty("requestStart", aTimings.requestStart); + aWriter.TimeProperty("responseStart", aTimings.responseStart); + aWriter.TimeProperty("responseEnd", aTimings.responseEnd); + } + } + static MarkerSchema MarkerTypeDisplay() { + return MarkerSchema::SpecialFrontendLocation{}; + } + + private: + static Span<const char> GetNetworkState(NetworkLoadType aType) { + switch (aType) { + case NetworkLoadType::LOAD_START: + return MakeStringSpan("STATUS_START"); + case NetworkLoadType::LOAD_STOP: + return MakeStringSpan("STATUS_STOP"); + case NetworkLoadType::LOAD_REDIRECT: + return MakeStringSpan("STATUS_REDIRECT"); + case NetworkLoadType::LOAD_CANCEL: + return MakeStringSpan("STATUS_CANCEL"); + default: + MOZ_ASSERT(false, "Unexpected NetworkLoadType enum value."); + return MakeStringSpan(""); + } + } + + static Span<const char> GetCacheState( + net::CacheDisposition aCacheDisposition) { + switch (aCacheDisposition) { + case net::kCacheUnresolved: + return MakeStringSpan("Unresolved"); + case net::kCacheHit: + return MakeStringSpan("Hit"); + case net::kCacheHitViaReval: + return MakeStringSpan("HitViaReval"); + case net::kCacheMissedViaReval: + return MakeStringSpan("MissedViaReval"); + case net::kCacheMissed: + return MakeStringSpan("Missed"); + case net::kCacheUnknown: + return MakeStringSpan(""); + default: + MOZ_ASSERT(false, "Unexpected CacheDisposition enum value."); + return MakeStringSpan(""); + } + } + + static Span<const char> getRedirectType(uint32_t aRedirectFlags) { + MOZ_ASSERT(aRedirectFlags != 0, "aRedirectFlags should be non-zero"); + if (aRedirectFlags & nsIChannelEventSink::REDIRECT_TEMPORARY) { + return MakeStringSpan("Temporary"); + } + if (aRedirectFlags & nsIChannelEventSink::REDIRECT_PERMANENT) { + return MakeStringSpan("Permanent"); + } + if (aRedirectFlags & nsIChannelEventSink::REDIRECT_INTERNAL) { + return MakeStringSpan("Internal"); + } + MOZ_ASSERT(false, "Couldn't find a redirect type from aRedirectFlags"); + return MakeStringSpan(""); + } + }; + + profiler_add_marker( + name, geckoprofiler::category::NETWORK, + {MarkerTiming::Interval(aStart, aEnd), + MarkerStack::TakeBacktrace(std::move(aSource)), + MarkerInnerWindowId(aInnerWindowID)}, + NetworkMarker{}, aStart, aEnd, static_cast<int64_t>(aChannelId), spec, + aRequestMethod, aType, aPriority, aCount, aCacheDisposition, + aIsPrivateBrowsing, aTimings ? *aTimings : scEmptyNetTimingStruct, + redirect_spec, + aContentType ? ProfilerString8View(*aContentType) : ProfilerString8View(), + aRedirectFlags, aRedirectChannelId); +} + +} // namespace net +} // namespace mozilla |