Changeset 263072 in webkit


Ignore:
Timestamp:
Jun 15, 2020 6:46:12 PM (4 years ago)
Author:
commit-queue@webkit.org
Message:

Web Inspector: introduce request interception
https://bugs.webkit.org/show_bug.cgi?id=207446

Patch by Pavel Feldman <pavel.feldman@gmail.com> on 2020-06-15
Reviewed by Devin Rousso.

Source/JavaScriptCore:

This change introduces network request interception to the Network
protocol domain. It adds Network.interceptWithRequest notification that
can be continued, modified or fulfilled. NetworkStage enum can now have
'request' and 'response' values.

  • inspector/protocol/Network.json:

Source/WebCore:

This change introduces network request interception to the Network
protocol domain. It adds Network.interceptWithRequest notification that
can be continued, modified or fulfilled. NetworkStage enum can now have
'request' and 'response' values.

Tests: http/tests/inspector/network/intercept-aborted-request.html

http/tests/inspector/network/intercept-request-continue.html
http/tests/inspector/network/intercept-request-fragment.html
http/tests/inspector/network/intercept-request-main-resource-with-response.html
http/tests/inspector/network/intercept-request-main-resource.html
http/tests/inspector/network/intercept-request-properties.html
http/tests/inspector/network/intercept-request-subresource-with-error.html
http/tests/inspector/network/intercept-request-subresource-with-response.html
http/tests/inspector/network/intercept-request-subresource.html
http/tests/inspector/network/intercept-request-with-response.html

  • inspector/InspectorInstrumentation.cpp:

(WebCore::InspectorInstrumentation::willInterceptImpl):
(WebCore::InspectorInstrumentation::shouldInterceptRequestImpl):
(WebCore::InspectorInstrumentation::interceptRequestImpl):

  • inspector/InspectorInstrumentation.h:

(WebCore::InspectorInstrumentation::willIntercept):
(WebCore::InspectorInstrumentation::shouldInterceptRequest):
(WebCore::InspectorInstrumentation::interceptRequest):

  • inspector/InspectorInstrumentationWebKit.cpp:

(WebCore::InspectorInstrumentationWebKit::shouldInterceptRequestInternal):
(WebCore::InspectorInstrumentationWebKit::interceptRequestInternal):

  • inspector/InspectorInstrumentationWebKit.h:

(WebCore::InspectorInstrumentationWebKit::shouldInterceptRequest):
(WebCore::InspectorInstrumentationWebKit::interceptRequest):

  • inspector/agents/InspectorNetworkAgent.cpp:

(WebCore::InspectorNetworkAgent::disable):
(WebCore::InspectorNetworkAgent::shouldIntercept):
(WebCore::InspectorNetworkAgent::continuePendingRequests):
(WebCore::InspectorNetworkAgent::setInterceptionEnabled):
(WebCore::InspectorNetworkAgent::addInterception):
(WebCore::InspectorNetworkAgent::removeInterception):
(WebCore::InspectorNetworkAgent::willIntercept):
(WebCore::InspectorNetworkAgent::shouldInterceptRequest):
(WebCore::InspectorNetworkAgent::shouldInterceptResponse):
(WebCore::InspectorNetworkAgent::interceptRequest):
(WebCore::InspectorNetworkAgent::interceptContinue):
(WebCore::InspectorNetworkAgent::interceptWithRequest):
(WebCore::InspectorNetworkAgent::interceptRequestWithResponse):
(WebCore::InspectorNetworkAgent::interceptRequestWithError):

  • inspector/agents/InspectorNetworkAgent.h:

(WebCore::InspectorNetworkAgent::PendingInterceptRequest::PendingInterceptRequest):
(WebCore::InspectorNetworkAgent::PendingInterceptRequest::continueWithOriginalRequest):
(WebCore::InspectorNetworkAgent::PendingInterceptRequest::continueWithRequest):
(WebCore::InspectorNetworkAgent::Intercept::operator== const):

  • loader/cache/CachedResourceLoader.cpp:

(WebCore::CachedResourceLoader::requestResource):
(WebCore::CachedResourceLoader::preload):

Source/WebInspectorUI:

This change introduces network request interception to the Network
protocol domain. It adds Network.interceptWithRequest notification that
can be continued, modified or fulfilled. NetworkStage enum can now have
'request' and 'response' values.

  • UserInterface/Controllers/NetworkManager.js:

(WI.NetworkManager.prototype.initializeTarget):
(WI.NetworkManager.prototype.addLocalResourceOverride):
(WI.NetworkManager.prototype.removeLocalResourceOverride):
(WI.NetworkManager.prototype.requestIntercepted):
(WI.NetworkManager.prototype.responseIntercepted):
(WI.NetworkManager.prototype._handleResourceOverrideDisabledChanged):

  • UserInterface/Protocol/NetworkObserver.js:

(WI.NetworkObserver.prototype.requestIntercepted):

Source/WebKit:

This change introduces network request interception to the Network
protocol domain. It adds Network.interceptWithRequest notification that
can be continued, modified or fulfilled. NetworkStage enum can now have
'request' and 'response' values.

  • WebProcess/Network/WebLoaderStrategy.cpp:

(WebKit::WebLoaderStrategy::scheduleLoad):

LayoutTests:

This change introduces network request interception to the Network
protocol domain. It adds Network.interceptWithRequest notification that
can be continued, modified or fulfilled. NetworkStage enum can now have
'request' and 'response' values.

  • http/tests/inspector/network/intercept-aborted-request-expected.txt: Added.
  • http/tests/inspector/network/intercept-aborted-request.html: Added.
  • http/tests/inspector/network/intercept-request-continue-expected.txt: Added.
  • http/tests/inspector/network/intercept-request-continue.html: Added.
  • http/tests/inspector/network/intercept-request-fragment-expected.txt: Added.
  • http/tests/inspector/network/intercept-request-fragment.html: Added.
  • http/tests/inspector/network/intercept-request-main-resource-expected.txt: Added.
  • http/tests/inspector/network/intercept-request-main-resource-with-response-expected.txt: Added.
  • http/tests/inspector/network/intercept-request-main-resource-with-response.html: Added.
  • http/tests/inspector/network/intercept-request-main-resource.html: Added.
  • http/tests/inspector/network/intercept-request-properties-expected.txt: Added.
  • http/tests/inspector/network/intercept-request-properties.html: Added.
  • http/tests/inspector/network/intercept-request-subresource-expected.txt: Added.
  • http/tests/inspector/network/intercept-request-subresource-with-error-expected.txt: Added.
  • http/tests/inspector/network/intercept-request-subresource-with-error.html: Added.
  • http/tests/inspector/network/intercept-request-subresource-with-response-expected.txt: Added.
  • http/tests/inspector/network/intercept-request-subresource-with-response.html: Added.
  • http/tests/inspector/network/intercept-request-subresource.html: Added.
  • http/tests/inspector/network/intercept-request-with-response-expected.txt: Added.
  • http/tests/inspector/network/intercept-request-with-response.html: Added.
  • http/tests/inspector/network/resources/intercept-echo.php: Added.
  • http/tests/inspector/network/resources/intercept-request-overriden-page.html: Added.
  • http/tests/inspector/network/resources/intercept-request-overriden-script.js: Added.
  • http/tests/inspector/resources/protocol-test.js:
  • inspector/network/local-resource-override-continue-response.html:
  • inspector/network/resources/data-intercepted.json: Added.
  • platform/mac-wk1/TestExpectations:
