summaryrefslogtreecommitdiffstats
path: root/netwerk/test/mochitests
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--netwerk/test/mochitests/beltzner.jpgbin0 -> 9995 bytes
-rw-r--r--netwerk/test/mochitests/beltzner.jpg^headers^3
-rw-r--r--netwerk/test/mochitests/empty.html16
-rw-r--r--netwerk/test/mochitests/file_1331680.js24
-rw-r--r--netwerk/test/mochitests/file_1502055.sjs17
-rw-r--r--netwerk/test/mochitests/file_1503201.sjs4
-rw-r--r--netwerk/test/mochitests/file_chromecommon.js15
-rw-r--r--netwerk/test/mochitests/file_documentcookie_maxage_chromescript.js45
-rw-r--r--netwerk/test/mochitests/file_domain_hierarchy_inner.html13
-rw-r--r--netwerk/test/mochitests/file_domain_hierarchy_inner.html^headers^4
-rw-r--r--netwerk/test/mochitests/file_domain_hierarchy_inner_inner.html13
-rw-r--r--netwerk/test/mochitests/file_domain_hierarchy_inner_inner.html^headers^4
-rw-r--r--netwerk/test/mochitests/file_domain_hierarchy_inner_inner_inner.html13
-rw-r--r--netwerk/test/mochitests/file_domain_hierarchy_inner_inner_inner.html^headers^1
-rw-r--r--netwerk/test/mochitests/file_domain_inner.html13
-rw-r--r--netwerk/test/mochitests/file_domain_inner.html^headers^4
-rw-r--r--netwerk/test/mochitests/file_domain_inner_inner.html13
-rw-r--r--netwerk/test/mochitests/file_domain_inner_inner.html^headers^4
-rw-r--r--netwerk/test/mochitests/file_iframe_allow_same_origin.html8
-rw-r--r--netwerk/test/mochitests/file_iframe_allow_scripts.html6
-rw-r--r--netwerk/test/mochitests/file_image_inner.html14
-rw-r--r--netwerk/test/mochitests/file_image_inner.html^headers^4
-rw-r--r--netwerk/test/mochitests/file_image_inner_inner.html19
-rw-r--r--netwerk/test/mochitests/file_image_inner_inner.html^headers^4
-rw-r--r--netwerk/test/mochitests/file_lnk.lnkbin0 -> 1531 bytes
-rw-r--r--netwerk/test/mochitests/file_loadflags_inner.html16
-rw-r--r--netwerk/test/mochitests/file_loadflags_inner.html^headers^4
-rw-r--r--netwerk/test/mochitests/file_loadinfo_redirectchain.sjs109
-rw-r--r--netwerk/test/mochitests/file_localhost_inner.html13
-rw-r--r--netwerk/test/mochitests/file_localhost_inner.html^headers^4
-rw-r--r--netwerk/test/mochitests/file_loopback_inner.html13
-rw-r--r--netwerk/test/mochitests/file_loopback_inner.html^headers^4
-rw-r--r--netwerk/test/mochitests/file_subdomain_inner.html13
-rw-r--r--netwerk/test/mochitests/file_subdomain_inner.html^headers^4
-rw-r--r--netwerk/test/mochitests/file_testcommon.js84
-rw-r--r--netwerk/test/mochitests/file_testloadflags.js130
-rw-r--r--netwerk/test/mochitests/file_testloadflags_chromescript.js144
-rw-r--r--netwerk/test/mochitests/iframe_1502055.html33
-rw-r--r--netwerk/test/mochitests/image1.pngbin0 -> 821 bytes
-rw-r--r--netwerk/test/mochitests/image1.png^headers^3
-rw-r--r--netwerk/test/mochitests/image2.pngbin0 -> 821 bytes
-rw-r--r--netwerk/test/mochitests/image2.png^headers^3
-rw-r--r--netwerk/test/mochitests/method.sjs9
-rw-r--r--netwerk/test/mochitests/mochitest.toml217
-rw-r--r--netwerk/test/mochitests/origin_header.sjs10
-rw-r--r--netwerk/test/mochitests/origin_header_form_post.html19
-rw-r--r--netwerk/test/mochitests/origin_header_form_post_xorigin.html19
-rw-r--r--netwerk/test/mochitests/partial_content.sjs193
-rw-r--r--netwerk/test/mochitests/redirect.sjs4
-rw-r--r--netwerk/test/mochitests/redirect_idn.html0
-rw-r--r--netwerk/test/mochitests/redirect_idn.html^headers^3
-rw-r--r--netwerk/test/mochitests/redirect_to.sjs4
-rw-r--r--netwerk/test/mochitests/rel_preconnect.sjs17
-rw-r--r--netwerk/test/mochitests/reset_cookie_xhr.sjs15
-rw-r--r--netwerk/test/mochitests/set_cookie_xhr.sjs15
-rw-r--r--netwerk/test/mochitests/signed_web_packaged_app.sjs73
-rw-r--r--netwerk/test/mochitests/subResources.sjs78
-rw-r--r--netwerk/test/mochitests/sw_1502055.js1
-rw-r--r--netwerk/test/mochitests/test1.css2
-rw-r--r--netwerk/test/mochitests/test1.css^headers^3
-rw-r--r--netwerk/test/mochitests/test2.css2
-rw-r--r--netwerk/test/mochitests/test2.css^headers^3
-rw-r--r--netwerk/test/mochitests/test_1331680.html87
-rw-r--r--netwerk/test/mochitests/test_1331680_iframe.html68
-rw-r--r--netwerk/test/mochitests/test_1331680_xhr.html90
-rw-r--r--netwerk/test/mochitests/test_1396395.html48
-rw-r--r--netwerk/test/mochitests/test_1421324.html88
-rw-r--r--netwerk/test/mochitests/test_1425031.html74
-rw-r--r--netwerk/test/mochitests/test_1502055.html49
-rw-r--r--netwerk/test/mochitests/test_1503201.html28
-rw-r--r--netwerk/test/mochitests/test_accept_header.html87
-rw-r--r--netwerk/test/mochitests/test_accept_header.sjs62
-rw-r--r--netwerk/test/mochitests/test_arraybufferinputstream.html89
-rw-r--r--netwerk/test/mochitests/test_arraybufferinputstream_large.html45
-rw-r--r--netwerk/test/mochitests/test_different_domain_in_hierarchy.html15
-rw-r--r--netwerk/test/mochitests/test_differentdomain.html15
-rw-r--r--netwerk/test/mochitests/test_documentcookies_maxage.html149
-rw-r--r--netwerk/test/mochitests/test_fetch_lnk.html17
-rw-r--r--netwerk/test/mochitests/test_idn_redirect.html35
-rw-r--r--netwerk/test/mochitests/test_image.html14
-rw-r--r--netwerk/test/mochitests/test_loadflags.html21
-rw-r--r--netwerk/test/mochitests/test_loadinfo_redirectchain.html269
-rw-r--r--netwerk/test/mochitests/test_origin_header.html398
-rw-r--r--netwerk/test/mochitests/test_partially_cached_content.html95
-rw-r--r--netwerk/test/mochitests/test_redirect_ref.html29
-rw-r--r--netwerk/test/mochitests/test_rel_preconnect.html61
-rw-r--r--netwerk/test/mochitests/test_same_base_domain.html15
-rw-r--r--netwerk/test/mochitests/test_same_base_domain_2.html15
-rw-r--r--netwerk/test/mochitests/test_same_base_domain_3.html15
-rw-r--r--netwerk/test/mochitests/test_same_base_domain_4.html15
-rw-r--r--netwerk/test/mochitests/test_same_base_domain_5.html15
-rw-r--r--netwerk/test/mochitests/test_same_base_domain_6.html26
-rw-r--r--netwerk/test/mochitests/test_samedomain.html15
-rw-r--r--netwerk/test/mochitests/test_uri_scheme.html50
-rw-r--r--netwerk/test/mochitests/test_url_perf.html75
-rw-r--r--netwerk/test/mochitests/test_viewsource_unlinkable.html25
-rw-r--r--netwerk/test/mochitests/test_xhr_method_case.html65
-rw-r--r--netwerk/test/mochitests/web_packaged_app.sjs47
98 files changed, 3836 insertions, 0 deletions
diff --git a/netwerk/test/mochitests/beltzner.jpg b/netwerk/test/mochitests/beltzner.jpg
new file mode 100644
index 0000000000..75849bc40d
--- /dev/null
+++ b/netwerk/test/mochitests/beltzner.jpg
Binary files differ
diff --git a/netwerk/test/mochitests/beltzner.jpg^headers^ b/netwerk/test/mochitests/beltzner.jpg^headers^
new file mode 100644
index 0000000000..cb51f27018
--- /dev/null
+++ b/netwerk/test/mochitests/beltzner.jpg^headers^
@@ -0,0 +1,3 @@
+Cache-Control: no-store
+Set-Cookie: mike=beltzer
+
diff --git a/netwerk/test/mochitests/empty.html b/netwerk/test/mochitests/empty.html
new file mode 100644
index 0000000000..e60f5abdf4
--- /dev/null
+++ b/netwerk/test/mochitests/empty.html
@@ -0,0 +1,16 @@
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+ This page does nothing. If the loading page managed to load this, the test
+ probably succeeded.
+</body>
+</html>
diff --git a/netwerk/test/mochitests/file_1331680.js b/netwerk/test/mochitests/file_1331680.js
new file mode 100644
index 0000000000..868d6991ae
--- /dev/null
+++ b/netwerk/test/mochitests/file_1331680.js
@@ -0,0 +1,24 @@
+/* eslint-env mozilla/chrome-script */
+
+"use strict";
+
+var observer = {
+ observe(subject, topic) {
+ if (topic == "cookie-changed") {
+ let notification = subject.QueryInterface(Ci.nsICookieNotification);
+ let cookie = notification.cookie.QueryInterface(Ci.nsICookie);
+ sendAsyncMessage("cookieName", cookie.name + "=" + cookie.value);
+ sendAsyncMessage("cookieOperation", notification.action);
+ }
+ },
+};
+
+addMessageListener("createObserver", function (e) {
+ Services.obs.addObserver(observer, "cookie-changed");
+ sendAsyncMessage("createObserver:return");
+});
+
+addMessageListener("removeObserver", function (e) {
+ Services.obs.removeObserver(observer, "cookie-changed");
+ sendAsyncMessage("removeObserver:return");
+});
diff --git a/netwerk/test/mochitests/file_1502055.sjs b/netwerk/test/mochitests/file_1502055.sjs
new file mode 100644
index 0000000000..71a4ddfa66
--- /dev/null
+++ b/netwerk/test/mochitests/file_1502055.sjs
@@ -0,0 +1,17 @@
+function handleRequest(request, response) {
+ var count = parseInt(getState("count"));
+ if (!count) {
+ count = 0;
+ }
+
+ if (count == 0) {
+ response.setStatusLine(request.httpVersion, "200", "OK");
+ response.setHeader("Content-Type", "text/html", false);
+ response.write("<html><body>Hello world!</body></html>");
+ setState("count", "1");
+ return;
+ }
+
+ response.setStatusLine(request.httpVersion, "304", "Not Modified");
+ response.setHeader("Clear-Site-Data", '"storage"');
+}
diff --git a/netwerk/test/mochitests/file_1503201.sjs b/netwerk/test/mochitests/file_1503201.sjs
new file mode 100644
index 0000000000..ac5c304103
--- /dev/null
+++ b/netwerk/test/mochitests/file_1503201.sjs
@@ -0,0 +1,4 @@
+function handleRequest(request, response) {
+ response.setStatusLine(request.httpVersion, 401, "Unauthorized");
+ response.setHeader("WWW-Authenticate", 'Bearer realm="foo"');
+}
diff --git a/netwerk/test/mochitests/file_chromecommon.js b/netwerk/test/mochitests/file_chromecommon.js
new file mode 100644
index 0000000000..986a9d7ef1
--- /dev/null
+++ b/netwerk/test/mochitests/file_chromecommon.js
@@ -0,0 +1,15 @@
+/* eslint-env mozilla/chrome-script */
+
+"use strict";
+
+// eslint-disable-next-line mozilla/use-services
+let cs = Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager);
+
+addMessageListener("getCookieCountAndClear", () => {
+ let count = cs.cookies.length;
+ cs.removeAll();
+
+ sendAsyncMessage("getCookieCountAndClear:return", { count });
+});
+
+cs.removeAll();
diff --git a/netwerk/test/mochitests/file_documentcookie_maxage_chromescript.js b/netwerk/test/mochitests/file_documentcookie_maxage_chromescript.js
new file mode 100644
index 0000000000..dc1e8eb05f
--- /dev/null
+++ b/netwerk/test/mochitests/file_documentcookie_maxage_chromescript.js
@@ -0,0 +1,45 @@
+/* eslint-env mozilla/chrome-script */
+
+"use strict";
+
+function getCookieService() {
+ // eslint-disable-next-line mozilla/use-services
+ return Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager);
+}
+
+function getCookies(cs) {
+ let cookies = [];
+ for (let cookie of cs.cookies) {
+ cookies.push({
+ host: cookie.host,
+ path: cookie.path,
+ name: cookie.name,
+ value: cookie.value,
+ expires: cookie.expires,
+ });
+ }
+ return cookies;
+}
+
+function removeAllCookies(cs) {
+ cs.removeAll();
+}
+
+addMessageListener("init", _ => {
+ let cs = getCookieService();
+ removeAllCookies(cs);
+ sendAsyncMessage("init:return");
+});
+
+addMessageListener("getCookies", _ => {
+ let cs = getCookieService();
+ let cookies = getCookies(cs);
+ removeAllCookies(cs);
+ sendAsyncMessage("getCookies:return", { cookies });
+});
+
+addMessageListener("shutdown", _ => {
+ let cs = getCookieService();
+ removeAllCookies(cs);
+ sendAsyncMessage("shutdown:return");
+});
diff --git a/netwerk/test/mochitests/file_domain_hierarchy_inner.html b/netwerk/test/mochitests/file_domain_hierarchy_inner.html
new file mode 100644
index 0000000000..713432196f
--- /dev/null
+++ b/netwerk/test/mochitests/file_domain_hierarchy_inner.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <script type="text/javascript">
+ document.cookie = "can=has";
+
+ // send a message to our test document, to say we're done loading
+ window.opener.postMessage("message", "http://mochi.test:8888");
+ </script>
+<body>
+<iframe name="frame1" src="https://example.com/tests/netwerk/test/mochitests/file_domain_hierarchy_inner_inner.html"></iframe>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/file_domain_hierarchy_inner.html^headers^ b/netwerk/test/mochitests/file_domain_hierarchy_inner.html^headers^
new file mode 100644
index 0000000000..a56be562a4
--- /dev/null
+++ b/netwerk/test/mochitests/file_domain_hierarchy_inner.html^headers^
@@ -0,0 +1,4 @@
+Set-Cookie: meta=tag
+Cache-Control: no-cache, no-store, must-revalidate
+Pragma: no-cache
+Expires: 0
diff --git a/netwerk/test/mochitests/file_domain_hierarchy_inner_inner.html b/netwerk/test/mochitests/file_domain_hierarchy_inner_inner.html
new file mode 100644
index 0000000000..dfceac2c6c
--- /dev/null
+++ b/netwerk/test/mochitests/file_domain_hierarchy_inner_inner.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <script type="text/javascript">
+ document.cookie = "can2=has2";
+
+ // send a message to our test document, to say we're done loading
+ window.parent.opener.postMessage("message", "http://mochi.test:8888");
+ </script>
+<body>
+<iframe name="frame1" src="https://example.org/tests/netwerk/test/mochitests/file_domain_hierarchy_inner_inner_inner.html"></iframe>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/file_domain_hierarchy_inner_inner.html^headers^ b/netwerk/test/mochitests/file_domain_hierarchy_inner_inner.html^headers^
new file mode 100644
index 0000000000..1ab9133473
--- /dev/null
+++ b/netwerk/test/mochitests/file_domain_hierarchy_inner_inner.html^headers^
@@ -0,0 +1,4 @@
+Set-Cookie: meta2=tag2
+Cache-Control: no-cache, no-store, must-revalidate
+Pragma: no-cache
+Expires: 0
diff --git a/netwerk/test/mochitests/file_domain_hierarchy_inner_inner_inner.html b/netwerk/test/mochitests/file_domain_hierarchy_inner_inner_inner.html
new file mode 100644
index 0000000000..d306efb1c0
--- /dev/null
+++ b/netwerk/test/mochitests/file_domain_hierarchy_inner_inner_inner.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <script type="text/javascript">
+ document.cookie = "can3=has3";
+
+ // send a message to our test document, to say we're done loading
+ window.parent.parent.opener.postMessage("message", "http://mochi.test:8888");
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/file_domain_hierarchy_inner_inner_inner.html^headers^ b/netwerk/test/mochitests/file_domain_hierarchy_inner_inner_inner.html^headers^
new file mode 100644
index 0000000000..add3336ec9
--- /dev/null
+++ b/netwerk/test/mochitests/file_domain_hierarchy_inner_inner_inner.html^headers^
@@ -0,0 +1 @@
+Set-Cookie: meta3=tag3
diff --git a/netwerk/test/mochitests/file_domain_inner.html b/netwerk/test/mochitests/file_domain_inner.html
new file mode 100644
index 0000000000..30a0821980
--- /dev/null
+++ b/netwerk/test/mochitests/file_domain_inner.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <script type="text/javascript">
+ document.cookie = "can=has";
+
+ // send a message to our test document, to say we're done loading
+ window.opener.postMessage("message", "http://mochi.test:8888");
+ </script>
+<body>
+<iframe name="frame1" src="https://example.org/tests/netwerk/test/mochitests/file_domain_inner_inner.html"></iframe>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/file_domain_inner.html^headers^ b/netwerk/test/mochitests/file_domain_inner.html^headers^
new file mode 100644
index 0000000000..a56be562a4
--- /dev/null
+++ b/netwerk/test/mochitests/file_domain_inner.html^headers^
@@ -0,0 +1,4 @@
+Set-Cookie: meta=tag
+Cache-Control: no-cache, no-store, must-revalidate
+Pragma: no-cache
+Expires: 0
diff --git a/netwerk/test/mochitests/file_domain_inner_inner.html b/netwerk/test/mochitests/file_domain_inner_inner.html
new file mode 100644
index 0000000000..5850e3fa0f
--- /dev/null
+++ b/netwerk/test/mochitests/file_domain_inner_inner.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <script type="text/javascript">
+ document.cookie = "can2=has2";
+
+ // send a message to our test document, to say we're done loading
+ window.parent.opener.postMessage("message", "http://mochi.test:8888");
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/file_domain_inner_inner.html^headers^ b/netwerk/test/mochitests/file_domain_inner_inner.html^headers^
new file mode 100644
index 0000000000..1ab9133473
--- /dev/null
+++ b/netwerk/test/mochitests/file_domain_inner_inner.html^headers^
@@ -0,0 +1,4 @@
+Set-Cookie: meta2=tag2
+Cache-Control: no-cache, no-store, must-revalidate
+Pragma: no-cache
+Expires: 0
diff --git a/netwerk/test/mochitests/file_iframe_allow_same_origin.html b/netwerk/test/mochitests/file_iframe_allow_same_origin.html
new file mode 100644
index 0000000000..c34187bb0a
--- /dev/null
+++ b/netwerk/test/mochitests/file_iframe_allow_same_origin.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html>
+<script>
+document.cookie = "if2_1=if2_val1";
+document.cookie = "if2_2=if2_val2";
+window.parent.postMessage(document.cookie, "*");
+</script>
+</html>
diff --git a/netwerk/test/mochitests/file_iframe_allow_scripts.html b/netwerk/test/mochitests/file_iframe_allow_scripts.html
new file mode 100644
index 0000000000..01504841a1
--- /dev/null
+++ b/netwerk/test/mochitests/file_iframe_allow_scripts.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+<script>
+document.cookie = "if1=if1_val";
+</script>
+</html>
diff --git a/netwerk/test/mochitests/file_image_inner.html b/netwerk/test/mochitests/file_image_inner.html
new file mode 100644
index 0000000000..6daf7224da
--- /dev/null
+++ b/netwerk/test/mochitests/file_image_inner.html
@@ -0,0 +1,14 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <script type="text/javascript">
+ document.cookie = "can=has";
+
+ // send a message to our test document, to say we're done loading
+ window.opener.postMessage("message", "http://mochi.test:8888");
+ </script>
+</head>
+<body>
+<iframe name="frame1" src="https://example.org/tests/netwerk/test/mochitests/file_image_inner_inner.html"></iframe>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/file_image_inner.html^headers^ b/netwerk/test/mochitests/file_image_inner.html^headers^
new file mode 100644
index 0000000000..a56be562a4
--- /dev/null
+++ b/netwerk/test/mochitests/file_image_inner.html^headers^
@@ -0,0 +1,4 @@
+Set-Cookie: meta=tag
+Cache-Control: no-cache, no-store, must-revalidate
+Pragma: no-cache
+Expires: 0
diff --git a/netwerk/test/mochitests/file_image_inner_inner.html b/netwerk/test/mochitests/file_image_inner_inner.html
new file mode 100644
index 0000000000..1e605f1a25
--- /dev/null
+++ b/netwerk/test/mochitests/file_image_inner_inner.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <link rel="stylesheet" type="text/css" media="all" href="https://example.org/tests/netwerk/test/mochitests/test1.css" />
+ <link rel="stylesheet" type="text/css" media="all" href="https://example.com/tests/netwerk/test/mochitests/test2.css" />
+ <script type="text/javascript">
+ function runTest() {
+ document.cookie = "can2=has2";
+
+ // send a message to our test document, to say we're done loading
+ window.parent.opener.postMessage("message", "http://mochi.test:8888");
+ }
+ </script>
+</head>
+<body>
+<img src="https://example.org/tests/netwerk/test/mochitests/image1.png" onload="runTest()" />
+<img src="https://example.com/tests/netwerk/test/mochitests/image2.png" onload="runTest()" />
+</body>
+</html>
diff --git a/netwerk/test/mochitests/file_image_inner_inner.html^headers^ b/netwerk/test/mochitests/file_image_inner_inner.html^headers^
new file mode 100644
index 0000000000..1ab9133473
--- /dev/null
+++ b/netwerk/test/mochitests/file_image_inner_inner.html^headers^
@@ -0,0 +1,4 @@
+Set-Cookie: meta2=tag2
+Cache-Control: no-cache, no-store, must-revalidate
+Pragma: no-cache
+Expires: 0
diff --git a/netwerk/test/mochitests/file_lnk.lnk b/netwerk/test/mochitests/file_lnk.lnk
new file mode 100644
index 0000000000..abce7587d2
--- /dev/null
+++ b/netwerk/test/mochitests/file_lnk.lnk
Binary files differ
diff --git a/netwerk/test/mochitests/file_loadflags_inner.html b/netwerk/test/mochitests/file_loadflags_inner.html
new file mode 100644
index 0000000000..5fc7e8d913
--- /dev/null
+++ b/netwerk/test/mochitests/file_loadflags_inner.html
@@ -0,0 +1,16 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <script type="text/javascript">
+ function runTest() {
+ document.cookie = "can=has";
+
+ // send a message to our test document, to say we're done loading
+ window.opener.postMessage("f_lf_i msg data img", "http://mochi.test:8888");
+ }
+ </script>
+</head>
+<body onload="window.opener.postMessage('f_lf_i msg data page', 'http://mochi.test:8888');">
+<img src="http://example.org/tests/netwerk/test/mochitests/beltzner.jpg" onload="runTest()" />
+</body>
+</html>
diff --git a/netwerk/test/mochitests/file_loadflags_inner.html^headers^ b/netwerk/test/mochitests/file_loadflags_inner.html^headers^
new file mode 100644
index 0000000000..a56be562a4
--- /dev/null
+++ b/netwerk/test/mochitests/file_loadflags_inner.html^headers^
@@ -0,0 +1,4 @@
+Set-Cookie: meta=tag
+Cache-Control: no-cache, no-store, must-revalidate
+Pragma: no-cache
+Expires: 0
diff --git a/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs b/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs
new file mode 100644
index 0000000000..0c89f7d538
--- /dev/null
+++ b/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs
@@ -0,0 +1,109 @@
+/*
+ * Redirect handler specifically for the needs of:
+ * Bug 1194052 - Append Principal to RedirectChain within LoadInfo before the channel is succesfully openend
+ */
+
+function createIframeContent(aQuery) {
+ var content = `
+ <!DOCTYPE HTML>
+ <html>
+ <head><meta charset="utf-8">
+ <title>Bug 1194052 - LoadInfo redirect chain subtest</title>
+ </head>
+ <body>
+ <script type="text/javascript">
+ var myXHR = new XMLHttpRequest();
+ myXHR.open("GET", "http://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?${aQuery}");
+ myXHR.onload = function() {
+ var loadinfo = SpecialPowers.wrap(myXHR).channel.loadInfo;
+ var redirectChain = loadinfo.redirectChain;
+ var redirectChainIncludingInternalRedirects = loadinfo.redirectChainIncludingInternalRedirects;
+ var resultOBJ = { redirectChain : [], redirectChainIncludingInternalRedirects : [] };
+ for (var i = 0; i < redirectChain.length; i++) {
+ resultOBJ.redirectChain.push(redirectChain[i].principal.spec);
+ }
+ for (var i = 0; i < redirectChainIncludingInternalRedirects.length; i++) {
+ resultOBJ.redirectChainIncludingInternalRedirects.push(redirectChainIncludingInternalRedirects[i].principal.spec);
+ }
+ var loadinfoJSON = JSON.stringify(resultOBJ);
+ window.parent.postMessage({ loadinfo: loadinfoJSON }, "*");
+ }
+ myXHR.onerror = function() {
+ var resultOBJ = { redirectChain : [], redirectChainIncludingInternalRedirects : [] };
+ var loadinfoJSON = JSON.stringify(resultOBJ);
+ window.parent.postMessage({ loadinfo: loadinfoJSON }, "*");
+ }
+ myXHR.send();
+ </script>
+ </body>
+ </html>`;
+
+ return content;
+}
+
+function handleRequest(request, response) {
+ response.setHeader("Cache-Control", "no-cache", false);
+ var queryString = request.queryString;
+
+ if (
+ queryString == "iframe-redir-https-2" ||
+ queryString == "iframe-redir-err-2"
+ ) {
+ var query = queryString.replace("iframe-", "");
+ // send upgrade-insecure-requests CSP header
+ response.setHeader("Content-Type", "text/html", false);
+ response.setHeader(
+ "Content-Security-Policy",
+ "upgrade-insecure-requests",
+ false
+ );
+ response.write(createIframeContent(query));
+ return;
+ }
+
+ // at the end of the redirectchain we return some text
+ // for sanity checking
+ if (queryString == "redir-0" || queryString == "redir-https-0") {
+ response.setHeader("Content-Type", "text/html", false);
+ response.write("checking redirectchain");
+ return;
+ }
+
+ // special case redir-err-1 and return an error to trigger the fallback
+ if (queryString == "redir-err-1") {
+ response.setStatusLine("1.1", 404, "Bad request");
+ return;
+ }
+
+ // must be a redirect
+ var newLocation = "";
+ switch (queryString) {
+ case "redir-err-2":
+ newLocation =
+ "http://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-err-1";
+ break;
+
+ case "redir-https-2":
+ newLocation =
+ "http://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-https-1";
+ break;
+
+ case "redir-https-1":
+ newLocation =
+ "http://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-https-0";
+ break;
+
+ case "redir-2":
+ newLocation =
+ "http://mochi.test:8888/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-1";
+ break;
+
+ case "redir-1":
+ newLocation =
+ "http://mochi.test:8888/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-0";
+ break;
+ }
+
+ response.setStatusLine("1.1", 302, "Found");
+ response.setHeader("Location", newLocation, false);
+}
diff --git a/netwerk/test/mochitests/file_localhost_inner.html b/netwerk/test/mochitests/file_localhost_inner.html
new file mode 100644
index 0000000000..d291370a47
--- /dev/null
+++ b/netwerk/test/mochitests/file_localhost_inner.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <script type="text/javascript">
+ document.cookie = "can=has";
+
+ // send a message to our test document, to say we're done loading
+ window.opener.postMessage("message", "http://mochi.test:8888");
+ </script>
+<body>
+<iframe name="frame1" src="http://mochi.test:8888/tests/netwerk/test/mochitests/file_domain_inner_inner.html"></iframe>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/file_localhost_inner.html^headers^ b/netwerk/test/mochitests/file_localhost_inner.html^headers^
new file mode 100644
index 0000000000..a56be562a4
--- /dev/null
+++ b/netwerk/test/mochitests/file_localhost_inner.html^headers^
@@ -0,0 +1,4 @@
+Set-Cookie: meta=tag
+Cache-Control: no-cache, no-store, must-revalidate
+Pragma: no-cache
+Expires: 0
diff --git a/netwerk/test/mochitests/file_loopback_inner.html b/netwerk/test/mochitests/file_loopback_inner.html
new file mode 100644
index 0000000000..91aa1d89c5
--- /dev/null
+++ b/netwerk/test/mochitests/file_loopback_inner.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <script type="text/javascript">
+ document.cookie = "can=has";
+
+ // send a message to our test document, to say we're done loading
+ window.opener.postMessage("message", "http://mochi.test:8888");
+ </script>
+<body>
+<iframe name="frame1" src="http://127.0.0.1:8888/tests/netwerk/test/mochitests/file_domain_inner_inner.html"></iframe>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/file_loopback_inner.html^headers^ b/netwerk/test/mochitests/file_loopback_inner.html^headers^
new file mode 100644
index 0000000000..a56be562a4
--- /dev/null
+++ b/netwerk/test/mochitests/file_loopback_inner.html^headers^
@@ -0,0 +1,4 @@
+Set-Cookie: meta=tag
+Cache-Control: no-cache, no-store, must-revalidate
+Pragma: no-cache
+Expires: 0
diff --git a/netwerk/test/mochitests/file_subdomain_inner.html b/netwerk/test/mochitests/file_subdomain_inner.html
new file mode 100644
index 0000000000..a48f36a7de
--- /dev/null
+++ b/netwerk/test/mochitests/file_subdomain_inner.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <script type="text/javascript">
+ document.cookie = "can=has";
+
+ // send a message to our test document, to say we're done loading
+ window.opener.postMessage("message", "http://mochi.test:8888");
+ </script>
+<body>
+<iframe name="frame1" src="https://test2.example.org/tests/netwerk/test/mochitests/file_domain_inner_inner.html"></iframe>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/file_subdomain_inner.html^headers^ b/netwerk/test/mochitests/file_subdomain_inner.html^headers^
new file mode 100644
index 0000000000..a56be562a4
--- /dev/null
+++ b/netwerk/test/mochitests/file_subdomain_inner.html^headers^
@@ -0,0 +1,4 @@
+Set-Cookie: meta=tag
+Cache-Control: no-cache, no-store, must-revalidate
+Pragma: no-cache
+Expires: 0
diff --git a/netwerk/test/mochitests/file_testcommon.js b/netwerk/test/mochitests/file_testcommon.js
new file mode 100644
index 0000000000..4a9b0504e9
--- /dev/null
+++ b/netwerk/test/mochitests/file_testcommon.js
@@ -0,0 +1,84 @@
+"use strict";
+
+const SCRIPT_URL = SimpleTest.getTestFileURL("file_chromecommon.js");
+
+var gExpectedCookies;
+var gExpectedLoads;
+
+var gPopup;
+
+var gScript;
+
+var gLoads = 0;
+
+function setupTest(uri, cookies, loads) {
+ SimpleTest.waitForExplicitFinish();
+
+ var prefSet = new Promise(resolve => {
+ SpecialPowers.pushPrefEnv(
+ {
+ set: [
+ ["network.cookie.cookieBehavior", 1],
+ // cookieBehavior 1 allows cookies from chrome script if we enable
+ // exceptions.
+ // Bug 1617611: Fix all the tests broken by "cookies SameSite=lax by default"
+ ["network.cookie.sameSite.laxByDefault", false],
+ ],
+ },
+ resolve
+ );
+ });
+
+ gScript = SpecialPowers.loadChromeScript(SCRIPT_URL);
+ gExpectedCookies = cookies;
+ gExpectedLoads = loads;
+
+ // Listen for MessageEvents.
+ window.addEventListener("message", messageReceiver);
+
+ prefSet.then(() => {
+ // load a window which contains an iframe; each will attempt to set
+ // cookies from their respective domains.
+ gPopup = window.open(uri, "hai", "width=100,height=100");
+ });
+}
+
+function finishTest() {
+ gScript.destroy();
+ SpecialPowers.clearUserPref("network.cookie.sameSite.laxByDefault");
+ SimpleTest.finish();
+}
+
+/** Receives MessageEvents to this window. */
+// Count and check loads.
+function messageReceiver(evt) {
+ is(evt.data, "message", "message data received from popup");
+ if (evt.data != "message") {
+ gPopup.close();
+ window.removeEventListener("message", messageReceiver);
+
+ finishTest();
+ return;
+ }
+
+ // only run the test when all our children are done loading & setting cookies
+ if (++gLoads == gExpectedLoads) {
+ gPopup.close();
+ window.removeEventListener("message", messageReceiver);
+
+ runTest();
+ }
+}
+
+// runTest() is run by messageReceiver().
+// Count and check cookies.
+function runTest() {
+ // set a cookie from a domain of "localhost"
+ document.cookie = "oh=hai";
+
+ gScript.addMessageListener("getCookieCountAndClear:return", ({ count }) => {
+ is(count, gExpectedCookies, "total number of cookies");
+ finishTest();
+ });
+ gScript.sendAsyncMessage("getCookieCountAndClear");
+}
diff --git a/netwerk/test/mochitests/file_testloadflags.js b/netwerk/test/mochitests/file_testloadflags.js
new file mode 100644
index 0000000000..54374b8b8d
--- /dev/null
+++ b/netwerk/test/mochitests/file_testloadflags.js
@@ -0,0 +1,130 @@
+"use strict";
+
+const SCRIPT_URL = SimpleTest.getTestFileURL(
+ "file_testloadflags_chromescript.js"
+);
+
+let gScript;
+var gExpectedCookies;
+var gExpectedHeaders;
+var gExpectedLoads;
+
+var gObs;
+var gPopup;
+
+var gHeaders = 0;
+var gLoads = 0;
+
+// setupTest() is run from 'onload='.
+function setupTest(iframeUri, domain, cookies, loads, headers) {
+ info(
+ "setupTest uri: " +
+ iframeUri +
+ " domain: " +
+ domain +
+ " cookies: " +
+ cookies +
+ " loads: " +
+ loads +
+ " headers: " +
+ headers
+ );
+
+ SimpleTest.waitForExplicitFinish();
+
+ var prefSet = new Promise(resolve => {
+ SpecialPowers.pushPrefEnv(
+ {
+ set: [
+ ["network.cookie.cookieBehavior", 1],
+ ["network.cookie.sameSite.schemeful", false],
+ ],
+ },
+ resolve
+ );
+ });
+
+ gExpectedCookies = cookies;
+ gExpectedLoads = loads;
+ gExpectedHeaders = headers;
+
+ gScript = SpecialPowers.loadChromeScript(SCRIPT_URL);
+ gScript.addMessageListener("info", ({ str }) => info(str));
+ gScript.addMessageListener("ok", ({ c, m }) => ok(c, m));
+ gScript.addMessageListener("observer:gotCookie", ({ cookie, uri }) => {
+ isnot(
+ cookie.indexOf("oh=hai"),
+ -1,
+ "cookie 'oh=hai' is in header for " + uri
+ );
+ ++gHeaders;
+ });
+
+ var scriptReady = new Promise(resolve => {
+ gScript.addMessageListener("init:return", resolve);
+ gScript.sendAsyncMessage("init", { domain });
+ });
+
+ // Listen for MessageEvents.
+ window.addEventListener("message", messageReceiver);
+
+ Promise.all([prefSet, scriptReady]).then(() => {
+ // load a window which contains an iframe; each will attempt to set
+ // cookies from their respective domains.
+ gPopup = window.open(iframeUri, "hai", "width=100,height=100");
+ });
+}
+
+function finishTest() {
+ gScript.addMessageListener("shutdown:return", () => {
+ gScript.destroy();
+ SimpleTest.finish();
+ });
+ gScript.sendAsyncMessage("shutdown");
+}
+
+/** Receives MessageEvents to this window. */
+// Count and check loads.
+function messageReceiver(evt) {
+ ok(
+ evt.data == "f_lf_i msg data img" || evt.data == "f_lf_i msg data page",
+ "message data received from popup"
+ );
+ if (evt.data == "f_lf_i msg data img") {
+ info("message data received from popup for image");
+ }
+ if (evt.data == "f_lf_i msg data page") {
+ info("message data received from popup for page");
+ }
+ if (evt.data != "f_lf_i msg data img" && evt.data != "f_lf_i msg data page") {
+ info("got this message but don't know what it is " + evt.data);
+ gPopup.close();
+ window.removeEventListener("message", messageReceiver);
+
+ finishTest();
+ return;
+ }
+
+ // only run the test when all our children are done loading & setting cookies
+ if (++gLoads == gExpectedLoads) {
+ gPopup.close();
+ window.removeEventListener("message", messageReceiver);
+
+ runTest();
+ }
+}
+
+// runTest() is run by messageReceiver().
+// Check headers, and count and check cookies.
+function runTest() {
+ // set a cookie from a domain of "localhost"
+ document.cookie = "o=noes";
+
+ is(gHeaders, gExpectedHeaders, "number of observed request headers");
+ gScript.addMessageListener("getCookieCount:return", ({ count }) => {
+ is(count, gExpectedCookies, "total number of cookies");
+ finishTest();
+ });
+
+ gScript.sendAsyncMessage("getCookieCount");
+}
diff --git a/netwerk/test/mochitests/file_testloadflags_chromescript.js b/netwerk/test/mochitests/file_testloadflags_chromescript.js
new file mode 100644
index 0000000000..a74920d2c2
--- /dev/null
+++ b/netwerk/test/mochitests/file_testloadflags_chromescript.js
@@ -0,0 +1,144 @@
+/* eslint-env mozilla/chrome-script */
+/* eslint-disable mozilla/use-services */
+
+"use strict";
+
+var gObs;
+
+function info(s) {
+ sendAsyncMessage("info", { str: String(s) });
+}
+
+function ok(c, m) {
+ sendAsyncMessage("ok", { c, m });
+}
+
+function is(a, b, m) {
+ ok(Object.is(a, b), m + " (" + a + " === " + b + ")");
+}
+
+// Count headers.
+function obs() {
+ info("adding observer");
+
+ this.os = Cc["@mozilla.org/observer-service;1"].getService(
+ Ci.nsIObserverService
+ );
+ this.os.addObserver(this, "http-on-modify-request");
+}
+
+obs.prototype = {
+ observe(theSubject, theTopic, theData) {
+ info("theSubject " + theSubject);
+ info("theTopic " + theTopic);
+ info("theData " + theData);
+
+ var channel = theSubject.QueryInterface(Ci.nsIHttpChannel);
+ info("channel " + channel);
+ try {
+ info("channel.URI " + channel.URI);
+ info("channel.URI.spec " + channel.URI.spec);
+ channel.visitRequestHeaders({
+ visitHeader(aHeader, aValue) {
+ info(aHeader + ": " + aValue);
+ },
+ });
+ } catch (err) {
+ ok(false, "catch error " + err);
+ }
+
+ // Ignore notifications we don't care about (like favicons)
+ if (
+ !channel.URI.spec.includes(
+ "http://example.org/tests/netwerk/test/mochitests/"
+ )
+ ) {
+ info("ignoring this one");
+ return;
+ }
+
+ sendAsyncMessage("observer:gotCookie", {
+ cookie: channel.getRequestHeader("Cookie"),
+ uri: channel.URI.spec,
+ });
+ },
+
+ remove() {
+ info("removing observer");
+
+ this.os.removeObserver(this, "http-on-modify-request");
+ this.os = null;
+ },
+};
+
+function getCookieCount(cs) {
+ let count = 0;
+ for (let cookie of cs.cookies) {
+ info("cookie: " + cookie);
+ info(
+ "cookie host " +
+ cookie.host +
+ " path " +
+ cookie.path +
+ " name " +
+ cookie.name +
+ " value " +
+ cookie.value +
+ " isSecure " +
+ cookie.isSecure +
+ " expires " +
+ cookie.expires
+ );
+ ++count;
+ }
+
+ return count;
+}
+
+addMessageListener("init", ({ domain }) => {
+ let cs = Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager);
+
+ info("we are going to remove these cookies");
+
+ let count = getCookieCount(cs);
+ info(count + " cookies");
+
+ cs.removeAll();
+ cs.add(
+ domain,
+ "/",
+ "oh",
+ "hai",
+ false,
+ false,
+ true,
+ Math.pow(2, 62),
+ {},
+ Ci.nsICookie.SAMESITE_NONE,
+ Ci.nsICookie.SCHEME_HTTPS
+ );
+ is(
+ cs.countCookiesFromHost(domain),
+ 1,
+ "number of cookies for domain " + domain
+ );
+
+ gObs = new obs();
+ sendAsyncMessage("init:return");
+});
+
+addMessageListener("getCookieCount", () => {
+ let cs = Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager);
+ let count = getCookieCount(cs);
+
+ cs.removeAll();
+ sendAsyncMessage("getCookieCount:return", { count });
+});
+
+addMessageListener("shutdown", () => {
+ gObs.remove();
+
+ let cs = Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager);
+ cs.removeAll();
+ sendAsyncMessage("shutdown:return");
+});
diff --git a/netwerk/test/mochitests/iframe_1502055.html b/netwerk/test/mochitests/iframe_1502055.html
new file mode 100644
index 0000000000..7f3e915978
--- /dev/null
+++ b/netwerk/test/mochitests/iframe_1502055.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML>
+<html>
+<body>
+<script type="application/javascript">
+
+function info(msg) {
+ parent.postMessage({type: "info", msg }, "*");
+}
+
+let registration;
+
+info("Registering a ServiceWorker");
+navigator.serviceWorker.register('sw_1502055.js', {scope: "foo/"})
+.then(reg => {
+ registration = reg;
+ info("Fetching a resource");
+ return fetch("file_1502055.sjs")
+}).then(r => r.text())
+.then(() => {
+ info("Fetching a resource, again");
+ return fetch("file_1502055.sjs")
+}).then(r => r.text()).then(() => {
+ info("Unregistering the ServiceWorker");
+ return registration.unregister();
+})
+.then(() => {
+ parent.postMessage({ type: "finish" }, "*");
+});
+
+</script>
+
+</body>
+</html>
diff --git a/netwerk/test/mochitests/image1.png b/netwerk/test/mochitests/image1.png
new file mode 100644
index 0000000000..272d67c0ce
--- /dev/null
+++ b/netwerk/test/mochitests/image1.png
Binary files differ
diff --git a/netwerk/test/mochitests/image1.png^headers^ b/netwerk/test/mochitests/image1.png^headers^
new file mode 100644
index 0000000000..2390289e01
--- /dev/null
+++ b/netwerk/test/mochitests/image1.png^headers^
@@ -0,0 +1,3 @@
+Cache-Control: no-store
+Set-Cookie: foo=bar
+
diff --git a/netwerk/test/mochitests/image2.png b/netwerk/test/mochitests/image2.png
new file mode 100644
index 0000000000..272d67c0ce
--- /dev/null
+++ b/netwerk/test/mochitests/image2.png
Binary files differ
diff --git a/netwerk/test/mochitests/image2.png^headers^ b/netwerk/test/mochitests/image2.png^headers^
new file mode 100644
index 0000000000..6c0eea5ab6
--- /dev/null
+++ b/netwerk/test/mochitests/image2.png^headers^
@@ -0,0 +1,3 @@
+Cache-Control: no-store
+Set-Cookie: foo2=bar2
+
diff --git a/netwerk/test/mochitests/method.sjs b/netwerk/test/mochitests/method.sjs
new file mode 100644
index 0000000000..f29b20aa00
--- /dev/null
+++ b/netwerk/test/mochitests/method.sjs
@@ -0,0 +1,9 @@
+function handleRequest(request, response) {
+ // avoid confusing cache behaviors
+ response.setHeader("Cache-Control", "no-cache", false);
+ response.setHeader("Content-Type", "text/plain", false);
+ response.setHeader("Access-Control-Allow-Origin", "*", false);
+
+ // echo method
+ response.write(request.method);
+}
diff --git a/netwerk/test/mochitests/mochitest.toml b/netwerk/test/mochitests/mochitest.toml
new file mode 100644
index 0000000000..8d5cb8ff92
--- /dev/null
+++ b/netwerk/test/mochitests/mochitest.toml
@@ -0,0 +1,217 @@
+[DEFAULT]
+support-files = [
+ "method.sjs",
+ "partial_content.sjs",
+ "rel_preconnect.sjs",
+ "set_cookie_xhr.sjs",
+ "reset_cookie_xhr.sjs",
+ "web_packaged_app.sjs",
+ "file_documentcookie_maxage_chromescript.js",
+ "file_loadinfo_redirectchain.sjs",
+ "file_1331680.js",
+ "file_1503201.sjs",
+ "file_iframe_allow_scripts.html",
+ "file_iframe_allow_same_origin.html",
+ "redirect_idn.html^headers^",
+ "redirect_idn.html",
+ "empty.html",
+ "redirect.sjs",
+ "redirect_to.sjs",
+ "origin_header.sjs",
+ "origin_header_form_post.html",
+ "origin_header_form_post_xorigin.html",
+ "subResources.sjs",
+ "beltzner.jpg",
+ "beltzner.jpg^headers^",
+ "file_chromecommon.js",
+ "file_domain_hierarchy_inner.html",
+ "file_domain_hierarchy_inner.html^headers^",
+ "file_domain_hierarchy_inner_inner.html",
+ "file_domain_hierarchy_inner_inner.html^headers^",
+ "file_domain_hierarchy_inner_inner_inner.html",
+ "file_domain_hierarchy_inner_inner_inner.html^headers^",
+ "file_domain_inner.html",
+ "file_domain_inner.html^headers^",
+ "file_domain_inner_inner.html",
+ "file_domain_inner_inner.html^headers^",
+ "file_image_inner.html",
+ "file_image_inner.html^headers^",
+ "file_image_inner_inner.html",
+ "file_image_inner_inner.html^headers^",
+ "file_lnk.lnk",
+ "file_loadflags_inner.html",
+ "file_loadflags_inner.html^headers^",
+ "file_localhost_inner.html",
+ "file_localhost_inner.html^headers^",
+ "file_loopback_inner.html",
+ "file_loopback_inner.html^headers^",
+ "file_subdomain_inner.html",
+ "file_subdomain_inner.html^headers^",
+ "file_testcommon.js",
+ "file_testloadflags.js",
+ "file_testloadflags_chromescript.js",
+ "image1.png",
+ "image1.png^headers^",
+ "image2.png",
+ "image2.png^headers^",
+ "test1.css",
+ "test1.css^headers^",
+ "test2.css",
+ "test2.css^headers^",
+]
+prefs = ["javascript.options.large_arraybuffers=true"]
+
+["test_1331680.html"]
+
+["test_1331680_iframe.html"]
+
+["test_1331680_xhr.html"]
+skip-if = ["verify"]
+
+["test_1396395.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_1421324.html"]
+
+["test_1425031.html"]
+
+["test_1502055.html"]
+support-files = [
+ "sw_1502055.js",
+ "file_1502055.sjs",
+ "iframe_1502055.html",
+]
+
+["test_1503201.html"]
+
+["test_accept_header.html"]
+support-files = ["test_accept_header.sjs"]
+
+["test_arraybufferinputstream.html"]
+
+["test_arraybufferinputstream_large.html"]
+# Large ArrayBuffers not supported on 32-bit. TSan shadow memory causes OOMs.
+skip-if = [
+ "win11_2009 && bits == 32",
+ "tsan",
+ "asan",
+]
+
+["test_different_domain_in_hierarchy.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_differentdomain.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_documentcookies_maxage.html"]
+# Bug 1617611: Fix all the tests broken by "cookies SameSite=lax by default"
+skip-if = ["xorigin"]
+
+["test_fetch_lnk.html"]
+
+["test_idn_redirect.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_image.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_loadflags.html"]
+# Bug 1617611: Fix all the tests broken by "cookies SameSite=lax by default"
+skip-if = [
+ "xorigin",
+ "http3",
+ "http2",
+]
+
+["test_loadinfo_redirectchain.html"]
+fail-if = ["xorigin"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_origin_header.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_partially_cached_content.html"]
+
+["test_redirect_ref.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_rel_preconnect.html"]
+
+["test_same_base_domain.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_same_base_domain_2.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_same_base_domain_3.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_same_base_domain_4.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_same_base_domain_5.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_same_base_domain_6.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_samedomain.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_uri_scheme.html"]
+skip-if = ["verify && debug && os == 'mac'"]
+
+["test_url_perf.html"]
+# test to check the performance of URL parsing.
+# No need to run in CI.
+skip-if = ["true"]
+
+["test_viewsource_unlinkable.html"]
+
+["test_xhr_method_case.html"]
+skip-if = ["http2"]
diff --git a/netwerk/test/mochitests/origin_header.sjs b/netwerk/test/mochitests/origin_header.sjs
new file mode 100644
index 0000000000..72cc4b2ae6
--- /dev/null
+++ b/netwerk/test/mochitests/origin_header.sjs
@@ -0,0 +1,10 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function handleRequest(request, response) {
+ response.setHeader("Content-Type", "text/plain", false);
+ response.setHeader("Cache-Control", "no-cache", false);
+
+ var origin = request.hasHeader("Origin") ? request.getHeader("Origin") : "";
+ response.write("Origin: " + origin);
+}
diff --git a/netwerk/test/mochitests/origin_header_form_post.html b/netwerk/test/mochitests/origin_header_form_post.html
new file mode 100644
index 0000000000..01c2df5ef2
--- /dev/null
+++ b/netwerk/test/mochitests/origin_header_form_post.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<html>
+<head>
+ <script>
+ function submitForm() {
+ document.getElementById("form").submit();
+ }
+ </script>
+</head>
+<body onload="submitForm()">
+ <form action="http://Mochi.test:8888/tests/netwerk/test/mochitests/origin_header.sjs"
+ method="POST"
+ id="form">
+ <input type="submit" value="Submit POST">
+ </form>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/origin_header_form_post_xorigin.html b/netwerk/test/mochitests/origin_header_form_post_xorigin.html
new file mode 100644
index 0000000000..52e173747b
--- /dev/null
+++ b/netwerk/test/mochitests/origin_header_form_post_xorigin.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<html>
+<head>
+ <script>
+ function submitForm() {
+ document.getElementById("form").submit();
+ }
+ </script>
+</head>
+<body onload="submitForm()">
+ <form action="http://test1.mochi.test:8888/tests/netwerk/test/mochitests/origin_header.sjs"
+ method="POST"
+ id="form">
+ <input type="submit" value="Submit POST">
+ </form>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/partial_content.sjs b/netwerk/test/mochitests/partial_content.sjs
new file mode 100644
index 0000000000..67bfff377a
--- /dev/null
+++ b/netwerk/test/mochitests/partial_content.sjs
@@ -0,0 +1,193 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* Debug and Error wrapper functions for dump().
+ */
+function ERR(response, responseCode, responseCodeStr, msg) {
+ // Reset state var.
+ setState("expectedRequestType", "");
+ // Dump to console log and send to client in response.
+ dump("SERVER ERROR: " + msg + "\n");
+ response.write("HTTP/1.1 " + responseCode + " " + responseCodeStr + "\r\n");
+ response.write("Content-Type: text/html; charset=UTF-8\r\n");
+ response.write("Content-Length: " + msg.length + "\r\n");
+ response.write("\r\n");
+ response.write(msg);
+}
+
+function DBG(msg) {
+ // Dump to console only.
+ dump("SERVER DEBUG: " + msg + "\n");
+}
+
+/* Delivers content in parts to test partially cached content: requires two
+ * requests for the same resource.
+ *
+ * First call will respond with partial content, but a 200 header and
+ * Content-Length equal to the full content length. No Range or If-Range
+ * headers are allowed in the request.
+ *
+ * Second call will require Range and If-Range in the request headers, and
+ * will respond with the range requested.
+ */
+function handleRequest(request, response) {
+ DBG("Trying to seize power");
+ response.seizePower();
+
+ DBG("About to check state vars");
+ // Get state var to determine if this is the first or second request.
+ var expectedRequestType;
+ var lastModified;
+ if (getState("expectedRequestType") === "") {
+ DBG("First call: Should be requesting full content.");
+ expectedRequestType = "fullRequest";
+ // Set state var for second request.
+ setState("expectedRequestType", "partialRequest");
+ // Create lastModified variable for responses.
+ lastModified = new Date().toUTCString();
+ setState("lastModified", lastModified);
+ } else if (getState("expectedRequestType") === "partialRequest") {
+ DBG("Second call: Should be requesting undelivered content.");
+ expectedRequestType = "partialRequest";
+ // Reset state var for first request.
+ setState("expectedRequestType", "");
+ // Get last modified date and reset state var.
+ lastModified = getState("lastModified");
+ } else {
+ ERR(
+ response,
+ 500,
+ "Internal Server Error",
+ 'Invalid expectedRequestType "' +
+ expectedRequestType +
+ '"in ' +
+ "server state db."
+ );
+ return;
+ }
+
+ // Look for Range and If-Range
+ var range = request.hasHeader("Range") ? request.getHeader("Range") : "";
+ var ifRange = request.hasHeader("If-Range")
+ ? request.getHeader("If-Range")
+ : "";
+
+ if (expectedRequestType === "fullRequest") {
+ // Should not have Range or If-Range in first request.
+ if (range && range.length) {
+ ERR(
+ response,
+ 400,
+ "Bad Request",
+ 'Should not receive "Range: ' + range + '" for first, full request.'
+ );
+ return;
+ }
+ if (ifRange && ifRange.length) {
+ ERR(
+ response,
+ 400,
+ "Bad Request",
+ 'Should not receive "Range: ' + range + '" for first, full request.'
+ );
+ return;
+ }
+ } else if (expectedRequestType === "partialRequest") {
+ // Range AND If-Range should both be present in second request.
+ if (!range) {
+ ERR(
+ response,
+ 400,
+ "Bad Request",
+ 'Should receive "Range: " for second, partial request.'
+ );
+ return;
+ }
+ if (!ifRange) {
+ ERR(
+ response,
+ 400,
+ "Bad Request",
+ 'Should receive "If-Range: " for second, partial request.'
+ );
+ return;
+ }
+ } else {
+ // Somewhat redundant, but a check for errors in this test code.
+ ERR(
+ response,
+ 500,
+ "Internal Server Error",
+ 'expectedRequestType not set correctly: "' + expectedRequestType + '"'
+ );
+ return;
+ }
+
+ // Prepare content in two parts for responses.
+ var partialContent =
+ '<html><head></head><body><p id="firstResponse">First response</p>';
+ var remainderContent =
+ '<p id="secondResponse">Second response</p></body></html>';
+ var totalLength = partialContent.length + remainderContent.length;
+
+ DBG("totalLength: " + totalLength);
+
+ // Prepare common headers for the two responses.
+ let date = new Date();
+ DBG("Date: " + date.toUTCString() + ", Last-Modified: " + lastModified);
+ var commonHeaders =
+ "Date: " +
+ date.toUTCString() +
+ "\r\n" +
+ "Last-Modified: " +
+ lastModified +
+ "\r\n" +
+ "Content-Type: text/html; charset=UTF-8\r\n" +
+ "ETag: abcd0123\r\n" +
+ "Accept-Ranges: bytes\r\n";
+
+ // Prepare specific headers and content for first and second responses.
+ if (expectedRequestType === "fullRequest") {
+ DBG("First response: Sending partial content with a full header");
+ response.write("HTTP/1.1 200 OK\r\n");
+ response.write(commonHeaders);
+ // Set Content-Length to full length of resource.
+ response.write("Content-Length: " + totalLength + "\r\n");
+ response.write("\r\n");
+ response.write(partialContent);
+ } else if (expectedRequestType === "partialRequest") {
+ DBG("Second response: Sending remaining content with a range header");
+ response.write("HTTP/1.1 206 Partial Content\r\n");
+ response.write(commonHeaders);
+ // Set Content-Length to length of bytes transmitted.
+ response.write("Content-Length: " + remainderContent.length + "\r\n");
+ response.write(
+ "Content-Range: bytes " +
+ partialContent.length +
+ "-" +
+ (totalLength - 1) +
+ "/" +
+ totalLength +
+ "\r\n"
+ );
+ response.write("\r\n");
+ response.write(remainderContent);
+ } else {
+ // Somewhat redundant, but a check for errors in this test code.
+ ERR(
+ response,
+ 500,
+ "Internal Server Error",
+ "Something very bad happened here: expectedRequestType is invalid " +
+ 'towards the end of handleRequest! - "' +
+ expectedRequestType +
+ '"'
+ );
+ return;
+ }
+
+ response.finish();
+}
diff --git a/netwerk/test/mochitests/redirect.sjs b/netwerk/test/mochitests/redirect.sjs
new file mode 100644
index 0000000000..73efea59cf
--- /dev/null
+++ b/netwerk/test/mochitests/redirect.sjs
@@ -0,0 +1,4 @@
+function handleRequest(request, response) {
+ response.setStatusLine(request.httpVersion, 301, "Moved Permanently");
+ response.setHeader("Location", "empty.html#");
+}
diff --git a/netwerk/test/mochitests/redirect_idn.html b/netwerk/test/mochitests/redirect_idn.html
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/netwerk/test/mochitests/redirect_idn.html
diff --git a/netwerk/test/mochitests/redirect_idn.html^headers^ b/netwerk/test/mochitests/redirect_idn.html^headers^
new file mode 100644
index 0000000000..753f65db87
--- /dev/null
+++ b/netwerk/test/mochitests/redirect_idn.html^headers^
@@ -0,0 +1,3 @@
+HTTP 301 Moved Permanently
+Location: http://exämple.test/tests/netwerk/test/mochitests/empty.html
+X-Comment: Bug 1142083 - This is a redirect to http://exämple.test
diff --git a/netwerk/test/mochitests/redirect_to.sjs b/netwerk/test/mochitests/redirect_to.sjs
new file mode 100644
index 0000000000..f090c70849
--- /dev/null
+++ b/netwerk/test/mochitests/redirect_to.sjs
@@ -0,0 +1,4 @@
+function handleRequest(request, response) {
+ response.setStatusLine(request.httpVersion, 308, "Permanent Redirect");
+ response.setHeader("Location", request.queryString);
+}
diff --git a/netwerk/test/mochitests/rel_preconnect.sjs b/netwerk/test/mochitests/rel_preconnect.sjs
new file mode 100644
index 0000000000..5423c877f0
--- /dev/null
+++ b/netwerk/test/mochitests/rel_preconnect.sjs
@@ -0,0 +1,17 @@
+// Generate response header "Link: <HREF>; rel=preconnect"
+// HREF is provided by the request header X-Link
+
+function handleRequest(request, response) {
+ response.setHeader("Cache-Control", "no-cache", false);
+ response.setHeader(
+ "Link",
+ "<" +
+ request.queryString +
+ ">; rel=preconnect" +
+ ", " +
+ "<" +
+ request.queryString +
+ ">; rel=preconnect; crossOrigin=anonymous"
+ );
+ response.write("check that header");
+}
diff --git a/netwerk/test/mochitests/reset_cookie_xhr.sjs b/netwerk/test/mochitests/reset_cookie_xhr.sjs
new file mode 100644
index 0000000000..3620958d29
--- /dev/null
+++ b/netwerk/test/mochitests/reset_cookie_xhr.sjs
@@ -0,0 +1,15 @@
+function handleRequest(request, response) {
+ var queryString = request.queryString;
+ switch (queryString) {
+ case "set_cookie":
+ response.setHeader("Set-Cookie", "testXHR1=xhr_val1; path=/", false);
+ break;
+ case "modify_cookie":
+ response.setHeader(
+ "Set-Cookie",
+ "testXHR1=xhr_val2; path=/; HttpOnly",
+ false
+ );
+ break;
+ }
+}
diff --git a/netwerk/test/mochitests/set_cookie_xhr.sjs b/netwerk/test/mochitests/set_cookie_xhr.sjs
new file mode 100644
index 0000000000..19855bfec9
--- /dev/null
+++ b/netwerk/test/mochitests/set_cookie_xhr.sjs
@@ -0,0 +1,15 @@
+function handleRequest(request, response) {
+ var queryString = request.queryString;
+ switch (queryString) {
+ case "xhr1":
+ response.setHeader("Set-Cookie", "xhr1=xhr_val1; path=/", false);
+ break;
+ case "xhr2":
+ response.setHeader(
+ "Set-Cookie",
+ "xhr2=xhr_val2; path=/; HttpOnly",
+ false
+ );
+ break;
+ }
+}
diff --git a/netwerk/test/mochitests/signed_web_packaged_app.sjs b/netwerk/test/mochitests/signed_web_packaged_app.sjs
new file mode 100644
index 0000000000..dc386ad6fe
--- /dev/null
+++ b/netwerk/test/mochitests/signed_web_packaged_app.sjs
@@ -0,0 +1,73 @@
+function handleRequest(request, response) {
+ response.setHeader("Content-Type", "application/package", false);
+ response.write(signedPackage);
+}
+
+// The package content
+// getData formats it as described at http://www.w3.org/TR/web-packaging/#streamable-package-format
+var signedPackage = `manifest-signature: MIIF1AYJKoZIhvcNAQcCoIIFxTCCBcECAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHAaCCA54wggOaMIICgqADAgECAgEEMA0GCSqGSIb3DQEBCwUAMHMxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEkMCIGA1UEChMbRXhhbXBsZSBUcnVzdGVkIENvcnBvcmF0aW9uMRkwFwYDVQQDExBUcnVzdGVkIFZhbGlkIENBMB4XDTE1MTExOTAzMDEwNVoXDTM1MTExOTAzMDEwNVowdDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MSQwIgYDVQQKExtFeGFtcGxlIFRydXN0ZWQgQ29ycG9yYXRpb24xGjAYBgNVBAMTEVRydXN0ZWQgQ29ycCBDZXJ0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzPback9X7RRxKTc3/5o2vm9Ro6XNiSM9NPsN3djjCIVz50bY0rJkP98zsqpFjnLwqHeJigxyYoqFexRhRLgKrG10CxNl4rxP6CEPENjvj5FfbX/HUZpT/DelNR18F498yD95vSHcSrCc3JrjV3bKA+wgt11E4a0Ba95S1RuwtehZw1+Y4hO8nHpbSGfjD0BpluFY2nDoYAm+aWSrsmLuJsKLO8Xn2I1brZFJUynR3q1ujuDE9EJk1niDLfOeVgXM4AavJS5C0ZBHhAhR2W+K9NN97jpkpmHFqecTwDXB7rEhsyB3185cI7anaaQfHHfH5+4SD+cMDNtYIOSgLO06ZwIDAQABozgwNjAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMDMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAQEAlnVyLz5dPhS0ZhZD6qJOUzSo6nFwMxNX1m0oS37mevtuh0b0o1gmEuMw3mVxiAVkC2vPsoxBL2wLlAkcEdBPxGEqhBmtiBY3F3DgvEkf+/sOY1rnr6O1qLZuBAnPzA1Vnco8Jwf0DYF0PxaRd8yT5XSl5qGpM2DItEldZwuKKaL94UEgIeC2c+Uv/IOyrv+EyftX96vcmRwr8ghPFLQ+36H5nuAKEpDD170EvfWl1zs0dUPiqSI6l+hy5V14gl63Woi34L727+FKx8oatbyZtdvbeeOmenfTLifLomnZdx+3WMLkp3TLlHa5xDLwifvZtBP2d3c6zHp7gdrGU1u2WTGCAf4wggH6AgEBMHgwczELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MSQwIgYDVQQKExtFeGFtcGxlIFRydXN0ZWQgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFRydXN0ZWQgVmFsaWQgQ0ECAQQwCQYFKw4DAhoFAKBdMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTE1MTEyNTAzMDQzMFowIwYJKoZIhvcNAQkEMRYEFD4ut4oKoYdcGzyfQE6ROeazv+uNMA0GCSqGSIb3DQEBAQUABIIBAFG99dKBSOzQmYVn6lHKWERVDtYXbDTIVF957ID8YH9B5unlX/PdludTNbP5dzn8GWQV08tNRgoXQ5sgxjifHunrpaR1WiR6XqvwOCBeA5NB688jxGNxth6zg6fCGFaynsYMX3FlglfIW+AYwyQUclbv+C4UORJpBjvuknOnK+UDBLVSoP9ivL6KhylYna3oFcs0SMsumc/jf/oQW51LzFHpn61TRUqdDgvGhwcjgphMhKj23KwkjwRspU2oIWNRAuhZgqDD5BJlNniCr9X5Hx1dW6tIVISO91CLAryYkGZKRJYekXctCpIvldUkIDeh2tAw5owr0jtsVd6ovFF3bV4=\r
+--NKWXJUAFXB\r
+Content-Location: manifest.webapp\r
+Content-Type: application/x-web-app-manifest+json\r
+\r
+{
+ "moz-package-origin": "http://mochi.test:8888",
+ "name": "My App",
+ "moz-resources": [
+ {
+ "src": "page2.html",
+ "integrity": "JREF3JbXGvZ+I1KHtoz3f46ZkeIPrvXtG4VyFQrJ7II="
+ },
+ {
+ "src": "index.html",
+ "integrity": "Jkvco7U8WOY9s0YREsPouX+DWK7FWlgZwA0iYYSrb7Q="
+ },
+ {
+ "src": "scripts/script.js",
+ "integrity": "6TqtNArQKrrsXEQWu3D9ZD8xvDRIkhyV6zVdTcmsT5Q="
+ },
+ {
+ "src": "scripts/library.js",
+ "integrity": "TN2ByXZiaBiBCvS4MeZ02UyNi44vED+KjdjLInUl4o8="
+ }
+ ],
+ "moz-permissions": [
+ {
+ "systemXHR": {
+ "description": "Needed to download stuff"
+ }
+ }
+ ],
+ "package-identifier": "09bc9714-7ab6-4320-9d20-fde4c237522c",
+ "description": "A great app!"
+}\r
+--NKWXJUAFXB\r
+Content-Location: page2.html\r
+Content-Type: text/html\r
+\r
+<html>
+ page2.html
+</html>
+\r
+--NKWXJUAFXB\r
+Content-Location: index.html\r
+Content-Type: text/html\r
+\r
+<html>
+ Last updated: 2015/10/28
+ <iframe id="innerFrame" src="page2.html"></iframe>
+</html>
+\r
+--NKWXJUAFXB\r
+Content-Location: scripts/script.js\r
+Content-Type: text/javascript\r
+\r
+// script.js
+\r
+--NKWXJUAFXB\r
+Content-Location: scripts/library.js\r
+Content-Type: text/javascript\r
+\r
+// library.js
+\r
+--NKWXJUAFXB--`;
diff --git a/netwerk/test/mochitests/subResources.sjs b/netwerk/test/mochitests/subResources.sjs
new file mode 100644
index 0000000000..ec2cfaa750
--- /dev/null
+++ b/netwerk/test/mochitests/subResources.sjs
@@ -0,0 +1,78 @@
+const kTwoDays = 2 * 24 * 60 * 60;
+const kInTwoDays = new Date().getTime() + kTwoDays * 1000;
+
+function getDateInTwoDays() {
+ let date2 = new Date(kInTwoDays);
+ let days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
+ let months = [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec",
+ ];
+ let day = date2.getUTCDate();
+ if (day < 10) {
+ day = "0" + day;
+ }
+ let month = months[date2.getUTCMonth()];
+ let year = date2.getUTCFullYear();
+ let hour = date2.getUTCHours();
+ if (hour < 10) {
+ hour = "0" + hour;
+ }
+ let minute = date2.getUTCMinutes();
+ if (minute < 10) {
+ minute = "0" + minute;
+ }
+ let second = date2.getUTCSeconds();
+ if (second < 10) {
+ second = "0" + second;
+ }
+ return (
+ days[date2.getUTCDay()] +
+ ", " +
+ day +
+ "-" +
+ month +
+ "-" +
+ year +
+ " " +
+ hour +
+ ":" +
+ minute +
+ ":" +
+ second +
+ " GMT"
+ );
+}
+
+function handleRequest(aRequest, aResponse) {
+ aResponse.setStatusLine(aRequest.httpVersion, 200);
+
+ let suffix = " path=/; domain:.mochi.test";
+
+ if (aRequest.queryString.includes("3")) {
+ aResponse.setHeader(
+ "Set-Cookie",
+ "test3=value3; expires=Fri, 02-Jan-2037 00:00:01 GMT;" + suffix
+ );
+ } else if (aRequest.queryString.includes("4")) {
+ let date2 = getDateInTwoDays();
+
+ aResponse.setHeader(
+ "Set-Cookie",
+ "test4=value4; expires=" + date2 + ";" + suffix
+ );
+ }
+
+ aResponse.setHeader("Content-Type", "text/javascript", false);
+ aResponse.write("42;");
+}
diff --git a/netwerk/test/mochitests/sw_1502055.js b/netwerk/test/mochitests/sw_1502055.js
new file mode 100644
index 0000000000..40a8c178f1
--- /dev/null
+++ b/netwerk/test/mochitests/sw_1502055.js
@@ -0,0 +1 @@
+/* empty */
diff --git a/netwerk/test/mochitests/test1.css b/netwerk/test/mochitests/test1.css
new file mode 100644
index 0000000000..139597f9cb
--- /dev/null
+++ b/netwerk/test/mochitests/test1.css
@@ -0,0 +1,2 @@
+
+
diff --git a/netwerk/test/mochitests/test1.css^headers^ b/netwerk/test/mochitests/test1.css^headers^
new file mode 100644
index 0000000000..729babb5a4
--- /dev/null
+++ b/netwerk/test/mochitests/test1.css^headers^
@@ -0,0 +1,3 @@
+Cache-Control: no-cache
+Set-Cookie: css=bar
+
diff --git a/netwerk/test/mochitests/test2.css b/netwerk/test/mochitests/test2.css
new file mode 100644
index 0000000000..139597f9cb
--- /dev/null
+++ b/netwerk/test/mochitests/test2.css
@@ -0,0 +1,2 @@
+
+
diff --git a/netwerk/test/mochitests/test2.css^headers^ b/netwerk/test/mochitests/test2.css^headers^
new file mode 100644
index 0000000000..b12d32c72b
--- /dev/null
+++ b/netwerk/test/mochitests/test2.css^headers^
@@ -0,0 +1,3 @@
+Cache-Control: no-cache
+Set-Cookie: css2=bar2
+
diff --git a/netwerk/test/mochitests/test_1331680.html b/netwerk/test/mochitests/test_1331680.html
new file mode 100644
index 0000000000..30d74de0af
--- /dev/null
+++ b/netwerk/test/mochitests/test_1331680.html
@@ -0,0 +1,87 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1331680
+-->
+<head>
+ <title>Cookies set in content processes update immediately.</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1331680">Mozilla Bug 1331680</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+<script type="application/javascript">
+
+SimpleTest.waitForExplicitFinish();
+
+var gScript = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('file_1331680.js'));
+
+// Bug 1617611: Fix all the tests broken by "cookies SameSite=lax by default"
+SpecialPowers.pushPrefEnv({
+ "set": [
+ ["network.cookie.sameSite.laxByDefault", false],
+ ]
+}, () => {
+ gScript.addMessageListener("cookieName", confirmCookieName);
+ gScript.addMessageListener("createObserver:return", testSetCookie);
+ gScript.addMessageListener("removeObserver:return", finishTest);
+ gScript.sendAsyncMessage('createObserver');
+});
+
+var testsNum = 0;
+
+function confirmRemoveAllCookies() {
+ is(document.cookie, "", "Removed all cookies.");
+ SpecialPowers.clearUserPref("network.cookie.sameSite.laxByDefault");
+ SimpleTest.finish();
+}
+
+// Confirm the notify which represents the cookie is updating.
+function confirmCookieName(name) {
+ testsNum++;
+ switch(testsNum) {
+ case 1:
+ case 3:
+ is(name, "cookie0=test1", "An update for the cookie named " + name + " was observed.");
+ break;
+ case 2:
+ is(name, "cookie2=test3", "An update for the cookie named " + name + " was observed.");
+ break;
+ case 4:
+ is(name, "cookie2=test3", "An update for the cookie named " + name + " was observed.");
+ gScript.sendAsyncMessage('removeObserver');
+ break;
+ }
+}
+
+function finishTest() {
+ is(document.cookie, "", "Removed all cookies from cookie-changed");
+ SimpleTest.finish();
+}
+
+/* Test document.cookie
+ * 1. Set a cookie and confirm the cookies which are processed from observer.
+ * 2. Set a cookie and get cookie.
+ */
+const COOKIE_NAMES = ["cookie0", "cookie1", "cookie2"];
+function testSetCookie() {
+ document.cookie = COOKIE_NAMES[0] + "=test1";
+ document.cookie = COOKIE_NAMES[1] + "=test2; HttpOnly";
+ document.cookie = COOKIE_NAMES[2] + "=test3";
+ var confirmCookieString = COOKIE_NAMES[0] + "=test1; " + COOKIE_NAMES[2] + "=test3";
+ is(document.cookie, confirmCookieString, "Confirm the cookies string which be get is current.");
+ for (var i = 0; i < COOKIE_NAMES.length; i++) {
+ document.cookie = COOKIE_NAMES[i] + "=; expires=Thu, 01-Jan-1970 00:00:01 GMT;";
+ }
+ is(document.cookie, "", "Removed all cookies.");
+}
+
+</script>
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/test_1331680_iframe.html b/netwerk/test/mochitests/test_1331680_iframe.html
new file mode 100644
index 0000000000..85842332b1
--- /dev/null
+++ b/netwerk/test/mochitests/test_1331680_iframe.html
@@ -0,0 +1,68 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=643051
+-->
+<head>
+ <title>Cookies set from iframe in content process</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1331680">Mozilla Bug 1331680</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+<script type="application/javascript">
+SimpleTest.waitForExplicitFinish();
+const IFRAME_COOKIE_NAMES = ["if1", "if2_1", "if2_2"];
+const ID = ["if_1", "if_2", "if_3"];
+
+var gScript = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('file_1331680.js'));
+
+/* Test iframe
+ * 1. Create three iframes, and one of the iframe will create two cookies.
+ * 2. Confirm the cookies can be proessed from observer.
+ * 3. Confirm document.cookie can get cookies "if2_1" and "if2_2".
+ * 4. Confirm the iframe whose source is "about:blank" can get parent's cookies.
+ */
+function createIframe(id, src, sandbox_flags) {
+ return new Promise(resolve => {
+ var ifr = document.createElement("iframe");
+ ifr.id = id;
+ ifr.src = src;
+ ifr.sandbox = sandbox_flags;
+ ifr.addEventListener("load", resolve);
+ document.body.appendChild(ifr);
+ });
+};
+
+function confirmCookies(id) {
+ is(document.cookie, "if2_1=if2_val1; if2_2=if2_val2", "Confirm the cookies can get after iframe was deleted");
+ var new_ifr = document.getElementById(id);
+ is(new_ifr.contentDocument.cookie, document.cookie, "Confirm the inner document.cookie = parent document.cookie");
+ document.cookie = IFRAME_COOKIE_NAMES[1] + "=; expires=Thu, 01-Jan-1970 00:00:01 GMT";
+ document.cookie = IFRAME_COOKIE_NAMES[2] + "=; expires=Thu, 01-Jan-1970 00:00:01 GMT";
+ is(document.cookie, "", "Removed all cookies");
+ SpecialPowers.clearUserPref("network.cookie.sameSite.laxByDefault");
+ SimpleTest.finish();
+}
+
+addEventListener("message", function(event) {
+ is(event.data, document.cookie, "Confirm the iframe 2 can communicate with iframe");
+});
+
+SpecialPowers.pushPrefEnv({
+ // Bug 1617611: Fix all the tests broken by "cookies SameSite=lax by default"
+ set: [["network.cookie.sameSite.laxByDefault", false]],
+}).then(_ => createIframe(ID[0], "file_iframe_allow_scripts.html", "allow-scripts"))
+ .then(_ => createIframe(ID[1], "file_iframe_allow_same_origin.html", "allow-scripts allow-same-origin"))
+ .then(_ => createIframe(ID[2], "about:blank", "allow-scripts allow-same-origin"))
+ .then(_ => confirmCookies(ID[2]));
+
+</script>
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/test_1331680_xhr.html b/netwerk/test/mochitests/test_1331680_xhr.html
new file mode 100644
index 0000000000..0649d33ff4
--- /dev/null
+++ b/netwerk/test/mochitests/test_1331680_xhr.html
@@ -0,0 +1,90 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+-->
+<head>
+ <title>Cookie changes from XHR requests are observed in content processes.</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+
+<script type="text/javascript">
+SimpleTest.waitForExplicitFinish();
+
+const XHR_COOKIE_NAMES = ["xhr1", "xhr2"];
+
+var gScript = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('file_1331680.js'));
+gScript.addMessageListener("cookieName", confirmCookieName);
+gScript.addMessageListener("removeObserver:return", finishTest);
+gScript.sendAsyncMessage('createObserver');
+
+// Confirm the notify which represents the cookie is updating.
+var testsNum = 0;
+function confirmCookieName(name) {
+ testsNum++;
+ switch(testsNum) {
+ case 1:
+ is(name, "xhr1=xhr_val1", "The cookie which names " + name + " is update to db");
+ break;
+ case 2:
+ is(document.cookie, "xhr1=xhr_val1", "Confirm the cookie string");
+ for (var i = 0; i < XHR_COOKIE_NAMES.length; i++) {
+ document.cookie = XHR_COOKIE_NAMES[i] + "=; path=/; expires=Thu, 01-Jan-1970 00:00:01 GMT";
+ }
+ break;
+ case 3:
+ is(document.cookie, "", "Confirm the cookie string");
+ gScript.sendAsyncMessage('removeObserver');
+ break;
+ }
+}
+
+function finishTest() {
+ SpecialPowers.clearUserPref("network.cookie.sameSite.laxByDefault");
+ SimpleTest.finish();
+}
+
+function createXHR(url) {
+ return new Promise(function (resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", url, true); // async request
+ xhr.onload = function () {
+ if (this.status >= 200 && this.status < 300) {
+ resolve(xhr.response);
+ } else {
+ reject({
+ status: this.status,
+ statusText: xhr.statusText
+ });
+ }
+ };
+ xhr.onerror = function () {
+ reject({
+ status: this.status,
+ statusText: xhr.statusText
+ });
+ };
+ xhr.send();
+ });
+}
+
+/* Test XHR
+ * 1. Create two XHR.
+ * 2. One of the XHR create a cookie names "xhr1", and other one create a http-only cookie names "xhr2".
+ * 3. Child process only set xhr1 to cookies hash table.
+ * 4. Child process only can get the xhr1 cookie from cookies hash table.
+ */
+SpecialPowers.pushPrefEnv({
+ // Bug 1617611: Fix all the tests broken by "cookies SameSite=lax by default"
+ set: [["network.cookie.sameSite.laxByDefault", false]],
+}).then(_ => createXHR('set_cookie_xhr.sjs?xhr1'))
+ .then(_ => createXHR('set_cookie_xhr.sjs?xhr2'));
+
+</script>
+</head>
+<body>
+<p id="display"></p>
+<div id="content" style="display: none"></div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/test_1396395.html b/netwerk/test/mochitests/test_1396395.html
new file mode 100644
index 0000000000..dcfb952b3a
--- /dev/null
+++ b/netwerk/test/mochitests/test_1396395.html
@@ -0,0 +1,48 @@
+<!DOCTYPE HTML>
+<!-- vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: -->
+<html>
+ <!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<head>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+</head>
+<body>
+ <iframe id="f" src="about:blank"></iframe>
+ <script type="text/javascript">
+SimpleTest.waitForExplicitFinish();
+
+var script = SpecialPowers.loadChromeScript(() => {
+ /* eslint-env mozilla/chrome-script */
+ Services.obs.addObserver(function onExamResp(subject, topic, data) {
+ let channel = subject.QueryInterface(Ci.nsIHttpChannel);
+ if (!channel.URI.spec.startsWith("http://example.org")) {
+ return;
+ }
+ Services.obs.removeObserver(onExamResp, 'http-on-examine-response');
+ channel.suspend();
+ Promise.resolve().then(() => {
+ channel.resume();
+ });
+ }, 'http-on-examine-response');
+
+ sendAsyncMessage('start-test');
+});
+
+script.addMessageListener('start-test', () => {
+ const iframe = document.getElementById('f');
+
+ iframe.contentWindow.onunload = function () {
+ info('initiate sync XHR during the page loading');
+ let xhr = new XMLHttpRequest();
+ xhr.open('GET', window.location, false);
+ xhr.send(null);
+ ok(true, 'complete without crash');
+ script.destroy();
+ SimpleTest.finish();
+ }
+
+ iframe.src = 'http://example.org';
+});
+ </script>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/test_1421324.html b/netwerk/test/mochitests/test_1421324.html
new file mode 100644
index 0000000000..627a339e0a
--- /dev/null
+++ b/netwerk/test/mochitests/test_1421324.html
@@ -0,0 +1,88 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+-->
+<head>
+ <title>Cookie changes from XHR requests are observed in content processes.</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+
+<script type="text/javascript">
+SimpleTest.waitForExplicitFinish();
+
+var gScript = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('file_1331680.js'));
+gScript.addMessageListener("cookieName", confirmCookieName);
+gScript.addMessageListener("removeObserver:return", finishTest);
+gScript.sendAsyncMessage('createObserver');
+
+// Confirm the notify which represents the cookie is updating.
+var testsNum = 0;
+function confirmCookieName(name) {
+ testsNum++;
+ switch(testsNum) {
+ case 1:
+ is(name, "testXHR1=xhr_val1", "The cookie which names " + name + " is update to db");
+ break;
+ case 2:
+ document.cookie = "testXHR2=xhr_val2; path=/";
+ break;
+ case 3:
+ is(document.cookie, "testXHR2=xhr_val2", "Confirm the cookie string");
+ document.cookie = "testXHR1=; path=/; expires=Thu, 01-Jan-1970 00:00:01 GMT";
+ document.cookie = "testXHR2=; path=/; expires=Thu, 01-Jan-1970 00:00:01 GMT";
+ gScript.sendAsyncMessage('removeObserver');
+ break;
+ }
+}
+
+function finishTest() {
+ SpecialPowers.clearUserPref("network.cookie.sameSite.laxByDefault");
+ SimpleTest.finish();
+}
+
+function createXHR(url) {
+ return new Promise(function (resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", url, true); // async request
+ xhr.onload = function () {
+ if (this.status >= 200 && this.status < 300) {
+ resolve(xhr.response);
+ } else {
+ reject({
+ status: this.status,
+ statusText: xhr.statusText
+ });
+ }
+ };
+ xhr.onerror = function () {
+ reject({
+ status: this.status,
+ statusText: xhr.statusText
+ });
+ };
+ xhr.send();
+ });
+}
+
+
+/* Test XHR
+ * 1. Create two XHR.
+ * 2. One of the XHR create a cookie names "set_cookie", and other one create a http-only cookie names "modify_cookie".
+ * 3. Child process only set testXHR1 to cookies hash table.
+ * 4. Child process only can get the testXHR1 cookie from cookies hash table.
+ */
+SpecialPowers.pushPrefEnv({
+ // Bug 1617611: Fix all the tests broken by "cookies SameSite=lax by default"
+ set: [["network.cookie.sameSite.laxByDefault", false]],
+}).then(_ => createXHR('reset_cookie_xhr.sjs?set_cookie'))
+ .then(_ => createXHR('reset_cookie_xhr.sjs?modify_cookie'));
+
+</script>
+</head>
+<body>
+<p id="display"></p>
+<div id="content" style="display: none"></div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/test_1425031.html b/netwerk/test/mochitests/test_1425031.html
new file mode 100644
index 0000000000..54865501c8
--- /dev/null
+++ b/netwerk/test/mochitests/test_1425031.html
@@ -0,0 +1,74 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1425031
+-->
+<head>
+ <title>Cookies set in content processes update immediately.</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1425031">Mozilla Bug 1425031</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+<script type="application/javascript">
+
+// Verify that cookie operations initiated by content processes do not cause
+// asynchronous updates for those operations to be processed later.
+
+SimpleTest.waitForExplicitFinish();
+
+var gScript = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('file_1331680.js'));
+var testsNum = 0;
+var cookieString = "cookie0=test";
+let {COOKIE_ADDED, COOKIE_DELETED} = SpecialPowers.Ci.nsICookieNotification;
+
+// Confirm the notify which represents the cookie is updating.
+function confirmCookieOperation(op) {
+ testsNum++;
+ switch(testsNum) {
+ case 1:
+ is(op, COOKIE_ADDED, "Confirm the cookie operation is added.");
+ is(document.cookie, cookieString, "Confirm the cookie string is unaffected by the addition");
+ break;
+ case 2:
+ is(op, COOKIE_DELETED, "Confirm the cookie operation is deleted.");
+ is(document.cookie, cookieString, "Confirm the cookie string is unaffected by the deletion");
+ break;
+ case 3:
+ is(op, COOKIE_ADDED, "Confirm the cookie operation is added.");
+ is(document.cookie, cookieString, "Confirm the cookie string is unaffected by the second addition.");
+ document.cookie = "cookie0=; expires=Thu, 01-Jan-1970 00:00:01 GMT;";
+ gScript.sendAsyncMessage('removeObserver');
+ SpecialPowers.clearUserPref("network.cookie.sameSite.laxByDefault");
+ SimpleTest.finish();
+ break;
+ }
+}
+
+function testSetCookie() {
+ document.cookie = cookieString;
+ is(document.cookie, cookieString, "Confirm cookie string.");
+ document.cookie = "cookie0=; expires=Thu, 01-Jan-1970 00:00:01 GMT;";
+ is(document.cookie, "", "Removed all cookies.");
+ document.cookie = cookieString;
+ is(document.cookie, cookieString, "Confirm cookie string.");
+}
+
+// Bug 1617611: Fix all the tests broken by "cookies SameSite=lax by default"
+SpecialPowers.pushPrefEnv({
+ set: [["network.cookie.sameSite.laxByDefault", false]],
+}, () => {
+ gScript.addMessageListener("cookieOperation", confirmCookieOperation);
+ gScript.addMessageListener("createObserver:return", testSetCookie);
+ gScript.sendAsyncMessage('createObserver');
+});
+
+</script>
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/test_1502055.html b/netwerk/test/mochitests/test_1502055.html
new file mode 100644
index 0000000000..472ee204e6
--- /dev/null
+++ b/netwerk/test/mochitests/test_1502055.html
@@ -0,0 +1,49 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Clear-Site-Data + 304 header.</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<script type="application/javascript">
+
+SimpleTest.waitForExplicitFinish();
+ (async () => {
+ // Grant example.org first-party storage-access to allow service workers to
+ // run in the third-party context when dFPI is enabled. This won't be
+ // necessary anymore once we enable service worker partitioning in beta and
+ // release. See Bug 1730885.
+ await SpecialPowers.pushPermissions([
+ {
+ type: "3rdPartyStorage^https://example.org",
+ allow: true,
+ context: document.location.origin,
+ },
+ ]);
+ await SpecialPowers.pushPrefEnv({
+ "set": [
+ ["dom.serviceWorkers.exemptFromPerDomainMax", true],
+ ["dom.serviceWorkers.enabled", true],
+ ["dom.serviceWorkers.testing.enabled", true]
+ ]
+ })
+ let ifr = document.createElement('iframe');
+ ifr.src = "https://example.org/tests/netwerk/test/mochitests/iframe_1502055.html";
+ document.body.appendChild(ifr);
+ addEventListener("message", e => {
+ if (e.data.type == "finish") {
+ ok(true, "Test passed");
+ SimpleTest.finish();
+ return;
+ }
+
+ if (e.data.type == "info") {
+ info(e.data.msg);
+ }
+ });
+ })();
+</script>
+
+</body>
+</html>
diff --git a/netwerk/test/mochitests/test_1503201.html b/netwerk/test/mochitests/test_1503201.html
new file mode 100644
index 0000000000..2e724f33ce
--- /dev/null
+++ b/netwerk/test/mochitests/test_1503201.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1503201
+-->
+<head>
+ <title>A WWW-Authenticate response header with an invalid realm doesn't crash the browser</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1503201">Mozilla Bug 1503201</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+<script type="application/javascript">
+
+SimpleTest.waitForExplicitFinish();
+fetch("file_1503201.sjs")
+ .then(() => ok(true, "no crash"))
+ .then(() => SimpleTest.finish());
+
+</script>
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/test_accept_header.html b/netwerk/test/mochitests/test_accept_header.html
new file mode 100644
index 0000000000..0acae2a825
--- /dev/null
+++ b/netwerk/test/mochitests/test_accept_header.html
@@ -0,0 +1,87 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Accept header</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<script>
+SimpleTest.requestCompleteLog();
+
+// All the requests are sent to test_accept_header.sjs which will return
+// different content based on the queryString. When the queryString is 'get',
+// test_accept_header.sjs returns a JSON object with the latest request and its
+// accept header value.
+
+function test_last_request_and_continue(query, expected) {
+ fetch("test_accept_header.sjs?get").then(r => r.json()).then(json => {
+ is(json.type, query, "Expected: " + query);
+ is(json.accept, expected, "Accept header: " + expected);
+ next();
+ });
+}
+
+function test_iframe() {
+ let ifr = document.createElement("iframe");
+ ifr.src = "test_accept_header.sjs?iframe";
+ ifr.onload = () => {
+ test_last_request_and_continue("iframe", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8");
+ };
+ document.body.appendChild(ifr);
+}
+
+function test_image() {
+ let i = new Image();
+ i.src = "test_accept_header.sjs?image";
+ i.onload = function() {
+ // Fetch spec says we should have: "image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5"
+ test_last_request_and_continue("image", "image/avif,image/webp,*/*");
+ }
+}
+
+function test_style() {
+ let head = document.getElementsByTagName("head")[0];
+ let link = document.createElement("link");
+ link.rel = "stylesheet";
+ link.type = "text/css";
+ link.href = "test_accept_header.sjs?style";
+ link.onload = () => {
+ test_last_request_and_continue("style", "text/css,*/*;q=0.1");
+ };
+ head.appendChild(link);
+}
+
+function test_worker() {
+ let w = new Worker("test_accept_header.sjs?worker");
+ w.onmessage = function() {
+ test_last_request_and_continue("worker", "*/*");
+ }
+}
+
+let tests = [
+ test_iframe,
+ test_image,
+ test_style,
+ test_worker,
+];
+
+function next() {
+ if (!tests.length) {
+ SimpleTest.finish();
+ return;
+ }
+
+ let test = tests.shift();
+ test();
+}
+
+SimpleTest.waitForExplicitFinish();
+
+SpecialPowers.pushPrefEnv({ "set": [
+ [ "dom.enable_performance_observer", true ]
+]}, next);
+
+</script>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/test_accept_header.sjs b/netwerk/test/mochitests/test_accept_header.sjs
new file mode 100644
index 0000000000..6e73acd293
--- /dev/null
+++ b/netwerk/test/mochitests/test_accept_header.sjs
@@ -0,0 +1,62 @@
+function handleRequest(request, response) {
+ response.setStatusLine(request.httpVersion, "200", "OK");
+ dump(`test_accept_header ${request.path}?${request.queryString}\n`);
+
+ if (request.queryString == "worker") {
+ response.setHeader("Content-Type", "text/javascript", false);
+ response.write("postMessage(42)");
+
+ setState(
+ "data",
+ JSON.stringify({ type: "worker", accept: request.getHeader("Accept") })
+ );
+ return;
+ }
+
+ if (request.queryString == "image") {
+ // A 1x1 PNG image.
+ // Source: https://commons.wikimedia.org/wiki/File:1x1.png (Public Domain)
+ const IMAGE = atob(
+ "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAA" +
+ "ACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII="
+ );
+
+ response.setHeader("Content-Type", "image/png", false);
+ response.write(IMAGE);
+
+ setState(
+ "data",
+ JSON.stringify({ type: "image", accept: request.getHeader("Accept") })
+ );
+ return;
+ }
+
+ if (request.queryString == "style") {
+ response.setHeader("Content-Type", "text/css", false);
+ response.write("");
+
+ setState(
+ "data",
+ JSON.stringify({ type: "style", accept: request.getHeader("Accept") })
+ );
+ return;
+ }
+
+ if (request.queryString == "iframe") {
+ response.setHeader("Content-Type", "text/html", false);
+ response.write("<h1>Hello world!</h1>");
+
+ setState(
+ "data",
+ JSON.stringify({ type: "iframe", accept: request.getHeader("Accept") })
+ );
+ return;
+ }
+
+ if (request.queryString == "get") {
+ response.setHeader("Content-Type", "application/json", false);
+ response.write(getState("data"));
+
+ setState("data", "");
+ }
+}
diff --git a/netwerk/test/mochitests/test_arraybufferinputstream.html b/netwerk/test/mochitests/test_arraybufferinputstream.html
new file mode 100644
index 0000000000..5e3c5faa3e
--- /dev/null
+++ b/netwerk/test/mochitests/test_arraybufferinputstream.html
@@ -0,0 +1,89 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+-->
+<head>
+ <title>ArrayBuffer stream test</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+
+<script type="text/javascript">
+function detachArrayBuffer(ab)
+{
+ var w = new Worker("data:application/javascript,");
+ w.postMessage(ab, [ab]);
+}
+
+function test()
+{
+ var ab = new ArrayBuffer(4000);
+ var ta = new Uint8Array(ab);
+ ta[0] = 'a'.charCodeAt(0);
+ ta[1] = 'b'.charCodeAt(0);
+
+ const Cc = SpecialPowers.Cc, Ci = SpecialPowers.Ci;
+ var abis = Cc["@mozilla.org/io/arraybuffer-input-stream;1"]
+ .createInstance(Ci.nsIArrayBufferInputStream);
+
+ var sis = Cc["@mozilla.org/scriptableinputstream;1"]
+ .createInstance(Ci.nsIScriptableInputStream);
+ sis.init(abis);
+
+ is(sis.read(1), "", "should read no data from an uninitialized ABIS");
+
+ abis.setData(ab, 0, 256 * 1024);
+
+ is(sis.read(1), "a", "should read 'a' after init");
+
+ detachArrayBuffer(ab);
+
+ SpecialPowers.forceGC();
+ SpecialPowers.forceGC();
+
+ try
+ {
+ is(sis.read(1), "b", "should read 'b' after detaching buffer");
+ }
+ catch (e)
+ {
+ ok(false, "reading from stream should have worked");
+ }
+
+ // A regression test for bug 1265076. Previously, overflowing
+ // the internal buffer from readSegments would cause incorrect
+ // copying. The constant mirrors the value in
+ // ArrayBufferInputStream::readSegments.
+ var size = 8192;
+ ab = new ArrayBuffer(2 * size);
+ ta = new Uint8Array(ab);
+
+ var i;
+ for (i = 0; i < size; ++i) {
+ ta[i] = 'x'.charCodeAt(0);
+ }
+ for (i = 0; i < size; ++i) {
+ ta[size + i] = 'y'.charCodeAt(0);
+ }
+
+ abis = Cc["@mozilla.org/io/arraybuffer-input-stream;1"]
+ .createInstance(Ci.nsIArrayBufferInputStream);
+ abis.setData(ab, 0, 2 * size);
+
+ sis = Cc["@mozilla.org/scriptableinputstream;1"]
+ .createInstance(Ci.nsIScriptableInputStream);
+ sis.init(abis);
+
+ var result = sis.read(2 * size);
+ is(result, "x".repeat(size) + "y".repeat(size), "correctly read the data");
+}
+
+test();
+</script>
+</head>
+<body>
+<p id="display"></p>
+<div id="content" style="display: none"></div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/test_arraybufferinputstream_large.html b/netwerk/test/mochitests/test_arraybufferinputstream_large.html
new file mode 100644
index 0000000000..33922d6e37
--- /dev/null
+++ b/netwerk/test/mochitests/test_arraybufferinputstream_large.html
@@ -0,0 +1,45 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>ArrayBuffer stream with large ArrayBuffer test</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+
+<script type="text/javascript">
+add_task(async function testLargeArrayBuffer() {
+ let ab = new ArrayBuffer(4.5 * 1024 * 1024 * 1024); // 4.5 GB.
+ let ta = new Uint8Array(ab);
+
+ const { Cc, Ci } = SpecialPowers;
+ let abis = Cc["@mozilla.org/io/arraybuffer-input-stream;1"]
+ .createInstance(Ci.nsIArrayBufferInputStream);
+
+ let sis = Cc["@mozilla.org/scriptableinputstream;1"]
+ .createInstance(Ci.nsIScriptableInputStream);
+ sis.init(abis);
+
+ // The stream currently doesn't support more than UINT32_MAX bytes.
+ let ex;
+ try {
+ abis.setData(ab, 0, ab.byteLength);
+ } catch (e) {
+ ex = e;
+ }
+ is(ex.message.includes("NS_ERROR_ILLEGAL_VALUE"), true, "Expecting exception");
+
+ // Reading a small slice of the large ArrayBuffer is fine, even near the end.
+ ta[ta.length - 10] = "a".charCodeAt(0);
+ ta[ta.length - 9] = "b".charCodeAt(0);
+ ta[ta.length - 8] = "c".charCodeAt(0);
+ abis.setData(ab, ab.byteLength - 10, 2);
+ is(sis.read(1), "a", "should read 'a' after init");
+ is(sis.read(1), "b", "should read 'b' after 'a'");
+ is(sis.read(1), "", "Should be done reading data");
+});
+</script>
+
+</head>
+<body>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/test_different_domain_in_hierarchy.html b/netwerk/test/mochitests/test_different_domain_in_hierarchy.html
new file mode 100644
index 0000000000..0ec6d35d4d
--- /dev/null
+++ b/netwerk/test/mochitests/test_different_domain_in_hierarchy.html
@@ -0,0 +1,15 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test cookie requests from within a window hierarchy of different base domains</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body onload="setupTest('https://example.org/tests/netwerk/test/mochitests/file_domain_hierarchy_inner.html', 4, 3)">
+<p id="display"></p>
+<pre id="test">
+<script class="testbody" type="text/javascript" src="file_testcommon.js">
+</script>
+</pre>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/test_differentdomain.html b/netwerk/test/mochitests/test_differentdomain.html
new file mode 100644
index 0000000000..75cc903758
--- /dev/null
+++ b/netwerk/test/mochitests/test_differentdomain.html
@@ -0,0 +1,15 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for Cross domain access to properties</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body onload="setupTest('https://example.com/tests/netwerk/test/mochitests/file_domain_inner.html', 3, 2)">
+<p id="display"></p>
+<pre id="test">
+<script class="testbody" type="text/javascript" src="file_testcommon.js">
+</script>
+</pre>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/test_documentcookies_maxage.html b/netwerk/test/mochitests/test_documentcookies_maxage.html
new file mode 100644
index 0000000000..eb130b2fed
--- /dev/null
+++ b/netwerk/test/mochitests/test_documentcookies_maxage.html
@@ -0,0 +1,149 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+-->
+<head>
+ <title>Test for document.cookie max-age pref</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+
+<script type="text/javascript">
+const kTwoDays = 2 * 24 * 60 * 60;
+const kSevenDays = 7 * 24 * 60 * 60;
+const kInTwoDays = (new Date().getTime() + kTwoDays * 1000);
+const kInSevenDays = (new Date().getTime() + kSevenDays * 1000);
+const kScriptURL = SimpleTest.getTestFileURL("file_documentcookie_maxage_chromescript.js");
+
+let gScript;
+
+function getDateInTwoDays()
+{
+ let date2 = new Date(kInTwoDays);
+ let days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
+ let months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct",
+ "Nov", "Dec"];
+ let day = date2.getUTCDate();
+ if (day < 10) {
+ day = "0" + day;
+ }
+ let month = months[date2.getUTCMonth()];
+ let year = date2.getUTCFullYear();
+ let hour = date2.getUTCHours();
+ if (hour < 10) {
+ hour = "0" + hour;
+ }
+ let minute = date2.getUTCMinutes();
+ if (minute < 10) {
+ minute = "0" + minute;
+ }
+ let second = date2.getUTCSeconds();
+ if (second < 10) {
+ second = "0" + second;
+ }
+ return days[date2.getUTCDay()] + ", " + day + "-" + month + "-" +
+ year + " " + hour + ":" + minute + ":" + second + " GMT";
+}
+
+function dotest()
+{
+ SimpleTest.waitForExplicitFinish();
+ SpecialPowers.pushPrefEnv({
+ set: [["privacy.documentCookies.maxage", kSevenDays]],
+ }).then(_ => {
+ gScript = SpecialPowers.loadChromeScript(kScriptURL);
+
+ return new Promise(resolve => {
+ gScript.addMessageListener("init:return", resolve);
+ gScript.sendAsyncMessage("init");
+ });
+ }).then(_ => {
+ let date2 = getDateInTwoDays();
+
+ document.cookie = "test1=value1; expires=Fri, 02-Jan-2037 00:00:01 GMT;";
+ document.cookie = "test2=value2; expires=" + date2 + ";";
+
+ return fetch("subResources.sjs?3");
+ }).then(_ => {
+ return fetch("subResources.sjs?4");
+ }).then(_ => {
+ return new Promise(resolve => {
+ gScript.addMessageListener("getCookies:return", resolve);
+ gScript.sendAsyncMessage("getCookies");
+ });
+ }).then(_ => {
+ for (let cookie of _.cookies) {
+ switch (cookie.name) {
+ case "test1": {
+ is(cookie.value, "value1", "The correct value expected");
+ let d = new Date(cookie.expires * 1000);
+ let [day, month, year] = [d.getUTCDate(), d.getUTCMonth(), d.getUTCFullYear()];
+ let d2 = new Date(kInSevenDays);
+ let [day2, month2, year2] = [d2.getUTCDate(), d2.getUTCMonth(), d2.getUTCFullYear()];
+ is(day, day2, "Days match");
+ is(month, month2, "Months match");
+ is(year, year2, "Years match");
+ }
+ break;
+
+ case "test2": {
+ is(cookie.value, "value2", "The correct value expected");
+ let d = new Date(cookie.expires * 1000);
+ let [day, month, year] = [d.getUTCDate(), d.getUTCMonth(), d.getUTCFullYear()];
+ let d2 = new Date(kInTwoDays);
+ let [day2, month2, year2] = [d2.getUTCDate(), d2.getUTCMonth(), d2.getUTCFullYear()];
+ is(day, day2, "Days match");
+ is(month, month2, "Months match");
+ is(year, year2, "Years match");
+ }
+ break;
+
+ case "test3": {
+ is(cookie.value, "value3", "The correct value expected");
+ let d = new Date(cookie.expires * 1000);
+ let [day, month, year] = [d.getUTCDate(), d.getUTCMonth(), d.getUTCFullYear()];
+ let d2 = new Date("Fri, 02 Jan 2037 00:00:01 GMT");
+ let [day2, month2, year2] = [d2.getUTCDate(), d2.getUTCMonth(), d2.getUTCFullYear()];
+ is(day, day2, "Days match");
+ is(month, month2, "Months match");
+ is(year, year2, "Years match");
+ }
+ break;
+
+ case "test4": {
+ is(cookie.value, "value4", "The correct value expected");
+ let d = new Date(cookie.expires * 1000);
+ let [day, month, year] = [d.getUTCDate(), d.getUTCMonth(), d.getUTCFullYear()];
+ let d2 = new Date(kInTwoDays);
+ let [day2, month2, year2] = [d2.getUTCDate(), d2.getUTCMonth(), d2.getUTCFullYear()];
+ is(day, day2, "Days match");
+ is(month, month2, "Months match");
+ is(year, year2, "Years match");
+ }
+ break;
+
+ default:
+ ok(false, "Unexpected cookie found!");
+ break;
+ }
+ }
+
+ return new Promise(resolve => {
+ gScript.addMessageListener("shutdown:return", resolve);
+ gScript.sendAsyncMessage("shutdown");
+ });
+ }).then(finish);
+}
+
+function finish()
+{
+ SimpleTest.finish();
+}
+</script>
+</head>
+<body onload="dotest();">
+<p id="display"></p>
+<div id="content" style="display: none"></div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/test_fetch_lnk.html b/netwerk/test/mochitests/test_fetch_lnk.html
new file mode 100644
index 0000000000..e1154a5951
--- /dev/null
+++ b/netwerk/test/mochitests/test_fetch_lnk.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Downloading .lnk through HTTP should always download the file without parsing it</title>
+<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<script>
+ SimpleTest.waitForExplicitFinish();
+ // Download .lnk which points to a system executable
+ fetch("file_lnk.lnk").then(async res => {
+ ok(res.ok, "Download success");
+ ok(res.url.endsWith("file_lnk.lnk"), "file name should be of the lnk file");
+ is(res.headers.get("Content-Length"), "1531", "The size should be of the lnk file");
+ SimpleTest.finish();
+ }, () => {
+ ok(false, "Unreachable code");
+ })
+</script>
diff --git a/netwerk/test/mochitests/test_idn_redirect.html b/netwerk/test/mochitests/test_idn_redirect.html
new file mode 100644
index 0000000000..cc920665b3
--- /dev/null
+++ b/netwerk/test/mochitests/test_idn_redirect.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+ Bug 1142083 - IDN Unicode domain redirect is broken
+ This test loads redirectme.html which is redirected simple_test.html, on a different IDN domain.
+ A message is posted to that page, with responds with another.
+ Upon receiving that message, we consider that the IDN redirect has functioned properly, since the intended page was loaded.
+-->
+<head>
+ <title>Test for URI Manipulation</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+
+<pre id="test">
+<script type="text/javascript">
+
+SimpleTest.waitForExplicitFinish();
+
+var iframe = document.createElement("iframe");
+iframe.src = "about:blank";
+iframe.addEventListener("load", finishTest);
+document.body.appendChild(iframe);
+iframe.src = "http://mochi.test:8888/tests/netwerk/test/mochitests/redirect_idn.html";
+
+function finishTest(e) {
+ ok(true);
+ SimpleTest.finish();
+}
+
+</script>
+
+</body>
+</html>
diff --git a/netwerk/test/mochitests/test_image.html b/netwerk/test/mochitests/test_image.html
new file mode 100644
index 0000000000..db75cdbca5
--- /dev/null
+++ b/netwerk/test/mochitests/test_image.html
@@ -0,0 +1,14 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for Cross domain access to properties</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body onload="setupTest('https://example.org/tests/netwerk/test/mochitests/file_image_inner.html', 7, 3)">
+<p id="display"></p>
+<pre id="test">
+<script class="testbody" type="text/javascript" src="file_testcommon.js"></script>
+</pre>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/test_loadflags.html b/netwerk/test/mochitests/test_loadflags.html
new file mode 100644
index 0000000000..fba93102ea
--- /dev/null
+++ b/netwerk/test/mochitests/test_loadflags.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for Cross domain access to properties</title>
+ <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<!--
+ *5 cookies: 1+1 from file_testloadflags.js, 2 from file_loadflags_inner.html + 1 from beltzner.jpg.
+ *1 load: file_loadflags_inner.html.
+ *2 headers: 1 for file_loadflags_inner.html + 1 for beltzner.jpg.
+ -->
+<body onload="setupTest('http://example.org/tests/netwerk/test/mochitests/file_loadflags_inner.html', 'example.org', 5, 2, 2)">
+<p id="display"></p>
+<pre id="test">
+<script class="testbody" type="text/javascript" src="file_testloadflags.js">
+</script>
+</pre>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/test_loadinfo_redirectchain.html b/netwerk/test/mochitests/test_loadinfo_redirectchain.html
new file mode 100644
index 0000000000..a657ce678c
--- /dev/null
+++ b/netwerk/test/mochitests/test_loadinfo_redirectchain.html
@@ -0,0 +1,269 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Bug 1194052 - Append Principal to RedirectChain within LoadInfo before the channel is succesfully openend</title>
+ <!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<iframe style="width:100%;" id="testframe"></iframe>
+
+<script class="testbody" type="text/javascript">
+
+/*
+ * We perform the following tests on the redirectchain of the loadinfo:
+ * (1) checkLoadInfoWithoutRedirects:
+ * checks the length of the redirectchain and tries to pop an element
+ * which should result in an exception and not a crash.
+ * (2) checkLoadInfoWithTwoRedirects:
+ * perform two redirects and confirm that both redirect chains
+ * contain the redirected URIs.
+ * (3) checkLoadInfoWithInternalRedirects:
+ * perform two redirects including CSPs upgrade-insecure-requests
+ * so that the redirectchain which includes internal redirects differs.
+ * (4) checkLoadInfoWithInternalRedirectsAndFallback
+ * perform two redirects including CSPs upgrade-insecure-requests
+ * including a 404 repsonse and hence a fallback.
+ * (5) checkHTTPURITruncation
+ * perform a redirect to a URI with an HTTP scheme to check that unwanted
+ * URI components are removed before being added to the redirectchain.
+ * (6) checkHTTPSURITruncation
+ * perform a redirect to a URI with an HTTPS scheme to check that unwanted
+ * URI components are removed before being added to the redirectchain.
+ */
+
+SimpleTest.waitForExplicitFinish();
+
+// ************** HELPERS ***************
+
+function compareChains(aLoadInfo, aExpectedRedirectChain, aExpectedRedirectChainIncludingInternalRedirects) {
+ var redirectChain = aLoadInfo.redirectChain;
+ var redirectChainIncludingInternalRedirects = aLoadInfo.redirectChainIncludingInternalRedirects;
+
+ is(redirectChain.length,
+ aExpectedRedirectChain.length,
+ "confirming length of redirectChain is " + aExpectedRedirectChain.length);
+
+ is(redirectChainIncludingInternalRedirects.length,
+ aExpectedRedirectChainIncludingInternalRedirects.length,
+ "confirming length of redirectChainIncludingInternalRedirects is " +
+ aExpectedRedirectChainIncludingInternalRedirects.length);
+}
+
+function compareTruncatedChains(redirectChain, aExpectedRedirectChain) {
+ is(redirectChain.length,
+ aExpectedRedirectChain.length,
+ "confirming length of redirectChain is " + aExpectedRedirectChain.length);
+
+ for (var i = 0; i < redirectChain.length; i++) {
+ is(redirectChain[i],
+ aExpectedRedirectChain[i],
+ "redirect chain should match expected chain");
+ }
+}
+
+
+// *************** TEST 1 ***************
+
+function checkLoadInfoWithoutRedirects() {
+ var myXHR = new XMLHttpRequest();
+ myXHR.open("GET", "http://mochi.test:8888/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-0");
+
+ myXHR.onload = function() {
+ var loadinfo = SpecialPowers.wrap(myXHR).channel.loadInfo;
+ var redirectChain = loadinfo.redirectChain;
+ var redirectChainIncludingInternalRedirects = loadinfo.redirectChainIncludingInternalRedirects;
+
+ is(redirectChain.length, 0, "no redirect, length should be 0");
+ is(redirectChainIncludingInternalRedirects.length, 0, "no redirect, length should be 0");
+ is(myXHR.responseText, "checking redirectchain", "sanity check to make sure redirects succeeded");
+
+ // try to pop an element from redirectChain
+ try {
+ loadinfo.popRedirectedPrincipal(false);
+ ok(false, "should not be possible to pop from redirectChain");
+ }
+ catch(e) {
+ ok(true, "popping element from empty redirectChain should throw");
+ }
+
+ // try to pop an element from redirectChainIncludingInternalRedirects
+ try {
+ loadinfo.popRedirectedPrincipal(true);
+ ok(false, "should not be possible to pop from redirectChainIncludingInternalRedirects");
+ }
+ catch(e) {
+ ok(true, "popping element from empty redirectChainIncludingInternalRedirects should throw");
+ }
+ // move on to the next test
+ checkLoadInfoWithTwoRedirects();
+ }
+ myXHR.onerror = function() {
+ ok(false, "xhr problem within checkLoadInfoWithoutRedirect()");
+ }
+ myXHR.send();
+}
+
+// *************** TEST 2 ***************
+
+function checkLoadInfoWithTwoRedirects() {
+ var myXHR = new XMLHttpRequest();
+ myXHR.open("GET", "http://mochi.test:8888/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-2");
+
+ const EXPECTED_REDIRECT_CHAIN = [
+ "http://mochi.test:8888/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs",
+ "http://mochi.test:8888/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs"
+ ];
+
+ const EXPECTED_REDIRECT_CHAIN_INCLUDING_INTERNAL_REDIRECTS = EXPECTED_REDIRECT_CHAIN;
+
+ // Referrer header will not change when redirect
+ const EXPECTED_REFERRER =
+ "http://mochi.test:8888/tests/netwerk/test/mochitests/test_loadinfo_redirectchain.html";
+ const isAndroid = !!navigator.userAgent.includes("Android");
+ const EXPECTED_REMOTE_IP = isAndroid ? "10.0.2.2" : "127.0.0.1";
+
+ myXHR.onload = function() {
+ is(myXHR.responseText, "checking redirectchain", "sanity check to make sure redirects succeeded");
+
+ var loadinfo = SpecialPowers.wrap(myXHR).channel.loadInfo;
+
+ compareChains(loadinfo, EXPECTED_REDIRECT_CHAIN, EXPECTED_REDIRECT_CHAIN_INCLUDING_INTERNAL_REDIRECTS);
+
+ for (var i = 0; i < loadinfo.redirectChain.length; i++) {
+ is(loadinfo.redirectChain[i].referrerURI.spec, EXPECTED_REFERRER, "referrer should match");
+ is(loadinfo.redirectChain[i].remoteAddress, EXPECTED_REMOTE_IP, "remote address should match");
+ }
+
+ // move on to the next test
+ checkLoadInfoWithInternalRedirects();
+ }
+ myXHR.onerror = function() {
+ ok(false, "xhr problem within checkLoadInfoWithTwoRedirects()");
+ }
+ myXHR.send();
+}
+
+// *************** TEST 3 ***************
+
+function confirmCheckLoadInfoWithInternalRedirects(event) {
+ const EXPECTED_REDIRECT_CHAIN = [
+ "https://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-https-2",
+ "https://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-https-1"
+ ];
+
+ const EXPECTED_REDIRECT_CHAIN_INCLUDING_INTERNAL_REDIRECTS = [
+ "http://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-https-2",
+ "https://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-https-2",
+ "http://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-https-1",
+ "https://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-https-1",
+ "http://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-https-0",
+ ];
+
+ var loadinfo = JSON.parse(event.data.loadinfo);
+ compareChains(loadinfo, EXPECTED_REDIRECT_CHAIN, EXPECTED_REDIRECT_CHAIN_INCLUDING_INTERNAL_REDIRECTS);
+
+ // remove the postMessage listener and move on to the next test
+ window.removeEventListener("message", confirmCheckLoadInfoWithInternalRedirects);
+ checkLoadInfoWithInternalRedirectsAndFallback();
+}
+
+function checkLoadInfoWithInternalRedirects() {
+ // load the XHR request into an iframe so we can apply a CSP to the iframe
+ // a postMessage returns the result back to the main page.
+ window.addEventListener("message", confirmCheckLoadInfoWithInternalRedirects);
+ document.getElementById("testframe").src =
+ "https://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?iframe-redir-https-2";
+}
+
+// *************** TEST 4 ***************
+
+function confirmCheckLoadInfoWithInternalRedirectsAndFallback(event) {
+ var EXPECTED_REDIRECT_CHAIN = [
+ "https://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-err-2",
+ ];
+
+ var EXPECTED_REDIRECT_CHAIN_INCLUDING_INTERNAL_REDIRECTS = [
+ "http://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-err-2",
+ "https://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-err-2",
+ "http://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-err-1",
+ ];
+
+ var loadinfo = JSON.parse(event.data.loadinfo);
+ compareChains(loadinfo, EXPECTED_REDIRECT_CHAIN, EXPECTED_REDIRECT_CHAIN_INCLUDING_INTERNAL_REDIRECTS);
+
+ // remove the postMessage listener and finish test
+ window.removeEventListener("message", confirmCheckLoadInfoWithInternalRedirectsAndFallback);
+ checkHTTPURITruncation();
+}
+
+function checkLoadInfoWithInternalRedirectsAndFallback() {
+ // load the XHR request into an iframe so we can apply a CSP to the iframe
+ // a postMessage returns the result back to the main page.
+ window.addEventListener("message", confirmCheckLoadInfoWithInternalRedirectsAndFallback);
+ document.getElementById("testframe").src =
+ "https://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?iframe-redir-err-2";
+}
+
+// *************** TEST 5 ***************
+
+function checkHTTPURITruncation() {
+ var myXHR = new XMLHttpRequest();
+ myXHR.open("GET", "http://root:toor@mochi.test:8888/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-1#baz");
+
+ const EXPECTED_REDIRECT_CHAIN = [
+ "http://mochi.test:8888/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs", // redir-1
+ ];
+
+ var loadinfo = SpecialPowers.wrap(myXHR).channel.loadInfo;
+
+ myXHR.onload = function() {
+ var redirectChain = [];
+
+ for (var i = 0; i < loadinfo.redirectChain.length; i++) {
+ redirectChain[i] = loadinfo.redirectChain[i].principal.asciiSpec;
+ }
+
+ compareTruncatedChains(redirectChain, EXPECTED_REDIRECT_CHAIN);
+
+ // move on to the next test
+ checkHTTPSURITruncation();
+ }
+ myXHR.onerror = function(e) {
+ ok(false, "xhr problem within checkHTTPURITruncation()" + e);
+ }
+ myXHR.send();
+}
+
+// *************** TEST 6 ***************
+
+function confirmCheckHTTPSURITruncation(event) {
+ const EXPECTED_REDIRECT_CHAIN = [
+ "https://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs", // redir-https-2
+ "https://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs", // redir-https-1
+ ];
+
+ var loadinfo = JSON.parse(event.data.loadinfo);
+ compareTruncatedChains(loadinfo.redirectChain, EXPECTED_REDIRECT_CHAIN);
+
+ // remove the postMessage listener and move on to the next test
+ window.removeEventListener("message", confirmCheckHTTPSURITruncation);
+ SimpleTest.finish();
+}
+
+function checkHTTPSURITruncation() {
+ // load the XHR request into an iframe so we can apply a CSP to the iframe
+ // a postMessage returns the result back to the main page.
+ window.addEventListener("message", confirmCheckHTTPSURITruncation);
+ document.getElementById("testframe").src =
+ "https://root:toor@example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?iframe-redir-https-2#baz";
+}
+
+// *************** START TESTS ***************
+
+checkLoadInfoWithoutRedirects();
+
+</script>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/test_origin_header.html b/netwerk/test/mochitests/test_origin_header.html
new file mode 100644
index 0000000000..f90887ddf0
--- /dev/null
+++ b/netwerk/test/mochitests/test_origin_header.html
@@ -0,0 +1,398 @@
+<!DOCTYPE HTML>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<html>
+<head>
+ <title> Bug 446344 - Test Origin Header</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
+</head>
+<body>
+
+<p><a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=446344">Mozilla Bug 446344</a></p>
+
+<p id="display"></p>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+const EMPTY_ORIGIN = "Origin: ";
+
+let testsToRun = [
+ {
+ name: "sendOriginHeader=0 (never)",
+ prefs: [
+ ["network.http.sendOriginHeader", 0],
+ ],
+ results: {
+ framePost: EMPTY_ORIGIN,
+ framePostXOrigin: EMPTY_ORIGIN,
+ frameGet: EMPTY_ORIGIN,
+ framePostNonSandboxed: EMPTY_ORIGIN,
+ framePostNonSandboxedXOrigin: EMPTY_ORIGIN,
+ framePostSandboxed: EMPTY_ORIGIN,
+ framePostSrcDoc: EMPTY_ORIGIN,
+ framePostSrcDocXOrigin: EMPTY_ORIGIN,
+ framePostDataURI: EMPTY_ORIGIN,
+ framePostSameOriginToXOrigin: EMPTY_ORIGIN,
+ framePostXOriginToSameOrigin: EMPTY_ORIGIN,
+ framePostXOriginToXOrigin: EMPTY_ORIGIN,
+ },
+ },
+ {
+ name: "sendOriginHeader=1 (same-origin)",
+ prefs: [
+ ["network.http.sendOriginHeader", 1],
+ ],
+ results: {
+ framePost: "Origin: http://mochi.test:8888",
+ framePostXOrigin: "Origin: null",
+ frameGet: EMPTY_ORIGIN,
+ framePostNonSandboxed: "Origin: http://mochi.test:8888",
+ framePostNonSandboxedXOrigin: "Origin: null",
+ framePostSandboxed: "Origin: null",
+ framePostSrcDoc: "Origin: http://mochi.test:8888",
+ framePostSrcDocXOrigin: "Origin: null",
+ framePostDataURI: "Origin: null",
+ framePostSameOriginToXOrigin: "Origin: null",
+ framePostXOriginToSameOrigin: "Origin: null",
+ framePostXOriginToXOrigin: "Origin: null",
+ },
+ },
+ {
+ name: "sendOriginHeader=2 (always)",
+ prefs: [
+ ["network.http.sendOriginHeader", 2],
+ ],
+ results: {
+ framePost: "Origin: http://mochi.test:8888",
+ framePostXOrigin: "Origin: http://mochi.test:8888",
+ frameGet: EMPTY_ORIGIN,
+ framePostNonSandboxed: "Origin: http://mochi.test:8888",
+ framePostNonSandboxedXOrigin: "Origin: http://mochi.test:8888",
+ framePostSandboxed: "Origin: null",
+ framePostSrcDoc: "Origin: http://mochi.test:8888",
+ framePostSrcDocXOrigin: "Origin: http://mochi.test:8888",
+ framePostDataURI: "Origin: null",
+ framePostSameOriginToXOrigin: "Origin: http://mochi.test:8888",
+ framePostXOriginToSameOrigin: "Origin: null",
+ framePostXOriginToXOrigin: "Origin: http://mochi.test:8888",
+ },
+ },
+ {
+ name: "sendRefererHeader=0 (never)",
+ prefs: [
+ ["network.http.sendRefererHeader", 0],
+ ],
+ results: {
+ framePost: "Origin: http://mochi.test:8888",
+ framePostXOrigin: "Origin: http://mochi.test:8888",
+ frameGet: EMPTY_ORIGIN,
+ framePostNonSandboxed: "Origin: http://mochi.test:8888",
+ framePostNonSandboxedXOrigin: "Origin: http://mochi.test:8888",
+ framePostSandboxed: "Origin: null",
+ framePostSrcDoc: "Origin: http://mochi.test:8888",
+ framePostSrcDocXOrigin: "Origin: http://mochi.test:8888",
+ framePostDataURI: "Origin: null",
+ framePostSameOriginToXOrigin: "Origin: http://mochi.test:8888",
+ framePostXOriginToSameOrigin: "Origin: null",
+ framePostXOriginToXOrigin: "Origin: http://mochi.test:8888",
+ },
+ },
+ {
+ name: "userControlPolicy=0 (no-referrer)",
+ prefs: [
+ ["network.http.sendRefererHeader", 2],
+ ["network.http.referer.defaultPolicy", 0],
+ ],
+ results: {
+ framePost: "Origin: null",
+ framePostXOrigin: "Origin: null",
+ frameGet: EMPTY_ORIGIN,
+ framePostNonSandboxed: "Origin: null",
+ framePostNonSandboxedXOrigin: "Origin: null",
+ framePostSandboxed: "Origin: null",
+ framePostSrcDoc: "Origin: null",
+ framePostSrcDocXOrigin: "Origin: null",
+ framePostDataURI: "Origin: null",
+ framePostSameOriginToXOrigin: "Origin: null",
+ framePostXOriginToSameOrigin: "Origin: null",
+ framePostXOriginToXOrigin: "Origin: null",
+ },
+ },
+];
+
+let checksToRun = [
+ {
+ name: "POST",
+ frameID: "framePost",
+ formID: "formPost",
+ },
+ {
+ name: "cross-origin POST",
+ frameID: "framePostXOrigin",
+ formID: "formPostXOrigin",
+ },
+ {
+ name: "GET",
+ frameID: "frameGet",
+ formID: "formGet",
+ },
+ {
+ name: "POST inside iframe",
+ frameID: "framePostNonSandboxed",
+ frameSrc: "HTTP://mochi.test:8888/tests/netwerk/test/mochitests/origin_header_form_post.html",
+ },
+ {
+ name: "cross-origin POST inside iframe",
+ frameID: "framePostNonSandboxedXOrigin",
+ frameSrc: "Http://mochi.test:8888/tests/netwerk/test/mochitests/origin_header_form_post_xorigin.html",
+ },
+ {
+ name: "POST inside sandboxed iframe",
+ frameID: "framePostSandboxed",
+ frameSrc: "http://mochi.test:8888/tests/netwerk/test/mochitests/origin_header_form_post.html",
+ },
+ {
+ name: "POST inside a srcdoc iframe",
+ frameID: "framePostSrcDoc",
+ srcdoc: "origin_header_form_post.html",
+ },
+ {
+ name: "cross-origin POST inside a srcdoc iframe",
+ frameID: "framePostSrcDocXOrigin",
+ srcdoc: "origin_header_form_post_xorigin.html",
+ },
+ {
+ name: "POST inside a data: iframe",
+ frameID: "framePostDataURI",
+ dataURI: "origin_header_form_post.html",
+ },
+ {
+ name: "same-origin POST redirected to cross-origin",
+ frameID: "framePostSameOriginToXOrigin",
+ formID: "formPostSameOriginToXOrigin",
+ },
+ {
+ name: "cross-origin POST redirected to same-origin",
+ frameID: "framePostXOriginToSameOrigin",
+ formID: "formPostXOriginToSameOrigin",
+ },
+ {
+ name: "cross-origin POST redirected to cross-origin",
+ frameID: "framePostXOriginToXOrigin",
+ formID: "formPostXOriginToXOrigin",
+ },
+];
+
+function frameLoaded(test, check)
+{
+ let frame = window.document.getElementById(check.frameID);
+ frame.onload = null;
+ let result = SpecialPowers.wrap(frame).contentDocument.documentElement.textContent;
+ is(result, test.results[check.frameID], check.name + " with " + test.name);
+}
+
+function submitForm(test, check)
+{
+ return new Promise((resolve, reject) => {
+ document.getElementById(check.frameID).onload = () => {
+ frameLoaded(test, check);
+ resolve();
+ };
+ document.getElementById(check.formID).submit();
+ });
+}
+
+function loadIframe(test, check)
+{
+ return new Promise((resolve, reject) => {
+ let frame = SpecialPowers.wrap(window.document.getElementById(check.frameID));
+ frame.onload = function () {
+ // Ignore the first load and wait for the submitted form instead.
+ let location = frame.contentWindow.location + "";
+ if (location.endsWith("origin_header.sjs")) {
+ frameLoaded(test, check);
+ resolve();
+ }
+ }
+ frame.src = check.frameSrc;
+ });
+}
+
+function loadSrcDocFrame(test, check)
+{
+ return new Promise((resolve, reject) => {
+ let frame = SpecialPowers.wrap(window.document.getElementById(check.frameID));
+ frame.onload = function () {
+ // Ignore the first load and wait for the submitted form instead.
+ let location = frame.contentWindow.location + "";
+ if (location.endsWith("origin_header.sjs")) {
+ frameLoaded(test, check);
+ resolve();
+ }
+ }
+ fetch(check.srcdoc).then((response) => {
+ response.text().then((body) => {
+ frame.srcdoc = body;
+ });;
+ });
+ });
+ }
+
+function loadDataURIFrame(test, check)
+{
+ return new Promise((resolve, reject) => {
+ let frame = SpecialPowers.wrap(window.document.getElementById(check.frameID));
+ frame.onload = function () {
+ // Ignore the first load and wait for the submitted form instead.
+ let location = frame.contentWindow.location + "";
+ if (location.endsWith("origin_header.sjs")) {
+ frameLoaded(test, check);
+ resolve();
+ }
+ }
+ fetch(check.dataURI).then((response) => {
+ response.text().then((body) => {
+ frame.src = "data:text/html," + encodeURIComponent(body);
+ });;
+ });
+ });
+}
+
+async function resetFrames()
+{
+ let checkPromises = [];
+ for (let check of checksToRun) {
+ checkPromises.push(new Promise((resolve, reject) => {
+ let frame = document.getElementById(check.frameID);
+ frame.onload = () => resolve();
+ if (check.srcdoc) {
+ frame.srcdoc = "";
+ } else {
+ frame.src = "about:blank";
+ }
+ }));
+ }
+ await Promise.all(checkPromises);
+}
+
+async function runTests()
+{
+ for (let test of testsToRun) {
+ await resetFrames();
+ await SpecialPowers.pushPrefEnv({"set": test.prefs});
+
+ let checkPromises = [];
+ for (let check of checksToRun) {
+ if (check.formID) {
+ checkPromises.push(submitForm(test, check));
+ } else if (check.frameSrc) {
+ checkPromises.push(loadIframe(test, check));
+ } else if (check.srcdoc) {
+ checkPromises.push(loadSrcDocFrame(test, check));
+ } else if (check.dataURI) {
+ checkPromises.push(loadDataURIFrame(test, check));
+ } else {
+ ok(false, "Unsupported check");
+ break;
+ }
+ }
+ await Promise.all(checkPromises);
+ };
+ SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.requestLongerTimeout(5); // work around Android timeouts
+addLoadEvent(runTests);
+
+</script>
+</pre>
+<table>
+<tr>
+ <td>
+ <iframe src="about:blank" name="framePost" id="framePost"></iframe>
+ <form action="origin_header.sjs"
+ method="POST"
+ id="formPost"
+ target="framePost">
+ <input type="submit" value="Submit POST">
+ </form>
+ </td>
+ <td>
+ <iframe src="about:blank" name="framePostXOrigin" id="framePostXOrigin"></iframe>
+ <form action="http://test1.mochi.test:8888/tests/netwerk/test/mochitests/origin_header.sjs"
+ method="POST"
+ id="formPostXOrigin"
+ target="framePostXOrigin">
+ <input type="submit" value="Submit XOrigin POST">
+ </form>
+ </td>
+ <td>
+ <iframe src="about:blank" name="frameGet" id="frameGet"></iframe>
+ <form action="origin_header.sjs"
+ method="GET"
+ id="formGet"
+ target="frameGet">
+ <input type="submit" value="Submit GET">
+ </form>
+ </td>
+ <td>
+ <iframe src="about:blank" name="framePostSameOriginToXOrigin" id="framePostSameOriginToXOrigin"></iframe>
+ <form action="redirect_to.sjs?http://test1.mochi.test:8888/tests/netwerk/test/mochitests/origin_header.sjs"
+ method="POST"
+ id="formPostSameOriginToXOrigin"
+ target="framePostSameOriginToXOrigin">
+ <input type="Submit" value="Submit SameOrigin POST redirected to XOrigin">
+ </form>
+ </td>
+ <td>
+ <iframe src="about:blank" name="framePostXOriginToSameOrigin" id="framePostXOriginToSameOrigin"></iframe>
+ <form action="http://test1.mochi.test:8888/tests/netwerk/test/mochitests/redirect_to.sjs?http://mochi.test:8888/tests/netwerk/test/mochitests/origin_header.sjs"
+ method="POST"
+ id="formPostXOriginToSameOrigin"
+ target="framePostXOriginToSameOrigin">
+ <input type="Submit" value="Submit XOrigin POST redirected to SameOrigin">
+ </form>
+ </td>
+ <td>
+ <iframe src="about:blank" name="framePostXOriginToXOrigin" id="framePostXOriginToXOrigin"></iframe>
+ <form action="http://test1.mochi.test:8888/tests/netwerk/test/mochitests/redirect_to.sjs?/tests/netwerk/test/mochitests/origin_header.sjs"
+ method="POST"
+ id="formPostXOriginToXOrigin"
+ target="framePostXOriginToXOrigin">
+ <input type="Submit" value="Submit XOrigin POST redirected to XOrigin">
+ </form>
+ </td>
+</tr>
+<tr>
+ <td>
+ <iframe src="about:blank" id="framePostNonSandboxed"></iframe>
+ <div>Non-sandboxed iframe</div>
+ </td>
+ <td>
+ <iframe src="about:blank" id="framePostNonSandboxedXOrigin"></iframe>
+ <div>Non-sandboxed cross-origin iframe</div>
+ </td>
+ <td>
+ <iframe src="about:blank" id="framePostSandboxed" sandbox="allow-forms allow-scripts"></iframe>
+ <div>Sandboxed iframe</div>
+ </td>
+</tr>
+<tr>
+ <td>
+ <iframe id="framePostSrcDoc" src="about:blank"></iframe>
+ <div>Srcdoc iframe</div>
+ </td>
+ <td>
+ <iframe id="framePostSrcDocXOrigin" src="about:blank"></iframe>
+ <div>Srcdoc cross-origin iframe</div>
+ </td>
+ <td>
+ <iframe id="framePostDataURI" src="about:blank"></iframe>
+ <div>data: URI iframe</div>
+ </td>
+</tr>
+</table>
+
+</body>
+</html>
diff --git a/netwerk/test/mochitests/test_partially_cached_content.html b/netwerk/test/mochitests/test_partially_cached_content.html
new file mode 100644
index 0000000000..8b6df555f8
--- /dev/null
+++ b/netwerk/test/mochitests/test_partially_cached_content.html
@@ -0,0 +1,95 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+ https://bugzilla.mozilla.org/show_bug.cgi?id=497003
+
+ This test verifies that partially cached content is read from the cache first
+ and then from the network. It is written in the mochitest framework to take
+ thread retargeting into consideration of nsIStreamListener callbacks (inc.
+ nsIRequestObserver). E.g. HTML5 Stream Parser requesting retargeting of
+ nsIStreamListener callbacks to the parser thread.
+-->
+<head>
+ <meta charset="UTF-8">
+ <title>Test for Bug 497003: support sending OnDataAvailable() to other threads</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+ <p><a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=497003">Mozilla Bug 497003: support sending OnDataAvailable() to other threads</a></p>
+ <p><iframe id="contentFrame" src="partial_content.sjs"></iframe></p>
+
+<pre id="test">
+<script>
+
+
+
+/* Check that the iframe has initial content only after the first load.
+ */
+function expectInitialContent(e) {
+ info("expectInitialContent",
+ "First response received: should have partial content");
+ var frameElement = document.getElementById('contentFrame');
+ var frameWindow = frameElement.contentWindow;
+
+ // Expect "First response" in received HTML.
+ var firstResponse = frameWindow.document.getElementById('firstResponse');
+ ok(firstResponse, "First response should exist");
+ if (firstResponse) {
+ is(firstResponse.innerHTML, "First response",
+ "First response should be correct");
+ }
+
+ // Expect NOT to get any second response element.
+ var secondResponse = frameWindow.document.getElementById('secondResponse');
+ ok(!secondResponse, "Should not get text for second response in first.");
+
+ // Set up listener for second load.
+ removeEventListener("load", expectInitialContent, false);
+ frameElement.addEventListener("load", expectFullContent);
+
+ var reload = ()=>frameElement.src = "partial_content.sjs";
+
+ // Before reload, disable rcwn to avoid racing and a non-range request.
+ SpecialPowers.pushPrefEnv({set: [["network.http.rcwn.enabled", false]]},
+ reload);
+}
+
+/* Check that the iframe has all the content after the second load.
+ */
+function expectFullContent(e)
+{
+ info("expectFullContent",
+ "Second response received: should complete content from first load");
+ var frameWindow = document.getElementById('contentFrame').contentWindow;
+
+ // Expect "First response" to still be there
+ var firstResponse = frameWindow.document.getElementById('firstResponse');
+ ok(firstResponse, "First response should exist");
+ if (firstResponse) {
+ is(firstResponse.innerHTML, "First response",
+ "First response should be correct");
+ }
+
+ // Expect "Second response" to be there also.
+ var secondResponse = frameWindow.document.getElementById('secondResponse');
+ ok(secondResponse, "Second response should exist");
+ if (secondResponse) {
+ is(secondResponse.innerHTML, "Second response",
+ "Second response should be correct");
+ }
+
+ SimpleTest.finish();
+}
+
+// Set listener for first load to expect partial content.
+// Note: Set listener on the global object/window since 'load' should not fire
+// for partially loaded content in an iframe.
+addEventListener("load", expectInitialContent, false);
+
+SimpleTest.waitForExplicitFinish();
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/test_redirect_ref.html b/netwerk/test/mochitests/test_redirect_ref.html
new file mode 100644
index 0000000000..0b234695d4
--- /dev/null
+++ b/netwerk/test/mochitests/test_redirect_ref.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title> Bug 1234575 - Test redirect ref</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+
+<pre id="test">
+<script type="text/javascript">
+
+SimpleTest.waitForExplicitFinish();
+
+var iframe = document.createElement("iframe");
+iframe.src = "about:blank";
+iframe.addEventListener("load", finishTest);
+document.body.appendChild(iframe);
+iframe.src = "redirect.sjs#start";
+
+function finishTest(e) {
+ is(iframe.contentWindow.location.href, "http://mochi.test:8888/tests/netwerk/test/mochitests/empty.html#");
+ SimpleTest.finish();
+}
+
+</script>
+
+</body>
+</html>
diff --git a/netwerk/test/mochitests/test_rel_preconnect.html b/netwerk/test/mochitests/test_rel_preconnect.html
new file mode 100644
index 0000000000..c7e0bada07
--- /dev/null
+++ b/netwerk/test/mochitests/test_rel_preconnect.html
@@ -0,0 +1,61 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+-->
+<head>
+ <title>Test for link rel=preconnect</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+
+<script type="text/javascript">
+SimpleTest.waitForExplicitFinish();
+
+const Cc = SpecialPowers.Cc, Ci = SpecialPowers.Ci, Cr = SpecialPowers.Cr;
+
+var remainder = 4;
+var observer;
+
+async function doTest()
+{
+ await SpecialPowers.setBoolPref("network.http.debug-observations", true);
+
+ observer = SpecialPowers.wrapCallback(function(subject, topic, data) {
+ remainder--;
+ ok(true, "observed remainder = " + remainder);
+ if (!remainder) {
+ SpecialPowers.removeObserver(observer, "speculative-connect-request");
+ SpecialPowers.setBoolPref("network.http.debug-observations", false);
+ SimpleTest.finish();
+ }
+ });
+ SpecialPowers.addObserver(observer, "speculative-connect-request");
+
+ // test the link rel=preconnect element in the head for both normal
+ // and crossOrigin=anonymous
+ var link = document.createElement("link");
+ link.rel = "preconnect";
+ link.href = "//localhost:8888";
+ document.head.appendChild(link);
+ link = document.createElement("link");
+ link.rel = "preconnect";
+ link.href = "//localhost:8888";
+ link.crossOrigin = "anonymous";
+ document.head.appendChild(link);
+
+ // test the http link response header - the test contains both a
+ // normal and anonymous preconnect link header
+ var iframe = document.createElement('iframe');
+ iframe.src = 'rel_preconnect.sjs?//localhost:8888';
+
+ document.body.appendChild(iframe);
+}
+
+</script>
+</head>
+<body onload="doTest();">
+<p id="display"></p>
+<div id="content" style="display: none"></div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/test_same_base_domain.html b/netwerk/test/mochitests/test_same_base_domain.html
new file mode 100644
index 0000000000..bcf069e8be
--- /dev/null
+++ b/netwerk/test/mochitests/test_same_base_domain.html
@@ -0,0 +1,15 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for Cross domain access to properties</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body onload="setupTest('https://test1.example.org/tests/netwerk/test/mochitests/file_domain_inner.html', 5, 2)">
+<p id="display"></p>
+<pre id="test">
+<script class="testbody" type="text/javascript" src="file_testcommon.js">
+</script>
+</pre>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/test_same_base_domain_2.html b/netwerk/test/mochitests/test_same_base_domain_2.html
new file mode 100644
index 0000000000..5647831c29
--- /dev/null
+++ b/netwerk/test/mochitests/test_same_base_domain_2.html
@@ -0,0 +1,15 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for Cross domain access to properties</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body onload="setupTest('https://test1.example.org/tests/netwerk/test/mochitests/file_subdomain_inner.html', 5, 2)">
+<p id="display"></p>
+<pre id="test">
+<script class="testbody" type="text/javascript" src="file_testcommon.js">
+</script>
+</pre>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/test_same_base_domain_3.html b/netwerk/test/mochitests/test_same_base_domain_3.html
new file mode 100644
index 0000000000..62a4cfba95
--- /dev/null
+++ b/netwerk/test/mochitests/test_same_base_domain_3.html
@@ -0,0 +1,15 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for Cross domain access to properties</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body onload="setupTest('https://example.org/tests/netwerk/test/mochitests/file_subdomain_inner.html', 5, 2)">
+<p id="display"></p>
+<pre id="test">
+<script class="testbody" type="text/javascript" src="file_testcommon.js">
+</script>
+</pre>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/test_same_base_domain_4.html b/netwerk/test/mochitests/test_same_base_domain_4.html
new file mode 100644
index 0000000000..87fbb1c720
--- /dev/null
+++ b/netwerk/test/mochitests/test_same_base_domain_4.html
@@ -0,0 +1,15 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for Cross domain access to properties</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body onload="setupTest('http://mochi.test:8888/tests/netwerk/test/mochitests/file_localhost_inner.html', 5, 2)">
+<p id="display"></p>
+<pre id="test">
+<script class="testbody" type="text/javascript" src="file_testcommon.js">
+</script>
+</pre>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/test_same_base_domain_5.html b/netwerk/test/mochitests/test_same_base_domain_5.html
new file mode 100644
index 0000000000..7e4d2e3b1f
--- /dev/null
+++ b/netwerk/test/mochitests/test_same_base_domain_5.html
@@ -0,0 +1,15 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for Cross domain access to properties</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body onload="setupTest('https://sub.sectest2.example.org/tests/netwerk/test/mochitests/file_subdomain_inner.html', 5, 2)">
+<p id="display"></p>
+<pre id="test">
+<script class="testbody" type="text/javascript" src="file_testcommon.js">
+</script>
+</pre>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/test_same_base_domain_6.html b/netwerk/test/mochitests/test_same_base_domain_6.html
new file mode 100644
index 0000000000..195c38657b
--- /dev/null
+++ b/netwerk/test/mochitests/test_same_base_domain_6.html
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for Cross domain access to properties</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body onload="runThisTest()">
+<p id="display"></p>
+<pre id="test">
+ <script>
+ function runThisTest() {
+ // By default, proxies don't apply to 127.0.0.1.
+ // We need them to for this test (at least on android), though:
+ SpecialPowers.pushPrefEnv({set: [
+ ["network.proxy.allow_hijacking_localhost", true]
+ ]}).then(function() {
+ setupTest('http://127.0.0.1:8888/tests/netwerk/test/mochitests/file_loopback_inner.html', 5, 2);
+ });
+ }
+ </script>
+<script class="testbody" type="text/javascript" src="file_testcommon.js">
+</script>
+</pre>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/test_samedomain.html b/netwerk/test/mochitests/test_samedomain.html
new file mode 100644
index 0000000000..82aace8bab
--- /dev/null
+++ b/netwerk/test/mochitests/test_samedomain.html
@@ -0,0 +1,15 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for Cross domain access to properties</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body onload="setupTest('http://example.org/tests/netwerk/test/mochitests/file_domain_inner.html', 5, 2)">
+<p id="display"></p>
+<pre id="test">
+<script class="testbody" type="text/javascript" src="file_testcommon.js">
+</script>
+</pre>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/test_uri_scheme.html b/netwerk/test/mochitests/test_uri_scheme.html
new file mode 100644
index 0000000000..b0c247f336
--- /dev/null
+++ b/netwerk/test/mochitests/test_uri_scheme.html
@@ -0,0 +1,50 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+-->
+<head>
+ <title>Test for URI Manipulation</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+
+<script type="text/javascript">
+function dotest1()
+{
+ SimpleTest.waitForExplicitFinish();
+ var o = new URL("http://localhost/");
+ try { o.href = "foopy:bar:baz"; } catch(e) { }
+ o.protocol = "http:";
+ o.hostname;
+ try { o.href = "http://localhost/"; } catch(e) { }
+ ok(o.protocol, "http:");
+ dotest2();
+}
+
+function dotest2()
+{
+ var o = new URL("http://www.mozilla.org/");
+ try {
+ o.href ="aaaaaaaaaaa:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
+ } catch(e) { }
+ o.hash = "#";
+ o.pathname = "/";
+ o.protocol = "http:";
+ try { o.href = "http://localhost/"; } catch(e) { }
+ ok(o.protocol, "http:");
+ dotest3();
+}
+
+function dotest3()
+{
+ is(new URL("resource://123/").href, "resource://123/");
+ SimpleTest.finish();
+}
+</script>
+</head>
+<body onload="dotest1();">
+<p id="display"></p>
+<div id="content" style="display: none"></div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/test_url_perf.html b/netwerk/test/mochitests/test_url_perf.html
new file mode 100644
index 0000000000..c403398f06
--- /dev/null
+++ b/netwerk/test/mochitests/test_url_perf.html
@@ -0,0 +1,75 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Networking performance test: url parsing</title>
+</head>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<script>
+
+ // this test is just used locally to get an idea of how long url parsing takes
+ "use strict";
+
+ let runs = 20000;
+ let timeToCreateDataUrl = 0;
+ let timeToCreateDataSlashUrl = 0;
+ let timeToCreateJsUrl = 0;
+ let timeToCreateJsSlashUrl = 0;
+
+ // data scheme
+ add_task(async () => {
+ let before = new Date().getTime();
+ for (let i = 0; i < runs; i++) {
+ new URL("data:,test" + i);
+ }
+ let after = new Date().getTime();
+ timeToCreateDataUrl = after - before;
+ dump(
+ "Time to create data url (milliseconds): " + timeToCreateDataUrl + "\n"
+ );
+ });
+
+ // data://
+ add_task(async () => {
+ let before = new Date().getTime();
+ for (let i = 0; i < runs; i++) {
+ new URL("data://,test" + i);
+ }
+ let after = new Date().getTime();
+ timeToCreateDataSlashUrl = after - before;
+ dump(
+ "Time to create data // url (milliseconds): " + timeToCreateDataSlashUrl + "\n"
+ );
+ });
+
+ // javascript scheme
+ add_task(async () => {
+ let beforeJs = new Date().getTime();
+ for (let i = 0; i < runs; i++) {
+ new URL("javascript:,test" + i);
+ }
+ let afterJs = new Date().getTime();
+ timeToCreateJsUrl = afterJs - beforeJs;
+ dump(
+ "Time to create JS url (milliseconds): " + timeToCreateJsUrl + "\n"
+ );
+ });
+
+ // javascript://
+ add_task(async () => {
+ let beforeJs = new Date().getTime();
+ for (let i = 0; i < runs; i++) {
+ new URL("javascript://,test" + i);
+ }
+ let afterJs = new Date().getTime();
+ timeToCreateJsSlashUrl = afterJs - beforeJs;
+ dump(
+ "Time to create JS // url (milliseconds): " + timeToCreateJsSlashUrl + "\n"
+ );
+ });
+
+ ok("finished");
+
+</script>
+<body>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/test_viewsource_unlinkable.html b/netwerk/test/mochitests/test_viewsource_unlinkable.html
new file mode 100644
index 0000000000..f4c4064183
--- /dev/null
+++ b/netwerk/test/mochitests/test_viewsource_unlinkable.html
@@ -0,0 +1,25 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+-->
+<head>
+ <title>Test for view-source linkability</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+
+<script type="text/javascript">
+function runTest() {
+ SimpleTest.doesThrow(function() {
+ window.open('view-source:' + location.href, "_blank");
+ }, "Trying to access view-source URL from unprivileged code should throw.");
+ SimpleTest.finish();
+}
+</script>
+</head>
+<body onload="runTest();">
+<p id="display"></p>
+<div id="content" style="display: none"></div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/test_xhr_method_case.html b/netwerk/test/mochitests/test_xhr_method_case.html
new file mode 100644
index 0000000000..ddb830328c
--- /dev/null
+++ b/netwerk/test/mochitests/test_xhr_method_case.html
@@ -0,0 +1,65 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+XHR uppercases certain method names, but not others
+-->
+<head>
+ <title>Test for XHR Method casing</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+
+<script type="text/javascript">
+
+const testMethods = [
+// these methods should be normalized
+ ["get", "GET"],
+ ["GET", "GET"],
+ ["GeT", "GET"],
+ ["geT", "GET"],
+ ["GEt", "GET"],
+ ["post", "POST"],
+ ["POST", "POST"],
+ ["delete", "DELETE"],
+ ["DELETE", "DELETE"],
+ ["options", "OPTIONS"],
+ ["OPTIONS", "OPTIONS"],
+ ["put", "PUT"],
+ ["PUT", "PUT"],
+// HEAD is not tested because we use the resposne body as part of the test
+// ["head", "HEAD"],
+// ["HEAD", "HEAD"],
+
+// other custom methods should not be normalized
+ ["Foo", "Foo"],
+ ["bAR", "bAR"],
+ ["foobar", "foobar"],
+ ["FOOBAR", "FOOBAR"]
+]
+
+function doIter(index)
+{
+ var xhr = new XMLHttpRequest();
+ xhr.open(testMethods[index][0], 'method.sjs', false); // sync request
+ xhr.send();
+ is(xhr.status, 200, 'transaction failed');
+ is(xhr.response, testMethods[index][1], 'unexpected method');
+}
+
+function dotest()
+{
+ SimpleTest.waitForExplicitFinish();
+ for (var i = 0; i < testMethods.length; i++) {
+ doIter(i);
+ }
+ SimpleTest.finish();
+}
+
+</script>
+</head>
+<body onload="dotest();">
+<p id="display"></p>
+<div id="content" style="display: none"></div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/web_packaged_app.sjs b/netwerk/test/mochitests/web_packaged_app.sjs
new file mode 100644
index 0000000000..772b8a0835
--- /dev/null
+++ b/netwerk/test/mochitests/web_packaged_app.sjs
@@ -0,0 +1,47 @@
+function handleRequest(request, response) {
+ response.setHeader("Content-Type", "application/package", false);
+ response.write(octetStreamData.getData());
+}
+
+// The package content
+// getData formats it as described at http://www.w3.org/TR/web-packaging/#streamable-package-format
+var octetStreamData = {
+ content: [
+ {
+ headers: ["Content-Location: /index.html", "Content-Type: text/html"],
+ data: "<html>\r\n <head>\r\n <script> alert('OK: hello'); alert('DONE'); </script>\r\n</head>\r\n Web Packaged App Index\r\n</html>\r\n",
+ type: "text/html",
+ },
+ {
+ headers: [
+ "Content-Location: /scripts/app.js",
+ "Content-Type: text/javascript",
+ ],
+ data: "module Math from '/scripts/helpers/math.js';\r\n...\r\n",
+ type: "text/javascript",
+ },
+ {
+ headers: [
+ "Content-Location: /scripts/helpers/math.js",
+ "Content-Type: text/javascript",
+ ],
+ data: "export function sum(nums) { ... }\r\n...\r\n",
+ type: "text/javascript",
+ },
+ ],
+ token: "gc0pJq0M:08jU534c0p",
+ getData() {
+ var str = "";
+ for (var i in this.content) {
+ str += "--" + this.token + "\r\n";
+ for (var j in this.content[i].headers) {
+ str += this.content[i].headers[j] + "\r\n";
+ }
+ str += "\r\n";
+ str += this.content[i].data + "\r\n";
+ }
+
+ str += "--" + this.token + "--";
+ return str;
+ },
+};