2009-12-08 Alexander Pavlov <apavlov@chromium.org>
authoreric@webkit.org <eric@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 8 Dec 2009 13:21:03 +0000 (13:21 +0000)
committereric@webkit.org <eric@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 8 Dec 2009 13:21:03 +0000 (13:21 +0000)
        Reviewed by Pavel Feldman.

        Change the way cookies are retrieved in the WebInspector frontend.

        Moved the cookie filtering from the native code into the frontend so that
        all cookies can be retrieved regardless of the associated domain
        (required for certain audits to run.)
        https://bugs.webkit.org/show_bug.cgi?id=32160

        * inspector/cookie-resource-match-expected.txt: Added.
        * inspector/cookie-resource-match.html: Added.
2009-12-08  Alexander Pavlov  <apavlov@chromium.org>

        Reviewed by Pavel Feldman.

        Change the way cookies are retrieved in the WebInspector frontend.

        Moved the cookie filtering from the native code into the frontend so that
        all cookies can be retrieved regardless of the associated domain
        (required for certain audits to run.)
        https://bugs.webkit.org/show_bug.cgi?id=32160

        Test: inspector/cookie-resource-match.html

        * inspector/InspectorBackend.cpp:
        (WebCore::InspectorBackend::getCookies):
        * inspector/InspectorBackend.h:
        * inspector/InspectorBackend.idl:
        * inspector/InspectorController.cpp:
        (WebCore::InspectorController::getCookies):
        * inspector/InspectorController.h:
        * inspector/front-end/CookieItemsView.js:
        (WebInspector.CookieItemsView.prototype.update.callback):
        (WebInspector.CookieItemsView.prototype.update):
        (WebInspector.CookieItemsView.prototype._cookiesForDomain):
        * inspector/front-end/DOMAgent.js:
        (WebInspector.Cookies.getCookiesAsync):
        (WebInspector.Cookies.cookieMatchesResourceURL):
        (WebInspector.Cookies.cookieDomainMatchesResourceDomain):
        * inspector/front-end/Resource.js:
        (WebInspector.Resource):
        (WebInspector.Resource.prototype.get documentURL):
        (WebInspector.Resource.prototype.set documentURL):
        * inspector/front-end/inspector.js:
        (WebInspector.addResource):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@51846 268f45cc-cd09-0410-ab3c-d52691b4dbfc

13 files changed:
LayoutTests/ChangeLog
LayoutTests/inspector/cookie-resource-match-expected.txt [new file with mode: 0644]
LayoutTests/inspector/cookie-resource-match.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/inspector/InspectorBackend.cpp
WebCore/inspector/InspectorBackend.h
WebCore/inspector/InspectorBackend.idl
WebCore/inspector/InspectorController.cpp
WebCore/inspector/InspectorController.h
WebCore/inspector/front-end/CookieItemsView.js
WebCore/inspector/front-end/DOMAgent.js
WebCore/inspector/front-end/Resource.js
WebCore/inspector/front-end/inspector.js

index dbc1d1c034a8ca078499b4b96bddc330f573c52a..e8f8b1414569266a8da1c63183240b84c4415f0f 100644 (file)
@@ -1,3 +1,17 @@
+2009-12-08  Alexander Pavlov  <apavlov@chromium.org>
+
+        Reviewed by Pavel Feldman.
+
+        Change the way cookies are retrieved in the WebInspector frontend.
+
+        Moved the cookie filtering from the native code into the frontend so that
+        all cookies can be retrieved regardless of the associated domain
+        (required for certain audits to run.)
+        https://bugs.webkit.org/show_bug.cgi?id=32160
+
+        * inspector/cookie-resource-match-expected.txt: Added.
+        * inspector/cookie-resource-match.html: Added.
+
 2009-12-08  Nikolas Zimmermann  <nzimmermann@rim.com>
 
         Rubber-stamped by Maciej Stachowiak.
