View difference between Paste ID: axaNZDJC and
SHOW: | | - or go back to the newest paste.
1-
1+
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
2
3
/*
4
 * Modify Headers Header
5
 */
6
function ModifyHeadersHeader() {
7
  this.aAction   = "";
8
  this.aName     = "";
9
  this.aValue    = "";
10
  this.aComment  = "";
11
  this.aEnabled  = false;
12
  this.aSelected = true;
13
}
14
15
ModifyHeadersHeader.prototype = {
16
  classDescription: "Modify Headers Header",
17
  classID:          Components.ID("{6b2f2fc7-a26c-4602-a08d-bd6d065a86e3}"),
18
  contractID:       "@modifyheaders.mozdev.org/header;1",
19
	
20
  QueryInterface: XPCOMUtils.generateQI([Components.interfaces.mhIHeader]),
21
22
  get action() { return this.aAction },
23
  set action(action) { this.aAction = action },
24
  
25
  get name() { return this.aName },
26
  set name(name) { this.aName = name },
27
  
28
  get value() { return this.aValue },
29
  set value(value) { this.aValue = value },
30
   
31
  get comment() { return this.aComment },
32
  set comment(comment) { this.aComment = comment },
33
  
34
  get enabled() { return this.aEnabled },
35
  set enabled(enabled) { this.aEnabled = enabled },
36
  
37
  get selected() { return this.aSelected },
38
  set selected(selected) { this.aSelected = selected },
39
  
40
  get wrappedJSObject() { return this },
41
  
42
  equals: function(obj) {
43
    return (this.action.toLowerCase() == obj.action.toLowerCase() && this.name.toLowerCase() == obj.name.toLowerCase() && this.value.toLowerCase() == obj.value.toLowerCase()) ? true : false;
44
  }
45
}
46
47
/* Defines the modifyheaders service for getting and setting headers */
48
function ModifyHeadersService() {
49
  //dump("\nEntered ModifyHeadersService");
50
51
  this.headers = new Array();
52
  this.preferencesUtil = new PreferencesUtil();
53
  
54
  // Observer service is used to notify observing ModifyHeadersProxy objects that the headers have been updated
55
  this.observerService = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
56
  
57
  this.initiated = false;
58
  this.winOpen = false;
59
  //dump("\nExiting ModifyHeadersService");
60
}
61
62
/*
63
 * Modify Headers Service
64
 */
65
ModifyHeadersService.prototype = {
66
  classDescription: "Modify Headers Service",
67
  classID:          Components.ID("{feb80fc3-9e72-4fc5-bc72-986957ada6cc}"),
68
  contractID:       "@modifyheaders.mozdev.org/service;1",
69
		
70
  QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsIModifyheaders]),
71
  
72
  get count() {
73
    if (!this.initiated) {
74
      this.init();
75
    }
76
77
    //dump("\nReturning the header count: " + this.headers.length);
78
    return this.headers.length;
79
  },
80
  set count(c) { /* Do nothing */ },
81
  
82
  get alwaysOn() {
83
    return this.preferencesUtil.getPreference("bool", PreferencesUtil.prefAlwaysOn);
84
  },
85
  
86
  set alwaysOn(alwaysOn) {
87
    this.preferencesUtil.setPreference("bool", PreferencesUtil.prefAlwaysOn, alwaysOn);
88
  },
89
  
90
  get openAsTab() {
91
    return this.preferencesUtil.getPreference("bool", PreferencesUtil.prefOpenAsTab);
92
  },
93
  
94
  set openAsTab(openAsTab) {
95
    this.preferencesUtil.setPreference("bool", PreferencesUtil.prefOpenAsTab, openAsTab);
96
  },
97
  
98
  get windowOpen() {
99
    return this.winOpen;
100
  },
101
  
102
  set windowOpen(winOpen) {
103
    this.winOpen = winOpen;
104
  },
105
  
