| Differences between
and this patch
- a/Source/JavaScriptCore/ChangeLog +14 lines
Lines 1-3 a/Source/JavaScriptCore/ChangeLog_sec1
1
2020-02-29  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 NOBODY (OOPS!).
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
1
2020-05-12  Ross Kirsling  <ross.kirsling@sony.com>
15
2020-05-12  Ross Kirsling  <ross.kirsling@sony.com>
2
16
3
        Fix existing usage of final/override/virtual in JSC and WTF
17
        Fix existing usage of final/override/virtual in JSC and WTF
- a/Source/WebCore/ChangeLog +49 lines
Lines 1-3 a/Source/WebCore/ChangeLog_sec1
1
2020-02-29  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 NOBODY (OOPS!).
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
        Test: inspector/network/intercept-request.html
14
15
        * inspector/InspectorInstrumentation.cpp:
16
        (WebCore::InspectorInstrumentation::willInterceptImpl):
17
        (WebCore::InspectorInstrumentation::shouldInterceptRequestImpl):
18
        (WebCore::InspectorInstrumentation::interceptRequestImpl):
19
        * inspector/InspectorInstrumentation.h:
20
        (WebCore::InspectorInstrumentation::willIntercept):
21
        (WebCore::InspectorInstrumentation::shouldInterceptRequest):
22
        (WebCore::InspectorInstrumentation::interceptRequest):
23
        * inspector/InspectorInstrumentationWebKit.cpp:
24
        (WebCore::InspectorInstrumentationWebKit::shouldInterceptRequestInternal):
25
        (WebCore::InspectorInstrumentationWebKit::interceptRequestInternal):
26
        * inspector/InspectorInstrumentationWebKit.h:
27
        (WebCore::InspectorInstrumentationWebKit::shouldInterceptRequest):
28
        (WebCore::InspectorInstrumentationWebKit::interceptRequest):
29
        * inspector/agents/InspectorNetworkAgent.cpp:
30
        (WebCore::InspectorNetworkAgent::disable):
31
        (WebCore::InspectorNetworkAgent::shouldIntercept):
32
        (WebCore::InspectorNetworkAgent::continuePendingRequests):
33
        (WebCore::InspectorNetworkAgent::setInterceptionEnabled):
34
        (WebCore::InspectorNetworkAgent::addInterception):
35
        (WebCore::InspectorNetworkAgent::removeInterception):
36
        (WebCore::InspectorNetworkAgent::willIntercept):
37
        (WebCore::InspectorNetworkAgent::shouldInterceptRequest):
38
        (WebCore::InspectorNetworkAgent::shouldInterceptResponse):
39
        (WebCore::InspectorNetworkAgent::interceptRequest):
40
        (WebCore::InspectorNetworkAgent::interceptContinue):
41
        (WebCore::InspectorNetworkAgent::interceptWithRequest):
42
        (WebCore::InspectorNetworkAgent::interceptWithResponse):
43
        * inspector/agents/InspectorNetworkAgent.h:
44
        (WebCore::InspectorNetworkAgent::PendingInterceptRequest::PendingInterceptRequest):
45
        (WebCore::InspectorNetworkAgent::Intercept::operator== const):
46
        * loader/cache/CachedResourceLoader.cpp:
47
        (WebCore::CachedResourceLoader::requestResource):
48
        (WebCore::CachedResourceLoader::preload):
49
1
2020-05-12  Eric Carlson  <eric.carlson@apple.com>
50
2020-05-12  Eric Carlson  <eric.carlson@apple.com>
2
51
3
        Poster set after playback begins should be ignored
52
        Poster set after playback begins should be ignored
- a/Source/WebInspectorUI/ChangeLog +22 lines
Lines 1-3 a/Source/WebInspectorUI/ChangeLog_sec1
1
2020-05-13  Pavel  <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 NOBODY (OOPS!).
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
1
2020-05-11  Devin Rousso  <drousso@apple.com>
23
2020-05-11  Devin Rousso  <drousso@apple.com>
2
24
3
        Web Inspector: Network: Timing: gaps around the "Resource does not have timing data" message
25
        Web Inspector: Network: Timing: gaps around the "Resource does not have timing data" message
- a/Source/WebKit/ChangeLog +15 lines
Lines 1-3 a/Source/WebKit/ChangeLog_sec1
1
2020-02-29  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 NOBODY (OOPS!).
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
1
2020-05-12  Carlos Garcia Campos  <cgarcia@igalia.com>
16
2020-05-12  Carlos Garcia Campos  <cgarcia@igalia.com>
2
17
3
        [GTK] Rework drag and drop handling in preparation for GTK4
18
        [GTK] Rework drag and drop handling in preparation for GTK4
- a/Source/JavaScriptCore/inspector/protocol/Network.json -11 / +58 lines
Lines 155-161 a/Source/JavaScriptCore/inspector/protocol/Network.json_sec1
155
            "id": "NetworkStage",
155
            "id": "NetworkStage",
156
            "type": "string",
156
            "type": "string",
157
            "description": "Different stages of a network request.",
157
            "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"]
159
        }
165
        }
160
    ],
166
    ],
161
    "commands": [
167
    "commands": [
Lines 238-247 a/Source/JavaScriptCore/inspector/protocol/Network.json_sec2
238
            "name": "addInterception",
244
            "name": "addInterception",
239
            "description": "Add an interception.",
245
            "description": "Add an interception.",
240
            "parameters": [
246
            "parameters": [
241
                { "name": "url", "type": "string" },
247
                { "name": "url", "type": "string", "description": "URL pattern to intercept, intercept everything if not specified or empty" },
248
                { "name": "stage", "$ref": "NetworkStage", "description": "Stage to intercept." },
242
                { "name": "caseSensitive", "type": "boolean", "optional": true, "description": "If false, ignores letter casing of `url` parameter." },
249
                { "name": "caseSensitive", "type": "boolean", "optional": true, "description": "If false, ignores letter casing of `url` parameter." },
243
                { "name": "isRegex", "type": "boolean", "optional": true, "description": "If true, treats `url` parameter as a regular expression." },
250
                { "name": "isRegex", "type": "boolean", "optional": true, "description": "If true, treats `url` parameter as a regular expression." }
244
                { "name": "stage", "$ref": "NetworkStage", "optional": true, "description": "If not present this applies to all network stages." }
245
            ]
251
            ]
246
        },
252
        },
247
        {
253
        {
Lines 249-264 a/Source/JavaScriptCore/inspector/protocol/Network.json_sec3
249
            "description": "Remove an interception.",
255
            "description": "Remove an interception.",
250
            "parameters": [
256
            "parameters": [
251
                { "name": "url", "type": "string" },
257
                { "name": "url", "type": "string" },
258
                { "name": "stage", "$ref": "NetworkStage", "description": "Stage to intercept." },
252
                { "name": "caseSensitive", "type": "boolean", "optional": true, "description": "If false, ignores letter casing of `url` parameter." },
259
                { "name": "caseSensitive", "type": "boolean", "optional": true, "description": "If false, ignores letter casing of `url` parameter." },
253
                { "name": "isRegex", "type": "boolean", "optional": true, "description": "If true, treats `url` parameter as a regular expression." },
260
                { "name": "isRegex", "type": "boolean", "optional": true, "description": "If true, treats `url` parameter as a regular expression." }
254
                { "name": "stage", "$ref": "NetworkStage", "optional": true, "description": "If not present this applies to all network stages." }
255
            ]
261
            ]
256
        },
262
        },
257
        {
263
        {
258
            "name": "interceptContinue",
264
            "name": "interceptContinue",
259
            "description": "Continue an interception with no modifications.",
265
            "description": "Continue request or response without modifications.",
260
            "parameters": [
266
            "parameters": [
261
                { "name": "requestId", "$ref": "RequestId", "description": "Identifier for the intercepted Network request or response to continue." }
267
                { "name": "requestId", "$ref": "RequestId", "description": "Identifier for the intercepted Network request or response to continue." },
268
                { "name": "stage", "$ref": "NetworkStage", "description": "Stage to continue." }
269
            ]
270
        },
271
        {
272
            "name": "interceptWithRequest",
273
            "description": "Replace intercepted request with the provided one.",
274
            "parameters": [
275
                { "name": "requestId", "$ref": "RequestId", "description": "Identifier for the intercepted Network request or response to continue." },
276
                { "name": "method", "type": "string", "optional": true,"description": "HTTP request method." },
277
                { "name": "url", "type": "string", "optional": true,"description": "HTTP request url." },
278
                { "name": "headers", "$ref": "Headers", "optional": true, "description": "HTTP response headers. Pass through original values if unmodified." },
279
                { "name": "postData", "type": "string", "optional": true, "description": "HTTP POST request data, base64-encoded." }
262
            ]
280
            ]
263
        },
281
        },
264
        {
282
        {
Lines 266-278 a/Source/JavaScriptCore/inspector/protocol/Network.json_sec4
266
            "description": "Provide response content for an intercepted response.",
284
            "description": "Provide response content for an intercepted response.",
267
            "parameters": [
285
            "parameters": [
268
                { "name": "requestId", "$ref": "RequestId", "description": "Identifier for the intercepted Network response to modify." },
286
                { "name": "requestId", "$ref": "RequestId", "description": "Identifier for the intercepted Network response to modify." },
269
                { "name": "content", "type": "string" },
287
                { "name": "content", "type": "string", "optional": true },
270
                { "name": "base64Encoded", "type": "boolean", "description": "True, if content was sent as base64." },
288
                { "name": "base64Encoded", "type": "boolean", "optional": true, "description": "True, if content was sent as base64." },
271
                { "name": "mimeType", "type": "string", "optional": true, "description": "MIME Type for the data." },
289
                { "name": "mimeType", "type": "string", "optional": true, "description": "MIME Type for the data." },
272
                { "name": "status", "type": "integer", "optional": true, "description": "HTTP response status code. Pass through original values if unmodified." },
290
                { "name": "status", "type": "integer", "optional": true, "description": "HTTP response status code. Pass through original values if unmodified." },
273
                { "name": "statusText", "type": "string", "optional": true, "description": "HTTP response status text. Pass through original values if unmodified." },
291
                { "name": "statusText", "type": "string", "optional": true, "description": "HTTP response status text. Pass through original values if unmodified." },
274
                { "name": "headers", "$ref": "Headers", "optional": true, "description": "HTTP response headers. Pass through original values if unmodified." }
292
                { "name": "headers", "$ref": "Headers", "optional": true, "description": "HTTP response headers. Pass through original values if unmodified." }
275
            ]
293
            ]
294
        },
295
        {
296
            "name": "interceptRequestWithResponse",
297
            "description": "Provide response content for an intercepted response.",
298
            "parameters": [
299
                { "name": "requestId", "$ref": "RequestId", "description": "Identifier for the intercepted Network response to modify." },
300
                { "name": "content", "type": "string" },
301
                { "name": "base64Encoded", "type": "boolean", "optional": true, "description": "True, if content was sent as base64." },
302
                { "name": "mimeType", "type": "string", "description": "MIME Type for the data." },
303
                { "name": "status", "type": "integer", "description": "HTTP response status code. Pass through original values if unmodified." },
304
                { "name": "statusText", "type": "string", "description": "HTTP response status text. Pass through original values if unmodified." },
305
                { "name": "headers", "$ref": "Headers", "description": "HTTP response headers. Pass through original values if unmodified." }
306
            ]
307
        },
308
        {
309
            "name": "interceptRequestWithError",
310
            "description": "Fail request or response with given error type.",
311
            "parameters": [
312
                { "name": "requestId", "$ref": "RequestId", "description": "Identifier for the intercepted Network request to fail." },
313
                { "name": "errorType", "$ref": "ResourceErrorType", "description": "Deliver error reason for the request failure." }
314
            ]
276
        }
315
        }
277
    ],
316
    ],
278
    "events": [
317
    "events": [
Lines 348-356 a/Source/JavaScriptCore/inspector/protocol/Network.json_sec5
348
                { "name": "resource", "$ref": "CachedResource", "description": "Cached resource data." }
387
                { "name": "resource", "$ref": "CachedResource", "description": "Cached resource data." }
349
            ]
388
            ]
350
        },
389
        },
