Title: [199091] trunk/Source/WebKit2
Revision
199091
Author
[email protected]
Date
2016-04-05 20:23:18 -0700 (Tue, 05 Apr 2016)

Log Message

Web Automation: add support for getting, deleting, and adding cookies
https://bugs.webkit.org/show_bug.cgi?id=156090
<rdar://problem/25477678>

Reviewed by Timothy Hatcher.

Add protocol commands for manipulating cookies with respect to a given page.
Implement all but the addSingleCookie command, which needs a new WebCore API.

* UIProcess/Automation/Automation.json:
Copy the Page domain Cookie object. Add new commands.

* UIProcess/Automation/WebAutomationSession.cpp:
(WebKit::WebAutomationSession::getAllCookies):
(WebKit::buildObjectForCookie): Copied from InspectorPageAgent.
(WebKit::buildArrayForCookies): Copied from InspectorPageAgent.
(WebKit::WebAutomationSession::didGetCookiesForFrame):
(WebKit::WebAutomationSession::deleteSingleCookie):
(WebKit::WebAutomationSession::didDeleteCookie):
(WebKit::WebAutomationSession::addSingleCookie): Added a stub for now.
(WebKit::WebAutomationSession::deleteAllCookies):
This command can use the WebCookieManager supplement directly instead of
proxying through AutomationSession. It doesn't block until the delete is
performed like the other methods do, but this shouldn't be a problem.

* UIProcess/Automation/WebAutomationSession.h:
* UIProcess/Automation/WebAutomationSession.messages.in:
* WebProcess/Automation/WebAutomationSessionProxy.cpp:
(WebKit::WebAutomationSessionProxy::getCookiesForFrame):
(WebKit::WebAutomationSessionProxy::deleteCookie):
* WebProcess/Automation/WebAutomationSessionProxy.h:
* WebProcess/Automation/WebAutomationSessionProxy.messages.in:

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (199090 => 199091)


--- trunk/Source/WebKit2/ChangeLog	2016-04-06 01:37:07 UTC (rev 199090)
+++ trunk/Source/WebKit2/ChangeLog	2016-04-06 03:23:18 UTC (rev 199091)
@@ -1,3 +1,38 @@
+2016-04-05  Brian Burg  <[email protected]>
+
+        Web Automation: add support for getting, deleting, and adding cookies
+        https://bugs.webkit.org/show_bug.cgi?id=156090
+        <rdar://problem/25477678>
+
+        Reviewed by Timothy Hatcher.
+
+        Add protocol commands for manipulating cookies with respect to a given page.
+        Implement all but the addSingleCookie command, which needs a new WebCore API.
+
+        * UIProcess/Automation/Automation.json:
+        Copy the Page domain Cookie object. Add new commands.
+
+        * UIProcess/Automation/WebAutomationSession.cpp:
+        (WebKit::WebAutomationSession::getAllCookies):
+        (WebKit::buildObjectForCookie): Copied from InspectorPageAgent.
+        (WebKit::buildArrayForCookies): Copied from InspectorPageAgent.
+        (WebKit::WebAutomationSession::didGetCookiesForFrame):
+        (WebKit::WebAutomationSession::deleteSingleCookie):
+        (WebKit::WebAutomationSession::didDeleteCookie):
+        (WebKit::WebAutomationSession::addSingleCookie): Added a stub for now.
+        (WebKit::WebAutomationSession::deleteAllCookies):
+        This command can use the WebCookieManager supplement directly instead of
+        proxying through AutomationSession. It doesn't block until the delete is
+        performed like the other methods do, but this shouldn't be a problem.
+
+        * UIProcess/Automation/WebAutomationSession.h:
+        * UIProcess/Automation/WebAutomationSession.messages.in:
+        * WebProcess/Automation/WebAutomationSessionProxy.cpp:
+        (WebKit::WebAutomationSessionProxy::getCookiesForFrame):
+        (WebKit::WebAutomationSessionProxy::deleteCookie):
+        * WebProcess/Automation/WebAutomationSessionProxy.h:
+        * WebProcess/Automation/WebAutomationSessionProxy.messages.in:
+
 2016-04-05  Alex Christensen  <[email protected]>
 
         Fix Range requests when not using the NetworkCache with NetworkSession