diff --git a/LayoutTests/inspector/cookie-resource-match-expected.txt b/LayoutTests/inspector/cookie-resource-match-expected.txt
new file mode 100644 (file)
index 0000000..2dc129c
--- /dev/null
@@ -0,0 +1,18 @@
+Tests that cookies are matched up with resources correctly.
+
+[0,2,4,6,8,10,12,14]
+[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
+[2,3,6,7,10,11,14,15]
+[6,14]
+[4,5,6,7,12,13,14,15]
+[6,7,14,15]
+[8,10,12,14]
+[8,9,10,11,12,13,14,15]
+[10,11,14,15]
+[14]
+[12,13,14,15]
+[14,15]
+[]
+[]
+[]
+
diff --git a/LayoutTests/inspector/cookie-resource-match.html b/LayoutTests/inspector/cookie-resource-match.html
new file mode 100644 (file)
index 0000000..8ee06d1
--- /dev/null
@@ -0,0 +1,100 @@
+<html>
+<head>
+<script src="inspector-test.js"></script>
+<script>
+
+function doit() {
+    function callback(result)
+    {
+        for (var i = 0; i < result.length; ++i)
+            output("[" + result[i] + "]");
+        notifyDone();
+    }
+    evaluateInWebInspector("frontend_doitAndDump", callback);
+}
+
+function frontend_doitAndDump()
+{
+    var cookies = [
+        frontend_createCookie("insecureOnlyWebkit", "1234567890", false, "webkit.org", "/"),
+        frontend_createCookie("insecureAllWebkit", "1234567890123456", false, ".webkit.org", "/"),
+        frontend_createCookie("insecureAllWebkitPath", "1234567890123456", false, ".webkit.org", "/path"),
+        frontend_createCookie("secureOnlyWebkitPath", "bar", true, "webkit.org", "/path"),
+        frontend_createCookie("secureAllWebkit", "foo", true, ".webkit.org", "/"),
+        frontend_createCookie("secureAllWebkitPath", "foo", true, ".webkit.org", "/path"),
+        frontend_createCookie("insecureOnlyWebkitPort", "1234567890", false, "webkit.org", "/", 80),
+        frontend_createCookie("insecureAllWebkitPort", "1234567890123456", false, ".webkit.org", "/", 80),
+        frontend_createCookie("insecureAllWebkitPathPort", "1234567890123456", false, ".webkit.org", "/path", 80),
+        frontend_createCookie("secureOnlyWebkitPathPort", "bar", true, "webkit.org", "/path", 80),
+        frontend_createCookie("secureAllWebkitPort", "foo", true, ".webkit.org", "/", 80),
+        frontend_createCookie("secureAllWebkitPathPort", "foo", true, ".webkit.org", "/path", 80),
+        frontend_createCookie("nonMatching1", "bar", false, "webkit.zoo", "/"),
+        frontend_createCookie("nonMatching2", "bar", false, "webkit.org", "/badPath"),
+        frontend_createCookie("nonMatching3", "bar", true, ".moo.com", "/")
+    ];
+
+    var resourceURLs = [
+        "http://webkit.org", // 0
+        "http://www.webkit.org:81", // 1
+        "http://webkit.org/path", // 2
+        "http://www.webkit.org/path", // 3
+        "https://webkit.org/", // 4
+        "https://www.webkit.org/", // 5
+        "https://webkit.org:81/path", // 6
+        "https://www.webkit.org/path", // 7
+
+        "http://webkit.org:80", // 8
+        "http://www.webkit.org:80", // 9
+        "http://webkit.org:80/path", // 10
+        "http://www.webkit.org:80/path", // 11
+        "https://webkit.org:80/", // 12
+        "https://www.webkit.org:80/", // 13
+        "https://webkit.org:80/path", // 14
+        "https://www.webkit.org:80/path", // 15
+
+        "http://www.boo.com:80", // 16
+        "https://www.boo.com:80/path", // 17
+        "http://www.moo.com:80/", // 18
+        "http://www.boo.com:80", // 19
+        "https://www.boo.com:80/path", // 20
+        "http://www.moo.com:80/" // 21
+    ];
+
+    var result = [];
+    for (var i = 0; i < cookies.length; ++i) {
+        var cookieResult = [];
+        for (var j = 0; j < resourceURLs.length; ++j) {
+            if (WebInspector.Cookies.cookieMatchesResourceURL(cookies[i], resourceURLs[j]))
+                cookieResult.push(j);
+        }
+        result.push(cookieResult);
+    }
+    return result;
+}
+
+function frontend_createCookie(name, value, secure, domain, path, port)
+{
+    return {
+        name: name,
+        value: value,
+        domain: domain,
+        port: port,
+        path: path,
+        expires: "Thu Jan 01 1970 00:00:00 GMT",
+        size: name.length + value.length,
+        httpOnly: false,
+        secure: secure,
+        session: true
+    };
+}
+
+</script>
+</head>
+
+<body onload="onload()">
+<p>
+Tests that cookies are matched up with resources correctly.
+</p>
+
+</body>
+</html>
index 88dbb43d07da0c55a8e83d7a88f69ada2b3bf211..1c24c6d5b85a857d784308cce9546faa9cfa790a 100644 (file)
@@ -1,3 +1,38 @@
+2009-12-08  Alexander Pavlov  <apavlov@chromium.org>
+
+        Reviewed by Pavel Feldman.
+
+        Change the way cookies are retrieved in the WebInspector frontend.
+
+        Moved the cookie filtering from the native code into the frontend so that
+        all cookies can be retrieved regardless of the associated domain
+        (required for certain audits to run.)
+        https://bugs.webkit.org/show_bug.cgi?id=32160
+
+        Test: inspector/cookie-resource-match.html
+
+        * inspector/InspectorBackend.cpp:
+        (WebCore::InspectorBackend::getCookies):
+        * inspector/InspectorBackend.h:
+        * inspector/InspectorBackend.idl:
+        * inspector/InspectorController.cpp:
+        (WebCore::InspectorController::getCookies):
+        * inspector/InspectorController.h:
+        * inspector/front-end/CookieItemsView.js:
+        (WebInspector.CookieItemsView.prototype.update.callback):
+        (WebInspector.CookieItemsView.prototype.update):
+        (WebInspector.CookieItemsView.prototype._cookiesForDomain):
+        * inspector/front-end/DOMAgent.js:
+        (WebInspector.Cookies.getCookiesAsync):
+        (WebInspector.Cookies.cookieMatchesResourceURL):
+        (WebInspector.Cookies.cookieDomainMatchesResourceDomain):
+        * inspector/front-end/Resource.js:
+        (WebInspector.Resource):
+        (WebInspector.Resource.prototype.get documentURL):
+        (WebInspector.Resource.prototype.set documentURL):
+        * inspector/front-end/inspector.js:
+        (WebInspector.addResource):
+
 2009-12-08  Nikolas Zimmermann  <nzimmermann@rim.com>
 
         Not reviewed. Touch svgtags.in, in order to force SVGNames.* regeneration. Praying for gtk bot to be fixed :-)
index 6b3268d5d434b277acc8a1819af22b9484f78ebc..11f58c7c71f661ae1afffceb5d92991b04af74cf 100644 (file)
@@ -357,11 +357,11 @@ void InspectorBackend::hideDOMNodeHighlight()
         m_inspectorController->hideHighlight();
 }
 
-void InspectorBackend::getCookies(long callId, const String& domain)
+void InspectorBackend::getCookies(long callId)
 {
     if (!m_inspectorController)
         return;
-    m_inspectorController->getCookies(callId, domain);
+    m_inspectorController->getCookies(callId);
 }
 
 void InspectorBackend::deleteCookie(const String& cookieName, const String& domain)
index 802629442152c57c3a98913ce2990548fca9f425..d6e89fa3c6b7b6e440a145bb4bc7f07200f32f94 100644 (file)
@@ -114,7 +114,7 @@ public:
     void highlightDOMNode(long nodeId);
     void hideDOMNodeHighlight();
 
-    void getCookies(long callId, const String& domain);
+    void getCookies(long callId);
     void deleteCookie(const String& cookieName, const String& domain);
 
     // Generic code called from custom implementations.
index e436e6b8ceb27161847e962e6238ff6e08701d3f..61c76d6e43c2756b1c1e17f08f12238b8f9e117c 100644 (file)
@@ -87,7 +87,7 @@ module core {
         void highlightDOMNode(in long nodeId);
         void hideDOMNodeHighlight();
 
-        void getCookies(in long callId, in DOMString domain);
+        void getCookies(in long callId);
         void deleteCookie(in DOMString cookieName, in DOMString domain);
 
         void releaseWrapperObjectGroup(in DOMString objectGroup);
index c269825d8a21f0badb6be9d625f1be2dd242b91f..fd319a4ed669d4b3781a6ed4a6ce52b028263322 100644 (file)
@@ -1149,46 +1149,44 @@ void InspectorController::didOpenDatabase(Database* database, const String& doma
 }
 #endif
 
-void InspectorController::getCookies(long callId, const String& host)
+void InspectorController::getCookies(long callId)
 {
     if (!m_frontend)
         return;
-    
+
     // If we can get raw cookies.
     ListHashSet<Cookie> rawCookiesList;
-    
+
     // If we can't get raw cookies - fall back to String representation
     String stringCookiesList;
-    
+
     // Return value to getRawCookies should be the same for every call because
     // the return value is platform/network backend specific, and the call will
     // always return the same true/false value.
     bool rawCookiesImplemented = false;
-    
+
     ResourcesMap::iterator resourcesEnd = m_resources.end();
     for (ResourcesMap::iterator it = m_resources.begin(); it != resourcesEnd; ++it) {
         Document* document = it->second->frame()->document();
-        if (document->url().host() == host) {
-            Vector<Cookie> docCookiesList;
-            rawCookiesImplemented = getRawCookies(document, document->cookieURL(), docCookiesList);
-            
-            if (!rawCookiesImplemented) {
-                // FIXME: We need duplication checking for the String representation of cookies.
-                ExceptionCode ec = 0;
-                stringCookiesList += document->cookie(ec);
-                // Exceptions are thrown by cookie() in sandboxed frames. That won't happen here
-                // because "document" is the document of the main frame of the page.
-                ASSERT(!ec);
-            } else {
-                int cookiesSize = docCookiesList.size();
-                for (int i = 0; i < cookiesSize; i++) {
-                    if (!rawCookiesList.contains(docCookiesList[i]))
-                        rawCookiesList.add(docCookiesList[i]);
-                }
+        Vector<Cookie> docCookiesList;
+        rawCookiesImplemented = getRawCookies(document, document->cookieURL(), docCookiesList);
+
+        if (!rawCookiesImplemented) {
+            // FIXME: We need duplication checking for the String representation of cookies.
+            ExceptionCode ec = 0;
+            stringCookiesList += document->cookie(ec);
+            // Exceptions are thrown by cookie() in sandboxed frames. That won't happen here
+            // because "document" is the document of the main frame of the page.
+            ASSERT(!ec);
+        } else {
+            int cookiesSize = docCookiesList.size();
+            for (int i = 0; i < cookiesSize; i++) {
+                if (!rawCookiesList.contains(docCookiesList[i]))
+                    rawCookiesList.add(docCookiesList[i]);
             }
         }
     }
-    
+
     if (!rawCookiesImplemented)
         m_frontend->didGetCookies(callId, m_frontend->newScriptArray(), stringCookiesList);
     else
index 0dd6fb15b3db88d930f2ef645eb6ed0c3abb9e54..bb4e1f3ece91586f5394839a77473f0d1f5c69b7 100644 (file)
@@ -186,7 +186,7 @@ public:
     void mainResourceFiredLoadEvent(DocumentLoader*, const KURL&);
     void mainResourceFiredDOMContentEvent(DocumentLoader*, const KURL&);
                                                         
-    void getCookies(long callId, const String& url);
+    void getCookies(long callId);
 
 #if ENABLE(DATABASE)
     void didOpenDatabase(Database*, const String& domain, const String& name, const String& version);
index 0caa1b7959db485a52cca56177b768c439fd182a..b31b7eac974a807fc704afa1bb7aa23a0d6749d6 100644 (file)
@@ -67,7 +67,8 @@ WebInspector.CookieItemsView.prototype = {
         this.element.removeChildren();
 
         var self = this;
-        function callback(cookies, isAdvanced) {
+        function callback(allCookies, isAdvanced) {
+            var cookies = self._cookiesForDomain(allCookies);
             var dataGrid = (isAdvanced ? self.dataGridForCookies(cookies) : self.simpleDataGridForCookies(cookies));
             if (dataGrid) {
                 self._dataGrid = dataGrid;
@@ -85,7 +86,31 @@ WebInspector.CookieItemsView.prototype = {
             }
         }
 
-        WebInspector.Cookies.getCookiesAsync(callback, this._cookieDomain);
+        WebInspector.Cookies.getCookiesAsync(callback);
+    },
+
+    _cookiesForDomain: function(allCookies)
+    {
+        var cookiesForDomain = [];
+        var resourceURLsForDocumentURL = [];
+
+        for (var id in WebInspector.resources) {
+            var resource = WebInspector.resources[id];
+            var match = resource.documentURL.match(WebInspector.URLRegExp);
+            if (match && match[2] === this._cookieDomain)
+                resourceURLsForDocumentURL.push(resource.url);
+        }
+
+        for (var i = 0; i < allCookies.length; ++i) {
+            for (var j = 0; j < resourceURLsForDocumentURL.length; ++j) {
+                var resourceURL = resourceURLsForDocumentURL[j];
+                if (WebInspector.Cookies.cookieMatchesResourceURL(allCookies[i], resourceURL)) {
+                    cookiesForDomain.push(allCookies[i]);
+                    break;
+                }
+            }
+        }
+        return cookiesForDomain;
     },
 
     dataGridForCookies: function(cookies)
index 28dafeb162bbfbe23cb92e69b77930ac50732a5a..4ccf843ebdb550112c1f995d7992112054fe8771 100644 (file)
@@ -439,7 +439,7 @@ WebInspector.DOMAgent.prototype = {
 
 WebInspector.Cookies = {}
 
-WebInspector.Cookies.getCookiesAsync = function(callback, cookieDomain)
+WebInspector.Cookies.getCookiesAsync = function(callback)
 {
     function mycallback(cookies, cookiesString) {
         if (cookiesString)
@@ -448,7 +448,7 @@ WebInspector.Cookies.getCookiesAsync = function(callback, cookieDomain)
             callback(cookies, true);
     }
     var callId = WebInspector.Callback.wrap(mycallback);
-    InspectorBackend.getCookies(callId, cookieDomain);
+    InspectorBackend.getCookies(callId);
 }
 
 WebInspector.Cookies.buildCookiesFromString = function(rawCookieString)
@@ -470,6 +470,28 @@ WebInspector.Cookies.buildCookiesFromString = function(rawCookieString)
     return cookies;
 }
 
+WebInspector.Cookies.cookieMatchesResourceURL = function(cookie, resourceURL)
+{
+    var match = resourceURL.match(WebInspector.URLRegExp);
+    if (!match)
+        return false;
+    // See WebInspector.URLRegExp for definitions of the group index constants.
+    if (!this.cookieDomainMatchesResourceDomain(cookie.domain, match[2]))
+        return false;
+    var resourcePort = match[3] ? match[3] : undefined;
+    var resourcePath = match[4] ? match[4] : '/';
+    return (resourcePath.indexOf(cookie.path) === 0
+        && (!cookie.port || resourcePort == cookie.port)
+        && (!cookie.secure || match[1].toLowerCase() === 'https'));
+}
+
+WebInspector.Cookies.cookieDomainMatchesResourceDomain = function(cookieDomain, resourceDomain)
+{
+    if (cookieDomain.charAt(0) !== '.')
+        return resourceDomain === cookieDomain;
+    return !!resourceDomain.match(new RegExp("^([^\\.]+\\.)?" + cookieDomain.substring(1).escapeForRegExp() + "$"), "i");
+}
+
 WebInspector.EventListeners = {}
 
 WebInspector.EventListeners.getEventListenersForNodeAsync = function(node, callback)
index 728f2acd1e32b7662625e6f224f3ec19784cdee5..d23b5dadbab0d677c788f41fc005f66474dd097f 100644 (file)
@@ -26,7 +26,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-WebInspector.Resource = function(requestHeaders, url, domain, path, lastPathComponent, identifier, mainResource, cached, requestMethod, requestFormData)
+WebInspector.Resource = function(requestHeaders, url, documentURL, domain, path, lastPathComponent, identifier, mainResource, cached, requestMethod, requestFormData)
 {
     this.identifier = identifier;
 
@@ -35,6 +35,7 @@ WebInspector.Resource = function(requestHeaders, url, domain, path, lastPathComp
     this.mainResource = mainResource;
     this.requestHeaders = requestHeaders;
     this.url = url;
+    this.documentURL = documentURL;
     this.domain = domain;
     this.path = path;
     this.lastPathComponent = lastPathComponent;
@@ -162,6 +163,18 @@ WebInspector.Resource.prototype = {
         this.dispatchEventToListeners("url changed");
     },
 
+    get documentURL()
+    {
+        return this._documentURL;
+    },
+
+    set documentURL(x)
+    {
+        if (this._documentURL === x)
+            return;
+        this._documentURL = x;
+    },
+
     get domain()
     {
         return this._domain;
index 2fd076c0a15e9122545ed0da62437a2660676f0e..9fcc657a6931e690e832a833aa3bebdc7d75a311 100644 (file)
@@ -74,6 +74,14 @@ var WebInspector = {
     missingLocalizedStrings: {},
     pendingDispatches: 0,
 
+    // RegExp groups:
+    // 1 - scheme
+    // 2 - hostname
+    // 3 - ?port
+    // 4 - ?path
+    // 5 - ?fragment
+    URLRegExp: /^(http[s]?|file):\/\/([^\/:]+)(?::([\d]+))?(?:(\/[^#]*)(?:#(.*))?)?$/i,
+
     get platform()
     {
         if (!("_platform" in this))
@@ -1009,6 +1017,7 @@ WebInspector.addResource = function(identifier, payload)
     var resource = new WebInspector.Resource(
         payload.requestHeaders,
         payload.requestURL,
+        payload.documentURL,
         payload.host,
         payload.path,
         payload.lastPathComponent,