Diff
Modified: trunk/LayoutTests/ChangeLog (213681 => 213682)
--- trunk/LayoutTests/ChangeLog 2017-03-09 23:21:19 UTC (rev 213681)
+++ trunk/LayoutTests/ChangeLog 2017-03-09 23:44:12 UTC (rev 213682)
@@ -1,3 +1,14 @@
+2017-03-09 Joseph Pecoraro <[email protected]>
+
+ Web Inspector: Show HTTP protocol version and other Network Load Metrics (IP Address, Priority, Connection ID)
+ https://bugs.webkit.org/show_bug.cgi?id=29687
+ <rdar://problem/19281586>
+
+ Reviewed by Matt Baker and Brian Burg.
+
+ * http/tests/inspector/network/resource-metrics-expected.txt: Added.
+ * http/tests/inspector/network/resource-metrics.html: Added.
+
2017-03-09 Ryan Haddad <[email protected]>
Add iOS baseline for compositing/contents-format/subpixel-antialiased-text-traversal.
Added: trunk/LayoutTests/http/tests/inspector/network/resource-metrics-expected.txt (0 => 213682)
--- trunk/LayoutTests/http/tests/inspector/network/resource-metrics-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/inspector/network/resource-metrics-expected.txt 2017-03-09 23:44:12 UTC (rev 213682)
@@ -0,0 +1,13 @@
+Test for Resource metrics (protocol, priority, remoteAddress, connectionIdentifier).
+
+
+== Running test suite: Resource.Metrics
+-- Running test case: Resource.Metrics.Network
+PASS: Resource should be created.
+PASS: Resource should receive a Response.
+PASS: statusCode should be 200.
+PASS: protocol should be null or http/1.1.
+PASS: priority should be Symbol(unknown) or Symbol(medium).
+PASS: remoteAddressType should be null or a string.
+PASS: connectionIdentifierType should be null or string.
+
Added: trunk/LayoutTests/http/tests/inspector/network/resource-metrics.html (0 => 213682)
--- trunk/LayoutTests/http/tests/inspector/network/resource-metrics.html (rev 0)
+++ trunk/LayoutTests/http/tests/inspector/network/resource-metrics.html 2017-03-09 23:44:12 UTC (rev 213682)
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<script src=""
+<script>
+function triggerNetworkLoad() {
+ let url = "" + Math.random();
+ fetch(url).then(() => {
+ TestPage.dispatchEventToFrontend("LoadComplete");
+ });
+}
+
+function test()
+{
+ let suite = InspectorTest.createAsyncSuite("Resource.Metrics");
+
+ function addTestCase({name, description, _expression_, statusCode, protocol, priority, remoteAddressType, connectionIdentifierType}) {
+ suite.addTestCase({
+ name, description,
+ test(resolve, reject) {
+ InspectorTest.evaluateInPage(_expression_);
+ Promise.all([
+ WebInspector.Frame.awaitEvent(WebInspector.Frame.Event.ResourceWasAdded),
+ WebInspector.Resource.awaitEvent(WebInspector.Resource.Event.ResponseReceived),
+ InspectorTest.awaitEvent("LoadComplete"),
+ ]).then(([resourceWasAddedEvent, responseReceivedEvent, loadCompleteEvent]) => {
+ let resource = resourceWasAddedEvent.data.resource;
+ InspectorTest.expectThat(resource instanceof WebInspector.Resource, "Resource should be created.");
+ InspectorTest.expectEqual(resource, responseReceivedEvent.target, "Resource should receive a Response.");
+ InspectorTest.expectEqual(resource.statusCode, statusCode, `statusCode should be ${statusCode}.`);
+ InspectorTest.expectThat(resource.protocol === null || resource.protocol === protocol, `protocol should be null or ${protocol}.`);
+ InspectorTest.expectThat(resource.priority === WebInspector.Resource.NetworkPriority.Unknown || resource.priority === priority, `priority should be ${String(WebInspector.Resource.NetworkPriority.Unknown)} or ${String(priority)}.`);
+ InspectorTest.expectThat(resource.remoteAddress === null || typeof resource.protocol === remoteAddressType, `remoteAddressType should be null or a ${remoteAddressType}.`);
+ InspectorTest.expectThat(resource.connectionIdentifier === null || typeof resource.protocol === connectionIdentifierType, `connectionIdentifierType should be null or ${connectionIdentifierType}.`);
+ }).then(resolve, reject);
+ }
+ });
+ }
+
+ addTestCase({
+ name: "Resource.Metrics.Network",
+ description: "Load a resource from the network by giving a random URL should have metrics.",
+ _expression_: `triggerNetworkLoad()`,
+ statusCode: 200,
+ protocol: "http/1.1",
+ priority: WebInspector.Resource.NetworkPriority.Medium,
+ remoteAddressType: "string",
+ connectionIdentifierType: "string",
+ });
+
+ suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body _onload_="runTest()">
+<p>Test for Resource metrics (protocol, priority, remoteAddress, connectionIdentifier).</p>
+</body>
+</html>
Modified: trunk/Source/_javascript_Core/ChangeLog (213681 => 213682)
--- trunk/Source/_javascript_Core/ChangeLog 2017-03-09 23:21:19 UTC (rev 213681)
+++ trunk/Source/_javascript_Core/ChangeLog 2017-03-09 23:44:12 UTC (rev 213682)
@@ -1,3 +1,14 @@
+2017-03-09 Joseph Pecoraro <[email protected]>
+
+ Web Inspector: Show HTTP protocol version and other Network Load Metrics (IP Address, Priority, Connection ID)
+ https://bugs.webkit.org/show_bug.cgi?id=29687
+ <rdar://problem/19281586>
+
+ Reviewed by Matt Baker and Brian Burg.
+
+ * inspector/protocol/Network.json:
+ Add metrics object with optional properties to loadingFinished event.
+
2017-03-09 Youenn Fablet <[email protected]>
Minimal build is broken
Modified: trunk/Source/_javascript_Core/inspector/protocol/Network.json (213681 => 213682)
--- trunk/Source/_javascript_Core/inspector/protocol/Network.json 2017-03-09 23:21:19 UTC (rev 213681)
+++ trunk/Source/_javascript_Core/inspector/protocol/Network.json 2017-03-09 23:44:12 UTC (rev 213682)
@@ -77,6 +77,17 @@
]
},
{
+ "id": "Metrics",
+ "type": "object",
+ "description": "Network load metrics.",
+ "properties": [
+ { "name": "protocol", "type": "string", "optional": true, "description": "Network protocol. ALPN Protocol ID Identification Sequence, as per RFC 7301 (for example, http/2, http/1.1, spdy/3.1)" },
+ { "name": "priority", "type": "string", "enum": ["low", "medium", "high"], "optional": true, "description": "Network priority." },
+ { "name": "connectionIdentifier", "type": "string", "optional": true, "description": "Connection identifier." },
+ { "name": "remoteAddress", "type": "string", "optional": true, "description": "Remote IP address." }
+ ]
+ },
+ {
"id": "WebSocketRequest",
"type": "object",
"description": "WebSocket request data.",
@@ -229,7 +240,8 @@
"parameters": [
{ "name": "requestId", "$ref": "RequestId", "description": "Request identifier." },
{ "name": "timestamp", "$ref": "Timestamp", "description": "Timestamp." },
- { "name": "sourceMapURL", "type": "string", "optional": true, "description": "URL of source map associated with this resource (if any)." }
+ { "name": "sourceMapURL", "type": "string", "optional": true, "description": "URL of source map associated with this resource (if any)." },
+ { "name": "metrics", "$ref": "Metrics", "optional": true, "description": "Network metrics." }
]
},
{
Modified: trunk/Source/WebCore/ChangeLog (213681 => 213682)
--- trunk/Source/WebCore/ChangeLog 2017-03-09 23:21:19 UTC (rev 213681)
+++ trunk/Source/WebCore/ChangeLog 2017-03-09 23:44:12 UTC (rev 213682)
@@ -1,3 +1,55 @@
+2017-03-09 Joseph Pecoraro <[email protected]>
+
+ Web Inspector: Show HTTP protocol version and other Network Load Metrics (IP Address, Priority, Connection ID)
+ https://bugs.webkit.org/show_bug.cgi?id=29687
+ <rdar://problem/19281586>
+
+ Reviewed by Matt Baker and Brian Burg.
+
+ Test: http/tests/inspector/network/resource-metrics.html
+
+ * inspector/InspectorNetworkAgent.cpp:
+ (WebCore::toProtocol):
+ (WebCore::InspectorNetworkAgent::buildObjectForMetrics):
+ (WebCore::InspectorNetworkAgent::didFinishLoading):
+ Send metrics at didFinishLoading time, we do not have all of
+ these at didReceiveResponse time.
+
+ * inspector/InspectorInstrumentation.cpp:
+ (WebCore::InspectorInstrumentation::didFinishLoadingImpl):
+ * inspector/InspectorInstrumentation.h:
+ (WebCore::InspectorInstrumentation::didFinishLoading):
+ * inspector/InspectorNetworkAgent.h:
+ * loader/CrossOriginPreflightChecker.cpp:
+ (WebCore::CrossOriginPreflightChecker::validatePreflightResponse):
+ * loader/DocumentLoader.cpp:
+ (WebCore::DocumentLoader::finishedLoading):
+ * loader/ResourceLoadNotifier.cpp:
+ (WebCore::ResourceLoadNotifier::didFinishLoad):
+ (WebCore::ResourceLoadNotifier::dispatchDidFinishLoading):
+ (WebCore::ResourceLoadNotifier::sendRemainingDelegateMessages):
+ * loader/ResourceLoadNotifier.h:
+ * loader/SubresourceLoader.cpp:
+ (WebCore::SubresourceLoader::didFinishLoading):
+ * loader/appcache/ApplicationCacheGroup.cpp:
+ (WebCore::ApplicationCacheGroup::didFinishLoading):
+ Include or pass on NetworkLoadMetrics to Web Inspector.
+
+ * platform/network/NetworkLoadMetrics.h:
+ (WebCore::NetworkLoadMetrics::isolatedCopy):
+ (WebCore::NetworkLoadMetrics::reset):
+ (WebCore::NetworkLoadMetrics::operator==):
+ (WebCore::NetworkLoadMetrics::encode):
+ (WebCore::NetworkLoadMetrics::decode):
+ Add new optional metrics properties.
+
+ (WTF::Persistence::Coder<std::optional<WebCore::NetworkLoadPriority>>::encode):
+ (WTF::Persistence::Coder<std::optional<WebCore::NetworkLoadPriority>>::decode):
+ We never encode this but this is needed for the compiler.
+
+ * platform/spi/cocoa/NSURLConnectionSPI.h:
+ New SPI for NSURLSessionTaskTransactionMetrics details.
+
2017-03-09 Anders Carlsson <[email protected]>
Use the right conditional.
Modified: trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp (213681 => 213682)
--- trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp 2017-03-09 23:21:19 UTC (rev 213681)
+++ trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp 2017-03-09 23:44:12 UTC (rev 213682)
@@ -599,13 +599,13 @@
networkAgent->didReceiveData(identifier, data, dataLength, encodedDataLength);
}
-void InspectorInstrumentation::didFinishLoadingImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier, DocumentLoader* loader)
+void InspectorInstrumentation::didFinishLoadingImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier, DocumentLoader* loader, const NetworkLoadMetrics& networkLoadMetrics)
{
if (!loader)
return;
if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent())
- networkAgent->didFinishLoading(identifier, *loader);
+ networkAgent->didFinishLoading(identifier, *loader, networkLoadMetrics);
}
void InspectorInstrumentation::didFailLoadingImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier, DocumentLoader* loader, const ResourceError& error)
Modified: trunk/Source/WebCore/inspector/InspectorInstrumentation.h (213681 => 213682)
--- trunk/Source/WebCore/inspector/InspectorInstrumentation.h 2017-03-09 23:21:19 UTC (rev 213681)
+++ trunk/Source/WebCore/inspector/InspectorInstrumentation.h 2017-03-09 23:44:12 UTC (rev 213682)
@@ -71,6 +71,7 @@
class HTTPHeaderMap;
class InspectorTimelineAgent;
class InstrumentingAgents;
+class NetworkLoadMetrics;
class Node;
class PseudoElement;
class RenderLayer;
@@ -156,7 +157,7 @@
static void didReceiveResourceResponse(Frame&, unsigned long identifier, DocumentLoader*, const ResourceResponse&, ResourceLoader*);
static void didReceiveThreadableLoaderResponse(DocumentThreadableLoader&, unsigned long identifier);
static void didReceiveData(Frame*, unsigned long identifier, const char* data, int dataLength, int encodedDataLength);
- static void didFinishLoading(Frame*, DocumentLoader*, unsigned long identifier);
+ static void didFinishLoading(Frame*, DocumentLoader*, unsigned long identifier, const NetworkLoadMetrics&);
static void didFailLoading(Frame*, DocumentLoader*, unsigned long identifier, const ResourceError&);
static void continueAfterXFrameOptionsDenied(Frame&, unsigned long identifier, DocumentLoader&, const ResourceResponse&);
static void continueWithPolicyDownload(Frame&, unsigned long identifier, DocumentLoader&, const ResourceResponse&);
@@ -326,7 +327,7 @@
static void didReceiveResourceResponseImpl(InstrumentingAgents&, unsigned long identifier, DocumentLoader*, const ResourceResponse&, ResourceLoader*);
static void didReceiveThreadableLoaderResponseImpl(InstrumentingAgents&, DocumentThreadableLoader&, unsigned long identifier);
static void didReceiveDataImpl(InstrumentingAgents&, unsigned long identifier, const char* data, int dataLength, int encodedDataLength);
- static void didFinishLoadingImpl(InstrumentingAgents&, unsigned long identifier, DocumentLoader*);
+ static void didFinishLoadingImpl(InstrumentingAgents&, unsigned long identifier, DocumentLoader*, const NetworkLoadMetrics&);
static void didFailLoadingImpl(InstrumentingAgents&, unsigned long identifier, DocumentLoader*, const ResourceError&);
static void didFinishXHRLoadingImpl(InstrumentingAgents&, unsigned long identifier, std::optional<String> decodedText, const String& url, const String& sendURL, unsigned sendLineNumber, unsigned sendColumnNumber);
static void willLoadXHRSynchronouslyImpl(InstrumentingAgents&);
@@ -857,10 +858,10 @@
didReceiveDataImpl(*instrumentingAgents, identifier, data, dataLength, encodedDataLength);
}
-inline void InspectorInstrumentation::didFinishLoading(Frame* frame, DocumentLoader* loader, unsigned long identifier)
+inline void InspectorInstrumentation::didFinishLoading(Frame* frame, DocumentLoader* loader, unsigned long identifier, const NetworkLoadMetrics& networkLoadMetrics)
{
if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame))
- didFinishLoadingImpl(*instrumentingAgents, identifier, loader);
+ didFinishLoadingImpl(*instrumentingAgents, identifier, loader, networkLoadMetrics);
}
inline void InspectorInstrumentation::didFailLoading(Frame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceError& error)
Modified: trunk/Source/WebCore/inspector/InspectorNetworkAgent.cpp (213681 => 213682)
--- trunk/Source/WebCore/inspector/InspectorNetworkAgent.cpp 2017-03-09 23:21:19 UTC (rev 213681)
+++ trunk/Source/WebCore/inspector/InspectorNetworkAgent.cpp 2017-03-09 23:44:12 UTC (rev 213682)
@@ -196,6 +196,37 @@
.release();
}
+static Inspector::Protocol::Network::Metrics::Priority toProtocol(NetworkLoadPriority priority)
+{
+ switch (priority) {
+ case NetworkLoadPriority::Low:
+ return Inspector::Protocol::Network::Metrics::Priority::Low;
+ case NetworkLoadPriority::Medium:
+ return Inspector::Protocol::Network::Metrics::Priority::Medium;
+ case NetworkLoadPriority::High:
+ return Inspector::Protocol::Network::Metrics::Priority::High;
+ }
+
+ ASSERT_NOT_REACHED();
+ return Inspector::Protocol::Network::Metrics::Priority::Medium;
+}
+
+Ref<Inspector::Protocol::Network::Metrics> InspectorNetworkAgent::buildObjectForMetrics(const NetworkLoadMetrics& networkLoadMetrics)
+{
+ auto metrics = Inspector::Protocol::Network::Metrics::create().release();
+
+ if (!networkLoadMetrics.protocol.isNull())
+ metrics->setProtocol(networkLoadMetrics.protocol);
+ if (networkLoadMetrics.priority)
+ metrics->setPriority(toProtocol(*networkLoadMetrics.priority));
+ if (networkLoadMetrics.remoteAddress)
+ metrics->setRemoteAddress(*networkLoadMetrics.remoteAddress);
+ if (networkLoadMetrics.connectionIdentifier)
+ metrics->setConnectionIdentifier(*networkLoadMetrics.connectionIdentifier);
+
+ return metrics;
+}
+
static Ref<Inspector::Protocol::Network::Request> buildObjectForResourceRequest(const ResourceRequest& request)
{
auto requestObject = Inspector::Protocol::Network::Request::create()
@@ -391,12 +422,12 @@
m_frontendDispatcher->dataReceived(requestId, timestamp(), dataLength, encodedDataLength);
}
-void InspectorNetworkAgent::didFinishLoading(unsigned long identifier, DocumentLoader& loader)
+void InspectorNetworkAgent::didFinishLoading(unsigned long identifier, DocumentLoader& loader, const NetworkLoadMetrics& networkLoadMetrics)
{
if (m_hiddenRequestIdentifiers.remove(identifier))
return;
- // FIXME: Inspector should make use of NetworkLoadMetrics.
+ // FIXME: We should use the NetworkLoadMetrics's responseEnd to match ResourceTiming.
double elapsedFinishTime = timestamp();
String requestId = IdentifiersFactory::requestId(identifier);
@@ -410,7 +441,9 @@
if (resourceData && resourceData->cachedResource())
sourceMappingURL = InspectorPageAgent::sourceMapURLForResource(resourceData->cachedResource());
- m_frontendDispatcher->loadingFinished(requestId, elapsedFinishTime, !sourceMappingURL.isEmpty() ? &sourceMappingURL : nullptr);
+ RefPtr<Inspector::Protocol::Network::Metrics> metrics = buildObjectForMetrics(networkLoadMetrics);
+
+ m_frontendDispatcher->loadingFinished(requestId, elapsedFinishTime, !sourceMappingURL.isEmpty() ? &sourceMappingURL : nullptr, metrics);
}
void InspectorNetworkAgent::didFailLoading(unsigned long identifier, DocumentLoader& loader, const ResourceError& error)
Modified: trunk/Source/WebCore/inspector/InspectorNetworkAgent.h (213681 => 213682)
--- trunk/Source/WebCore/inspector/InspectorNetworkAgent.h 2017-03-09 23:21:19 UTC (rev 213681)
+++ trunk/Source/WebCore/inspector/InspectorNetworkAgent.h 2017-03-09 23:44:12 UTC (rev 213682)
@@ -78,7 +78,7 @@
void willSendRequest(unsigned long identifier, DocumentLoader&, ResourceRequest&, const ResourceResponse& redirectResponse);
void didReceiveResponse(unsigned long identifier, DocumentLoader&, const ResourceResponse&, ResourceLoader*);
void didReceiveData(unsigned long identifier, const char* data, int dataLength, int encodedDataLength);
- void didFinishLoading(unsigned long identifier, DocumentLoader&);
+ void didFinishLoading(unsigned long identifier, DocumentLoader&, const NetworkLoadMetrics&);
void didFailLoading(unsigned long identifier, DocumentLoader&, const ResourceError&);
void didLoadResourceFromMemoryCache(DocumentLoader&, CachedResource&);
void didReceiveThreadableLoaderResponse(unsigned long identifier, DocumentThreadableLoader&);
@@ -117,6 +117,7 @@
void enable();
Ref<Inspector::Protocol::Network::ResourceTiming> buildObjectForTiming(const NetworkLoadMetrics&, ResourceLoader&);
+ Ref<Inspector::Protocol::Network::Metrics> buildObjectForMetrics(const NetworkLoadMetrics&);
RefPtr<Inspector::Protocol::Network::Response> buildObjectForResourceResponse(const ResourceResponse&, ResourceLoader*);
Ref<Inspector::Protocol::Network::CachedResource> buildObjectForCachedResource(CachedResource*);
Modified: trunk/Source/WebCore/loader/CrossOriginPreflightChecker.cpp (213681 => 213682)
--- trunk/Source/WebCore/loader/CrossOriginPreflightChecker.cpp 2017-03-09 23:21:19 UTC (rev 213681)
+++ trunk/Source/WebCore/loader/CrossOriginPreflightChecker.cpp 2017-03-09 23:44:12 UTC (rev 213682)
@@ -39,6 +39,7 @@
#include "CrossOriginPreflightResultCache.h"
#include "DocumentThreadableLoader.h"
#include "InspectorInstrumentation.h"
+#include "NetworkLoadMetrics.h"
#include "RuntimeEnabledFeatures.h"
namespace WebCore {
@@ -82,8 +83,9 @@
// FIXME: <https://webkit.org/b/164889> Web Inspector: Show Preflight Request information in inspector
// This is only showing success preflight requests and responses but we should show network events
// for preflight failures and distinguish them better from non-preflight requests.
+ NetworkLoadMetrics emptyMetrics;
InspectorInstrumentation::didReceiveResourceResponse(*frame, identifier, frame->loader().documentLoader(), response, nullptr);
- InspectorInstrumentation::didFinishLoading(frame, frame->loader().documentLoader(), identifier);
+ InspectorInstrumentation::didFinishLoading(frame, frame->loader().documentLoader(), identifier, emptyMetrics);
CrossOriginPreflightResultCache::singleton().appendEntry(loader.securityOrigin().toString(), request.url(), WTFMove(result));
loader.preflightSuccess(WTFMove(request));
Modified: trunk/Source/WebCore/loader/DocumentLoader.cpp (213681 => 213682)
--- trunk/Source/WebCore/loader/DocumentLoader.cpp 2017-03-09 23:21:19 UTC (rev 213681)
+++ trunk/Source/WebCore/loader/DocumentLoader.cpp 2017-03-09 23:44:12 UTC (rev 213682)
@@ -62,6 +62,7 @@
#include "Logging.h"
#include "MainFrame.h"
#include "MemoryCache.h"
+#include "NetworkLoadMetrics.h"
#include "Page.h"
#include "PolicyChecker.h"
#include "ProgressTracker.h"
@@ -390,9 +391,10 @@
// being finished). Clear m_identifierForLoadWithoutResourceLoader
// before calling dispatchDidFinishLoading so that we don't later try to
// cancel the already-finished substitute load.
+ NetworkLoadMetrics emptyMetrics;
unsigned long identifier = m_identifierForLoadWithoutResourceLoader;
m_identifierForLoadWithoutResourceLoader = 0;
- frameLoader()->notifier().dispatchDidFinishLoading(this, identifier);
+ frameLoader()->notifier().dispatchDidFinishLoading(this, identifier, emptyMetrics);
}
maybeFinishLoadingMultipartContent();
Modified: trunk/Source/WebCore/loader/ResourceLoadNotifier.cpp (213681 => 213682)
--- trunk/Source/WebCore/loader/ResourceLoadNotifier.cpp 2017-03-09 23:21:19 UTC (rev 213681)
+++ trunk/Source/WebCore/loader/ResourceLoadNotifier.cpp 2017-03-09 23:44:12 UTC (rev 213682)
@@ -87,14 +87,12 @@
dispatchDidReceiveData(loader->documentLoader(), loader->identifier(), data, dataLength, encodedDataLength);
}
-void ResourceLoadNotifier::didFinishLoad(ResourceLoader* loader, const NetworkLoadMetrics&)
+void ResourceLoadNotifier::didFinishLoad(ResourceLoader* loader, const NetworkLoadMetrics& networkLoadMetrics)
{
if (Page* page = m_frame.page())
page->progress().completeProgress(loader->identifier());
- // FIXME: Inspector should make use of NetworkLoadMetrics.
-
- dispatchDidFinishLoading(loader->documentLoader(), loader->identifier());
+ dispatchDidFinishLoading(loader->documentLoader(), loader->identifier(), networkLoadMetrics);
}
void ResourceLoadNotifier::didFailToLoad(ResourceLoader* loader, const ResourceError& error)
@@ -162,13 +160,13 @@
InspectorInstrumentation::didReceiveData(&m_frame, identifier, data, dataLength, encodedDataLength);
}
-void ResourceLoadNotifier::dispatchDidFinishLoading(DocumentLoader* loader, unsigned long identifier)
+void ResourceLoadNotifier::dispatchDidFinishLoading(DocumentLoader* loader, unsigned long identifier, const NetworkLoadMetrics& networkLoadMetrics)
{
// Notifying the FrameLoaderClient may cause the frame to be destroyed.
Ref<Frame> protect(m_frame);
m_frame.loader().client().dispatchDidFinishLoading(loader, identifier);
- InspectorInstrumentation::didFinishLoading(&m_frame, loader, identifier);
+ InspectorInstrumentation::didFinishLoading(&m_frame, loader, identifier, networkLoadMetrics);
}
void ResourceLoadNotifier::dispatchDidFailLoading(DocumentLoader* loader, unsigned long identifier, const ResourceError& error)
@@ -196,9 +194,10 @@
if (dataLength > 0)
dispatchDidReceiveData(loader, identifier, data, dataLength, encodedDataLength);
- if (error.isNull())
- dispatchDidFinishLoading(loader, identifier);
- else
+ if (error.isNull()) {
+ NetworkLoadMetrics emptyMetrics;
+ dispatchDidFinishLoading(loader, identifier, emptyMetrics);
+ } else
dispatchDidFailLoading(loader, identifier, error);
}
Modified: trunk/Source/WebCore/loader/ResourceLoadNotifier.h (213681 => 213682)
--- trunk/Source/WebCore/loader/ResourceLoadNotifier.h 2017-03-09 23:21:19 UTC (rev 213681)
+++ trunk/Source/WebCore/loader/ResourceLoadNotifier.h 2017-03-09 23:44:12 UTC (rev 213682)
@@ -60,7 +60,7 @@
void dispatchWillSendRequest(DocumentLoader*, unsigned long identifier, ResourceRequest&, const ResourceResponse& redirectResponse);
void dispatchDidReceiveResponse(DocumentLoader*, unsigned long identifier, const ResourceResponse&, ResourceLoader* = nullptr);
void dispatchDidReceiveData(DocumentLoader*, unsigned long identifier, const char* data, int dataLength, int encodedDataLength);
- void dispatchDidFinishLoading(DocumentLoader*, unsigned long identifier);
+ void dispatchDidFinishLoading(DocumentLoader*, unsigned long identifier, const NetworkLoadMetrics&);
void dispatchDidFailLoading(DocumentLoader*, unsigned long identifier, const ResourceError&);
void sendRemainingDelegateMessages(DocumentLoader*, unsigned long identifier, const ResourceRequest&, const ResourceResponse&, const char* data, int dataLength, int encodedDataLength, const ResourceError&);
Modified: trunk/Source/WebCore/loader/SubresourceLoader.cpp (213681 => 213682)
--- trunk/Source/WebCore/loader/SubresourceLoader.cpp 2017-03-09 23:21:19 UTC (rev 213681)
+++ trunk/Source/WebCore/loader/SubresourceLoader.cpp 2017-03-09 23:44:12 UTC (rev 213682)
@@ -559,7 +559,7 @@
return;
m_resource->finish();
ASSERT(!reachedTerminalState());
- didFinishLoadingOnePart(m_resource->response().deprecatedNetworkLoadMetrics());
+ didFinishLoadingOnePart(networkLoadMetrics);
notifyDone();
if (reachedTerminalState())
return;
Modified: trunk/Source/WebCore/loader/appcache/ApplicationCacheGroup.cpp (213681 => 213682)
--- trunk/Source/WebCore/loader/appcache/ApplicationCacheGroup.cpp 2017-03-09 23:21:19 UTC (rev 213681)
+++ trunk/Source/WebCore/loader/appcache/ApplicationCacheGroup.cpp 2017-03-09 23:44:12 UTC (rev 213682)
@@ -41,6 +41,7 @@
#include "HTTPHeaderNames.h"
#include "InspectorInstrumentation.h"
#include "ManifestParser.h"
+#include "NetworkLoadMetrics.h"
#include "Page.h"
#include "ProgressTracker.h"
#include "ResourceHandle.h"
@@ -572,7 +573,9 @@
void ApplicationCacheGroup::didFinishLoading(ResourceHandle* handle)
{
- InspectorInstrumentation::didFinishLoading(m_frame, m_frame->loader().documentLoader(), m_currentResourceIdentifier);
+ // FIXME: We should have NetworkLoadMetrics for ApplicationCache loads.
+ NetworkLoadMetrics emptyMetrics;
+ InspectorInstrumentation::didFinishLoading(m_frame, m_frame->loader().documentLoader(), m_currentResourceIdentifier, emptyMetrics);
if (handle == m_manifestHandle) {
didFinishLoadingManifest();
Modified: trunk/Source/WebCore/platform/network/NetworkLoadMetrics.h (213681 => 213682)
--- trunk/Source/WebCore/platform/network/NetworkLoadMetrics.h 2017-03-09 23:21:19 UTC (rev 213681)
+++ trunk/Source/WebCore/platform/network/NetworkLoadMetrics.h 2017-03-09 23:44:12 UTC (rev 213682)
@@ -26,7 +26,10 @@
#pragma once
+#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)
@@ -35,6 +38,12 @@
namespace WebCore {
+enum class NetworkLoadPriority {
+ Low,
+ Medium,
+ High,
+};
+
class NetworkLoadMetrics {
public:
NetworkLoadMetrics()
@@ -57,6 +66,13 @@
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;
+
return copy;
}
@@ -70,8 +86,11 @@
requestStart = Seconds(0);
responseStart = Seconds(0);
responseEnd = Seconds(0);
+ complete = false;
protocol = String();
- complete = false;
+ remoteAddress = std::nullopt;
+ connectionIdentifier = std::nullopt;
+ priority = std::nullopt;
}
bool operator==(const NetworkLoadMetrics& other) const
@@ -85,7 +104,10 @@
&& responseStart == other.responseStart
&& responseEnd == other.responseEnd
&& complete == other.complete
- && protocol == other.protocol;
+ && protocol == other.protocol
+ && remoteAddress == other.remoteAddress
+ && connectionIdentifier == other.connectionIdentifier
+ && priority == other.priority;
}
bool operator!=(const NetworkLoadMetrics& other) const
@@ -115,6 +137,10 @@
// ALPN Protocol ID: https://w3c.github.io/resource-timing/#bib-RFC7301
String protocol;
+
+ std::optional<String> remoteAddress;
+ std::optional<String> connectionIdentifier;
+ std::optional<NetworkLoadPriority> priority;
};
#if PLATFORM(COCOA)
@@ -138,21 +164,46 @@
encoder << responseEnd;
encoder << complete;
encoder << protocol;
+ encoder << remoteAddress;
+ encoder << connectionIdentifier;
+ encoder << priority;
}
template<class Decoder>
-bool NetworkLoadMetrics::decode(Decoder& decoder, NetworkLoadMetrics& timing)
+bool NetworkLoadMetrics::decode(Decoder& decoder, NetworkLoadMetrics& metrics)
{
- return decoder.decode(timing.domainLookupStart)
- && decoder.decode(timing.domainLookupEnd)
- && decoder.decode(timing.connectStart)
- && decoder.decode(timing.secureConnectionStart)
- && decoder.decode(timing.connectEnd)
- && decoder.decode(timing.requestStart)
- && decoder.decode(timing.responseStart)
- && decoder.decode(timing.responseEnd)
- && decoder.decode(timing.complete)
- && decoder.decode(timing.protocol);
+ 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);
}
-}
+} // namespace WebCore
+
+// NetworkLoadMetrics should not be stored by the WTF::Persistence::Decoder.
+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;
+ }
+};
+
+}} // namespace WTF::Persistence
Modified: trunk/Source/WebCore/platform/spi/cocoa/NSURLConnectionSPI.h (213681 => 213682)
--- trunk/Source/WebCore/platform/spi/cocoa/NSURLConnectionSPI.h 2017-03-09 23:21:19 UTC (rev 213681)
+++ trunk/Source/WebCore/platform/spi/cocoa/NSURLConnectionSPI.h 2017-03-09 23:44:12 UTC (rev 213682)
@@ -46,4 +46,11 @@
- (NSDictionary *)_timingData;
@end
+#if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300) || (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000)
+@interface NSURLSessionTaskTransactionMetrics ()
+@property (copy, readonly) NSString* _remoteAddressAndPort;
+@property (copy, readonly) NSUUID* _connectionIdentifier;
+@end
#endif
+
+#endif
Modified: trunk/Source/WebInspectorUI/ChangeLog (213681 => 213682)
--- trunk/Source/WebInspectorUI/ChangeLog 2017-03-09 23:21:19 UTC (rev 213681)
+++ trunk/Source/WebInspectorUI/ChangeLog 2017-03-09 23:44:12 UTC (rev 213682)
@@ -1,3 +1,68 @@
+2017-03-09 Joseph Pecoraro <[email protected]>
+
+ Web Inspector: Show HTTP protocol version and other Network Load Metrics (IP Address, Priority, Connection ID)
+ https://bugs.webkit.org/show_bug.cgi?id=29687
+ <rdar://problem/19281586>
+
+ Reviewed by Matt Baker and Brian Burg.
+
+ These columns are available in the Network DataGrids, but are
+ initially hidden. They can be shown by right clicking on the
+ table header and showing these columns. We are going to rework
+ the default list of visible columns later.
+
+ * Localizations/en.lproj/localizedStrings.js:
+ New localized strings for data grid headers and Low/Medium/High.
+
+ * UserInterface/Controllers/FrameResourceManager.js:
+ (WebInspector.FrameResourceManager.prototype.resourceRequestDidFinishLoading):
+ * UserInterface/Protocol/NetworkObserver.js:
+ (WebInspector.NetworkObserver.prototype.loadingFinished):
+ Pass metrics on to the Resource.
+
+ * UserInterface/Models/Resource.js:
+ (WebInspector.Resource):
+ (WebInspector.Resource.displayNameForType):
+ (WebInspector.Resource.responseSourceFromPayload):
+ (WebInspector.Resource.networkPriorityFromPayload):
+ (WebInspector.Resource.connectionIdentifierFromPayload):
+ (WebInspector.Resource.prototype.get protocol):
+ (WebInspector.Resource.prototype.get priority):
+ (WebInspector.Resource.prototype.get remoteAddress):
+ (WebInspector.Resource.prototype.get connectionIdentifier):
+ (WebInspector.Resource.prototype.updateWithMetrics):
+ Include metrics accessors and default values.
+
+ * UserInterface/Views/NetworkGridContentView.js:
+ (WebInspector.NetworkGridContentView):
+ * UserInterface/Views/NetworkTimelineView.js:
+ (WebInspector.NetworkTimelineView):
+ Add metrics columns if the backend may be sending them.
+
+ * UserInterface/Views/ResourceTimelineDataGridNode.js:
+ (WebInspector.ResourceTimelineDataGridNode.prototype.get data):
+ (WebInspector.ResourceTimelineDataGridNode.prototype.createCellContent):
+ (WebInspector.ResourceTimelineDataGridNode.prototype._displayNameForPriority):
+ (WebInspector.ResourceTimelineDataGridNode.prototype._cachedCellContent):
+ Display strings for new columns.
+
+ * UserInterface/Views/TimelineDataGridNode.js:
+ * UserInterface/Views/TimelineRecordBar.js:
+ (WebInspector.TimelineRecordBar.prototype.refresh):
+ Avoid assertions if Graph column is unavailable.
+
+ * UserInterface/Views/DataGrid.js:
+ (WebInspector.DataGrid):
+ (WebInspector.DataGrid.prototype.createSettings):
+ (WebInspector.DataGrid.prototype.setColumnVisible):
+ Better support for restoring user preference of initially
+ hidden columns which the user may have shown.
+
+ * UserInterface/Views/ResourceDetailsSidebarPanel.js:
+ (WebInspector.ResourceDetailsSidebarPanel):
+ (WebInspector.ResourceDetailsSidebarPanel.prototype._refreshRequestAndResponse):
+ Show the Protocol and Priority in the Resources sidebar.
+
2017-03-09 Nikita Vasilyev <[email protected]>
Web Inspector: Show individual messages in the content pane for a WebSocket
Modified: trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js (213681 => 213682)
--- trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js 2017-03-09 23:21:19 UTC (rev 213681)
+++ trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js 2017-03-09 23:44:12 UTC (rev 213682)
@@ -416,6 +416,7 @@
localizedStrings["Hide the navigation sidebar (%s)"] = "Hide the navigation sidebar (%s)";
localizedStrings["Hide type information"] = "Hide type information";
localizedStrings["Hierarchy Level"] = "Hierarchy Level";
+localizedStrings["High"] = "High";
localizedStrings["Highest: %s"] = "Highest: %s";
localizedStrings["Horizontal"] = "Horizontal";
localizedStrings["Host"] = "Host";
@@ -492,6 +493,7 @@
localizedStrings["Log Value"] = "Log Value";
localizedStrings["Log: "] = "Log: ";
localizedStrings["Logs"] = "Logs";
+localizedStrings["Low"] = "Low";
localizedStrings["Lowest: %s"] = "Lowest: %s";
localizedStrings["MIME Type"] = "MIME Type";
localizedStrings["Main"] = "Main";
@@ -505,6 +507,7 @@
localizedStrings["Maximum Size: %s"] = "Maximum Size: %s";
localizedStrings["Maximum maximum memory size in this recording"] = "Maximum maximum memory size in this recording";
localizedStrings["Media: "] = "Media: ";
+localizedStrings["Medium"] = "Medium";
localizedStrings["Memory"] = "Memory";
localizedStrings["Memory: %s"] = "Memory: %s";
localizedStrings["Message"] = "Message";
@@ -605,6 +608,7 @@
localizedStrings["Pretty print"] = "Pretty print";
localizedStrings["Primary Key"] = "Primary Key";
localizedStrings["Primary Key \u2014 %s"] = "Primary Key \u2014 %s";
+localizedStrings["Priority"] = "Priority";
localizedStrings["Probe _expression_"] = "Probe _expression_";
localizedStrings["Probe Sample Recorded"] = "Probe Sample Recorded";
localizedStrings["Probes"] = "Probes";
@@ -611,6 +615,7 @@
localizedStrings["Processing Instruction"] = "Processing Instruction";
localizedStrings["Properties"] = "Properties";
localizedStrings["Property"] = "Property";
+localizedStrings["Protocol"] = "Protocol";
localizedStrings["Query Parameters"] = "Query Parameters";
localizedStrings["Query String"] = "Query String";
localizedStrings["Query returned no results."] = "Query returned no results.";
@@ -630,6 +635,7 @@
localizedStrings["Region Flow"] = "Region Flow";
localizedStrings["Region announced in its entirety."] = "Region announced in its entirety.";
localizedStrings["Reload page (%s)\nReload ignoring cache (%s)"] = "Reload page (%s)\nReload ignoring cache (%s)";
+localizedStrings["Remote Address"] = "Remote Address";
localizedStrings["Removals"] = "Removals";
localizedStrings["Remove Watch _expression_"] = "Remove Watch _expression_";
localizedStrings["Remove link"] = "Remove link";
Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/FrameResourceManager.js (213681 => 213682)
--- trunk/Source/WebInspectorUI/UserInterface/Controllers/FrameResourceManager.js 2017-03-09 23:21:19 UTC (rev 213681)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/FrameResourceManager.js 2017-03-09 23:44:12 UTC (rev 213682)
@@ -414,7 +414,7 @@
resource.increaseTransferSize(encodedDataLength);
}
- resourceRequestDidFinishLoading(requestIdentifier, timestamp, sourceMapURL)
+ resourceRequestDidFinishLoading(requestIdentifier, timestamp, sourceMapURL, metrics)
{
// Called from WebInspector.NetworkObserver.
@@ -429,7 +429,10 @@
if (!resource)
return;
- var elapsedTime = WebInspector.timelineManager.computeElapsedTime(timestamp);
+ if (metrics)
+ resource.updateWithMetrics(metrics);
+
+ let elapsedTime = WebInspector.timelineManager.computeElapsedTime(timestamp);
resource.markAsFinished(elapsedTime);
if (sourceMapURL)
@@ -453,7 +456,7 @@
if (!resource)
return;
- var elapsedTime = WebInspector.timelineManager.computeElapsedTime(timestamp);
+ let elapsedTime = WebInspector.timelineManager.computeElapsedTime(timestamp);
resource.markAsFailed(canceled, elapsedTime);
if (resource === resource.parentFrame.provisionalMainResource)
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/Resource.js (213681 => 213682)
--- trunk/Source/WebInspectorUI/UserInterface/Models/Resource.js 2017-03-09 23:21:19 UTC (rev 213681)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/Resource.js 2017-03-09 23:44:12 UTC (rev 213682)
@@ -63,6 +63,10 @@
this._cached = false;
this._responseSource = WebInspector.Resource.ResponseSource.Unknown;
this._timingData = new WebInspector.ResourceTimingData(this);
+ this._protocol = null;
+ this._priority = WebInspector.Resource.NetworkPriority.Unknown;
+ this._remoteAddress = null;
+ this._connectionIdentifier = null;
this._target = targetId ? WebInspector.targetManager.targetForIdentifier(targetId) : WebInspector.mainTarget;
if (this._initiatorSourceCodeLocation && this._initiatorSourceCodeLocation.sourceCode instanceof WebInspector.Resource)
@@ -128,7 +132,7 @@
case WebInspector.Resource.Type.Other:
return WebInspector.UIString("Other");
default:
- console.error("Unknown resource type: ", type);
+ console.error("Unknown resource type", type);
return null;
}
}
@@ -148,11 +152,43 @@
case NetworkAgent.ResponseSource.DiskCache:
return WebInspector.Resource.ResponseSource.DiskCache;
default:
- console.error("Unknown response source type: ", source);
+ console.error("Unknown response source type", source);
return WebInspector.Resource.ResponseSource.Unknown;
}
}
+ static networkPriorityFromPayload(priority)
+ {
+ switch (priority) {
+ case NetworkAgent.MetricsPriority.Low:
+ return WebInspector.Resource.NetworkPriority.Low;
+ case NetworkAgent.MetricsPriority.Medium:
+ return WebInspector.Resource.NetworkPriority.Medium;
+ case NetworkAgent.MetricsPriority.High:
+ return WebInspector.Resource.NetworkPriority.High;
+ default:
+ console.error("Unknown metrics priority", priority);
+ return WebInspector.Resource.NetworkPriority.Unknown;
+ }
+ }
+
+ static connectionIdentifierFromPayload(connectionIdentifier)
+ {
+ // Map backend connection identifiers to an easier to read number.
+ if (!WebInspector.Resource.connectionIdentifierMap) {
+ WebInspector.Resource.connectionIdentifierMap = new Map;
+ WebInspector.Resource.nextConnectionIdentifier = 1;
+ }
+
+ let id = WebInspector.Resource.connectionIdentifierMap.get(connectionIdentifier);
+ if (id)
+ return id;
+
+ id = WebInspector.Resource.nextConnectionIdentifier++;
+ WebInspector.Resource.connectionIdentifierMap.set(connectionIdentifier, id);
+ return id;
+ }
+
// Public
get target() { return this._target; }
@@ -165,6 +201,10 @@
get statusText() { return this._statusText; }
get responseSource() { return this._responseSource; }
get timingData() { return this._timingData; }
+ get protocol() { return this._protocol; }
+ get priority() { return this._priority; }
+ get remoteAddress() { return this._remoteAddress; }
+ get connectionIdentifier() { return this._connectionIdentifier; }
get url()
{
@@ -520,6 +560,18 @@
this.dispatchEventToListeners(WebInspector.Resource.Event.TimestampsDidChange);
}
+ updateWithMetrics(metrics)
+ {
+ if (metrics.protocol)
+ this._protocol = metrics.protocol;
+ if (metrics.priority)
+ this._priority = WebInspector.Resource.networkPriorityFromPayload(metrics.priority);
+ if (metrics.remoteAddress)
+ this._remoteAddress = metrics.remoteAddress;
+ if (metrics.connectionIdentifier)
+ this._connectionIdentifier = WebInspector.Resource.connectionIdentifierFromPayload(metrics.connectionIdentifier);
+ }
+
canRequestContent()
{
return this._finished;
@@ -799,6 +851,13 @@
DiskCache: Symbol("disk-cache"),
};
+WebInspector.Resource.NetworkPriority = {
+ Unknown: Symbol("unknown"),
+ Low: Symbol("low"),
+ Medium: Symbol("medium"),
+ High: Symbol("high"),
+};
+
// This MIME Type map is private, use WebInspector.Resource.typeFromMIMEType().
WebInspector.Resource._mimeTypeMap = {
"text/html": WebInspector.Resource.Type.Document,
Modified: trunk/Source/WebInspectorUI/UserInterface/Protocol/NetworkObserver.js (213681 => 213682)
--- trunk/Source/WebInspectorUI/UserInterface/Protocol/NetworkObserver.js 2017-03-09 23:21:19 UTC (rev 213681)
+++ trunk/Source/WebInspectorUI/UserInterface/Protocol/NetworkObserver.js 2017-03-09 23:44:12 UTC (rev 213682)
@@ -48,9 +48,9 @@
WebInspector.frameResourceManager.resourceRequestDidReceiveData(requestId, dataLength, encodedDataLength, timestamp);
}
- loadingFinished(requestId, timestamp, sourceMapURL)
+ loadingFinished(requestId, timestamp, sourceMapURL, metrics)
{
- WebInspector.frameResourceManager.resourceRequestDidFinishLoading(requestId, timestamp, sourceMapURL);
+ WebInspector.frameResourceManager.resourceRequestDidFinishLoading(requestId, timestamp, sourceMapURL, metrics);
}
loadingFailed(requestId, timestamp, errorText, canceled)
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/DataGrid.js (213681 => 213682)
--- trunk/Source/WebInspectorUI/UserInterface/Views/DataGrid.js 2017-03-09 23:21:19 UTC (rev 213681)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/DataGrid.js 2017-03-09 23:44:12 UTC (rev 213682)
@@ -37,7 +37,7 @@
this._sortColumnIdentifierSetting = null;
this._sortOrder = WebInspector.DataGrid.SortOrder.Indeterminate;
this._sortOrderSetting = null;
- this._hiddenColumnSetting = null;
+ this._columnVisibilitySetting = null;
this._columnChooserEnabled = false;
this._headerVisible = true;
@@ -362,7 +362,7 @@
this._sortColumnIdentifierSetting = new WebInspector.Setting(this._settingsIdentifier + "-sort", this._sortColumnIdentifier);
this._sortOrderSetting = new WebInspector.Setting(this._settingsIdentifier + "-sort-order", this._sortOrder);
- this._hiddenColumnSetting = new WebInspector.Setting(this._settingsIdentifier + "-hidden-columns", []);
+ this._columnVisibilitySetting = new WebInspector.Setting(this._settingsIdentifier + "-column-visibility", {});
if (!this.columns)
return;
@@ -372,8 +372,11 @@
this.sortOrder = this._sortOrderSetting.value;
}
- for (let columnIdentifier of this._hiddenColumnSetting.value)
- this.setColumnVisible(columnIdentifier, false);
+ let visibilitySettings = this._columnVisibilitySetting.value;
+ for (let columnIdentifier in visibilitySettings) {
+ let visible = visibilitySettings[columnIdentifier];
+ this.setColumnVisible(columnIdentifier, visible);
+ }
}
_updateScrollListeners()
@@ -919,14 +922,12 @@
column.element.style.width = visible ? column.width : 0;
column.hidden = !visible;
- if (this._hiddenColumnSetting) {
- let hiddenColumns = this._hiddenColumnSetting.value.slice();
- if (column.hidden)
- hiddenColumns.push(columnIdentifier);
- else
- hiddenColumns.remove(columnIdentifier);
-
- this._hiddenColumnSetting.value = hiddenColumns;
+ if (this._columnVisibilitySetting) {
+ if (this._columnVisibilitySetting.value[columnIdentifier] !== visible) {
+ let copy = Object.shallowCopy(this._columnVisibilitySetting.value);
+ copy[columnIdentifier] = visible;
+ this._columnVisibilitySetting.value = copy;
+ }
}
this._columnWidthsInitialized = false;
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/NetworkGridContentView.js (213681 => 213682)
--- trunk/Source/WebInspectorUI/UserInterface/Views/NetworkGridContentView.js 2017-03-09 23:21:19 UTC (rev 213681)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/NetworkGridContentView.js 2017-03-09 23:44:12 UTC (rev 213682)
@@ -39,7 +39,7 @@
this._contentTreeOutline = this._networkSidebarPanel.contentTreeOutline;
this._contentTreeOutline.addEventListener(WebInspector.TreeOutline.Event.SelectionDidChange, this._treeSelectionDidChange, this);
- var columns = {domain: {}, type: {}, method: {}, scheme: {}, statusCode: {}, cached: {}, size: {}, transferSize: {}, requestSent: {}, latency: {}, duration: {}, graph: {}};
+ let columns = {domain: {}, type: {}, method: {}, scheme: {}, statusCode: {}, cached: {}, protocol: {}, priority: {}, remoteAddress: {}, connectionIdentifier: {}, size: {}, transferSize: {}, requestSent: {}, latency: {}, duration: {}, graph: {}};
columns.domain.title = WebInspector.UIString("Domain");
columns.domain.width = "10%";
@@ -59,6 +59,23 @@
columns.cached.title = WebInspector.UIString("Cached");
columns.cached.width = "8%";
+ columns.protocol.title = WebInspector.UIString("Protocol");
+ columns.protocol.width = "5%";
+ columns.protocol.hidden = true;
+
+ columns.priority.title = WebInspector.UIString("Priority");
+ columns.priority.width = "5%";
+ columns.priority.hidden = true;
+
+ columns.remoteAddress.title = WebInspector.UIString("Remote Address");
+ columns.remoteAddress.width = "8%";
+ columns.remoteAddress.hidden = true;
+
+ columns.connectionIdentifier.title = WebInspector.UIString("Connection");
+ columns.connectionIdentifier.width = "5%";
+ columns.connectionIdentifier.hidden = true;
+ columns.connectionIdentifier.aligned = "right";
+
columns.size.title = WebInspector.UIString("Size");
columns.size.width = "6%";
columns.size.aligned = "right";
@@ -79,7 +96,7 @@
columns.duration.width = "9%";
columns.duration.aligned = "right";
- for (var column in columns)
+ for (let column in columns)
columns[column].sortable = true;
this._timelineRuler = new WebInspector.TimelineRuler;
@@ -90,6 +107,14 @@
columns.graph.headerView = this._timelineRuler;
columns.graph.sortable = false;
+ // COMPATIBILITY(iOS 10.3): Network load metrics were not previously available.
+ if (!NetworkAgent.hasEventParameter("loadingFinished", "metrics")) {
+ delete columns.protocol;
+ delete columns.priority;
+ delete columns.remoteAddress;
+ delete columns.connectionIdentifier;
+ }
+
this._dataGrid = new WebInspector.TimelineDataGrid(columns, this._contentTreeOutline);
this._dataGrid.addEventListener(WebInspector.DataGrid.Event.SelectedNodeChanged, this._dataGridNodeSelected, this);
this._dataGrid.sortColumnIdentifier = "requestSent";
@@ -99,7 +124,7 @@
this.element.classList.add("network-grid");
this.addSubview(this._dataGrid);
- var networkTimeline = WebInspector.timelineManager.persistentNetworkTimeline;
+ let networkTimeline = WebInspector.timelineManager.persistentNetworkTimeline;
networkTimeline.addEventListener(WebInspector.Timeline.Event.RecordAdded, this._networkTimelineRecordAdded, this);
networkTimeline.addEventListener(WebInspector.Timeline.Event.Reset, this._networkTimelineReset, this);
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/NetworkTimelineView.js (213681 => 213682)
--- trunk/Source/WebInspectorUI/UserInterface/Views/NetworkTimelineView.js 2017-03-09 23:21:19 UTC (rev 213681)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/NetworkTimelineView.js 2017-03-09 23:44:12 UTC (rev 213682)
@@ -31,7 +31,7 @@
console.assert(timeline.type === WebInspector.TimelineRecord.Type.Network);
- let columns = {name: {}, domain: {}, type: {}, method: {}, scheme: {}, statusCode: {}, cached: {}, size: {}, transferSize: {}, requestSent: {}, latency: {}, duration: {}, graph: {}};
+ let columns = {name: {}, domain: {}, type: {}, method: {}, scheme: {}, statusCode: {}, cached: {}, protocol: {}, priority: {}, remoteAddress: {}, connectionIdentifier: {}, size: {}, transferSize: {}, requestSent: {}, latency: {}, duration: {}, graph: {}};
columns.name.title = WebInspector.UIString("Name");
columns.name.icon = true;
@@ -44,9 +44,9 @@
columns.type.title = WebInspector.UIString("Type");
columns.type.width = "7%";
- var typeToLabelMap = new Map;
- for (var key in WebInspector.Resource.Type) {
- var value = WebInspector.Resource.Type[key];
+ let typeToLabelMap = new Map;
+ for (let key in WebInspector.Resource.Type) {
+ let value = WebInspector.Resource.Type[key];
typeToLabelMap.set(value, WebInspector.Resource.displayNameForType(value, true));
}
@@ -65,6 +65,23 @@
columns.cached.title = WebInspector.UIString("Cached");
columns.cached.width = "6%";
+ columns.protocol.title = WebInspector.UIString("Protocol");
+ columns.protocol.width = "5%";
+ columns.protocol.hidden = true;
+
+ columns.priority.title = WebInspector.UIString("Priority");
+ columns.priority.width = "5%";
+ columns.priority.hidden = true;
+
+ columns.remoteAddress.title = WebInspector.UIString("Remote Address");
+ columns.remoteAddress.width = "8%";
+ columns.remoteAddress.hidden = true;
+
+ columns.connectionIdentifier.title = WebInspector.UIString("Connection");
+ columns.connectionIdentifier.width = "5%";
+ columns.connectionIdentifier.hidden = true;
+ columns.connectionIdentifier.aligned = "right";
+
columns.size.title = WebInspector.UIString("Size");
columns.size.width = "6%";
columns.size.aligned = "right";
@@ -85,7 +102,7 @@
columns.duration.width = "9%";
columns.duration.aligned = "right";
- for (var column in columns)
+ for (let column in columns)
columns[column].sortable = true;
this._timelineRuler = new WebInspector.TimelineRuler;
@@ -96,6 +113,14 @@
columns.graph.headerView = this._timelineRuler;
columns.graph.sortable = false;
+ // COMPATIBILITY(iOS 10.3): Network load metrics were not previously available.
+ if (!NetworkAgent.hasEventParameter("loadingFinished", "metrics")) {
+ delete columns.protocol;
+ delete columns.priority;
+ delete columns.remoteAddress;
+ delete columns.connectionIdentifier;
+ }
+
this._dataGrid = new WebInspector.TimelineDataGrid(columns);
this._dataGrid.sortDelegate = this;
this._dataGrid.sortColumnIdentifier = "requestSent";
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ResourceDetailsSidebarPanel.js (213681 => 213682)
--- trunk/Source/WebInspectorUI/UserInterface/Views/ResourceDetailsSidebarPanel.js 2017-03-09 23:21:19 UTC (rev 213681)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ResourceDetailsSidebarPanel.js 2017-03-09 23:44:12 UTC (rev 213682)
@@ -68,6 +68,8 @@
this._requestDataSection = new WebInspector.DetailsSection("resource-request-data", WebInspector.UIString("Request Data"));
this._requestMethodRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Method"));
+ this._protocolRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Protocol"));
+ this._priorityRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Priority"));
this._cachedRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Cached"));
this._statusTextRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Status"));
@@ -80,10 +82,10 @@
this._compressedRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Compressed"));
this._compressionRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Compression"));
- var requestGroup = new WebInspector.DetailsSectionGroup([this._requestMethodRow, this._cachedRow]);
- var statusGroup = new WebInspector.DetailsSectionGroup([this._statusTextRow, this._statusCodeRow]);
- var sizeGroup = new WebInspector.DetailsSectionGroup([this._encodedSizeRow, this._decodedSizeRow, this._transferSizeRow]);
- var compressionGroup = new WebInspector.DetailsSectionGroup([this._compressedRow, this._compressionRow]);
+ let requestGroup = new WebInspector.DetailsSectionGroup([this._requestMethodRow, this._protocolRow, this._priorityRow, this._cachedRow]);
+ let statusGroup = new WebInspector.DetailsSectionGroup([this._statusTextRow, this._statusCodeRow]);
+ let sizeGroup = new WebInspector.DetailsSectionGroup([this._encodedSizeRow, this._decodedSizeRow, this._transferSizeRow]);
+ let compressionGroup = new WebInspector.DetailsSectionGroup([this._compressedRow, this._compressionRow]);
this._requestAndResponseSection = new WebInspector.DetailsSection("resource-request-response", WebInspector.UIString("Request & Response"), [requestGroup, statusGroup, sizeGroup, compressionGroup]);
@@ -290,20 +292,39 @@
_refreshRequestAndResponse()
{
- var resource = this._resource;
- if (!resource)
+ if (!this._resource)
return;
// If we don't have a value, we set an em-dash to keep the row from hiding.
// This keeps the UI from shifting around as data comes in.
- this._requestMethodRow.value = resource.requestMethod || emDash;
+ this._requestMethodRow.value = this._resource.requestMethod || emDash;
- this._cachedRow.value = resource.cached ? WebInspector.UIString("Yes") : WebInspector.UIString("No");
+ // COMPATIBILITY(iOS 10.3): Network load metrics were not previously available.
+ if (NetworkAgent.hasEventParameter("loadingFinished", "metrics")) {
+ this._protocolRow.value = this._resource.protocol || emDash;
- this._statusCodeRow.value = resource.statusCode || emDash;
- this._statusTextRow.value = resource.statusText || emDash;
+ switch (this._resource.priority) {
+ case WebInspector.Resource.NetworkPriority.Low:
+ this._priorityRow.value = WebInspector.UIString("Low");
+ break;
+ case WebInspector.Resource.NetworkPriority.Medium:
+ this._priorityRow.value = WebInspector.UIString("Medium");
+ break;
+ case WebInspector.Resource.NetworkPriority.High:
+ this._priorityRow.value = WebInspector.UIString("High");
+ break;
+ default:
+ this._priorityRow.value = emDash;
+ break;
+ }
+ }
+ this._cachedRow.value = this._resource.cached ? WebInspector.UIString("Yes") : WebInspector.UIString("No");
+
+ this._statusCodeRow.value = this._resource.statusCode || emDash;
+ this._statusTextRow.value = this._resource.statusText || emDash;
+
this._refreshResponseHeaders();
this._refreshCompressed();
}
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ResourceTimelineDataGridNode.js (213681 => 213682)
--- trunk/Source/WebInspectorUI/UserInterface/Views/ResourceTimelineDataGridNode.js 2017-03-09 23:21:19 UTC (rev 213681)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ResourceTimelineDataGridNode.js 2017-03-09 23:44:12 UTC (rev 213682)
@@ -80,6 +80,10 @@
data.requestSent = resource.requestSentTimestamp - zeroTime;
data.duration = resource.receiveDuration;
data.latency = resource.latency;
+ data.protocol = resource.protocol;
+ data.priority = resource.priority;
+ data.remoteAddress = resource.remoteAddress;
+ data.connectionIdentifier = resource.connectionIdentifier;
}
data.graph = this._record.startTime;
@@ -125,6 +129,14 @@
case "latency":
case "duration":
return isNaN(value) ? emDash : Number.secondsToString(value, true);
+
+ case "protocol":
+ case "remoteAddress":
+ case "connectionIdentifier":
+ return value || emDash;
+
+ case "priority":
+ return this._displayNameForPriority(value);
}
return super.createCellContent(columnIdentifier, cell);
@@ -188,6 +200,20 @@
// Private
+ _displayNameForPriority(priority)
+ {
+ switch (priority) {
+ case WebInspector.Resource.NetworkPriority.Low:
+ return WebInspector.UIString("Low");
+ case WebInspector.Resource.NetworkPriority.Medium:
+ return WebInspector.UIString("Medium");
+ case WebInspector.Resource.NetworkPriority.High:
+ return WebInspector.UIString("High");
+ }
+
+ return emDash;
+ }
+
_createNameCellDocumentFragment()
{
let fragment = document.createDocumentFragment();
@@ -226,7 +252,7 @@
let responseSource = this._resource.responseSource;
if (responseSource === WebInspector.Resource.ResponseSource.MemoryCache || responseSource === WebInspector.Resource.ResponseSource.DiskCache) {
- console.assert(this._resource.cached, "This resource has a cache responseSource it should also be marked as cached", resource);
+ console.assert(this._resource.cached, "This resource has a cache responseSource it should also be marked as cached", this._resource);
let span = document.createElement("span");
let cacheType = document.createElement("span");
cacheType.classList = "cache-type";
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TimelineDataGridNode.js (213681 => 213682)
--- trunk/Source/WebInspectorUI/UserInterface/Views/TimelineDataGridNode.js 2017-03-09 23:21:19 UTC (rev 213681)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TimelineDataGridNode.js 2017-03-09 23:44:12 UTC (rev 213682)
@@ -226,9 +226,12 @@
if (!this.revealed)
return;
- var secondsPerPixel = this._graphDataSource.secondsPerPixel;
- console.assert(isFinite(secondsPerPixel) && secondsPerPixel > 0);
+ let secondsPerPixel = this._graphDataSource.secondsPerPixel;
+ if (isNaN(secondsPerPixel))
+ return;
+ console.assert(secondsPerPixel > 0);
+
var recordBarIndex = 0;
function createBar(records, renderMode)
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRecordBar.js (213681 => 213682)
--- trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRecordBar.js 2017-03-09 23:21:19 UTC (rev 213681)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRecordBar.js 2017-03-09 23:44:12 UTC (rev 213682)
@@ -231,6 +231,9 @@
refresh(graphDataSource)
{
+ if (isNaN(graphDataSource.secondsPerPixel))
+ return;
+
console.assert(graphDataSource.zeroTime);
console.assert(graphDataSource.startTime);
console.assert(graphDataSource.currentTime);
Modified: trunk/Source/WebKit2/ChangeLog (213681 => 213682)
--- trunk/Source/WebKit2/ChangeLog 2017-03-09 23:21:19 UTC (rev 213681)
+++ trunk/Source/WebKit2/ChangeLog 2017-03-09 23:44:12 UTC (rev 213682)
@@ -1,3 +1,17 @@
+2017-03-09 Joseph Pecoraro <[email protected]>
+
+ Web Inspector: Show HTTP protocol version and other Network Load Metrics (IP Address, Priority, Connection ID)
+ https://bugs.webkit.org/show_bug.cgi?id=29687
+ <rdar://problem/19281586>
+
+ Reviewed by Matt Baker and Brian Burg.
+
+ * NetworkProcess/cocoa/NetworkSessionCocoa.mm:
+ (toNetworkLoadPriority):
+ (-[WKNetworkSessionDelegate URLSession:task:didFinishCollectingMetrics:]):
+ * Shared/WebCoreArgumentCoders.h:
+ Additional optional metrics on NetworkLoadMetrics.
+
2017-03-09 Daniel Bates <[email protected]>
Guard Credential Management implementation behind a runtime enabled feature flag
Modified: trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkSessionCocoa.mm (213681 => 213682)
--- trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkSessionCocoa.mm 2017-03-09 23:21:19 UTC (rev 213681)
+++ trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkSessionCocoa.mm 2017-03-09 23:44:12 UTC (rev 213682)
@@ -80,6 +80,15 @@
}
}
+static WebCore::NetworkLoadPriority toNetworkLoadPriority(float priority)
+{
+ if (priority <= NSURLSessionTaskPriorityLow)
+ return WebCore::NetworkLoadPriority::Low;
+ if (priority >= NSURLSessionTaskPriorityHigh)
+ return WebCore::NetworkLoadPriority::High;
+ return WebCore::NetworkLoadPriority::Medium;
+}
+
@interface WKNetworkSessionDelegate : NSObject <NSURLSessionDataDelegate> {
RefPtr<WebKit::NetworkSessionCocoa> _session;
bool _withCredentials;
@@ -290,7 +299,13 @@
networkLoadMetrics.responseStart = Seconds(responseStartInterval);
networkLoadMetrics.responseEnd = Seconds(responseEndInterval);
networkLoadMetrics.markComplete();
+
networkLoadMetrics.protocol = String(m.networkProtocolName);
+ networkLoadMetrics.priority = toNetworkLoadPriority(task.priority);
+#if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300) || (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000)
+ networkLoadMetrics.remoteAddress = String(m._remoteAddressAndPort);
+ networkLoadMetrics.connectionIdentifier = String([m._connectionIdentifier UUIDString]);
+#endif
}
}
Modified: trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.h (213681 => 213682)
--- trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.h 2017-03-09 23:21:19 UTC (rev 213681)
+++ trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.h 2017-03-09 23:44:12 UTC (rev 213682)
@@ -30,6 +30,7 @@
#include <WebCore/DiagnosticLoggingClient.h>
#include <WebCore/FrameLoaderTypes.h>
#include <WebCore/IndexedDB.h>
+#include <WebCore/NetworkLoadMetrics.h>
#include <WebCore/PaymentHeaders.h>
#include <WebCore/ScrollSnapOffsetsInfo.h>
@@ -678,6 +679,15 @@
>;
};
+template<> struct EnumTraits<WebCore::NetworkLoadPriority> {
+ using values = EnumValues<
+ WebCore::NetworkLoadPriority,
+ WebCore::NetworkLoadPriority::Low,
+ WebCore::NetworkLoadPriority::Medium,
+ WebCore::NetworkLoadPriority::High
+ >;
+};
+
#if ENABLE(INDEXED_DATABASE)
template<> struct EnumTraits<WebCore::IndexedDB::GetAllType> {
using values = EnumValues<