Modified: trunk/Source/WebKit2/UIProcess/Automation/Automation.json (199090 => 199091)


--- trunk/Source/WebKit2/UIProcess/Automation/Automation.json	2016-04-06 01:37:07 UTC (rev 199090)
+++ trunk/Source/WebKit2/UIProcess/Automation/Automation.json	2016-04-06 03:23:18 UTC (rev 199091)
@@ -187,6 +187,21 @@
                 { "name": "key", "$ref": "VirtualKey", "optional": true, "description": "A virtual key to be used to perform the specified interaction." },
                 { "name": "text", "type": "string", "optional": true, "description": "A unicode string to be delivered to the page. The sequence of key events is determined by splitting the string at grapheme cluster boundaries." }
             ]
+        },
+        {
+            "id": "Cookie",
+            "type": "object",
+            "properties": [
+                { "name": "name", "type": "string", "description": "Cookie name." },
+                { "name": "value", "type": "string", "description": "Cookie value." },
+                { "name": "domain", "type": "string", "description": "Cookie domain. If empty, the domain is inherited from the relevant browsing context." },
+                { "name": "path", "type": "string", "description": "Cookie path." },
+                { "name": "expires", "type": "number", "description": "Cookie expires." },
+                { "name": "size", "type": "integer", "description": "Cookie size." },
+                { "name": "httpOnly", "type": "boolean", "description": "True if cookie is http-only." },
+                { "name": "secure", "type": "boolean", "description": "True if cookie is secure." },
+                { "name": "session", "type": "boolean", "description": "True in case of session cookie." }
+            ]
         }
     ],
     "commands": [
@@ -410,6 +425,43 @@
                 { "name": "browsingContextHandle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context." },
                 { "name": "userInput", "type": "string", "description": "The text to enter in the prompt." }
             ]
+        },
+        {
+            "name": "getAllCookies",
+            "description": "Returns all cookies visible to the specified browsing context.",
+            "parameters": [
+                { "name": "browsingContextHandle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context." }
+            ],
+            "returns": [
+                { "name": "cookies", "type": "array", "items": { "$ref": "Cookie" }, "description": "Array of cookie objects." }
+            ],
+            "async": true
+        },
+        {
+            "name": "deleteSingleCookie",
+            "description": "Deletes a cookie with the given name if visible to the specified browsing context.",
+            "parameters": [
+                { "name": "browsingContextHandle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context." },
+                { "name": "cookieName", "type": "string", "description": "Name of the cookie to remove." }
+            ],
+            "async": true
+        },
+        {
+            "name": "addSingleCookie",
+            "description": "Add a cookie to cookie storage for the specified browsing context.",
+            "parameters": [
+                { "name": "browsingContextHandle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context." },
+                { "name": "cookie", "$ref": "Cookie", "description": "The cookie that should be added to storage." }
+            ],
+            "async": true
+        },
+        {
+            "name": "deleteAllCookies",
+            "description": "Delete all cookies that are visible to the specified browsing context.",
+            "parameters": [
+                { "name": "browsingContextHandle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context." }
+            ],
+            "async": true
         }
     ]
 }

Modified: trunk/Source/WebKit2/UIProcess/Automation/WebAutomationSession.cpp (199090 => 199091)


--- trunk/Source/WebKit2/UIProcess/Automation/WebAutomationSession.cpp	2016-04-06 01:37:07 UTC (rev 199090)
+++ trunk/Source/WebKit2/UIProcess/Automation/WebAutomationSession.cpp	2016-04-06 03:23:18 UTC (rev 199091)
@@ -30,6 +30,7 @@
 #include "AutomationProtocolObjects.h"
 #include "WebAutomationSessionMessages.h"
 #include "WebAutomationSessionProxyMessages.h"
+#include "WebCookieManagerProxy.h"
 #include "WebProcessPool.h"
 #include <_javascript_Core/InspectorBackendDispatcher.h>
 #include <_javascript_Core/InspectorFrontendRouter.h>
@@ -657,6 +658,118 @@
     m_client->setUserInputForCurrentJavaScriptPromptOnPage(this, page, promptValue);
 }
 
+void WebAutomationSession::getAllCookies(ErrorString& errorString, const String& browsingContextHandle, Ref<GetAllCookiesCallback>&& callback)
+{
+    WebPageProxy* page = webPageProxyForHandle(browsingContextHandle);
+    if (!page)
+        FAIL_WITH_PREDEFINED_ERROR_MESSAGE(WindowNotFound);
+
+    WebFrameProxy* mainFrame = page->mainFrame();
+    ASSERT(mainFrame);
+    if (!mainFrame)
+        FAIL_WITH_PREDEFINED_ERROR_MESSAGE(WindowNotFound);
+
+    uint64_t callbackID = m_nextGetCookiesCallbackID++;
+    m_getCookieCallbacks.set(callbackID, WTFMove(callback));
+
+    page->process().send(Messages::WebAutomationSessionProxy::GetCookiesForFrame(mainFrame->frameID(), callbackID), 0);
+}
+
+static Ref<Inspector::Protocol::Automation::Cookie> buildObjectForCookie(const WebCore::Cookie& cookie)
+{
+    return Inspector::Protocol::Automation::Cookie::create()
+        .setName(cookie.name)
+        .setValue(cookie.value)
+        .setDomain(cookie.domain)
+        .setPath(cookie.path)
+        .setExpires(cookie.expires)
+        .setSize((cookie.name.length() + cookie.value.length()))
+        .setHttpOnly(cookie.httpOnly)
+        .setSecure(cookie.secure)
+        .setSession(cookie.session)
+        .release();
+}
+
+static Ref<Inspector::Protocol::Array<Inspector::Protocol::Automation::Cookie>> buildArrayForCookies(Vector<WebCore::Cookie>& cookiesList)
+{
+    auto cookies = Inspector::Protocol::Array<Inspector::Protocol::Automation::Cookie>::create();
+
+    for (const auto& cookie : cookiesList)
+        cookies->addItem(buildObjectForCookie(cookie));
+
+    return cookies;
+}
+
+void WebAutomationSession::didGetCookiesForFrame(uint64_t callbackID, Vector<WebCore::Cookie> cookies, const String& errorType)
+{
+    auto callback = m_getCookieCallbacks.take(callbackID);
+    if (!callback)
+        return;
+
+    if (!errorType.isEmpty()) {
+        callback->sendFailure(errorType);
+        return;
+    }
+
+    callback->sendSuccess(buildArrayForCookies(cookies));
+}
+
+void WebAutomationSession::deleteSingleCookie(ErrorString& errorString, const String& browsingContextHandle, const String& cookieName, Ref<DeleteSingleCookieCallback>&& callback)
+{
+    WebPageProxy* page = webPageProxyForHandle(browsingContextHandle);
+    if (!page)
+        FAIL_WITH_PREDEFINED_ERROR_MESSAGE(WindowNotFound);
+
+    WebFrameProxy* mainFrame = page->mainFrame();
+    ASSERT(mainFrame);
+    if (!mainFrame)
+        FAIL_WITH_PREDEFINED_ERROR_MESSAGE(WindowNotFound);
+
+    uint64_t callbackID = m_nextDeleteCookieCallbackID++;
+    m_deleteCookieCallbacks.set(callbackID, WTFMove(callback));
+
+    page->process().send(Messages::WebAutomationSessionProxy::DeleteCookie(mainFrame->frameID(), cookieName, callbackID), 0);
+}
+
+void WebAutomationSession::didDeleteCookie(uint64_t callbackID, const String& errorType)
+{
+    auto callback = m_deleteCookieCallbacks.take(callbackID);
+    if (!callback)
+        return;
+
+    if (!errorType.isEmpty()) {
+        callback->sendFailure(errorType);
+        return;
+    }
+
+    callback->sendSuccess();
+}
+
+void WebAutomationSession::addSingleCookie(ErrorString& errorString, const String& browsingContextHandle, const Inspector::InspectorObject& cookie, Ref<AddSingleCookieCallback>&& callback)
+{
+    // FIXME: Implementing this command requires a new CookieJar API <https://webkit.org/b/156091>
+    UNUSED_PARAM(browsingContextHandle);
+    // FIXME: if the incoming cookie's domain is the string '(inherit)',
+    // then it should be inherited from the main frame's domain.
+    UNUSED_PARAM(cookie);
+    UNUSED_PARAM(callback);
+
+    FAIL_WITH_PREDEFINED_ERROR_MESSAGE(NotImplemented);
+}
+
+void WebAutomationSession::deleteAllCookies(ErrorString& errorString, const String& browsingContextHandle, Ref<DeleteAllCookiesCallback>&& callback)
+{
+    WebPageProxy* page = webPageProxyForHandle(browsingContextHandle);
+    if (!page)
+        FAIL_WITH_PREDEFINED_ERROR_MESSAGE(WindowNotFound);
+
+    WebCore::URL activeURL = WebCore::URL(WebCore::URL(), page->pageLoadState().activeURL());
+    ASSERT(activeURL.isValid());
+
+    WebCookieManagerProxy* cookieManager = m_processPool->supplement<WebCookieManagerProxy>();
+    cookieManager->deleteCookiesForHostname(activeURL.host());
+}
+
 #if USE(APPKIT)
 static WebEvent::Modifiers protocolModifierToWebEventModifier(Inspector::Protocol::Automation::KeyModifier modifier)
 {

Modified: trunk/Source/WebKit2/UIProcess/Automation/WebAutomationSession.h (199090 => 199091)


--- trunk/Source/WebKit2/UIProcess/Automation/WebAutomationSession.h	2016-04-06 01:37:07 UTC (rev 199090)
+++ trunk/Source/WebKit2/UIProcess/Automation/WebAutomationSession.h	2016-04-06 03:23:18 UTC (rev 199091)
@@ -46,11 +46,10 @@
 }
 
 namespace WebCore {
+class IntPoint;
 class IntRect;
-}
 
-namespace WebCore {
-class IntPoint;
+struct Cookie;
 }
 
 #if USE(APPKIT)
@@ -117,7 +116,10 @@
     void acceptCurrentJavaScriptDialog(Inspector::ErrorString&, const String& browsingContextHandle) override;
     void messageOfCurrentJavaScriptDialog(Inspector::ErrorString&, const String& browsingContextHandle, String* text) override;
     void setUserInputForCurrentJavaScriptPrompt(Inspector::ErrorString&, const String& browsingContextHandle, const String& text) override;
-
+    void getAllCookies(Inspector::ErrorString&, const String& browsingContextHandle, Ref<GetAllCookiesCallback>&&) override;
+    void deleteSingleCookie(Inspector::ErrorString&, const String& browsingContextHandle, const String& cookieName, Ref<DeleteSingleCookieCallback>&&) override;
+    void addSingleCookie(Inspector::ErrorString&, const String& browsingContextHandle, const Inspector::InspectorObject& cookie, Ref<AddSingleCookieCallback>&&) override;
+    void deleteAllCookies(Inspector::ErrorString&, const String& browsingContextHandle, Ref<DeleteAllCookiesCallback>&&) override;
 #if USE(APPKIT)
     bool wasEventSynthesizedForAutomation(NSEvent *);
 #endif
@@ -140,6 +142,8 @@
     void didResolveParentFrame(uint64_t callbackID, uint64_t frameID, const String& errorType);
     void didComputeElementLayout(uint64_t callbackID, WebCore::IntRect, const String& errorType);
     void didTakeScreenshot(uint64_t callbackID, const ShareableBitmap::Handle&, const String& errorType);
+    void didGetCookiesForFrame(uint64_t callbackID, Vector<WebCore::Cookie>, const String& errorType);
+    void didDeleteCookie(uint64_t callbackID, const String& errorType);
 
     // Platform-specific helper methods.
     void platformSimulateMouseInteraction(WebPageProxy&, const WebCore::IntPoint& viewPosition, Inspector::Protocol::Automation::MouseInteraction, Inspector::Protocol::Automation::MouseButton, WebEvent::Modifiers);
@@ -186,6 +190,12 @@
     uint64_t m_nextScreenshotCallbackID { 1 };
     HashMap<uint64_t, RefPtr<Inspector::AutomationBackendDispatcherHandler::TakeScreenshotCallback>> m_screenshotCallbacks;
 
+    uint64_t m_nextGetCookiesCallbackID { 1 };
+    HashMap<uint64_t, RefPtr<Inspector::AutomationBackendDispatcherHandler::GetAllCookiesCallback>> m_getCookieCallbacks;
+
+    uint64_t m_nextDeleteCookieCallbackID { 1 };
+    HashMap<uint64_t, RefPtr<Inspector::AutomationBackendDispatcherHandler::DeleteSingleCookieCallback>> m_deleteCookieCallbacks;
+
 #if ENABLE(REMOTE_INSPECTOR)
     Inspector::FrontendChannel* m_remoteChannel { nullptr };
 #endif

Modified: trunk/Source/WebKit2/UIProcess/Automation/WebAutomationSession.messages.in (199090 => 199091)


--- trunk/Source/WebKit2/UIProcess/Automation/WebAutomationSession.messages.in	2016-04-06 01:37:07 UTC (rev 199090)
+++ trunk/Source/WebKit2/UIProcess/Automation/WebAutomationSession.messages.in	2016-04-06 03:23:18 UTC (rev 199091)
@@ -29,4 +29,7 @@
     DidComputeElementLayout(uint64_t callbackID, WebCore::IntRect rect, String errorType)
 
     DidTakeScreenshot(uint64_t callbackID, WebKit::ShareableBitmap::Handle imageDataHandle, String errorType)
+
+    DidGetCookiesForFrame(uint64_t callbackID, Vector<WebCore::Cookie> cookies, String errorType)
+    DidDeleteCookie(uint64_t callbackID, String errorType)
 }

Modified: trunk/Source/WebKit2/WebProcess/Automation/WebAutomationSessionProxy.cpp (199090 => 199091)


--- trunk/Source/WebKit2/WebProcess/Automation/WebAutomationSessionProxy.cpp	2016-04-06 01:37:07 UTC (rev 199090)
+++ trunk/Source/WebKit2/WebProcess/Automation/WebAutomationSessionProxy.cpp	2016-04-06 03:23:18 UTC (rev 199091)
@@ -39,6 +39,7 @@
 #include <_javascript_Core/JSRetainPtr.h>
 #include <_javascript_Core/JSStringRefPrivate.h>
 #include <_javascript_Core/OpaqueJSString.h>
+#include <WebCore/CookieJar.h>
 #include <WebCore/DOMWindow.h>
 #include <WebCore/Frame.h>
 #include <WebCore/FrameTree.h>
@@ -492,4 +493,38 @@
     WebProcess::singleton().parentProcessConnection()->send(Messages::WebAutomationSession::DidTakeScreenshot(callbackID, handle, String()), 0);    
 }
 
