mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-01 13:28:39 +09:00
283 lines
8.1 KiB
JavaScript
283 lines
8.1 KiB
JavaScript
var boundary = "1234567891011121314151617";
|
|
|
|
// fn(body) should create a Body subclass with content body treated as
|
|
// FormData and return it.
|
|
function testFormDataParsing(fn) {
|
|
|
|
function makeTest(shouldPass, input, testFn) {
|
|
var obj = fn(input);
|
|
return obj.formData().then(function(fd) {
|
|
ok(shouldPass, "Expected test to be valid FormData for " + input);
|
|
if (testFn) {
|
|
return testFn(fd);
|
|
}
|
|
}, function(e) {
|
|
if (shouldPass) {
|
|
ok(false, "Expected test to pass for " + input);
|
|
} else {
|
|
ok(e.name == "TypeError", "Error should be a TypeError.");
|
|
}
|
|
});
|
|
}
|
|
|
|
// [shouldPass?, input, testFn]
|
|
var tests =
|
|
[
|
|
[ true,
|
|
|
|
boundary +
|
|
'\r\nContent-Disposition: form-data; name="greeting"\r\n\r\n"hello"\r\n' +
|
|
boundary + '-',
|
|
|
|
function(fd) {
|
|
is(fd.get("greeting"), '"hello"');
|
|
}
|
|
],
|
|
[ false,
|
|
|
|
// Invalid disposition.
|
|
boundary +
|
|
'\r\nContent-Disposition: form-datafoobar; name="greeting"\r\n\r\n"hello"\r\n' +
|
|
boundary + '-',
|
|
],
|
|
[ true,
|
|
|
|
'--' +
|
|
boundary +
|
|
'\r\nContent-Disposition: form-data; name="greeting"\r\n\r\n"hello"\r\n' +
|
|
boundary + '-',
|
|
|
|
function(fd) {
|
|
is(fd.get("greeting"), '"hello"');
|
|
}
|
|
],
|
|
[ false,
|
|
boundary + "\r\n\r\n" + boundary + '-',
|
|
],
|
|
[ false,
|
|
// No valid ending.
|
|
boundary + "\r\n\r\n" + boundary,
|
|
],
|
|
[ false,
|
|
|
|
// One '-' prefix is not allowed. 2 or none.
|
|
'-' +
|
|
boundary +
|
|
'\r\nContent-Disposition: form-data; name="greeting"\r\n\r\n"hello"\r\n' +
|
|
boundary + '-',
|
|
],
|
|
[ false,
|
|
|
|
'invalid' +
|
|
boundary +
|
|
'\r\nContent-Disposition: form-data; name="greeting"\r\n\r\n"hello"\r\n' +
|
|
boundary + '-',
|
|
],
|
|
[ false,
|
|
|
|
boundary + 'suffix' +
|
|
'\r\nContent-Disposition: form-data; name="greeting"\r\n\r\n"hello"\r\n' +
|
|
boundary + '-',
|
|
],
|
|
[ false,
|
|
|
|
boundary + 'suffix' +
|
|
'\r\nContent-Disposition: form-data; name="greeting"\r\n\r\n"hello"\r\n' +
|
|
boundary + '-',
|
|
],
|
|
[ false,
|
|
|
|
// Partial boundary
|
|
boundary.substr(3) +
|
|
'\r\nContent-Disposition: form-data; name="greeting"\r\n\r\n"hello"\r\n' +
|
|
boundary + '-',
|
|
],
|
|
[ false,
|
|
|
|
boundary +
|
|
// Missing '\n' at beginning.
|
|
'\rContent-Disposition: form-data; name="greeting"\r\n\r\n"hello"\r\n' +
|
|
boundary + '-',
|
|
],
|
|
[ false,
|
|
|
|
boundary +
|
|
// No form-data.
|
|
'\r\nContent-Disposition: mixed; name="greeting"\r\n\r\n"hello"\r\n' +
|
|
boundary + '-',
|
|
],
|
|
[ false,
|
|
|
|
boundary +
|
|
// No headers.
|
|
'\r\n\r\n"hello"\r\n' +
|
|
boundary + '-',
|
|
],
|
|
[ false,
|
|
|
|
boundary +
|
|
// No content-disposition.
|
|
'\r\nContent-Dispositypo: form-data; name="greeting"\r\n\r\n"hello"\r\n' +
|
|
boundary + '-',
|
|
],
|
|
[ false,
|
|
|
|
boundary +
|
|
// No name.
|
|
'\r\nContent-Disposition: form-data;\r\n\r\n"hello"\r\n' +
|
|
boundary + '-',
|
|
],
|
|
[ false,
|
|
|
|
boundary +
|
|
// Missing empty line between headers and body.
|
|
'\r\nContent-Disposition: form-data; name="greeting"\r\n"hello"\r\n' +
|
|
boundary + '-',
|
|
],
|
|
[ false,
|
|
|
|
// Empty entry followed by valid entry.
|
|
boundary + "\r\n\r\n" + boundary +
|
|
'\r\nContent-Disposition: form-data; name="greeting"\r\n\r\n"hello"\r\n' +
|
|
boundary + '-',
|
|
],
|
|
[ false,
|
|
|
|
boundary +
|
|
// Header followed by empty line, but empty body not followed by
|
|
// newline.
|
|
'\r\nContent-Disposition: form-data; name="greeting"\r\n\r\n' +
|
|
boundary + '-',
|
|
],
|
|
[ true,
|
|
|
|
boundary +
|
|
// Empty body followed by newline.
|
|
'\r\nContent-Disposition: form-data; name="greeting"\r\n\r\n\r\n' +
|
|
boundary + '-',
|
|
|
|
function(fd) {
|
|
is(fd.get("greeting"), "", "Empty value is allowed.");
|
|
}
|
|
],
|
|
[ false,
|
|
boundary +
|
|
// Value is boundary itself.
|
|
'\r\nContent-Disposition: form-data; name="greeting"\r\n\r\n' +
|
|
boundary + '\r\n' +
|
|
boundary + '-',
|
|
],
|
|
[ false,
|
|
boundary +
|
|
// Variant of above with no valid ending boundary.
|
|
'\r\nContent-Disposition: form-data; name="greeting"\r\n\r\n' +
|
|
boundary
|
|
],
|
|
[ true,
|
|
boundary +
|
|
// Unquoted filename with empty body.
|
|
'\r\nContent-Disposition: form-data; name="file"; filename=file1.txt\r\n\r\n\r\n' +
|
|
boundary + '-',
|
|
|
|
function(fd) {
|
|
var f = fd.get("file");
|
|
ok(f instanceof File, "Entry with filename attribute should be read as File.");
|
|
is(f.name, "file1.txt", "Filename should match.");
|
|
is(f.type, "text/plain", "Default content-type should be text/plain.");
|
|
return readAsText(f).then(function(text) {
|
|
is(text, "", "File should be empty.");
|
|
});
|
|
}
|
|
],
|
|
[ true,
|
|
boundary +
|
|
// Quoted filename with empty body.
|
|
'\r\nContent-Disposition: form-data; name="file"; filename="file1.txt"\r\n\r\n\r\n' +
|
|
boundary + '-',
|
|
|
|
function(fd) {
|
|
var f = fd.get("file");
|
|
ok(f instanceof File, "Entry with filename attribute should be read as File.");
|
|
is(f.name, "file1.txt", "Filename should match.");
|
|
is(f.type, "text/plain", "Default content-type should be text/plain.");
|
|
return readAsText(f).then(function(text) {
|
|
is(text, "", "File should be empty.");
|
|
});
|
|
}
|
|
],
|
|
[ false,
|
|
boundary +
|
|
// Invalid filename
|
|
'\r\nContent-Disposition: form-data; name="file"; filename="[\n@;xt"\r\n\r\n\r\n' +
|
|
boundary + '-',
|
|
],
|
|
[ true,
|
|
boundary +
|
|
'\r\nContent-Disposition: form-data; name="file"; filename="[@;xt"\r\n\r\n\r\n' +
|
|
boundary + '-',
|
|
|
|
function(fd) {
|
|
var f = fd.get("file");
|
|
ok(f instanceof File, "Entry with filename attribute should be read as File.");
|
|
is(f.name, "[@", "Filename should match.");
|
|
}
|
|
],
|
|
[ true,
|
|
boundary +
|
|
'\r\nContent-Disposition: form-data; name="file"; filename="file with spaces"\r\n\r\n\r\n' +
|
|
boundary + '-',
|
|
|
|
function(fd) {
|
|
var f = fd.get("file");
|
|
ok(f instanceof File, "Entry with filename attribute should be read as File.");
|
|
is(f.name, "file with spaces", "Filename should match.");
|
|
}
|
|
],
|
|
[ true,
|
|
boundary + '\r\n' +
|
|
'Content-Disposition: form-data; name="file"; filename="xml.txt"\r\n' +
|
|
'content-type : application/xml\r\n' +
|
|
'\r\n' +
|
|
'<body>foobar\r\n\r\n</body>\r\n' +
|
|
boundary + '-',
|
|
|
|
function(fd) {
|
|
var f = fd.get("file");
|
|
ok(f instanceof File, "Entry with filename attribute should be read as File.");
|
|
is(f.name, "xml.txt", "Filename should match.");
|
|
is(f.type, "application/xml", "content-type should be application/xml.");
|
|
return readAsText(f).then(function(text) {
|
|
is(text, "<body>foobar\r\n\r\n</body>", "File should have correct text.");
|
|
});
|
|
}
|
|
],
|
|
];
|
|
|
|
var promises = [];
|
|
for (var i = 0; i < tests.length; ++i) {
|
|
var test = tests[i];
|
|
promises.push(makeTest(test[0], test[1], test[2]));
|
|
}
|
|
|
|
return Promise.all(promises);
|
|
}
|
|
|
|
function makeRequest(body) {
|
|
var req = new Request("", { method: 'post', body: body,
|
|
headers: {
|
|
'Content-Type': 'multipart/form-data; boundary=' + boundary
|
|
}});
|
|
return req;
|
|
}
|
|
|
|
function makeResponse(body) {
|
|
var res = new Response(body, { headers: {
|
|
'Content-Type': 'multipart/form-data; boundary=' + boundary
|
|
}});
|
|
return res;
|
|
}
|
|
|
|
function runTest() {
|
|
return Promise.all([testFormDataParsing(makeRequest),
|
|
testFormDataParsing(makeResponse)]);
|
|
}
|