106
  // Load the headers from the preferences
107
  init: function() {
108
    //dump("\nEntered ModifyHeadersService.init")
109
110
    this.headers = new Array();
111
    
112
    // Load the headers from the preferences
113
    var enabled;
114
    var action;
115
    var name;
116
    var value;
117
    var comment;
118
    
119
   	// Read preferences into headersArray
120
    var headerCount = this.preferencesUtil.getPreference("int", PreferencesUtil.prefHeaderCount);
121
    
122
   	for (var i=0; i < headerCount; i++) {
123
      name = this.preferencesUtil.getPreference("char", PreferencesUtil.prefHeaderName + i);
124
      value = this.preferencesUtil.getPreference("char", PreferencesUtil.prefHeaderValue + i);
125
      action = this.preferencesUtil.getPreference("char", PreferencesUtil.prefHeaderAction + i);
126
      comment = this.preferencesUtil.getPreference("char", PreferencesUtil.prefHeaderComment + i);
127
      enabled = this.preferencesUtil.getPreference("bool", PreferencesUtil.prefHeaderEnabled + i);
128
      
129
      this.addHeader(name, value, action, comment, enabled);
130
    }
131
    
132
    this.initiated = true;
133
    //dump("\nExiting ModifyHeadersService.init");
134
  },
135
  
136
  getHeader: function(index) {
137
    var objHeader = Components.classes["@modifyheaders.mozdev.org/header;1"].createInstance(Components.interfaces.mhIHeader);
138
    objHeader.action = this.headers[index]["action"];
139
    objHeader.name = this.headers[index]["name"];
140
    objHeader.value = this.headers[index]["value"];
141
    objHeader.comment = this.headers[index]["comment"];
142
    objHeader.enabled = this.headers[index]["enabled"];
143
    
144
    return objHeader;
145
  }, 
146
  
147
  getHeaders: function(count) {
148
    //dump("\nEntered ModifyHeadersService.getHeaders");
149
    
150
    var objHeader = null;
151
    var aHeaders = new Array();
152
    
153
    for (var i=0; i < this.headers.length; i++) {
154
      objHeader = this.getHeader(i);
155
      aHeaders[i] = objHeader;
156
    }
157
    
158
  	count.value = aHeaders.length;
159
  	//dump("\nReturning the header object");
160
  	return aHeaders;
161
  },
162
  
163
  getHeadersAsXML: function(strHeaderIndices) {
164
    //dump("\nEntered ModifyHeadersService.getHeadersAsJSONString: " + strHeaderIndices);
165
    var headerIndices = strHeaderIndices.split(",");
166
    
167
    var parser = Components.classes["@mozilla.org/xmlextras/domparser;1"].createInstance(Components.interfaces.nsIDOMParser);
168
    var headersXML = parser.parseFromString("<modifyheaders></modifyheaders>", "text/xml");
169
    var root = headersXML.documentElement;
170
    
171
    // Loop over the values
172
    for (var i=0; i < headerIndices.length; i++) {
173
      objHeader = this.getHeader(headerIndices[i]);
174
      
175
      var action = headersXML.createTextNode(objHeader.action);
176
      var actionElem = headersXML.createElement("action");
177
      actionElem.appendChild(action);
178
      
179
      var name = headersXML.createTextNode(objHeader.name);
180
      var nameElem = headersXML.createElement("name");
181
      nameElem.appendChild(name);
182
      
183
      var value = headersXML.createTextNode(objHeader.value);
184
      var valueElem = headersXML.createElement("value");
185
      valueElem.appendChild(value);
186
      
187
      var comment = headersXML.createTextNode(objHeader.comment);
188
      var commentElem = headersXML.createElement("comment");
189
      commentElem.appendChild(comment);
190
      
191
      var header = headersXML.createElement("header");
192
      header.appendChild(actionElem);
193
      header.appendChild(nameElem);
194
      header.appendChild(valueElem);
195
      header.appendChild(commentElem);
196
      
197
      root.appendChild(header);
198
    }
199
    
200
    var serializer = Components.classes["@mozilla.org/xmlextras/xmlserializer;1"].createInstance(Components.interfaces.nsIDOMSerializer);
201
    
202
    //dump("\nExiting ModifyHeadersService.getHeadersAsJSONString");
203
    // Return a XML string
204
    return "<?xml version=\"1.0\"?>" + serializer.serializeToString(headersXML);
205
  },