Location:
trunk
Files:
24 added
19 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r263069 r263072  
     12020-06-15  Pavel Feldman <pavel.feldman@gmail.com>
     2
     3        Web Inspector: introduce request interception
     4        https://bugs.webkit.org/show_bug.cgi?id=207446
     5
     6        Reviewed by Devin Rousso.
     7
     8        This change introduces network request interception to the Network
     9        protocol domain. It adds Network.interceptWithRequest notification that
     10        can be continued, modified or fulfilled. NetworkStage enum can now have
     11        'request' and 'response' values.
     12
     13        * http/tests/inspector/network/intercept-aborted-request-expected.txt: Added.
     14        * http/tests/inspector/network/intercept-aborted-request.html: Added.
     15        * http/tests/inspector/network/intercept-request-continue-expected.txt: Added.
     16        * http/tests/inspector/network/intercept-request-continue.html: Added.
     17        * http/tests/inspector/network/intercept-request-fragment-expected.txt: Added.
     18        * http/tests/inspector/network/intercept-request-fragment.html: Added.
     19        * http/tests/inspector/network/intercept-request-main-resource-expected.txt: Added.
     20        * http/tests/inspector/network/intercept-request-main-resource-with-response-expected.txt: Added.
     21        * http/tests/inspector/network/intercept-request-main-resource-with-response.html: Added.
     22        * http/tests/inspector/network/intercept-request-main-resource.html: Added.
     23        * http/tests/inspector/network/intercept-request-properties-expected.txt: Added.
     24        * http/tests/inspector/network/intercept-request-properties.html: Added.
     25        * http/tests/inspector/network/intercept-request-subresource-expected.txt: Added.
     26        * http/tests/inspector/network/intercept-request-subresource-with-error-expected.txt: Added.
     27        * http/tests/inspector/network/intercept-request-subresource-with-error.html: Added.
     28        * http/tests/inspector/network/intercept-request-subresource-with-response-expected.txt: Added.
     29        * http/tests/inspector/network/intercept-request-subresource-with-response.html: Added.
     30        * http/tests/inspector/network/intercept-request-subresource.html: Added.
     31        * http/tests/inspector/network/intercept-request-with-response-expected.txt: Added.
     32        * http/tests/inspector/network/intercept-request-with-response.html: Added.
     33        * http/tests/inspector/network/resources/intercept-echo.php: Added.
     34        * http/tests/inspector/network/resources/intercept-request-overriden-page.html: Added.
     35        * http/tests/inspector/network/resources/intercept-request-overriden-script.js: Added.
     36        * http/tests/inspector/resources/protocol-test.js:
     37        * inspector/network/local-resource-override-continue-response.html:
     38        * inspector/network/resources/data-intercepted.json: Added.
     39        * platform/mac-wk1/TestExpectations:
     40
    1412020-06-15  Wenson Hsieh  <wenson_hsieh@apple.com>
    242
  • trunk/LayoutTests/http/tests/inspector/resources/protocol-test.js

    r195147 r263072  
    8888        alert("Failed to send test() because it is not a function.");
    8989        testRunner.notifyDone();
     90        return;
    9091    }
    9192
     
    9495        alert("Failed to obtain inspector test stub URL.");
    9596        testRunner.notifyDone();
     97        return;
    9698    }
    9799
  • trunk/LayoutTests/inspector/network/local-resource-override-continue-response.html

    r249504 r263072  
    4747            await Promise.all([
    4848                InspectorProtocol.awaitEvent({event: "Network.responseReceived"}),
    49                 InspectorProtocol.awaitCommand({method: "Network.interceptContinue", params: {requestId: messageObject.params.requestId}}),
     49                InspectorProtocol.awaitCommand({method: "Network.interceptContinue", params: {requestId: messageObject.params.requestId, stage: "response"}}),
    5050            ]);
    5151            ProtocolTest.pass("Response received.");
  • trunk/LayoutTests/platform/mac-wk1/TestExpectations

    r263042 r263072  
    574574inspector/network/local-resource-override-continue-response.html [ Skip ]
    575575
     576# Request interception is not available in WebKit1
     577http/tests/inspector/network/intercept-aborted-request.html [ Skip ]
     578http/tests/inspector/network/intercept-request-continue.html [ Skip ]
     579http/tests/inspector/network/intercept-request-fragment.html [ Skip ]
     580http/tests/inspector/network/intercept-request-main-resource.html [ Skip ]
     581http/tests/inspector/network/intercept-request-main-resource-with-response.html [ Skip ]
     582http/tests/inspector/network/intercept-request-properties.html [ Skip ]
     583http/tests/inspector/network/intercept-request-subresource.html [ Skip ]
     584http/tests/inspector/network/intercept-request-subresource-with-error.html [ Skip ]
     585http/tests/inspector/network/intercept-request-subresource-with-response.html [ Skip ]
     586http/tests/inspector/network/intercept-request-with-response.html [ Skip ]
     587
    576588webkit.org/b/164933 http/tests/misc/link-rel-icon-beforeload.html [ Failure ]
    577589
  • trunk/Source/JavaScriptCore/ChangeLog

    r263071 r263072  
     12020-06-15  Pavel Feldman  <pavel.feldman@gmail.com>
     2
     3        Web Inspector: introduce request interception
     4        https://bugs.webkit.org/show_bug.cgi?id=207446
     5
     6        Reviewed by Devin Rousso.
     7
     8        This change introduces network request interception to the Network
     9        protocol domain. It adds Network.interceptWithRequest notification that
     10        can be continued, modified or fulfilled. NetworkStage enum can now have
     11        'request' and 'response' values.
     12
     13        * inspector/protocol/Network.json:
     14
    1152020-06-15  Tadeu Zagallo  <tzagallo@apple.com>
    216
  • trunk/Source/JavaScriptCore/inspector/protocol/Network.json

    r262302 r263072  
    156156            "type": "string",
    157157            "description": "Different stages of a network request.",
    158             "enum": ["response"]
     158            "enum": ["request", "response"]
     159        },
     160        {
     161            "id": "ResourceErrorType",
     162            "type": "string",
     163            "description": "Different stages of a network request.",
     164            "enum": ["General", "AccessControl", "Cancellation", "Timeout"]
    159165        }
    160166    ],
     
    245251            "targetTypes": ["page"],
    246252            "parameters": [
    247                 { "name": "url", "type": "string" },
     253                { "name": "url", "type": "string", "description": "URL pattern to intercept, intercept everything if not specified or empty" },
     254                { "name": "stage", "$ref": "NetworkStage", "description": "Stage to intercept." },
    248255                { "name": "caseSensitive", "type": "boolean", "optional": true, "description": "If false, ignores letter casing of `url` parameter." },
    249                 { "name": "isRegex", "type": "boolean", "optional": true, "description": "If true, treats `url` parameter as a regular expression." },
    250                 { "name": "stage", "$ref": "NetworkStage", "optional": true, "description": "If not present this applies to all network stages." }
     256                { "name": "isRegex", "type": "boolean", "optional": true, "description": "If true, treats `url` parameter as a regular expression." }
    251257            ]
    252258        },
     
    257263            "parameters": [
    258264                { "name": "url", "type": "string" },
     265                { "name": "stage", "$ref": "NetworkStage", "description": "Stage to intercept." },
    259266                { "name": "caseSensitive", "type": "boolean", "optional": true, "description": "If false, ignores letter casing of `url` parameter." },
    260                 { "name": "isRegex", "type": "boolean", "optional": true, "description": "If true, treats `url` parameter as a regular expression." },
    261                 { "name": "stage", "$ref": "NetworkStage", "optional": true, "description": "If not present this applies to all network stages." }
     267                { "name": "isRegex", "type": "boolean", "optional": true, "description": "If true, treats `url` parameter as a regular expression." }
    262268            ]
    263269        },
    264270        {
    265271            "name": "interceptContinue",
    266             "description": "Continue an interception with no modifications.",
    267             "targetTypes": ["page"],
    268             "parameters": [
    269                 { "name": "requestId", "$ref": "RequestId", "description": "Identifier for the intercepted Network request or response to continue." }
     272            "description": "Continue request or response without modifications.",
     273            "targetTypes": ["page"],
     274            "parameters": [
     275                { "name": "requestId", "$ref": "RequestId", "description": "Identifier for the intercepted Network request or response to continue." },
     276                { "name": "stage", "$ref": "NetworkStage", "description": "Stage to continue." }
     277            ]
     278        },
     279        {
     280            "name": "interceptWithRequest",
     281            "description": "Replace intercepted request with the provided one.",
     282            "parameters": [
     283                { "name": "requestId", "$ref": "RequestId", "description": "Identifier for the intercepted Network request or response to continue." },
     284                { "name": "url", "type": "string", "optional": true,"description": "HTTP request url." },
     285                { "name": "method", "type": "string", "optional": true,"description": "HTTP request method." },
     286                { "name": "headers", "$ref": "Headers", "optional": true, "description": "HTTP response headers. Pass through original values if unmodified." },
     287                { "name": "postData", "type": "string", "optional": true, "description": "HTTP POST request data, base64-encoded." }
    270288            ]
    271289        },
     
    282300                { "name": "statusText", "type": "string", "optional": true, "description": "HTTP response status text. Pass through original values if unmodified." },
    283301                { "name": "headers", "$ref": "Headers", "optional": true, "description": "HTTP response headers. Pass through original values if unmodified." }
     302            ]
     303        },
     304        {
     305            "name": "interceptRequestWithResponse",
     306            "description": "Provide response for an intercepted request. Request completely bypasses the network in this case and is immediately fulfilled with the provided data.",
     307            "parameters": [
     308                { "name": "requestId", "$ref": "RequestId", "description": "Identifier for the intercepted Network response to modify." },
     309                { "name": "content", "type": "string" },
     310                { "name": "base64Encoded", "type": "boolean", "description": "True, if content was sent as base64." },
     311                { "name": "mimeType", "type": "string", "description": "MIME Type for the data." },
     312                { "name": "status", "type": "integer", "description": "HTTP response status code." },
     313                { "name": "statusText", "type": "string", "description": "HTTP response status text." },
     314                { "name": "headers", "$ref": "Headers", "description": "HTTP response headers." }
     315            ]
     316        },
     317        {
     318            "name": "interceptRequestWithError",
     319            "description": "Fail request with given error type.",
     320            "parameters": [
     321                { "name": "requestId", "$ref": "RequestId", "description": "Identifier for the intercepted Network request to fail." },
     322                { "name": "errorType", "$ref": "ResourceErrorType", "description": "Deliver error reason for the request failure." }
    284323            ]
    285324        }
     
    359398        },
    360399        {
     400            "name": "requestIntercepted",
     401            "description": "Fired when HTTP request has been intercepted. The frontend must respond with <code>Network.interceptContinue</code>, <code>Network.interceptWithRequest</code>` or <code>Network.interceptWithResponse</code>` to resolve this request.",
     402            "parameters": [
     403                { "name": "requestId", "$ref": "RequestId", "description": "Identifier for this intercepted network. Corresponds with an earlier <code>Network.requestWillBeSent</code>." },
     404                { "name": "request", "$ref": "Request", "description": "Original request content that would proceed if this is continued." }
     405            ]
     406        },
     407        {
    361408            "name": "responseIntercepted",
    362             "description": "Fired when HTTP response has been intercepted. The frontend must response with <code>Network.interceptContinue</code> or <code>Network.interceptWithRespons</code>` to continue this response.",
     409            "description": "Fired when HTTP response has been intercepted. The frontend must response with <code>Network.interceptContinue</code> or <code>Network.interceptWithResponse</code>` to continue this response.",
    363410            "targetTypes": ["page"],
    364411            "parameters": [
  • trunk/Source/WebCore/ChangeLog

    r263049 r263072  
     12020-06-15  Pavel Feldman  <pavel.feldman@gmail.com>
     2
     3        Web Inspector: introduce request interception
     4        https://bugs.webkit.org/show_bug.cgi?id=207446
     5
     6        Reviewed by Devin Rousso.
     7
     8        This change introduces network request interception to the Network
     9        protocol domain. It adds Network.interceptWithRequest notification that
     10        can be continued, modified or fulfilled. NetworkStage enum can now have
     11        'request' and 'response' values.
     12
     13        Tests: http/tests/inspector/network/intercept-aborted-request.html
     14               http/tests/inspector/network/intercept-request-continue.html
     15               http/tests/inspector/network/intercept-request-fragment.html
     16               http/tests/inspector/network/intercept-request-main-resource-with-response.html
     17               http/tests/inspector/network/intercept-request-main-resource.html
     18               http/tests/inspector/network/intercept-request-properties.html
     19               http/tests/inspector/network/intercept-request-subresource-with-error.html
     20               http/tests/inspector/network/intercept-request-subresource-with-response.html
     21               http/tests/inspector/network/intercept-request-subresource.html
     22               http/tests/inspector/network/intercept-request-with-response.html
     23
     24        * inspector/InspectorInstrumentation.cpp:
     25        (WebCore::InspectorInstrumentation::willInterceptImpl):
     26        (WebCore::InspectorInstrumentation::shouldInterceptRequestImpl):
     27        (WebCore::InspectorInstrumentation::interceptRequestImpl):
     28        * inspector/InspectorInstrumentation.h:
     29        (WebCore::InspectorInstrumentation::willIntercept):
     30        (WebCore::InspectorInstrumentation::shouldInterceptRequest):
     31        (WebCore::InspectorInstrumentation::interceptRequest):
     32        * inspector/InspectorInstrumentationWebKit.cpp:
     33        (WebCore::InspectorInstrumentationWebKit::shouldInterceptRequestInternal):
     34        (WebCore::InspectorInstrumentationWebKit::interceptRequestInternal):
     35        * inspector/InspectorInstrumentationWebKit.h:
     36        (WebCore::InspectorInstrumentationWebKit::shouldInterceptRequest):
     37        (WebCore::InspectorInstrumentationWebKit::interceptRequest):
     38        * inspector/agents/InspectorNetworkAgent.cpp:
     39        (WebCore::InspectorNetworkAgent::disable):
     40        (WebCore::InspectorNetworkAgent::shouldIntercept):
     41        (WebCore::InspectorNetworkAgent::continuePendingRequests):
     42        (WebCore::InspectorNetworkAgent::setInterceptionEnabled):
     43        (WebCore::InspectorNetworkAgent::addInterception):
     44        (WebCore::InspectorNetworkAgent::removeInterception):
     45        (WebCore::InspectorNetworkAgent::willIntercept):
     46        (WebCore::InspectorNetworkAgent::shouldInterceptRequest):
     47        (WebCore::InspectorNetworkAgent::shouldInterceptResponse):
     48        (WebCore::InspectorNetworkAgent::interceptRequest):
     49        (WebCore::InspectorNetworkAgent::interceptContinue):
     50        (WebCore::InspectorNetworkAgent::interceptWithRequest):
     51        (WebCore::InspectorNetworkAgent::interceptRequestWithResponse):
     52        (WebCore::InspectorNetworkAgent::interceptRequestWithError):
     53        * inspector/agents/InspectorNetworkAgent.h:
     54        (WebCore::InspectorNetworkAgent::PendingInterceptRequest::PendingInterceptRequest):
     55        (WebCore::InspectorNetworkAgent::PendingInterceptRequest::continueWithOriginalRequest):
     56        (WebCore::InspectorNetworkAgent::PendingInterceptRequest::continueWithRequest):
     57        (WebCore::InspectorNetworkAgent::Intercept::operator== const):
     58        * loader/cache/CachedResourceLoader.cpp:
     59        (WebCore::CachedResourceLoader::requestResource):
     60        (WebCore::CachedResourceLoader::preload):
     61
    1622020-06-15  Keith Miller  <keith_miller@apple.com>
    263
  • trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp

    r262688 r263072  
    812812}
    813813
    814 bool InspectorInstrumentation::willInterceptRequestImpl(InstrumentingAgents& instrumentingAgents, const ResourceRequest& request)
    815 {
    816     if (auto* networkAgent = instrumentingAgents.enabledNetworkAgent())
    817         return networkAgent->willInterceptRequest(request);
     814bool InspectorInstrumentation::willInterceptImpl(InstrumentingAgents& instrumentingAgents, const ResourceRequest& request)
     815{
     816    if (auto* networkAgent = instrumentingAgents.enabledNetworkAgent())
     817        return networkAgent->willIntercept(request);
     818    return false;
     819}
     820
     821bool InspectorInstrumentation::shouldInterceptRequestImpl(InstrumentingAgents& instrumentingAgents, const ResourceRequest& request)
     822{
     823    if (auto* networkAgent = instrumentingAgents.enabledNetworkAgent())
     824        return networkAgent->shouldInterceptRequest(request);
    818825    return false;
    819826}
     
    824831        return networkAgent->shouldInterceptResponse(response);
    825832    return false;
     833}
     834
     835void InspectorInstrumentation::interceptRequestImpl(InstrumentingAgents& instrumentingAgents, ResourceLoader& loader, CompletionHandler<void(const ResourceRequest&)>&& handler)
     836{
     837    if (auto* networkAgent = instrumentingAgents.enabledNetworkAgent())
     838        networkAgent->interceptRequest(loader, WTFMove(handler));
    826839}
    827840
  • trunk/Source/WebCore/inspector/InspectorInstrumentation.h

    r262404 r263072  
    4646#include "InspectorInstrumentationPublic.h"
    4747#include "Page.h"
     48#include "ResourceLoader.h"
    4849#include "StorageArea.h"
    4950#include "WebAnimation.h"
     
    235236    static void willDestroyCachedResource(CachedResource&);
    236237
    237     static bool willInterceptRequest(const Frame*, const ResourceRequest&);
     238    static bool willIntercept(const Frame*, const ResourceRequest&);
     239    static bool shouldInterceptRequest(const Frame&, const ResourceRequest&);
    238240    static bool shouldInterceptResponse(const Frame&, const ResourceResponse&);
     241    static void interceptRequest(ResourceLoader&, CompletionHandler<void(const ResourceRequest&)>&&);
    239242    static void interceptResponse(const Frame&, const ResourceResponse&, unsigned long identifier, CompletionHandler<void(const ResourceResponse&, RefPtr<SharedBuffer>)>&&);
    240243
     
    443446    static void willDestroyCachedResourceImpl(CachedResource&);
    444447
    445     static bool willInterceptRequestImpl(InstrumentingAgents&, const ResourceRequest&);
     448    static bool willInterceptImpl(InstrumentingAgents&, const ResourceRequest&);
     449    static bool shouldInterceptRequestImpl(InstrumentingAgents&, const ResourceRequest&);
    446450    static bool shouldInterceptResponseImpl(InstrumentingAgents&, const ResourceResponse&);
     451    static void interceptRequestImpl(InstrumentingAgents&, ResourceLoader&, CompletionHandler<void(const ResourceRequest&)>&&);
    447452    static void interceptResponseImpl(InstrumentingAgents&, const ResourceResponse&, unsigned long identifier, CompletionHandler<void(const ResourceResponse&, RefPtr<SharedBuffer>)>&&);
    448453
     
    12581263}
    12591264
    1260 inline bool InspectorInstrumentation::willInterceptRequest(const Frame* frame, const ResourceRequest& request)
     1265inline bool InspectorInstrumentation::willIntercept(const Frame* frame, const ResourceRequest& request)
    12611266{
    12621267    FAST_RETURN_IF_NO_FRONTENDS(false);
    12631268    if (auto* instrumentingAgents = instrumentingAgentsForFrame(frame))
    1264         return willInterceptRequestImpl(*instrumentingAgents, request);
     1269        return willInterceptImpl(*instrumentingAgents, request);
     1270    return false;
     1271}
     1272
     1273inline bool InspectorInstrumentation::shouldInterceptRequest(const Frame& frame, const ResourceRequest& request)
     1274{
     1275    ASSERT(InspectorInstrumentationPublic::hasFrontends());
     1276    if (auto* instrumentingAgents = instrumentingAgentsForFrame(frame))
     1277        return shouldInterceptRequestImpl(*instrumentingAgents, request);
    12651278    return false;
    12661279}
     
    12741287}
    12751288
     1289inline void InspectorInstrumentation::interceptRequest(ResourceLoader& loader, CompletionHandler<void(const ResourceRequest&)>&& handler)
     1290{
     1291    ASSERT(InspectorInstrumentation::shouldInterceptRequest(*loader.frame(), loader.request()));
     1292    if (auto* instrumentingAgents = instrumentingAgentsForFrame(loader.frame()))
     1293        interceptRequestImpl(*instrumentingAgents, loader, WTFMove(handler));
     1294}
     1295
    12761296inline void InspectorInstrumentation::interceptResponse(const Frame& frame, const ResourceResponse& response, unsigned long identifier, CompletionHandler<void(const ResourceResponse&, RefPtr<SharedBuffer>)>&& handler)
    12771297{
  • trunk/Source/WebCore/inspector/InspectorInstrumentationWebKit.cpp

    r249504 r263072  
    3131namespace WebCore {
    3232
     33bool InspectorInstrumentationWebKit::shouldInterceptRequestInternal(const Frame& frame, const ResourceRequest& request)
     34{
     35    return InspectorInstrumentation::shouldInterceptRequest(frame, request);
     36}
     37
    3338bool InspectorInstrumentationWebKit::shouldInterceptResponseInternal(const Frame& frame, const ResourceResponse& response)
    3439{
    3540    return InspectorInstrumentation::shouldInterceptResponse(frame, response);
     41}
     42
     43void InspectorInstrumentationWebKit::interceptRequestInternal(ResourceLoader& loader, CompletionHandler<void(const ResourceRequest&)>&& handler)
     44{
     45    InspectorInstrumentation::interceptRequest(loader, WTFMove(handler));
    3646}
    3747
  • trunk/Source/WebCore/inspector/InspectorInstrumentationWebKit.h

    r249504 r263072  
    3737class WEBCORE_EXPORT InspectorInstrumentationWebKit {
    3838public:
     39    static bool shouldInterceptRequest(const Frame*, const ResourceRequest&);
    3940    static bool shouldInterceptResponse(const Frame*, const ResourceResponse&);
     41    static void interceptRequest(ResourceLoader&, CompletionHandler<void(const ResourceRequest&)>&&);
    4042    static void interceptResponse(const Frame*, const ResourceResponse&, unsigned long identifier, CompletionHandler<void(const ResourceResponse&, RefPtr<SharedBuffer>)>&&);
    4143
    4244private:
     45    static bool shouldInterceptRequestInternal(const Frame&, const ResourceRequest&);
    4346    static bool shouldInterceptResponseInternal(const Frame&, const ResourceResponse&);
     47    static void interceptRequestInternal(ResourceLoader&, CompletionHandler<void(const ResourceRequest&)>&&);
    4448    static void interceptResponseInternal(const Frame&, const ResourceResponse&, unsigned long identifier, CompletionHandler<void(const ResourceResponse&, RefPtr<SharedBuffer>)>&&);
    4549};
     50
     51inline bool InspectorInstrumentationWebKit::shouldInterceptRequest(const Frame* frame, const ResourceRequest& request)
     52{
     53    FAST_RETURN_IF_NO_FRONTENDS(false);
     54    if (!frame)
     55        return false;
     56
     57    return shouldInterceptRequestInternal(*frame, request);
     58}
    4659
    4760inline bool InspectorInstrumentationWebKit::shouldInterceptResponse(const Frame* frame, const ResourceResponse& response)
     
    5467}
    5568
     69inline void InspectorInstrumentationWebKit::interceptRequest(ResourceLoader& loader, CompletionHandler<void(const ResourceRequest&)>&& handler)
     70{
     71    ASSERT(InspectorInstrumentationWebKit::shouldInterceptRequest(loader.frame(), loader.request()));
     72    interceptRequestInternal(loader, WTFMove(handler));
     73}
     74
    5675inline void InspectorInstrumentationWebKit::interceptResponse(const Frame* frame, const ResourceResponse& response, unsigned long identifier, CompletionHandler<void(const ResourceResponse&, RefPtr<SharedBuffer>)>&& handler)
    5776{
  • trunk/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp

    r262683 r263072  
    4343#include "DocumentLoader.h"
    4444#include "DocumentThreadableLoader.h"
     45#include "FormData.h"
    4546#include "Frame.h"
    4647#include "FrameLoader.h"
     
    466467    if (resource)
    467468        return InspectorPageAgent::inspectorResourceType(*resource);
     469
    468470    return InspectorPageAgent::OtherResource;
    469471}
     
    841843    m_extraRequestHeaders.clear();
    842844
     845    continuePendingRequests();
    843846    continuePendingResponses();
    844847
     
    846849}
    847850
    848 bool InspectorNetworkAgent::shouldIntercept(URL url)
     851bool InspectorNetworkAgent::shouldIntercept(URL url, NetworkStage networkStage)
    849852{
    850853    url.removeFragmentIdentifier();
     
    855858
    856859    for (auto& intercept : m_intercepts) {
     860        if (intercept.networkStage != networkStage)
     861            continue;
     862        if (intercept.url.isEmpty())
     863            return true;
     864
    857865        auto searchStringType = intercept.isRegex ? ContentSearchUtilities::SearchStringType::Regex : ContentSearchUtilities::SearchStringType::ExactString;
    858866        auto regex = ContentSearchUtilities::createRegularExpressionForSearchString(intercept.url, intercept.caseSensitive, searchStringType);
     
    862870
    863871    return false;
     872}
     873
     874void InspectorNetworkAgent::continuePendingRequests()
     875{
     876    for (auto& pendingRequest : m_pendingInterceptRequests.values())
     877        pendingRequest->continueWithOriginalRequest();
     878    m_pendingInterceptRequests.clear();
    864879}
    865880
     
    10291044    m_interceptionEnabled = enabled;
    10301045
    1031     if (!m_interceptionEnabled)
     1046    if (!m_interceptionEnabled) {
     1047        continuePendingRequests();
    10321048        continuePendingResponses();
    1033 }
    1034 
    1035 void InspectorNetworkAgent::addInterception(ErrorString& errorString, const String& url, const bool* optionalCaseSensitive, const bool* optionalIsRegex, const String* networkStageString)
    1036 {
    1037     if (networkStageString) {
    1038         auto networkStage = Inspector::Protocol::InspectorHelpers::parseEnumValueFromString<Inspector::Protocol::Network::NetworkStage>(*networkStageString);
    1039         if (!networkStage) {
    1040             errorString = makeString("Unknown networkStage: "_s, *networkStageString);
    1041             return;
    1042         }
     1049    }
     1050}
     1051
     1052void InspectorNetworkAgent::addInterception(ErrorString& errorString, const String& url, const String& networkStageString, const bool* optionalCaseSensitive, const bool* optionalIsRegex)
     1053{
     1054    auto networkStage = Inspector::Protocol::InspectorHelpers::parseEnumValueFromString<Inspector::Protocol::Network::NetworkStage>(networkStageString);
     1055    if (!networkStage) {
     1056        errorString = makeString("Unknown networkStage: "_s, networkStageString);
     1057        return;
    10431058    }
    10441059
     
    10491064    if (optionalIsRegex)
    10501065        intercept.isRegex = *optionalIsRegex;
    1051 
    1052     // FIXME: Support intercepting requests.
     1066    intercept.networkStage = networkStage.value();
    10531067
    10541068    if (!m_intercepts.appendIfNotContains(intercept))
    1055         errorString = "Intercept for given url and given isRegex already exists"_s;
    1056 }
    1057 
    1058 void InspectorNetworkAgent::removeInterception(ErrorString& errorString, const String& url, const bool* optionalCaseSensitive, const bool* optionalIsRegex, const String* networkStageString)
    1059 {
    1060     if (networkStageString) {
    1061         auto networkStage = Inspector::Protocol::InspectorHelpers::parseEnumValueFromString<Inspector::Protocol::Network::NetworkStage>(*networkStageString);
    1062         if (!networkStage) {
    1063             errorString = makeString("Unknown networkStage: "_s, *networkStageString);
    1064             return;
    1065         }
     1069        errorString = "Intercept for given url, given isRegex, and given stage already exists"_s;
     1070}
     1071
     1072void InspectorNetworkAgent::removeInterception(ErrorString& errorString, const String& url, const String& networkStageString, const bool* optionalCaseSensitive, const bool* optionalIsRegex)
     1073{
     1074    auto networkStage = Inspector::Protocol::InspectorHelpers::parseEnumValueFromString<Inspector::Protocol::Network::NetworkStage>(networkStageString);
     1075    if (!networkStage) {
     1076        errorString = makeString("Unknown networkStage: "_s, networkStageString);
     1077        return;
    10661078    }
    10671079
     
    10721084    if (optionalIsRegex)
    10731085        intercept.isRegex = *optionalIsRegex;
    1074 
    1075     // FIXME: Support intercepting requests.
     1086    intercept.networkStage = networkStage.value();
    10761087
    10771088    if (!m_intercepts.removeAll(intercept))
    1078         errorString = "Missing intercept for given url and given isRegex"_s;
    1079 }
    1080 
    1081 bool InspectorNetworkAgent::willInterceptRequest(const ResourceRequest& request)
     1089        errorString = "Missing intercept for given url, given isRegex, and given stage"_s;
     1090}
     1091
     1092bool InspectorNetworkAgent::willIntercept(const ResourceRequest& request)
    10821093{
    10831094    if (!m_interceptionEnabled)
    10841095        return false;
    10851096
    1086     return shouldIntercept(request.url());
    1087 }
    1088 
    1089 bool InspectorNetworkAgent::shouldInterceptResponse(const ResourceResponse& response)
     1097    return shouldIntercept(request.url(), NetworkStage::Request)
     1098        || shouldIntercept(request.url(), NetworkStage::Response);
     1099}
     1100
     1101bool InspectorNetworkAgent::shouldInterceptRequest(const ResourceRequest& request)
    10901102{
    10911103    if (!m_interceptionEnabled)
    10921104        return false;
    10931105
    1094     return shouldIntercept(response.url());
     1106    return shouldIntercept(request.url(), NetworkStage::Request);
     1107}
     1108
     1109bool InspectorNetworkAgent::shouldInterceptResponse(const ResourceResponse& response)
     1110{
     1111    if (!m_interceptionEnabled)
     1112        return false;
     1113
     1114    return shouldIntercept(response.url(), NetworkStage::Response);
     1115}
     1116
     1117void InspectorNetworkAgent::interceptRequest(ResourceLoader& loader, CompletionHandler<void(const ResourceRequest&)>&& handler)
     1118{
     1119    ASSERT(m_enabled);
     1120    ASSERT(m_interceptionEnabled);
     1121
     1122    String requestId = IdentifiersFactory::requestId(loader.identifier());
     1123    if (m_pendingInterceptRequests.contains(requestId)) {
     1124        handler(loader.request());
     1125        return;
     1126    }
     1127    m_pendingInterceptRequests.set(requestId, makeUnique<PendingInterceptRequest>(&loader, WTFMove(handler)));
     1128    m_frontendDispatcher->requestIntercepted(requestId, buildObjectForResourceRequest(loader.request()));
    10951129}
    10961130
     
    11121146}
    11131147
    1114 void InspectorNetworkAgent::interceptContinue(ErrorString& errorString, const String& requestId)
    1115 {
    1116     auto pendingInterceptResponse = m_pendingInterceptResponses.take(requestId);
    1117     if (!pendingInterceptResponse) {
    1118         errorString = "Missing pending intercept response for given requestId"_s;
    1119         return;
    1120     }
    1121 
    1122     pendingInterceptResponse->respondWithOriginalResponse();
     1148void InspectorNetworkAgent::interceptContinue(ErrorString& errorString, const String& requestId, const String& networkStageString)
     1149{
     1150    auto networkStage = Inspector::Protocol::InspectorHelpers::parseEnumValueFromString<Inspector::Protocol::Network::NetworkStage>(networkStageString);
     1151    if (!networkStage) {
     1152        errorString = makeString("Unknown networkStage: "_s, networkStageString);
     1153        return;
     1154    }
     1155
     1156    switch (networkStage.value()) {
     1157    case NetworkStage::Request:
     1158        if (auto pendingInterceptRequest = m_pendingInterceptRequests.take(requestId))
     1159            pendingInterceptRequest->continueWithOriginalRequest();
     1160        else
     1161            errorString = "Missing pending intercept request for given requestId"_s;
     1162        return;
     1163    case NetworkStage::Response:
     1164        if (auto pendingInterceptResponse = m_pendingInterceptResponses.take(requestId))
     1165            pendingInterceptResponse->respondWithOriginalResponse();
     1166        else
     1167            errorString = "Missing pending intercept response for given requestId"_s;
     1168        return;
     1169    }
     1170    ASSERT_NOT_REACHED();
     1171}
     1172
     1173void InspectorNetworkAgent::interceptWithRequest(ErrorString& errorString, const String& requestId, const String* url, const String* method, const JSON::Object* headers, const String* postData)
     1174{
     1175    auto pendingRequest = m_pendingInterceptRequests.take(requestId);
     1176    if (!pendingRequest) {
     1177        errorString = "Missing pending intercept request for given requestId"_s;
     1178        return;
     1179    }
     1180
     1181    auto& loader = *pendingRequest->m_loader;
     1182    ResourceRequest request = loader.request();
     1183    if (url)
     1184        request.setURL(URL({ }, *url));
     1185    if (method)
     1186        request.setHTTPMethod(*method);
     1187    if (headers) {
     1188        HTTPHeaderMap explicitHeaders;
     1189        for (auto& [key, value] : *headers) {
     1190            String headerValue;
     1191            if (value->asString(headerValue))
     1192                explicitHeaders.add(key, headerValue);
     1193        }
     1194        request.setHTTPHeaderFields(WTFMove(explicitHeaders));
     1195    }
     1196    if (postData) {
     1197        Vector<uint8_t> buffer;
     1198        if (!base64Decode(*postData, buffer)) {
     1199            errorString = "Unable to decode given postData"_s;
     1200            return;
     1201        }
     1202
     1203        request.setHTTPBody(FormData::create(buffer));
     1204    }
     1205    // FIXME: figure out how to identify when a request has been overridden when we add this to the frontend.
     1206    pendingRequest->continueWithRequest(request);
    11231207}
    11241208
     
    11591243            return;
    11601244        }
     1245
    11611246        overrideData = SharedBuffer::create(WTFMove(buffer));
    11621247    } else
     
    11641249
    11651250    pendingInterceptResponse->respond(overrideResponse, overrideData);
     1251}
     1252
     1253void InspectorNetworkAgent::interceptRequestWithResponse(ErrorString& errorString, const String& requestId, const String& content, bool base64Encoded, const String& mimeType, int status, const String& statusText, const JSON::Object& headers)
     1254{
     1255    auto pendingRequest = m_pendingInterceptRequests.take(requestId);
     1256    if (!pendingRequest) {
     1257        errorString = "Missing pending intercept request for given requestId"_s;
     1258        return;
     1259    }
     1260
     1261    // Loader will be retained in the didReceiveResponse lambda below.
     1262    RefPtr<ResourceLoader> loader = pendingRequest->m_loader.get();
     1263    if (loader->reachedTerminalState()) {
     1264        errorString = "Unable to fulfill request, it has already been processed"_s;
     1265        return;
     1266    }
     1267
     1268    RefPtr<SharedBuffer> data;
     1269    if (base64Encoded) {
     1270        Vector<uint8_t> buffer;
     1271        if (!base64Decode(content, buffer)) {
     1272            errorString = "Unable to decode given content"_s;
     1273            return;
     1274        }
     1275
     1276        data = SharedBuffer::create(WTFMove(buffer));
     1277    } else
     1278        data = SharedBuffer::create(content.utf8().data(), content.utf8().length());
     1279
     1280    // Mimic data URL load behavior - report didReceiveResponse & didFinishLoading.
     1281    ResourceResponse response(pendingRequest->m_loader->url(), mimeType, data->size(), String());
     1282    response.setSource(ResourceResponse::Source::InspectorOverride);
     1283    response.setHTTPStatusCode(status);
     1284    response.setHTTPStatusText(statusText);
     1285    HTTPHeaderMap explicitHeaders;
     1286    for (auto& [key, value] : headers) {
     1287        String headerValue;
     1288        if (value->asString(headerValue))
     1289            explicitHeaders.add(key, headerValue);
     1290    }
     1291    response.setHTTPHeaderFields(WTFMove(explicitHeaders));
     1292    response.setHTTPHeaderField(HTTPHeaderName::ContentType, response.mimeType());
     1293    loader->didReceiveResponse(response, [loader, buffer = data.releaseNonNull()]() mutable {
     1294        if (buffer->size())
     1295            loader->didReceiveBuffer(WTFMove(buffer), buffer->size(), DataPayloadWholeResource);
     1296        loader->didFinishLoading(NetworkLoadMetrics());
     1297    });
     1298}
     1299
     1300void InspectorNetworkAgent::interceptRequestWithError(ErrorString& errorString, const String& requestId, const String& errorTypeString)
     1301{
     1302    auto pendingRequest = m_pendingInterceptRequests.take(requestId);
     1303    if (!pendingRequest) {
     1304        errorString = "Missing pending intercept request for given requestId"_s;
     1305        return;
     1306    }
     1307
     1308    auto& loader = *pendingRequest->m_loader;
     1309    if (loader.reachedTerminalState()) {
     1310        errorString = "Unable to abort request, it has already been processed"_s;
     1311        return;
     1312    }
     1313
     1314    auto errorType = Inspector::Protocol::InspectorHelpers::parseEnumValueFromString<Inspector::Protocol::Network::ResourceErrorType>(errorTypeString);
     1315    if (!errorType) {
     1316        errorString = makeString("Unknown errorType: "_s, errorTypeString);
     1317        return;
     1318    }
     1319
     1320    ResourceError error;
     1321    switch (errorType.value()) {
     1322    case Inspector::Protocol::Network::ResourceErrorType::General:
     1323        error = ResourceError(errorDomainWebKitInternal, 0, loader.url(), "Request intercepted"_s, ResourceError::Type::General);
     1324        break;
     1325    case Inspector::Protocol::Network::ResourceErrorType::AccessControl:
     1326        error = ResourceError(errorDomainWebKitInternal, 0, loader.url(), "Access denied"_s, ResourceError::Type::AccessControl);
     1327        break;
     1328    case Inspector::Protocol::Network::ResourceErrorType::Cancellation:
     1329        error = ResourceError(errorDomainWebKitInternal, 0, loader.url(), "Request canceled"_s, ResourceError::Type::Cancellation);
     1330        break;
     1331    case Inspector::Protocol::Network::ResourceErrorType::Timeout:
     1332        error = ResourceError(errorDomainWebKitInternal, 0, loader.url(), "Request timed out"_s, ResourceError::Type::Timeout);
     1333        break;
     1334    }
     1335    loader.didFail(error);
    11661336}
    11671337
     
    11821352    if (MIMETypeRegistry::isTextMIMEType(mimeType))
    11831353        return TextResourceDecoder::create(mimeType, "UTF-8");
     1354
    11841355    if (MIMETypeRegistry::isXMLMIMEType(mimeType)) {
    11851356        auto decoder = TextResourceDecoder::create("application/xml"_s);
  • trunk/Source/WebCore/inspector/agents/InspectorNetworkAgent.h

    r261546 r263072  
    8989    void resolveWebSocket(ErrorString&, const String& requestId, const String* objectGroup, RefPtr<Inspector::Protocol::Runtime::RemoteObject>&) final;
    9090    void setInterceptionEnabled(ErrorString&, bool enabled) final;
    91     void addInterception(ErrorString&, const String& url, const bool* caseSensitive, const bool* isRegex, const String* networkStageString) final;
    92     void removeInterception(ErrorString&, const String& url, const bool* caseSensitive, const bool* isRegex, const String* networkStageString) final;
    93     void interceptContinue(ErrorString&, const String& requestId) final;
     91    void addInterception(ErrorString&, const String& url, const String& networkStageString, const bool* caseSensitive, const bool* isRegex) final;
     92    void removeInterception(ErrorString&, const String& url, const String& networkStageString, const bool* caseSensitive, const bool* isRegex) final;
     93    void interceptContinue(ErrorString&, const String& requestId, const String& networkStageString) final;
     94    void interceptWithRequest(ErrorString&, const String& requestId, const String* url, const String* method, const JSON::Object* headers, const String* postData) final;
    9495    void interceptWithResponse(ErrorString&, const String& requestId, const String& content, bool base64Encoded, const String* mimeType, const int* status, const String* statusText, const JSON::Object* headers) final;
     96    void interceptRequestWithResponse(ErrorString&, const String& requestId, const String& content, bool base64Encoded, const String& mimeType, int status, const String& statusText, const JSON::Object& headers) final;
     97    void interceptRequestWithError(ErrorString&, const String& requestId, const String& errorType) final;
    9598
    9699    // InspectorInstrumentation
     
    119122    void setInitialScriptContent(unsigned long identifier, const String& sourceString);
    120123    void didScheduleStyleRecalculation(Document&);
    121     bool willInterceptRequest(const ResourceRequest&);
     124    bool willIntercept(const ResourceRequest&);
     125    bool shouldInterceptRequest(const ResourceRequest&);
    122126    bool shouldInterceptResponse(const ResourceResponse&);
    123127    void interceptResponse(const ResourceResponse&, unsigned long identifier, CompletionHandler<void(const ResourceResponse&, RefPtr<SharedBuffer>)>&&);
     128    void interceptRequest(ResourceLoader&, CompletionHandler<void(const ResourceRequest&)>&&);
    124129
    125130    void searchOtherRequests(const JSC::Yarr::RegularExpression&, RefPtr<JSON::ArrayOf<Inspector::Protocol::Page::SearchResult>>&);
     
    141146    void willSendRequest(unsigned long identifier, DocumentLoader*, ResourceRequest&, const ResourceResponse& redirectResponse, InspectorPageAgent::ResourceType);
    142147
    143     bool shouldIntercept(URL);
     148    using NetworkStage = Inspector::Protocol::Network::NetworkStage;
     149    bool shouldIntercept(URL, NetworkStage);
     150    void continuePendingRequests();
    144151    void continuePendingResponses();
    145152
     
    153160
    154161    double timestamp();
     162
     163    class PendingInterceptRequest {
     164        WTF_MAKE_NONCOPYABLE(PendingInterceptRequest);
     165        WTF_MAKE_FAST_ALLOCATED;
     166    public:
     167        PendingInterceptRequest(RefPtr<ResourceLoader> loader, CompletionHandler<void(const ResourceRequest&)>&& completionHandler)
     168            : m_loader(loader)
     169            , m_completionHandler(WTFMove(completionHandler))
     170        { }
     171
     172        void continueWithOriginalRequest()
     173        {
     174            if (!m_loader->reachedTerminalState())
     175                m_completionHandler(m_loader->request());
     176        }
     177
     178        void continueWithRequest(const ResourceRequest& request)
     179        {
     180            m_completionHandler(request);
     181        }
     182
     183        PendingInterceptRequest() = default;
     184        RefPtr<ResourceLoader> m_loader;
     185        CompletionHandler<void(const ResourceRequest&)> m_completionHandler;
     186    };
    155187
    156188    class PendingInterceptResponse {
     
    205237        bool caseSensitive { true };
    206238        bool isRegex { false };
     239        NetworkStage networkStage { NetworkStage::Response };
    207240
    208241        inline bool operator==(const Intercept& other) const
     
    210243            return url == other.url
    211244                && caseSensitive == other.caseSensitive
    212                 && isRegex == other.isRegex;
     245                && isRegex == other.isRegex
     246                && networkStage == other.networkStage;
    213247        }
    214248    };
    215249    Vector<Intercept> m_intercepts;
     250    HashMap<String, std::unique_ptr<PendingInterceptRequest>> m_pendingInterceptRequests;
    216251    HashMap<String, std::unique_ptr<PendingInterceptResponse>> m_pendingInterceptResponses;
    217252
  • trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp

    r262695 r263072  
    842842    request.updateReferrerPolicy(document() ? document()->referrerPolicy() : ReferrerPolicy::NoReferrerWhenDowngrade);
    843843
    844     if (InspectorInstrumentation::willInterceptRequest(&frame, request.resourceRequest()))
     844    if (InspectorInstrumentation::willIntercept(&frame, request.resourceRequest()))
    845845        request.setCachingPolicy(CachingPolicy::DisallowCaching);
    846846
     
    14321432ResourceErrorOr<CachedResourceHandle<CachedResource>> CachedResourceLoader::preload(CachedResource::Type type, CachedResourceRequest&& request)
    14331433{
    1434     if (InspectorInstrumentation::willInterceptRequest(frame(), request.resourceRequest()))
     1434    if (InspectorInstrumentation::willIntercept(frame(), request.resourceRequest()))
    14351435        return makeUnexpected(ResourceError { errorDomainWebKitInternal, 0, request.resourceRequest().url(), "Inspector intercept"_s });
    14361436
  • trunk/Source/WebInspectorUI/ChangeLog

    r262956 r263072  
     12020-06-15  Pavel Feldman <pavel.feldman@gmail.com>
     2
     3        Web Inspector: introduce request interception
     4        https://bugs.webkit.org/show_bug.cgi?id=207446
     5
     6        Reviewed by Devin Rousso.
     7
     8        This change introduces network request interception to the Network
     9        protocol domain. It adds Network.interceptWithRequest notification that
     10        can be continued, modified or fulfilled. NetworkStage enum can now have
     11        'request' and 'response' values.
     12
     13        * UserInterface/Controllers/NetworkManager.js:
     14        (WI.NetworkManager.prototype.initializeTarget):
     15        (WI.NetworkManager.prototype.addLocalResourceOverride):
     16        (WI.NetworkManager.prototype.removeLocalResourceOverride):
     17        (WI.NetworkManager.prototype.requestIntercepted):
     18        (WI.NetworkManager.prototype.responseIntercepted):
     19        (WI.NetworkManager.prototype._handleResourceOverrideDisabledChanged):
     20        * UserInterface/Protocol/NetworkObserver.js:
     21        (WI.NetworkObserver.prototype.requestIntercepted):
     22
    1232020-06-12  Devin Rousso  <drousso@apple.com>
    224
  • trunk/Source/WebInspectorUI/UserInterface/Controllers/NetworkManager.js

    r262956 r263072  
    160160                        target.NetworkAgent.addInterception.invoke({
    161161                            url: localResourceOverride.url,
     162                            stage: InspectorBackend.Enum.Network.NetworkStage.Response,
    162163                            caseSensitive: localResourceOverride.isCaseSensitive,
    163164                            isRegex: localResourceOverride.isRegex,
    164                             networkStage: InspectorBackend.Enum.Network.NetworkStage.Response,
    165165                        });
    166166                    }
     
    365365                caseSensitive: localResourceOverride.isCaseSensitive,
    366366                isRegex: localResourceOverride.isRegex,
    367                 networkStage: InspectorBackend.Enum.Network.NetworkStage.Response,
     367                stage: InspectorBackend.Enum.Network.NetworkStage.Response,
    368368            };
    369369
     
    398398                caseSensitive: localResourceOverride.isCaseSensitive,
    399399                isRegex: localResourceOverride.isRegex,
    400                 networkStage: InspectorBackend.Enum.Network.NetworkStage.Response,
     400                stage: InspectorBackend.Enum.Network.NetworkStage.Response,
    401401            };
    402402
     
    909909    }
    910910
     911    requestIntercepted(target, requestId, request)
     912    {
     913        // FIXME: add request interception support to the frontend.
     914        this.dispatchEventToListeners(WI.NetworkManager.Event.RequestIntercepted, {target, requestId, request});
     915    }
     916
    911917    responseIntercepted(target, requestId, response)
    912918    {
     
    914920        let localResourceOverride = this.localResourceOverrideForURL(url);
    915921        if (!localResourceOverride || localResourceOverride.disabled) {
    916             target.NetworkAgent.interceptContinue(requestId);
     922            target.NetworkAgent.interceptContinue.invoke({
     923                requestId,
     924                stage: InspectorBackend.Enum.Network.NetworkStage.Response,
     925            });
    917926            return;
    918927        }
     
    13771386            caseSensitive: localResourceOverride.isCaseSensitive,
    13781387            isRegex: localResourceOverride.isRegex,
    1379             networkStage: InspectorBackend.Enum.Network.NetworkStage.Response,
     1388            stage: InspectorBackend.Enum.Network.NetworkStage.Response,
    13801389        };
    13811390
     
    14331442    LocalResourceOverrideAdded: "network-manager-local-resource-override-added",
    14341443    LocalResourceOverrideRemoved: "network-manager-local-resource-override-removed",
     1444    RequestIntercepted: "network-manager-request-intercepted"
    14351445};
  • trunk/Source/WebInspectorUI/UserInterface/Protocol/NetworkObserver.js

    r261105 r263072  
    109109    }
    110110
     111    requestIntercepted(requestId, request)
     112    {
     113        WI.networkManager.requestIntercepted(this._target, requestId, request);
     114    }
     115
    111116    responseIntercepted(requestId, response)
    112117    {
  • trunk/Source/WebKit/ChangeLog

    r263061 r263072  
     12020-06-15  Pavel Feldman  <pavel.feldman@gmail.com>
     2
     3        Web Inspector: introduce request interception
     4        https://bugs.webkit.org/show_bug.cgi?id=207446
     5
     6        Reviewed by Devin Rousso.
     7
     8        This change introduces network request interception to the Network
     9        protocol domain. It adds Network.interceptWithRequest notification that
     10        can be continued, modified or fulfilled. NetworkStage enum can now have
     11        'request' and 'response' values.
     12
     13        * WebProcess/Network/WebLoaderStrategy.cpp:
     14        (WebKit::WebLoaderStrategy::scheduleLoad):
     15
    1162020-06-15  Brent Fulgham  <bfulgham@apple.com>
    217
  • trunk/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp

    r262695 r263072  
    5959#include <WebCore/FrameLoader.h>
    6060#include <WebCore/HTMLFrameOwnerElement.h>
     61#include <WebCore/InspectorInstrumentationWebKit.h>
    6162#include <WebCore/NetscapePlugInStreamLoader.h>
    6263#include <WebCore/NetworkLoadInformation.h>
     
    229230    if (!tryLoadingUsingURLSchemeHandler(resourceLoader, trackingParameters)) {
    230231        WEBLOADERSTRATEGY_RELEASE_LOG_IF_ALLOWED("scheduleLoad: URL will be scheduled with the NetworkProcess");
     232
     233        if (!resourceLoader.options().serviceWorkerRegistrationIdentifier && InspectorInstrumentationWebKit::shouldInterceptRequest(resourceLoader.frame(), resourceLoader.request())) {
     234            InspectorInstrumentationWebKit::interceptRequest(resourceLoader, [this, protectedResourceLoader = makeRefPtr(&resourceLoader), trackingParameters, shouldClearReferrerOnHTTPSToHTTPRedirect, resource](const ResourceRequest& request) {
     235                scheduleLoadFromNetworkProcess(*protectedResourceLoader, request, trackingParameters, shouldClearReferrerOnHTTPSToHTTPRedirect, maximumBufferingTime(resource));
     236            });
     237            return;
     238        }
    231239        scheduleLoadFromNetworkProcess(resourceLoader, resourceLoader.request(), trackingParameters, shouldClearReferrerOnHTTPSToHTTPRedirect, maximumBufferingTime(resource));
    232240        return;
Note: See TracChangeset for help on using the changeset viewer.