Skip to content
Permalink
Browse files
Web Inspector: provide an option for controlling whether local overri…
…des entirely replace or have some passthrough

https://bugs.webkit.org/show_bug.cgi?id=241990

Reviewed by Patrick Angle.

* Source/WebInspectorUI/UserInterface/Models/LocalResourceOverride.js:
(WI.LocalResourceOverride.prototype.create):
(WI.LocalResourceOverride.fromJSON):
(WI.LocalResourceOverride.prototype.toJSON):
(WI.LocalResourceOverride.prototype.get isPassthrough): Added.
Add a `isPassthrough` member that indicates whether to include original request/response data (where
applicable/possible, e.g. headers).

* Source/WebInspectorUI/UserInterface/Controllers/NetworkManager.js:
(WI.NetworkManager.prototype.async requestIntercepted):
(WI.NetworkManager.prototype.async responseIntercepted):
Use `isPassthrough` to decide whether to return the original `request`/`response` data (or `undefined`
if the argument is optional) or the data from the `WI.LocalResourceOverride` (or `WI.LocalResource`).

* Source/WebInspectorUI/UserInterface/Views/LocalResourceOverridePopover.js:
(WI.LocalResourceOverridePopover):
(WI.LocalResourceOverridePopover.prototype.get serializedData):
(WI.LocalResourceOverridePopover.prototype.show):
* Source/WebInspectorUI/UserInterface/Views/LocalResourceOverridePopover.css:
(.popover .local-resource-override-popover-content > table > tr.options > th): Added.
(.popover .local-resource-override-popover-content > table > tr.options > td > label:not([hidden])): Added.
(.popover .local-resource-override-popover-content .options td): Deleted.
Add UI at the bottom of the local override popover for controlling `isPassthrough`.

* Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js:

* LayoutTests/http/tests/inspector/network/intercept-request-properties.html:
* LayoutTests/http/tests/inspector/network/intercept-request-properties-expected.txt:
* LayoutTests/http/tests/inspector/network/local-resource-override-basic.html:
* LayoutTests/http/tests/inspector/network/local-resource-override-basic-expected.txt:

Canonical link: https://commits.webkit.org/251884@main
  • Loading branch information
dcrousso committed Jun 27, 2022
1 parent 3e3f9ab commit 716557a92a13730d3648c09b0bf8d18cc691a735
Show file tree
Hide file tree
Showing 9 changed files with 225 additions and 45 deletions.
@@ -79,14 +79,37 @@ Request details:
Request Headers:
X-Value: overridden

-- Running test case: Network.interceptRequest.Headers.Passthrough
-- Running test case: Network.interceptRequest.Headers.Empty
Triggering load...
Request details:
URI: /inspector/network/resources/intercept-echo.py
Response URL: http://127.0.0.1:8000/inspector/network/resources/intercept-echo.py
Method: POST
Request Headers:
Post:
value: overridden

-- Running test case: Network.interceptRequest.Headers.Passthrough.Add
Triggering load...
Request details:
URI: /inspector/network/resources/intercept-echo.py
Response URL: http://127.0.0.1:8000/inspector/network/resources/intercept-echo.py
Method: POST
Request Headers:
Content-Type: application/x-www-form-urlencoded
X-Expected: PASS
Post:
value: overridden

-- Running test case: Network.interceptRequest.Headers.Passthrough.Replace
Triggering load...
Request details:
URI: /inspector/network/resources/intercept-echo.py
Response URL: http://127.0.0.1:8000/inspector/network/resources/intercept-echo.py
Method: POST
Request Headers:
Content-Type: application/x-www-form-urlencoded
X-Expected: PASS
Post:
value: overridden

@@ -17,13 +17,13 @@
}
}

async function postData(url)
async function postData(url, headers = {})
{
headers["Content-Type"] = "application/x-www-form-urlencoded"

let response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
headers,
body: "value=original",
});
// Eval to accept trailing coma JSON.
@@ -164,12 +164,37 @@
});

addTestCase({
name: "Network.interceptRequest.Headers.Passthrough",
description: "Tests request headers passthrough",
name: "Network.interceptRequest.Headers.Empty",
description: "Tests request headers interception removing all headers",
expression: "postData('resources/intercept-echo.py')",
override: {
requestMethod: "POST",
requestData: "value=overridden",
requestHeaders: {},
},
});

addTestCase({
name: "Network.interceptRequest.Headers.Passthrough.Add",
description: "Tests request headers passthrough with a new header",
expression: "postData('resources/intercept-echo.py')",
override: {
requestMethod: "POST",
requestData: "value=overridden",
requestHeaders: { "X-Expected": "PASS" },
isPassthrough: true,
},
});

