merge
authorHonza Bambas <honzab.moz@firemni.cz>
Tue, 23 Oct 2012 17:37:27 +0200
changeset 111290 0596b33d527d98e71fd52d65a8b93fa2672e17bd
parent 111288 f191bbf51b6bb2fa6fb39f67f14afe1cfab0a0ac (current diff)
parent 111289 22effc39c25074d1996f980d725f154dab1471df (diff)
child 111292 f39a603626882c606a248ab97cffa0b51000e245
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
milestone19.0a1
merge
netwerk/protocol/http/nsHttpChannelAuthProvider.cpp
--- a/content/base/test/file_XHR_anon.sjs
+++ b/content/base/test/file_XHR_anon.sjs
@@ -1,18 +1,17 @@
 function handleRequest(request, response) {
   let invalidHeaders = ["Cookie"];
   let headers = {};
 
   if (request.queryString == "expectAuth=true") {
     if (request.hasHeader("Authorization")) {
       headers["authorization"] = request.getHeader("Authorization");
     } else {
-      response.setStatusLine(null, 401, "Authentication required");
-      response.setHeader("WWW-Authenticate", "basic realm=\"testrealm\"", true);
+      response.setStatusLine(null, 500, "Server Error");
     }
   } else {
     invalidHeaders.push("Authorization");
   }
 
   for each (let header in invalidHeaders) {
     if (request.hasHeader(header)) {
       response.setStatusLine(null, 500, "Server Error");
--- a/content/base/test/test_XHR_anon.html
+++ b/content/base/test/test_XHR_anon.html
@@ -11,168 +11,77 @@
 <iframe id="loader"></iframe>
 </p>
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
 <script class="testbody" type="application/javascript;version=1.8">
 
-// An XHR with the anon flag set will not send cookie and auth information.
-const TEST_URL = "http://example.com/tests/content/base/test/file_XHR_anon.sjs";
-document.cookie = "foo=bar";
-
-let am = {
-  authMgr: null,
-
-  init: function() {
-    const {classes: Cc, interfaces: Ci} = SpecialPowers.wrap(Components);
-
-    this.authMgr = Cc["@mozilla.org/network/http-auth-manager;1"]
-                     .getService(Components.interfaces.nsIHttpAuthManager)
-  },
-
-  addIdentity: function() {
-    this.authMgr.setAuthIdentity("http", "example.com", -1, "basic", "testrealm",
-                                 "", "example.com", "user1", "password1");
-  },
-
-  tearDown: function() {
-    this.authMgr.clearAll();
-  },
-}
-
-var tests = [ test1, test2, test2a, test3, test3, test3, test4, test4, test4, test5, test5, test5 ];
 
 function runTests() {
-  if (!tests.length) {
-    am.tearDown();
-    SpecialPowers.removePermission("systemXHR", document);
-    SimpleTest.finish();
-    return;
+  let tearDown = (function setUp() {
+    SimpleTest.waitForExplicitFinish();
+
+    const {classes: Cc, interfaces: Ci} = SpecialPowers.wrap(SpecialPowers.Components);
+
+    let authMgr = Cc["@mozilla.org/network/http-auth-manager;1"]
+                    .getService(SpecialPowers.Ci.nsIHttpAuthManager)
+    authMgr.setAuthIdentity("http", "example.com", 80, "basic", "testrealm",
+                            "", "example.com", "user1", "password1");
+
+    SpecialPowers.addPermission("systemXHR", true, document);
+
+    return function tearDown() {
+      authMgr.clearAll();
+      SpecialPowers.removePermission("systemXHR", document);
+      SimpleTest.finish();
+    }
+  }());
+
+  // An XHR with the anon flag set will not send cookie and auth information.
+
+  const TEST_URL = "http://example.com/tests/content/base/test/file_XHR_anon.sjs";
+
+  document.cookie = "foo=bar";
+
+
+  function withoutCredentials() {
+    let xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true});
+    is(xhr.mozAnon, true, "withoutCredentials: .mozAnon == true");
+    xhr.open("GET", TEST_URL);
+    xhr.onload = function onload() {
+      is(xhr.status, 200, "withoutCredentials: " + xhr.responseText);
+      withCredentials();
+    };
+    xhr.onerror = function onerror() {
+      ok(false, "Got an error event!");
+      tearDown();
+    }
+    xhr.send();
   }
 
-  var test = tests.shift();
-  test();
-}
-
-function test1() {
-  am.addIdentity();
+  function withCredentials() {
+    // TODO: this currently does not work as expected, see bug 761479
+    let xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true});
+    is(xhr.mozAnon, true, "withCredentials: .mozAnon == true");
+    xhr.open("GET", TEST_URL + "?expectAuth=true", true,
+             "user2name", "pass2word");
+    xhr.onload = function onload() {
+      todo_is(xhr.status, 200, "withCredentials: " + xhr.responseText);
+      let response = JSON.parse(xhr.responseText);
+      todo_is(response.authorization, "Basic dXNlcjJuYW1lOnBhc3Myd29yZA==");
+      tearDown();
+    };
+    xhr.onerror = function onerror() {
+      ok(false, "Got an error event!");
+      tearDown();
+    }
+    xhr.send();
+  }
 
-  let xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true});
-  is(xhr.mozAnon, true, "test1: .mozAnon == true");
-  xhr.open("GET", TEST_URL);
-  xhr.onload = function onload() {
-    is(xhr.status, 200, "test1: " + xhr.responseText);
-    am.tearDown();
-    runTests();
-  };
-  xhr.onerror = function onerror() {
-    ok(false, "Got an error event!");
-    am.tearDown();
-    runTests();
-  }
-  xhr.send();
+  withoutCredentials();
 }
 
