Bug 522416 - Add an asyncFetch method on NetUtil.jsm

This adds an asyncFetch method on NetUtil that will open a channel
asynchronously and provide the consumer with an input stream upon completion.
r=bz
sr=vlad

--HG--
extra : rebase_source : bbeffb5669ba0f040773fca5faca28494982ff94
This commit is contained in:
Shawn Wilsher 2009-10-15 16:16:01 -07:00
parent bdb1e8e0d6
commit 3e6c5bc384
2 changed files with 110 additions and 3 deletions

View File

@ -53,6 +53,8 @@ const Ci = Components.interfaces;
const Cc = Components.classes;
const Cr = Components.results;
const PR_UINT32_MAX = 0xffffffff;
////////////////////////////////////////////////////////////////////////////////
//// NetUtil Object
@ -125,6 +127,49 @@ const NetUtil = {
return copier;
},
/**
* Asynchronously opens a channel and fetches the response. The provided
* callback will get an input stream containing the response, and the result
* code.
*
* @param aChannel
* The nsIChannel to open.
* @param aCallback
* The callback function that will be notified upon completion. It
* will get two arguments:
* 1) An nsIInputStream containing the data from the channel, if any.
* 2) The status code from opening the channel.
*/
asyncFetch: function NetUtil_asyncOpen(aChannel, aCallback)
{
if (!aChannel || !aCallback) {
let exception = new Components.Exception(
"Must have a channel and a callback",
Cr.NS_ERROR_INVALID_ARG,
Components.stack.caller
);
throw exception;
}
// Create a pipe that will create our output stream that we can use once
// we have gotten all the data.
let pipe = Cc["@mozilla.org/pipe;1"].
createInstance(Ci.nsIPipe);
pipe.init(false, false, 0, PR_UINT32_MAX, null);
// Create a listener that will give data to the pipe's output stream.
let listener = Cc["@mozilla.org/network/simple-stream-listener;1"].
createInstance(Ci.nsISimpleStreamListener);
listener.init(pipe.outputStream, {
onStartRequest: function(aRequest, aContext) {},
onStopRequest: function(aRequest, aContext, aStatusCode) {
aCallback(pipe.inputStream, aStatusCode);
}
});
aChannel.asyncOpen(listener, null);
},
/**
* Constructs a new URI for the given spec, character set, and base URI.
*

View File

@ -41,10 +41,9 @@
* This file tests the methods on NetUtil.jsm.
*/
do_load_httpd_js();
Components.utils.import("resource://gre/modules/NetUtil.jsm");
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
////////////////////////////////////////////////////////////////////////////////
//// Helper Methods
@ -179,6 +178,66 @@ function test_ioService()
run_next_test();
}
function test_asyncFetch_no_channel()
{
try {
NetUtil.asyncFetch(null, function() { });
do_throw("should throw!");
}
catch (e) {
do_check_eq(e.result, Cr.NS_ERROR_INVALID_ARG);
}
run_next_test();
}
function test_asyncFetch_no_callback()
{
try {
NetUtil.asyncFetch({ });
do_throw("should throw!");
}
catch (e) {
do_check_eq(e.result, Cr.NS_ERROR_INVALID_ARG);
}
run_next_test();
}
function test_asyncFetch()
{
const TEST_DATA = "this is a test string";
// Start the http server, and register our handler.
let server = new nsHttpServer();
server.registerPathHandler("/test", function(aRequest, aResponse) {
aResponse.setStatusLine(aRequest.httpVersion, 200, "OK");
aResponse.setHeader("Content-Type", "text/plain", false);
aResponse.write(TEST_DATA);
});
server.start(4444);
// Create our channel.
let channel = NetUtil.ioService.
newChannel("http://localhost:4444/test", null, null);
// Open our channel asynchronously.
NetUtil.asyncFetch(channel, function(aInputStream, aResult) {
// Check that we had success.
do_check_true(Components.isSuccessCode(aResult));
// Check that we got the right data.
do_check_eq(aInputStream.available(), TEST_DATA.length);
let is = Cc["@mozilla.org/scriptableinputstream;1"].
createInstance(Ci.nsIScriptableInputStream);
is.init(aInputStream);
let result = is.read(TEST_DATA.length);
do_check_eq(TEST_DATA, result);
server.stop(run_next_test);
});
}
////////////////////////////////////////////////////////////////////////////////
//// Test Runner
@ -188,6 +247,9 @@ let tests = [
test_newURI_no_spec_throws,
test_newURI,
test_ioService,
test_asyncFetch_no_channel,
test_asyncFetch_no_callback,
test_asyncFetch,
];
let index = 0;