Skip to content
Permalink
Browse files
Web Inspector: include referrerPolicy in "Copy as fetch"
https://bugs.webkit.org/show_bug.cgi?id=241218
<rdar://problem/94698964>

Reviewed by Patrick Angle.

* Source/JavaScriptCore/inspector/protocol/Network.json:
* Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp:
(WebCore::toProtocol):
(WebCore::buildObjectForResourceRequest):
(WebCore::InspectorNetworkAgent::willSendRequest):
(WebCore::InspectorNetworkAgent::willSendRequestOfType):
(WebCore::InspectorNetworkAgent::interceptRequest):
Add a `Network.ReferrerPolicy` protocol enum (corresponding to `WebCore::ReferrerPolicy`) and pass it to the frontend.

* Source/WebCore/inspector/InspectorInstrumentation.h:
(WebCore::InspectorInstrumentation::willSendRequest):
* Source/WebCore/inspector/InspectorInstrumentation.cpp:
(WebCore::InspectorInstrumentation::willSendRequestImpl):
* Source/WebCore/loader/ResourceLoadNotifier.h:
* Source/WebCore/loader/ResourceLoadNotifier.cpp:
(WebCore::ResourceLoadNotifier::willSendRequest):
(WebCore::ResourceLoadNotifier::dispatchWillSendRequest):
* Source/WebCore/loader/ResourceLoader.cpp:
(WebCore::ResourceLoader::willSendRequestInternal):
* Source/WebCore/loader/appcache/ApplicationCacheGroup.cpp:
(WebCore::ApplicationCacheGroup::update):
(WebCore::ApplicationCacheGroup::startLoadingEntry):
Pass along a `ResourceLoader*` when `willSendRequest` so that the `InspectorNetworkAgent` can look
at it to get the `FetchOptions` for that request.

* Source/WebInspectorUI/UserInterface/Models/Resource.js:
(WI.Resource.prototype.get referrerPolicy): Added.
(WI.Resource.prototype.updateForRedirectResponse):
(WI.Resource.prototype.generateFetchCode):
* Source/WebInspectorUI/UserInterface/Controllers/NetworkManager.js:
(WI.NetworkManager.prototype.resourceRequestWillBeSent):
Pass along the `Network.ReferrerPolicy` whenever creating/updating a `WI.Resource` with a `Network.Request`.

* Source/WebCore/inspector/agents/InspectorPageAgent.h:
* Source/WebCore/inspector/agents/InspectorPageAgent.cpp:
(WebCore::InspectorPageAgent::cachedResource):
Drive-by: Change to `const Frame*`.

* LayoutTests/http/tests/inspector/network/copy-as-fetch.html:
* LayoutTests/http/tests/inspector/network/copy-as-fetch-expected.txt:

Canonical link: https://commits.webkit.org/251818@main
  • Loading branch information
dcrousso committed Jun 24, 2022
1 parent 6dfa4f8 commit 531afa8f61ee4bb09cc15dea91bd0dc280ef0fd1
Show file tree
Hide file tree
Showing 15 changed files with 129 additions and 36 deletions.
@@ -13,7 +13,8 @@ fetch("http://127.0.0.1:8000/inspector/network/resources/url?query=true", {
"method": "GET",
"mode": "cors",
"redirect": "follow",
"referrer": "http://127.0.0.1:8000/inspector/network/copy-as-fetch.html"
"referrer": "http://127.0.0.1:8000/inspector/network/copy-as-fetch.html",
"referrerPolicy": "strict-origin-when-cross-origin"
})

-- Running test case: WI.Resource.prototype.generateFetchCode.SpecialURL
@@ -27,7 +28,8 @@ fetch("http://127.0.0.1:8000/inspector/network/resources/url'with$special%7B1..2
"method": "GET",
"mode": "cors",
"redirect": "follow",
"referrer": "http://127.0.0.1:8000/inspector/network/copy-as-fetch.html"
"referrer": "http://127.0.0.1:8000/inspector/network/copy-as-fetch.html",
"referrerPolicy": "strict-origin-when-cross-origin"
})