-function test2() {
-  am.addIdentity();
-
-  let xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true});
-  is(xhr.mozAnon, true, "test2: .mozAnon == true");
-  xhr.open("GET", TEST_URL + "?expectAuth=true", true,
-           "user2name", "pass2word");
-  xhr.onload = function onload() {
-    is(xhr.status, 200, "test2: " + xhr.responseText);
-    let response = JSON.parse(xhr.responseText);
-    is(response.authorization, "Basic dXNlcjJuYW1lOnBhc3Myd29yZA==");
-    am.tearDown();
-    runTests();
-  };
-  xhr.onerror = function onerror() {
-    ok(false, "Got an error event!");
-    am.tearDown();
-    runTests();
-  }
-  xhr.send();
-}
-
-function test2a() {
-  am.addIdentity();
-
-  let xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true});
-  is(xhr.mozAnon, true, "test2: .mozAnon == true");
-  xhr.open("GET", TEST_URL + "?expectAuth=true", true,
-           "user1", "pass2word");
-  xhr.onload = function onload() {
-    is(xhr.status, 200, "test2: " + xhr.responseText);
-    let response = JSON.parse(xhr.responseText);
-    is(response.authorization, "Basic dXNlcjE6cGFzczJ3b3Jk");
-    am.tearDown();
-    runTests();
-  };
-  xhr.onerror = function onerror() {
-    ok(false, "Got an error event!");
-    am.tearDown();
-    runTests();
-  }
-  xhr.send();
-}
-
-function test3() {
-  am.addIdentity();
-
-  let xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true});
-  is(xhr.mozAnon, true, "test3: .mozAnon == true");
-  xhr.open("GET", TEST_URL + "?expectAuth=true", true);
-  xhr.onload = function onload() {
-    is(xhr.status, 401, "test3: " + xhr.responseText);
-    am.tearDown();
-    runTests();
-  };
-  xhr.onerror = function onerror() {
-    ok(false, "Got an error event!");
-    am.tearDown();
-    runTests();
-  }
-  xhr.send();
-}
-
-function test4() {
-  let xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true});
-  is(xhr.mozAnon, true, "test4: .mozAnon == true");
-  xhr.open("GET", TEST_URL + "?expectAuth=true", true);
-  xhr.onload = function onload() {
-    is(xhr.status, 401, "test4: " + xhr.responseText);
-    runTests();
-  };
-  xhr.onerror = function onerror() {
-    ok(false, "Got an error event!");
-    runTests();
-  }
-  xhr.send();
-}
-
-function test5() {
-  let xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true});
-  is(xhr.mozAnon, true, "test5: .mozAnon == true");
-  xhr.open("GET", TEST_URL + "?expectAuth=true", true,
-           "user2name", "pass2word");
-  xhr.onload = function onload() {
-    is(xhr.status, 200, "test5: " + xhr.responseText);
-    let response = JSON.parse(xhr.responseText);
-    is(response.authorization, "Basic dXNlcjJuYW1lOnBhc3Myd29yZA==");
-    runTests();
-  };
-  xhr.onerror = function onerror() {
-    ok(false, "Got an error event!");
-    runTests();
-  }
-  xhr.send();
-}
-
-am.init();
-SpecialPowers.addPermission("systemXHR", true, document);
-SimpleTest.waitForExplicitFinish();
 </script>
 </pre>
 </body>
 </html>
