@@ -183,7 +183,8 @@ function HTTPSEverywhere() {
183183 this . log = https_everywhereLog ;
184184 this . wrappedJSObject = this ;
185185 this . https_rules = HTTPSRules ;
186- this . rw = RuleWriter ;
186+ this . rw = RuleWriter ; // currently used for some file IO helpers, though that
187+ // should probably be refactored
187188 this . INCLUDE = INCLUDE ;
188189 this . ApplicableList = ApplicableList ;
189190 this . browser_initialised = false ; // the browser is completely loaded
@@ -263,6 +264,9 @@ In recent versions of Firefox and HTTPS Everywhere, the call stack for performin
263264
2642651. HTTPSEverywhere.observe() gets a callback with the "http-on-modify-request" topic, and the channel as a subject
265266
267+ 1. HTTPSEverywhere.shouldIgnoreURI() checks for very quick reasons to ignore a
268+ request, such as redirection loops, non-HTTP[S] URIs, and OCSP
269+
266270 2. HTTPS.replaceChannel()
267271
268272 3. HTTPSRules.rewrittenURI()
@@ -282,8 +286,7 @@ In recent versions of Firefox and HTTPS Everywhere, the call stack for performin
282286
283287In addition, the following other important tasks happen along the way:
284288
285- HTTPSEverywhere.observe() aborts if there is a redirect loop
286- finds a reference to the ApplicableList or alist that represents the toolbar context menu
289+ HTTPSEverywhere.observe() finds a reference to the ApplicableList or alist that represents the toolbar context menu
287290
288291HTTPS.replaceChannel() notices redirect loops (and used to do much more complex XPCOM API work in the NoScript-based past)
289292
@@ -468,28 +471,71 @@ HTTPSEverywhere.prototype = {
468471 return alist ;
469472 } ,
470473
474+ // These are the highest level heuristics for figuring out whether
475+ // we should consider rewriting a URI. Everything here should be simple
476+ // and avoid dependence on the ruleset library
477+ shouldIgnoreURI : function ( uri , alist ) {
478+ // Ignore all non-http(s) requests?
479+ if ( ! ( uri . schemeIs ( "http" ) || uri . schemeIs ( "https" ) ) ) { return true ; }
480+
481+ // These are URIs we've seen redirecting back in loops after we redirect them
482+ if ( uri . spec in https_everywhere_blacklist ) {
483+ this . log ( DBUG , "Avoiding blacklisted " + uri . spec ) ;
484+ if ( alist ) {
485+ alist . breaking_rule ( https_everywhere_blacklist [ uri . spec ] ) ;
486+ } else {
487+ this . log ( NOTE , "Failed to indicate breakage in content menu" ) ;
488+ }
489+ return true ;
490+ }
491+
492+ // OCSP (currently) needs to be HTTP to avoid cert validation loops
493+ // though someone should rev the spec to allow opportunistic encryption
494+ if ( "allowSTS" in channel ) {
495+ // Firefox 32+ lets us infer whether this is an OCSP request
496+ if ( ! channel . allowSTS ) {
497+ this . log ( INFO , "Channel with HTTPS rewrites forbidden, deeming OCSP, for " + channel . URI . spec ) ;
498+ return true ;
499+ }
500+ } else {
501+ // Firefox <32 requires a more hacky estimate
502+ // load the list opportunistically to speed startup & FF 32+
503+ if ( this . ocspList == undefined ) { this . loadOCSPList ( ) ; }
504+ if ( this . ocspList . indexOf ( uri . spec . replace ( / \/ $ / , '' ) ) !== - 1 ) {
505+ this . log ( INFO , "Known ocsp request " + uri . spec ) ;
506+ return true ;
507+ }
508+ }
509+
510+ return false ;
511+ } ,
512+
513+ loadOCSPList : function ( ) {
514+ try {
515+ var loc = "chrome://https-everywhere/content/code/commonOCSP.json" ;
516+ var file = CC [ "@mozilla.org/file/local;1" ] . createInstance ( CI . nsILocalFile ) ;
517+ file . initWithPath ( this . rw . chromeToPath ( loc ) ) ;
518+ var data = this . rw . read ( file ) ;
519+ this . ocspList = JSON . parse ( data ) ;
520+ } catch ( e ) {
521+ this . log ( WARN , "Failed to load OCSP list: " + e ) ;
522+ this . ocspList = [ ] ;
523+ }
524+ } ,
525+
471526 observe : function ( subject , topic , data ) {
472527 // Top level glue for the nsIObserver API
473528 var channel = subject ;
474529 //this.log(VERB,"Got observer topic: "+topic);
475530
476531 if ( topic == "http-on-modify-request" ) {
477532 if ( ! ( channel instanceof CI . nsIHttpChannel ) ) return ;
478-
479533 this . log ( DBUG , "Got http-on-modify-request: " + channel . URI . spec ) ;
534+
480535 var lst = this . getApplicableListForChannel ( channel ) ; // null if no window is associated (ex: xhr)
481- // Firefox 32+ lets us infer whether this is an OCSP request
482- if ( "allowSTS" in channel && ! channel . allowSTS ) {
483- this . log ( INFO , "Channel with HTTPS rewrites forbidden, probably OCSP, for " + channel . URI . spec ) ;
484- return ;
485- }
486- if ( channel . URI . spec in https_everywhere_blacklist ) {
487- this . log ( DBUG , "Avoiding blacklisted " + channel . URI . spec ) ;
488- if ( lst ) lst . breaking_rule ( https_everywhere_blacklist [ channel . URI . spec ] ) ;
489- else this . log ( NOTE , "Failed to indicate breakage in content menu" ) ;
490- return ;
491- }
536+ if ( this . shouldIgnoreURI ( channel . URI , lst ) ) return ;
492537 HTTPS . replaceChannel ( lst , channel ) ;
538+
493539 } else if ( topic == "http-on-examine-response" ) {
494540 this . log ( DBUG , "Got http-on-examine-response @ " + ( channel . URI ? channel . URI . spec : '' ) ) ;
495541 HTTPS . handleSecureCookies ( channel ) ;
0 commit comments