206
  
207
  // Adds a header to the headers array
208
  addHeader: function(name, value, action, comment, enabled) {
209
    //dump("\nEntered ModifyHeadersService.addHeader");
210
    
211
    // TODO Validate the arguments
212
    
213
    // Add the header to the Array
214
    var header = new Array();
215
    header["enabled"] = enabled;
216
    header["action"]  = action;
217
    header["name"]    = name;
218
    header["value"]   = value;
219
    header["comment"] = comment;
220
    
221
    this.headers.push(header);
222
    
223
    this.savePreferences();
224
    //dump("\nExiting ModifyHeadersService.addHeader");
225
  },
226
  
227
  setHeader: function(index, name, value, action, comment, enabled) {
228
    //dump("\nEntered ModifyHeadersService.setHeader");
229
    
230
    // TODO Validate the arguments
231
    
232
    // Update the values
233
    this.headers[index]["enabled"] = enabled;
234
    this.headers[index]["action"]  = action;
235
    this.headers[index]["name"]    = name;
236
    this.headers[index]["value"]   = value;
237
    this.headers[index]["comment"] = comment;
238
    
239
    this.savePreferences()
240
    //dump("\nExiting ModifyHeadersService.setHeader")
241
  },
242
  
243
  // Remove the header with the specified index
244
  removeHeader: function(index) {
245
    //dump("\nEntered ModifyHeadersService.removeHeader");
246
    this.headers.splice(index, 1);
247
    this.savePreferences();
248
    //dump("\nExiting ModifyHeadersService.removeHeader");
249
  },
250
  
251
  isHeaderEnabled: function(index) {
252
    return this.headers[index]["enabled"];
253
  },
254
  
255
  setHeaderEnabled: function(index, enabled) {
256
    this.headers[index]["enabled"] = enabled;
257
    this.savePreferences();
258
  },
259
  
260
  getHeaderAction: function(index) {
261
    return this.headers[index]["action"];
262
  },
263
  
264
  getHeaderName: function(index) {
265
    return this.headers[index]["name"];
266
  },
267
  
268
  getHeaderValue: function(index) {
269
    return this.headers[index]["value"];
270
  },
271
  
272
  getHeaderComment: function(index) {
273
    return this.headers[index]["comment"];
274
  },
275
  
276
  switchHeaders: function(index1, index2) {
277
    var header = this.headers[index1];
278
    this.headers[index1] = this.headers[index2];
279
    this.headers[index2] = header;
280
    this.savePreferences();
281
  },
282
  
283
  // Persist the headers to the preferences.
284
  savePreferences: function() {
285
    //dump("\nEntered ModifyHeadersService.savePreferences");
286
    // Only save headers if the service has been initiated
287
    if (this.initiated) {
288
      // TODO Clear the preferences first
289
      // This ensures old headers are not maintained in the preferences
290
      // I'm sure there is a better way than this
291
      
292
      // Loop over the headers
293
      for (var i=0; i < this.count; i++) {
294
        this.preferencesUtil.setPreference("char", PreferencesUtil.prefHeaderAction + i, this.headers[i]["action"]);
295
        this.preferencesUtil.setPreference("char", PreferencesUtil.prefHeaderName + i, this.headers[i]["name"]);
296
        this.preferencesUtil.setPreference("char", PreferencesUtil.prefHeaderValue + i, this.headers[i]["value"]);
297
        this.preferencesUtil.setPreference("char", PreferencesUtil.prefHeaderComment + i, this.headers[i]["comment"]);
298
        this.preferencesUtil.setPreference("bool", PreferencesUtil.prefHeaderEnabled + i, this.headers[i]["enabled"]);
299
      }
300
      
301
      this.preferencesUtil.setPreference("int", PreferencesUtil.prefHeaderCount, this.count);
302
    }
303
    //dump("\nExiting ModifyHeadersService.savePreferences");
304
  },
