nsITraceableChannel, Intercept HTTP Traffic code - javascript

Ive been trying to get this code working for firefox, that I got from
nsITraceableChannel, Intercept HTTP Traffic and from How to get an url from nsITraceableChannel?, Ive been googling for the answer, with no luck.
What I would like to do is intercept certain links, and change them.
Any help is welcomed
The error I get is function statement requires a name witch points to observe: function(aSubject, aTopic, aData) part of the code
const Cc = Components.classes;
const Ci = Components.interfaces;
var observerService = Cc["#mozilla.org/observer-service;1"]
.getService(Ci.nsIObserverService);
observerService.addObserver(httpRequestObserver,
"http-on-examine-response", false);
observerService.removeObserver(httpRequestObserver,
"http-on-examine-response");
//--------------------------------------------------------
var httpRequestObserver =
{
observe: function(aSubject, aTopic, aData)
{
if (aTopic == "http-on-examine-response")
{
}
},
QueryInterface : function (aIID)
{
if (aIID.equals(Ci.nsIObserver) ||
aIID.equals(Ci.nsISupports))
{
return this;
}
throw Components.results.NS_NOINTERFACE;
}
}
//------------------------------------------------------------
function TracingListener() {
this.originalListener = null;
}
TracingListener.prototype =
{
onDataAvailable: function(request, context, inputStream, offset, count) {
this.originalListener.onDataAvailable(request, context, inputStream, offset, count);
},
onStartRequest: function(request, context) {
this.originalListener.onStartRequest(request, context);
},
onStopRequest: function(request, context, statusCode) {
this.originalListener.onStopRequest(request, context, statusCode);
},
QueryInterface: function (aIID) {
if (aIID.equals(Ci.nsIStreamListener) ||
aIID.equals(Ci.nsISupports)) {
return this;
}
throw Components.results.NS_NOINTERFACE;
}
}
observe: function(aSubject, aTopic, aData)
{
if (aTopic == "http-on-examine-response") {
var newListener = new TracingListener();
aSubject.QueryInterface(Ci.nsITraceableChannel);
newListener.originalListener = aSubject.setNewListener(newListener);
}
}
aSubject = aSubject.QueryInterface(Ci.nsIChannel);
var uri = aSubject.URI;
// original URI that was requested before any other resolver steps
// and/or redirects.
var ouri = aSubject.originalURI;
ch = Services.io.newChannel("https://google.com/", null, null);
console.log(ch.toString());
// "[xpconnect wrapped nsIChannel]"
ch.QueryInterface(Ci.nsITraceableChannel);
console.log(ch.toString());
// "[xpconnect wrapped (nsISupports, nsIChannel, nsITraceableChannel)]"
console.log(ch instanceof Ci.nsIUploadChannel);
// true
console.log(ch.toString());
// "[xpconnect wrapped (nsISupports, nsIChannel, nsITraceableChannel, nsIUploadChannel)]"
// the variable "ch" is known to implement the four given interfaces at this point.

