Skip to content

Commit 53654d7

Browse files
Bug 1988955 - [bidi] Add support for dataType=request to network data collection r=whimboo
Differential Revision: https://phabricator.services.mozilla.com/D267227
1 parent 532a561 commit 53654d7

File tree

5 files changed

+256
-72
lines changed

5 files changed

+256
-72
lines changed

remote/jar.mn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ remote.jar:
2727
content/shared/Navigate.sys.mjs (shared/Navigate.sys.mjs)
2828
content/shared/NavigationManager.sys.mjs (shared/NavigationManager.sys.mjs)
2929
content/shared/NetworkCacheManager.sys.mjs (shared/NetworkCacheManager.sys.mjs)
30+
content/shared/NetworkDataBytes.sys.mjs (shared/NetworkDataBytes.sys.mjs)
3031
content/shared/NetworkDecodedBodySizeMap.sys.mjs (shared/NetworkDecodedBodySizeMap.sys.mjs)
3132
content/shared/NetworkRequest.sys.mjs (shared/NetworkRequest.sys.mjs)
3233
content/shared/NetworkResponse.sys.mjs (shared/NetworkResponse.sys.mjs)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/* This Source Code Form is subject to the terms of the Mozilla Public
2+
* License, v. 2.0. If a copy of the MPL was not distributed with this
3+
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4+
5+
export class NetworkDataBytes {
6+
#getBytesValue;
7+
#isBase64;
8+
9+
/**
10+
* Common interface used to handle network BytesValue for collected data which
11+
* might be encoded and require an additional async step in order to retrieve
12+
* the actual bytes.
13+
*
14+
* This is a simple wrapper mostly designed to ensure a common interface in
15+
* case this is used for request or response bodies.
16+
*
17+
* @param {object} options
18+
* @param {Function} options.getBytesValue
19+
* A -potentially async- callable which returns the bytes as a string.
20+
* @param {boolean} options.isBase64
21+
* Whether this represents a base64-encoded binary data.
22+
*/
23+
constructor(options) {
24+
this.#getBytesValue = options.getBytesValue;
25+
this.#isBase64 = options.isBase64;
26+
}
27+
28+
get isBase64() {
29+
return this.#isBase64;
30+
}
31+
32+
async getBytesValue() {
33+
return this.#getBytesValue();
34+
}
35+
}

remote/shared/NetworkRequest.sys.mjs

