Bug 1203680 P1 Test file blob uploads with service worker interception. r=nsm

This commit is contained in:
Ben Kelly 2015-09-15 10:15:45 -07:00
parent 4ad9119bae
commit 02082548f3
4 changed files with 261 additions and 0 deletions

View File

@ -160,6 +160,8 @@ support-files =
fetch/plugin/worker.js
fetch/plugin/plugins.html
eventsource/*
sw_clients/file_blob_upload_frame.html
redirect_post.sjs
[test_app_protocol.html]
skip-if = release_build
@ -251,3 +253,4 @@ skip-if = toolkit == "android" || toolkit == "gonk"
[test_escapedSlashes.html]
[test_eventsource_intercept.html]
[test_not_intercept_plugin.html]
[test_file_blob_upload.html]

View File

@ -0,0 +1,35 @@
const CC = Components.Constructor;
const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1",
"nsIBinaryInputStream",
"setInputStream");
function handleRequest(request, response)
{
var query = {};
request.queryString.split('&').forEach(function (val) {
var [name, value] = val.split('=');
query[name] = unescape(value);
});
var bodyStream = new BinaryInputStream(request.bodyInputStream);
var bodyBytes = [];
while ((bodyAvail = bodyStream.available()) > 0)
Array.prototype.push.apply(bodyBytes, bodyStream.readByteArray(bodyAvail));
var body = decodeURIComponent(
escape(String.fromCharCode.apply(null, bodyBytes)));
var currentHop = query.hop ? parseInt(query.hop) : 0;
var obj = JSON.parse(body);
if (currentHop < obj.hops) {
var newURL = '/tests/dom/workers/test/serviceworkers/redirect_post.sjs?hop=' +
(1 + currentHop);
response.setStatusLine(null, 307, 'redirect');
response.setHeader('Location', newURL);
return;
}
response.setHeader('Content-Type', 'application/json');
response.write(body);
}

View File

@ -0,0 +1,77 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE HTML>
<html>
<head>
<title>test file blob upload with SW interception</title>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test"></pre>
<script class="testbody" type="text/javascript">
if (!parent) {
dump("sw_clients/file_blob_upload_frame.html shouldn't be launched directly!");
}
function makeFileBlob(obj) {
return new Promise(function(resolve, reject) {
var request = indexedDB.open(window.location.pathname, 1);
request.onerror = reject;
request.onupgradeneeded = function(evt) {
var db = evt.target.result;
db.onerror = reject;
var objectStore = db.createObjectStore('test', { autoIncrement: true });
var index = objectStore.createIndex('test', 'index');
};
request.onsuccess = function(evt) {
var db = evt.target.result;
db.onerror = reject;
var blob = new Blob([JSON.stringify(obj)],
{ type: 'application/json' });
var data = { blob: blob, index: 5 };
objectStore = db.transaction('test', 'readwrite').objectStore('test');
objectStore.add(data).onsuccess = function(evt) {
var key = evt.target.result;
objectStore = db.transaction('test').objectStore('test');
objectStore.get(key).onsuccess = function(evt) {
resolve(evt.target.result.blob);
};
};
};
});
}
navigator.serviceWorker.ready.then(function() {
parent.postMessage({ status: 'READY' }, '*');
});
var URL = '/tests/dom/workers/test/serviceworkers/redirect_post.sjs';
addEventListener('message', function(evt) {
if (evt.data.type = 'TEST') {
makeFileBlob(evt.data.body).then(function(blob) {
return fetch(URL, { method: 'POST', body: blob });
}).then(function(response) {
return response.json();
}).then(function(result) {
parent.postMessage({ status: 'OK', result: result }, '*');
}).catch(function(e) {
parent.postMessage({ status: 'ERROR', result: e.toString() }, '*');
});
}
});
</script>
</pre>
</body>
</html>

View File

@ -0,0 +1,146 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE HTML>
<html>
<head>
<title>Bug 1203680 - Test interception of file blob uploads</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test"></pre>
<script class="testbody" type="text/javascript">
var registration;
var iframe;
function start() {
return navigator.serviceWorker.register("empty.js",
{ scope: "./sw_clients/" })
.then((swr) => registration = swr);
}
function unregister() {
if (iframe) {
iframe.remove();
iframe = null;
}
return registration.unregister().then(function(result) {
ok(result, "Unregister should return true.");
}, function(e) {
ok(false, "Unregistering the SW failed with " + e + "\n");
});
}
function withFrame() {
var content = document.getElementById("content");
ok(content, "Parent exists.");
iframe = document.createElement("iframe");
iframe.setAttribute('src', "sw_clients/file_blob_upload_frame.html");
content.appendChild(iframe);
return new Promise(function(resolve, reject) {
window.addEventListener('message', function readyCallback(evt) {
window.removeEventListener('message', readyCallback);
if (evt.data.status === 'READY') {
resolve();
} else {
reject(evt.data.result);
}
});
});
}
function postBlob(body) {
return new Promise(function(resolve, reject) {
window.addEventListener('message', function postBlobCallback(evt) {
window.removeEventListener('message', postBlobCallback);
if (evt.data.status === 'OK') {
is(JSON.stringify(body), JSON.stringify(evt.data.result),
'body echoed back correctly');
resolve();
} else {
reject(evt.data.result);
}
});
iframe.contentWindow.postMessage({ type: 'TEST', body: body }, '*');
});
}
function generateMessage(length) {
var lorem =
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis egestas '
'vehicula tortor eget ultrices. Sed et luctus est. Nunc eu orci ligula. '
'In vel ornare eros, eget lacinia diam. Praesent vel metus mattis, '
'cursus nulla sit amet, rhoncus diam. Aliquam nulla tortor, aliquet et '
'viverra non, dignissim vel tellus. Praesent sed ex in dolor aliquet '
'aliquet. In at facilisis sem, et aliquet eros. Maecenas feugiat nisl '
'quis elit blandit posuere. Duis viverra odio sed eros consectetur, '
'viverra mattis ligula volutpat.';
var result = '';
while (result.length < length) {
var remaining = length - result.length;
if (remaining < lorem.length) {
result += lorem.slice(0, remaining);
} else {
result += lorem;
}
}
return result;
}
var smallBody = generateMessage(64);
var mediumBody = generateMessage(1024);
// TODO: Test large bodies over the default pipe size. Currently stalls
// due to bug 1134372.
//var largeBody = generateMessage(100 * 1024);
function runTest() {
start()
.then(withFrame)
.then(function() {
return postBlob({ hops: 0, message: smallBody });
})
.then(function() {
return postBlob({ hops: 1, message: smallBody });
})
.then(function() {
return postBlob({ hops: 10, message: smallBody });
})
.then(function() {
return postBlob({ hops: 0, message: mediumBody });
})
.then(function() {
return postBlob({ hops: 1, message: mediumBody });
})
.then(function() {
return postBlob({ hops: 10, message: mediumBody });
})
.then(unregister)
.catch(function(e) {
ok(false, "Some test failed with error " + e);
}).then(SimpleTest.finish);
}
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.serviceWorkers.interception.enabled", true],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true]
]}, runTest);
</script>
</pre>
</body>
</html>