Copy paste this it works:
// const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
// Cu.import('resource://gre/modules/Services.jsm');
Services.obs.addObserver(httpRequestObserver, "http-on-examine-response", false);
// Services.obs.removeObserver(httpRequestObserver, "http-on-examine-response");
//--------------------------------------------------------
var httpRequestObserver = {
observe: function(aSubject, aTopic, aData) {
// if (aTopic == "http-on-examine-response") {} // no need for this, we added observer for `http-on-examine-response` so we know for sure this only triggers for `http-on-examine-response`
var newListener = new TracingListener();
aSubject.QueryInterface(Ci.nsITraceableChannel);
newListener.originalListener = aSubject.setNewListener(newListener);
}
/* // what was the point of this block of code?
,
QueryInterface: function(aIID) {
if (aIID.equals(Ci.nsIObserver) || aIID.equals(Ci.nsISupports)) {
return this;
}
throw Cr.NS_NOINTERFACE;
}
*/
}
//------------------------------------------------------------
function TracingListener() {}
TracingListener.prototype = {
onDataAvailable: function(request, context, inputStream, offset, count) {
console.log('data available');
this.originalListener.onDataAvailable(request, context, inputStream, offset, count);
},
onStartRequest: function(request, context) {
this.originalListener.onStartRequest(request, context);
},
onStopRequest: function(request, context, statusCode) {
this.originalListener.onStopRequest(request, context, statusCode);
},
QueryInterface: function(aIID) {
if (aIID.equals(Ci.nsIStreamListener) || aIID.equals(Ci.nsISupports)) {
return this;
}
throw Cr.NS_NOINTERFACE;
}
}
// what the hell? this is not part of an object? why observe colon?
/*
observe: function(aSubject, aTopic, aData) {
if (aTopic == "http-on-examine-response") {
var newListener = new TracingListener();
aSubject.QueryInterface(Ci.nsITraceableChannel);
newListener.originalListener = aSubject.setNewListener(newListener);
}
}
*/
// whats with all this junk? is it supposed to be in an observer??
/*
aSubject = aSubject.QueryInterface(Ci.nsIChannel);
var uri = aSubject.URI;
// original URI that was requested before any other resolver steps
// and/or redirects.
var ouri = aSubject.originalURI;
ch = Services.io.newChannel("https://google.com/", null, null);
console.log(ch.toString());
// "[xpconnect wrapped nsIChannel]"
ch.QueryInterface(Ci.nsITraceableChannel);
console.log(ch.toString());
// "[xpconnect wrapped (nsISupports, nsIChannel, nsITraceableChannel)]"
console.log(ch instanceof Ci.nsIUploadChannel);
// true
console.log(ch.toString());
// "[xpconnect wrapped (nsISupports, nsIChannel, nsITraceableChannel, nsIUploadChannel)]"
// the variable "ch" is known to implement the four given interfaces at this point.
*/
Update
Someone asked me how to get the response source with this, so I created a gist out of it: https://gist.github.com/Noitidart/d0b08629ee2804538ad9#file-_ff-addon-snippet-copyofrequestsource-js-L16

Related

Not able to displaying answer-er Video with the sdpOffer of Offer-er. using WEBRTC

I am not able to displaying answer-er Video with the sdpOffer of Offer-er. using WEBRTC.
Here is my code.could you please help me out. I don't understand Where am going wrong in my code.
var offer;
function getPeerOffer(video_stream) {
var message = {
id : 'Viwer'
}
ws.send(JSON.stringify(message));
ws.onmessage=function(message){
var obj = JSON.parse(message.data)
offer = obj.sdpOffer
answererPeer2(offer, video_stream);
}
}
function answererPeer2(offer, video_stream) {
answerer = new RTCPeerConnection(null);
answerer.addStream(video_stream);
answerer.onaddstream =function (event) {
offererToAnswerer.src = URL.createObjectURL(event.stream);
offererToAnswerer.play();
};
answerer.onicecandidate = function (event) {
if (!event || !event.candidate) return;
answerer.addIceCandidate(event.candidate);
};
var remoteDescription = new RTCSessionDescription(offer);
answerer.setRemoteDescription(remoteDescription);
answerer.createAnswer(function (answer) {
answerer.setLocalDescription(answer);
answerer.addStream(video_stream)
}, function() {}, video_constraints);
}
var video_constraints = {
mandatory: {},
optional: []
};
function getUserMedia(callback) {
var n = navigator;
n.getMedia = n.webkitGetUserMedia || n.mozGetUserMedia;
n.getMedia({
audio: true,
video: true
}, callback, onerror);
function onerror(e) {
alert(JSON.stringify(e, null, '\t'));
}
}
getUserMedia(function (video_stream) {
getPeerOffer(video_stream)
});
}

How to Handle CallBack Functions in AngularJs?

