1 /* See license.txt for terms of usage */ 2 3 // ********************************************************************************************* // 4 // Constants 5 6 const Cc = Components.classes; 7 const Ci = Components.interfaces; 8 const Cr = Components.results; 9 const Cu = Components.utils; 10 11 var EXPORTED_SYMBOLS = ["httpRequestObserver"]; 12 13 var observerService = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService); 14 var categoryManager = Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager); 15 16 Cu["import"]("resource://firebug/fbtrace.js"); 17 18 // ********************************************************************************************* // 19 // HTTP Request Observer implementation 20 21 /** 22 * @service This service is intended as the only HTTP observer registered by Firebug. 23 * All FB extensions and Firebug itself should register a listener within this 24 * service in order to listen for http-on-modify-request, http-on-examine-response and 25 * http-on-examine-cached-response events. 26 * 27 * See also: <a href="http://developer.mozilla.org/en/Setting_HTTP_request_headers"> 28 * Setting_HTTP_request_headers</a> 29 */ 30 var httpRequestObserver = 31 /** lends HttpRequestObserver */ 32 { 33 preInitialize: function() 34 { 35 this.observers = []; 36 this.observing = 0; 37 this.initialize(); 38 }, 39 40 initialize: function() 41 { 42 observerService.addObserver(this, "quit-application", false); 43 44 if (FBTrace.DBG_HTTPOBSERVER) 45 FBTrace.sysout("httpObserver.initialize OK"); 46 }, 47 48 shutdown: function() 49 { 50 observerService.removeObserver(this, "quit-application"); 51 52 if (FBTrace.DBG_HTTPOBSERVER) 53 FBTrace.sysout("httpObserver.shutdown OK"); 54 }, 55 56 registerObservers: function() 57 { 58 if (FBTrace.DBG_HTTPOBSERVER) 59 FBTrace.sysout("httpObserver.registerObservers; wasObserving: " + 60 this.observing + " with observers "+this.observers.length, this.observers); 61 62 if (!this.observing) 63 { 64 observerService.addObserver(this, "http-on-opening-request", false); 65 observerService.addObserver(this, "http-on-modify-request", false); 66 observerService.addObserver(this, "http-on-examine-response", false); 67 observerService.addObserver(this, "http-on-examine-cached-response", false); 68 } 69 70 this.observing = true; 71 }, 72 73 unregisterObservers: function() 74 { 75 if (FBTrace.DBG_HTTPOBSERVER) 76 FBTrace.sysout("httpObserver.unregisterObservers; wasObserving: " + 77 this.observing + " with observers "+this.observers.length, this.observers); 78 79 if (this.observing) 80 { 81 observerService.removeObserver(this, "http-on-opening-request"); 82 observerService.removeObserver(this, "http-on-modify-request"); 83 observerService.removeObserver(this, "http-on-examine-response"); 84 observerService.removeObserver(this, "http-on-examine-cached-response"); 85 } 86 87 this.observing = false; 88 }, 89 90 /* nsIObserve */ 91 observe: function(subject, topic, data) 92 { 93 if (topic == "quit-application") 94 { 95 this.shutdown(); 96 return; 97 } 98 99 try 100 { 101 if (!(subject instanceof Ci.nsIHttpChannel)) 102 return; 103 104 if (FBTrace.DBG_HTTPOBSERVER) 105 FBTrace.sysout("httpObserver.observe " + (topic ? topic.toUpperCase() : topic) + 106 ", " + safeGetName(subject)); 107 108 // Notify all registered observers. 109 if (topic == "http-on-opening-request" || 110 topic == "http-on-modify-request" || 111 topic == "http-on-examine-response" || 112 topic == "http-on-examine-cached-response") 113 { 114 this.notifyObservers(subject, topic, data); 115 } 116 } 117 catch (err) 118 { 119 if (FBTrace.DBG_ERRORS) 120 FBTrace.sysout("httpObserver.observe EXCEPTION", err); 121 } 122 }, 123 124 /* nsIObserverService */ 125 addObserver: function(observer, topic, weak) 126 { 127 if (!topic) 128 topic = "firebug-http-event"; 129 130 if (topic != "firebug-http-event") 131 throw Cr.NS_ERROR_INVALID_ARG; 132 133 this.observers.push(observer); 134 135 if (this.observers.length > 0) 136 this.registerObservers(); 137 }, 138 139 removeObserver: function(observer, topic) 140 { 141 if (!topic) 142 topic = "firebug-http-event"; 143 144 if (topic != "firebug-http-event") 145 throw Cr.NS_ERROR_INVALID_ARG; 146 147 for (var i=0; i<this.observers.length; i++) 148 { 149 if (this.observers[i] == observer) 150 { 151 this.observers.splice(i, 1); 152 153 if (this.observers.length == 0) 154 this.unregisterObservers(); 155 156 return; 157 } 158 } 159 160 if (FBTrace.DBG_HTTPOBSERVER) 161 FBTrace.sysout("httpObserver.removeObserver FAILED (no such observer)"); 162 }, 163 164 notifyObservers: function(subject, topic, data) 165 { 166 if (FBTrace.DBG_HTTPOBSERVER) 167 FBTrace.sysout("httpObserver.notifyObservers (" + this.observers.length + ") " + topic); 168 169 for (var i=0; i<this.observers.length; i++) 170 { 171 var observer = this.observers[i]; 172 try 173 { 174 if (observer.observe) 175 observer.observe(subject, topic, data); 176 } 177 catch (err) 178 { 179 if (FBTrace.DBG_HTTPOBSERVER) 180 FBTrace.sysout("httpObserver.notifyObservers; EXCEPTION " + err, err); 181 } 182 } 183 } 184 } 185 186 // ********************************************************************************************* // 187 // Request helpers 188 189 function safeGetName(request) 190 { 191 try 192 { 193 return request.name; 194 } 195 catch (exc) 196 { 197 } 198 199 return null; 200 } 201 202 // ********************************************************************************************* // 203 // Debugging Helpers 204 205 function dumpStack(message) 206 { 207 dump(message + "\n"); 208 209 for (var frame = Components.stack, i = 0; frame; frame = frame.caller, i++) 210 { 211 if (i < 1) 212 continue; 213 214 var fileName = unescape(frame.filename ? frame.filename : ""); 215 var lineNumber = frame.lineNumber ? frame.lineNumber : ""; 216 217 dump(fileName + ":" + lineNumber + "\n"); 218 } 219 } 220 221 // ********************************************************************************************* // 222 // Initialization 223 224 httpRequestObserver.preInitialize(); 225 226 // ********************************************************************************************* // 227