Lines changed: 52 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ ChromeUtils.defineESModuleGetters(lazy, {
1212
generateUUID: "chrome://remote/content/shared/UUID.sys.mjs",
1313
NavigableManager: "chrome://remote/content/shared/NavigableManager.sys.mjs",
1414
NavigationState: "chrome://remote/content/shared/NavigationManager.sys.mjs",
15+
NetworkDataBytes: "chrome://remote/content/shared/NetworkDataBytes.sys.mjs",
1516
notifyNavigationStarted:
1617
"chrome://remote/content/shared/NavigationManager.sys.mjs",
1718
});
@@ -29,6 +30,7 @@ export class NetworkRequest {
2930
#isDataURL;
3031
#navigationId;
3132
#navigationManager;
33+
#postData;
3234
#postDataSize;
3335
#rawHeaders;
3436
#redirectCount;
@@ -97,9 +99,10 @@ export class NetworkRequest {
9799
this.#contextId = this.#getContextId();
98100
this.#navigationId = this.#getNavigationId();
99101

100-
// The postDataSize will no longer be available after the channel is closed.
101-
// Compute and cache the value, to be updated when `setRequestBody` is used.
102-
this.#postDataSize = this.#computePostDataSize();
102+
// The postData will no longer be available after the channel is closed.
103+
// Compute the postData and postDataSize properties, to be updated later if
104+
// `setRequestBody` is used.
105+
this.#updatePostData();
103106
}
104107

105108
get alreadyCompleted() {
@@ -159,6 +162,10 @@ export class NetworkRequest {
159162
return this.#navigationId;
160163
}
161164

165+
get postData() {
166+
return this.#postData;
167+
}
168+
162169
get postDataSize() {
163170
return this.#postDataSize;
164171
}
@@ -216,6 +223,19 @@ export class NetworkRequest {
216223
);
217224
}
218225

226+
/**
227+
* Returns the NetworkDataBytes instance representing the request body for
228+
* this request.
229+
*
230+
* @returns {NetworkDataBytes}
231+
*/
232+
readAndProcessRequestBody = () => {
233+
return new lazy.NetworkDataBytes({
234+
getBytesValue: () => this.#postData.text,
235+
isBase64: this.#postData.isBase64,
236+
});
237+
};
238+
219239
/**
220240
* Redirect the request to another provided URL.
221241
*
@@ -253,7 +273,7 @@ export class NetworkRequest {
253273
} finally {
254274
// Make sure to reset the flag once the modification was attempted.
255275
this.#channel.requestObserversCalled = true;
256-
this.#postDataSize = this.#computePostDataSize();
276+
this.#updatePostData();
257277
}
258278
}
259279

@@ -337,6 +357,7 @@ export class NetworkRequest {
337357
initiatorType: this.initiatorType,
338358
method: this.method,
339359
navigationId: this.navigationId,
360+
postData: this.postData,
340361
postDataSize: this.postDataSize,
341362
redirectCount: this.redirectCount,
342363
requestId: this.requestId,
@@ -348,15 +369,6 @@ export class NetworkRequest {
348369
};
349370
}
350371

351-
#computePostDataSize() {
352-
const charset = lazy.NetworkUtils.getCharset(this.#channel);
353-
const sentBody = lazy.NetworkHelper.readPostTextFromRequest(
354-
this.#channel,
355-
charset
356-
);
357-
return sentBody ? sentBody.length : 0;
358-
}
359-
360372
/**
361373
* Convert the provided request timing to a timing relative to the beginning
362374
* of the request. Note that https://w3c.github.io/resource-timing/#dfn-convert-fetch-timestamp
@@ -517,4 +529,31 @@ export class NetworkRequest {
517529
);
518530
return !browsingContext.parent;
519531
}
532+
533+
#readPostDataFromRequestAsUTF8() {
534+
const postData = lazy.NetworkHelper.readPostDataFromRequest(
535+
this.#channel,
536+
"UTF-8"
537+
);
538+
539+
if (postData === null || postData.data === null) {
540+
return null;
541+
}
542+
543+
return {
544+
text: postData.isDecodedAsText ? postData.data : btoa(postData.data),
545+
isBase64: !postData.isDecodedAsText,
546+
};
547+
}
548+
549+
#updatePostData() {
550+
const sentBody = this.#readPostDataFromRequestAsUTF8();
551+
if (sentBody) {
552+
this.#postData = sentBody;
553+
this.#postDataSize = sentBody.text.length;
554+
} else {
555+
this.#postData = null;
556+
this.#postDataSize = 0;
557+
}
558+
}
520559
}

remote/shared/NetworkResponse.sys.mjs

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ const lazy = {};
66
ChromeUtils.defineESModuleGetters(lazy, {
77
NetworkUtils:
88
"resource://devtools/shared/network-observer/NetworkUtils.sys.mjs",
9+
10+
NetworkDataBytes: "chrome://remote/content/shared/NetworkDataBytes.sys.mjs",
911
});
1012

1113
/**
@@ -157,34 +159,37 @@ export class NetworkResponse {
157159
);
158160
}
159161

160-
async readResponseBody() {
161-
return this.#responseBodyReady.promise;
162-
}
162+
/**
163+
* Returns the NetworkDataBytes instance representing the response body for
164+
* this response.
165+
*
166+
* @returns {NetworkDataBytes}
167+
*/
168+
readAndProcessResponseBody = async () => {
169+
const responseContent = await this.#responseBodyReady.promise;
170+
171+
return new lazy.NetworkDataBytes({
172+
getBytesValue: async () => {
173+
if (responseContent.isContentEncoded) {
174+
return lazy.NetworkUtils.decodeResponseChunks(
175+
responseContent.encodedData,
176+
{
177+
// Should always attempt to decode as UTF-8.
178+
charset: "UTF-8",
179+
compressionEncodings: responseContent.compressionEncodings,
180+
encodedBodySize: responseContent.encodedBodySize,
181+
encoding: responseContent.encoding,
182+
}
183+
);
184+
}
185+
return responseContent.text;
186+
},
187+
isBase64: responseContent.encoding === "base64",
188+
});
189+
};
163190

164191
setResponseContent(responseContent) {
165-
// Extract the properties necessary to decode the response body later on.
166-
let encodedResponseBody;
167-
168-
if (responseContent.isContentEncoded) {
169-
encodedResponseBody = {
170-
encoding: responseContent.encoding,
171-
getDecodedResponseBody: async () =>
172-
lazy.NetworkUtils.decodeResponseChunks(responseContent.encodedData, {
173-
// Should always attempt to decode as UTF-8.
174-
charset: "UTF-8",
175-
compressionEncodings: responseContent.compressionEncodings,
176-
encodedBodySize: responseContent.encodedBodySize,
177-
encoding: responseContent.encoding,
178-
}),
179-
};
180-
} else {
181-
encodedResponseBody = {
182-
encoding: responseContent.encoding,
183-
getDecodedResponseBody: () => responseContent.text,
184-
};
185-
}
186-
187-
this.#responseBodyReady.resolve(encodedResponseBody);
192+
this.#responseBodyReady.resolve(responseContent);
188193
}
189194

190195
/**

0 commit comments

Comments
 (0)