-- Running test case: WI.Resource.prototype.generateFetchCode.SpecialHeaders
@@ -44,7 +46,8 @@ fetch("http://127.0.0.1:8000/inspector/network/resources/url", {
"method": "GET",
"mode": "cors",
"redirect": "follow",
"referrer": "http://127.0.0.1:8000/inspector/network/copy-as-fetch.html"
"referrer": "http://127.0.0.1:8000/inspector/network/copy-as-fetch.html",
"referrerPolicy": "strict-origin-when-cross-origin"
})

-- Running test case: WI.Resource.prototype.generateFetchCode.URLUTF8
@@ -58,7 +61,8 @@ fetch("http://127.0.0.1:8000/inspector/network/resources/url?utf8=%F0%9F%91%8D",
"method": "GET",
"mode": "cors",
"redirect": "follow",
"referrer": "http://127.0.0.1:8000/inspector/network/copy-as-fetch.html"
"referrer": "http://127.0.0.1:8000/inspector/network/copy-as-fetch.html",
"referrerPolicy": "strict-origin-when-cross-origin"
})

-- Running test case: WI.Resource.prototype.generateFetchCode.POSTRequestURLEncodedData
@@ -74,7 +78,8 @@ fetch("http://127.0.0.1:8000/inspector/network/resources/url", {
"method": "POST",
"mode": "cors",
"redirect": "follow",
"referrer": "http://127.0.0.1:8000/inspector/network/copy-as-fetch.html"
"referrer": "http://127.0.0.1:8000/inspector/network/copy-as-fetch.html",
"referrerPolicy": "strict-origin-when-cross-origin"
})

-- Running test case: WI.Resource.prototype.generateFetchCode.POSTRequestURLUTF8
@@ -90,7 +95,8 @@ fetch("http://127.0.0.1:8000/inspector/network/resources/url?utf8=%F0%9F%91%8D",
"method": "POST",
"mode": "cors",
"redirect": "follow",
"referrer": "http://127.0.0.1:8000/inspector/network/copy-as-fetch.html"
"referrer": "http://127.0.0.1:8000/inspector/network/copy-as-fetch.html",
"referrerPolicy": "strict-origin-when-cross-origin"
})

-- Running test case: WI.Resource.prototype.generateFetchCode.PUTRequestWithJSON
@@ -106,6 +112,36 @@ fetch("http://127.0.0.1:8000/inspector/network/resources/url", {
"method": "PUT",
"mode": "cors",
"redirect": "follow",
"referrer": "http://127.0.0.1:8000/inspector/network/copy-as-fetch.html"
"referrer": "http://127.0.0.1:8000/inspector/network/copy-as-fetch.html",
"referrerPolicy": "strict-origin-when-cross-origin"
})

-- Running test case: WI.Resource.prototype.generateFetchCode.ReferrerPolicy.EmptyString
fetch("http://127.0.0.1:8000/inspector/network/resources/url", {
"cache": "default",
"credentials": "omit",
"headers": {
"Accept": "*/*",
"User-Agent": <filtered>
},
"method": "GET",
"mode": "cors",
"redirect": "follow",
"referrer": "http://127.0.0.1:8000/inspector/network/copy-as-fetch.html",
"referrerPolicy": "strict-origin-when-cross-origin"
})

-- Running test case: WI.Resource.prototype.generateFetchCode.ReferrerPolicy.NoReferrer
fetch("http://127.0.0.1:8000/inspector/network/resources/url", {
"cache": "default",
"credentials": "omit",
"headers": {
"Accept": "*/*",
"User-Agent": <filtered>
},
"method": "GET",
"mode": "cors",
"redirect": "follow",
"referrerPolicy": "no-referrer"
})

@@ -71,9 +71,12 @@
{name: "POSTRequestURLEncodedData", expression: `createPOSTRequestWithURLEncodedData()`},
{name: "POSTRequestURLUTF8", expression: `createPOSTRequestWithUTF8()`},
{name: "PUTRequestWithJSON", expression: `createPUTRequestWithJSON()`},