In controller, i am returning object from factory. The method is callback type.
But the problem is that the object is not returing.
My implementation is as:
.factory('fileReadFactory', ['$http',
function ($http) {
var objRead = {
setReadObject: '',
setPath: 'comMyTaxi',
setFileName: '',
status: false,
errorCode: ''
};
var factory = {};
factory.fileRead = function RequestFileSystem(fileName) {
alert('factory start');
objRead.setFileName = fileName;
try {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, createDirectory, fail);
objRead.status = true;
return objRead;
} catch (e) {
return objRead;
}
}
///write steps starts
function createDirectory(fs) {
fs.root.getDirectory(objRead.setPath, {create: true, exclusive: false}, onSuccessCreateFile, fail);
}
function onSuccessCreateFile(dirEntry) {
dirEntry.getFile(objRead.setFileName + '.txt.gz', null, gotFileEntryRead, fail);
}
function gotFileEntryRead(fileEntry) {
// alert('in 2 type step2');
fileEntry.file(gotFileReading, fail);
}
function gotFileReading(file) {
// alert('in 2 type step3');
readFile(file);
}
function readFile(file) {
// alert('in 2 type step4');
var reader = new FileReader();
reader.onloadend = function (e) {
// alert("Text is: "+this.result);
objRead.setReadObject = this.result;
}
reader.readAsText(file);
// alert('reading Ends');
}
//write file ends
function fail(err) {
alert('error ' + err.code);
objRead.errorCode = err.code;
throw e;
}
return factory;
}]);
And my call inside controller is like
var objReturn = fileReadFactory.fileRead('myProfile');
alert(objReturn.status);
alert(JSON.parse(objReturn.setReadObject));
if(objReturn.status){
var obj= JSON.parse(objReturn.setReadObject);
// alert(obj);
// alert('Inside Object World');
$scope.myprofile = obj;
}
I am not getting the if block. So how do i manage the call back;
Try to call your service and execute the alerts in then() function. You should also read about promises: http://andyshora.com/promises-angularjs-explained-as-cartoon.html
var objReturn = fileReadFactory.fileRead('myProfile').then(function(){
alert(objReturn.status);
alert(JSON.parse(objReturn.setReadObject));
if(objReturn.status){
var obj= JSON.parse(objReturn.setReadObject);
// alert(obj);
// alert('Inside Object World');
$scope.myprofile = obj;
}
});

File Reading Failing

The script is being ran on the android OS at the moment.
Globals File
///Store Global Variables
var Globals = {
Storage: window.localStorage,
OfflineMode: false,
GetSettingsString : function()
{
return JSON.stringify(Settings);
},
SetSettings : function(str)
{
try
{
Settings = JSON.parse(str);
if(Settings.Id != 0)
VelocityMeetings.app.navigate("scan/", { root: true });
}
catch(e)
{
alert(e);
Globals.SetSettings();
}
},
///Experimentation Function
SetSettings: function () {
//Settings = JSON.parse(str);
Settings.OfflineMode = false,
Settings.Username = "mager1794",
Settings.Password = "mn1apwfm",
Settings.Id = 0;
alert("Values Set Manually");
//VelocityMeetings.app.navigate("scan/", { root: true });
},
Init: function () {
// this.SetSettings(/*FileStream.ReadFile("settings.dat")*/);
alert("test2");
this.SetSettings(FileStream.ReadFile("settings.dat"));
alert("test3");
},
Save: function () {
FileStream.WriteFile("settings.dat", GetSettingsString());
}
};
document.addEventListener("deviceready", ondeviceReady(), false);
// Cordova is ready to be used!
//
function ondeviceReady() {
alert("test");
Globals.Init();
}
FileSystem File
var FileStream = {
WriteFile: function (filename, objtoWrite) {
_filename = filename;
_dataobj = objtoWrite;
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, _gotFSWrite, fail);
},
WriteFile: function (filename, objtoWrite, type) {
_filename = filename;
_dataobj = objtoWrite;
_type = type;
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, _gotFSWrite, fail);
},
ReadFile: function (filename) {
alert("ReadFile Called");
_filename = filename;
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, _gotFSRead, fail);
return _dataread;
},
_dataread: null,
_dataobj: null,
_type : "WRITE",
_filename: "",
_gotFileWriter: function (writer) {
writer.onwrite = function (evt) {
_isBusy = false;
};
if(_type=="WRITE")
writer.write(_dataobj);
if (_type == "APPEND")
{
writer.seek(writer.length);
writer.write(_dataobj);
}
writer.abort();
},
_gotFSWrite: function (fileSystem) {
fileSystem.root.getFile(_filename, { create: true }, _gotFileEntryWrite, fail);
},
_gotFileEntryWrite: function (fileEntry) {
fileEntry.createWriter(_gotFileWriter, fail);
},
_gotFSRead: function (fileSystem) {
alert("gotFSRead Called");
fileSystem.root.getFile(_filename, { create: true }, _gotFileEntryRead, fail);
},
_gotFileEntryRead: function (fileEntry) {
alert("gotFileEntryRead Called");
fileEntry.file(_gotFileRead, fail);
},
_gotFileRead: function (file) {
alert("gotFileRead Called");
var reader = new FileReader();
reader.onloadend = function (evt) {
_dataread = evt.target.result;
};
reader.readAsText(file);
},
_fail: function (error) {
throw "File Failed";
}
};
the GotFSRead function is never being reached and I cannot figure out why, I've placed in the alerts just so I can watch as it progressed through the functions. Additionally, can you store a callback in a variable? because it seems that the read file function is going to need a callback in order to successfully receive the data.
Yes, in Javascript functions are objects, so they can be assigned to variables just like you're doing in your code here.
The function references in your FileStream object are missing this references, such as this._gotFSRead. For example:
ReadFile: function (filename) {
alert("ReadFile Called");
this._filename = filename;
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, this._gotFSRead, this._fail);
return this._dataread;
},
There are many places where this is missing, and you need to fix your _fail references too.