390
        {
391
            "name": "requestIntercepted",
392
            "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.",
393
            "parameters": [
394
                { "name": "requestId", "$ref": "RequestId", "description": "Identifier for this intercepted network. Corresponds with an earlier <code>Network.requestWillBeSent</code>." },
395
                { "name": "request", "$ref": "Request", "description": "Original request content that would proceed if this is continued." }
396
            ]
397
        },
351
        {
398
        {
352
            "name": "responseIntercepted",
399
            "name": "responseIntercepted",
353
            "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.",
400
            "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.",
354
            "parameters": [
401
            "parameters": [
355
                { "name": "requestId", "$ref": "RequestId", "description": "Identifier for this intercepted network. Corresponds with an earlier <code>Network.requestWillBeSent</code>." },
402
                { "name": "requestId", "$ref": "RequestId", "description": "Identifier for this intercepted network. Corresponds with an earlier <code>Network.requestWillBeSent</code>." },
356
                { "name": "response", "$ref": "Response", "description": "Original response content that would proceed if this is continued." }
403
                { "name": "response", "$ref": "Response", "description": "Original response content that would proceed if this is continued." }
- a/Source/WebCore/inspector/InspectorInstrumentation.cpp -2 / +15 lines
Lines 810-819 void InspectorInstrumentation::willDestroyCachedResourceImpl(CachedResource& cac a/Source/WebCore/inspector/InspectorInstrumentation.cpp_sec1
810
    }
810
    }
811
}
811
}
812
812
813
bool InspectorInstrumentation::willInterceptRequestImpl(InstrumentingAgents& instrumentingAgents, const ResourceRequest& request)
813
bool InspectorInstrumentation::willInterceptImpl(InstrumentingAgents& instrumentingAgents, const ResourceRequest& request)
814
{
814
{
815
    if (auto* networkAgent = instrumentingAgents.inspectorNetworkAgent())
815
    if (auto* networkAgent = instrumentingAgents.inspectorNetworkAgent())
816
        return networkAgent->willInterceptRequest(request);
816
        return networkAgent->willIntercept(request);
817
    return false;
818
}
819
820
bool InspectorInstrumentation::shouldInterceptRequestImpl(InstrumentingAgents& instrumentingAgents, const ResourceRequest& request)
821
{
822
    if (auto* networkAgent = instrumentingAgents.inspectorNetworkAgent())
823
        return networkAgent->shouldInterceptRequest(request);
817
    return false;
824
    return false;
818
}
825
}
819
826
Lines 824-829 bool InspectorInstrumentation::shouldInterceptResponseImpl(InstrumentingAgents& a/Source/WebCore/inspector/InspectorInstrumentation.cpp_sec2
824
    return false;
831
    return false;
825
}
832
}
826
833
834
void InspectorInstrumentation::interceptRequestImpl(InstrumentingAgents& instrumentingAgents, ResourceLoader& loader, CompletionHandler<void(const ResourceRequest*)>&& handler)
835
{
836
    if (auto* networkAgent = instrumentingAgents.inspectorNetworkAgent())
837
        networkAgent->interceptRequest(loader, WTFMove(handler));
838
}
839
827
void InspectorInstrumentation::interceptResponseImpl(InstrumentingAgents& instrumentingAgents, const ResourceResponse& response, unsigned long identifier, CompletionHandler<void(const ResourceResponse&, RefPtr<SharedBuffer>)>&& handler)
840
void InspectorInstrumentation::interceptResponseImpl(InstrumentingAgents& instrumentingAgents, const ResourceResponse& response, unsigned long identifier, CompletionHandler<void(const ResourceResponse&, RefPtr<SharedBuffer>)>&& handler)
828
{
841
{
829
    if (auto* networkAgent = instrumentingAgents.inspectorNetworkAgent())
842
    if (auto* networkAgent = instrumentingAgents.inspectorNetworkAgent())
- a/Source/WebCore/inspector/InspectorInstrumentation.h -4 / +24 lines
Lines 45-50 a/Source/WebCore/inspector/InspectorInstrumentation.h_sec1
45
#include "HitTestResult.h"
45
#include "HitTestResult.h"
46
#include "InspectorInstrumentationPublic.h"
46
#include "InspectorInstrumentationPublic.h"
47
#include "Page.h"
47
#include "Page.h"
48
#include "ResourceLoader.h"
48
#include "StorageArea.h"
49
#include "StorageArea.h"
49
#include "WebAnimation.h"
50
#include "WebAnimation.h"
50
#include "WorkerInspectorProxy.h"
51
#include "WorkerInspectorProxy.h"
Lines 232-239 public: a/Source/WebCore/inspector/InspectorInstrumentation.h_sec2
232
    static void defaultAppearanceDidChange(Page&, bool useDarkAppearance);
233
    static void defaultAppearanceDidChange(Page&, bool useDarkAppearance);
233
    static void willDestroyCachedResource(CachedResource&);
234
    static void willDestroyCachedResource(CachedResource&);
234
235
235
    static bool willInterceptRequest(const Frame*, const ResourceRequest&);
236
    static bool willIntercept(const Frame*, const ResourceRequest&);
237
    static bool shouldInterceptRequest(const Frame&, const ResourceRequest&);
236
    static bool shouldInterceptResponse(const Frame&, const ResourceResponse&);
238
    static bool shouldInterceptResponse(const Frame&, const ResourceResponse&);
239
    static void interceptRequest(ResourceLoader&, CompletionHandler<void(const ResourceRequest*)>&&);
237
    static void interceptResponse(const Frame&, const ResourceResponse&, unsigned long identifier, CompletionHandler<void(const ResourceResponse&, RefPtr<SharedBuffer>)>&&);
240
    static void interceptResponse(const Frame&, const ResourceResponse&, unsigned long identifier, CompletionHandler<void(const ResourceResponse&, RefPtr<SharedBuffer>)>&&);
238
241
239
    static void addMessageToConsole(Page&, std::unique_ptr<Inspector::ConsoleMessage>);
242
    static void addMessageToConsole(Page&, std::unique_ptr<Inspector::ConsoleMessage>);
Lines 437-444 private: a/Source/WebCore/inspector/InspectorInstrumentation.h_sec3
437
    static void defaultAppearanceDidChangeImpl(InstrumentingAgents&, bool useDarkAppearance);
440
    static void defaultAppearanceDidChangeImpl(InstrumentingAgents&, bool useDarkAppearance);
438
    static void willDestroyCachedResourceImpl(CachedResource&);
441
    static void willDestroyCachedResourceImpl(CachedResource&);
439
442
440
    static bool willInterceptRequestImpl(InstrumentingAgents&, const ResourceRequest&);
443
    static bool willInterceptImpl(InstrumentingAgents&, const ResourceRequest&);
444
    static bool shouldInterceptRequestImpl(InstrumentingAgents&, const ResourceRequest&);
441
    static bool shouldInterceptResponseImpl(InstrumentingAgents&, const ResourceResponse&);
445
    static bool shouldInterceptResponseImpl(InstrumentingAgents&, const ResourceResponse&);
446
    static void interceptRequestImpl(InstrumentingAgents&, ResourceLoader&, CompletionHandler<void(const ResourceRequest*)>&&);
442
    static void interceptResponseImpl(InstrumentingAgents&, const ResourceResponse&, unsigned long identifier, CompletionHandler<void(const ResourceResponse&, RefPtr<SharedBuffer>)>&&);
447
    static void interceptResponseImpl(InstrumentingAgents&, const ResourceResponse&, unsigned long identifier, CompletionHandler<void(const ResourceResponse&, RefPtr<SharedBuffer>)>&&);
443
448
444
    static void addMessageToConsoleImpl(InstrumentingAgents&, std::unique_ptr<Inspector::ConsoleMessage>);
449
    static void addMessageToConsoleImpl(InstrumentingAgents&, std::unique_ptr<Inspector::ConsoleMessage>);
Lines 1249-1259 inline void InspectorInstrumentation::willDestroyCachedResource(CachedResource& a/Source/WebCore/inspector/InspectorInstrumentation.h_sec4
1249
    willDestroyCachedResourceImpl(cachedResource);
1254
    willDestroyCachedResourceImpl(cachedResource);
1250
}
1255
}
1251
1256
1252
inline bool InspectorInstrumentation::willInterceptRequest(const Frame* frame, const ResourceRequest& request)
1257
inline bool InspectorInstrumentation::willIntercept(const Frame* frame, const ResourceRequest& request)
1253
{
1258
{
1254
    FAST_RETURN_IF_NO_FRONTENDS(false);
1259
    FAST_RETURN_IF_NO_FRONTENDS(false);
1255
    if (auto* instrumentingAgents = instrumentingAgentsForFrame(frame))
1260
    if (auto* instrumentingAgents = instrumentingAgentsForFrame(frame))
1256
        return willInterceptRequestImpl(*instrumentingAgents, request);
1261
        return willInterceptImpl(*instrumentingAgents, request);
1262
    return false;
1263
}
1264
1265
inline bool InspectorInstrumentation::shouldInterceptRequest(const Frame& frame, const ResourceRequest& request)
1266
{
1267
    ASSERT(InspectorInstrumentationPublic::hasFrontends());
1268
    if (auto* instrumentingAgents = instrumentingAgentsForFrame(frame))
1269
        return shouldInterceptRequestImpl(*instrumentingAgents, request);
1257
    return false;
1270
    return false;
1258
}
1271
}
1259
1272
Lines 1265-1270 inline bool InspectorInstrumentation::shouldInterceptResponse(const Frame& frame a/Source/WebCore/inspector/InspectorInstrumentation.h_sec5
1265
    return false;
1278
    return false;
1266
}
1279
}
1267
1280
1281
inline void InspectorInstrumentation::interceptRequest(ResourceLoader& loader, CompletionHandler<void(const ResourceRequest*)>&& handler)
1282
{
1283
    ASSERT(InspectorInstrumentation::shouldInterceptRequest(loader.frame(), loader.request()));
1284
    if (auto* instrumentingAgents = instrumentingAgentsForFrame(loader.frame()))
1285
        interceptRequestImpl(*instrumentingAgents, loader, WTFMove(handler));
1286
}
1287
1268
inline void InspectorInstrumentation::interceptResponse(const Frame& frame, const ResourceResponse& response, unsigned long identifier, CompletionHandler<void(const ResourceResponse&, RefPtr<SharedBuffer>)>&& handler)
1288
inline void InspectorInstrumentation::interceptResponse(const Frame& frame, const ResourceResponse& response, unsigned long identifier, CompletionHandler<void(const ResourceResponse&, RefPtr<SharedBuffer>)>&& handler)
1269
{
1289
{
1270
    ASSERT(InspectorInstrumentation::shouldInterceptResponse(frame, response));
1290
    ASSERT(InspectorInstrumentation::shouldInterceptResponse(frame, response));
- a/Source/WebCore/inspector/InspectorInstrumentationWebKit.cpp +10 lines
Lines 30-40 a/Source/WebCore/inspector/InspectorInstrumentationWebKit.cpp_sec1
30
30
31
namespace WebCore {
31
namespace WebCore {
32
32
33
bool InspectorInstrumentationWebKit::shouldInterceptRequestInternal(const Frame& frame, const ResourceRequest& request)
34
{
35
    return InspectorInstrumentation::shouldInterceptRequest(frame, request);
36
}
37
33
bool InspectorInstrumentationWebKit::shouldInterceptResponseInternal(const Frame& frame, const ResourceResponse& response)
38
bool InspectorInstrumentationWebKit::shouldInterceptResponseInternal(const Frame& frame, const ResourceResponse& response)
34
{
39
{
35
    return InspectorInstrumentation::shouldInterceptResponse(frame, response);
40
    return InspectorInstrumentation::shouldInterceptResponse(frame, response);
36
}
41
}
37
42
43
void InspectorInstrumentationWebKit::interceptRequestInternal(ResourceLoader& loader, CompletionHandler<void(const ResourceRequest*)>&& handler)
44
{
45
    InspectorInstrumentation::interceptRequest(loader, WTFMove(handler));
46
}
47
38
void InspectorInstrumentationWebKit::interceptResponseInternal(const Frame& frame, const ResourceResponse& response, unsigned long identifier, CompletionHandler<void(const ResourceResponse&, RefPtr<SharedBuffer>)>&& handler)
48
void InspectorInstrumentationWebKit::interceptResponseInternal(const Frame& frame, const ResourceResponse& response, unsigned long identifier, CompletionHandler<void(const ResourceResponse&, RefPtr<SharedBuffer>)>&& handler)
39
{
49
{
40
    InspectorInstrumentation::interceptResponse(frame, response, identifier, WTFMove(handler));
50
    InspectorInstrumentation::interceptResponse(frame, response, identifier, WTFMove(handler));
- a/Source/WebCore/inspector/InspectorInstrumentationWebKit.h +19 lines
Lines 36-49 class SharedBuffer; a/Source/WebCore/inspector/InspectorInstrumentationWebKit.h_sec1
36
36
37
class WEBCORE_EXPORT InspectorInstrumentationWebKit {
37
class WEBCORE_EXPORT InspectorInstrumentationWebKit {
38
public:
38
public:
39
    static bool shouldInterceptRequest(const Frame*, const ResourceRequest&);
39
    static bool shouldInterceptResponse(const Frame*, const ResourceResponse&);
40
    static bool shouldInterceptResponse(const Frame*, const ResourceResponse&);
41
    static void interceptRequest(ResourceLoader&, CompletionHandler<void(const ResourceRequest*)>&&);
40
    static void interceptResponse(const Frame*, const ResourceResponse&, unsigned long identifier, CompletionHandler<void(const ResourceResponse&, RefPtr<SharedBuffer>)>&&);
42
    static void interceptResponse(const Frame*, const ResourceResponse&, unsigned long identifier, CompletionHandler<void(const ResourceResponse&, RefPtr<SharedBuffer>)>&&);
41
43
42
private:
44
private:
45
    static bool shouldInterceptRequestInternal(const Frame&, const ResourceRequest&);
43
    static bool shouldInterceptResponseInternal(const Frame&, const ResourceResponse&);
46
    static bool shouldInterceptResponseInternal(const Frame&, const ResourceResponse&);
47
    static void interceptRequestInternal(ResourceLoader&, CompletionHandler<void(const ResourceRequest*)>&&);
44
    static void interceptResponseInternal(const Frame&, const ResourceResponse&, unsigned long identifier, CompletionHandler<void(const ResourceResponse&, RefPtr<SharedBuffer>)>&&);
48
    static void interceptResponseInternal(const Frame&, const ResourceResponse&, unsigned long identifier, CompletionHandler<void(const ResourceResponse&, RefPtr<SharedBuffer>)>&&);
45
};
49
};
46
50
51
inline 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
}
59
47
inline bool InspectorInstrumentationWebKit::shouldInterceptResponse(const Frame* frame, const ResourceResponse& response)
60
inline bool InspectorInstrumentationWebKit::shouldInterceptResponse(const Frame* frame, const ResourceResponse& response)
48
{
61
{
49
    FAST_RETURN_IF_NO_FRONTENDS(false);
62
    FAST_RETURN_IF_NO_FRONTENDS(false);
Lines 53-58 inline bool InspectorInstrumentationWebKit::shouldInterceptResponse(const Frame* a/Source/WebCore/inspector/InspectorInstrumentationWebKit.h_sec2
53
    return shouldInterceptResponseInternal(*frame, response);
66
    return shouldInterceptResponseInternal(*frame, response);
54
}
67
}
55
68
69
inline 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
56
inline void InspectorInstrumentationWebKit::interceptResponse(const Frame* frame, const ResourceResponse& response, unsigned long identifier, CompletionHandler<void(const ResourceResponse&, RefPtr<SharedBuffer>)>&& handler)
75
inline void InspectorInstrumentationWebKit::interceptResponse(const Frame* frame, const ResourceResponse& response, unsigned long identifier, CompletionHandler<void(const ResourceResponse&, RefPtr<SharedBuffer>)>&& handler)
57
{
76
{
58
    ASSERT(InspectorInstrumentationWebKit::shouldInterceptResponse(frame, response));
77
    ASSERT(InspectorInstrumentationWebKit::shouldInterceptResponse(frame, response));
- a/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp -36 / +209 lines
Lines 43-48 a/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp_sec1
43
#include "Document.h"
43
#include "Document.h"
44
#include "DocumentLoader.h"
44
#include "DocumentLoader.h"
45
#include "DocumentThreadableLoader.h"
45
#include "DocumentThreadableLoader.h"
46
#include "FormData.h"
46
#include "Frame.h"
47
#include "Frame.h"
47
#include "FrameLoader.h"
48
#include "FrameLoader.h"
48
#include "HTTPHeaderMap.h"
49
#include "HTTPHeaderMap.h"
Lines 841-852 void InspectorNetworkAgent::disable(ErrorString&) a/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp_sec2
841
    m_resourcesData->clear();
842
    m_resourcesData->clear();
842
    m_extraRequestHeaders.clear();
843
    m_extraRequestHeaders.clear();
843
844
845
    continuePendingRequests();
844
    continuePendingResponses();
846
    continuePendingResponses();
845
847
846
    setResourceCachingDisabled(false);
848
    setResourceCachingDisabled(false);
847
}
849
}
848
850
849
bool InspectorNetworkAgent::shouldIntercept(URL url)
851
bool InspectorNetworkAgent::shouldIntercept(URL url, NetworkStage networkStage)
850
{
852
{
851
    url.removeFragmentIdentifier();
853
    url.removeFragmentIdentifier();
852
854
Lines 855-860 bool InspectorNetworkAgent::shouldIntercept(URL url) a/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp_sec3
855
        return false;
857
        return false;
856
858
857
    for (auto& intercept : m_intercepts) {
859
    for (auto& intercept : m_intercepts) {
860
        if (intercept.networkStage != networkStage)
861
            continue;
862
        if (intercept.url.isEmpty())
863
            return true;
858
        auto searchStringType = intercept.isRegex ? ContentSearchUtilities::SearchStringType::Regex : ContentSearchUtilities::SearchStringType::ExactString;
864
        auto searchStringType = intercept.isRegex ? ContentSearchUtilities::SearchStringType::Regex : ContentSearchUtilities::SearchStringType::ExactString;
859
        auto regex = ContentSearchUtilities::createRegularExpressionForSearchString(intercept.url, intercept.caseSensitive, searchStringType);
865
        auto regex = ContentSearchUtilities::createRegularExpressionForSearchString(intercept.url, intercept.caseSensitive, searchStringType);
860
        if (regex.match(urlString) != -1)
866
        if (regex.match(urlString) != -1)
Lines 864-869 bool InspectorNetworkAgent::shouldIntercept(URL url) a/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp_sec4
864
    return false;
870
    return false;
865
}
871
}
866
872
873
void InspectorNetworkAgent::continuePendingRequests()
874
{
875
    for (auto& pendingRequest : m_pendingInterceptRequests.values()) {
876
        ResourceLoader* loader = pendingRequest->m_loader.get();
877
        if (loader->identifier())
878
            pendingRequest->m_completionHandler(&loader->request());
879
    }
880
    m_pendingInterceptRequests.clear();
881
}
882
867
void InspectorNetworkAgent::continuePendingResponses()
883
void InspectorNetworkAgent::continuePendingResponses()
868
{
884
{
869
    for (auto& pendingInterceptResponse : m_pendingInterceptResponses.values())
885
    for (auto& pendingInterceptResponse : m_pendingInterceptResponses.values())
Lines 1029-1090 void InspectorNetworkAgent::setInterceptionEnabled(ErrorString& errorString, boo a/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp_sec5
1029
1045
1030
    m_interceptionEnabled = enabled;
1046
    m_interceptionEnabled = enabled;
1031
1047
1032
    if (!m_interceptionEnabled)
1048
    if (!m_interceptionEnabled) {
1049
        continuePendingRequests();
1033
        continuePendingResponses();
1050
        continuePendingResponses();
1051
    }
1034
}
1052
}
1035
1053
1036
void InspectorNetworkAgent::addInterception(ErrorString& errorString, const String& url, const bool* optionalCaseSensitive, const bool* optionalIsRegex, const String* networkStageString)
1054
void InspectorNetworkAgent::addInterception(ErrorString& errorString, const String& url, const String& networkStageString, const bool* optionalCaseSensitive, const bool* optionalIsRegex)
1037
{
1055
{
1038
    if (networkStageString) {
1039
        auto networkStage = Inspector::Protocol::InspectorHelpers::parseEnumValueFromString<Inspector::Protocol::Network::NetworkStage>(*networkStageString);
1040
        if (!networkStage) {
1041
            errorString = makeString("Unknown networkStage: "_s, *networkStageString);
1042
            return;
1043
        }
1044
    }
1045
1046
    Intercept intercept;
1056
    Intercept intercept;
1047
    intercept.url = url;
1057
    intercept.url = url;
1048
    if (optionalCaseSensitive)
1058
    if (optionalCaseSensitive)
1049
        intercept.caseSensitive = *optionalCaseSensitive;
1059
        intercept.caseSensitive = *optionalCaseSensitive;
1050
    if (optionalIsRegex)
1060
    if (optionalIsRegex)
1051
        intercept.isRegex = *optionalIsRegex;
1061
        intercept.isRegex = *optionalIsRegex;
1052
1062
    auto networkStage = Inspector::Protocol::InspectorHelpers::parseEnumValueFromString<Inspector::Protocol::Network::NetworkStage>(networkStageString);
1053
    // FIXME: Support intercepting requests.
1063
    if (!networkStage) {
1064
        errorString = makeString("Unknown networkStage: "_s, networkStageString);
1065
        return;
1066
    }
1067
    intercept.networkStage = networkStage.value();
1054
1068
1055
    if (!m_intercepts.appendIfNotContains(intercept))
1069
    if (!m_intercepts.appendIfNotContains(intercept))
1056
        errorString = "Intercept for given url and given isRegex already exists"_s;
1070
        errorString = "Intercept for given url and given isRegex already exists"_s;
1057
}
1071
}
1058
1072
1059
void InspectorNetworkAgent::removeInterception(ErrorString& errorString, const String& url, const bool* optionalCaseSensitive, const bool* optionalIsRegex, const String* networkStageString)
1073
void InspectorNetworkAgent::removeInterception(ErrorString& errorString, const String& url, const String& networkStageString, const bool* optionalCaseSensitive, const bool* optionalIsRegex)
1060
{
1074
{
1061
    if (networkStageString) {
1062
        auto networkStage = Inspector::Protocol::InspectorHelpers::parseEnumValueFromString<Inspector::Protocol::Network::NetworkStage>(*networkStageString);
1063
        if (!networkStage) {
1064
            errorString = makeString("Unknown networkStage: "_s, *networkStageString);
1065
            return;
1066
        }
1067
    }
1068
1069
    Intercept intercept;
1075
    Intercept intercept;
1070
    intercept.url = url;
1076
    intercept.url = url;
1071
    if (optionalCaseSensitive)
1077
    if (optionalCaseSensitive)
1072
        intercept.caseSensitive = *optionalCaseSensitive;
1078
        intercept.caseSensitive = *optionalCaseSensitive;
1073
    if (optionalIsRegex)
1079
    if (optionalIsRegex)
1074
        intercept.isRegex = *optionalIsRegex;
1080
        intercept.isRegex = *optionalIsRegex;
1075
1081
    auto networkStage = Inspector::Protocol::InspectorHelpers::parseEnumValueFromString<Inspector::Protocol::Network::NetworkStage>(networkStageString);
1076
    // FIXME: Support intercepting requests.
1082
    if (!networkStage) {
1083
        errorString = makeString("Unknown networkStage: "_s, networkStageString);
1084
        return;
1085
    }
1086
    intercept.networkStage = networkStage.value();
1077
1087
1078
    if (!m_intercepts.removeAll(intercept))
1088
    if (!m_intercepts.removeAll(intercept))
1079
        errorString = "Missing intercept for given url and given isRegex"_s;
1089
        errorString = "Missing intercept for given url and given isRegex"_s;
1080
}
1090
}
1081
1091
1082
bool InspectorNetworkAgent::willInterceptRequest(const ResourceRequest& request)
1092
bool InspectorNetworkAgent::willIntercept(const ResourceRequest& request)
1093
{
1094
    if (!m_interceptionEnabled)
1095
        return false;
1096
1097
    return shouldIntercept(request.url(), NetworkStage::Request) || shouldIntercept(request.url(), NetworkStage::Response);
1098
}
1099
1100
bool InspectorNetworkAgent::shouldInterceptRequest(const ResourceRequest& request)
1083
{
1101
{
1084
    if (!m_interceptionEnabled)
1102
    if (!m_interceptionEnabled)
1085
        return false;
1103
        return false;
1086
1104
1087
    return shouldIntercept(request.url());
1105
    return shouldIntercept(request.url(), NetworkStage::Request);
1088
}
1106
}
1089
1107
1090
bool InspectorNetworkAgent::shouldInterceptResponse(const ResourceResponse& response)
1108
bool InspectorNetworkAgent::shouldInterceptResponse(const ResourceResponse& response)
Lines 1092-1098 bool InspectorNetworkAgent::shouldInterceptResponse(const ResourceResponse& resp a/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp_sec6
1092
    if (!m_interceptionEnabled)
1110
    if (!m_interceptionEnabled)
1093
        return false;
1111
        return false;
1094
1112
1095
    return shouldIntercept(response.url());
1113
    return shouldIntercept(response.url(), NetworkStage::Response);
1114
}
1115
1116
void InspectorNetworkAgent::interceptRequest(ResourceLoader& loader, CompletionHandler<void(const ResourceRequest*)>&& handler)
1117
{
1118
    ASSERT(m_enabled);
1119
    ASSERT(m_interceptionEnabled);
1120
1121
    String requestId = IdentifiersFactory::requestId(loader.identifier());
1122
    if (m_pendingInterceptRequests.contains(requestId)) {
1123
        handler(&loader.request());
1124
        return;
1125
    }
1126
    m_pendingInterceptRequests.set(requestId, makeUnique<PendingInterceptRequest>(&loader, WTFMove(handler)));
1127
    m_frontendDispatcher->requestIntercepted(requestId, buildObjectForResourceRequest(loader.request()));
1096
}
1128
}
1097
1129
1098
void InspectorNetworkAgent::interceptResponse(const ResourceResponse& response, unsigned long identifier, CompletionHandler<void(const ResourceResponse&, RefPtr<SharedBuffer>)>&& handler)
1130
void InspectorNetworkAgent::interceptResponse(const ResourceResponse& response, unsigned long identifier, CompletionHandler<void(const ResourceResponse&, RefPtr<SharedBuffer>)>&& handler)
Lines 1112-1129 void InspectorNetworkAgent::interceptResponse(const ResourceResponse& response, a/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp_sec7
1112
    m_frontendDispatcher->responseIntercepted(requestId, buildObjectForResourceResponse(response, nullptr));
1144
    m_frontendDispatcher->responseIntercepted(requestId, buildObjectForResourceResponse(response, nullptr));
1113
}
1145
}
1114
1146
1115
void InspectorNetworkAgent::interceptContinue(ErrorString& errorString, const String& requestId)
1147
void InspectorNetworkAgent::interceptContinue(ErrorString& errorString, const String& requestId, const String& networkStageString)
1116
{
1148
{
1149
    auto networkStage = Inspector::Protocol::InspectorHelpers::parseEnumValueFromString<Inspector::Protocol::Network::NetworkStage>(networkStageString);
1150
    if (!networkStage) {
1151
        errorString = makeString("Unknown networkStage: "_s, networkStageString);
1152
        return;
1153
    }
1154
1155
    if (networkStage.value() == NetworkStage::Request) {
1156
        auto pendingInterceptRequest = m_pendingInterceptRequests.take(requestId);
1157
        if (pendingInterceptRequest) {
1158
            pendingInterceptRequest->m_completionHandler(&pendingInterceptRequest->m_loader->request());
1159
            return;
1160
        }
1161
        errorString = "Missing pending intercept request for given requestId"_s;
1162
        return;
1163
    }
1164
1117
    auto pendingInterceptResponse = m_pendingInterceptResponses.take(requestId);
1165
    auto pendingInterceptResponse = m_pendingInterceptResponses.take(requestId);
1118
    if (!pendingInterceptResponse) {
1166
    if (pendingInterceptResponse) {
1119
        errorString = "Missing pending intercept response for given requestId"_s;
1167
        pendingInterceptResponse->respondWithOriginalResponse();
1168
        return;
1169
    }
1170
    errorString = "Missing pending intercept response for given requestId"_s;
1171
}
1172
1173
void InspectorNetworkAgent::interceptWithRequest(ErrorString& errorString, const String& requestId, const String* method, const String* url, const JSON::Object* headers, const String* postData)
1174
{
1175
    auto pendingRequest = m_pendingInterceptRequests.take(requestId);
1176
    if (pendingRequest) {
1177
        ResourceLoader* loader = pendingRequest->m_loader.get();
1178
        if (!loader->identifier()) {
1179
            // Do not throw upon continue of canceled requests.
1180
            return;
1181
        }
1182
        // Safe to const cast at this point, we are only adjusting the method / headers / post.
1183
        ResourceRequest request = loader->request();
1184
        if (url)
1185
            request.setURL(URL({ }, *url));
1186
        if (method)
1187
            request.setHTTPMethod(*method);
1188
        if (headers) {
1189
            HTTPHeaderMap explicitHeaders;
1190
            for (auto& [key, value] : *headers) {
1191
                String headerValue;
1192
                if (value->asString(headerValue))
1193
                    explicitHeaders.add(key, headerValue);
1194
            }
1195
            request.setHTTPHeaderFields(WTFMove(explicitHeaders));
1196
        }
1197
        if (postData) {
1198
            Vector<uint8_t> buffer;
1199
            if (!base64Decode(*postData, buffer)) {
1200
                errorString = "Unable to decode given postData"_s;
1201
                return;
1202
            }
1203
            request.setHTTPBody(FormData::create(buffer));
1204
        }
1205
        pendingRequest->m_completionHandler(&request);
1120
        return;
1206
        return;
1121
    }
1207
    }
1122
1208
1123
    pendingInterceptResponse->respondWithOriginalResponse();
1209
    errorString = "Missing pending intercept request for given requestId"_s;
1124
}
1210
}
1125
1211
1126
void InspectorNetworkAgent::interceptWithResponse(ErrorString& errorString, const String& requestId, const String& content, bool base64Encoded, const String* mimeType, const int* status, const String* statusText, const JSON::Object* headers)
1212
void InspectorNetworkAgent::interceptWithResponse(ErrorString& errorString, const String& requestId, const String* content, const bool* base64Encoded, const String* mimeType, const int* status, const String* statusText, const JSON::Object* headers)
1127
{
1213
{
1128
    auto pendingInterceptResponse = m_pendingInterceptResponses.take(requestId);
1214
    auto pendingInterceptResponse = m_pendingInterceptResponses.take(requestId);
1129
    if (!pendingInterceptResponse) {
1215
    if (!pendingInterceptResponse) {
Lines 1152-1171 void InspectorNetworkAgent::interceptWithResponse(ErrorString& errorString, cons a/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp_sec8
1152
    }
1238
    }
1153
1239
1154
    RefPtr<SharedBuffer> overrideData;
1240
    RefPtr<SharedBuffer> overrideData;
1155
    if (base64Encoded) {
1241
    if (base64Encoded && *base64Encoded && content) {
1156
        Vector<uint8_t> buffer;
1242
        Vector<uint8_t> buffer;
1157
        if (!base64Decode(content, buffer)) {
1243
        if (!base64Decode(*content, buffer)) {
1158
            errorString = "Unable to decode given content"_s;
1244
            errorString = "Unable to decode given content"_s;
1159
            pendingInterceptResponse->respondWithOriginalResponse();
1245
            pendingInterceptResponse->respondWithOriginalResponse();
1160
            return;
1246
            return;
1161
        }
1247
        }
1162
        overrideData = SharedBuffer::create(WTFMove(buffer));
1248
        overrideData = SharedBuffer::create(WTFMove(buffer));
1163
    } else
1249
    } else if (content)
1164
        overrideData = SharedBuffer::create(content.utf8().data(), content.utf8().length());
1250
        overrideData = SharedBuffer::create(content->utf8().data(), content->utf8().length());
1165
1251
1166
    pendingInterceptResponse->respond(overrideResponse, overrideData);
1252
    pendingInterceptResponse->respond(overrideResponse, overrideData);
1167
}
1253
}
1168
1254
1255
void InspectorNetworkAgent::interceptRequestWithResponse(ErrorString& errorString, const String& requestId, const String& content, const bool* base64Encoded, const String& mimeType, int status, const String& statusText, const JSON::Object& headers)
1256
{
1257
    auto pendingRequest = m_pendingInterceptRequests.take(requestId);
1258
    if (!pendingRequest) {
1259
        errorString = "Missing pending intercept response for given requestId"_s;
1260
        return;
1261
    }
1262
1263
    RefPtr<ResourceLoader> loader = pendingRequest->m_loader.get();
1264
    if (!loader->identifier()) {
1265
        errorString = "Unable to fulfill request, it has already been processed"_s;
1266
        return;
1267
    }
1268
    RefPtr<SharedBuffer> data;
1269
    if (base64Encoded && *base64Encoded) {
1270
        Vector<uint8_t> buffer;
1271
        if (!base64Decode(content, buffer)) {
1272
            errorString = "Unable to decode given content"_s;
1273
            return;
1274
        }
1275
        data = SharedBuffer::create(WTFMove(buffer));
1276
    } else
1277
        data = SharedBuffer::create(content.utf8().data(), content.utf8().length());
1278
1279
    // Mimic data URL load behavior - report didReceiveResponse & didFinishLoading.
1280
    ResourceResponse response(pendingRequest->m_loader->url(), mimeType, data->size(), String());
1281
    response.setSource(ResourceResponse::Source::InspectorOverride);
1282
    response.setHTTPStatusCode(status);
1283
    response.setHTTPStatusText(statusText);
1284
    HTTPHeaderMap explicitHeaders;
1285
    for (auto& header : headers) {
1286
        String headerValue;
1287
        if (header.value->asString(headerValue))
1288
            explicitHeaders.add(header.key, headerValue);
1289
    }
1290
    response.setHTTPHeaderFields(WTFMove(explicitHeaders));
1291
    response.setHTTPHeaderField(HTTPHeaderName::ContentType, response.mimeType());
1292
    loader->didReceiveResponse(response, [loader, buffer = data.releaseNonNull()]() mutable {
1293
        if (buffer->size())
1294
            loader->didReceiveBuffer(WTFMove(buffer), buffer->size(), DataPayloadWholeResource);
1295
        loader->didFinishLoading(NetworkLoadMetrics());
1296
    });
1297
    pendingRequest->m_completionHandler(nullptr);
1298
}
1299
1300
void 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 response for given requestId"_s;
1305
        return;
1306
    }
1307
1308
    ResourceLoader* loader = pendingRequest->m_loader.get();
1309
    if (!loader->identifier()) {
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 = "Unknown error type"_s;
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
    default:
1335
        ASSERT_NOT_REACHED();
1336
        return;
1337
    }
1338
    loader->didFail(error);
1339
    pendingRequest->m_completionHandler(nullptr);
1340
}
1341
1169
bool InspectorNetworkAgent::shouldTreatAsText(const String& mimeType)
1342
bool InspectorNetworkAgent::shouldTreatAsText(const String& mimeType)
1170
{
1343
{
1171
    return startsWithLettersIgnoringASCIICase(mimeType, "text/")
1344
    return startsWithLettersIgnoringASCIICase(mimeType, "text/")
- a/Source/WebCore/inspector/agents/InspectorNetworkAgent.h -7 / +31 lines
Lines 88-97 public: a/Source/WebCore/inspector/agents/InspectorNetworkAgent.h_sec1
88
    void getSerializedCertificate(ErrorString&, const String& requestId, String* serializedCertificate) final;
88
    void getSerializedCertificate(ErrorString&, const String& requestId, String* serializedCertificate) final;
89
    void resolveWebSocket(ErrorString&, const String& requestId, const String* objectGroup, RefPtr<Inspector::Protocol::Runtime::RemoteObject>&) final;
89
    void resolveWebSocket(ErrorString&, const String& requestId, const String* objectGroup, RefPtr<Inspector::Protocol::Runtime::RemoteObject>&) final;
90
    void setInterceptionEnabled(ErrorString&, bool enabled) final;
90
    void setInterceptionEnabled(ErrorString&, bool enabled) final;
91
    void addInterception(ErrorString&, const String& url, const bool* caseSensitive, const bool* isRegex, const String* networkStageString) 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 bool* caseSensitive, const bool* isRegex, const String* networkStageString) 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) final;
93
    void interceptContinue(ErrorString&, const String& requestId, const String& networkStageString) final;
94
    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;
94
    void interceptWithRequest(ErrorString&, const String& requestId, const String* method, const String* url, const JSON::Object* headers, const String* postData) final;
95
    void interceptWithResponse(ErrorString&, const String& requestId, const String* content, const 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, const 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;
95
98
96
    // InspectorInstrumentation
99
    // InspectorInstrumentation
97
    void willRecalculateStyle();
100
    void willRecalculateStyle();
Lines 118-126 public: a/Source/WebCore/inspector/agents/InspectorNetworkAgent.h_sec2
118
    void mainFrameNavigated(DocumentLoader&);
121
    void mainFrameNavigated(DocumentLoader&);
119
    void setInitialScriptContent(unsigned long identifier, const String& sourceString);
122
    void setInitialScriptContent(unsigned long identifier, const String& sourceString);
120
    void didScheduleStyleRecalculation(Document&);
123
    void didScheduleStyleRecalculation(Document&);
121
    bool willInterceptRequest(const ResourceRequest&);
124
    bool willIntercept(const ResourceRequest&);
125
    bool shouldInterceptRequest(const ResourceRequest&);
122
    bool shouldInterceptResponse(const ResourceResponse&);
126
    bool shouldInterceptResponse(const ResourceResponse&);
123
    void interceptResponse(const ResourceResponse&, unsigned long identifier, CompletionHandler<void(const ResourceResponse&, RefPtr<SharedBuffer>)>&&);
127
    void interceptResponse(const ResourceResponse&, unsigned long identifier, CompletionHandler<void(const ResourceResponse&, RefPtr<SharedBuffer>)>&&);
128
    void interceptRequest(ResourceLoader&, CompletionHandler<void(const ResourceRequest*)>&&);
124
129
125
    void searchOtherRequests(const JSC::Yarr::RegularExpression&, RefPtr<JSON::ArrayOf<Inspector::Protocol::Page::SearchResult>>&);
130
    void searchOtherRequests(const JSC::Yarr::RegularExpression&, RefPtr<JSON::ArrayOf<Inspector::Protocol::Page::SearchResult>>&);
126
    void searchInRequest(ErrorString&, const String& requestId, const String& query, bool caseSensitive, bool isRegex, RefPtr<JSON::ArrayOf<Inspector::Protocol::GenericTypes::SearchMatch>>&);
131
    void searchInRequest(ErrorString&, const String& requestId, const String& query, bool caseSensitive, bool isRegex, RefPtr<JSON::ArrayOf<Inspector::Protocol::GenericTypes::SearchMatch>>&);
Lines 140-146 private: a/Source/WebCore/inspector/agents/InspectorNetworkAgent.h_sec3
140
145
141
    void willSendRequest(unsigned long identifier, DocumentLoader*, ResourceRequest&, const ResourceResponse& redirectResponse, InspectorPageAgent::ResourceType);
146
    void willSendRequest(unsigned long identifier, DocumentLoader*, ResourceRequest&, const ResourceResponse& redirectResponse, InspectorPageAgent::ResourceType);
142
147
143
    bool shouldIntercept(URL);
148
    using NetworkStage = Inspector::Protocol::Network::NetworkStage;
149
    bool shouldIntercept(URL, NetworkStage);
150
    void continuePendingRequests();
144
    void continuePendingResponses();
151
    void continuePendingResponses();
145
152
146
    WebSocket* webSocketForRequestId(const String& requestId);
153
    WebSocket* webSocketForRequestId(const String& requestId);
Lines 153-158 private: a/Source/WebCore/inspector/agents/InspectorNetworkAgent.h_sec4
153
160
154
    double timestamp();
161
    double timestamp();
155
162
163
    class PendingInterceptRequest {
164
        WTF_MAKE_NONCOPYABLE(PendingInterceptRequest);
165
        WTF_MAKE_FAST_ALLOCATED;
166
    public:
167
        PendingInterceptRequest(ResourceLoader* loader, CompletionHandler<void(const ResourceRequest*)>&& completionHandler)
168
            : m_loader(loader)
169
            , m_completionHandler(WTFMove(completionHandler))
170
        { }
171
172
        PendingInterceptRequest() = default;
173
        RefPtr<ResourceLoader> m_loader;
174
        CompletionHandler<void(const ResourceRequest*)> m_completionHandler;
175
    };
176
156
    class PendingInterceptResponse {
177
    class PendingInterceptResponse {
157
        WTF_MAKE_NONCOPYABLE(PendingInterceptResponse);
178
        WTF_MAKE_NONCOPYABLE(PendingInterceptResponse);
158
        WTF_MAKE_FAST_ALLOCATED;
179
        WTF_MAKE_FAST_ALLOCATED;
Lines 204-218 private: a/Source/WebCore/inspector/agents/InspectorNetworkAgent.h_sec5
204
        String url;
225
        String url;
205
        bool caseSensitive { true };
226
        bool caseSensitive { true };
206
        bool isRegex { false };
227
        bool isRegex { false };
228
        NetworkStage networkStage { NetworkStage::Response };
207
229
208
        inline bool operator==(const Intercept& other) const
230
        inline bool operator==(const Intercept& other) const
209
        {
231
        {
210
            return url == other.url
232
            return url == other.url
211
                && caseSensitive == other.caseSensitive
233
                && caseSensitive == other.caseSensitive
212
                && isRegex == other.isRegex;
234
                && isRegex == other.isRegex
235
                && networkStage == other.networkStage;
213
        }
236
        }
214
    };
237
    };
215
    Vector<Intercept> m_intercepts;
238
    Vector<Intercept> m_intercepts;
239
    HashMap<String, std::unique_ptr<PendingInterceptRequest>> m_pendingInterceptRequests;
216
    HashMap<String, std::unique_ptr<PendingInterceptResponse>> m_pendingInterceptResponses;
240
    HashMap<String, std::unique_ptr<PendingInterceptResponse>> m_pendingInterceptResponses;
217
241
218
    // FIXME: InspectorNetworkAgent should not be aware of style recalculation.
242
    // FIXME: InspectorNetworkAgent should not be aware of style recalculation.
- a/Source/WebCore/loader/cache/CachedResourceLoader.cpp -2 / +2 lines
Lines 846-852 ResourceErrorOr<CachedResourceHandle<CachedResource>> CachedResourceLoader::requ a/Source/WebCore/loader/cache/CachedResourceLoader.cpp_sec1
846
846
847
    request.updateReferrerPolicy(document() ? document()->referrerPolicy() : ReferrerPolicy::NoReferrerWhenDowngrade);
847
    request.updateReferrerPolicy(document() ? document()->referrerPolicy() : ReferrerPolicy::NoReferrerWhenDowngrade);
848
848
849
    if (InspectorInstrumentation::willInterceptRequest(&frame, request.resourceRequest()))
849
    if (InspectorInstrumentation::willIntercept(&frame, request.resourceRequest()))
850
        request.setCachingPolicy(CachingPolicy::DisallowCaching);
850
        request.setCachingPolicy(CachingPolicy::DisallowCaching);
851
851
852
    auto& page = *frame.page();
852
    auto& page = *frame.page();
Lines 1436-1442 Vector<Ref<SVGImage>> CachedResourceLoader::allCachedSVGImages() const a/Source/WebCore/loader/cache/CachedResourceLoader.cpp_sec2
1436
1436
1437
ResourceErrorOr<CachedResourceHandle<CachedResource>> CachedResourceLoader::preload(CachedResource::Type type, CachedResourceRequest&& request)
1437
ResourceErrorOr<CachedResourceHandle<CachedResource>> CachedResourceLoader::preload(CachedResource::Type type, CachedResourceRequest&& request)
1438
{
1438
{
1439
    if (InspectorInstrumentation::willInterceptRequest(frame(), request.resourceRequest()))
1439
    if (InspectorInstrumentation::willIntercept(frame(), request.resourceRequest()))
1440
        return makeUnexpected(ResourceError { errorDomainWebKitInternal, 0, request.resourceRequest().url(), "Inspector intercept"_s });
1440
        return makeUnexpected(ResourceError { errorDomainWebKitInternal, 0, request.resourceRequest().url(), "Inspector intercept"_s });
1441
1441
1442
    if (request.charset().isEmpty() && (type == CachedResource::Type::Script || type == CachedResource::Type::CSSStyleSheet))
1442
    if (request.charset().isEmpty() && (type == CachedResource::Type::Script || type == CachedResource::Type::CSSStyleSheet))
- a/Source/WebInspectorUI/UserInterface/Controllers/NetworkManager.js -5 / +11 lines
Lines 161-167 WI.NetworkManager = class NetworkManager extends WI.Object a/Source/WebInspectorUI/UserInterface/Controllers/NetworkManager.js_sec1
161
                            url: localResourceOverride.url,
161
                            url: localResourceOverride.url,
162
                            caseSensitive: localResourceOverride.isCaseSensitive,
162
                            caseSensitive: localResourceOverride.isCaseSensitive,
163
                            isRegex: localResourceOverride.isRegex,
163
                            isRegex: localResourceOverride.isRegex,
164
                            networkStage: InspectorBackend.Enum.Network.NetworkStage.Response,
164
                            stage: InspectorBackend.Enum.Network.NetworkStage.Response,
165
                        });
165
                        });
166
                    }
166
                    }
167
                }
167
                }
Lines 364-370 WI.NetworkManager = class NetworkManager extends WI.Object a/Source/WebInspectorUI/UserInterface/Controllers/NetworkManager.js_sec2
364
                url: localResourceOverride.url,
364
                url: localResourceOverride.url,
365
                caseSensitive: localResourceOverride.isCaseSensitive,
365
                caseSensitive: localResourceOverride.isCaseSensitive,
366
                isRegex: localResourceOverride.isRegex,
366
                isRegex: localResourceOverride.isRegex,
367
                networkStage: InspectorBackend.Enum.Network.NetworkStage.Response,
367
                stage: InspectorBackend.Enum.Network.NetworkStage.Response,
368
            };
