Reputation: 621
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
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