[or-cvs] [https-everywhere/master 1/4] Bring IOUTil.js up to 2.0.5.1

pde at torproject.org pde at torproject.org
Fri Nov 12 00:00:47 UTC 2010


Author: Mike Perry <mikeperry-git fscked org>
Date: Thu, 11 Nov 2010 12:33:53 -0800
Subject: Bring IOUTil.js up to 2.0.5.1
Commit: 8d3af8a504f7b7c3aba1b3158f41068aaa4a9788

See https://bugzilla.mozilla.org/show_bug.cgi?id=548102#c47 for description of
redirect code path fixes.
---
 src/chrome/content/code/IOUtil.js |  132 ++++++++++++++++--------------------
 1 files changed, 59 insertions(+), 73 deletions(-)

diff --git a/src/chrome/content/code/IOUtil.js b/src/chrome/content/code/IOUtil.js
index 566ed8f..17b3789 100644
--- a/src/chrome/content/code/IOUtil.js
+++ b/src/chrome/content/code/IOUtil.js
@@ -280,25 +280,19 @@ const IOUtil = {
   
 };
 
-function CtxCapturingListener(tracingChannel, notify) {
+function CtxCapturingListener(tracingChannel, onCapture) {
   this.originalListener = tracingChannel.setNewListener(this);
-  if (notify) this.notify = true;
+  this.onCapture = onCapture;
 }
 CtxCapturingListener.prototype = {
   originalListener: null,
   originalCtx: null,
-  notify: false,
-  onDataAvailable: function(request, ctx, inputStream, offset, count) {
-    this.originalCtx = ctx;
-  },
   onStartRequest: function(request, ctx) {
     this.originalCtx = ctx;
-    if (this.notify) this.originalListener.onStartRequest(request, ctx);
-  },
-  onStopRequest: function(request, ctx, statusCode) {
-    this.originalCtx = ctx;
-    if (this.notify) this.originalListener.onStopRequest(request, ctx, statusCode);
+    if (this.onCapture) this.onCapture(request, ctx);
   },
+  onDataAvailable: function(request, ctx, inputStream, offset, count) {},
+  onStopRequest: function(request, ctx, statusCode) {},
   QueryInterface: function (aIID) {
     if (aIID.equals(CI.nsIStreamListener) ||
         aIID.equals(CI.nsISupports)) {
@@ -317,14 +311,19 @@ ChannelReplacement.supported = "nsITraceableChannel" in CI;
 ChannelReplacement.prototype = {
   listener: null,
   context: null,
-  _ccListener: null,
   oldChannel: null,
   channel: null,
   window: null,
+
   get _unsupportedError() {
     return new Error("Can't replace channels without nsITraceableChannel!");
   },
   
+  get _mustClassify() {
+    delete this.__proto__._mustClassify;
+    return this.__proto__._mustClassify = !("LOAD_CLASSIFIER_URI" in CI.nsIChannel);
+  },
+  
   _init: function(chan, newURI, newMethod) {
     if (!(ChannelReplacement.supported && chan instanceof CI.nsITraceableChannel))
       throw this._unsupportedError;
@@ -332,10 +331,7 @@ ChannelReplacement.prototype = {
     newURI = newURI || chan.URI;
     
     var newChan = IOS.newChannelFromURI(newURI);
-    
-    
-    
-    
+
     // porting of http://mxr.mozilla.org/mozilla-central/source/netwerk/protocol/http/src/nsHttpChannel.cpp#2750
     
     var loadFlags = chan.loadFlags;
@@ -391,7 +387,7 @@ ChannelReplacement.prototype = {
     
     if (chan.referrer) newChan.referrer = chan.referrer;
     newChan.allowPipelining = chan.allowPipelining;
-    newChan.redirectionLimit = chan.redirectionLimit - 1;
+    newChan.redirectionLimit -= 1;
     if (chan instanceof CI.nsIHttpChannelInternal && newChan instanceof CI.nsIHttpChannelInternal) {
       if (chan.URI == chan.documentURI) {
         newChan.documentURI = newURI;
@@ -446,7 +442,7 @@ ChannelReplacement.prototype = {
     const CES = CI.nsIChannelEventSink;
     const flags = CES.REDIRECT_INTERNAL;
     this._callSink(
-    CC["@mozilla.org/netwerk/global-channel-event-sink;1"].getService(CES),
+      CC["@mozilla.org/netwerk/global-channel-event-sink;1"].getService(CES),
       oldChan, newChan, flags);
     var sink;
     
@@ -487,38 +483,50 @@ ChannelReplacement.prototype = {
     : null;
   },
   
-  replace: function(isRedir) {
-    var oldChan = this.oldChannel;
-    try {
-      this._onChannelRedirect(isRedir);
-    } catch(ex) {
-      oldChan.cancel(NS_BINDING_ABORTED);
-      throw ex;
+  replace: function(isRedir, callback) {
+    let self = this;
+    let oldChan = this.oldChannel;
+    this.isRedir = !!isRedir;
+    if (typeof(callback) !== "function") {
+      callback = this._defaultCallback;
     }
-    // dirty trick to grab listenerContext
-   
-    var ccl = new CtxCapturingListener(oldChan);
-    
-    oldChan.cancel(NS_BINDING_REDIRECTED); // this works because we've been called after loadGroup->addRequest(), therefore asyncOpen() always return NS_OK
+    IOUtil.runWhenPending(oldChan, function() {
+      let ccl = new CtxCapturingListener(oldChan,
+        function() {
+          try {
+            callback(self._replaceNow(isRedir, this))
+          } catch (e) {
+            self.dispose();
+          }
+        });
+      self.loadGroup = oldChan.loadGroup;
+      oldChan.loadGroup = null; // prevents the wheel from stopping spinning
+      // this calls asyncAbort, which calls onStartRequest on our listener
+      oldChan.cancel(NS_BINDING_REDIRECTED); 
+    });
+  },
+  
+  _defaultCallback: function(replacement) {
+    replacement.open();
+  },
+  
+  _replaceNow: function(isRedir, ccl) {
+    let oldChan = this.oldChannel;
+    oldChan.loadGroup = this.loadGroup;
     
-    oldChan.notificationCallbacks =
-        oldChan.loadGroup = null; // prevent loadGroup removal and wheel stop
+    this._onChannelRedirect(isRedir);
     
-    if (oldChan instanceof CI.nsIRequestObserver) {
-      oldChan.onStartRequest(oldChan, null);
-    }
-
+    // dirty trick to grab listenerContext
+   
     this.listener = ccl.originalListener;
     this.context = ccl.originalCtx;
-    this._ccListener = ccl;
-    
     return this;
   },
   
   open: function() {
-    var oldChan = this.oldChannel, newChan = this.channel;
-
-    var overlap, fail = false;
+    let oldChan = this.oldChannel,
+      newChan = this.channel,
+      overlap;
     
     /* XXX: Hack
     if (!(this.window && (overlap = ABERequest.getLoadingChannel(this.window)) !== oldChan)) {
@@ -532,49 +540,27 @@ ChannelReplacement.prototype = {
         newChan.asyncOpen(this.listener, this.context);
         
         // safe browsing hook
-        try {
+        if (this._mustClassify)
           CC["@mozilla.org/channelclassifier"].createInstance(CI.nsIChannelClassifier).start(newChan, true);
-        } catch (e) {
-          // may throw if host app doesn't implement url classification
-        }
-      } catch (e) {
-        // redirect failed: we must notify the original channel listener, so let's restore bindings
-        fail = true;
-      }
+        
+      } catch (e) {}
     } else {
       if (ABE.consoleDump) {
         ABE.log("Detected double load on the same window: " + oldChan.name + " - " + (overlap && overlap.name));
       }
     }
     
-    this.cancel(NS_BINDING_REDIRECTED, fail);
+    this.dispose();
   },
   
-  cancel: function(status, fail) {
-    var oldChan = this.oldChannel, newChan = this.channel;
-    if (fail) {
-      oldChan.notificationCallbacks = newChan.notificationCallbacks;
-      this._ccListener.notify = true;
-      if (oldChan instanceof CI.nsIRequestObserver)
-        try {
-        oldChan.onStartRequest(oldChan, null);
-        } catch(e) {}
-    }
-    
-    if (oldChan instanceof CI.nsIRequestObserver)
-      try {  
-        oldChan.onStopRequest(oldChan, null, status);
-      } catch(e) {}
-    
-    if (newChan.loadGroup)
+  dispose: function() {
+    if (this.loadGroup) {
       try {
-        newChan.loadGroup.removeRequest(oldChan, null, status);
-      } catch(e) {}
+        this.loadGroup.removeRequest(this.oldChannel, null, NS_BINDING_REDIRECTED);
+      } catch (e) {}
+      this.loadGroup = null;
+    }
 
-    oldChan.notificationCallbacks = null;
-    delete this._ccListener;
-    delete this.window;
-    delete this.oldChannel;
   }
 }
 
-- 
1.7.1




More information about the tor-commits mailing list