@@ -144,40 +144,13 @@ INCLUDE('ChannelReplacement', 'IOUtil', 'HTTPSRules', 'HTTPS', 'Thread', 'Applic
144144
145145Components . utils . import ( "resource://gre/modules/XPCOMUtils.jsm" ) ;
146146
147- // This is black magic for storing Expando data w/ an nsIDOMWindow
148- // See http://pastebin.com/qY28Jwbv ,
149- // https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIControllers
150-
151- StorageController . prototype = {
152- QueryInterface : XPCOMUtils . generateQI (
153- [ Components . interfaces . nsISupports ,
154- Components . interfaces . nsIController ] ) ,
155- wrappedJSObject : null , // Initialized by constructor
156- supportsCommand : function ( cmd ) { return ( cmd == this . command ) ; } ,
157- isCommandEnabled : function ( cmd ) { return ( cmd == this . command ) ; } ,
158- onEvent : function ( eventName ) { return true ; } ,
159- doCommand : function ( ) { return true ; }
160- } ;
161-
162- function StorageController ( command ) {
163- this . command = command ;
164- this . data = { } ;
165- this . wrappedJSObject = this ;
166- }
167-
168- /*var Controller = Class("Controller", XPCOM(CI.nsIController), {
169- init: function (command, data) {
170- this.command = command;
171- this.data = data;
172- },
173- supportsCommand: function (cmd) cmd === this.command
174- });*/
175-
176147function HTTPSEverywhere ( ) {
177148
178149 // Set up logging in each component:
179150 HTTPS . log = HTTPSRules . log = RuleWriter . log = this . log = https_everywhereLog ;
180151
152+ this . expandoMap = new WeakMap ( ) ;
153+
181154 this . log = https_everywhereLog ;
182155 this . wrappedJSObject = this ;
183156 this . https_rules = HTTPSRules ;
@@ -307,128 +280,128 @@ HTTPSEverywhere.prototype = {
307280 } ,
308281
309282 // An "expando" is an attribute glued onto something. From NoScript.
310- getExpando : function ( domWin , key ) {
311- var c = domWin . controllers . getControllerForCommand ( "https-everywhere-storage" ) ;
312- try {
313- if ( c ) {
314- c = c . wrappedJSObject ;
315- //this.log(DBUG, "Found a controller, returning data");
316- return c . data [ key ] ;
317- } else {
318- this . log ( INFO , "No controller attached to " + domWin ) ;
283+ getExpando : function ( browser , key ) {
284+ let obj = this . expandoMap . get ( browser ) ;
285+ if ( ! obj ) {
286+ dump ( new Error ( ) . stack ) ;
287+ this . log ( INFO , "No expando for " + browser ) ;
319288 return null ;
320- }
321- } catch ( e ) {
322- // Firefox 3.5
323- this . log ( WARN , "exception in getExpando" ) ;
324- this . getExpando = this . getExpando_old ;
325- this . setExpando = this . setExpando_old ;
326- return this . getExpando_old ( domWin , key , null ) ;
327289 }
290+ return obj [ key ] ;
328291 } ,
329- setExpando : function ( domWin , key , value ) {
330- var c = domWin . controllers . getControllerForCommand ( "https-everywhere-storage" ) ;
331- try {
332- if ( ! c ) {
333- this . log ( DBUG , "Appending new StorageController for " + domWin ) ;
334- c = new StorageController ( "https-everywhere-storage" ) ;
335- domWin . controllers . appendController ( c ) ;
336- } else {
337- c = c . wrappedJSObject ;
338- }
339- c . data [ key ] = value ;
340- } catch ( e ) {
341- this . log ( WARN , "exception in setExpando" ) ;
342- this . getExpando = this . getExpando_old ;
343- this . setExpando = this . setExpando_old ;
344- this . setExpando_old ( domWin , key , value ) ;
292+
293+ setExpando : function ( browser , key , value ) {
294+ dump ( "SET EXPANDO\n" ) ;
295+ dump ( new Error ( ) . stack ) ;
296+ if ( ! this . expandoMap . has ( browser ) ) {
297+ this . expandoMap . set ( browser , { } ) ;
345298 }
299+ let obj = this . expandoMap . get ( browser ) ;
300+ obj [ key ] = value ;
346301 } ,
347302
348- // This method is straight out of NoScript... we fall back to it in FF 3.*?
349- getExpando_old : function ( domWin , key , defValue ) {
350- var domObject = domWin . document ;
351- return domObject && domObject . __httpsEStorage && domObject . __httpsEStorage [ key ] ||
352- ( defValue ? this . setExpando ( domObject , key , defValue ) : null ) ;
353- } ,
354- setExpando_old : function ( domWin , key , value ) {
355- var domObject = domWin . document ;
356- if ( ! domObject ) return null ;
357- if ( ! domObject . __httpsEStorage ) domObject . __httpsEStorage = { } ;
358- if ( domObject . __httpsEStorage ) domObject . __httpsEStorage [ key ] = value ;
359- else this . log ( WARN , "Warning: cannot set expando " + key + " to value " + value ) ;
360- return value ;
303+ onStateChange : function ( wp , req , flags , status ) {
304+ if ( ( flags & CI . nsIWebProgressListener . STATE_START ) &&
305+ ( flags & CI . nsIWebProgressListener . STATE_IS_DOCUMENT ) &&
306+ wp . isTopLevel ) {
307+ dump ( "\nDOC START\n\n" ) ;
308+ let channel = req . QueryInterface ( CI . nsIChannel ) ;
309+ let browser = this . getBrowserForChannel ( channel ) ;
310+ if ( ! browser ) {
311+ this . log ( WARN , "Unable to get <browser>" ) ;
312+ return ;
313+ }
314+ dump ( "ON LOCATION $$$$$$$$$$\n" ) ;
315+ if ( ! this . newApplicableListForBrowser ( browser ) )
316+ this . log ( WARN , "Something went wrong in onLocationChange" ) ;
317+ }
361318 } ,
362-
319+ /*
363320 // We use onLocationChange to make a fresh list of rulesets that could have
364321 // applied to the content in the current page (the "applicable list" is used
365322 // for the context menu in the UI). This will be appended to as various
366323 // content is embedded / requested by JavaScript.
367324 onLocationChange: function(wp, req, uri) {
368325 if (wp instanceof CI.nsIWebProgress) {
369- if ( ! this . newApplicableListForDOMWin ( wp . DOMWindow ) )
326+ let location = uri.spec;
327+ if(location.substr(0, 6) == "about:"){
328+ return;
329+ }
330+ if (!req || !(req instanceof CI.nsIChannel)) {
331+ this.log(WARN, "Bad request " + req + " for " + uri.spec);
332+ return;
333+ }
334+ let browser = this.getBrowserForChannel(req);
335+ if (!browser) {
336+ this.log(WARN, "Unable to get browser for " + uri.spec);
337+ return;
338+ }
339+ dump("ON LOCATION $$$$$$$$$$\n");
340+ if (!this.newApplicableListForBrowser(browser))
370341 this.log(WARN,"Something went wrong in onLocationChange");
371342 } else {
372343 this.log(WARN,"onLocationChange: no nsIWebProgress");
373344 }
374345 },
375-
376- getWindowForChannel : function ( channel ) {
346+ */
347+ getBrowserForChannel : function ( channel ) {
377348 // Obtain an nsIDOMWindow from a channel
378- let loadContext ;
349+ let nc ;
379350 try {
380- loadContext = channel . notificationCallbacks . getInterface ( CI . nsILoadContext ) ;
351+ nc = channel . notificationCallbacks ?
352+ channel . notificationCallbacks :
353+ channel . loadGroup . notificationCallbacks ;
381354 } catch ( e ) {
382- try {
383- loadContext = channel . loadGroup . notificationCallbacks . getInterface ( CI . nsILoadContext ) ;
384- } catch ( e ) {
385- this . log ( NOTE , "No loadContext for " + channel . URI . spec ) ;
386- return null ;
387- }
355+ this . log ( WARN , "no loadgroup notificationCallbacks for " + channel . URI . spec ) ;
356+ return null ;
388357 }
389-
390- let domWin = loadContext . associatedWindow ;
391- if ( ! domWin ) {
392- this . log ( NOTE , "failed to get DOMWin for " + channel . URI . spec ) ;
358+ if ( ! nc ) {
393359 return null ;
394360 }
395-
396- domWin = domWin . top ;
397- return domWin ;
361+ try {
362+ var loadContext = nc . getInterface ( CI . nsILoadContext ) ;
363+ dump ( "loadContext = " + loadContext + "\n" ) ;
364+ var browser = loadContext . topFrameElement ;
365+ } catch ( e ) {
366+ this . log ( INFO , "No <browser> element associated with request: " + channel . URI . spec ) ;
367+ return null ;
368+ }
369+ if ( ! browser ) {
370+ this . log ( NOTE , "failed to get <browser> for " + channel . URI . spec ) ;
371+ return null ;
372+ }
373+ return browser ;
398374 } ,
399375
400376 // the lists get made when the urlbar is loading something new, but they
401377 // need to be appended to with reference only to the channel
402378 getApplicableListForChannel : function ( channel ) {
403- var domWin = this . getWindowForChannel ( channel ) ;
404- return this . getApplicableListForDOMWin ( domWin , "on-modify-request w " + domWin ) ;
379+ var browser = this . getBrowserForChannel ( channel ) ;
380+ return this . getApplicableListForBrowser ( browser , "on-modify-request w " + browser ) ;
405381 } ,
406382
407- newApplicableListForDOMWin : function ( domWin ) {
408- if ( ! domWin || ! ( domWin instanceof CI . nsIDOMWindow ) ) {
409- this . log ( WARN , "Get alist without domWin " ) ;
383+ newApplicableListForBrowser : function ( browser ) {
384+ if ( ! browser || ! ( browser instanceof CI . nsIContent ) ) {
385+ this . log ( WARN , "Get alist without browser " ) ;
410386 return null ;
411387 }
412- var dw = domWin . top ;
413- var alist = new ApplicableList ( this . log , dw . document , dw ) ;
414- this . setExpando ( dw , "applicable_rules" , alist ) ;
388+ var alist = new ApplicableList ( this . log , browser ) ;
389+ this . setExpando ( browser , "applicable_rules" , alist ) ;
415390 return alist ;
416391 } ,
417392
418- getApplicableListForDOMWin : function ( domWin , where ) {
419- if ( ! domWin || ! ( domWin instanceof CI . nsIDOMWindow ) ) {
420- //this.log(WARN, "Get alist without domWin");
393+ getApplicableListForBrowser : function ( browser , where ) {
394+ if ( ! browser || ! ( browser instanceof CI . nsIContent ) ) {
421395 return null ;
422396 }
423- var dw = domWin . top ;
424- var alist = this . getExpando ( dw , "applicable_rules" , null ) ;
397+ var alist = this . getExpando ( browser , "applicable_rules" ) ;
425398 if ( alist ) {
426399 //this.log(DBUG,"get AL success in " + where);
427400 return alist ;
428401 } else {
429- //this.log(DBUG, "Making new AL in getApplicableListForDOMWin in " + where);
430- alist = new ApplicableList ( this . log , dw . document , dw ) ;
431- this . setExpando ( dw , "applicable_rules" , alist ) ;
402+ //this.log(DBUG, "Making new AL in getApplicableListForBrowser in " + where);
403+ alist = new ApplicableList ( this . log , browser ) ;
404+ this . setExpando ( browser , "applicable_rules" , alist ) ;
432405 }
433406 return alist ;
434407 } ,
@@ -548,7 +521,7 @@ HTTPSEverywhere.prototype = {
548521
549522 var dls = CC [ '@mozilla.org/docloaderservice;1' ]
550523 . getService ( CI . nsIWebProgress ) ;
551- dls . addProgressListener ( this , CI . nsIWebProgress . NOTIFY_LOCATION ) ;
524+ dls . addProgressListener ( this , CI . nsIWebProgress . NOTIFY_ALL ) ;
552525 this . log ( INFO , "ChannelReplacement.supported = " + ChannelReplacement . supported ) ;
553526
554527 HTTPSRules . init ( ) ;
@@ -672,19 +645,19 @@ HTTPSEverywhere.prototype = {
672645 // If the new channel doesn't yet have a list of applicable rulesets, start
673646 // with the old one because that's probably a better representation of how
674647 // secure the load process was for this page
675- var domWin = this . getWindowForChannel ( oldChannel ) ;
648+ var browser = this . getBrowserForChannel ( oldChannel ) ;
676649 var old_alist = null ;
677- if ( domWin )
678- old_alist = this . getExpando ( domWin , "applicable_rules" , null ) ;
679- domWin = this . getWindowForChannel ( newChannel ) ;
680- if ( ! domWin ) return null ;
681- var new_alist = this . getExpando ( domWin , "applicable_rules" , null ) ;
650+ if ( browser )
651+ old_alist = this . getExpando ( browser , "applicable_rules" , null ) ;
652+ browser = this . getBrowserForChannel ( newChannel ) ;
653+ if ( ! browser ) return null ;
654+ var new_alist = this . getExpando ( browser , "applicable_rules" , null ) ;
682655 if ( old_alist && ! new_alist ) {
683656 new_alist = old_alist ;
684- this . setExpando ( domWin , "applicable_rules" , new_alist ) ;
657+ this . setExpando ( browser , "applicable_rules" , new_alist ) ;
685658 } else if ( ! new_alist ) {
686- new_alist = new ApplicableList ( this . log , domWin . document , domWin ) ;
687- this . setExpando ( domWin , "applicable_rules" , new_alist ) ;
659+ new_alist = new ApplicableList ( this . log , browser ) ;
660+ this . setExpando ( browser , "applicable_rules" , new_alist ) ;
688661 }
689662 return new_alist ;
690663 } ,
0 commit comments