admin管理员组文章数量:1327823
I am trying to develop a Firefox extension that drops every HTTP request to a certain site and returns a fake response. No request should get through to the original web server, but I want to be able to create a custom response. I tried to intercept the "http-on-modify-request" message, but cancelling the request doesn't seem to work, as I cannot simulate a real response afterwards. Similarly, using an nsITraceableStream instance, I don't seem to be able to really cancel the request. I am out of ideas, can somebody help?
I am trying to develop a Firefox extension that drops every HTTP request to a certain site and returns a fake response. No request should get through to the original web server, but I want to be able to create a custom response. I tried to intercept the "http-on-modify-request" message, but cancelling the request doesn't seem to work, as I cannot simulate a real response afterwards. Similarly, using an nsITraceableStream instance, I don't seem to be able to really cancel the request. I am out of ideas, can somebody help?
Share Improve this question edited Aug 15, 2014 at 22:21 Niklas B. asked Aug 28, 2011 at 17:25 Niklas B.Niklas B. 95.4k18 gold badges199 silver badges226 bronze badges 7- What is this extension supposed to be used for? – Amir Raminfar Commented Aug 28, 2011 at 17:31
- Maybe you want to have a look how LeechBlock blocks the requests: addons.mozilla/en-US/firefox/addon/leechblock – Felix Kling Commented Aug 28, 2011 at 17:52
- @Felix: I know how to block requests, but if I do it the usual way (reacting to the "http-on-modify-request" message), I can not fake a response. – Niklas B. Commented Aug 28, 2011 at 18:24
- @Amir: We (an IT security pany I work for) want to use it for demonstration purposes to show how easy it is to manipulate SSL-secured connections when you have access to the client side (browser). – Niklas B. Commented Aug 28, 2011 at 18:37
- 1 @Niklas: Why not just use the Fiddler (www.fiddler2.) AutoResponder to do this? You can then do your demo in ALL browsers. – EricLaw Commented Aug 29, 2011 at 0:13
1 Answer
Reset to default 9The answer below has been superseded as of Firefox 21, now the nsIHttpChannel.redirectTo() method does the job nicely. You can redirect to a data: URI, something like this will work:
Components.utils.import("resource://gre/modules/Services.jsm");
const Ci = Components.interfaces;
[...]
onModifyRequest: function(channel)
{
if (channel instanceof Ci.nsIHttpChannel && shouldRedirect(channel.URI.spec))
{
let redirectURL = "data:text/html," + encodeURIComponent("<html>Hi there!</html>");
channel.redirectTo(Services.io.newURI(redirectURI, null, null));
}
}
Original answer (outdated)
Each channel has its associated stream listener that gets notified when data is received. All you need to do to fake a response is to get this listener and feed it with wrong data. And nsITraceableChannel is in fact the way to do it. You need to replace the channel's usual listener by your own that won't do anything, after that you can cancel the channel without the listener being notified about it. And then you trigger the listener and give it your own data. Something like this:
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
const Cc = Components.classes;
const Ci = Components.interfaces;
[...]
onModifyRequest: function(channel)
{
if (channel instanceof Ci.nsIHttpChannel && channel instanceof Ci.nsITraceableChannel)
{
// Our own listener for the channel
var fakeListener = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIStreamListener,
Ci.nsIRequestObserver, Ci.nsIRunnable]),
oldListener: null,
run: function()
{
// Replace old listener by our fake listener
this.oldListener = channel.setNewListener(this);
// Now we can cancel the channel, listener old won't notice
//channel.cancel(Components.results.NS_BINDING_ABORTED);
},
onDataAvailable: function(){},
onStartRequest: function(){},
onStopRequest: function(request, context, status)
{
// Call old listener with our data and set "response" headers
var stream = Cc["@mozilla/io/string-input-stream;1"]
.createInstance(Ci.nsIStringInputStream);
stream.setData("<html>Hi there!</html>", -1);
this.oldListener.onStartRequest(channel, context);
channel.setResponseHeader("Refresh", "5; url=http://google./", false);
this.oldListener.onDataAvailable(channel, context, stream, 0, stream.available());
this.oldListener.onStopRequest(channel, context, Components.results.NS_OK);
}
}
// We cannot replace the listener right now, see
// https://bugzilla.mozilla/show_bug.cgi?id=646370.
// Do it asynchronously instead.
var threadManager = Cc["@mozilla/thread-manager;1"]
.getService(Ci.nsIThreadManager);
threadManager.currentThread.dispatch(fakeListener, Ci.nsIEventTarget.DISPATCH_NORMAL);
}
}
The problem with this code is still that the page shows up blank if the channel is canceled (so I mented that line) - it seems that the listener still looks at the channel and notices that it is canceled.
本文标签: javascriptFirefox extension Cancel requests and emit fake responsesStack Overflow
版权声明:本文标题:javascript - Firefox extension: Cancel requests and emit fake responses - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742224520a2435923.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论