{name: "ReferrerPolicy.EmptyString", expression: `fetch("resources/url", {referrerPolicy: ""})`},
{name: "ReferrerPolicy.NoReferrer", expression: `fetch("resources/url", {referrerPolicy: "no-referrer"})`},
].forEach(({name, expression}) => {
suite.addTestCase({
name: suite.name + "." + name,
name: "WI.Resource.prototype.generateFetchCode." + name,
async test() {
let [resourceWasAddedEvent] = await Promise.all([
WI.Frame.awaitEvent(WI.Frame.Event.ResourceWasAdded),
@@ -29,6 +29,22 @@
"type": "number",
"description": "Number of seconds since epoch."
},
{
"id": "ReferrerPolicy",
"type": "string",
"description": "Controls how much referrer information is sent with the request",
"enum": [
"empty-string",
"no-referrer",
"no-referrer-when-downgrade",
"same-origin",
"origin",
"strict-origin",
"origin-when-cross-origin",
"strict-origin-when-cross-origin",
"unsafe-url"
]
},
{
"id": "Headers",
"type": "object",
@@ -61,7 +77,8 @@
{ "name": "url", "type": "string", "description": "Request URL." },
{ "name": "method", "type": "string", "description": "HTTP request method." },
{ "name": "headers", "$ref": "Headers", "description": "HTTP request headers." },
{ "name": "postData", "type": "string", "optional": true, "description": "HTTP POST request data." }
{ "name": "postData", "type": "string", "optional": true, "description": "HTTP POST request data." },
{ "name": "referrerPolicy", "$ref": "ReferrerPolicy", "optional": true, "description": "The level of included referrer information." }
]
},
{
@@ -590,10 +590,10 @@ void InspectorInstrumentation::flexibleBoxRendererWrappedToNextLineImpl(Instrume
domAgent->flexibleBoxRendererWrappedToNextLine(renderer, lineStartItemIndex);
}

void InspectorInstrumentation::willSendRequestImpl(InstrumentingAgents& instrumentingAgents, ResourceLoaderIdentifier identifier, DocumentLoader* loader, ResourceRequest& request, const ResourceResponse& redirectResponse, const CachedResource* cachedResource)
void InspectorInstrumentation::willSendRequestImpl(InstrumentingAgents& instrumentingAgents, ResourceLoaderIdentifier identifier, DocumentLoader* loader, ResourceRequest& request, const ResourceResponse& redirectResponse, const CachedResource* cachedResource, ResourceLoader* resourceLoader)
{
if (auto* networkAgent = instrumentingAgents.enabledNetworkAgent())
networkAgent->willSendRequest(identifier, loader, request, redirectResponse, cachedResource);
networkAgent->willSendRequest(identifier, loader, request, redirectResponse, cachedResource, resourceLoader);
}

void InspectorInstrumentation::willSendRequestOfTypeImpl(InstrumentingAgents& instrumentingAgents, ResourceLoaderIdentifier identifier, DocumentLoader* loader, ResourceRequest& request, LoadType loadType)
@@ -194,7 +194,7 @@ class InspectorInstrumentation {
static void flexibleBoxRendererBeganLayout(const RenderObject&);
static void flexibleBoxRendererWrappedToNextLine(const RenderObject&, size_t lineStartItemIndex);

static void willSendRequest(Frame*, ResourceLoaderIdentifier, DocumentLoader*, ResourceRequest&, const ResourceResponse& redirectResponse, const CachedResource*);
static void willSendRequest(Frame*, ResourceLoaderIdentifier, DocumentLoader*, ResourceRequest&, const ResourceResponse& redirectResponse, const CachedResource*, ResourceLoader*);
static void didLoadResourceFromMemoryCache(Page&, DocumentLoader*, CachedResource*);
static void didReceiveResourceResponse(Frame&, ResourceLoaderIdentifier, DocumentLoader*, const ResourceResponse&, ResourceLoader*);
static void didReceiveThreadableLoaderResponse(DocumentThreadableLoader&, ResourceLoaderIdentifier);
@@ -416,7 +416,7 @@ class InspectorInstrumentation {
static void flexibleBoxRendererBeganLayoutImpl(InstrumentingAgents&, const RenderObject&);
static void flexibleBoxRendererWrappedToNextLineImpl(InstrumentingAgents&, const RenderObject&, size_t lineStartItemIndex);

static void willSendRequestImpl(InstrumentingAgents&, ResourceLoaderIdentifier, DocumentLoader*, ResourceRequest&, const ResourceResponse& redirectResponse, const CachedResource*);
static void willSendRequestImpl(InstrumentingAgents&, ResourceLoaderIdentifier, DocumentLoader*, ResourceRequest&, const ResourceResponse& redirectResponse, const CachedResource*, ResourceLoader*);
static void willSendRequestOfTypeImpl(InstrumentingAgents&, ResourceLoaderIdentifier, DocumentLoader*, ResourceRequest&, LoadType);
static void markResourceAsCachedImpl(InstrumentingAgents&, ResourceLoaderIdentifier);
static void didLoadResourceFromMemoryCacheImpl(InstrumentingAgents&, DocumentLoader*, CachedResource*);
@@ -1060,17 +1060,17 @@ inline void InspectorInstrumentation::flexibleBoxRendererWrappedToNextLine(const
flexibleBoxRendererWrappedToNextLineImpl(*agents, renderer, lineStartItemIndex);
}

inline void InspectorInstrumentation::willSendRequest(Frame* frame, ResourceLoaderIdentifier identifier, DocumentLoader* loader, ResourceRequest& request, const ResourceResponse& redirectResponse, const CachedResource* cachedResource)
inline void InspectorInstrumentation::willSendRequest(Frame* frame, ResourceLoaderIdentifier identifier, DocumentLoader* loader, ResourceRequest& request, const ResourceResponse& redirectResponse, const CachedResource* cachedResource, ResourceLoader* resourceLoader)
{
FAST_RETURN_IF_NO_FRONTENDS(void());
if (auto* agents = instrumentingAgents(frame))
willSendRequestImpl(*agents, identifier, loader, request, redirectResponse, cachedResource);
willSendRequestImpl(*agents, identifier, loader, request, redirectResponse, cachedResource, resourceLoader);
}

inline void InspectorInstrumentation::willSendRequest(WorkerOrWorkletGlobalScope& globalScope, ResourceLoaderIdentifier identifier, ResourceRequest& request)
{
FAST_RETURN_IF_NO_FRONTENDS(void());
willSendRequestImpl(instrumentingAgents(globalScope), identifier, nullptr, request, ResourceResponse { }, nullptr);
willSendRequestImpl(instrumentingAgents(globalScope), identifier, nullptr, request, ResourceResponse { }, nullptr, nullptr);
}

inline void InspectorInstrumentation::willSendRequestOfType(Frame* frame, ResourceLoaderIdentifier identifier, DocumentLoader* loader, ResourceRequest& request, LoadType loadType)
@@ -299,17 +299,49 @@ Ref<Protocol::Network::Metrics> InspectorNetworkAgent::buildObjectForMetrics(con
return metrics;
}

static Ref<Protocol::Network::Request> buildObjectForResourceRequest(const ResourceRequest& request)
static Protocol::Network::ReferrerPolicy toProtocol(ReferrerPolicy referrerPolicy)
{
switch (referrerPolicy) {
case ReferrerPolicy::EmptyString:
return Protocol::Network::ReferrerPolicy::EmptyString;
case ReferrerPolicy::NoReferrer:
return Protocol::Network::ReferrerPolicy::NoReferrer;
case ReferrerPolicy::NoReferrerWhenDowngrade:
return Protocol::Network::ReferrerPolicy::NoReferrerWhenDowngrade;
case ReferrerPolicy::SameOrigin:
return Protocol::Network::ReferrerPolicy::SameOrigin;
case ReferrerPolicy::Origin:
return Protocol::Network::ReferrerPolicy::Origin;
case ReferrerPolicy::StrictOrigin:
return Protocol::Network::ReferrerPolicy::StrictOrigin;
case ReferrerPolicy::OriginWhenCrossOrigin:
return Protocol::Network::ReferrerPolicy::OriginWhenCrossOrigin;
case ReferrerPolicy::StrictOriginWhenCrossOrigin:
return Protocol::Network::ReferrerPolicy::StrictOriginWhenCrossOrigin;
case ReferrerPolicy::UnsafeUrl:
return Protocol::Network::ReferrerPolicy::UnsafeUrl;
}

ASSERT_NOT_REACHED();
return Protocol::Network::ReferrerPolicy::EmptyString;
}

static Ref<Protocol::Network::Request> buildObjectForResourceRequest(const ResourceRequest& request, ResourceLoader* resourceLoader)
{
auto requestObject = Protocol::Network::Request::create()
.setUrl(request.url().string())
.setMethod(request.httpMethod())
.setHeaders(buildObjectForHeaders(request.httpHeaderFields()))
.release();

if (request.httpBody() && !request.httpBody()->isEmpty()) {
auto bytes = request.httpBody()->flatten();
requestObject->setPostData(String::fromUTF8WithLatin1Fallback(bytes.data(), bytes.size()));
}

if (resourceLoader)
requestObject->setReferrerPolicy(toProtocol(resourceLoader->options().referrerPolicy));

return requestObject;
}

@@ -418,7 +450,7 @@ double InspectorNetworkAgent::timestamp()
return m_environment.executionStopwatch().elapsedTime().seconds();
}

void InspectorNetworkAgent::willSendRequest(ResourceLoaderIdentifier identifier, DocumentLoader* loader, ResourceRequest& request, const ResourceResponse& redirectResponse, InspectorPageAgent::ResourceType type)
void InspectorNetworkAgent::willSendRequest(ResourceLoaderIdentifier identifier, DocumentLoader* loader, ResourceRequest& request, const ResourceResponse& redirectResponse, InspectorPageAgent::ResourceType type, ResourceLoader* resourceLoader)
{
if (request.hiddenFromInspector()) {
m_hiddenRequestIdentifiers.add(identifier);
@@ -464,7 +496,7 @@ void InspectorNetworkAgent::willSendRequest(ResourceLoaderIdentifier identifier,
std::optional<Protocol::Page::ResourceType> typePayload;
if (type != InspectorPageAgent::OtherResource)
typePayload = protocolResourceType;
m_frontendDispatcher->requestWillBeSent(requestId, frameId, loaderId, url, buildObjectForResourceRequest(request), sendTimestamp, walltime.secondsSinceEpoch().seconds(), WTFMove(initiatorObject), buildObjectForResourceResponse(redirectResponse, nullptr), WTFMove(typePayload), targetId);
m_frontendDispatcher->requestWillBeSent(requestId, frameId, loaderId, url, buildObjectForResourceRequest(request, resourceLoader), sendTimestamp, walltime.secondsSinceEpoch().seconds(), WTFMove(initiatorObject), buildObjectForResourceResponse(redirectResponse, nullptr), WTFMove(typePayload), targetId);
}

static InspectorPageAgent::ResourceType resourceTypeForCachedResource(const CachedResource* resource)
@@ -488,16 +520,16 @@ static InspectorPageAgent::ResourceType resourceTypeForLoadType(InspectorInstrum
return InspectorPageAgent::OtherResource;
}

void InspectorNetworkAgent::willSendRequest(ResourceLoaderIdentifier identifier, DocumentLoader* loader, ResourceRequest& request, const ResourceResponse& redirectResponse, const CachedResource* cachedResource)
void InspectorNetworkAgent::willSendRequest(ResourceLoaderIdentifier identifier, DocumentLoader* loader, ResourceRequest& request, const ResourceResponse& redirectResponse, const CachedResource* cachedResource, ResourceLoader* resourceLoader)
{
if (!cachedResource && loader)
cachedResource = InspectorPageAgent::cachedResource(loader->frame(), request.url());
willSendRequest(identifier, loader, request, redirectResponse, resourceTypeForCachedResource(cachedResource));
willSendRequest(identifier, loader, request, redirectResponse, resourceTypeForCachedResource(cachedResource), resourceLoader);
}

void InspectorNetworkAgent::willSendRequestOfType(ResourceLoaderIdentifier identifier, DocumentLoader* loader, ResourceRequest& request, InspectorInstrumentation::LoadType loadType)
{
willSendRequest(identifier, loader, request, ResourceResponse(), resourceTypeForLoadType(loadType));
willSendRequest(identifier, loader, request, ResourceResponse(), resourceTypeForLoadType(loadType), nullptr);
}

void InspectorNetworkAgent::didReceiveResponse(ResourceLoaderIdentifier identifier, DocumentLoader* loader, const ResourceResponse& response, ResourceLoader* resourceLoader)
@@ -1141,7 +1173,7 @@ void InspectorNetworkAgent::interceptRequest(ResourceLoader& loader, Function<vo
return;
}
m_pendingInterceptRequests.set(requestId, makeUnique<PendingInterceptRequest>(&loader, WTFMove(handler)));
m_frontendDispatcher->requestIntercepted(requestId, buildObjectForResourceRequest(loader.request()));
m_frontendDispatcher->requestIntercepted(requestId, buildObjectForResourceRequest(loader.request(), &loader));
}

void InspectorNetworkAgent::interceptResponse(const ResourceResponse& response, ResourceLoaderIdentifier identifier, CompletionHandler<void(const ResourceResponse&, RefPtr<FragmentedSharedBuffer>)>&& handler)
@@ -102,7 +102,7 @@ class InspectorNetworkAgent : public InspectorAgentBase, public Inspector::Netwo
// InspectorInstrumentation
void willRecalculateStyle();
void didRecalculateStyle();
void willSendRequest(ResourceLoaderIdentifier, DocumentLoader*, ResourceRequest&, const ResourceResponse& redirectResponse, const CachedResource*);
void willSendRequest(ResourceLoaderIdentifier, DocumentLoader*, ResourceRequest&, const ResourceResponse& redirectResponse, const CachedResource*, ResourceLoader*);
void willSendRequestOfType(ResourceLoaderIdentifier, DocumentLoader*, ResourceRequest&, InspectorInstrumentation::LoadType);
void didReceiveResponse(ResourceLoaderIdentifier, DocumentLoader*, const ResourceResponse&, ResourceLoader*);
void didReceiveData(ResourceLoaderIdentifier, const SharedBuffer*, int expectedDataLength, int encodedDataLength);
@@ -145,7 +145,7 @@ class InspectorNetworkAgent : public InspectorAgentBase, public Inspector::Netwo
virtual bool shouldForceBufferingNetworkResourceData() const = 0;

private:
void willSendRequest(ResourceLoaderIdentifier, DocumentLoader*, ResourceRequest&, const ResourceResponse& redirectResponse, InspectorPageAgent::ResourceType);
void willSendRequest(ResourceLoaderIdentifier, DocumentLoader*, ResourceRequest&, const ResourceResponse& redirectResponse, InspectorPageAgent::ResourceType, ResourceLoader*);

bool shouldIntercept(URL, Inspector::Protocol::Network::NetworkStage);
void continuePendingRequests();
@@ -197,7 +197,7 @@ String InspectorPageAgent::sourceMapURLForResource(CachedResource* cachedResourc
return String();
}

CachedResource* InspectorPageAgent::cachedResource(Frame* frame, const URL& url)
CachedResource* InspectorPageAgent::cachedResource(const Frame* frame, const URL& url)
{
if (url.isNull())
return nullptr;
@@ -80,7 +80,7 @@ class InspectorPageAgent final : public InspectorAgentBase, public Inspector::Pa
static Vector<CachedResource*> cachedResourcesForFrame(Frame*);
static void resourceContent(Inspector::Protocol::ErrorString&, Frame*, const URL&, String* result, bool* base64Encoded);
static String sourceMapURLForResource(CachedResource*);
static CachedResource* cachedResource(Frame*, const URL&);
static CachedResource* cachedResource(const Frame*, const URL&);
static Inspector::Protocol::Page::ResourceType resourceTypeJSON(ResourceType);
static ResourceType inspectorResourceType(CachedResource::Type);
static ResourceType inspectorResourceType(const CachedResource&);

0 comments on commit 531afa8

Please sign in to comment.