addTestCase({
name: "Network.interceptRequest.Headers.Passthrough.Replace",
description: "Tests request headers passthrough with an overridden header",
expression: "postData('resources/intercept-echo.py', {'X-Expected': 'FAIL'})",
override: {
requestMethod: "POST",
requestData: "value=overridden",
requestHeaders: { "X-Expected": "PASS" },
isPassthrough: true,
},
});

@@ -127,7 +127,40 @@ Response Headers:
X-Expected: PASS
Content: PASS

-- Running test case: LocalResourceOverride.Headers.Passthrough
-- Running test case: LocalResourceOverride.Headers.Empty
Creating Local Resource Override for: http://127.0.0.1:8000/inspector/network/resources/override.txt
Triggering load...
Resource Loaded:
URL: http://127.0.0.1:8000/inspector/network/resources/override.txt
MIME Type: text/plain
Status: 200 OK
Response Source: Symbol(inspector-override)
Response Headers:
Content-Type: text/plain
Content: PASS

-- Running test case: LocalResourceOverride.Headers.Passthrough.Add
Creating Local Resource Override for: http://127.0.0.1:8000/inspector/network/resources/override.txt
Triggering load...
Resource Loaded:
URL: http://127.0.0.1:8000/inspector/network/resources/override.txt
MIME Type: text/plain
Status: 200 OK
Response Source: Symbol(inspector-override)
Response Headers:
Accept-Ranges: <filtered>
Connection: <filtered>
Content-Length: 29
Content-Type: text/plain
Date: <filtered>
ETag: <filtered>
Keep-Alive: <filtered>
Last-Modified: <filtered>
Server: <filtered>
X-Expected: PASS
Content: PASS

-- Running test case: LocalResourceOverride.Headers.Passthrough.Replace
Creating Local Resource Override for: http://127.0.0.1:8000/inspector/network/resources/override.txt
Triggering load...
Resource Loaded:
@@ -145,6 +178,7 @@ Response Headers:
Keep-Alive: <filtered>
Last-Modified: <filtered>
Server: <filtered>
X-Expected: PASS
Content: PASS