368
            };
369
369
370
            // COMPATIBILITY (iOS 13.0): Network.addInterception did not exist.
370
            // COMPATIBILITY (iOS 13.0): Network.addInterception did not exist.
Lines 397-403 WI.NetworkManager = class NetworkManager extends WI.Object a/Source/WebInspectorUI/UserInterface/Controllers/NetworkManager.js_sec3
397
                url: localResourceOverride.url,
397
                url: localResourceOverride.url,
398
                caseSensitive: localResourceOverride.isCaseSensitive,
398
                caseSensitive: localResourceOverride.isCaseSensitive,
399
                isRegex: localResourceOverride.isRegex,
399
                isRegex: localResourceOverride.isRegex,
400
                networkStage: InspectorBackend.Enum.Network.NetworkStage.Response,
400
                stage: InspectorBackend.Enum.Network.NetworkStage.Response,
401
            };
401
            };
402
402
403
            // COMPATIBILITY (iOS 13.0): Network.removeInterception did not exist.
403
            // COMPATIBILITY (iOS 13.0): Network.removeInterception did not exist.
Lines 906-917 WI.NetworkManager = class NetworkManager extends WI.Object a/Source/WebInspectorUI/UserInterface/Controllers/NetworkManager.js_sec4
906
        this._resourceRequestIdentifierMap.delete(requestIdentifier);
