merge backout

This commit is contained in:
Honza Bambas 2009-11-16 23:08:40 +01:00
commit d64783cfd5
6 changed files with 48 additions and 77 deletions

View File

@ -38,32 +38,14 @@
#include "nsIStreamListener.idl"
interface nsIOutputStream;
interface nsIRequestObserver;
/**
* As data "flows" into a stream listener tee, it is copied to the output stream
* and then forwarded to the real listener.
*/
[scriptable, uuid(8e86c460-2f6b-4595-a6ba-d5444827cd57)]
[scriptable, uuid(fb683e76-d42b-41a4-8ae6-65a6c2b146e5)]
interface nsIStreamListenerTee : nsIStreamListener
{
/**
* Initalize the tee.
*
* @param listener
* the original listener the tee will propagate onStartRequest,
* onDataAvailable and onStopRequest notifications to, exceptions from
* the listener will be propagated back to the channel
* @param sink
* the stream the data coming from the channel will be written to,
* should be blocking
* @param requestObserver
* optional parameter, listener that gets only onStartRequest and
* onStopRequest notifications; exceptions threw within this optional
* observer are also propagated to the channel, but exceptions from
* the original listener (listener parameter) are privileged
*/
void init(in nsIStreamListener listener,
in nsIOutputStream sink,
[optional] in nsIRequestObserver requestObserver);
in nsIOutputStream sink);
};

View File

@ -47,13 +47,7 @@ nsStreamListenerTee::OnStartRequest(nsIRequest *request,
nsISupports *context)
{
NS_ENSURE_TRUE(mListener, NS_ERROR_NOT_INITIALIZED);
nsresult rv1 = mListener->OnStartRequest(request, context);
nsresult rv2 = NS_OK;
if (mObserver)
rv2 = mObserver->OnStartRequest(request, context);
// Preserve NS_SUCCESS_XXX in rv1 in case mObserver didn't throw
return (NS_FAILED(rv2) && NS_SUCCEEDED(rv1)) ? rv2 : rv1;
return mListener->OnStartRequest(request, context);
}
NS_IMETHODIMP
@ -68,11 +62,7 @@ nsStreamListenerTee::OnStopRequest(nsIRequest *request,
mInputTee = 0;
}
mSink = 0;
nsresult rv = mListener->OnStopRequest(request, context, status);
if (mObserver)
mObserver->OnStopRequest(request, context, status);
mObserver = 0;
return rv;
return mListener->OnStopRequest(request, context, status);
}
NS_IMETHODIMP
@ -109,11 +99,9 @@ nsStreamListenerTee::OnDataAvailable(nsIRequest *request,
NS_IMETHODIMP
nsStreamListenerTee::Init(nsIStreamListener *listener,
nsIOutputStream *sink,
nsIRequestObserver *requestObserver)
nsIOutputStream *sink)
{
mListener = listener;
mSink = sink;
mObserver = requestObserver;
return NS_OK;
}

View File

@ -58,7 +58,6 @@ private:
nsCOMPtr<nsIInputStreamTee> mInputTee;
nsCOMPtr<nsIStreamListener> mListener;
nsCOMPtr<nsIOutputStream> mSink;
nsCOMPtr<nsIRequestObserver> mObserver;
};
#endif

View File

@ -1596,7 +1596,7 @@ nsFtpState::InstallCacheListener()
do_CreateInstance(NS_STREAMLISTENERTEE_CONTRACTID);
NS_ENSURE_STATE(tee);
nsresult rv = tee->Init(mChannel->StreamListener(), out, nsnull);
nsresult rv = tee->Init(mChannel->StreamListener(), out);
NS_ENSURE_SUCCESS(rv, rv);
mChannel->SetStreamListener(tee);

View File

@ -2675,7 +2675,7 @@ nsHttpChannel::InstallCacheListener(PRUint32 offset)
do_CreateInstance(kStreamListenerTeeCID, &rv);
if (NS_FAILED(rv)) return rv;
rv = tee->Init(mListener, out, nsnull);
rv = tee->Init(mListener, out);
if (NS_FAILED(rv)) return rv;
mListener = tee;
@ -2701,7 +2701,7 @@ nsHttpChannel::InstallOfflineCacheListener()
do_CreateInstance(kStreamListenerTeeCID, &rv);
if (NS_FAILED(rv)) return rv;
rv = tee->Init(mListener, out, nsnull);
rv = tee->Init(mListener, out);
if (NS_FAILED(rv)) return rv;
mListener = tee;