-- Running test case: LocalResourceOverride.404
@@ -4,11 +4,11 @@
<meta charset="utf-8">
<script src="../resources/inspector-test.js"></script>
<script>
function triggerOverrideLoad(urlSuffix) {
function triggerOverrideLoad(urlSuffix, headers = {}) {
let url = "http://127.0.0.1:8000/inspector/network/resources/override.txt";
if (urlSuffix)
url += urlSuffix;
fetch(url).then(() => {
fetch(url, {headers}).then(() => {
TestPage.dispatchEventToFrontend("LoadComplete");
});
}
@@ -214,8 +214,8 @@
});

addTestCase({
name: "LocalResourceOverride.Headers.Passthrough",
description: "Load an override without modifying headers.",
name: "LocalResourceOverride.Headers.Empty",
description: "Tests request headers interception removing all headers.",
expression: `triggerOverrideLoad()`,
overrides: [{
url: "http://127.0.0.1:8000/inspector/network/resources/override.txt",
@@ -228,6 +228,38 @@
}]
});

addTestCase({
name: "LocalResourceOverride.Headers.Passthrough.Add",
description: "Tests request headers passthrough with a new header.",
expression: `triggerOverrideLoad()`,
overrides: [{
url: "http://127.0.0.1:8000/inspector/network/resources/override.txt",
responseMIMEType: "text/plain",
responseContent: "PASS",
responseBase64Encoded: false,
responseStatusCode: 200,
responseStatusText: "OK",
responseHeaders: {"X-Expected": "PASS"},
isPassthrough: true,
}]
});

addTestCase({
name: "LocalResourceOverride.Headers.Passthrough.Replace",
description: "Tests request headers passthrough with an overridden header.",
expression: `triggerOverrideLoad("", {"X-Expected": "FAIL"})`,
overrides: [{
url: "http://127.0.0.1:8000/inspector/network/resources/override.txt",
responseMIMEType: "text/plain",
responseContent: "PASS",
responseBase64Encoded: false,
responseStatusCode: 200,
responseStatusText: "OK",
responseHeaders: {"X-Expected": "PASS"},
isPassthrough: true,
}]
});

addTestCase({
name: "LocalResourceOverride.404",
description: "Test for a 404 override.",
@@ -66,7 +66,6 @@ localizedStrings["%s Fired"] = "%s Fired";
localizedStrings["%s Prototype"] = "%s Prototype";
/* Format string for the suggested filename when saving the content for a request local override. */
localizedStrings["%s Request Data @ Local Override Request Content View"] = "%s Request Data";
localizedStrings["%s Result"] = "%s Result";
localizedStrings["%s \u2013 %s"] = "%s \u2013 %s";
localizedStrings["%s \u2013 %s (%s)"] = "%s \u2013 %s (%s)";
localizedStrings["%s \u2014 %s"] = "%s \u2014 %s";
@@ -821,6 +820,8 @@ localizedStrings["Import audit or result"] = "Import audit or result";
localizedStrings["Imported"] = "Imported";
localizedStrings["Imported - %s"] = "Imported - %s";
localizedStrings["Imported \u2014 %s"] = "Imported \u2014 %s";
localizedStrings["Include original repsonse data"] = "Include original repsonse data";
localizedStrings["Include original request data"] = "Include original request data";
localizedStrings["Incomplete"] = "Incomplete";
localizedStrings["Indent width:"] = "Indent width:";
localizedStrings["Index"] = "Index";
@@ -966,6 +966,9 @@ WI.NetworkManager = class NetworkManager extends WI.Object
if (localResourceOverride.disabled)
continue;

let isPassthrough = localResourceOverride.isPassthrough;
let originalHeaders = isPassthrough ? request.headers : {};

let localResource = localResourceOverride.localResource;
await localResource.requestContent();

@@ -983,9 +986,17 @@ WI.NetworkManager = class NetworkManager extends WI.Object
target.NetworkAgent.interceptWithRequest.invoke({
requestId,
url: localResourceOverride.generateRequestRedirectURL(request.url) ?? undefined,
method: localResource.requestMethod ?? undefined,
headers: !isEmptyObject(localResource.requestHeaders) ? localResource.requestHeaders : undefined,
postData: (WI.HTTPUtilities.RequestMethodsWithBody.has(localResource.requestMethod) && localResource.requestData) ? btoa(localResource.requestData) : undefined,
method: localResource.requestMethod ?? (isPassthrough ? request.method : ""),
headers: {...originalHeaders, ...localResource.requestHeaders},
postData: (function() {
if (!WI.HTTPUtilities.RequestMethodsWithBody.has(localResource.requestMethod))
return undefined;
if (localResource.requestData ?? false)
return btoa(localResource.requestData);
if (isPassthrough)
return request.data;
return "";
})(),
});
return;
}
@@ -996,10 +1007,18 @@ WI.NetworkManager = class NetworkManager extends WI.Object
requestId,
content: revision.content,
base64Encoded: !!revision.base64Encoded,
mimeType: revision.mimeType ?? undefined,
mimeType: revision.mimeType ?? "text/plain",
status: !isNaN(localResource.statusCode) ? localResource.statusCode : 200,
statusText: !isNaN(localResource.statusCode) ? (localResource.statusText ?? "") : WI.HTTPUtilities.statusTextForStatusCode(200),
headers: localResource.responseHeaders,
statusText: (function() {
if (localResource.statusText ?? false)
return localResource.statusText;

if (!isNaN(localResource.statusCode))
return WI.HTTPUtilities.statusTextForStatusCode(localResource.statusCode);

return WI.HTTPUtilities.statusTextForStatusCode(200);
})(),
headers: {...originalHeaders, ...localResource.responseHeaders},
});
return;
}
@@ -1020,6 +1039,9 @@ WI.NetworkManager = class NetworkManager extends WI.Object
if (localResourceOverride.disabled)
continue;

let isPassthrough = localResourceOverride.isPassthrough;
let originalHeaders = isPassthrough ? response.headers : {};

let localResource = localResourceOverride.localResource;
await localResource.requestContent();

@@ -1032,10 +1054,29 @@ WI.NetworkManager = class NetworkManager extends WI.Object
requestId,
content: revision.content,
base64Encoded: !!revision.base64Encoded,
mimeType: revision.mimeType ?? undefined,
status: !isNaN(localResource.statusCode) ? localResource.statusCode : undefined,
statusText: !isNaN(localResource.statusCode) ? (localResource.statusText ?? "") : undefined,
headers: !isEmptyObject(localResource.responseHeaders) ? localResource.responseHeaders : undefined,
mimeType: revision.mimeType ?? (isPassthrough ? response.mimeType : "text/plain"),
status: (function() {
if (!isNaN(localResource.statusCode))
return localResource.statusCode;

if (isPassthrough)
return response.statusCode;

return 200;
})(),
statusText: (function() {
if (localResource.statusText ?? false)
return localResource.statusText;

if (isPassthrough)
return response.statusText;

if (!isNaN(localResource.statusCode))
return WI.HTTPUtilities.statusTextForStatusCode(localResource.statusCode);

return WI.HTTPUtilities.statusTextForStatusCode(200);
})(),
headers: {...originalHeaders, ...localResource.responseHeaders},
});
return;
}

0 comments on commit 716557a

Please sign in to comment.