906
        this._resourceRequestIdentifierMap.delete(requestIdentifier);
907
    }
907
    }
908
908
909
    requestIntercepted(target, requestId, request)
910
    {
911
        this.dispatchEventToListeners(WI.NetworkManager.Event.RequestIntercepted, {target, requestId, request});
912
    }
913
909
    responseIntercepted(target, requestId, response)
914
    responseIntercepted(target, requestId, response)
910
    {
915
    {
911
        let url = WI.urlWithoutFragment(response.url);
916
        let url = WI.urlWithoutFragment(response.url);
912
        let localResourceOverride = this.localResourceOverrideForURL(url);
917
        let localResourceOverride = this.localResourceOverrideForURL(url);
913
        if (!localResourceOverride || localResourceOverride.disabled) {
918
        if (!localResourceOverride || localResourceOverride.disabled) {
914
            target.NetworkAgent.interceptContinue(requestId);
919
            target.NetworkAgent.interceptContinue(requestId, InspectorBackend.Enum.Network.NetworkStage.Response);
915
            return;
920
            return;
916
        }
921
        }
917
922
Lines 1377-1383 WI.NetworkManager = class NetworkManager extends WI.Object a/Source/WebInspectorUI/UserInterface/Controllers/NetworkManager.js_sec5
1377
            url: localResourceOverride.url,
1382
            url: localResourceOverride.url,
1378
            caseSensitive: localResourceOverride.isCaseSensitive,
1383
            caseSensitive: localResourceOverride.isCaseSensitive,
1379
            isRegex: localResourceOverride.isRegex,
1384
            isRegex: localResourceOverride.isRegex,
1380
            networkStage: InspectorBackend.Enum.Network.NetworkStage.Response,
1385
            stage: InspectorBackend.Enum.Network.NetworkStage.Response,
1381
        };
1386
        };
