javascriptfirefoxfirefox-addonfirefox-addon-sdktamper-data

Firefox addon - Catch post variables before submit [no enctype]


I have the following form:

<form method="post" action="includes/do.php">
    <input type="text" name="action" value="login" />
    <input type="text" name="email" value="myemail@hotmail.com" />
    <input type="text" name="pass" value="helloworld" />
    <input type="submit" value="Send" />
</form>

Then, I want to catch the variables values before being submitted inside a firefox addon observer. Notice that the form DOESN'T have the attribute: enctype="multipart/form-data". That's an important detail because I have a code that let me get the post data but it only works if enctype="multipart/form-data".

I'm sure I have to use:

var scrStream = Cc["@mozilla.org/scriptableinputstream;1"]
                .createInstance(Ci.nsIScriptableInputStream);

but I have not get a working code so far (I'm a beginner).

I wanna get something like:

{
    "action": "login",
    "email": "myemail@hotmail.com",
    "pass": "helloworld"
}

If you know about some function with the following interface, then better:

function get_post_data(channel) {
    var data;
    // ...
    return data
}

Thank you!


Solution

  • Given you have a nsIUploadChannel channel, you can read the contents of the stream and parse them as if they where GET parameters (e.g. some=value&someother=thing).

    Reading

    var instream = Cc["@mozilla.org/scriptableinputstream;1"].
                   createInstance(Ci.nsIScriptableInputStream);
    instream.init(channel.uploadStream);
    var data = instream.read(instream.available());
    

    Keeping the original upload stream intact

    There are some things to consider, though, if you want to have the original .uploadStream still working, namely you must not access nsIMultiplexInputStream instances at all (these will break) and you must check nsISeekableStream and rewind the stream.

    var ustream = channel.uploadStream;
    if (ustream instanceof Ci.nsIMultiplexInputStream) {
      throw new Error("multiplexed input streams are not supported!");
    }
    if (!(ustream instanceof Ci.nsISeekableStream)) {
      throw new Error("cannot rewind upload stream; not touching");
    }
    var pos = ustream.tell();
    var instream = Cc["@mozilla.org/scriptableinputstream;1"].
                   createInstance(Ci.nsIScriptableInputStream);
    instream.init(ustream);
    var data = instream.read(instream.available());
    ustream.seek(0, pos); // restore position
    

    If you replace the stream with .setUploadStream anyway, then these aren't much of a concern and can be ignored.

    Parsing

    How exactly you parse the GET style parameters is up to you and discussed in other answers already. Only thing to remember is, that usually GET parsers expect a leading ? (e.g. ?some=value), POST data does not have that (e.g. just some=value).