View File

@ -6,19 +6,43 @@
do_load_httpd_js();
var httpserver = null;
var pipe = null;
var streamSink = null;
var originalBody = "original http response body";
var gotOnStartRequest = false;
var replacedBody = "replaced http response body";
function TracingListener() {}
TracingListener.prototype = {
onStartRequest: function(request, context) {
dump("*** tracing listener onStartRequest\n");
gotOnStartRequest = true;
// Replace received response body.
onDataAvailable: function(request, context, inputStream,
offset, count) {
dump("*** tracing listener onDataAvailable\n");
var binaryInputStream = Cc["@mozilla.org/binaryinputstream;1"].
createInstance(Components.interfaces.nsIBinaryInputStream);
binaryInputStream.setInputStream(inputStream);
var data = binaryInputStream.readBytes(count);
var origBody = originalBody.substr(offset, count);
do_check_eq(origBody, data);
var storageStream = Cc["@mozilla.org/storagestream;1"].
createInstance(Components.interfaces.nsIStorageStream);
var binaryOutputStream = Cc["@mozilla.org/binaryoutputstream;1"].
createInstance(Components.interfaces.nsIBinaryOutputStream);
storageStream.init(8192, 100, null);
binaryOutputStream.setOutputStream(storageStream.getOutputStream(0));
var newBody = replacedBody.substr(offset, count);
binaryOutputStream.writeBytes(newBody, newBody.length);
this.listener.onDataAvailable(request, context,
storageStream.newInputStream(0), 0,
replacedBody.length);
},
onStartRequest: function(request, context) {
this.listener.onStartRequest(request, context);
// Make sure listener can't be replaced after OnStartRequest was called.
request.QueryInterface(Components.interfaces.nsITraceableChannel);
@ -32,28 +56,13 @@ TracingListener.prototype = {
},
onStopRequest: function(request, context, statusCode) {
dump("*** tracing listener onStopRequest\n");
do_check_eq(gotOnStartRequest, true);
var sin = Components.classes["@mozilla.org/scriptableinputstream;1"].
createInstance(Ci.nsIScriptableInputStream);
streamSink.close();
var input = pipe.inputStream;
sin.init(input);
do_check_eq(sin.available(), originalBody.length);
var result = sin.read(originalBody.length);
do_check_eq(result, originalBody);
input.close();
this.listener.onStopRequest(request, context, statusCode);
httpserver.stop(do_test_finished);
},
QueryInterface: function(iid) {
if (iid.equals(Components.interfaces.nsIRequestObserver) ||
if (iid.equals(Components.interfaces.nsIStreamListener) ||
iid.equals(Components.interfaces.nsIRequestObserver) ||
iid.equals(Components.interfaces.nsISupports)
)
return this;
@ -77,22 +86,14 @@ HttpResponseExaminer.prototype = {
observe: function(subject, topic, data) {
try {
subject.QueryInterface(Components.interfaces.nsITraceableChannel);
var tee = Cc["@mozilla.org/network/stream-listener-tee;1"].
createInstance(Ci.nsIStreamListenerTee);
var newListener = new TracingListener();
pipe = Cc["@mozilla.org/pipe;1"].createInstance(Ci.nsIPipe);
pipe.init(false, false, 0, 0xffffffff, null);
streamSink = pipe.outputStream;
var originalListener = subject.setNewListener(tee);
tee.init(originalListener, streamSink, newListener);
newListener.listener = subject.setNewListener(newListener);
} catch(e) {
do_throw("can't replace listener " + e);
do_throw("can't replace listener" + e);
}
},
QueryInterface: function(iid) {
QueryInterface: function(iid) {
if (iid.equals(Components.interfaces.nsIObserver) ||
iid.equals(Components.interfaces.nsISupportsWeakReference) ||
iid.equals(Components.interfaces.nsISupports))
@ -115,7 +116,8 @@ function make_channel(url) {
}
// Check if received body is correctly modified.
function channel_finished(request, input, ctx) {
function get_data(request, input, ctx) {
do_check_eq(replacedBody, input);
}
function run_test() {
@ -127,6 +129,6 @@ function run_test() {
httpserver.start(4444);
var channel = make_channel("http://localhost:4444/testdir");
channel.asyncOpen(new ChannelListener(channel_finished), null);
channel.asyncOpen(new ChannelListener(get_data), null);
do_test_pending();
}