Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.

Commit d756214

Browse files
committed
Bug 1467223 - Part 6: Add basic test for process-changing POST loads, r=qdot
This test checks that POST data can be submitted from both file and moz-extension URIs to web content without the data being lost, or the load being performed in the incorrect process. Depends on D15612 Differential Revision: https://phabricator.services.mozilla.com/D15613 --HG-- extra : moz-landing-system : lando
1 parent 45b85ee commit d756214

4 files changed

Lines changed: 189 additions & 0 deletions

File tree

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
function handleRequest(request, response)
2+
{
3+
response.setStatusLine(request.httpVersion, 307, "Temporary Redirect");
4+
let location = request.queryString;
5+
response.setHeader("Location", location, false);
6+
response.write("Hello world!");
7+
}

toolkit/components/remotebrowserutils/tests/browser/browser.ini

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,8 @@
22
run-if = e10s
33
support-files =
44
dummy_page.html
5+
print_postdata.sjs
6+
307redirect.sjs
57

68
[browser_RemoteWebNavigation.js]
9+
[browser_httpResponseProcessSelection.js]
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
ChromeUtils.import("resource://gre/modules/Services.jsm");
2+
ChromeUtils.import("resource://gre/modules/E10SUtils.jsm");
3+
4+
let PREF_NAME = "browser.tabs.remote.useHTTPResponseProcessSelection";
5+
6+
function fileURL(filename) {
7+
let ifile = getChromeDir(getResolvedURI(gTestPath));
8+
ifile.append(filename);
9+
return Services.io.newFileURI(ifile).spec;
10+
}
11+
12+
function httpURL(filename, host = "https://example.com/") {
13+
let root = getRootDirectory(gTestPath)
14+
.replace("chrome://mochitests/content/", host);
15+
return root + filename;
16+
}
17+
18+
function add307(url, host = "https://example.com/") {
19+
return httpURL("307redirect.sjs?" + url, host);
20+
}
21+
22+
async function performLoad(browser, opts, action) {
23+
let loadedPromise = BrowserTestUtils.browserLoaded(
24+
browser, false, opts.url, opts.maybeErrorPage);
25+
await action();
26+
await loadedPromise;
27+
}
28+
29+
const EXTENSION_DATA = {
30+
manifest: {
31+
"name": "Simple extension test",
32+
"version": "1.0",
33+
"manifest_version": 2,
34+
"description": "",
35+
},
36+
37+
files: {
38+
"dummy.html": "<html>webext dummy</html>",
39+
},
40+
};
41+
42+
async function withExtensionDummy(callback) {
43+
let extension = ExtensionTestUtils.loadExtension(EXTENSION_DATA);
44+
await extension.startup();
45+
let rv = await callback(`moz-extension://${extension.uuid}/dummy.html`);
46+
await extension.unload();
47+
return rv;
48+
}
49+
50+
const PRINT_POSTDATA = httpURL("print_postdata.sjs");
51+
const FILE_DUMMY = fileURL("dummy_page.html");
52+
53+
async function postFrom(start, target) {
54+
return BrowserTestUtils.withNewTab({
55+
gBrowser, url: start,
56+
}, async function(browser) {
57+
info("Test tab ready: " + start);
58+
59+
// Create the form element in our loaded URI.
60+
await ContentTask.spawn(browser, { target }, function({ target }) {
61+
// eslint-disable-next-line no-unsanitized/property
62+
content.document.body.innerHTML = `
63+
<form method="post" action="${target}">
64+
<input type="text" name="initialRemoteType" value="${Services.appinfo.remoteType}">
65+
<input type="submit" id="submit">
66+
</form>`;
67+
});
68+
69+
// Perform a form POST submit load.
70+
info("Performing POST submission");
71+
await performLoad(browser, {
72+
url(url) { return url == PRINT_POSTDATA || url == target; },
73+
maybeErrorPage: true,
74+
}, async () => {
75+
await ContentTask.spawn(browser, null, () => {
76+
content.document.querySelector("#submit").click();
77+
});
78+
});
79+
80+
// Check that the POST data was submitted.
81+
info("Fetching results");
82+
return ContentTask.spawn(browser, null, () => {
83+
return {
84+
remoteType: Services.appinfo.remoteType,
85+
location: "" + content.location.href,
86+
body: content.document.body.textContent,
87+
};
88+
});
89+
});
90+
}
91+
92+
add_task(async function test_disabled() {
93+
await SpecialPowers.pushPrefEnv({set: [[PREF_NAME, false]]});
94+
95+
// With the pref disabled, file URIs should successfully POST, but remain in
96+
// the 'file' process.
97+
info("DISBALED -- FILE -- raw URI load");
98+
let resp = await postFrom(FILE_DUMMY, PRINT_POSTDATA);
99+
is(resp.remoteType, E10SUtils.FILE_REMOTE_TYPE, "no process switch");
100+
is(resp.location, PRINT_POSTDATA, "correct location");
101+
is(resp.body, "initialRemoteType=file", "correct POST body");
102+
103+
info("DISABLED -- FILE -- 307-redirect URI load");
104+
let resp307 = await postFrom(FILE_DUMMY, add307(PRINT_POSTDATA));
105+
is(resp307.remoteType, E10SUtils.FILE_REMOTE_TYPE, "no process switch");
106+
is(resp307.location, PRINT_POSTDATA, "correct location");
107+
is(resp307.body, "initialRemoteType=file", "correct POST body");
108+
109+
// With the pref disabled, extension URIs should fail to POST, but correctly
110+
// switch processes.
111+
await withExtensionDummy(async (dummy) => {
112+
info("DISABLED -- EXTENSION -- raw URI load");
113+
let respExt = await postFrom(dummy, PRINT_POSTDATA);
114+
is(respExt.remoteType, E10SUtils.WEB_REMOTE_TYPE, "process switch");
115+
is(respExt.location, PRINT_POSTDATA, "correct location");
116+
is(respExt.body, "", "no POST body");
117+
118+
info("DISABLED -- EXTENSION -- 307-redirect URI load");
119+
let respExt307 = await postFrom(dummy, add307(PRINT_POSTDATA));
120+
is(respExt307.remoteType, E10SUtils.WEB_REMOTE_TYPE, "process switch");
121+
is(respExt307.location, PRINT_POSTDATA, "correct location");
122+
is(respExt307.body, "", "no POST body");
123+
});
124+
});
125+
126+
add_task(async function test_enabled() {
127+
await SpecialPowers.pushPrefEnv({set: [[PREF_NAME, true]]});
128+
129+
// With the pref enabled, URIs should correctly switch processes & the POST
130+
// should succeed.
131+
info("ENABLED -- FILE -- raw URI load");
132+
let resp = await postFrom(FILE_DUMMY, PRINT_POSTDATA);
133+
is(resp.remoteType, E10SUtils.WEB_REMOTE_TYPE, "process switch");
134+
is(resp.location, PRINT_POSTDATA, "correct location");
135+
is(resp.body, "initialRemoteType=file", "correct POST body");
136+
137+
info("ENABLED -- FILE -- 307-redirect URI load");
138+
let resp307 = await postFrom(FILE_DUMMY, add307(PRINT_POSTDATA));
139+
is(resp307.remoteType, E10SUtils.WEB_REMOTE_TYPE, "process switch");
140+
is(resp307.location, PRINT_POSTDATA, "correct location");
141+
is(resp307.body, "initialRemoteType=file", "correct POST body");
142+
143+
// Same with extensions
144+
await withExtensionDummy(async (dummy) => {
145+
info("ENABLED -- EXTENSION -- raw URI load");
146+
let respExt = await postFrom(dummy, PRINT_POSTDATA);
147+
is(respExt.remoteType, E10SUtils.WEB_REMOTE_TYPE, "process switch");
148+
is(respExt.location, PRINT_POSTDATA, "correct location");
149+
is(respExt.body, "initialRemoteType=extension", "correct POST body");
150+
151+
info("ENABLED -- EXTENSION -- 307-redirect URI load");
152+
let respExt307 = await postFrom(dummy, add307(PRINT_POSTDATA));
153+
is(respExt307.remoteType, E10SUtils.WEB_REMOTE_TYPE, "process switch");
154+
is(respExt307.location, PRINT_POSTDATA, "correct location");
155+
is(respExt307.body, "initialRemoteType=extension", "correct POST body");
156+
});
157+
});
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
const CC = Components.Constructor;
2+
const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1",
3+
"nsIBinaryInputStream",
4+
"setInputStream");
5+
6+
function handleRequest(request, response) {
7+
response.setHeader("Content-Type", "text/plain", false);
8+
if (request.method == "GET") {
9+
response.write(request.queryString);
10+
} else {
11+
var body = new BinaryInputStream(request.bodyInputStream);
12+
13+
var avail;
14+
var bytes = [];
15+
16+
while ((avail = body.available()) > 0)
17+
Array.prototype.push.apply(bytes, body.readByteArray(avail));
18+
19+
var data = String.fromCharCode.apply(null, bytes);
20+
response.bodyOutputStream.write(data, data.length);
21+
}
22+
}

0 commit comments

Comments
 (0)