1382
1387
1383
        // COMPATIBILITY (iOS 13.0): Network.addInterception / Network.removeInterception did not exist.
1388
        // COMPATIBILITY (iOS 13.0): Network.addInterception / Network.removeInterception did not exist.
Lines 1433-1436 WI.NetworkManager.Event = { a/Source/WebInspectorUI/UserInterface/Controllers/NetworkManager.js_sec6
1433
    BootstrapScriptDestroyed: "network-manager-bootstrap-script-destroyed",
1438
    BootstrapScriptDestroyed: "network-manager-bootstrap-script-destroyed",
1434
    LocalResourceOverrideAdded: "network-manager-local-resource-override-added",
1439
    LocalResourceOverrideAdded: "network-manager-local-resource-override-added",
1435
    LocalResourceOverrideRemoved: "network-manager-local-resource-override-removed",
1440
    LocalResourceOverrideRemoved: "network-manager-local-resource-override-removed",
1441
    RequestIntercepted: "network-manager-request-intercepted"
1436
};
1442
};
- a/Source/WebInspectorUI/UserInterface/Protocol/NetworkObserver.js +5 lines
Lines 108-113 WI.NetworkObserver = class NetworkObserver extends InspectorBackend.Dispatcher a/Source/WebInspectorUI/UserInterface/Protocol/NetworkObserver.js_sec1
108
        // FIXME: Not implemented.
