home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2006 March / PCpro_2006_03.ISO / files / freeware / greasemonkey-0.6.4-fx.xpi / chrome / chromeFiles / content / xmlhttprequester.js < prev   
Encoding:
JavaScript  |  2005-11-30  |  4.2 KB  |  112 lines

  1.  
  2.  
  3. function GM_xmlhttpRequester(unsafeContentWin, chromeWindow) {
  4.   this.unsafeContentWin = unsafeContentWin;
  5.   this.chromeWindow = chromeWindow;
  6. }
  7.  
  8. // this function gets called by user scripts in content security scope to
  9. // start a cross-domain xmlhttp request.
  10. //
  11. // details should look like: 
  12. // {method,url,onload,onerror,onreadystatechange,headers,data}
  13. // headers should be in the form {name:value,name:value,etc}
  14. // can't support mimetype because i think it's only used for forcing
  15. // text/xml and we can't support that
  16. GM_xmlhttpRequester.prototype.contentStartRequest = function(details) {
  17.   // don't actually need the timer functionality, but this pops it 
  18.   // out into chromeWindow's thread so that we get that security 
  19.   // context.
  20.   GM_log("> GM_xmlhttpRequest.contentStartRequest");
  21.  
  22.   // important to store this locally so that content cannot trick us up with
  23.   // a fancy getter that checks the number of times it has been accessed, 
  24.   // returning a dangerous URL the time that we actually use it.
  25.   var url = details.url;
  26.   
  27.   // make sure that we have an actual string so that we can't be fooled with
  28.   // tricky toString() implementations.
  29.   if (typeof url != "string") {
  30.     throw new Error("Invalid url: url must be of type string");
  31.   }
  32.   
  33.   var ioService = Components.classes["@mozilla.org/network/io-service;1"]
  34.                   .getService(Components.interfaces.nsIIOService);
  35.   var scheme = ioService.extractScheme(url);
  36.  
  37.   // This is important - without it, GM_xmlhttpRequest can be used to get
  38.   // access to things like files and chrome. Careful.
  39.   switch (scheme) {
  40.     case "http":
  41.     case "https":
  42.     case "ftp":
  43.       this.chromeWindow.setTimeout(
  44.         GM_hitch(this, "chromeStartRequest", url, details), 0);
  45.       break;
  46.     default:
  47.       throw new Error("Invalid url: " + url);
  48.   }
  49.  
  50.   GM_log("< GM_xmlhttpRequest.contentStartRequest");
  51. }
  52.  
  53. // this function is intended to be called in chrome's security context, so 
  54. // that it can access other domains without security warning
  55. GM_xmlhttpRequester.prototype.chromeStartRequest = function(safeUrl, details) {
  56.   GM_log("> GM_xmlhttpRequest.chromeStartRequest");
  57.   var req = new this.chromeWindow.XMLHttpRequest();
  58.  
  59.   this.setupRequestEvent(this.unsafeContentWin, req, "onload", details);
  60.   this.setupRequestEvent(this.unsafeContentWin, req, "onerror", details);
  61.   this.setupRequestEvent(this.unsafeContentWin, req, "onreadystatechange", 
  62.                          details);
  63.  
  64.   req.open(details.method, safeUrl);
  65.  
  66.   if (details.headers) {
  67.     for (var prop in details.headers) {
  68.       req.setRequestHeader(prop, details.headers[prop]);
  69.     }
  70.   }
  71.  
  72.   req.send(details.data);
  73.   GM_log("< GM_xmlhttpRequest.chromeStartRequest");
  74. }
  75.  
  76. // arranges for the specified 'event' on xmlhttprequest 'req' to call the
  77. // method by the same name which is a property of 'details' in the content
  78. // window's security context.
  79. GM_xmlhttpRequester.prototype.setupRequestEvent = 
  80. function(unsafeContentWin, req, event, details) {
  81.   GM_log("> GM_xmlhttpRequester.setupRequestEvent");
  82.  
  83.   if (details[event]) {
  84.     req[event] = function() {
  85.       GM_log("> GM_xmlhttpRequester -- callback for " + event);
  86.  
  87.       var responseState = {
  88.         // can't support responseXML because security won't
  89.         // let the browser call properties on it
  90.         responseText:req.responseText,
  91.         readyState:req.readyState,
  92.         responseHeaders:(req.readyState == 4 ? 
  93.                          req.getAllResponseHeaders() : 
  94.                          ''),
  95.         status:(req.readyState == 4 ? req.status : 0),
  96.         statusText:(req.readyState == 4 ? req.statusText : '')
  97.       }
  98.  
  99.       // Pop back onto browser thread and call event handler.
  100.       // Have to use nested function here instead of GM_hitch because 
  101.       // otherwise details[event].apply can point to window.setTimeout, which
  102.       // can be abused to get increased priveledges.
  103.       new XPCNativeWrapper(unsafeContentWin, "setTimeout()")
  104.         .setTimeout(function(){details[event](responseState);}, 0);
  105.  
  106.       GM_log("< GM_xmlhttpRequester -- callback for " + event);
  107.     }
  108.   }
  109.  
  110.   GM_log("< GM_xmlhttpRequester.setupRequestEvent");
  111. }
  112.