Changeset 213682 in webkit


Ignore:
Timestamp:
Mar 9, 2017 3:44:12 PM (7 years ago)
Author:
Joseph Pecoraro
Message:

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.

Source/JavaScriptCore:

  • inspector/protocol/Network.json:

Add metrics object with optional properties to loadingFinished event.

Source/WebCore:

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.

Source/WebInspectorUI:

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.

Source/WebKit2:

  • NetworkProcess/cocoa/NetworkSessionCocoa.mm:

(toNetworkLoadPriority):
(-[WKNetworkSessionDelegate URLSession:task:didFinishCollectingMetrics:]):

  • Shared/WebCoreArgumentCoders.h:

Additional optional metrics on NetworkLoadMetrics.

LayoutTests:

  • http/tests/inspector/network/resource-metrics-expected.txt: Added.
  • http/tests/inspector/network/resource-metrics.html: Added.
Location:
trunk
Files:
2 added
31 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r213681 r213682  
     12017-03-09  Joseph Pecoraro  <pecoraro@apple.com>
     2
     3        Web Inspector: Show HTTP protocol version and other Network Load Metrics (IP Address, Priority, Connection ID)
     4        https://bugs.webkit.org/show_bug.cgi?id=29687
     5        <rdar://problem/19281586>
     6
     7        Reviewed by Matt Baker and Brian Burg.
     8
     9        * http/tests/inspector/network/resource-metrics-expected.txt: Added.
     10        * http/tests/inspector/network/resource-metrics.html: Added.
     11
    1122017-03-09  Ryan Haddad  <ryanhaddad@apple.com>
    213
  • trunk/Source/JavaScriptCore/ChangeLog

    r213680 r213682  
     12017-03-09  Joseph Pecoraro  <pecoraro@apple.com>
     2
     3        Web Inspector: Show HTTP protocol version and other Network Load Metrics (IP Address, Priority, Connection ID)
     4        https://bugs.webkit.org/show_bug.cgi?id=29687
     5        <rdar://problem/19281586>
     6
     7        Reviewed by Matt Baker and Brian Burg.
     8
     9        * inspector/protocol/Network.json:
     10        Add metrics object with optional properties to loadingFinished event.
     11
    1122017-03-09  Youenn Fablet  <youenn@apple.com>
    213
  • trunk/Source/JavaScriptCore/inspector/protocol/Network.json

    r213666 r213682  
    7575                { "name": "requestHeadersText", "type": "string", "optional": true, "description": "HTTP request headers text." },
    7676                { "name": "timing", "$ref": "ResourceTiming", "optional": true, "description": "Timing information for the given request." }
     77            ]
     78        },
     79        {
     80            "id": "Metrics",
     81            "type": "object",
     82            "description": "Network load metrics.",
     83            "properties": [
     84                { "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)" },
     85                { "name": "priority", "type": "string", "enum": ["low", "medium", "high"], "optional": true, "description": "Network priority." },
     86                { "name": "connectionIdentifier", "type": "string", "optional": true, "description": "Connection identifier." },
     87                { "name": "remoteAddress", "type": "string", "optional": true, "description": "Remote IP address." }
    7788            ]
    7889        },
     
    230241                { "name": "requestId", "$ref": "RequestId", "description": "Request identifier." },
    231242                { "name": "timestamp", "$ref": "Timestamp", "description": "Timestamp." },
    232                 { "name": "sourceMapURL", "type": "string", "optional": true, "description": "URL of source map associated with this resource (if any)." }
     243                { "name": "sourceMapURL", "type": "string", "optional": true, "description": "URL of source map associated with this resource (if any)." },
     244                { "name": "metrics", "$ref": "Metrics", "optional": true, "description": "Network metrics." }
    233245            ]
    234246        },
  • trunk/Source/WebCore/ChangeLog

    r213679 r213682  
     12017-03-09  Joseph Pecoraro  <pecoraro@apple.com>
     2
     3        Web Inspector: Show HTTP protocol version and other Network Load Metrics (IP Address, Priority, Connection ID)
     4        https://bugs.webkit.org/show_bug.cgi?id=29687
     5        <rdar://problem/19281586>
     6
     7        Reviewed by Matt Baker and Brian Burg.
     8
     9        Test: http/tests/inspector/network/resource-metrics.html
     10
     11        * inspector/InspectorNetworkAgent.cpp:
     12        (WebCore::toProtocol):
     13        (WebCore::InspectorNetworkAgent::buildObjectForMetrics):
     14        (WebCore::InspectorNetworkAgent::didFinishLoading):
     15        Send metrics at didFinishLoading time, we do not have all of
     16        these at didReceiveResponse time.
     17
     18        * inspector/InspectorInstrumentation.cpp:
     19        (WebCore::InspectorInstrumentation::didFinishLoadingImpl):
     20        * inspector/InspectorInstrumentation.h:
     21        (WebCore::InspectorInstrumentation::didFinishLoading):
     22        * inspector/InspectorNetworkAgent.h:
     23        * loader/CrossOriginPreflightChecker.cpp:
     24        (WebCore::CrossOriginPreflightChecker::validatePreflightResponse):
     25        * loader/DocumentLoader.cpp:
     26        (WebCore::DocumentLoader::finishedLoading):
     27        * loader/ResourceLoadNotifier.cpp:
     28        (WebCore::ResourceLoadNotifier::didFinishLoad):
     29        (WebCore::ResourceLoadNotifier::dispatchDidFinishLoading):
     30        (WebCore::ResourceLoadNotifier::sendRemainingDelegateMessages):
     31        * loader/ResourceLoadNotifier.h:
     32        * loader/SubresourceLoader.cpp:
     33        (WebCore::SubresourceLoader::didFinishLoading):
     34        * loader/appcache/ApplicationCacheGroup.cpp:
     35        (WebCore::ApplicationCacheGroup::didFinishLoading):
     36        Include or pass on NetworkLoadMetrics to Web Inspector.
     37
     38        * platform/network/NetworkLoadMetrics.h:
     39        (WebCore::NetworkLoadMetrics::isolatedCopy):
     40        (WebCore::NetworkLoadMetrics::reset):
     41        (WebCore::NetworkLoadMetrics::operator==):
     42        (WebCore::NetworkLoadMetrics::encode):
     43        (WebCore::NetworkLoadMetrics::decode):
     44        Add new optional metrics properties.
     45
     46        (WTF::Persistence::Coder<std::optional<WebCore::NetworkLoadPriority>>::encode):
     47        (WTF::Persistence::Coder<std::optional<WebCore::NetworkLoadPriority>>::decode):
     48        We never encode this but this is needed for the compiler.
     49
     50        * platform/spi/cocoa/NSURLConnectionSPI.h:
     51        New SPI for NSURLSessionTaskTransactionMetrics details.
     52
    1532017-03-09  Anders Carlsson  <andersca@apple.com>
    254
  • trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp

    r213626 r213682  
    600600}
    601601
    602 void InspectorInstrumentation::didFinishLoadingImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier, DocumentLoader* loader)
     602void InspectorInstrumentation::didFinishLoadingImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier, DocumentLoader* loader, const NetworkLoadMetrics& networkLoadMetrics)
    603603{
    604604    if (!loader)
     
    606606
    607607    if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent())
    608         networkAgent->didFinishLoading(identifier, *loader);
     608        networkAgent->didFinishLoading(identifier, *loader, networkLoadMetrics);
    609609}
    610610
  • trunk/Source/WebCore/inspector/InspectorInstrumentation.h

    r213621 r213682  
    7272class InspectorTimelineAgent;
    7373class InstrumentingAgents;
     74class NetworkLoadMetrics;
    7475class Node;
    7576class PseudoElement;
     
    157158    static void didReceiveThreadableLoaderResponse(DocumentThreadableLoader&, unsigned long identifier);
    158159    static void didReceiveData(Frame*, unsigned long identifier, const char* data, int dataLength, int encodedDataLength);
    159     static void didFinishLoading(Frame*, DocumentLoader*, unsigned long identifier);
     160    static void didFinishLoading(Frame*, DocumentLoader*, unsigned long identifier, const NetworkLoadMetrics&);
    160161    static void didFailLoading(Frame*, DocumentLoader*, unsigned long identifier, const ResourceError&);
    161162    static void continueAfterXFrameOptionsDenied(Frame&, unsigned long identifier, DocumentLoader&, const ResourceResponse&);
     
    327328    static void didReceiveThreadableLoaderResponseImpl(InstrumentingAgents&, DocumentThreadableLoader&, unsigned long identifier);
    328329    static void didReceiveDataImpl(InstrumentingAgents&, unsigned long identifier, const char* data, int dataLength, int encodedDataLength);
    329     static void didFinishLoadingImpl(InstrumentingAgents&, unsigned long identifier, DocumentLoader*);
     330    static void didFinishLoadingImpl(InstrumentingAgents&, unsigned long identifier, DocumentLoader*, const NetworkLoadMetrics&);
    330331    static void didFailLoadingImpl(InstrumentingAgents&, unsigned long identifier, DocumentLoader*, const ResourceError&);
    331332    static void didFinishXHRLoadingImpl(InstrumentingAgents&, unsigned long identifier, std::optional<String> decodedText, const String& url, const String& sendURL, unsigned sendLineNumber, unsigned sendColumnNumber);
     
    858859}
    859860
    860 inline void InspectorInstrumentation::didFinishLoading(Frame* frame, DocumentLoader* loader, unsigned long identifier)
    861 {
    862     if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame))
    863         didFinishLoadingImpl(*instrumentingAgents, identifier, loader);
     861inline void InspectorInstrumentation::didFinishLoading(Frame* frame, DocumentLoader* loader, unsigned long identifier, const NetworkLoadMetrics& networkLoadMetrics)
     862{
     863    if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame))
     864        didFinishLoadingImpl(*instrumentingAgents, identifier, loader, networkLoadMetrics);
    864865}
    865866
  • trunk/Source/WebCore/inspector/InspectorNetworkAgent.cpp

    r213666 r213682  
    197197}
    198198
     199static Inspector::Protocol::Network::Metrics::Priority toProtocol(NetworkLoadPriority priority)
     200{
     201    switch (priority) {
     202    case NetworkLoadPriority::Low:
     203        return Inspector::Protocol::Network::Metrics::Priority::Low;
     204    case NetworkLoadPriority::Medium:
     205        return Inspector::Protocol::Network::Metrics::Priority::Medium;
     206    case NetworkLoadPriority::High:
     207        return Inspector::Protocol::Network::Metrics::Priority::High;
     208    }
     209
     210    ASSERT_NOT_REACHED();
     211    return Inspector::Protocol::Network::Metrics::Priority::Medium;
     212}
     213
     214Ref<Inspector::Protocol::Network::Metrics> InspectorNetworkAgent::buildObjectForMetrics(const NetworkLoadMetrics& networkLoadMetrics)
     215{
     216    auto metrics = Inspector::Protocol::Network::Metrics::create().release();
     217
     218    if (!networkLoadMetrics.protocol.isNull())
     219        metrics->setProtocol(networkLoadMetrics.protocol);
     220    if (networkLoadMetrics.priority)
     221        metrics->setPriority(toProtocol(*networkLoadMetrics.priority));
     222    if (networkLoadMetrics.remoteAddress)
     223        metrics->setRemoteAddress(*networkLoadMetrics.remoteAddress);
     224    if (networkLoadMetrics.connectionIdentifier)
     225        metrics->setConnectionIdentifier(*networkLoadMetrics.connectionIdentifier);
     226
     227    return metrics;
     228}
     229
    199230static Ref<Inspector::Protocol::Network::Request> buildObjectForResourceRequest(const ResourceRequest& request)
    200231{
     
    392423}
    393424
    394 void InspectorNetworkAgent::didFinishLoading(unsigned long identifier, DocumentLoader& loader)
     425void InspectorNetworkAgent::didFinishLoading(unsigned long identifier, DocumentLoader& loader, const NetworkLoadMetrics& networkLoadMetrics)
    395426{
    396427    if (m_hiddenRequestIdentifiers.remove(identifier))
    397428        return;
    398429
    399     // FIXME: Inspector should make use of NetworkLoadMetrics.
     430    // FIXME: We should use the NetworkLoadMetrics's responseEnd to match ResourceTiming.
    400431    double elapsedFinishTime = timestamp();
    401432
     
    411442        sourceMappingURL = InspectorPageAgent::sourceMapURLForResource(resourceData->cachedResource());
    412443
    413     m_frontendDispatcher->loadingFinished(requestId, elapsedFinishTime, !sourceMappingURL.isEmpty() ? &sourceMappingURL : nullptr);
     444    RefPtr<Inspector::Protocol::Network::Metrics> metrics = buildObjectForMetrics(networkLoadMetrics);
     445
     446    m_frontendDispatcher->loadingFinished(requestId, elapsedFinishTime, !sourceMappingURL.isEmpty() ? &sourceMappingURL : nullptr, metrics);
    414447}
    415448
  • trunk/Source/WebCore/inspector/InspectorNetworkAgent.h

    r213621 r213682  
    7979    void didReceiveResponse(unsigned long identifier, DocumentLoader&, const ResourceResponse&, ResourceLoader*);
    8080    void didReceiveData(unsigned long identifier, const char* data, int dataLength, int encodedDataLength);
    81     void didFinishLoading(unsigned long identifier, DocumentLoader&);
     81    void didFinishLoading(unsigned long identifier, DocumentLoader&, const NetworkLoadMetrics&);
    8282    void didFailLoading(unsigned long identifier, DocumentLoader&, const ResourceError&);
    8383    void didLoadResourceFromMemoryCache(DocumentLoader&, CachedResource&);
     
    118118
    119119    Ref<Inspector::Protocol::Network::ResourceTiming> buildObjectForTiming(const NetworkLoadMetrics&, ResourceLoader&);
     120    Ref<Inspector::Protocol::Network::Metrics> buildObjectForMetrics(const NetworkLoadMetrics&);
    120121    RefPtr<Inspector::Protocol::Network::Response> buildObjectForResourceResponse(const ResourceResponse&, ResourceLoader*);
    121122    Ref<Inspector::Protocol::Network::CachedResource> buildObjectForCachedResource(CachedResource*);
  • trunk/Source/WebCore/loader/CrossOriginPreflightChecker.cpp

    r212993 r213682  
    4040#include "DocumentThreadableLoader.h"
    4141#include "InspectorInstrumentation.h"
     42#include "NetworkLoadMetrics.h"
    4243#include "RuntimeEnabledFeatures.h"
    4344
     
    8384    // This is only showing success preflight requests and responses but we should show network events
    8485    // for preflight failures and distinguish them better from non-preflight requests.
     86    NetworkLoadMetrics emptyMetrics;
    8587    InspectorInstrumentation::didReceiveResourceResponse(*frame, identifier, frame->loader().documentLoader(), response, nullptr);
    86     InspectorInstrumentation::didFinishLoading(frame, frame->loader().documentLoader(), identifier);
     88    InspectorInstrumentation::didFinishLoading(frame, frame->loader().documentLoader(), identifier, emptyMetrics);
    8789
    8890    CrossOriginPreflightResultCache::singleton().appendEntry(loader.securityOrigin().toString(), request.url(), WTFMove(result));
  • trunk/Source/WebCore/loader/DocumentLoader.cpp

    r213182 r213682  
    6363#include "MainFrame.h"
    6464#include "MemoryCache.h"
     65#include "NetworkLoadMetrics.h"
    6566#include "Page.h"
    6667#include "PolicyChecker.h"
     
    391392        // before calling dispatchDidFinishLoading so that we don't later try to
    392393        // cancel the already-finished substitute load.
     394        NetworkLoadMetrics emptyMetrics;
    393395        unsigned long identifier = m_identifierForLoadWithoutResourceLoader;
    394396        m_identifierForLoadWithoutResourceLoader = 0;
    395         frameLoader()->notifier().dispatchDidFinishLoading(this, identifier);
     397        frameLoader()->notifier().dispatchDidFinishLoading(this, identifier, emptyMetrics);
    396398    }
    397399
  • trunk/Source/WebCore/loader/ResourceLoadNotifier.cpp

    r213182 r213682  
    8888}
    8989
    90 void ResourceLoadNotifier::didFinishLoad(ResourceLoader* loader, const NetworkLoadMetrics&)
     90void ResourceLoadNotifier::didFinishLoad(ResourceLoader* loader, const NetworkLoadMetrics& networkLoadMetrics)
    9191{   
    9292    if (Page* page = m_frame.page())
    9393        page->progress().completeProgress(loader->identifier());
    9494
    95     // FIXME: Inspector should make use of NetworkLoadMetrics.
    96 
    97     dispatchDidFinishLoading(loader->documentLoader(), loader->identifier());
     95    dispatchDidFinishLoading(loader->documentLoader(), loader->identifier(), networkLoadMetrics);
    9896}
    9997
     
    163161}
    164162
    165 void ResourceLoadNotifier::dispatchDidFinishLoading(DocumentLoader* loader, unsigned long identifier)
     163void ResourceLoadNotifier::dispatchDidFinishLoading(DocumentLoader* loader, unsigned long identifier, const NetworkLoadMetrics& networkLoadMetrics)
    166164{
    167165    // Notifying the FrameLoaderClient may cause the frame to be destroyed.
     
    169167    m_frame.loader().client().dispatchDidFinishLoading(loader, identifier);
    170168
    171     InspectorInstrumentation::didFinishLoading(&m_frame, loader, identifier);
     169    InspectorInstrumentation::didFinishLoading(&m_frame, loader, identifier, networkLoadMetrics);
    172170}
    173171
     
    197195        dispatchDidReceiveData(loader, identifier, data, dataLength, encodedDataLength);
    198196
    199     if (error.isNull())
    200         dispatchDidFinishLoading(loader, identifier);
    201     else
     197    if (error.isNull()) {
     198        NetworkLoadMetrics emptyMetrics;
     199        dispatchDidFinishLoading(loader, identifier, emptyMetrics);
     200    } else
    202201        dispatchDidFailLoading(loader, identifier, error);
    203202}
  • trunk/Source/WebCore/loader/ResourceLoadNotifier.h

    r212993 r213682  
    6161    void dispatchDidReceiveResponse(DocumentLoader*, unsigned long identifier, const ResourceResponse&, ResourceLoader* = nullptr);
    6262    void dispatchDidReceiveData(DocumentLoader*, unsigned long identifier, const char* data, int dataLength, int encodedDataLength);
    63     void dispatchDidFinishLoading(DocumentLoader*, unsigned long identifier);
     63    void dispatchDidFinishLoading(DocumentLoader*, unsigned long identifier, const NetworkLoadMetrics&);
    6464    void dispatchDidFailLoading(DocumentLoader*, unsigned long identifier, const ResourceError&);
    6565
  • trunk/Source/WebCore/loader/SubresourceLoader.cpp

    r213621 r213682  
    560560    m_resource->finish();
    561561    ASSERT(!reachedTerminalState());
    562     didFinishLoadingOnePart(m_resource->response().deprecatedNetworkLoadMetrics());
     562    didFinishLoadingOnePart(networkLoadMetrics);
    563563    notifyDone();
    564564    if (reachedTerminalState())
  • trunk/Source/WebCore/loader/appcache/ApplicationCacheGroup.cpp

    r212993 r213682  
    4242#include "InspectorInstrumentation.h"
    4343#include "ManifestParser.h"
     44#include "NetworkLoadMetrics.h"
    4445#include "Page.h"
    4546#include "ProgressTracker.h"
     
    573574void ApplicationCacheGroup::didFinishLoading(ResourceHandle* handle)
    574575{
    575     InspectorInstrumentation::didFinishLoading(m_frame, m_frame->loader().documentLoader(), m_currentResourceIdentifier);
     576    // FIXME: We should have NetworkLoadMetrics for ApplicationCache loads.
     577    NetworkLoadMetrics emptyMetrics;
     578    InspectorInstrumentation::didFinishLoading(m_frame, m_frame->loader().documentLoader(), m_currentResourceIdentifier, emptyMetrics);
    576579
    577580    if (handle == m_manifestHandle) {
  • trunk/Source/WebCore/platform/network/NetworkLoadMetrics.h

    r212993 r213682  
    2727#pragma once
    2828
     29#include <wtf/Optional.h>
    2930#include <wtf/Seconds.h>
     31#include <wtf/persistence/Decoder.h>
     32#include <wtf/persistence/Encoder.h>
    3033#include <wtf/text/WTFString.h>
    3134
     
    3538
    3639namespace WebCore {
     40
     41enum class NetworkLoadPriority {
     42    Low,
     43    Medium,
     44    High,
     45};
    3746
    3847class NetworkLoadMetrics {
     
    5867        copy.protocol = protocol.isolatedCopy();
    5968
     69        if (remoteAddress)
     70            copy.remoteAddress = remoteAddress.value().isolatedCopy();
     71        if (connectionIdentifier)
     72            copy.connectionIdentifier = connectionIdentifier.value().isolatedCopy();
     73        if (priority)
     74            copy.priority = *priority;
     75
    6076        return copy;
    6177    }
     
    7187        responseStart = Seconds(0);
    7288        responseEnd = Seconds(0);
     89        complete = false;
    7390        protocol = String();
    74         complete = false;
     91        remoteAddress = std::nullopt;
     92        connectionIdentifier = std::nullopt;
     93        priority = std::nullopt;
    7594    }
    7695
     
    86105            && responseEnd == other.responseEnd
    87106            && complete == other.complete
    88             && protocol == other.protocol;
     107            && protocol == other.protocol
     108            && remoteAddress == other.remoteAddress
     109            && connectionIdentifier == other.connectionIdentifier
     110            && priority == other.priority;
    89111    }
    90112
     
    116138    // ALPN Protocol ID: https://w3c.github.io/resource-timing/#bib-RFC7301
    117139    String protocol;
     140
     141    std::optional<String> remoteAddress;
     142    std::optional<String> connectionIdentifier;
     143    std::optional<NetworkLoadPriority> priority;
    118144};
    119145
     
    139165    encoder << complete;
    140166    encoder << protocol;
     167    encoder << remoteAddress;
     168    encoder << connectionIdentifier;
     169    encoder << priority;
    141170}
    142171
    143172template<class Decoder>
    144 bool NetworkLoadMetrics::decode(Decoder& decoder, NetworkLoadMetrics& timing)
     173bool NetworkLoadMetrics::decode(Decoder& decoder, NetworkLoadMetrics& metrics)
    145174{
    146     return decoder.decode(timing.domainLookupStart)
    147         && decoder.decode(timing.domainLookupEnd)
    148         && decoder.decode(timing.connectStart)
    149         && decoder.decode(timing.secureConnectionStart)
    150         && decoder.decode(timing.connectEnd)
    151         && decoder.decode(timing.requestStart)
    152         && decoder.decode(timing.responseStart)
    153         && decoder.decode(timing.responseEnd)
    154         && decoder.decode(timing.complete)
    155         && decoder.decode(timing.protocol);
     175    return decoder.decode(metrics.domainLookupStart)
     176        && decoder.decode(metrics.domainLookupEnd)
     177        && decoder.decode(metrics.connectStart)
     178        && decoder.decode(metrics.secureConnectionStart)
     179        && decoder.decode(metrics.connectEnd)
     180        && decoder.decode(metrics.requestStart)
     181        && decoder.decode(metrics.responseStart)
     182        && decoder.decode(metrics.responseEnd)
     183        && decoder.decode(metrics.complete)
     184        && decoder.decode(metrics.protocol)
     185        && decoder.decode(metrics.remoteAddress)
     186        && decoder.decode(metrics.connectionIdentifier)
     187        && decoder.decode(metrics.priority);
    156188}
    157189
    158 }
     190} // namespace WebCore
     191
     192// NetworkLoadMetrics should not be stored by the WTF::Persistence::Decoder.
     193namespace WTF {
     194namespace Persistence {
     195
     196template<> struct Coder<std::optional<WebCore::NetworkLoadPriority>> {
     197    static NO_RETURN_DUE_TO_ASSERT void encode(Encoder&, const std::optional<WebCore::NetworkLoadPriority>&)
     198    {
     199        ASSERT_NOT_REACHED();
     200    }
     201
     202    static bool decode(Decoder&, std::optional<WebCore::NetworkLoadPriority>&)
     203    {
     204        ASSERT_NOT_REACHED();
     205        return false;
     206    }
     207};
     208
     209}} // namespace WTF::Persistence
  • trunk/Source/WebCore/platform/spi/cocoa/NSURLConnectionSPI.h

    r194156 r213682  
    4747@end
    4848
     49#if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300) || (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000)
     50@interface NSURLSessionTaskTransactionMetrics ()
     51@property (copy, readonly) NSString* _remoteAddressAndPort;
     52@property (copy, readonly) NSUUID* _connectionIdentifier;
     53@end
    4954#endif
     55
     56#endif
  • trunk/Source/WebInspectorUI/ChangeLog

    r213666 r213682  
     12017-03-09  Joseph Pecoraro  <pecoraro@apple.com>
     2
     3        Web Inspector: Show HTTP protocol version and other Network Load Metrics (IP Address, Priority, Connection ID)
     4        https://bugs.webkit.org/show_bug.cgi?id=29687
     5        <rdar://problem/19281586>
     6
     7        Reviewed by Matt Baker and Brian Burg.
     8
     9        These columns are available in the Network DataGrids, but are
     10        initially hidden. They can be shown by right clicking on the
     11        table header and showing these columns. We are going to rework
     12        the default list of visible columns later.
     13
     14        * Localizations/en.lproj/localizedStrings.js:
     15        New localized strings for data grid headers and Low/Medium/High.
     16
     17        * UserInterface/Controllers/FrameResourceManager.js:
     18        (WebInspector.FrameResourceManager.prototype.resourceRequestDidFinishLoading):
     19        * UserInterface/Protocol/NetworkObserver.js:
     20        (WebInspector.NetworkObserver.prototype.loadingFinished):
     21        Pass metrics on to the Resource.
     22
     23        * UserInterface/Models/Resource.js:
     24        (WebInspector.Resource):
     25        (WebInspector.Resource.displayNameForType):
     26        (WebInspector.Resource.responseSourceFromPayload):
     27        (WebInspector.Resource.networkPriorityFromPayload):
     28        (WebInspector.Resource.connectionIdentifierFromPayload):
     29        (WebInspector.Resource.prototype.get protocol):
     30        (WebInspector.Resource.prototype.get priority):
     31        (WebInspector.Resource.prototype.get remoteAddress):
     32        (WebInspector.Resource.prototype.get connectionIdentifier):
     33        (WebInspector.Resource.prototype.updateWithMetrics):
     34        Include metrics accessors and default values.
     35
     36        * UserInterface/Views/NetworkGridContentView.js:
     37        (WebInspector.NetworkGridContentView):
     38        * UserInterface/Views/NetworkTimelineView.js:
     39        (WebInspector.NetworkTimelineView):
     40        Add metrics columns if the backend may be sending them.
     41
     42        * UserInterface/Views/ResourceTimelineDataGridNode.js:
     43        (WebInspector.ResourceTimelineDataGridNode.prototype.get data):
     44        (WebInspector.ResourceTimelineDataGridNode.prototype.createCellContent):
     45        (WebInspector.ResourceTimelineDataGridNode.prototype._displayNameForPriority):
     46        (WebInspector.ResourceTimelineDataGridNode.prototype._cachedCellContent):
     47        Display strings for new columns.
     48
     49        * UserInterface/Views/TimelineDataGridNode.js:
     50        * UserInterface/Views/TimelineRecordBar.js:
     51        (WebInspector.TimelineRecordBar.prototype.refresh):
     52        Avoid assertions if Graph column is unavailable.
     53
     54        * UserInterface/Views/DataGrid.js:
     55        (WebInspector.DataGrid):
     56        (WebInspector.DataGrid.prototype.createSettings):
     57        (WebInspector.DataGrid.prototype.setColumnVisible):
     58        Better support for restoring user preference of initially
     59        hidden columns which the user may have shown.
     60
     61        * UserInterface/Views/ResourceDetailsSidebarPanel.js:
     62        (WebInspector.ResourceDetailsSidebarPanel):
     63        (WebInspector.ResourceDetailsSidebarPanel.prototype._refreshRequestAndResponse):
     64        Show the Protocol and Priority in the Resources sidebar.
     65
    1662017-03-09  Nikita Vasilyev  <nvasilyev@apple.com>
    267
  • trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js

    r213666 r213682  
    417417localizedStrings["Hide type information"] = "Hide type information";
    418418localizedStrings["Hierarchy Level"] = "Hierarchy Level";
     419localizedStrings["High"] = "High";
    419420localizedStrings["Highest: %s"] = "Highest: %s";
    420421localizedStrings["Horizontal"] = "Horizontal";
     
    493494localizedStrings["Log: "] = "Log: ";
    494495localizedStrings["Logs"] = "Logs";
     496localizedStrings["Low"] = "Low";
    495497localizedStrings["Lowest: %s"] = "Lowest: %s";
    496498localizedStrings["MIME Type"] = "MIME Type";
     
    506508localizedStrings["Maximum maximum memory size in this recording"] = "Maximum maximum memory size in this recording";
    507509localizedStrings["Media: "] = "Media: ";
     510localizedStrings["Medium"] = "Medium";
    508511localizedStrings["Memory"] = "Memory";
    509512localizedStrings["Memory: %s"] = "Memory: %s";
     
    606609localizedStrings["Primary Key"] = "Primary Key";
    607610localizedStrings["Primary Key \u2014 %s"] = "Primary Key \u2014 %s";
     611localizedStrings["Priority"] = "Priority";
    608612localizedStrings["Probe Expression"] = "Probe Expression";
    609613localizedStrings["Probe Sample Recorded"] = "Probe Sample Recorded";
     
    612616localizedStrings["Properties"] = "Properties";
    613617localizedStrings["Property"] = "Property";
     618localizedStrings["Protocol"] = "Protocol";
    614619localizedStrings["Query Parameters"] = "Query Parameters";
    615620localizedStrings["Query String"] = "Query String";
     
    631636localizedStrings["Region announced in its entirety."] = "Region announced in its entirety.";
    632637localizedStrings["Reload page (%s)\nReload ignoring cache (%s)"] = "Reload page (%s)\nReload ignoring cache (%s)";
     638localizedStrings["Remote Address"] = "Remote Address";
    633639localizedStrings["Removals"] = "Removals";
    634640localizedStrings["Remove Watch Expression"] = "Remove Watch Expression";
  • trunk/Source/WebInspectorUI/UserInterface/Controllers/FrameResourceManager.js

    r213666 r213682  
    415415    }
    416416
    417     resourceRequestDidFinishLoading(requestIdentifier, timestamp, sourceMapURL)
     417    resourceRequestDidFinishLoading(requestIdentifier, timestamp, sourceMapURL, metrics)
    418418    {
    419419        // Called from WebInspector.NetworkObserver.
     
    430430            return;
    431431
    432         var elapsedTime = WebInspector.timelineManager.computeElapsedTime(timestamp);
     432        if (metrics)
     433            resource.updateWithMetrics(metrics);
     434
     435        let elapsedTime = WebInspector.timelineManager.computeElapsedTime(timestamp);
    433436        resource.markAsFinished(elapsedTime);
    434437
     
    454457            return;
    455458
    456         var elapsedTime = WebInspector.timelineManager.computeElapsedTime(timestamp);
     459        let elapsedTime = WebInspector.timelineManager.computeElapsedTime(timestamp);
    457460        resource.markAsFailed(canceled, elapsedTime);
    458461
  • trunk/Source/WebInspectorUI/UserInterface/Models/Resource.js

    r213621 r213682  
    6464        this._responseSource = WebInspector.Resource.ResponseSource.Unknown;
    6565        this._timingData = new WebInspector.ResourceTimingData(this);
     66        this._protocol = null;
     67        this._priority = WebInspector.Resource.NetworkPriority.Unknown;
     68        this._remoteAddress = null;
     69        this._connectionIdentifier = null;
    6670        this._target = targetId ? WebInspector.targetManager.targetForIdentifier(targetId) : WebInspector.mainTarget;
    6771
     
    129133            return WebInspector.UIString("Other");
    130134        default:
    131             console.error("Unknown resource type: ", type);
     135            console.error("Unknown resource type", type);
    132136            return null;
    133137        }
     
    149153            return WebInspector.Resource.ResponseSource.DiskCache;
    150154        default:
    151             console.error("Unknown response source type: ", source);
     155            console.error("Unknown response source type", source);
    152156            return WebInspector.Resource.ResponseSource.Unknown;
    153157        }
     158    }
     159
     160    static networkPriorityFromPayload(priority)
     161    {
     162        switch (priority) {
     163        case NetworkAgent.MetricsPriority.Low:
     164            return WebInspector.Resource.NetworkPriority.Low;
     165        case NetworkAgent.MetricsPriority.Medium:
     166            return WebInspector.Resource.NetworkPriority.Medium;
     167        case NetworkAgent.MetricsPriority.High:
     168            return WebInspector.Resource.NetworkPriority.High;
     169        default:
     170            console.error("Unknown metrics priority", priority);
     171            return WebInspector.Resource.NetworkPriority.Unknown;
     172        }
     173    }
     174
     175    static connectionIdentifierFromPayload(connectionIdentifier)
     176    {
     177        // Map backend connection identifiers to an easier to read number.
     178        if (!WebInspector.Resource.connectionIdentifierMap) {
     179            WebInspector.Resource.connectionIdentifierMap = new Map;
     180            WebInspector.Resource.nextConnectionIdentifier = 1;
     181        }
     182
     183        let id = WebInspector.Resource.connectionIdentifierMap.get(connectionIdentifier);
     184        if (id)
     185            return id;
     186
     187        id = WebInspector.Resource.nextConnectionIdentifier++;
     188        WebInspector.Resource.connectionIdentifierMap.set(connectionIdentifier, id);
     189        return id;
    154190    }
    155191
     
    166202    get responseSource() { return this._responseSource; }
    167203    get timingData() { return this._timingData; }
     204    get protocol() { return this._protocol; }
     205    get priority() { return this._priority; }
     206    get remoteAddress() { return this._remoteAddress; }
     207    get connectionIdentifier() { return this._connectionIdentifier; }
    168208
    169209    get url()
     
    519559        this.dispatchEventToListeners(WebInspector.Resource.Event.ResponseReceived);
    520560        this.dispatchEventToListeners(WebInspector.Resource.Event.TimestampsDidChange);
     561    }
     562
     563    updateWithMetrics(metrics)
     564    {
     565        if (metrics.protocol)
     566            this._protocol = metrics.protocol;
     567        if (metrics.priority)
     568            this._priority = WebInspector.Resource.networkPriorityFromPayload(metrics.priority);
     569        if (metrics.remoteAddress)
     570            this._remoteAddress = metrics.remoteAddress;
     571        if (metrics.connectionIdentifier)
     572            this._connectionIdentifier = WebInspector.Resource.connectionIdentifierFromPayload(metrics.connectionIdentifier);
    521573    }
    522574
     
    798850    MemoryCache: Symbol("memory-cache"),
    799851    DiskCache: Symbol("disk-cache"),
     852};
     853
     854WebInspector.Resource.NetworkPriority = {
     855    Unknown: Symbol("unknown"),
     856    Low: Symbol("low"),
     857    Medium: Symbol("medium"),
     858    High: Symbol("high"),
    800859};
    801860
  • trunk/Source/WebInspectorUI/UserInterface/Protocol/NetworkObserver.js

    r213666 r213682  
    4949    }
    5050
    51     loadingFinished(requestId, timestamp, sourceMapURL)
     51    loadingFinished(requestId, timestamp, sourceMapURL, metrics)
    5252    {
    53         WebInspector.frameResourceManager.resourceRequestDidFinishLoading(requestId, timestamp, sourceMapURL);
     53        WebInspector.frameResourceManager.resourceRequestDidFinishLoading(requestId, timestamp, sourceMapURL, metrics);
    5454    }
    5555
  • trunk/Source/WebInspectorUI/UserInterface/Views/DataGrid.js

    r213622 r213682  
    3838        this._sortOrder = WebInspector.DataGrid.SortOrder.Indeterminate;
    3939        this._sortOrderSetting = null;
    40         this._hiddenColumnSetting = null;
     40        this._columnVisibilitySetting = null;
    4141        this._columnChooserEnabled = false;
    4242        this._headerVisible = true;
     
    363363        this._sortColumnIdentifierSetting = new WebInspector.Setting(this._settingsIdentifier + "-sort", this._sortColumnIdentifier);
    364364        this._sortOrderSetting = new WebInspector.Setting(this._settingsIdentifier + "-sort-order", this._sortOrder);
    365         this._hiddenColumnSetting = new WebInspector.Setting(this._settingsIdentifier + "-hidden-columns", []);
     365        this._columnVisibilitySetting = new WebInspector.Setting(this._settingsIdentifier + "-column-visibility", {});
    366366
    367367        if (!this.columns)
     
    373373        }
    374374
    375         for (let columnIdentifier of this._hiddenColumnSetting.value)
    376             this.setColumnVisible(columnIdentifier, false);
     375        let visibilitySettings = this._columnVisibilitySetting.value;
     376        for (let columnIdentifier in visibilitySettings) {
     377            let visible = visibilitySettings[columnIdentifier];
     378            this.setColumnVisible(columnIdentifier, visible);
     379        }
    377380    }
    378381
     
    920923        column.hidden = !visible;
    921924
    922         if (this._hiddenColumnSetting) {
    923             let hiddenColumns = this._hiddenColumnSetting.value.slice();
    924             if (column.hidden)
    925                 hiddenColumns.push(columnIdentifier);
    926             else
    927                 hiddenColumns.remove(columnIdentifier);
    928 
    929             this._hiddenColumnSetting.value = hiddenColumns;
     925        if (this._columnVisibilitySetting) {
     926            if (this._columnVisibilitySetting.value[columnIdentifier] !== visible) {
     927                let copy = Object.shallowCopy(this._columnVisibilitySetting.value);
     928                copy[columnIdentifier] = visible;
     929                this._columnVisibilitySetting.value = copy;
     930            }
    930931        }
    931932
  • trunk/Source/WebInspectorUI/UserInterface/Views/NetworkGridContentView.js

    r213621 r213682  
    4040        this._contentTreeOutline.addEventListener(WebInspector.TreeOutline.Event.SelectionDidChange, this._treeSelectionDidChange, this);
    4141
    42         var columns = {domain: {}, type: {}, method: {}, scheme: {}, statusCode: {}, cached: {}, size: {}, transferSize: {}, requestSent: {}, latency: {}, duration: {}, graph: {}};
     42        let columns = {domain: {}, type: {}, method: {}, scheme: {}, statusCode: {}, cached: {}, protocol: {}, priority: {}, remoteAddress: {}, connectionIdentifier: {}, size: {}, transferSize: {}, requestSent: {}, latency: {}, duration: {}, graph: {}};
    4343
    4444        columns.domain.title = WebInspector.UIString("Domain");
     
    5959        columns.cached.title = WebInspector.UIString("Cached");
    6060        columns.cached.width = "8%";
     61
     62        columns.protocol.title = WebInspector.UIString("Protocol");
     63        columns.protocol.width = "5%";
     64        columns.protocol.hidden = true;
     65
     66        columns.priority.title = WebInspector.UIString("Priority");
     67        columns.priority.width = "5%";
     68        columns.priority.hidden = true;
     69
     70        columns.remoteAddress.title = WebInspector.UIString("Remote Address");
     71        columns.remoteAddress.width = "8%";
     72        columns.remoteAddress.hidden = true;
     73
     74        columns.connectionIdentifier.title = WebInspector.UIString("Connection");
     75        columns.connectionIdentifier.width = "5%";
     76        columns.connectionIdentifier.hidden = true;
     77        columns.connectionIdentifier.aligned = "right";
    6178
    6279        columns.size.title = WebInspector.UIString("Size");
     
    8097        columns.duration.aligned = "right";
    8198
    82         for (var column in columns)
     99        for (let column in columns)
    83100            columns[column].sortable = true;
    84101
     
    90107        columns.graph.headerView = this._timelineRuler;
    91108        columns.graph.sortable = false;
     109
     110        // COMPATIBILITY(iOS 10.3): Network load metrics were not previously available.
     111        if (!NetworkAgent.hasEventParameter("loadingFinished", "metrics")) {
     112            delete columns.protocol;
     113            delete columns.priority;
     114            delete columns.remoteAddress;
     115            delete columns.connectionIdentifier;
     116        }
    92117
    93118        this._dataGrid = new WebInspector.TimelineDataGrid(columns, this._contentTreeOutline);
     
    100125        this.addSubview(this._dataGrid);
    101126
    102         var networkTimeline = WebInspector.timelineManager.persistentNetworkTimeline;
     127        let networkTimeline = WebInspector.timelineManager.persistentNetworkTimeline;
    103128        networkTimeline.addEventListener(WebInspector.Timeline.Event.RecordAdded, this._networkTimelineRecordAdded, this);
    104129        networkTimeline.addEventListener(WebInspector.Timeline.Event.Reset, this._networkTimelineReset, this);
  • trunk/Source/WebInspectorUI/UserInterface/Views/NetworkTimelineView.js

    r213621 r213682  
    3232        console.assert(timeline.type === WebInspector.TimelineRecord.Type.Network);
    3333
    34         let columns = {name: {}, domain: {}, type: {}, method: {}, scheme: {}, statusCode: {}, cached: {}, size: {}, transferSize: {}, requestSent: {}, latency: {}, duration: {}, graph: {}};
     34        let columns = {name: {}, domain: {}, type: {}, method: {}, scheme: {}, statusCode: {}, cached: {}, protocol: {}, priority: {}, remoteAddress: {}, connectionIdentifier: {}, size: {}, transferSize: {}, requestSent: {}, latency: {}, duration: {}, graph: {}};
    3535
    3636        columns.name.title = WebInspector.UIString("Name");
     
    4545        columns.type.width = "7%";
    4646
    47         var typeToLabelMap = new Map;
    48         for (var key in WebInspector.Resource.Type) {
    49             var value = WebInspector.Resource.Type[key];
     47        let typeToLabelMap = new Map;
     48        for (let key in WebInspector.Resource.Type) {
     49            let value = WebInspector.Resource.Type[key];
    5050            typeToLabelMap.set(value, WebInspector.Resource.displayNameForType(value, true));
    5151        }
     
    6565        columns.cached.title = WebInspector.UIString("Cached");
    6666        columns.cached.width = "6%";
     67
     68        columns.protocol.title = WebInspector.UIString("Protocol");
     69        columns.protocol.width = "5%";
     70        columns.protocol.hidden = true;
     71
     72        columns.priority.title = WebInspector.UIString("Priority");
     73        columns.priority.width = "5%";
     74        columns.priority.hidden = true;
     75
     76        columns.remoteAddress.title = WebInspector.UIString("Remote Address");
     77        columns.remoteAddress.width = "8%";
     78        columns.remoteAddress.hidden = true;
     79
     80        columns.connectionIdentifier.title = WebInspector.UIString("Connection");
     81        columns.connectionIdentifier.width = "5%";
     82        columns.connectionIdentifier.hidden = true;
     83        columns.connectionIdentifier.aligned = "right";
    6784
    6885        columns.size.title = WebInspector.UIString("Size");
     
    86103        columns.duration.aligned = "right";
    87104
    88         for (var column in columns)
     105        for (let column in columns)
    89106            columns[column].sortable = true;
    90107
     
    96113        columns.graph.headerView = this._timelineRuler;
    97114        columns.graph.sortable = false;
     115
     116        // COMPATIBILITY(iOS 10.3): Network load metrics were not previously available.
     117        if (!NetworkAgent.hasEventParameter("loadingFinished", "metrics")) {
     118            delete columns.protocol;
     119            delete columns.priority;
     120            delete columns.remoteAddress;
     121            delete columns.connectionIdentifier;
     122        }
    98123
    99124        this._dataGrid = new WebInspector.TimelineDataGrid(columns);
  • trunk/Source/WebInspectorUI/UserInterface/Views/ResourceDetailsSidebarPanel.js

    r212423 r213682  
    6969
    7070        this._requestMethodRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Method"));
     71        this._protocolRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Protocol"));
     72        this._priorityRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Priority"));
    7173        this._cachedRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Cached"));
    7274
     
    8183        this._compressionRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Compression"));
    8284
    83         var requestGroup = new WebInspector.DetailsSectionGroup([this._requestMethodRow, this._cachedRow]);
    84         var statusGroup = new WebInspector.DetailsSectionGroup([this._statusTextRow, this._statusCodeRow]);
    85         var sizeGroup = new WebInspector.DetailsSectionGroup([this._encodedSizeRow, this._decodedSizeRow, this._transferSizeRow]);
    86         var compressionGroup = new WebInspector.DetailsSectionGroup([this._compressedRow, this._compressionRow]);
     85        let requestGroup = new WebInspector.DetailsSectionGroup([this._requestMethodRow, this._protocolRow, this._priorityRow, this._cachedRow]);
     86        let statusGroup = new WebInspector.DetailsSectionGroup([this._statusTextRow, this._statusCodeRow]);
     87        let sizeGroup = new WebInspector.DetailsSectionGroup([this._encodedSizeRow, this._decodedSizeRow, this._transferSizeRow]);
     88        let compressionGroup = new WebInspector.DetailsSectionGroup([this._compressedRow, this._compressionRow]);
    8789
    8890        this._requestAndResponseSection = new WebInspector.DetailsSection("resource-request-response", WebInspector.UIString("Request & Response"), [requestGroup, statusGroup, sizeGroup, compressionGroup]);
     
    291293    _refreshRequestAndResponse()
    292294    {
    293         var resource = this._resource;
    294         if (!resource)
     295        if (!this._resource)
    295296            return;
    296297
     
    298299        // This keeps the UI from shifting around as data comes in.
    299300
    300         this._requestMethodRow.value = resource.requestMethod || emDash;
    301 
    302         this._cachedRow.value = resource.cached ? WebInspector.UIString("Yes") : WebInspector.UIString("No");
    303 
    304         this._statusCodeRow.value = resource.statusCode || emDash;
    305         this._statusTextRow.value = resource.statusText || emDash;
     301        this._requestMethodRow.value = this._resource.requestMethod || emDash;
     302
     303        // COMPATIBILITY(iOS 10.3): Network load metrics were not previously available.
     304        if (NetworkAgent.hasEventParameter("loadingFinished", "metrics")) {
     305            this._protocolRow.value = this._resource.protocol || emDash;
     306
     307            switch (this._resource.priority) {
     308            case WebInspector.Resource.NetworkPriority.Low:
     309                this._priorityRow.value = WebInspector.UIString("Low");
     310                break;
     311            case WebInspector.Resource.NetworkPriority.Medium:
     312                this._priorityRow.value = WebInspector.UIString("Medium");
     313                break;
     314            case WebInspector.Resource.NetworkPriority.High:
     315                this._priorityRow.value = WebInspector.UIString("High");
     316                break;
     317            default:
     318                this._priorityRow.value = emDash;
     319                break;
     320            }
     321        }
     322
     323        this._cachedRow.value = this._resource.cached ? WebInspector.UIString("Yes") : WebInspector.UIString("No");
     324
     325        this._statusCodeRow.value = this._resource.statusCode || emDash;
     326        this._statusTextRow.value = this._resource.statusText || emDash;
    306327
    307328        this._refreshResponseHeaders();
  • trunk/Source/WebInspectorUI/UserInterface/Views/ResourceTimelineDataGridNode.js

    r213621 r213682  
    8181            data.duration = resource.receiveDuration;
    8282            data.latency = resource.latency;
     83            data.protocol = resource.protocol;
     84            data.priority = resource.priority;
     85            data.remoteAddress = resource.remoteAddress;
     86            data.connectionIdentifier = resource.connectionIdentifier;
    8387        }
    8488
     
    126130        case "duration":
    127131            return isNaN(value) ? emDash : Number.secondsToString(value, true);
     132
     133        case "protocol":
     134        case "remoteAddress":
     135        case "connectionIdentifier":
     136            return value || emDash;
     137
     138        case "priority":
     139            return this._displayNameForPriority(value);
    128140        }
    129141
     
    188200
    189201    // Private
     202
     203    _displayNameForPriority(priority)
     204    {
     205        switch (priority) {
     206        case WebInspector.Resource.NetworkPriority.Low:
     207            return WebInspector.UIString("Low");
     208        case WebInspector.Resource.NetworkPriority.Medium:
     209            return WebInspector.UIString("Medium");
     210        case WebInspector.Resource.NetworkPriority.High:
     211            return WebInspector.UIString("High");
     212        }
     213
     214        return emDash;
     215    }
    190216
    191217    _createNameCellDocumentFragment()
     
    227253        let responseSource = this._resource.responseSource;
    228254        if (responseSource === WebInspector.Resource.ResponseSource.MemoryCache || responseSource === WebInspector.Resource.ResponseSource.DiskCache) {
    229             console.assert(this._resource.cached, "This resource has a cache responseSource it should also be marked as cached", resource);
     255            console.assert(this._resource.cached, "This resource has a cache responseSource it should also be marked as cached", this._resource);
    230256            let span = document.createElement("span");
    231257            let cacheType = document.createElement("span");
  • trunk/Source/WebInspectorUI/UserInterface/Views/TimelineDataGridNode.js

    r212570 r213682  
    227227            return;
    228228
    229         var secondsPerPixel = this._graphDataSource.secondsPerPixel;
    230         console.assert(isFinite(secondsPerPixel) && secondsPerPixel > 0);
     229        let secondsPerPixel = this._graphDataSource.secondsPerPixel;
     230        if (isNaN(secondsPerPixel))
     231            return;
     232
     233        console.assert(secondsPerPixel > 0);
    231234
    232235        var recordBarIndex = 0;
  • trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRecordBar.js

    r205578 r213682  
    232232    refresh(graphDataSource)
    233233    {
     234        if (isNaN(graphDataSource.secondsPerPixel))
     235            return;
     236
    234237        console.assert(graphDataSource.zeroTime);
    235238        console.assert(graphDataSource.startTime);
  • trunk/Source/WebKit2/ChangeLog

    r213676 r213682  
     12017-03-09  Joseph Pecoraro  <pecoraro@apple.com>
     2
     3        Web Inspector: Show HTTP protocol version and other Network Load Metrics (IP Address, Priority, Connection ID)
     4        https://bugs.webkit.org/show_bug.cgi?id=29687
     5        <rdar://problem/19281586>
     6
     7        Reviewed by Matt Baker and Brian Burg.
     8
     9        * NetworkProcess/cocoa/NetworkSessionCocoa.mm:
     10        (toNetworkLoadPriority):
     11        (-[WKNetworkSessionDelegate URLSession:task:didFinishCollectingMetrics:]):
     12        * Shared/WebCoreArgumentCoders.h:
     13        Additional optional metrics on NetworkLoadMetrics.
     14
    1152017-03-09  Daniel Bates  <dabates@apple.com>
    216
  • trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkSessionCocoa.mm

    r213441 r213682  
    8181}
    8282
     83static WebCore::NetworkLoadPriority toNetworkLoadPriority(float priority)
     84{
     85    if (priority <= NSURLSessionTaskPriorityLow)
     86        return WebCore::NetworkLoadPriority::Low;
     87    if (priority >= NSURLSessionTaskPriorityHigh)
     88        return WebCore::NetworkLoadPriority::High;
     89    return WebCore::NetworkLoadPriority::Medium;
     90}
     91
    8392@interface WKNetworkSessionDelegate : NSObject <NSURLSessionDataDelegate> {
    8493    RefPtr<WebKit::NetworkSessionCocoa> _session;
     
    291300        networkLoadMetrics.responseEnd = Seconds(responseEndInterval);
    292301        networkLoadMetrics.markComplete();
     302
    293303        networkLoadMetrics.protocol = String(m.networkProtocolName);
     304        networkLoadMetrics.priority = toNetworkLoadPriority(task.priority);
     305#if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300) || (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000)
     306        networkLoadMetrics.remoteAddress = String(m._remoteAddressAndPort);
     307        networkLoadMetrics.connectionIdentifier = String([m._connectionIdentifier UUIDString]);
     308#endif
    294309    }
    295310}
  • trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.h

    r213601 r213682  
    3131#include <WebCore/FrameLoaderTypes.h>
    3232#include <WebCore/IndexedDB.h>
     33#include <WebCore/NetworkLoadMetrics.h>
    3334#include <WebCore/PaymentHeaders.h>
    3435#include <WebCore/ScrollSnapOffsetsInfo.h>
     
    679680};
    680681
     682template<> struct EnumTraits<WebCore::NetworkLoadPriority> {
     683    using values = EnumValues<
     684        WebCore::NetworkLoadPriority,
     685        WebCore::NetworkLoadPriority::Low,
     686        WebCore::NetworkLoadPriority::Medium,
     687        WebCore::NetworkLoadPriority::High
     688    >;
     689};
     690
    681691#if ENABLE(INDEXED_DATABASE)
    682692template<> struct EnumTraits<WebCore::IndexedDB::GetAllType> {
Note: See TracChangeset for help on using the changeset viewer.