Идентифицировать http-запрос/ответ по идентификатору

Я создаю расширение с помощью Firefox ADD ON SDK (v1.9), которое сможет читать все HTTP-запросы/ответы и вычислять время их загрузки. Сюда входит не только основной фрейм, но и любой другой загружаемый файл (подкадр, скрипт, css, изображение и т. д.).

Пока что я могу использовать модуль «observer-service» для прослушивания:

  • «http-on-modify-request» при создании HTTP-запроса.
  • "http-on-examine-response" при получении HTTP-ответа
  • «http-on-examine-cached-response», когда ответ HTTP полностью получен из кеша
  • «http-on-examine-merged-response», когда ответ HTTP частично получен из кеша

Мое приложение следует следующей последовательности:

  1. Запрос создается и регистрируется через обозреватель.
  2. Я сохраняю текущее время и отмечаю его как start_time загрузки запроса.
  3. Ответ на запрос принимается и регистрируется через одного из наблюдателей.
  4. Я сохраняю текущее время и использую ранее сохраненное время для расчета времени загрузки запроса.

Проблема: я не могу связать время начала и окончания загрузки, так как не могу найти идентификатор запроса (или другое уникальное значение), который свяжет запрос с ответом. В настоящее время я использую URL-адрес запроса/ответа, чтобы связать их вместе, но это неправильно, поскольку это вызовет «состояние гонки», если два или более одинаковых URL-адреса загружаются одновременно. Google Chrome решает эту проблему, предоставляя уникальные идентификаторы запросов, но мне не удалось найти аналогичную функциональность в Firefox.


person josesigna    schedule 20.08.2012    source источник


Ответы (2)


Я знаю два способа распознать канал, который вы получаете в этом обозревателе. «Старое» решение заключается в использовании nsIWritablePropertyBag интерфейса для присоединения данных к канал:

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"));

Другим решением будет использование WeakMap API (работает только правильно, начиная с 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));

Я не уверен, доступен ли WeakMap в контексте дополнительных модулей SDK, возможно, вам придется «украсть» его из обычного модуля JavaScript:

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

Очевидно, что в обоих случаях к каналу можно привязать больше данных, чем просто номер.

person Wladimir Palant    schedule 21.08.2012

Firebug делает то, о чем вы думаете, реализуя центрального наблюдателя для этих событий:

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

Это может быть хорошей отправной точкой, хотя в конечном счете Firefox по умолчанию будет поставлять более полный сетевой монитор/отладчик. Кажется, я где-то читал, что он будет основан на Firebug.

person therealjeffg    schedule 21.08.2012