зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1251175 - Removed dependence on CPOW. r=mconley
This commit is contained in:
Родитель
47d1fa5cde
Коммит
e244d2e2e3
|
@ -1,8 +1,9 @@
|
|||
[DEFAULT]
|
||||
support-files =
|
||||
manifestLoader.html
|
||||
file_reg_install_event.html
|
||||
file_testserver.sjs
|
||||
manifestLoader.html
|
||||
resource.sjs
|
||||
[browser_ManifestFinder_browserHasManifestLink.js]
|
||||
[browser_ManifestObtainer_obtain.js]
|
||||
[browser_fire_install_event.js]
|
|
@ -1,83 +1,54 @@
|
|||
//Used by JSHint:
|
||||
/*global Cu, BrowserTestUtils, is, ok, add_task, gBrowser, ManifestFinder */
|
||||
/*global Cu, BrowserTestUtils, ok, add_task, gBrowser */
|
||||
"use strict";
|
||||
Cu.import("resource://gre/modules/ManifestFinder.jsm", this); // jshint ignore:line
|
||||
const { ManifestFinder } = Cu.import("resource://gre/modules/ManifestFinder.jsm", {});
|
||||
const defaultURL = new URL("http://example.org/browser/dom/manifest/test/resource.sjs");
|
||||
defaultURL.searchParams.set("Content-Type", "text/html; charset=utf-8");
|
||||
|
||||
const defaultURL =
|
||||
"http://example.org/tests/dom/manifest/test/resource.sjs";
|
||||
const tests = [{
|
||||
expected: "Document has a web manifest.",
|
||||
get tabURL() {
|
||||
let query = [
|
||||
`body=<h1>${this.expected}</h1>`,
|
||||
"Content-Type=text/html; charset=utf-8",
|
||||
];
|
||||
const URL = `${defaultURL}?${query.join("&")}`;
|
||||
return URL;
|
||||
},
|
||||
body: `
|
||||
<link rel="manifesto" href='${defaultURL}?body={"name":"fail"}'>
|
||||
<link rel="foo bar manifest bar test" href='${defaultURL}?body={"name":"value"}'>
|
||||
<link rel="manifest" href='${defaultURL}?body={"name":"fail"}'>
|
||||
`,
|
||||
run(result) {
|
||||
is(result, true, this.expected);
|
||||
ok(result, "Document has a web manifest.");
|
||||
},
|
||||
testData: `
|
||||
<link rel="manifesto" href='${defaultURL}?body={"name":"fail"}'>
|
||||
<link rel="foo bar manifest bar test" href='${defaultURL}?body={"name":"value"}'>
|
||||
<link rel="manifest" href='${defaultURL}?body={"name":"fail"}'>`
|
||||
}, {
|
||||
expected: "Document does not have a web manifest.",
|
||||
get tabURL() {
|
||||
let query = [
|
||||
`body=<h1>${this.expected}</h1>`,
|
||||
"Content-Type=text/html; charset=utf-8",
|
||||
];
|
||||
const URL = `${defaultURL}?${query.join("&")}`;
|
||||
return URL;
|
||||
},
|
||||
body: `
|
||||
<link rel="amanifista" href='${defaultURL}?body={"name":"fail"}'>
|
||||
<link rel="foo bar manifesto bar test" href='${defaultURL}?body={"name":"pass-1"}'>
|
||||
<link rel="manifesto" href='${defaultURL}?body={"name":"fail"}'>`,
|
||||
run(result) {
|
||||
is(result, false, this.expected);
|
||||
ok(!result, "Document does not have a web manifest.");
|
||||
},
|
||||
testData: `
|
||||
<link rel="amanifista" href='${defaultURL}?body={"name":"fail"}'>
|
||||
<link rel="foo bar manifesto bar test" href='${defaultURL}?body={"name":"pass-1"}'>
|
||||
<link rel="manifesto" href='${defaultURL}?body={"name":"fail"}'>`
|
||||
}, {
|
||||
expected: "Manifest link is has empty href.",
|
||||
get tabURL() {
|
||||
let query = [
|
||||
`body=<h1>${this.expected}</h1>`,
|
||||
"Content-Type=text/html; charset=utf-8",
|
||||
];
|
||||
const URL = `${defaultURL}?${query.join("&")}`;
|
||||
return URL;
|
||||
},
|
||||
body: `
|
||||
<link rel="manifest" href="">
|
||||
<link rel="manifest" href='${defaultURL}?body={"name":"fail"}'>`,
|
||||
run(result) {
|
||||
is(result, false, this.expected);
|
||||
ok(!result, "Manifest link is has empty href.");
|
||||
},
|
||||
testData: `
|
||||
<link rel="manifest" href="">
|
||||
<link rel="manifest" href='${defaultURL}?body={"name":"fail"}'>`
|
||||
}, {
|
||||
expected: "Manifest link is missing.",
|
||||
get tabURL() {
|
||||
let query = [
|
||||
`body=<h1>${this.expected}</h1>`,
|
||||
"Content-Type=text/html; charset=utf-8",
|
||||
];
|
||||
const URL = `${defaultURL}?${query.join("&")}`;
|
||||
return URL;
|
||||
},
|
||||
run(result) {
|
||||
is(result, false, this.expected);
|
||||
},
|
||||
testData: `
|
||||
body: `
|
||||
<link rel="manifest">
|
||||
<link rel="manifest" href='${defaultURL}?body={"name":"fail"}'>`
|
||||
<link rel="manifest" href='${defaultURL}?body={"name":"fail"}'>`,
|
||||
run(result) {
|
||||
ok(!result, "Manifest link is missing.");
|
||||
},
|
||||
}];
|
||||
|
||||
function makeTestURL({ body }) {
|
||||
const url = new URL(defaultURL);
|
||||
url.searchParams.set("body", encodeURIComponent(body));
|
||||
return url.href;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test basic API error conditions
|
||||
*/
|
||||
add_task(function* () {
|
||||
let expected = "Invalid types should throw a TypeError.";
|
||||
add_task(function*() {
|
||||
const expected = "Invalid types should throw a TypeError.";
|
||||
for (let invalidValue of [undefined, null, 1, {}, "test"]) {
|
||||
try {
|
||||
yield ManifestFinder.contentManifestLink(invalidValue);
|
||||
|
@ -94,21 +65,20 @@ add_task(function* () {
|
|||
}
|
||||
});
|
||||
|
||||
add_task(function* () {
|
||||
for (let test of tests) {
|
||||
let tabOptions = {
|
||||
gBrowser: gBrowser,
|
||||
url: test.tabURL,
|
||||
};
|
||||
yield BrowserTestUtils.withNewTab(
|
||||
tabOptions,
|
||||
browser => testHasManifest(browser, test)
|
||||
add_task(function*() {
|
||||
const runningTests = tests
|
||||
.map(
|
||||
test => ({
|
||||
gBrowser,
|
||||
test,
|
||||
url: makeTestURL(test),
|
||||
})
|
||||
)
|
||||
.map(
|
||||
tabOptions => BrowserTestUtils.withNewTab(tabOptions, function*(browser) {
|
||||
const result = yield ManifestFinder.browserHasManifestLink(browser);
|
||||
tabOptions.test.run(result);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function* testHasManifest(aBrowser, aTest) {
|
||||
aBrowser.contentWindowAsCPOW.document.head.innerHTML = aTest.testData;
|
||||
const result = yield ManifestFinder.browserHasManifestLink(aBrowser);
|
||||
aTest.run(result);
|
||||
}
|
||||
yield Promise.all(runningTests);
|
||||
});
|
||||
|
|
|
@ -1,104 +1,53 @@
|
|||
//Used by JSHint:
|
||||
/*global requestLongerTimeout, Cu, BrowserTestUtils, add_task, SpecialPowers, gBrowser, Assert*/ 'use strict';
|
||||
const {
|
||||
ManifestObtainer
|
||||
} = Cu.import('resource://gre/modules/ManifestObtainer.jsm', {});
|
||||
/*global is, Cu, BrowserTestUtils, add_task, gBrowser, makeTestURL*/
|
||||
'use strict';
|
||||
const { ManifestObtainer } = Cu.import('resource://gre/modules/ManifestObtainer.jsm', {});
|
||||
const remoteURL = 'http://mochi.test:8888/browser/dom/manifest/test/resource.sjs';
|
||||
const defaultURL = new URL('http://example.org/browser/dom/manifest/test/resource.sjs');
|
||||
defaultURL.searchParams.set('Content-Type', 'text/html; charset=utf-8');
|
||||
|
||||
requestLongerTimeout(4); // e10s tests take time.
|
||||
const defaultURL =
|
||||
'http://example.org/tests/dom/manifest/test/resource.sjs';
|
||||
const remoteURL =
|
||||
'http://mochi.test:8888/tests/dom/manifest/test/resource.sjs';
|
||||
const tests = [
|
||||
// Fetch tests.
|
||||
{
|
||||
expected: 'Manifest is first `link` where @rel contains token manifest.',
|
||||
get tabURL() {
|
||||
let query = [
|
||||
`body=<h1>${this.expected}</h1>`,
|
||||
'Content-Type=text/html; charset=utf-8',
|
||||
];
|
||||
const URL = `${defaultURL}?${query.join('&')}`;
|
||||
return URL;
|
||||
},
|
||||
body: `
|
||||
<link rel="manifesto" href='resource.sjs?body={"name":"fail"}'>
|
||||
<link rel="foo bar manifest bar test" href='resource.sjs?body={"name":"pass-1"}'>
|
||||
<link rel="manifest" href='resource.sjs?body={"name":"fail"}'>`,
|
||||
run(manifest) {
|
||||
Assert.strictEqual(manifest.name, 'pass-1', this.expected);
|
||||
},
|
||||
testData: `
|
||||
<link rel="manifesto" href='${defaultURL}?body={"name":"fail"}'>
|
||||
<link rel="foo bar manifest bar test" href='${defaultURL}?body={"name":"pass-1"}'>
|
||||
<link rel="manifest" href='${defaultURL}?body={"name":"fail"}'>`
|
||||
is(manifest.name, 'pass-1', 'Manifest is first `link` where @rel contains token manifest.');
|
||||
}
|
||||
}, {
|
||||
expected: 'Manifest is first `link` where @rel contains token manifest.',
|
||||
get tabURL() {
|
||||
let query = [
|
||||
`body=<h1>${this.expected}</h1>`,
|
||||
'Content-Type=text/html; charset=utf-8',
|
||||
];
|
||||
const URL = `${defaultURL}?${query.join('&')}`;
|
||||
return URL;
|
||||
},
|
||||
run(manifest) {
|
||||
Assert.strictEqual(manifest.name, 'pass-2', this.expected);
|
||||
},
|
||||
testData: `
|
||||
body: `
|
||||
<link rel="foo bar manifest bar test" href='resource.sjs?body={"name":"pass-2"}'>
|
||||
<link rel="manifest" href='resource.sjs?body={"name":"fail"}'>
|
||||
<link rel="manifest foo bar test" href='resource.sjs?body={"name":"fail"}'>`
|
||||
<link rel="manifest foo bar test" href='resource.sjs?body={"name":"fail"}'>`,
|
||||
run(manifest) {
|
||||
is(manifest.name, 'pass-2', 'Manifest is first `link` where @rel contains token manifest.');
|
||||
},
|
||||
}, {
|
||||
expected: 'By default, manifest cannot load cross-origin.',
|
||||
get tabURL() {
|
||||
let query = [
|
||||
`body=<h1>${this.expected}</h1>`,
|
||||
'Content-Type=text/html; charset=utf-8',
|
||||
];
|
||||
const URL = `${defaultURL}?${query.join('&')}`;
|
||||
return URL;
|
||||
},
|
||||
body: `<link rel="manifest" href='${remoteURL}?body={"name":"pass-3"}'>`,
|
||||
run(err) {
|
||||
Assert.strictEqual(err.name, 'TypeError', this.expected);
|
||||
is(err.name, 'TypeError', 'By default, manifest cannot load cross-origin.');
|
||||
},
|
||||
testData: `<link rel="manifest" href='${remoteURL}?body={"name":"pass-3"}'>`
|
||||
},
|
||||
// CORS Tests.
|
||||
{
|
||||
expected: 'CORS enabled, manifest must be fetched.',
|
||||
get tabURL() {
|
||||
let query = [
|
||||
`body=<h1>${this.expected}</h1>`,
|
||||
'Content-Type=text/html; charset=utf-8',
|
||||
];
|
||||
const URL = `${defaultURL}?${query.join('&')}`;
|
||||
return URL;
|
||||
},
|
||||
run(manifest) {
|
||||
Assert.strictEqual(manifest.name, 'pass-4', this.expected);
|
||||
},
|
||||
get testData() {
|
||||
get body() {
|
||||
const body = 'body={"name": "pass-4"}';
|
||||
const CORS =
|
||||
`Access-Control-Allow-Origin=${new URL(this.tabURL).origin}`;
|
||||
`Access-Control-Allow-Origin=${defaultURL.origin}`;
|
||||
const link =
|
||||
`<link
|
||||
crossorigin=anonymous
|
||||
rel="manifest"
|
||||
href='${remoteURL}?${body}&${CORS}'>`;
|
||||
return link;
|
||||
}
|
||||
},
|
||||
run(manifest) {
|
||||
is(manifest.name, 'pass-4', 'CORS enabled, manifest must be fetched.');
|
||||
},
|
||||
}, {
|
||||
expected: 'Fetch blocked by CORS - origin does not match.',
|
||||
get tabURL() {
|
||||
let query = [
|
||||
`body=<h1>${this.expected}</h1>`,
|
||||
'Content-Type=text/html; charset=utf-8',
|
||||
];
|
||||
const URL = `${defaultURL}?${query.join('&')}`;
|
||||
return URL;
|
||||
},
|
||||
run(err) {
|
||||
Assert.strictEqual(err.name, 'TypeError', this.expected);
|
||||
},
|
||||
get testData() {
|
||||
get body() {
|
||||
const body = 'body={"name": "fail"}';
|
||||
const CORS = 'Access-Control-Allow-Origin=http://not-here';
|
||||
const link =
|
||||
|
@ -107,82 +56,60 @@ const tests = [
|
|||
rel="manifest"
|
||||
href='${remoteURL}?${body}&${CORS}'>`;
|
||||
return link;
|
||||
}
|
||||
},{
|
||||
expected: 'Trying to load from about:whatever is a TypeError.',
|
||||
get tabURL() {
|
||||
let query = [
|
||||
`body=<h1>${this.expected}</h1>`,
|
||||
'Content-Type=text/html; charset=utf-8',
|
||||
];
|
||||
const URL = `${defaultURL}?${query.join('&')}`;
|
||||
return URL;
|
||||
},
|
||||
run(err) {
|
||||
Assert.strictEqual(err.name, 'TypeError', this.expected);
|
||||
},
|
||||
testData: `<link rel="manifest" href='about:whatever'>`
|
||||
},
|
||||
{
|
||||
expected: 'Trying to load from file://whatever is a TypeError.',
|
||||
get tabURL() {
|
||||
let query = [
|
||||
`body=<h1>${this.expected}</h1>`,
|
||||
'Content-Type=text/html; charset=utf-8',
|
||||
];
|
||||
const URL = `${defaultURL}?${query.join('&')}`;
|
||||
return URL;
|
||||
is(err.name, 'TypeError', 'Fetch blocked by CORS - origin does not match.');
|
||||
},
|
||||
}, {
|
||||
body: `<link rel="manifest" href='about:whatever'>`,
|
||||
run(err) {
|
||||
Assert.strictEqual(err.name, 'TypeError', this.expected);
|
||||
is(err.name, 'TypeError', 'Trying to load from about:whatever is TypeError.');
|
||||
},
|
||||
}, {
|
||||
body: `<link rel="manifest" href='file://manifest'>`,
|
||||
run(err) {
|
||||
is(err.name, 'TypeError', 'Trying to load from file://whatever is a TypeError.');
|
||||
},
|
||||
testData: `<link rel="manifest" href='file://manifest'>`
|
||||
},
|
||||
//URL parsing tests
|
||||
{
|
||||
expected: 'Trying to load invalid URL is a TypeError.',
|
||||
get tabURL() {
|
||||
let query = [
|
||||
`body=<h1>${this.expected}</h1>`,
|
||||
'Content-Type=text/html; charset=utf-8',
|
||||
];
|
||||
const URL = `${defaultURL}?${query.join('&')}`;
|
||||
return URL;
|
||||
},
|
||||
body: `<link rel="manifest" href='http://[12.1212.21.21.12.21.12]'>`,
|
||||
run(err) {
|
||||
Assert.strictEqual(err.name, 'TypeError', this.expected);
|
||||
is(err.name, 'TypeError', 'Trying to load invalid URL is a TypeError.');
|
||||
},
|
||||
testData: `<link rel="manifest" href='http://[12.1212.21.21.12.21.12]'>`
|
||||
},
|
||||
];
|
||||
|
||||
add_task(function*() {
|
||||
yield new Promise(resolve => {
|
||||
SpecialPowers.pushPrefEnv({
|
||||
'set': [
|
||||
['dom.fetch.enabled', true]
|
||||
]
|
||||
}, resolve);
|
||||
});
|
||||
for (let test of tests) {
|
||||
let tabOptions = {
|
||||
gBrowser: gBrowser,
|
||||
url: test.tabURL,
|
||||
};
|
||||
yield BrowserTestUtils.withNewTab(
|
||||
tabOptions,
|
||||
browser => testObtainingManifest(browser, test)
|
||||
);
|
||||
}
|
||||
function makeTestURL({ body }) {
|
||||
const url = new URL(defaultURL);
|
||||
url.searchParams.set("body", encodeURIComponent(body));
|
||||
return url.href;
|
||||
}
|
||||
|
||||
function* testObtainingManifest(aBrowser, aTest) {
|
||||
aBrowser.contentWindowAsCPOW.document.head.innerHTML = aTest.testData;
|
||||
try {
|
||||
const manifest = yield ManifestObtainer.browserObtainManifest(aBrowser);
|
||||
aTest.run(manifest);
|
||||
} catch (e) {
|
||||
aTest.run(e);
|
||||
}
|
||||
add_task(function*() {
|
||||
const promises = tests
|
||||
.map(test => ({
|
||||
gBrowser,
|
||||
testRunner: testObtainingManifest(test),
|
||||
url: makeTestURL(test)
|
||||
}))
|
||||
.reduce((collector, tabOpts) => {
|
||||
const promise = BrowserTestUtils.withNewTab(tabOpts, tabOpts.testRunner);
|
||||
collector.push(promise);
|
||||
return collector;
|
||||
}, []);
|
||||
|
||||
const results = yield Promise.all(promises);
|
||||
|
||||
function testObtainingManifest(aTest) {
|
||||
return function*(aBrowser) {
|
||||
try {
|
||||
const manifest = yield ManifestObtainer.browserObtainManifest(aBrowser);
|
||||
aTest.run(manifest);
|
||||
} catch (e) {
|
||||
aTest.run(e);
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -192,36 +119,36 @@ add_task(function*() {
|
|||
* in each tab. They should all return pass.
|
||||
*/
|
||||
add_task(function*() {
|
||||
const defaultPath = '/tests/dom/manifest/test/manifestLoader.html';
|
||||
const defaultPath = '/browser/dom/manifest/test/manifestLoader.html';
|
||||
const tabURLs = [
|
||||
`http://test:80${defaultPath}`,
|
||||
`http://mochi.test:8888${defaultPath}`,
|
||||
`http://test1.mochi.test:8888${defaultPath}`,
|
||||
`http://sub1.test1.mochi.test:8888${defaultPath}`,
|
||||
`http://sub2.xn--lt-uia.mochi.test:8888${defaultPath}`,
|
||||
`http://test2.mochi.test:8888${defaultPath}`,
|
||||
`http://example.org:80${defaultPath}`,
|
||||
`http://test1.example.org:80${defaultPath}`,
|
||||
`http://test2.example.org:80${defaultPath}`,
|
||||
`http://sub1.test1.example.org:80${defaultPath}`,
|
||||
`http://sub1.test2.example.org:80${defaultPath}`,
|
||||
`http://sub2.test1.example.org:80${defaultPath}`,
|
||||
`http://sub2.test2.example.org:80${defaultPath}`,
|
||||
`http://example.org:8000${defaultPath}`,
|
||||
`http://test1.example.org:8000${defaultPath}`,
|
||||
`http://test2.example.org:8000${defaultPath}`,
|
||||
`http://sub1.test1.example.org:8000${defaultPath}`,
|
||||
`http://sub1.test2.example.org:8000${defaultPath}`,
|
||||
`http://sub2.test1.example.org:8000${defaultPath}`,
|
||||
`http://sub2.test2.example.org:8000${defaultPath}`,
|
||||
`http://example.com:80${defaultPath}`,
|
||||
`http://www.example.com:80${defaultPath}`,
|
||||
`http://test1.example.com:80${defaultPath}`,
|
||||
`http://test2.example.com:80${defaultPath}`,
|
||||
`http://example.org:80${defaultPath}`,
|
||||
`http://example.org:8000${defaultPath}`,
|
||||
`http://mochi.test:8888${defaultPath}`,
|
||||
`http://sub1.test1.example.com:80${defaultPath}`,
|
||||
`http://sub1.test1.example.org:80${defaultPath}`,
|
||||
`http://sub1.test1.example.org:8000${defaultPath}`,
|
||||
`http://sub1.test1.mochi.test:8888${defaultPath}`,
|
||||
`http://sub1.test2.example.com:80${defaultPath}`,
|
||||
`http://sub1.test2.example.org:80${defaultPath}`,
|
||||
`http://sub1.test2.example.org:8000${defaultPath}`,
|
||||
`http://sub2.test1.example.com:80${defaultPath}`,
|
||||
`http://sub2.test1.example.org:80${defaultPath}`,
|
||||
`http://sub2.test1.example.org:8000${defaultPath}`,
|
||||
`http://sub2.test2.example.com:80${defaultPath}`,
|
||||
`http://sub2.test2.example.org:80${defaultPath}`,
|
||||
`http://sub2.test2.example.org:8000${defaultPath}`,
|
||||
`http://sub2.xn--lt-uia.mochi.test:8888${defaultPath}`,
|
||||
`http://test1.example.com:80${defaultPath}`,
|
||||
`http://test1.example.org:80${defaultPath}`,
|
||||
`http://test1.example.org:8000${defaultPath}`,
|
||||
`http://test1.mochi.test:8888${defaultPath}`,
|
||||
`http://test2.example.com:80${defaultPath}`,
|
||||
`http://test2.example.org:80${defaultPath}`,
|
||||
`http://test2.example.org:8000${defaultPath}`,
|
||||
`http://test2.mochi.test:8888${defaultPath}`,
|
||||
`http://test:80${defaultPath}`,
|
||||
`http://www.example.com:80${defaultPath}`,
|
||||
];
|
||||
// Open tabs an collect corresponding browsers
|
||||
let browsers = [
|
||||
|
@ -236,9 +163,8 @@ add_task(function*() {
|
|||
const results = yield Promise.all((
|
||||
for (browser of randBrowsers(browsers, 100)) ManifestObtainer.browserObtainManifest(browser)
|
||||
));
|
||||
const expected = 'Expect every manifest to have name equal to `pass`.';
|
||||
const pass = results.every(manifest => manifest.name === 'pass');
|
||||
Assert.ok(pass, expected);
|
||||
ok(pass, 'Expect every manifest to have name equal to `pass`.');
|
||||
//cleanup
|
||||
browsers
|
||||
.map(browser => gBrowser.getTabForBrowser(browser))
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
*/
|
||||
//global handleRequest
|
||||
'use strict';
|
||||
Components.utils.importGlobalProperties(["URLSearchParams"]);
|
||||
const HTTPStatus = new Map([
|
||||
[100, 'Continue'],
|
||||
[101, 'Switching Protocol'],
|
||||
|
@ -66,7 +67,7 @@ const HTTPStatus = new Map([
|
|||
]);
|
||||
|
||||
function handleRequest(request, response) {
|
||||
const queryMap = createQueryMap(request);
|
||||
const queryMap = new URLSearchParams(request.queryString);
|
||||
if (queryMap.has('statusCode')) {
|
||||
let statusCode = parseInt(queryMap.get('statusCode'));
|
||||
let statusText = HTTPStatus.get(statusCode);
|
||||
|
@ -76,18 +77,9 @@ function handleRequest(request, response) {
|
|||
if (queryMap.has('body')) {
|
||||
let body = queryMap.get('body') || '';
|
||||
queryMap.delete('body');
|
||||
response.write(body);
|
||||
response.write(decodeURIComponent(body));
|
||||
}
|
||||
for (let [key, value] of queryMap) {
|
||||
for (let [key, value] of queryMap.entries()) {
|
||||
response.setHeader(key, value);
|
||||
}
|
||||
|
||||
function createQueryMap(request) {
|
||||
const queryMap = new Map();
|
||||
request.queryString.split('&')
|
||||
//split on first "="
|
||||
.map((component) => component.split(/=(.+)?/))
|
||||
.forEach(pair => queryMap.set(pair[0], decodeURIComponent(pair[1])));
|
||||
return queryMap;
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче