>Форум Mozilla Россия http://forum.mozilla-russia.org/index.php >Разработка http://forum.mozilla-russia.org/viewforum.php?id=18 >Дополнение для веб тестировщиков (подскажите куда копать) http://forum.mozilla-russia.org/viewtopic.php?id=49787 |
Ven0m > 13-05-2011 17:32:57 |
Приветствую. Приложение должно следить за всей деятельностью пользователя в браузере или (если возможно) в определенных табах. Так вот, по созданию интерфейса приложения, материалов хватает, но не могу вот найти нормальных док по слежению за пользователем (перехват запросов (ГЕТ и ПОСТ), иначе как мы узнаем что пользователь ввел на странице). Я в этом деле начинающий. Так может кто чего нибудь подсказать. Желательно в каких-нибудь сэмплах. Буду благодарен. |
Ven0m > 13-05-2011 18:08:21 |
Вот нашел интересный семпл, но не совсем догоняю как его юзать. Выделить код Код:if(!livehttpheaders) var livehttpheaders={}; if(!livehttpheaders.nshi) livehttpheaders.nshi={}; livehttpheaders.nshi.HEADERINFO_CONTRACTID = "@mozilla.org/js_headerinfo;1"; livehttpheaders.nshi.HEADERINFO_CID = Components.ID('{d5598f0d-5eba-43bc-b8e1-342a23bce3ea}'); livehttpheaders.nshi.CATMAN_CONTRACTID = "@mozilla.org/categorymanager;1"; livehttpheaders.nshi.JS_SCRIPTABLEINPUTSTREAM_CID = "@mozilla.org/scriptableinputstream;1"; livehttpheaders.nshi.JS_SCRIPTABLEINPUTSTREAM = "nsIScriptableInputStream"; livehttpheaders.nshi.JS_ScriptableInputStream = new Components.Constructor ( livehttpheaders.nshi.JS_SCRIPTABLEINPUTSTREAM_CID, livehttpheaders.nshi.JS_SCRIPTABLEINPUTSTREAM ); /* * Utility functions */ livehttpheaders.nshi.dtb = function (v,d) { var tmp = ("00000000000000000000000000000000"+Math.round(v).toString(2)).slice(-d); return tmp.match(/......../g).join(" "); } livehttpheaders.nshi.dth = function (v,d) { return ("000000000000"+Math.round(v).toString(16)).slice(-d); } /* * Class definitions */ livehttpheaders.nshi.flag = 1; livehttpheaders.nshi.nsHeaderInfo = { onStateChange: function(aProg, aRequest, aFlags, aStatus) { //dump("onStateChange\n"); // As we want all headers, we must wait for the 'STOP' state if (aFlags & Components.interfaces.nsIWebProgressListener.STATE_STOP && aFlags & Components.interfaces.nsIWebProgressListener.STATE_IS_DOCUMENT) { try { // Only http and https are supported... var scheme = aRequest.QueryInterface(Components.interfaces.nsIChannel).URI.scheme; if (scheme != 'http' && scheme != 'https') return; // We must find the 'DOMWindow' to be able to put our 'HeaderInfo' object in it try { aRequest.QueryInterface(Components.interfaces.nsIHttpChannel); } catch (ex) { aRequest.QueryInterface(Components.interfaces.nsIMultiPartChannel); aRequest = aRequest.baseChannel.QueryInterface(Components.interfaces.nsIHttpChannel); } aProg.DOMWindow.document._liveHttpHeaders = new livehttpheaders.nshi.HeaderInfoVisitor(aRequest).getHeaders(); if (livehttpheaders.nshi.flag) { try { var controller = new livehttpheaders.nshi.FakeController(new livehttpheaders.nshi.HeaderInfoVisitor(aRequest).getHeaders()); controller.install(aProg.DOMWindow); } catch (ex) { livehttpheaders.nshi.flag = 0; } } // We are done with the listener, release it aProg.removeProgressListener(this); } catch (ex) {} } }, onProgressChange: function(aProg, b,c,d,e,f) {}, onLocationChange: function(aProg, aRequest, aURI) {}, onStatusChange: function(aProg, aRequest, aStatus, aMessage) {}, onSecurityChange: function(aWebProgress, aRequest, aState) {}, onModifyRequest : function (oHttp) { //dump("onModifyRequest\n"); try { oHttp.QueryInterface(Components.interfaces.nsIRequest); //dump("OMR: loadFlags: " + this.dtb(oHttp.loadFlags,32) + "\n"); // We only need to register a listener if this is a document uri as all embeded object // are checked by the same listener (not true for frames but frames are document uri...) if ((oHttp.loadFlags & Components.interfaces.nsIChannel.LOAD_DOCUMENT_URI) && oHttp.loadGroup && oHttp.loadGroup.groupObserver) { var go = oHttp.loadGroup.groupObserver; go.QueryInterface(Components.interfaces.nsIWebProgress); //go.addProgressListener(this, 0x0b); // 0x2 or 0xff go.addProgressListener(this, Components.interfaces.nsIWebProgress.NOTIFY_STATE_DOCUMENT); // 0x2 or 0xff } } catch (ex) { //dump("nsHeaderInfo: onModifyRequest-ex\n"+ex+"\n"); } }, onExamineResponse : function (oHttp) {}, addObserver : function (observer) { this.observers[observer] = observer; }, removeObserver : function (observer) { delete this.observers[observer]; }, observe: function(aSubject, aTopic, aData) { //dump("Observe\n"); if (aTopic == 'http-on-modify-request') { aSubject.QueryInterface(Components.interfaces.nsIHttpChannel); this.onModifyRequest(aSubject); //} else if (aTopic == 'http-on-examine-response') { // aSubject.QueryInterface(Components.interfaces.nsIHttpChannel); // this.onExamineResponse(aSubject); } else if (aTopic == 'app-startup' || aTopic == 'profile-after-change') { if ('nsINetModuleMgr' in Components.interfaces) { // Should be an old version of Mozilla (before september 15, 2003 var netModuleMgr = Components.classes["@mozilla.org/network/net-extern-mod;1"].getService(Components.interfaces.nsINetModuleMgr); netModuleMgr.registerModule("@mozilla.org/network/moduleMgr/http/request;1", livehttpheaders.nshi.nsHeaderInfo); //netModuleMgr.registerModule("@mozilla.org/network/moduleMgr/http/response;1", nsHeaderInfo); } else { // Should be a new version of Mozilla (after september 15, 2003) var observerService = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService); observerService.addObserver(livehttpheaders.nshi.nsHeaderInfo, "http-on-modify-request", false); //observerService.addObserver(nsHeaderInfo, "http-on-examine-response", false); } // Initialisation of all needed vars this.observers = new Array(); this.delays = new Array(); } else { dump("nsHeaderInfo: unknown TOPIC: " + aTopic + "\n"); } }, GetWeakReference : function () { dump("nsHeaderInfo: GetWeakReference called!!!\n"); }, QueryInterface: function(iid) { if (!iid.equals(Components.interfaces.nsISupports) && !iid.equals(Components.interfaces.nsISupportsWeakReference) && //!iid.equals(Components.interfaces.nsIWeakReference) && //!iid.equals("db242e01-e4d9-11d2-9dde-000064657374") && !iid.equals(Components.interfaces.nsIObserver) && !iid.equals(Components.interfaces.nsIWebProgressListener) && !iid.equals(Components.interfaces.nsIHttpNotify)) { //dump("nsHeaderInfo: QI unknown interface: " + iid + "\n"); throw Components.results.NS_ERROR_NO_INTERFACE; } return this; } }; livehttpheaders.nshi.HeaderInfoVisitor = function(oHttp) { // Keep the Http request object this.oHttp = oHttp; // headers pseudo-object this.headers = new Object(); this.headers.isFromCache = false; this.headers.isFromProxy = false; this.headers.request = ""; this.headers.requestHeaders = null; this.headers.response = ""; this.headers.responseHeaders = null; // Initialize headers this.visitRequest(this); this.visitResponse(this); } livehttpheaders.nshi.HeaderInfoVisitor.prototype = { oHttp : null, headers : null, usedCache : function () { // Check to see if the headers are from the cache try { this.oHttp.QueryInterface(Components.interfaces.nsIRequest); if (this.oHttp.loadFlags & Components.interfaces.nsIRequest.VALIDATE_NEVER) { return true; } else { return false; } } catch (ex) {} }, getHttpResponseVersion: function () { var version = "1.z"; // Default value // Check if this is Mozilla v1.5a and more try { var maj = new Object(); var min = new Object(); this.oHttp.QueryInterface(Components.interfaces.nsIHttpChannelInternal); this.oHttp.getResponseVersion(maj,min); version = "" + maj.value + "."+ min.value; } catch (ex) {} return version; }, getHttpRequestVersion: function (httpProxy) { var version = "1.x"; // Default value for direct HTTP and proxy HTTP // Check if this is Mozilla v1.5a and more try { var maj = new Object(); var min = new Object(); this.oHttp.QueryInterface(Components.interfaces.nsIHttpChannelInternal); this.oHttp.getRequestVersion(maj,min); version = "" + maj.value + "."+ min.value; } catch (ex) { try { // This code is based on netwerk/protocol/http/src/nsHttpHandler.cpp (PrefsChanged) var pref = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService); pref = pref.getBranch(""); // Now, get the value of the HTTP version fields if (httpProxy) { var tmp = pref.getCharPref("network.http.proxy.version"); if (tmp == "1.1") version = tmp; } else { var tmp = pref.getCharPref("network.http.version"); if (tmp == "1.1" || tmp == "0.9") version = tmp; } } catch (ex) {} } return version; }, useHttpProxy : function (uri) { // This code is based on netwerk/base/src/nsProtocolProxyService.cpp (ExamineForProxy) try { var pps = Components.classes["@mozilla.org/network/protocol-proxy-service;1"].getService().QueryInterface(Components.interfaces.nsIProtocolProxyService); // If a proxy is used for this url, we need to keep the host part if (typeof(pps.proxyEnabled) != "undefined") { // Mozilla up to 1.7 if (pps.proxyEnabled && (pps.examineForProxy(uri)!=null)) { // Proxies are enabled. Now, check if it is an HTTP proxy. return this.isHttpProxy(); } } else { // Firefox and Mozilla 1.8+ if (pps.resolve(uri, pps.RESOLVE_NON_BLOCKING)!=null) { // Proxies are enabled. Now, check if it is an HTTP proxy. return this.isHttpProxy(); } } return false; // No proxy or not HTTP Proxy } catch (ex) { return null; // Error } }, isHttpProxy : function() { // Check if an HTTP proxy is configured. var pref = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService); pref = pref.getBranch(""); // Now, get the value of the HTTP proxy fields var http_host = pref.getCharPref("network.proxy.http"); var http_port = pref.getIntPref("network.proxy.http_port"); // network.proxy.http_port network.proxy.http if (http_host && http_port>0) { return true; // HTTP Proxy } return false; }, readLine : function(stream) { var line = ""; var size = 0; try { size = stream.available(); } catch(ex) { size = 0; } for (var i=0; i<size; i++) { var c = stream.read(1); if (c == '\r') { } else if (c == '\n') { break; } else { line += c; } } return line; }, visitPostHeaders: function(visitor) { // Get the headers from postData stream if present try { // Must change HttpChannel to UploadChannel to be able to access post data this.oHttp.QueryInterface(Components.interfaces.nsIUploadChannel); // Get the post data stream if (this.oHttp.uploadStream) { try { // Must check if there is headers in the stream this.oHttp.uploadStream.QueryInterface(Components.interfaces.nsIMIMEInputStream); // Must change to SeekableStream to be able to rewind the stream this.oHttp.uploadStream.QueryInterface(Components.interfaces.nsISeekableStream); this.oHttp.uploadStream.seek(0,0); // Need to create a seekable stream to be able to read the stream in javascript var stream = new livehttpheaders.nshi.JS_ScriptableInputStream(); stream.init(this.oHttp.uploadStream); // Now we can start to get the headers var line = this.readLine(stream); while (line) { var tmp = line.split(/:\s?/); visitor.visitHeader(tmp[0],tmp[1]); line = this.readLine(stream); } } catch (ex) { } finally { // The main request should take care of closing the stream, // not this listener. But this seems to cause problems with // Seamonkey! //this.oHttp.uploadStream.close(); //stream.close(); //this.oHttp.uploadStream.seek(2,0); try { stream.read(stream.available()); } catch (ex) {} } } } catch (e) {} }, visitHeader : function (name, value) { this.theaders[name] = value; }, visitRequest : function () { this.theaders = new Array(); var uri, note, ver; try { // Get the URL and get parts // Should I use this.oHttp.URI.prePath and this.oHttp.URI.path to make // the URL ? I still need to remove the '#' sign if present in 'path' var url = String(this.oHttp.URI.asciiSpec); // If an http proxy is used for this url, we need to keep the host part this.headers.isFromProxy = this.useHttpProxy(this.oHttp.URI); if (this.headers.isFromProxy) { uri = url.match(/^(.*?\/\/[^\/]+\/[^#]*)/)[1]; ver = this.getHttpRequestVersion(true); } else { uri = url.match(/^.*?\/\/[^\/]+(\/[^#]*)/)[1]; ver = this.getHttpRequestVersion(false); } } catch (ex) { uri = String(this.oHttp.URI.asciiSpec); ver = "1.x"; } this.headers.request = this.oHttp.requestMethod + " " + uri + " HTTP/" + ver; this.oHttp.visitRequestHeaders(this); this.visitPostHeaders(this); this.headers.requestHeaders = this.theaders; }, visitResponse : function () { var ver = this.getHttpResponseVersion(); this.theaders = new Array(); this.headers.response = "HTTP/" + ver + " " + this.oHttp.responseStatus + " " + this.oHttp.responseStatusText; this.oHttp.visitResponseHeaders(this); this.headers.responseHeaders = this.theaders; // Check if we received theses headers from the cache or not this.headers.isFromCache = this.usedCache(); }, getHeaders : function() { return this.headers; } } livehttpheaders.nshi.FakeController = function(oHeaders) { this.headers = oHeaders; this.wrappedJSObject = this; } livehttpheaders.nshi.FakeController.prototype = { headers: null, url: null, isCommandEnabled: function(command) { return false; }, supportsCommand: function(command) { return (command == 'livehttpheaders'); }, install: function(oWindow) { // Remove any previously installed controllers first var controllers = oWindow.controllers; while (controllers.wrappedJSObject) controllers = controllers.wrappedJSObject var constroller = controllers.getControllerForCommand('livehttpheaders'); var controller; while (controller = controllers.getControllerForCommand('livehttpheaders')) controllers.removeController(controller); this.url = oWindow.location.href; controllers.appendController(this); } } /* * Objects */ /* nsHeaderInfo Module (for XPCOM registration) */ livehttpheaders.nshi.nsHeaderInfoModule = { classID: Components.ID("{d5598f0d-5eba-43bc-b8e1-342a23bce3ea}"), firstTime : true, registerSelf: function(compMgr, fileSpec, location, type) { dump("nsHeaderInfo: registerSelf called!\n"); if (this.firstTime) { this.firstTime = false; throw Components.results.NS_ERROR_FACTORY_REGISTER_AGAIN; } var compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar); compMgr.registerFactoryLocation(livehttpheaders.nshi.HEADERINFO_CID, "nsHeaderInfo JS component", livehttpheaders.nshi.HEADERINFO_CONTRACTID, fileSpec, location, type); var catman = Components.classes[livehttpheaders.nshi.CATMAN_CONTRACTID].getService(Components.interfaces.nsICategoryManager); catman.addCategoryEntry("app-startup", "HeaderInfo", livehttpheaders.nshi.HEADERINFO_CONTRACTID,true, true); }, unregisterSelf: function(compMgr, fileSpec, location) { // Remove the auto-startup var compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar); compMgr.unregisterFactoryLocation(livehttpheaders.nshi.HEADERINFO_CID, fileSpec); var catman = Components.classes[livehttpheaders.nshi.CATMAN_CONTRACTID].getService(Components.interfaces.nsICategoryManager); catman.deleteCategoryEntry("app-startup", livehttpheaders.nshi.HEADERINFO_CONTRACTID, true); }, getClassObject: function(compMgr, cid, iid) { if (!cid.equals(livehttpheaders.nshi.HEADERINFO_CID)) throw Components.results.NS_ERROR_NO_INTERFACE; if (!iid.equals(Components.interfaces.nsIFactory)) throw Components.results.NS_ERROR_NOT_IMPLEMENTED; return livehttpheaders.nshi.nsHeaderInfoFactory; }, canUnload: function(compMgr) { return true; } }; /* nsHeaderInfo Class Factory */ livehttpheaders.nshi.nsHeaderInfoFactory = { createInstance: function(outer, iid) { if (outer != null) { throw Components.results.NS_ERROR_NO_AGGREGATION; } if (!iid.equals(Components.interfaces.nsISupports) && !iid.equals(Components.interfaces.nsIObserver)) { throw Components.results.NS_ERROR_INVALID_ARG; } return livehttpheaders.nshi.nsHeaderInfo; } } /* * Functions */ /* module initialisation */ function NSGetModule(comMgr, fileSpec) { return livehttpheaders.nshi.nsHeaderInfoModule; } function NSGetFactory(cid) { return livehttpheaders.nshi.nsHeaderInfoFactory; } Может ли кто-нибудь провести краткий ликбез? |
lazy_man > 19-05-2011 11:39:27 |
Ven0m пишет
А чем вам Firebug не подходит? |
Ven0m > 19-05-2011 11:52:05 |
Файрбаг подходит для самого тестинга и отладки, а меня же интересует тема автоматизации составления документации. С пунктами 5 и 6 все ясно, как делать, а вот 3й самый главный, хотелось бы реализовать что бы сохранялись POST запросы и данные инпутов при сабмите форм. Есть большое желание автоматизировать рутинные процессы составления кейсов и отчетов. |
lazy_man > 19-05-2011 15:51:45 |
Аааа... Я не понял о чем речь шла. Тогда действительно мое сообщение ни к чему |