+void WebAutomationSessionProxy::getCookiesForFrame(uint64_t frameID, uint64_t callbackID)
+{
+    String frameNotFoundErrorType = Inspector::Protocol::AutomationHelpers::getEnumConstantValue(Inspector::Protocol::Automation::ErrorMessage::FrameNotFound);
+
+    WebFrame* frame = WebProcess::singleton().webFrame(frameID);
+    if (!frame || !frame->coreFrame() || !frame->coreFrame()->document()) {
+        WebProcess::singleton().parentProcessConnection()->send(Messages::WebAutomationSession::DidGetCookiesForFrame(callbackID, Vector<WebCore::Cookie>(), frameNotFoundErrorType), 0);
+        return;
+    }
+
+    // This returns the same list of cookies as when evaluating `document.cookies` in _javascript_.
+    WebCore::Document* document = frame->coreFrame()->document();
+    Vector<WebCore::Cookie> foundCookies;
+    WebCore::getRawCookies(document, document->cookieURL(), foundCookies);
+
+    WebProcess::singleton().parentProcessConnection()->send(Messages::WebAutomationSession::DidGetCookiesForFrame(callbackID, foundCookies, String()), 0);
+}
+
+void WebAutomationSessionProxy::deleteCookie(uint64_t frameID, String cookieName, uint64_t callbackID)
+{
+    String frameNotFoundErrorType = Inspector::Protocol::AutomationHelpers::getEnumConstantValue(Inspector::Protocol::Automation::ErrorMessage::FrameNotFound);
+
+    WebFrame* frame = WebProcess::singleton().webFrame(frameID);
+    if (!frame || !frame->coreFrame() || !frame->coreFrame()->document()) {
+        WebProcess::singleton().parentProcessConnection()->send(Messages::WebAutomationSession::DidDeleteCookie(callbackID, frameNotFoundErrorType), 0);
+        return;
+    }
+
+    WebCore::Document* document = frame->coreFrame()->document();
+    WebCore::deleteCookie(document, document->cookieURL(), cookieName);
+
+    WebProcess::singleton().parentProcessConnection()->send(Messages::WebAutomationSession::DidDeleteCookie(callbackID, String()), 0);
+}
+
 } // namespace WebKit

Modified: trunk/Source/WebKit2/WebProcess/Automation/WebAutomationSessionProxy.h (199090 => 199091)


--- trunk/Source/WebKit2/WebProcess/Automation/WebAutomationSessionProxy.h	2016-04-06 01:37:07 UTC (rev 199090)
+++ trunk/Source/WebKit2/WebProcess/Automation/WebAutomationSessionProxy.h	2016-04-06 03:23:18 UTC (rev 199091)
@@ -66,6 +66,8 @@
     void focusFrame(uint64_t frameID);
     void computeElementLayout(uint64_t frameID, String nodeHandle, bool scrollIntoViewIfNeeded, bool useViewportCoordinates, uint64_t callbackID);
     void takeScreenshot(uint64_t pageID, uint64_t callbackID);
+    void getCookiesForFrame(uint64_t frameID, uint64_t callbackID);
+    void deleteCookie(uint64_t frameID, String cookieName, uint64_t callbackID);
 
     String m_sessionIdentifier;
 

Modified: trunk/Source/WebKit2/WebProcess/Automation/WebAutomationSessionProxy.messages.in (199090 => 199091)


--- trunk/Source/WebKit2/WebProcess/Automation/WebAutomationSessionProxy.messages.in	2016-04-06 01:37:07 UTC (rev 199090)
+++ trunk/Source/WebKit2/WebProcess/Automation/WebAutomationSessionProxy.messages.in	2016-04-06 03:23:18 UTC (rev 199091)
@@ -33,4 +33,7 @@
     ComputeElementLayout(uint64_t frameID, String nodeHandle, bool scrollIntoViewIfNeeded, bool useViewportCoordinates, uint64_t callbackID)
 
     TakeScreenshot(uint64_t pageID, uint64_t callbackID)
+
+    GetCookiesForFrame(uint64_t frameID, uint64_t callbackID)
+    DeleteCookie(uint64_t frameID, String cookieName, uint64_t callbackID)
 }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to