mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-19 07:26:26 +00:00
Bug 476567: Clear Access-Control preflight cache when spec says to. Also rewrite cache test-runner to make it more sane. r/sr=jst
--HG-- extra : rebase_source : d92d2eccd14bc58d3e82dff969e27f00fd185f95
This commit is contained in:
parent
42dec6a621
commit
b211410505
@ -53,6 +53,7 @@
|
||||
#include "nsWhitespaceTokenizer.h"
|
||||
#include "nsIChannelEventSink.h"
|
||||
#include "nsCommaSeparatedTokenizer.h"
|
||||
#include "nsXMLHttpRequest.h"
|
||||
|
||||
static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);
|
||||
|
||||
@ -117,6 +118,18 @@ nsCrossSiteListenerProxy::OnStartRequest(nsIRequest* aRequest,
|
||||
{
|
||||
mRequestApproved = NS_SUCCEEDED(CheckRequestApproved(aRequest, PR_FALSE));
|
||||
if (!mRequestApproved) {
|
||||
if (nsXMLHttpRequest::sAccessControlCache) {
|
||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
|
||||
if (channel) {
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
channel->GetURI(getter_AddRefs(uri));
|
||||
if (uri) {
|
||||
nsXMLHttpRequest::sAccessControlCache->
|
||||
RemoveEntries(uri, mRequestingPrincipal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aRequest->Cancel(NS_ERROR_DOM_BAD_URI);
|
||||
mOuterListener->OnStartRequest(aRequest, aContext);
|
||||
|
||||
@ -317,7 +330,17 @@ nsCrossSiteListenerProxy::OnChannelRedirect(nsIChannel *aOldChannel,
|
||||
nsresult rv;
|
||||
if (!NS_IsInternalSameURIRedirect(aOldChannel, aNewChannel, aFlags)) {
|
||||
rv = CheckRequestApproved(aOldChannel, PR_TRUE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
if (nsXMLHttpRequest::sAccessControlCache) {
|
||||
nsCOMPtr<nsIURI> oldURI;
|
||||
aOldChannel->GetURI(getter_AddRefs(oldURI));
|
||||
if (oldURI) {
|
||||
nsXMLHttpRequest::sAccessControlCache->
|
||||
RemoveEntries(oldURI, mRequestingPrincipal);
|
||||
}
|
||||
}
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIChannelEventSink> outer =
|
||||
|
@ -974,7 +974,7 @@ nsAccessControlLRUCache::GetEntry(nsIURI* aURI,
|
||||
// This will delete 'lruEntry'.
|
||||
mTable.Remove(lruEntry->mKey);
|
||||
|
||||
NS_ASSERTION(mTable.Count() >= ACCESS_CONTROL_CACHE_SIZE,
|
||||
NS_ASSERTION(mTable.Count() == ACCESS_CONTROL_CACHE_SIZE,
|
||||
"Somehow tried to remove an entry that was never added!");
|
||||
}
|
||||
}
|
||||
@ -982,6 +982,24 @@ nsAccessControlLRUCache::GetEntry(nsIURI* aURI,
|
||||
return entry;
|
||||
}
|
||||
|
||||
void
|
||||
nsAccessControlLRUCache::RemoveEntries(nsIURI* aURI, nsIPrincipal* aPrincipal)
|
||||
{
|
||||
CacheEntry* entry;
|
||||
nsCString key;
|
||||
if (GetCacheKey(aURI, aPrincipal, PR_TRUE, key) &&
|
||||
mTable.Get(key, &entry)) {
|
||||
PR_REMOVE_LINK(entry);
|
||||
mTable.Remove(key);
|
||||
}
|
||||
|
||||
if (GetCacheKey(aURI, aPrincipal, PR_FALSE, key) &&
|
||||
mTable.Get(key, &entry)) {
|
||||
PR_REMOVE_LINK(entry);
|
||||
mTable.Remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsAccessControlLRUCache::Clear()
|
||||
{
|
||||
|
@ -127,6 +127,7 @@ public:
|
||||
|
||||
CacheEntry* GetEntry(nsIURI* aURI, nsIPrincipal* aPrincipal,
|
||||
PRBool aWithCredentials, PRBool aCreate);
|
||||
void RemoveEntries(nsIURI* aURI, nsIPrincipal* aPrincipal);
|
||||
|
||||
void Clear();
|
||||
|
||||
|
@ -6,26 +6,28 @@ function handleRequest(request, response)
|
||||
query[name] = unescape(value);
|
||||
});
|
||||
|
||||
if ("setState" in query) {
|
||||
setState("test/content/base/test_CrossSiteXHR_cache:secData",
|
||||
query.setState);
|
||||
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
response.setHeader("Content-Type", "text/plain", false);
|
||||
response.write("hi");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var isPreflight = request.method == "OPTIONS";
|
||||
|
||||
// Send response
|
||||
|
||||
response.setHeader("Access-Control-Allow-Origin", query.allowOrigin);
|
||||
secData =
|
||||
eval(getState("test/content/base/test_CrossSiteXHR_cache:secData"));
|
||||
|
||||
if (secData.allowOrigin)
|
||||
response.setHeader("Access-Control-Allow-Origin", secData.allowOrigin);
|
||||
|
||||
if (isPreflight) {
|
||||
var secData = {};
|
||||
|
||||
if (request.hasHeader("Access-Control-Request-Headers")) {
|
||||
var magicHeader =
|
||||
request.getHeader("Access-Control-Request-Headers").split(",").
|
||||
filter(function(name) /^magic-/.test(name))[0];
|
||||
}
|
||||
|
||||
if (magicHeader) {
|
||||
secData = eval(unescape(magicHeader.substr(6)));
|
||||
secData.allowHeaders = (secData.allowHeaders || "") + "," + magicHeader;
|
||||
}
|
||||
|
||||
if (secData.allowHeaders)
|
||||
response.setHeader("Access-Control-Allow-Headers", secData.allowHeaders);
|
||||
|
||||
@ -38,6 +40,7 @@ function handleRequest(request, response)
|
||||
return;
|
||||
}
|
||||
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
response.setHeader("Content-Type", "application/xml", false);
|
||||
response.write("<res>hello pass</res>\n");
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ function runTest() {
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "y-my-header": "hello" },
|
||||
allowHeaders: "y-my-header",
|
||||
allowHeaders: "y-my-header,x-my-header",
|
||||
cacheTime: 3600,
|
||||
},
|
||||
{ pass: 1,
|
||||
@ -158,9 +158,33 @@ function runTest() {
|
||||
allowHeaders: "second-header",
|
||||
cacheTime: 3600,
|
||||
},
|
||||
{ pass: 0,
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "third-header": "myValue" },
|
||||
allowHeaders: "third-header",
|
||||
cacheTime: 2,
|
||||
},
|
||||
{ pause: 2.1 },
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "second-header": "myValue" },
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "GET",
|
||||
headers: { "first-header": "myValue" },
|
||||
},
|
||||
{ newTest: "*******" },
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "first-header": "myValue" },
|
||||
allowHeaders: "first-header",
|
||||
cacheTime: 2,
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "second-header": "myValue" },
|
||||
allowHeaders: "second-header",
|
||||
cacheTime: 3600,
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
@ -169,10 +193,6 @@ function runTest() {
|
||||
cacheTime: 2,
|
||||
},
|
||||
{ pause: 2.1 },
|
||||
{ pass: 0,
|
||||
method: "GET",
|
||||
headers: { "first-header": "myValue" },
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "second-header": "myValue" },
|
||||
@ -214,7 +234,7 @@ function runTest() {
|
||||
{ pass: 1,
|
||||
method: "PATCH",
|
||||
},
|
||||
{ pass: 1,
|
||||
{ pass: 0,
|
||||
method: "XXDELETE",
|
||||
},
|
||||
{ pass: 0,
|
||||
@ -259,8 +279,28 @@ function runTest() {
|
||||
allowMethods: "SECOND",
|
||||
cacheTime: 3600,
|
||||
},
|
||||
{ pass: 0,
|
||||
{ pass: 1,
|
||||
method: "THIRD",
|
||||
allowMethods: "THIRD",
|
||||
cacheTime: 2,
|
||||
},
|
||||
{ pause: 2.1 },
|
||||
{ pass: 1,
|
||||
method: "SECOND",
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "FIRST",
|
||||
},
|
||||
{ newTest: "*******" },
|
||||
{ pass: 1,
|
||||
method: "FIRST",
|
||||
allowMethods: "FIRST",
|
||||
cacheTime: 2,
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "SECOND",
|
||||
allowMethods: "SECOND",
|
||||
cacheTime: 3600,
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "THIRD",
|
||||
@ -268,19 +308,120 @@ function runTest() {
|
||||
cacheTime: 2,
|
||||
},
|
||||
{ pause: 2.1 },
|
||||
{ pass: 0,
|
||||
method: "FIRST",
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "SECOND",
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "THIRD",
|
||||
},
|
||||
{ newTest: "*******" },
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "x-value" },
|
||||
allowHeaders: "x-my-header",
|
||||
cacheTime: 3600,
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "x-value" }
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "GET",
|
||||
headers: { "y-my-header": "y-value" }
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "x-value" }
|
||||
},
|
||||
{ newTest: "*******" },
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "x-value" },
|
||||
allowHeaders: "x-my-header",
|
||||
cacheTime: 3600,
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "x-value" },
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "XXPUT",
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "x-value" },
|
||||
},
|
||||
{ newTest: "*******" },
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "x-value" },
|
||||
allowHeaders: "x-my-header",
|
||||
cacheTime: 3600,
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "x-value" },
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "GET",
|
||||
noOrigin: 1,
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "x-value" },
|
||||
},
|
||||
{ newTest: "*******" },
|
||||
{ pass: 1,
|
||||
method: "XXDELETE",
|
||||
allowMethods: "XXDELETE",
|
||||
cacheTime: 3600,
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "XXDELETE"
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "XXPUT"
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "XXDELETE"
|
||||
},
|
||||
{ newTest: "*******" },
|
||||
{ pass: 1,
|
||||
method: "XXDELETE",
|
||||
allowMethods: "XXDELETE",
|
||||
cacheTime: 3600,
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "XXDELETE"
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "XXDELETE",
|
||||
headers: { "my-header": "value" },
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "XXDELETE"
|
||||
},
|
||||
{ newTest: "*******" },
|
||||
{ pass: 1,
|
||||
method: "XXDELETE",
|
||||
allowMethods: "XXDELETE",
|
||||
cacheTime: 3600,
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "XXDELETE"
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "GET",
|
||||
noOrigin: 1,
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "XXDELETE"
|
||||
},
|
||||
];
|
||||
|
||||
baseURL = "http://localhost:8888/tests/content/base/test/" +
|
||||
"file_CrossSiteXHR_cache_server.sjs?";
|
||||
setStateURL = baseURL + "setState=";
|
||||
|
||||
var unique = Date.now();
|
||||
for each (test in tests) {
|
||||
@ -295,19 +436,18 @@ function runTest() {
|
||||
}
|
||||
|
||||
req = {
|
||||
url: baseURL + "c=" + unique +
|
||||
"&allowOrigin=" + escape(origin),
|
||||
url: baseURL + "c=" + unique,
|
||||
method: test.method,
|
||||
headers: test.headers,
|
||||
};
|
||||
|
||||
if (test.cacheTime || test.allowHeaders || test.allowMethods) {
|
||||
sec = { allowHeaders: test.allowHeaders,
|
||||
allowMethods: test.allowMethods,
|
||||
cacheTime: test.cacheTime };
|
||||
req.headers = req.headers || {};
|
||||
req.headers["magic-" + escape(sec.toSource())] = "";
|
||||
}
|
||||
sec = { allowOrigin: test.noOrigin ? "" : origin,
|
||||
allowHeaders: test.allowHeaders,
|
||||
allowMethods: test.allowMethods,
|
||||
cacheTime: test.cacheTime };
|
||||
xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", setStateURL + escape(sec.toSource()), false);
|
||||
xhr.send();
|
||||
|
||||
loaderWindow.postMessage(req.toSource(), origin);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user