What is the difference between plug-in-type methods and methods in a global variable

In terms of efficiency,
what's the fastest and most standard way to tweak a function in javascript?
Plugin-style coding would be like this.
; (function ($, window, document, undefined) {
var pluginName = "SoketManager",
dataPlugin = "plugin_" + pluginName,
settings = {
target: this,
width: 350,
height: 150,
theme: 'default'
}
var Plugin = {
// instance...
}
Plugin.prototype = {
connect: function() {
//something.
},
disconnect: function() {
//something.
},
sendmessage: function() {
//something...
},
etc: function() {
}
//etc2: function() .......
}
$.fn[pluginName] = function (arg, contents) {
var args, instance;
if (typeof arg === 'string' && typeof instance[arg] === 'function') {
args = Array.prototype.slice.call(arguments, 1);
return instance[arg].apply(instance, args);
}
And using global variable would be like this..
var SocketManager = {
sock: '',
connect: function () {
var stdInfo = new JSONClientParameters();
var socket = io.connect('http://192.168.1.39:3000', {
query: stdInfo.toGetString()
//'reconnect': true,
// 'reconnection delay': 500,//default 500
//'max reconnection attempts': 10
});
kdbSocketManager.ksock = socket;
socket.on('connect', function () {
alert('successfully connected to the database!!');
});
},
disconnect: function () {
this.ksock.disconnect();
},
sendMessage: function (pMsg, pTargetId) {
this.ksock.emit('sendMessage', { msg: pMsg, targetId: pTargetId });
},
I see no point in coding like the plugin-way. Is it much more simple and easy to read to code like the latter one? could somebody explain this in detail?

Altering HTTP Responses in Firefox Extension

How can I alter the HTTP response body in a Firefox extension? I have setup an http-on-examine-response observer and an nsIStreamListener object with the code below. After I get the data, parse it, and alter it, how do I push the altered response back to the firefox browser? For example, let's say I go to Google.com with my extension enabled, the extension should intercept the response and change every occurence of "google" to "goggle". So when the page is loaded, the user will see "goggle" everywhere.
function TmSteroidsObserver()
{
this.register();
}
TmSteroidsObserver.prototype = {
observe: function(subject, topic, data) {
if (topic == "http-on-examine-response") {
}
else if (topic == "http-on-modify-request") {
var channel = subject.QueryInterface(Components.interfaces.nsIChannel);
var listener = new StreamListener(channel);
}
},
register: function() {
var observerService = Components.classes["#mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
observerService.addObserver(listener, "http-on-modify-request", false);
observerService.addObserver(listener, "http-on-examine-response", false);
},
unregister: function() {
var observerService = Components.classes["#mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
observerService.removeObserver(this, "http-on-modify-request");
observerService.removeObserver(this, "http-on-examine-response");
},
QueryInterface : function(aIID) {
if (aIID.equals(Components.interfaces.nsISupports) ||
aIID.equals(Components.interfaces.nsIObserver))
return this;
throw Components.results.NS_NOINTERFACE;
}
}
function StreamListener(channel) {
channel.notificationCallbacks = listener;
channel.asyncOpen(listener, null);
}
StreamListener.prototype = {
mData: "",
mChannel: null,
// nsIStreamListener
onStartRequest: function (aRequest, aContext) {
this.mData = "";
},
onDataAvailable: function (aRequest, aContext, aStream, aSourceOffset, aLength) {
var scriptableInputStream =
Components.classes["#mozilla.org/scriptableinputstream;1"]
.createInstance(Components.interfaces.nsIScriptableInputStream);
scriptableInputStream.init(aStream);
this.mData += scriptableInputStream.read(aLength);
},
onStopRequest: function (aRequest, aContext, aStatus) {
if (Components.isSuccessCode(aStatus)) {
// request was successfull
this.mCallbackFunc(this.mData);
} else {
// request failed
this.mCallbackFunc(null);
}
this.mChannel = null;
},
// nsIChannelEventSink
onChannelRedirect: function (aOldChannel, aNewChannel, aFlags) {
// if redirecting, store the new channel
this.mChannel = aNewChannel;
},
// nsIInterfaceRequestor
getInterface: function (aIID) {
try {
return this.QueryInterface(aIID);
} catch (e) {
throw Components.results.NS_NOINTERFACE;
}
},
// nsIProgressEventSink (not implementing will cause annoying exceptions)
onProgress : function (aRequest, aContext, aProgress, aProgressMax) { },
onStatus : function (aRequest, aContext, aStatus, aStatusArg) { },
// nsIHttpEventSink (not implementing will cause annoying exceptions)
onRedirect : function (aOldChannel, aNewChannel) { },
// we are faking an XPCOM interface, so we need to implement QI
QueryInterface : function(aIID) {
if (aIID.equals(Components.interfaces.nsISupports) ||
aIID.equals(Components.interfaces.nsIInterfaceRequestor) ||
aIID.equals(Components.interfaces.nsIChannelEventSink) ||
aIID.equals(Components.interfaces.nsIProgressEventSink) ||
aIID.equals(Components.interfaces.nsIHttpEventSink) ||
aIID.equals(Components.interfaces.nsIStreamListener))
return this;
throw Components.results.NS_NOINTERFACE;
}
};
You can use nsITraceableChannel to intercept the response.
You should modify the data which is available to what you need and pass it to the innerListener's OnDataAvailable
Below links would help you understand this better.
http://www.softwareishard.com/blog/firebug/nsitraceablechannel-intercept-http-traffic/
http://www.ashita.org/howto-xhr-listening-by-a-firefox-addon/
For future readers looking for a way to do this in Firefox Quantum, there is an API that lets you filter responses. Using the method for long documents mentioned here, I was able to reliably change what I needed in my (temporary) plugin's background.js like so:
browser.webRequest.onBeforeRequest.addListener(
function fixenator(details) {
let filter = browser.webRequest.filterResponseData(details.requestId);
let decoder = new TextDecoder("utf-8");
let encoder = new TextEncoder();
let str = '';
filter.ondata = event => {
str += decoder.decode(event.data, {stream: true});
};
filter.onstop = event => {
str = str.replace(/searchPattern/g, 'replace pattern');
filter.write(encoder.encode(str));
filter.close();
}
return {};
},
{
urls: ['https://example.com/path/to/url']
//, types: ['main_frame', 'script', 'sub_frame', 'xmlhttprequest', 'other'] // optional
}
, ['blocking']
);
The observer service just call your listeners. Firefox will receive the requests,call your listeners, and send responses. see Mozilla docs Creating HTTP POSTs.

Categories