--- a/netwerk/protocol/http/nsHttpChannelAuthProvider.cpp
+++ b/netwerk/protocol/http/nsHttpChannelAuthProvider.cpp
@@ -87,19 +87,30 @@ nsHttpChannelAuthProvider::ProcessAuthen
     nsCOMPtr<nsIProxyInfo> proxyInfo;
     nsresult rv = mAuthChannel->GetProxyInfo(getter_AddRefs(proxyInfo));
     if (NS_FAILED(rv)) return rv;
     if (proxyInfo) {
         mProxyInfo = do_QueryInterface(proxyInfo);
         if (!mProxyInfo) return NS_ERROR_NO_INTERFACE;
     }
 
+    uint32_t loadFlags;
+    rv = mAuthChannel->GetLoadFlags(&loadFlags);
+    if (NS_FAILED(rv)) return rv;
+
     nsAutoCString challenges;
     mProxyAuth = (httpStatus == 407);
 
+    // Do proxy auth even if we're LOAD_ANONYMOUS
+    if ((loadFlags & nsIRequest::LOAD_ANONYMOUS) &&
+        (!mProxyAuth || !UsingHttpProxy())) {
+        LOG(("Skipping authentication for anonymous non-proxy request\n"));
+        return NS_ERROR_NOT_AVAILABLE;
+    }
+
     rv = PrepareForAuthentication(mProxyAuth);
     if (NS_FAILED(rv))
         return rv;
 
     if (mProxyAuth) {
         // only allow a proxy challenge if we have a proxy server configured.
         // otherwise, we could inadvertently expose the user's proxy
         // credentials to an origin server.  We could attempt to proceed as
@@ -660,39 +671,23 @@ nsHttpChannelAuthProvider::GetCredential
     nsAutoCString path, scheme;
     bool identFromURI = false;
     nsISupports **continuationState;
 
     rv = GetAuthorizationMembers(proxyAuth, scheme, host, port,
                                  path, ident, continuationState);
     if (NS_FAILED(rv)) return rv;
 
-    uint32_t loadFlags;
-    rv = mAuthChannel->GetLoadFlags(&loadFlags);
-    if (NS_FAILED(rv)) return rv;
-
     if (!proxyAuth) {
         // if this is the first challenge, then try using the identity
         // specified in the URL.
         if (mIdent.IsEmpty()) {
             GetIdentityFromURI(authFlags, mIdent);
             identFromURI = !mIdent.IsEmpty();
         }
-
-        if ((loadFlags & nsIRequest::LOAD_ANONYMOUS) && !identFromURI) {
-            LOG(("Skipping authentication for anonymous non-proxy request\n"));
-            return NS_ERROR_NOT_AVAILABLE;
-        }
-
-        // Let explicit URL credentials pass
-        // regardless of the LOAD_ANONYMOUS flag
-    }
-    else if ((loadFlags & nsIRequest::LOAD_ANONYMOUS) && !UsingHttpProxy()) {
-        LOG(("Skipping authentication for anonymous non-proxy request\n"));
-        return NS_ERROR_NOT_AVAILABLE;
     }
 
     //
     // if we already tried some credentials for this transaction, then
     // we need to possibly clear them from the cache, unless the credentials
     // in the cache have changed, in which case we'd want to give them a
     // try instead.
     //
@@ -729,19 +724,18 @@ nsHttpChannelAuthProvider::GetCredential
                     // corresponding entry from the auth cache.
                     authCache->ClearAuthEntry(scheme.get(), host,
                                               port, realm.get());
                     entry = nullptr;
                     ident->Clear();
                 }
             }
             else if (!identFromURI ||
-                     (nsCRT::strcmp(ident->User(),
-                                    entry->Identity().User()) == 0 &&
-                     !(loadFlags && nsIChannel::LOAD_ANONYMOUS))) {
+                     nsCRT::strcmp(ident->User(),
+                                   entry->Identity().User()) == 0) {
                 LOG(("  taking identity from auth cache\n"));
                 // the password from the auth cache is more likely to be
                 // correct than the one in the URL.  at least, we know that it
                 // works with the given username.  it is possible for a server
                 // to distinguish logons based on the supplied password alone,
                 // but that would be quite unusual... and i don't think we need
                 // to worry about such unorthodox cases.
                 ident->Set(entry->Identity());