108
        // FIXME: Not implemented.
109
    }
109
    }
110
110
111
    requestIntercepted(requestId, request)
112
    {
113
        WI.networkManager.requestIntercepted(this._target, requestId, request);
114
    }
115
111
    responseIntercepted(requestId, response)
116
    responseIntercepted(requestId, response)
112
    {
117
    {
113
        WI.networkManager.responseIntercepted(this._target, requestId, response);
118
        WI.networkManager.responseIntercepted(this._target, requestId, response);
- a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp -2 / +12 lines
Lines 58-63 a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp_sec1
58
#include <WebCore/Frame.h>
58
#include <WebCore/Frame.h>
59
#include <WebCore/FrameLoader.h>
59
#include <WebCore/FrameLoader.h>
60
#include <WebCore/HTMLFrameOwnerElement.h>
60
#include <WebCore/HTMLFrameOwnerElement.h>
61
#include <WebCore/InspectorInstrumentationWebKit.h>
61
#include <WebCore/NetscapePlugInStreamLoader.h>
62
#include <WebCore/NetscapePlugInStreamLoader.h>
62
#include <WebCore/NetworkLoadInformation.h>
63
#include <WebCore/NetworkLoadInformation.h>
63
#include <WebCore/PlatformStrategies.h>
64
#include <WebCore/PlatformStrategies.h>
Lines 230-237 void WebLoaderStrategy::scheduleLoad(ResourceLoader& resourceLoader, CachedResou a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp_sec2
230
231
231
    if (!tryLoadingUsingURLSchemeHandler(resourceLoader, trackingParameters)) {
232
    if (!tryLoadingUsingURLSchemeHandler(resourceLoader, trackingParameters)) {
232
        WEBLOADERSTRATEGY_RELEASE_LOG_IF_ALLOWED("scheduleLoad: URL will be scheduled with the NetworkProcess");
233
        WEBLOADERSTRATEGY_RELEASE_LOG_IF_ALLOWED("scheduleLoad: URL will be scheduled with the NetworkProcess");
233
        scheduleLoadFromNetworkProcess(resourceLoader, resourceLoader.request(), trackingParameters, shouldClearReferrerOnHTTPSToHTTPRedirect, maximumBufferingTime(resource));
234
234
        return;
235
        if (resourceLoader.options().serviceWorkerRegistrationIdentifier || !InspectorInstrumentationWebKit::shouldInterceptRequest(resourceLoader.frame(), resourceLoader.request())) {
236
            scheduleLoadFromNetworkProcess(resourceLoader, resourceLoader.request(), trackingParameters, shouldClearReferrerOnHTTPSToHTTPRedirect, maximumBufferingTime(resource));
237
            return;
238
        }
239
240
        InspectorInstrumentationWebKit::interceptRequest(resourceLoader, [this, protectedResourceLoader = makeRefPtr(&resourceLoader), trackingParameters, shouldClearReferrerOnHTTPSToHTTPRedirect, resource](const ResourceRequest* request) mutable {
241
            if (request)
242
                scheduleLoadFromNetworkProcess(*protectedResourceLoader, *request, trackingParameters, shouldClearReferrerOnHTTPSToHTTPRedirect, maximumBufferingTime(resource));
243
            return;
244
        });
235
    }
245
    }
236
246
237
    WEBLOADERSTRATEGY_RELEASE_LOG_IF_ALLOWED("scheduleLoad: URL not handled by any handlers");
247
    WEBLOADERSTRATEGY_RELEASE_LOG_IF_ALLOWED("scheduleLoad: URL not handled by any handlers");
- a/LayoutTests/ChangeLog +33 lines
Lines 1-3 a/LayoutTests/ChangeLog_sec1
1
2020-05-28  Pavel  <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 NOBODY (OOPS!).
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-request-main-resource-expected.txt: Added.
14
        * http/tests/inspector/network/intercept-request-main-resource-with-response-expected.txt: Added.
15
        * http/tests/inspector/network/intercept-request-main-resource-with-response.html: Added.
16
        * http/tests/inspector/network/intercept-request-main-resource.html: Added.
17
        * http/tests/inspector/network/intercept-request-properties-expected.txt: Added.
18
        * http/tests/inspector/network/intercept-request-properties.html: Added.
19
        * http/tests/inspector/network/intercept-request-subresource-expected.txt: Added.
20
        * http/tests/inspector/network/intercept-request-subresource-with-error-expected.txt: Added.
21
        * http/tests/inspector/network/intercept-request-subresource-with-error.html: Added.
22
        * http/tests/inspector/network/intercept-request-subresource-with-response-expected.txt: Added.
23
        * http/tests/inspector/network/intercept-request-subresource-with-response.html: Added.
24
        * http/tests/inspector/network/intercept-request-subresource.html: Added.
25
        * http/tests/inspector/network/resources/intercept-echo.php: Added.
26
        * http/tests/inspector/network/resources/intercept-request-overriden-page.html: Added.
27
        * http/tests/inspector/network/resources/intercept-request-overriden-script.js: Added.
28
        * http/tests/inspector/resources/protocol-test.js:
29
        * inspector/network/intercept-request-expected.txt: Added.
30
        * inspector/network/intercept-request.html: Added.
31
        * inspector/network/local-resource-override-continue-response.html:
32
        * inspector/network/resources/data2.json: Added.
33
1
2020-05-12  Fujii Hironori  <Hironori.Fujii@sony.com>
34
2020-05-12  Fujii Hironori  <Hironori.Fujii@sony.com>
2
35
3
        [WinCairo][WK1] requestAnimationFrame doesn't work since r244182 in Accelerated Compositing mode
36
        [WinCairo][WK1] requestAnimationFrame doesn't work since r244182 in Accelerated Compositing mode
- a/LayoutTests/http/tests/inspector/network/intercept-request-main-resource-expected.txt +3 lines
Line 0 a/LayoutTests/http/tests/inspector/network/intercept-request-main-resource-expected.txt_sec1
1
ALERT: ORIGINAL HTML CONTENT
2
ALERT: REPLACED HTML CONTENT
3
Overridden page content
- a/LayoutTests/http/tests/inspector/network/intercept-request-main-resource-with-response-expected.txt +3 lines
Line 0 a/LayoutTests/http/tests/inspector/network/intercept-request-main-resource-with-response-expected.txt_sec1
1
ALERT: ORIGINAL HTML CONTENT
2
ALERT: REPLACED HTML CONTENT
3
Overridden page content
- a/LayoutTests/http/tests/inspector/network/intercept-request-main-resource-with-response.html +46 lines
Line 0 a/LayoutTests/http/tests/inspector/network/intercept-request-main-resource-with-response.html_sec1
1
<!DOCTYPE html>
2
<html>
3
<head>
4
<meta charset="utf-8">
5
<script src="../resources/inspector-test.js"></script>
6
<script>
7
function test()
8
{
9
    let suite = InspectorTest.createAsyncSuite("Network.interceptRequest");
10
11
    suite.addTestCase({
12
        name: "Network.interceptRequest.MainResource with response",
13
        description: "Main resource uses request interception on next page load and fulfills request",
14
        async test() {
15
            let target = WI.assumingMainTarget();
16
            await target.NetworkAgent.addInterception.invoke({
17
                url: "http://127.0.0.1:8000/inspector/network/intercept-request-main-resource-with-response.html",
18
                stage: InspectorBackend.Enum.Network.NetworkStage.Request,
19
            });
20
21
            let interceptWithResponse = (event) => {
22
                let {target, requestId, request} = event.data;
23
                target.NetworkAgent.interceptRequestWithResponse.invoke({
24
                    requestId,
25
                    mimeType: "text/html",
26
                    content: `<!DOCTYPE html><html><head><script src="../resources/inspector-test.js"></`+`script></head><body><p>Overridden page content</p><script>alert("REPLACED HTML CONTENT"); TestPage.completeTest();</`+`script></body></html>`,
27
                    status: 200,
28
                    statusText: "OK",
29
                    headers: {},
30
                });
31
            };
32
            WI.networkManager.addEventListener(WI.NetworkManager.Event.RequestIntercepted, interceptWithResponse);
33
34
            InspectorTest.reloadPage({ignoreCache: false, revalidateAllResources: true});
35
        }
36
    });
37
38
    suite.runTestCasesAndFinish();
39
}
40
</script>
41
</head>
42
<body onload="runTest()">
43
<p>Test request interception intercepting the main resource load with response.</p>
44
<script>alert("ORIGINAL HTML CONTENT");</script>
45
</body>
46
</html>
- a/LayoutTests/http/tests/inspector/network/intercept-request-main-resource.html +42 lines
Line 0 a/LayoutTests/http/tests/inspector/network/intercept-request-main-resource.html_sec1
1
<!DOCTYPE html>
2
<html>
3
<head>
4
<meta charset="utf-8">
5
<script src="../resources/inspector-test.js"></script>
6
<script>
7
function test()
8
{
9
    let suite = InspectorTest.createAsyncSuite("Network.interceptRequest");
10
11
    suite.addTestCase({
12
        name: "Network.interceptRequest.MainResource",
13
        description: "Main resource uses request interception on next page load",
14
        async test() {
15
            let target = WI.assumingMainTarget();
16
            await target.NetworkAgent.addInterception.invoke({
17
                url: "http://127.0.0.1:8000/inspector/network/intercept-request-main-resource.html",
18
                stage: InspectorBackend.Enum.Network.NetworkStage.Request,
19
            });
20
21
            let interceptWithRequest = (event) => {
22
                let {target, requestId, request} = event.data;
23
                target.NetworkAgent.interceptWithRequest.invoke({
24
                    url: "http://127.0.0.1:8000/inspector/network/resources/intercept-request-overriden-page.html",
25
                    requestId
26
                });
27
            };
28
            WI.networkManager.addEventListener(WI.NetworkManager.Event.RequestIntercepted, interceptWithRequest);
29
30
            InspectorTest.reloadPage({ignoreCache: false, revalidateAllResources: true});
31
        }
32
    });
33
34
    suite.runTestCasesAndFinish();
35
}
36
</script>
37
</head>
38
<body onload="runTest()">
39
<p>Test request interception intercepting the main resource load.</p>
40
<script>alert("ORIGINAL HTML CONTENT");</script>
41
</body>
42
</html>
- a/LayoutTests/http/tests/inspector/network/intercept-request-properties-expected.txt +13 lines
Line 0 a/LayoutTests/http/tests/inspector/network/intercept-request-properties-expected.txt_sec1
1
Test request interception altering request properties.
2
3
4
== Running test suite: Network.interceptRequest
5
-- Running test case: Network.interceptRequest.Method
6
Method=POST
7
8
-- Running test case: Network.interceptRequest.Headers
9
Overriden header:overriden
10
11
-- Running test case: Network.interceptRequest.PostData
12
Overriden value: overriden
13
- a/LayoutTests/http/tests/inspector/network/intercept-request-properties.html +121 lines
Line 0 a/LayoutTests/http/tests/inspector/network/intercept-request-properties.html_sec1
1
<!DOCTYPE html>
2
<html>
3
<head>
4
<meta charset="utf-8">
5
<script src="../resources/inspector-test.js"></script>
6
<script>
7
async function fetchData(url)
8
{
9
    let response = await fetch(url);
10
    return await response.text();
11
}
12
13
async function postData(url)
14
{
15
    let response = await fetch(url, {
16
        method: "POST",
17
        headers: {
18
            "Content-Type": "application/x-www-form-urlencoded"
19
        },
20
        body: "value=original"
21
    });
22
    return await response.text();
23
}
24
25
function test()
26
{
27
    let suite = InspectorTest.createAsyncSuite("Network.interceptRequest");
28
29
    suite.addTestCase({
30
        name: "Network.interceptRequest.Method",
31
        description: "Tests request method interception",
32
        async test() {
33
            let target = WI.assumingMainTarget();
34
            await target.NetworkAgent.addInterception.invoke({
35
                url: "http://127.0.0.1:8000/inspector/network/resources/intercept-echo.php?method",
36
                stage: InspectorBackend.Enum.Network.NetworkStage.Request,
37
            });
38
39
            let interceptWithRequest = (event) => {
40
                let {target, requestId, request} = event.data;
41
                if (!request.url.includes('?method'))
42
                    return;
43
                target.NetworkAgent.interceptWithRequest.invoke({
44
                    requestId,
45
                    method: "POST",
46
                });
47
            };
48
            WI.networkManager.addEventListener(WI.NetworkManager.Event.RequestIntercepted, interceptWithRequest);
49
50
            let response = await target.RuntimeAgent.evaluate("fetchData('resources/intercept-echo.php?method')");
51
            response = await target.RuntimeAgent.awaitPromise(response.result.objectId, true);
52
            let data = eval('(' + response.result.value + ')');
53
            InspectorTest.log("Method=" + data.method);
54
        }
55
    });
56
57
    suite.addTestCase({
58
        name: "Network.interceptRequest.Headers",
59
        description: "Tests request headers interception",
60
        async test() {
61
            let target = WI.assumingMainTarget();
62
            await target.NetworkAgent.addInterception.invoke({
63
                url: "http://127.0.0.1:8000/inspector/network/resources/intercept-echo.php?headers",
64
                stage: InspectorBackend.Enum.Network.NetworkStage.Request,
65
            });
66
67
            let interceptWithRequest = (event) => {
68
                let {target, requestId, request} = event.data;
69
                if (!request.url.includes('?headers'))
70
                    return;
71
                target.NetworkAgent.interceptWithRequest.invoke({
72
                    requestId,
73
                    headers: { "value": "overriden" },
74
                });
75
            };
76
            WI.networkManager.addEventListener(WI.NetworkManager.Event.RequestIntercepted, interceptWithRequest);
77
78
            let response = await target.RuntimeAgent.evaluate("fetchData('resources/intercept-echo.php?headers')");
79
            response = await target.RuntimeAgent.awaitPromise(response.result.objectId, true);
80
            let data = eval('(' + response.result.value + ')');
81
            InspectorTest.log("Overriden header:" + data.headers.value);
82
        }
83
    });
84
85
    suite.addTestCase({
86
        name: "Network.interceptRequest.PostData",
87
        description: "Tests request post data interception",
88
        async test() {
89
            let target = WI.assumingMainTarget();
90
            await target.NetworkAgent.addInterception.invoke({
91
                url: "http://127.0.0.1:8000/inspector/network/resources/intercept-echo.php?postData",
92
                stage: InspectorBackend.Enum.Network.NetworkStage.Request,
93
            });
94
95
            let interceptWithRequest = (event) => {
96
                let {target, requestId, request} = event.data;
97
                if (!request.url.includes('?postData'))
98
                    return;
99
                target.NetworkAgent.interceptWithRequest.invoke({
100
                    requestId,
101
                    method: "POST",
102
                    postData: btoa("value=overriden"),
103
                });
104
            };
105
            WI.networkManager.addEventListener(WI.NetworkManager.Event.RequestIntercepted, interceptWithRequest);
106
107
            let response = await target.RuntimeAgent.evaluate("postData('resources/intercept-echo.php?postData')");
108
            response = await target.RuntimeAgent.awaitPromise(response.result.objectId, true);
109
            let data = eval('(' + response.result.value + ')');
110
            InspectorTest.log("Overriden value: " + data.post.value);
111
        }
112
    });
113
114
    suite.runTestCasesAndFinish();
115
}
116
</script>
117
</head>
118
<body onload="runTest()">
119
<p>Test request interception altering request properties.</p>
120
</body>
121
</html>
- a/LayoutTests/http/tests/inspector/network/intercept-request-subresource-expected.txt +8 lines
Line 0 a/LayoutTests/http/tests/inspector/network/intercept-request-subresource-expected.txt_sec1
1
ALERT: DEFAULT override.js TEXT
2
ALERT: OVERRIDEN override.js TEXT
3
Test request interception intercepting the subresource load.
4
5
6
== Running test suite: Network.interceptRequest
7
-- Running test case: Network.interceptRequest.Subresource
8
- a/LayoutTests/http/tests/inspector/network/intercept-request-subresource-with-error-expected.txt +7 lines
Line 0 a/LayoutTests/http/tests/inspector/network/intercept-request-subresource-with-error-expected.txt_sec1
1
ALERT: DEFAULT override.js TEXT
2
Test request interception with error for the subresource load.
3
4
5
== Running test suite: Network.interceptRequest
6
-- Running test case: Network.interceptRequest.Subresource with error
7
- a/LayoutTests/http/tests/inspector/network/intercept-request-subresource-with-error.html +42 lines
Line 0 a/LayoutTests/http/tests/inspector/network/intercept-request-subresource-with-error.html_sec1
1
<!DOCTYPE html>
2
<html>
3
<head>
4
<meta charset="utf-8">
5
<script src="../resources/inspector-test.js"></script>
6
<script>
7
function test()
8
{
9
    let suite = InspectorTest.createAsyncSuite("Network.interceptRequest");
10
11
    suite.addTestCase({
12
        name: "Network.interceptRequest.Subresource with error",
13
        description: "Subresource uses request interception with error",
14
        async test() {
15
            let target = WI.assumingMainTarget();
16
            await target.NetworkAgent.addInterception.invoke({
17
                url: "http://127.0.0.1:8000/inspector/network/resources/override.js",
18
                stage: InspectorBackend.Enum.Network.NetworkStage.Request,
19
            });
20
    
21
            let interceptWithRequest = (event) => {
22
                let {target, requestId, request} = event.data;
23
                target.NetworkAgent.interceptRequestWithError.invoke({
24
                    requestId,
25
                    errorType: "General",
26
                });
27
            };
28
            WI.networkManager.addEventListener(WI.NetworkManager.Event.RequestIntercepted, interceptWithRequest);
29
30
            await InspectorTest.reloadPage({ignoreCache: false, revalidateAllResources: true});
31
        }
32
    });
33
34
    suite.runTestCasesAndFinish();
35
}
36
</script>
37
</head>
38
<body onload="runTest()">
39
<p>Test request interception with error for the subresource load.</p>
40
<script src="resources/override.js"></script>
41
</body>
42
</html>
- a/LayoutTests/http/tests/inspector/network/intercept-request-subresource-with-response-expected.txt +8 lines
Line 0 a/LayoutTests/http/tests/inspector/network/intercept-request-subresource-with-response-expected.txt_sec1
1
ALERT: DEFAULT override.js TEXT
2
ALERT: OVERRIDDEN override.js TEXT
3
Test request interception with response for the subresource load.
4
5
6
== Running test suite: Network.interceptRequest
7
-- Running test case: Network.interceptRequest.Subresource with response
8
- a/LayoutTests/http/tests/inspector/network/intercept-request-subresource-with-response.html +48 lines
Line 0 a/LayoutTests/http/tests/inspector/network/intercept-request-subresource-with-response.html_sec1
1
<!DOCTYPE html>
2
<html>
3
<head>
4
<meta charset="utf-8">
5
<script src="../resources/inspector-test.js"></script>
6
<script>
7
function test()
8
{
9
    let suite = InspectorTest.createAsyncSuite("Network.interceptRequest");
10
11
    suite.addTestCase({
12
        name: "Network.interceptRequest.Subresource with response",
13
        description: "Subresource uses request interception with response",
14
        async test() {
15
          InspectorTest.debug();
16
            let target = WI.assumingMainTarget();
17
            await target.NetworkAgent.addInterception.invoke({
18
                url: "http://127.0.0.1:8000/inspector/network/resources/override.js",
19
                stage: InspectorBackend.Enum.Network.NetworkStage.Request,
20
            });
21
22
            let interceptWithRequest = (event) => {
23
                let {target, requestId, request} = event.data;
24
                target.NetworkAgent.interceptRequestWithResponse.invoke({
25
                    requestId,
26
                    mimeType: "text/javascript",
27
                    content: `alert("OVERRIDDEN override.js TEXT"); TestPage.dispatchEventToFrontend("OverrideContentDidLoad");`,
28
                    status: 200,
29
                    statusText: "OK",
30
                    headers: {},
31
                });
32
            };
33
            WI.networkManager.addEventListener(WI.NetworkManager.Event.RequestIntercepted, interceptWithRequest);
34
35
            await InspectorTest.reloadPage({ignoreCache: false, revalidateAllResources: true});
36
            await InspectorTest.awaitEvent("OverrideContentDidLoad");
37
        }
38
    });
39
40
    suite.runTestCasesAndFinish();
41
}
42
</script>
43
</head>
44
<body onload="runTest()">
45
<p>Test request interception with response for the subresource load.</p>
46
<script src="resources/override.js"></script>
47
</body>
48
</html>
- a/LayoutTests/http/tests/inspector/network/intercept-request-subresource.html +43 lines
Line 0 a/LayoutTests/http/tests/inspector/network/intercept-request-subresource.html_sec1
1
<!DOCTYPE html>
2
<html>
3
<head>
4
<meta charset="utf-8">
5
<script src="../resources/inspector-test.js"></script>
6
<script>
7
function test()
8
{
9
    let suite = InspectorTest.createAsyncSuite("Network.interceptRequest");
10
11
    suite.addTestCase({
12
        name: "Network.interceptRequest.Subresource",
13
        description: "Subresource uses request interception",
14
        async test() {
15
					  let target = WI.assumingMainTarget()
16
						await target.NetworkAgent.addInterception.invoke({
17
								url: "http://127.0.0.1:8000/inspector/network/resources/override.js",
18
								stage: InspectorBackend.Enum.Network.NetworkStage.Request,
19
						});
20
21
						let interceptWithRequest = (event) => {
22
                let {target, requestId, request} = event.data;
23
                target.NetworkAgent.interceptWithRequest.invoke({
24
                    url: "http://127.0.0.1:8000/inspector/network/resources/intercept-request-overriden-script.js",
25
                    requestId
26
                });
27
            };
28
            WI.networkManager.addEventListener(WI.NetworkManager.Event.RequestIntercepted, interceptWithRequest);
29
30
            await InspectorTest.reloadPage({ignoreCache: false, revalidateAllResources: true});
31
						await InspectorTest.awaitEvent("OverrideContentDidLoad");
32
        }
33
    });
34
35
    suite.runTestCasesAndFinish();
36
}
37
</script>
38
</head>
39
<body onload="runTest()">
40
<p>Test request interception intercepting the subresource load.</p>
41
<script src="resources/override.js"></script>
42
</body>
43
</html>
- a/LayoutTests/http/tests/inspector/network/resources/intercept-echo.php +16 lines
Line 0 a/LayoutTests/http/tests/inspector/network/resources/intercept-echo.php_sec1
1
<?php
2
$method = $_SERVER['REQUEST_METHOD'];
3
echo "{\n";
4
echo "  \"method\": \"$method\",\n";
5
echo "  \"headers\": {\n";
6
foreach (getallheaders() as $name => $value) {
7
	echo "    \"$name\": \"$value\",\n";
8
}
9
echo "  },\n";
10
echo "  \"post\": {\n";
11
foreach ($_POST as $name => $value){
12
	echo "    \"$name\": \"$value\",\n";
13
}
14
echo "  },\n";
15
echo "}\n";
16
?>
- a/LayoutTests/http/tests/inspector/network/resources/intercept-request-overriden-page.html +11 lines
Line 0 a/LayoutTests/http/tests/inspector/network/resources/intercept-request-overriden-page.html_sec1
1
<!DOCTYPE html>
2
<html>
3
	  <head>
4
				<script src="../resources/inspector-test.js">
5
				</script>
6
		</head>
7
	  <body>
8
				<p>Overridden page content</p>
9
				<script>alert("REPLACED HTML CONTENT"); TestPage.completeTest();</script>
10
		</body>
11
</html>
- a/LayoutTests/http/tests/inspector/network/resources/intercept-request-overriden-script.js +2 lines
Line 0 a/LayoutTests/http/tests/inspector/network/resources/intercept-request-overriden-script.js_sec1
1
alert("OVERRIDEN override.js TEXT");
2
TestPage.dispatchEventToFrontend("OverrideContentDidLoad");
- a/LayoutTests/http/tests/inspector/resources/protocol-test.js +2 lines
Lines 87-98 TestPage.runTest = window.runTest = function() a/LayoutTests/http/tests/inspector/resources/protocol-test.js_sec1
87
    if (typeof testFunction !== "function") {
87
    if (typeof testFunction !== "function") {
88
        alert("Failed to send test() because it is not a function.");
88
        alert("Failed to send test() because it is not a function.");
89
        testRunner.notifyDone();
89
        testRunner.notifyDone();
90
        return;
90
    }
91
    }
91
92
92
    let url = testRunner.inspectorTestStubURL;
93
    let url = testRunner.inspectorTestStubURL;
93
    if (!url) {
94
    if (!url) {
94
        alert("Failed to obtain inspector test stub URL.");
95
        alert("Failed to obtain inspector test stub URL.");
95
        testRunner.notifyDone();
96
        testRunner.notifyDone();
97
        return;
96
    }
98
    }
97
99
98
    function runInitializationMethodsInFrontend(initializers)
100
    function runInitializationMethodsInFrontend(initializers)
- a/LayoutTests/inspector/network/intercept-request-expected.txt +22 lines
Line 0 a/LayoutTests/inspector/network/intercept-request-expected.txt_sec1
1
Test request interception.
2
3
4
== Running test suite: Network request interception
5
-- Running test case: setUp
6
-- Running test case: Network request interception: requestIntercepted.interceptContinue
7
Response data: '{"alpha":"beta","gamma":12345}'
8
9
-- Running test case: Network request interception: requestIntercepted.interceptWithRequest
10
text: intercepted request
11
12
13
-- Running test case: Network request interception: requestIntercepted.interceptRequestWithResponse
14
text: intercepted data
15
status: 200
16
statusText: OK
17
mimeType: application/octet-stream
18
my-header: my-value
19
20
-- Running test case: Network request interception: requestIntercepted.interceptRequestWithError
21
Request error: 'Request canceled'
22
- a/LayoutTests/inspector/network/intercept-request.html +177 lines
Line 0 a/LayoutTests/inspector/network/intercept-request.html_sec1
1
<!DOCTYPE html>
2
<html>
3
<head>
4
<meta charset="utf-8">
5
<script src="../../http/tests/inspector/resources/protocol-test.js"></script>
6
<script>
7
8
async function fetchData() {
9
    try {
10
        let response = await fetch('resources/data.json');
11
        return {
12
            text: await response.text(),
13
            status: response.status,
14
            statusText: response.statusText,
15
            mimeType: response.headers.get('content-type'),
16
            header: response.headers.get('my-header'),
17
        };
18
    } catch (e) {
19
        return e.message;
20
    }
21
}
22
23
function test()
24
{
25
    let suite = ProtocolTest.createAsyncSuite("Network request interception");
26
27
    function printFetchResult(result)
28
    {
29
        ProtocolTest.log("text: " + result.text);
30
        ProtocolTest.log("status: " + result.status);
31
        ProtocolTest.log("statusText: " + result.statusText);
32
        ProtocolTest.log("mimeType: " + result.mimeType);
33
        ProtocolTest.log("my-header: " + result.header);
34
    }
35
36
    let url;
37
    suite.addTestCase({
38
        name: "setUp",
39
        async test() {
40
            let [result1, result2, {result}] = await Promise.all([
41
                InspectorProtocol.awaitCommand({method: "Network.enable", params: {}}),
42
                InspectorProtocol.awaitCommand({method: "Runtime.enable", params: {}}),
43
                InspectorProtocol.awaitCommand({method: "Runtime.evaluate", params: {
44
                    expression: "document.URL",
45
                }}),
46
                InspectorProtocol.awaitCommand({method: "Network.setInterceptionEnabled", params: {
47
                    enabled: true,
48
                }}),
49
            ]);
50
51
            let baseURL = result.value.substring(0, result.value.lastIndexOf("/"));
52
            url = baseURL + "/resources/data.json";
53
            await InspectorProtocol.awaitCommand({method: "Network.addInterception", params: { url, stage: "request" }});
54
        }
55
    });
56
57
    suite.addTestCase({
58
        name: "Network request interception: requestIntercepted.interceptContinue",
59
        description: "Test continue intercepted request.",
60
        async test() {
61
            // Fetch URL and intercept it.
62
            let [fetchResultPromise, interceptedEvent] = await Promise.all([
63
                InspectorProtocol.awaitCommand({method: "Runtime.evaluate", params: {
64
                    expression: "fetchData()",
65
                }}),
66
                InspectorProtocol.awaitEvent({event: "Network.requestIntercepted"}),
67
            ]);
68
69
            // Let the load continue.
70
            let [fetchResult] = await Promise.all([
71
                InspectorProtocol.awaitCommand({method: "Runtime.awaitPromise", params: {
72
                    promiseObjectId: fetchResultPromise.result.objectId,
73
                    returnByValue: true,
74
                }}),
75
                InspectorProtocol.awaitCommand({method: "Network.interceptContinue", params: {
76
                    requestId: interceptedEvent.params.requestId,
77
                    stage: "request",
78
                }}),
79
            ]);
80
            ProtocolTest.log("Response data: '" + fetchResult.result.value.text.trim() + "'");
81
        }
82
    });
83
84
    suite.addTestCase({
85
        name: "Network request interception: requestIntercepted.interceptWithRequest",
86
        description: "Test fulfill intercepted request with response.",
87
        async test() {
88
            // Fetch URL and intercept it.
89
            let [fetchResultPromise, interceptedEvent] = await Promise.all([
90
                InspectorProtocol.awaitCommand({method: "Runtime.evaluate", params: {
91
                    expression: "fetchData()",
92
                }}),
93
                InspectorProtocol.awaitEvent({event: "Network.requestIntercepted"}),
94
            ]);
95
96
            // Fulfill the request with data.
97
            let [fetchResult] = await Promise.all([
98
                InspectorProtocol.awaitCommand({method: "Runtime.awaitPromise", params: {
99
                    promiseObjectId: fetchResultPromise.result.objectId,
100
                    returnByValue: true,
101
                }}),
102
                InspectorProtocol.awaitCommand({method: "Network.interceptWithRequest", params: {
103
                    requestId: interceptedEvent.params.requestId,
104
                    url: url.replace('data.json', 'data2.json'),
105
                }}),
106
            ]);
107
            ProtocolTest.log("text: " + fetchResult.result.value.text);
108
        }
109
    });
110
111
    suite.addTestCase({
112
        name: "Network request interception: requestIntercepted.interceptRequestWithResponse",
113
        description: "Test fulfill intercepted request with response.",
114
        async test() {
115
            // Fetch URL and intercept it.
116
            let [fetchResultPromise, interceptedEvent] = await Promise.all([
117
                InspectorProtocol.awaitCommand({method: "Runtime.evaluate", params: {
118
                    expression: "fetchData()",
119
                }}),
120
                InspectorProtocol.awaitEvent({event: "Network.requestIntercepted"}),
121
            ]);
122
123
            // Fulfill the request with data.
124
            let [fetchResult] = await Promise.all([
125
                InspectorProtocol.awaitCommand({method: "Runtime.awaitPromise", params: {
126
                    promiseObjectId: fetchResultPromise.result.objectId,
127
                    returnByValue: true
128
                }}),
129
                InspectorProtocol.awaitCommand({method: "Network.interceptRequestWithResponse", params: {
130
                    requestId: interceptedEvent.params.requestId,
131
                    status: 200,
132
                    statusText: "OK",
133
                    headers: { "my-header": "my-value" },
134
                    mimeType: "application/octet-stream",
135
                    content: btoa("intercepted data"),
136
                    base64Encoded: true,
137
                }}),
138
            ]);
139
            printFetchResult(fetchResult.result.value);
140
        }
141
    });
142
143
    suite.addTestCase({
144
        name: "Network request interception: requestIntercepted.interceptRequestWithError",
145
        description: "Test abort intercepted request with error.",
146
        async test() {
147
            // Fetch URL and intercept it.
148
            let [fetchResultPromise, interceptedEvent] = await Promise.all([
149
                InspectorProtocol.awaitCommand({method: "Runtime.evaluate", params: {
150
                    expression: "fetchData()",
151
                }}),
152
                InspectorProtocol.awaitEvent({event: "Network.requestIntercepted"}),
153
            ]);
154
155
            // Abort the request as canceled.
156
            let [fetchResult] = await Promise.all([
157
                InspectorProtocol.awaitCommand({method: "Runtime.awaitPromise", params: {
158
                    promiseObjectId: fetchResultPromise.result.objectId,
159
                    returnByValue: true,
160
                }}),
161
                InspectorProtocol.awaitCommand({method: "Network.interceptRequestWithError", params: {
162
                    requestId: interceptedEvent.params.requestId,
163
                    errorType: "Cancellation",
164
                }}),
165
            ]);
166
            ProtocolTest.log("Request error: '" + fetchResult.result.value + "'");
167
        }
168
    });
169
170
    suite.runTestCasesAndFinish();
171
}
172
</script>
173
</head>
174
<body onload="runTest()">
175
<p>Test request interception.</p>
176
</body>
177
</html>
- a/LayoutTests/inspector/network/local-resource-override-continue-response.html -1 / +1 lines
Lines 46-52 function test() a/LayoutTests/inspector/network/local-resource-override-continue-response.html_sec1
46
            // Let the load continue.
46
            // Let the load continue.
47
            await Promise.all([
47
            await Promise.all([
48
                InspectorProtocol.awaitEvent({event: "Network.responseReceived"}),
48
                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"}}),
50
            ]);
50
            ]);
51
            ProtocolTest.pass("Response received.");
51
            ProtocolTest.pass("Response received.");
52
52
- a/LayoutTests/inspector/network/resources/data2.json +1 lines
Line 0 a/LayoutTests/inspector/network/resources/data2.json_sec1
1
intercepted request

Return to Bug 207446