Dhay
Dhay

Reputation: 621

Firefox add-on: HTTP Log that saves to text file with time, username, computername doesn't create text file

I tried to modify a Firefox add-on to save HTTP request to the text file in location I mentioned, with system name and username with time (if the request contains "flag=unknown"). It is to monitor how my subordinates work on the site I gave. But it doesn't work. I don't know how to make it work. Below is my code

Components.utils.import('resource://gre/modules/XPCOMUtils.jsm');
function HttpRequestLogger() {
  var httpRequestLogger = {
    observe: function(subject, topic, data) {
      if (topic == "http-on-modify-request") {
        var httpChannel = subject.QueryInterface(Components.interfaces.nsIHttpChannel);
        var ref = httpChannel.referrer ? httpChannel.referrer.spec : "(none)";
        var buffer = ref + " " + httpChannel.requestMethod + " " 
                         + httpChannel.URI.spec + "\n";
        var n = buffer.search("flag=unknown");
        If (n > 0) {
          fos.write(buffer + "^" + ThisUserName + "^" + TimeStamp + "\r\n");
        }
      }
    }
  };

  var file = 'T:\test';
  file.append("log.txt");
  var fos = Components.classes["@mozilla.org/network/file-output-stream;1"]
                      .createInstance(Components.interfaces.nsIFileOutputStream);

  fos.init(file, 0x02 | 0x08 | 0x10, -1, 0);

  var observerService = Components.classes["@mozilla.org/observer-service;1"]
                                  .getService(Components.interfaces.nsIObserverService);
  observerService.addObserver(httpRequestLogger, "http-on-modify-request", false);
}

HttpRequestLogger.prototype.classID = 
                                Components.ID('{c4a9bb50-b9b2-11e0-a4dd-0800200c9a66}');
HttpRequestLogger.prototype.classDescription = 'Http Request Logger XPCOM Component';
HttpRequestLogger.prototype.contractID = '@prekageo/HttpRequestLogger;1';
var NSGetFactory = XPCOMUtils.generateNSGetFactory([HttpRequestLogger]);

var nsIEnvironment = Components.classes["@mozilla.org/process/environment;1"]
                               .getService(Components.interfaces.nsIEnvironment);
var ThisUserName = nsIEnvironment.get("UserName");
var ThisUserName = nsIEnvironment.get("ComputerName");
var date = new Date();
var TimeStamp = date.toLocaleString();

FYKI:I don't know if it is wrong to leave the classID as it is. credits for the original code goes to @prekageo/HttpRequestLogger.

Upvotes: 0

Views: 203

Answers (1)

Makyen
Makyen

Reputation: 33376

Well, the first problem is that file is a string instead of the required nsIFile in the following statement:

fos.init(file, 0x02 | 0x08 | 0x10, -1, 0);

See: nsIFileOutputStream where it shows that init() has the following parameters:

void init(in nsIFile file, in long ioFlags, in long perm, in long behaviorFlags);

Note that it should also be an nsIFile for the statement: file.append("log.txt");

You should do something like the following:

...
var FileUtils = Components.utils.import("resource://gre/modules/FileUtils.jsm").FileUtils;

var file = new FileUtils.File( 'T:\\test' );
file.append("log.txt");
...

Problem two:
Note: the \\ instead of \ in 'T:\\test'. A single \ just quotes the next character in the string literal. You need the string to actually contain a \, thus it needs to be quoted with another \.

Problem three:
Your use of:

fos.write(buffer + "^" + ThisUserName + "^" + TimeStamp + "\r\n");

does not contain the required length count needed for write().

Possible issue:
You are creating your TimeStamp once, outside of the observer. This will result in a single time-stamp for all entries.

Solving those issues, cleaning up and optimizing a bit gives the following tested functional code:

Components.utils.import('resource://gre/modules/XPCOMUtils.jsm');
function HttpRequestLogger() {
  var httpRequestLogger = {
    observe: function(subject, topic, data) {
      if (topic == "http-on-modify-request") {
        var httpChannel = subject.QueryInterface(Components.interfaces.nsIHttpChannel);
        var ref = httpChannel.referrer ? httpChannel.referrer.spec : "(none)";
        var buffer = ref + " " + httpChannel.requestMethod + " " 
                         + httpChannel.URI.spec + "\n";
        searchRegExp.lastIndex = 0; //Make sure searching from begining.
        if(searchRegExp.test(buffer) ) {
          var date = new Date();
          var TimeStamp = date.toLocaleString();
          buffer += "^" + ThisUserName + "^" + TimeStamp + "\r\n";
          fos.write(buffer, buffer.length);
        }
      }
    }
  };

  //Explicitly define the RegExp here once so it is not implicitly done each time
  //  the observer is called. This saves time in the observer, which, if possible, we
  //  should code to be fast.
  var searchRegExp = /flag=unknown/;

  var FileUtils = Components.utils
                            .import("resource://gre/modules/FileUtils.jsm").FileUtils;

  var file = new FileUtils.File( "T:\\test" );
  file.append("log.txt");

  var fos = Components.classes["@mozilla.org/network/file-output-stream;1"]
                      .createInstance(Components.interfaces.nsIFileOutputStream);
  // PR_WRONLY | PR_CREATE_FILE | PR_APPEND
  fos.init(file, 0x02 | 0x08 | 0x10, -1, 0);


  var nsIEnvironment = Components.classes["@mozilla.org/process/environment;1"]
                                 .getService(Components.interfaces.nsIEnvironment);
  var ThisUserName = nsIEnvironment.get("UserName");
  var ThisComputerName = nsIEnvironment.get("ComputerName");

  var observerService = Components.classes["@mozilla.org/observer-service;1"]
                                  .getService(Components.interfaces.nsIObserverService);
  observerService.addObserver(httpRequestLogger, "http-on-modify-request", false);
}

HttpRequestLogger.prototype.classID =
                                Components.ID('{c4a9bb50-b9b2-11e0-a4dd-0800200c9a66}');
HttpRequestLogger.prototype.classDescription = 'Http Request Logger XPCOM Component';
HttpRequestLogger.prototype.contractID = '@prekageo/HttpRequestLogger;1';
var NSGetFactory = XPCOMUtils.generateNSGetFactory([HttpRequestLogger]);

The other files from the prekageo/http-request-logger repository on GitHub did not require any changes.

Upvotes: 1

Related Questions