0
votes

I am building an extension with Firefox's ADD ON SDK (v1.9) that will be able to read all HTTP requests / responses and calculate the time they took to load. This includes not only the main frame but any other loading file (sub frame, script, css, image, etc.).

So far, I am able to use the "observer-service" module to listen for:

  • "http-on-modify-request" when a HTTP request is created.
  • "http-on-examine-response" when a HTTP response is received
  • "http-on-examine-cached-response" when a HTTP response is received entirely from cache
  • "http-on-examine-merged-response" when a HTTP response is received partially from cache

My application follows the following sequence:

  1. A request is created and registered through the observer.
  2. I save the current time and mark it as start_time of the request load.
  3. A response for a request is received and registered through one of the observers.
  4. I save the current time and use the previously saved time to calculate load time of the request.

Problem: I am not able to link the start and end times of the load since I cannot find a request ID (or other unique value) that will tie the request with the response. I am currently using the URL of the request / response to tie them together but this is not correct since it will raise a "race condition" if two or more equal urls are loading at the same time. Google Chrome solves this issue by providing unique requestIds, but I have not been able to find a similar functionality on Firefox.

2

2 Answers

2
votes

I am aware of two ways to recognize a channel that you receive in this observer. The "old" solution is to use nsIWritablePropertyBag interface to attach data to the channel:

var {Ci} = require("chrome");
var channelId = 0;

...

// Attach channel ID to a channel
if (channel instanceof Ci.nsIWritablePropertyBag)
  channel.setProperty("myExtension-channelId", ++channelId);

...

// Read out channel ID for a channel
if (channel instanceof Ci.nsIPropertyBag)
  console.log(channel.getProperty("myExtension-channelId"));

The other solution would be using WeakMap API (only works properly starting with Firefox 13):

var channelMap = new WeakMap();
var channelId = 0;

...

// Attach channel ID to a channel
channelMap.set(channel, ++channelId);

...

// Read out channel ID for a channel
console.log(channelMap.get(channel));

I'm not sure whether WeakMap is available in the context of Add-on SDK modules, you might have to "steal" it from a regular JavaScript module:

var {Cu} = require("chrome");
var {WeakMap} = Cu.import("resource://gre/modules/FileUtils.jsm", null);

Obviously, in both cases you can attach more data to the channel than a simple number.

0
votes

Firebug does what you're thinking of by implementing a central observer for these events:

https://github.com/firebug/firebug/blob/master/extension/modules/firebug-http-observer.js

This might be a good place to start, although eventually Firefox will ship a more complete network monitor / debugger by default. I think I read somewhere that it will be based on Firebug's.