// : var uriString = "https://addons.mozilla.org/firefox/downloads/latest/413716/addon-413716-latest.xpi"; var referer = "https://addons.mozilla.org/"; var ios = Components.classes["@mozilla.org/network/io-service;1"] .getService(Components.interfaces.nsIIOService); var uri = ios.newURI(uriString, null, null); var scheme = uri.scheme && uri.scheme.toLowerCase(); var channel = scheme == "about" && "nsIAboutModule" in Components.interfaces // about: ? Components.classes["@mozilla.org/network/protocol/about;1?what=" + uri.path.replace(/[?&#].*$/, "")] .getService(Components.interfaces.nsIAboutModule) .newChannel(uri) : ios.newChannelFromURI(uri);
var observer = { ... }; // nsIStreamListener nsIHttpHeaderVisitor var data = []; // var headers = []; // , if(channel instanceof Components.interfaces.nsIHttpChannel) { // instanceof // channel.QueryInterface(Components.interfaces.nsIHttpChannel), // channel.requestMethod = "HEAD"; // HEAD- channel.setRequestHeader("Referer", referer, false); channel.visitRequestHeaders(observer); headers.push(""); // } // , nsIFTPChannel channel instanceof Components.interfaces.nsIFTPChannel; channel.asyncOpen(observer, null);
var observer = { // nsIRequestObserver (nsIStreamListener ) onStartRequest: function(aRequest, aContext) { if(aRequest instanceof Components.interfaces.nsIHttpChannel) aRequest.visitResponseHeaders(this); else { if("contentType" in channel) data.push(" : " + channel.contentType); if("contentLength" in channel) data.push(" : " + channel.contentLength); if("responseStatus" in channel && "responseStatusText" in channel) data.push(": " + channel.responseStatus + " " + channel.responseStatusText); if("lastModifiedTime" in aRequest && aRequest.lastModifiedTime) { // Firefox 4 var t = aRequest.lastModifiedTime; data.push(" : " + new Date(t > 1e14 ? t/1000 : t).toLocaleString()); } } }, onStopRequest: function(aRequest, aContext, aStatusCode) { if(aRequest instanceof Components.interfaces.nsIChannel && aRequest.URI) data.push(" : " + aRequest.URI.spec); this.done(); }, // nsIStreamListener onDataAvailable: function(aRequest, aContext, aInputStream, aOffset, aCount) { // , - , , aRequest.cancel(Components.results.NS_BINDING_ABORTED); }, // nsIHttpHeaderVisitor visitHeader: function(aHeader, aValue) { headers.push(aHeader + ": " + aValue); switch(aHeader) { // - case "Content-Length": data.push(" : " + aValue); break; case "Content-Type": data.push(" : " + aValue); break; case "Last-Modified": data.push(" : " + new Date(aValue).toLocaleString()); } }, done: function() { alert( data.join("\n") + "\n\n:\n" + headers.join("\n") ); } };
: application/x-xpinstall : 26 2013 . 0:46:30 : 46897 : https://addons.cdn.mozilla.net/storage/public-staging/413716/link_properties_plus-1.5.1-fx+sm+tb.xpi : Host: addons.mozilla.org User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:20.0) Gecko/20100101 Firefox/20.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate Referer: https://addons.mozilla.org/ Server: nginx X-Backend-Server: web13.addons.phx1.mozilla.com Content-Type: application/x-xpinstall Accept-Ranges: bytes Last-Modified: Tue, 26 Feb 2013 00:46:30 GMT X-Cache-Info: caching Content-Length: 46897 Cache-Control: max-age=79492 Expires: Sun, 07 Apr 2013 17:32:01 GMT Date: Sat, 06 Apr 2013 19:27:09 GMT
channel.notificationCallbacks = observer;
var redirects = []; //
done: function() { alert( data.join("\n") + "\n\n:\n" + redirects.join("\n") + "\n\n:\n" + headers.join("\n") ); }
var observer = { ... // nsIInterfaceRequestor getInterface: function(iid) { if(iid.equals(Components.interfaces.nsIChannelEventSink)) return this; throw Components.results.NS_ERROR_NO_INTERFACE; }, // nsIChannelEventSink onChannelRedirect: function(oldChannel, newChannel, flags) { // Gecko < 2 this.onRedirect.apply(this, arguments); }, asyncOnChannelRedirect: function(oldChannel, newChannel, flags, callback) { // , ! callback.onRedirectVerifyCallback(Components.results.NS_OK); this.onRedirect.apply(this, arguments); }, onRedirect: function(oldChannel, newChannel, flags) { if(!redirects.length) // redirects.push(oldChannel.URI.spec); // https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsIChannelEventSink#Constants var ces = Components.interfaces.nsIChannelEventSink; var types = []; if(flags & ces.REDIRECT_TEMPORARY) types.push(""); if(flags & ces.REDIRECT_PERMANENT) types.push(""); if(flags & ces.REDIRECT_INTERNAL) types.push(""); redirects.push("=> (" + types.join(", ") + ") " + newChannel.URI.spec); }, ...
: https://addons.mozilla.org/firefox/downloads/latest/413716/addon-413716-latest.xpi => () https://addons.mozilla.org/firefox/downloads/latest/link-properties-plus/addon-link-properties-plus-latest.xpi => () https://addons.mozilla.org/firefox/downloads/file/185918/link_properties_plus-1.5.1-fx+sm+tb.xpi => () https://addons.cdn.mozilla.net/storage/public-staging/413716/link_properties_plus-1.5.1-fx+sm+tb.xpi
var channel = Services.io.newChannel("http://example.org", null, null); channel.QueryInterface(Components.interfaces.nsIPrivateBrowsingChannel); channel.setPrivate(true); // force the channel to be loaded in private mode
if( private // - && "nsIPrivateBrowsingChannel" in Components.interfaces && channel instanceof Components.interfaces.nsIPrivateBrowsingChannel && "setPrivate" in channel ) channel.setPrivate(true);
Source: https://habr.com/ru/post/175745/
All Articles