305
306
  // Clear the headers from their preferences
307
  clearPreferences: function() {
308
    // Loop over the headers
309
    for (var i=0; i < this.count; i++) {
310
      this.preferencesUtil.deletePreference(PreferencesUtil.prefHeaderAction + i);
311
      this.preferencesUtil.deletePreference(PreferencesUtil.prefHeaderEnabled + i);
312
      this.preferencesUtil.deletePreference(PreferencesUtil.prefHeaderName + i);
313
      this.preferencesUtil.deletePreference(PreferencesUtil.prefHeaderValue + i);
314
      this.preferencesUtil.deletePreference(PreferencesUtil.prefHeaderComment + i);
315
    }
316
  }
317
}
318
319
/*
320
 * Modify Headers Proxy
321
 */
322
function ModifyHeadersProxy() {
323
  //dump("\nEntered ModifyHeadersProxy");
324
  this.headers = new Array();
325
  this.preferencesUtil = new PreferencesUtil();
326
  
327
  this.modifyheadersService = Components.classes["@modifyheaders.mozdev.org/service;1"].getService(Components.interfaces.nsIModifyheaders);
328
  //dump("\nExiting ModifyHeadersProxy");
329
}
330
331
ModifyHeadersProxy.prototype = {
332
  classDescription: "Modify Headers Proxy",
333
  classID:          Components.ID("{0eff9eeb-c51a-4f07-9823-27bc32fdae13}"),
334
  contractID:       "@modifyheaders.mozdev.org/proxy;1",
335
			
336
  QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsIObserver]),
337
  
338
  _xpcom_categories: [
339
    {
340
      category: "profile-after-change",
341
      entry: "Modify Headers Proxy"
342
    }
343
  ],
344
345
		
346
  // nsIObserver interface method
347
  observe: function(subject, topic, data) {
348
349
    //dump("\nEntered ModifyHeadersProxy.prototype.observe");
350
  
351
    if (topic == 'http-on-modify-request') {
352
      //dump("\ntopic is http-on-modify-request");
353
      subject.QueryInterface(Components.interfaces.nsIHttpChannel);
354
    
355
      if (this.modifyheadersService.windowOpen || this.modifyheadersService.alwaysOn) {
356
        var headerCount = this.modifyheadersService.count;
357
      
358
        for (var i=0; i < headerCount; i++) {
359
          //dump("\niteration: " + i);
360
        
361
          if (this.modifyheadersService.isHeaderEnabled(i)) {
362
            var headerName = this.modifyheadersService.getHeaderName(i);
363
          
364
            // This is the default for action = Modify
365
            var headerValue = this.modifyheadersService.getHeaderValue(i);
366
            var headerAppend = false;
367
          
368
            if (this.modifyheadersService.getHeaderAction(i) == "Add") {
369
              headerAppend = true;
370
            } else if (this.modifyheadersService.getHeaderAction(i) == "Filter") {
371
              headerValue = "";
372
            }
373
            //dump("\nAdded header: " + headerName);
374
            subject.setRequestHeader(headerName, headerValue, headerAppend);
375
          }
376
        }
377
        // TODO Add an optional ModifyHeaders header so that users know the tool is active
378
        // subject.setRequestHeader("x-modifyheaders", "version 0.4", true)
379
      }
380
    } else if (topic == 'profile-after-change') {
381
      //dump("\ntopic is profile-after-change");
382
      
383
      if ("nsINetModuleMgr" in Components.interfaces) {
384
        // Should be an old version of Mozilla (before september 15, 2003
385
        // Do Nothing as these old versions of firefox (firebird, phoenix etc) are not supported
386
  	  } else {
387
        // Should be a new version of  Mozilla (after september 15, 2003)
388
        var observerService = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
389
        observerService.addObserver(this, "http-on-modify-request", false);
390
      }
391
    } else {
392
      //dump("\nNo observable topic defined");
393
    }
394
    //dump("\nExiting ModifyHeadersProxy.prototype.observe");
395
  }
