webextensions quantum extensions extensiones activar javascript firefox-addon httprequest

extensions - javascript firefox quantum



Solicitud de redireccionamiento(nsiHttpChannel?) En extensiones de Firefox (4)

He estado intentando esto por mucho tiempo y no tengo buenos resultados.

var myObserver = { observe: function(subject, topic, data) { if (topic == "http-on-examine-response") { // implement later } else if(topic == "http-on-modify-request") { // implement later } }, QueryInterface : function (id) { if (id.equals(Components.interfaces["nsIObserver"]) || id.equals(Components.interfaces["nsISupports"])) { return this; } throw Components.results.NS_NOINTERFACE; } }; var obs = new Service("observer-service", "ObserverService"); obs.addObserver(myObserver, "http-on-modify-request", false);

Básicamente, en http-on-modify-request , sé cómo examinar el URI, averiguar a qué ventana (si hay alguna) está asociado, y un montón de otras cosas. Lo que no puedo entender es cómo redirigir una solicitud, que sé que es posible desde aquí, porque puedo obtener un nsIHttpChannel antes de que se envíe alguna solicitud.

¿Alguien sabe qué hacer? : / He estado intentándolo por un par de semanas dentro y fuera, y no llegué a ninguna parte.


Lo he hecho de esta manera: detenga nsIHttpChannel en el nsIHttpChannel "http-on-modify-request" , obtenga el objeto del navegador para la ventana actual, llame al browser.loadURI .

var utils = require("sdk/window/utils"); function needsRedirect(url) { // to be implemented return true; } function generateNewUrl(url) { // to be implemented return "http://www.example.com/"; } Cc["@mozilla.org/observer-service;1"] .getService(Ci.nsIObserverService) .addObserver({ observe: function(subject, topic, data) { var channel = subject.QueryInterface(Ci.nsIHttpChannel); var url = channel.originalURI.spec; if (needsRedirect(url)) { //stop channel.cancel(Cr.NS_BINDING_ABORTED); //redirect var gBrowser = utils.getMostRecentBrowserWindow().gBrowser; var domWin = channel.notificationCallbacks.getInterface(Ci.nsIDOMWindow); var browser = gBrowser.getBrowserForDocument(domWin.top.document); browser.loadURI(generateNewUrl(url)); } } }, "http-on-modify-request", false);


Mientras probaba algo, creé una versión condensada (ver esta esencia ) de la lógica de reemplazo de canales mencionada en otras respuestas.

La idea general parece ser transferir todas las propiedades críticas al nuevo canal, eliminar las devoluciones de llamadas del canal anterior para que las manipulaciones no interrumpan la carga de la página y luego cierren el canal anterior.

Con algunas modificaciones, se puede cambiar el URI de la página para cargas de documentos o dejarlo tal como está.

Advertencia: Eso fue solo un truco rápido para cargar algunas páginas, no lo he probado en profundidad y probablemente se romperá en algunos casos. Sospecho que hay razones por las que HTTPS Everywhere es más complejo.


Podemos hacer esto redefiniendo el nsiHttpChannel con uno nuevo, haciendo esto es un poco complicado, pero afortunadamente el add-on https-everywhere implementa esto para forzar una conexión https.

El código fuente de https-everywhere está disponible here

La mayoría del código necesario para esto está en los archivos

[ IO Util.js ] [ ChannelReplacement.js ]

Podemos trabajar solo con los archivos anteriores, siempre que tengamos las variables básicas como Cc, Ci configuradas y la función xpcom_generateQI definida.

var httpRequestObserver = { observe: function(subject, topic, data) { if (topic == "http-on-modify-request") { var httpChannel = subject.QueryInterface(Components.interfaces.nsIHttpChannel); var requestURL = subject.URI.spec; if(isToBeReplaced(requestURL)) { var newURL = getURL(requestURL); ChannelReplacement.runWhenPending(subject, function() { var cr = new ChannelReplacement(subject, ch); cr.replace(true,null); cr.open(); }); } } }, get observerService() { return Components.classes["@mozilla.org/observer-service;1"] .getService(Components.interfaces.nsIObserverService); }, register: function() { this.observerService.addObserver(this, "http-on-modify-request", false); }, unregister: function() { this.observerService.removeObserver(this, "http-on-modify-request"); } }; httpRequestObserver.register();

El código reemplazará la solicitud no redireccionará.

Si bien he probado el código anterior lo suficientemente bien, no estoy seguro de su implementación. Hasta donde puedo llegar, copia todos los atributos del canal solicitado y los establece en el canal que se anulará. Después de lo cual, de alguna manera, la salida solicitada por la solicitud original se suministra utilizando el nuevo canal.

PD: había visto una publicación SO en la que se sugería este enfoque.


Tengo la impresión de que no se puede hacer esto en este nivel. Probé una variedad de métodos para "engañar" externamente el código que requiere la creación de un nsIHttpChannel (ejemplo al final de la publicación).

Lo que recomendaría es que si desea una redirección, contacte a la ventana de propietario del canal (que funciona el 99% del tiempo) y solicítelo para que lo redirija. Sé que no se comportará de la misma manera, pero como no sé exactamente por qué lo haces, esto externamente (para el usuario) parecerá estar haciendo lo mismo que lo que pides.

Aquí está lo básico de lo que estaba intentando:

if(aTopic == "http-on-examine-response") { var request = aSubject.QueryInterface(Components.interfaces.nsIHttpChannel); if(!request.URI.spec.match("^http://www.apple.com/")) { var ios = Components.classes["@mozilla.org/network/io-service;1"] .getService(Components.interfaces.nsIIOService); var ch = ios.newChannel("http://www.apple.com/", null, null); var listener = { QueryInterface : XPCOMUtils.generateQI([Ci.nsIChannelEventSink]), onDataAvailable: function() {}, onStopRequest: function() {}, onStartRequest: function() {} }; ch.asyncOpen(listener,null); var eventSink = request.notificationCallbacks.getInterface(Ci.nsIChannelEventSink); eventSink.asyncOnChannelRedirect(request,ch,Ci.nsIChannelEventSink.REDIRECT_INTERNAL,function() {}); }