Bug 938023 - Download API (Asynchronous Responses for API Tests). r=fabrice, gwagner

This commit is contained in:
Ghislain Lacroix 2013-11-27 23:18:17 -08:00
parent 5c8a818f7a
commit fb94306f7a
3 changed files with 83 additions and 10 deletions

View File

@ -1,5 +1,4 @@
// Serves a file with a given mime type and size.
// Serves a file with a given mime type and size at an optionally given rate.
function getQuery(request) {
var query = {};
@ -10,25 +9,99 @@ function getQuery(request) {
return query;
}
// Timer used to handle the request response.
var timer = null;
function handleResponse() {
// Is this a rate limited response?
if (this.state.rate > 0) {
// Calculate how many bytes we have left to send.
var bytesToWrite = this.state.totalBytes - this.state.sentBytes;
// Do we have any bytes left to send? If not we'll just fall thru and
// cancel our repeating timer and finalize the response.
if (bytesToWrite > 0) {
// Figure out how many bytes to send, based on the rate limit.
bytesToWrite =
(bytesToWrite > this.state.rate) ? this.state.rate : bytesToWrite;
for (let i = 0; i < bytesToWrite; i++) {
this.response.write("0");
}
// Update the number of bytes we've sent to the client.
this.state.sentBytes += bytesToWrite;
// Wait until the next call to do anything else.
return;
}
}
else {
// Not rate limited, write it all out.
for (let i = 0; i < this.state.totalBytes; i++) {
this.response.write("0");
}
}
// Finalize the response.
this.response.finish();
// All done sending, go ahead and cancel our repeating timer.
timer.cancel();
}
function handleRequest(request, response) {
var query = getQuery(request);
// Default values for content type and size.
// Default values for content type, size and rate.
var contentType = "text/plain";
var size = 1024;
var rate = 0;
// optional content type to be used by our response.
if ("contentType" in query) {
contentType = query["contentType"];
}
// optional size (in bytes) for generated file.
if ("size" in query) {
size = query["size"];
size = parseInt(query["size"]);
}
// Generate the content.
// optional rate (in bytes/s) at which to send the file.
if ("rate" in query) {
rate = parseInt(query["rate"]);
}
// The context for the responseHandler.
var context = {
response: response,
state: {
contentType: contentType,
totalBytes: size,
sentBytes: 0,
rate: rate
}
};
// The notify implementation for the timer.
context.notify = handleResponse.bind(context);
timer =
Components.classes["@mozilla.org/timer;1"]
.createInstance(Components.interfaces.nsITimer);
// sending at a specific rate requires our response to be asynchronous so
// we handle all requests asynchronously. See handleResponse().
response.processAsync();
// generate the content.
response.setHeader("Content-Type", contentType, false);
response.setHeader("Content-Length", size.toString(), false);
// initialize the timer and start writing out the response.
timer.initWithCallback(context,
1000,
Components.interfaces.nsITimer.TYPE_REPEATING_SLACK);
for (let i = 0; i < size; i++) {
response.write("0");
}
}

View File

@ -15,7 +15,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=938023
<p id="display"></p>
<div id="content" style="display: none">
</div>
<a href="serve_file.sjs?contentType=application/octet-stream&size=102400" download="test.bin" id="download1">Large Download</a>
<a href="serve_file.sjs?contentType=application/octet-stream&size=102400&rate=1024" download="test.bin" id="download1">Large Download</a>
<pre id="test">
<script class="testbody" type="text/javascript;version=1.7">

View File

@ -15,7 +15,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=938023
<p id="display"></p>
<div id="content" style="display: none">
</div>
<a href="serve_file.sjs?contentType=application/octet-stream&size=102400" download="test.bin" id="download1">Large Download</a>
<a href="serve_file.sjs?contentType=application/octet-stream&size=102400&rate=1024" download="test.bin" id="download1">Large Download</a>
<pre id="test">
<script class="testbody" type="text/javascript;version=1.7">