diff options
-rw-r--r-- | 0001-Make-cached-parameter-for-making-a-resource-explicit.patch | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/0001-Make-cached-parameter-for-making-a-resource-explicit.patch b/0001-Make-cached-parameter-for-making-a-resource-explicit.patch new file mode 100644 index 0000000..678e0e2 --- /dev/null +++ b/0001-Make-cached-parameter-for-making-a-resource-explicit.patch @@ -0,0 +1,157 @@ +From 5e88bb97d50c1ee32f60aa9ae062a101781de97c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Mat=C4=9Bj=20Cepl?= <mcepl@redhat.com> +Date: Sun, 22 May 2011 02:46:39 +0200 +Subject: [PATCH] Make cached parameter for making a resource explicitly + cached. + +Attempt to fix https://bugzilla.mozilla.org/show_bug.cgi?id=655749 +(I wonder how much this cache is different from Firefox own caching). +--- + packages/addon-kit/lib/request.js | 92 +++++++++++++++++++++++++++++++++++-- + 1 files changed, 87 insertions(+), 5 deletions(-) + +diff --git a/packages/addon-kit/lib/request.js b/packages/addon-kit/lib/request.js +index 50da22a..f93716d 100644 +--- a/packages/addon-kit/lib/request.js ++++ b/packages/addon-kit/lib/request.js +@@ -39,6 +39,8 @@ const xpcom = require("xpcom"); + const xhr = require("xhr"); + const errors = require("errors"); + const apiUtils = require("api-utils"); ++const ss = require("simple-storage"); ++ + + // Ugly but will fix with: https://bugzilla.mozilla.org/show_bug.cgi?id=596248 + const EventEmitter = require('events').EventEmitter.compose({ +@@ -62,6 +64,10 @@ const validator = new OptionsValidator({ + contentType: { + map: function (v) v || "application/x-www-form-urlencoded", + is: ["string"] ++ }, ++ cached: { ++ map: function (v) v || false, ++ is: ["boolean"] + } + }); + +@@ -74,9 +80,9 @@ function Request(options) { + // request will hold the actual XHR object + let request; + let response; +- +- if ('onComplete' in options) +- self.on('complete', options.onComplete) ++ if ('onComplete' in options) { ++ self.on('complete', options.onComplete); ++ } + options = validator.validateOptions(options); + + // function to prep the request since it's the same between GET and POST +@@ -86,6 +92,17 @@ function Request(options) { + throw new Error(REUSE_ERROR); + } + ++ var _recordingCache = (typeof options.recording === "undefined") ? false : options.recording; ++ ++ if (options.cached && !("httpRequestCache" in ss.storage)) { ++ ss.storage.httpRequestCache = {}; ++ } ++ ++ if (options.cached) { ++ makeCachedRequest(mode); ++ return; ++ } ++ + request = new xhr.XMLHttpRequest(); + + let url = options.url; +@@ -111,19 +128,84 @@ function Request(options) { + // handle the readystate, create the response, and call the callback + request.onreadystatechange = function () { + if (request.readyState == 4) { ++ if (_recordingCache && request.status == 200) { ++ // index by unmodified URL we don't want to index by data ++ ss.storage.httpRequestCache[options.url] = { ++ responseText: request.responseText, ++ lastModified: new Date(request.getResponseHeader("Last-Modified")), ++ eTag: request.getResponseHeader("ETag"), ++ allResponseHeaders: request.getAllResponseHeaders() ++ }; ++ } + response = new Response(request); + errors.catchAndLog(function () { + self._emit('complete', response); + })(); + } +- } ++ }; + + // actually send the request. we only want to send data on POST requests + request.send(mode == "POST" ? data : null); + } + ++ /** ++ * return simulated request object or null, if the request is not cached ++ */ ++ function makeCachedRequest(_mode) { ++ // request must provide in emitting "complete" at least these properties: ++ // request.responseText, request.status, request.statusText, ++ // and request.getAllResponseHeaders() ++ if (ss.storage.httpRequestCache && (options.url in ss.storage.httpRequestCache)) { ++ var cache = ss.storage.httpRequestCache[options.url]; ++ ++ // Randomize URL to avoid caching ++ // TODO see https://fedorahosted.org/bugzilla-triage-scripts/ticket/21 ++ // for more thorough discussion and possible further improvement ++ options.url += (options.url.match(/\?/) == null ? "?" : "&") + (new Date()).getTime(); ++ ++ // check HEAD request and if (etag != cachedETag) && (last-modified > cachedLastModified) ++ // recursive call, but with options.cached set to false ++ var _headRequest = new xhr.XMLHttpRequest(); ++ _headRequest.open("HEAD", options.url, true); ++ _headRequest.onreadystatechange=function() { ++ if (_headRequest.readyState==4) { ++ var _curETag = _headRequest.getResponseHeader("ETag"); ++ var _curLastModified = new Date(_headRequest.getResponseHeader("Last-Modified")); ++ console.log("_curLastModified = " + _curLastModified); ++ console.log("cache.lastModified = " + cache.lastModified); ++ if ((_curETag == cache.eTag) || (_curLastModified <= cache.lastModified)) { ++ console.log("Loading from cache!"); ++ // create false request with cached values ++ var fake_response = new Response({ ++ responseText: cache.responseText, ++ status: 200, // could we have anything else than 200? ++ statusText: "200 OK", ++ getAllResponseHeaders: function() { ++ return cache.allResponseHeaders; ++ } ++ }); ++ errors.catchAndLog(function () { ++ self._emit('complete', fake_response); ++ })(); ++ } else { // cache is not up-to-date ++ console.log("Too old cache!"); ++ options.cached = false; ++ options.recording = true; ++ makeRequest(_mode); ++ } ++ } ++ } ++ _headRequest.send(null); ++ } else { // We don't have this URL in cache at all ++ console.log("Not cached at all!"); ++ options.cached = false; ++ options.recording = true; ++ makeRequest(_mode); ++ } ++ } ++ + // Map these setters/getters to the options +- ["url", "headers", "content", "contentType"].forEach(function (k) { ++ ["url", "headers", "cached", "content", "contentType"].forEach(function (k) { + _public.__defineGetter__(k, function () options[k]); + _public.__defineSetter__(k, function (v) { + // This will automatically rethrow errors from apiUtils.validateOptions. +-- +1.7.6.1 + |