396
}
397
398
//A utility class for getting and setting user preferences
399
function PreferencesUtil() {
400
  //dump("\nEntered PreferencesUtil");
401
  this.prefService = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
402
  this.prefService = this.prefService.getBranch("");
403
  //dump("\nExiting PreferencesUtil");
404
}
405
406
// Static strings that specify the names of the preferences used by modifyheaders
407
PreferencesUtil.prefAlwaysOn      = "modifyheaders.config.alwaysOn";
408
PreferencesUtil.prefHeaderCount   = "modifyheaders.headers.count";
409
PreferencesUtil.prefHeaderAction  = "modifyheaders.headers.action";
410
PreferencesUtil.prefHeaderEnabled = "modifyheaders.headers.enabled";
411
PreferencesUtil.prefHeaderName    = "modifyheaders.headers.name";
412
PreferencesUtil.prefHeaderValue   = "modifyheaders.headers.value";
413
PreferencesUtil.prefHeaderComment = "modifyheaders.headers.comment";
414
PreferencesUtil.prefLogMsgs       = "modifyheaders.config.logMsgs";
415
PreferencesUtil.prefOpenAsTab     = "modifyheaders.config.openNewTab";
416
417
// Convenience method to get a user preference value
418
PreferencesUtil.prototype.getPreference = function(type, name) {
419
  var prefValue;
420
  
421
  if (this.prefService.prefHasUserValue(name)) {
422
    if (type=='bool') {
423
      prefValue = this.prefService.getBoolPref(name);
424
    } else if (type=='char') {
425
      prefValue = this.prefService.getCharPref(name);
426
    } else if (type=='int') {
427
      prefValue = this.prefService.getIntPref(name);
428
    }
429
430
  // Set the preference with a default value
431
  } else {
432
    if (type=='bool') {
433
 	    this.setPreference(type, name, false);
434
 	    prefValue = false;
435
    } else if (type=='char') {
436
 	    this.setPreference(type, name, "");
437
 	    prefValue = "";
438
    } else if (type=='int') {
439
      this.setPreference(type, name, 0);
440
      prefValue = 0;
441
    }
442
  }
443
  
444
  return prefValue;
445
}
446
447
// Convenience method to set a user preference
448
PreferencesUtil.prototype.setPreference = function(type, name, value) {
449
  if (type=='bool') {
450
    this.prefService.setBoolPref(name, value);
451
  } else if (type=='char') {
452
    this.prefService.setCharPref(name, value);
453
  } else if (type=='int') {
454
    this.prefService.setIntPref(name, value);
455
  }
456
}
457
458
PreferencesUtil.prototype.deletePreference = function(name) {
459
  this.prefService.clearUserPref(name);
460
}
461
462
/* Entry point - registers the component with the browser */
463
if (XPCOMUtils.generateNSGetFactory) {
464
	//dump("\nUsing NSGetFactory");
465
    var NSGetFactory = XPCOMUtils.generateNSGetFactory([ModifyHeadersService,ModifyHeadersHeader,ModifyHeadersProxy]);
466
} else {
467
	//dump("\nUsing NSGetModule");
468
    var NSGetModule = XPCOMUtils.generateNSGetModule([ModifyHeadersService,ModifyHeadersHeader,ModifyHeadersProxy]);
469
}