diff --git a/platform/platform-api/src/com/intellij/ui/jcef/JBCefCookie.java b/platform/platform-api/src/com/intellij/ui/jcef/JBCefCookie.java
new file mode 100644
index 000000000000..0a36c59ebba1
--- /dev/null
+++ b/platform/platform-api/src/com/intellij/ui/jcef/JBCefCookie.java
@@ -0,0 +1,114 @@
+// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+package com.intellij.ui.jcef;
+
+import org.cef.network.CefCookie;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Date;
+import java.util.Objects;
+
+/**
+ * A wrapper over {@link CefCookie}.
+ *
+ * @author Aleksey.Rostovskiy
+ */
+public class JBCefCookie {
+ private final CefCookie myCefCookie;
+
+ public JBCefCookie(CefCookie cefCookie) {
+ myCefCookie = cefCookie;
+ }
+
+ public JBCefCookie(@NotNull String name,
+ @NotNull String value,
+ @NotNull String domain,
+ @NotNull String path,
+ boolean secure,
+ boolean httponly,
+ @Nullable Date creation,
+ @Nullable Date lastAccess,
+ boolean hasExpires,
+ @Nullable Date expires) {
+ this(new CefCookie(name, value, domain, path, secure, httponly, creation, lastAccess, hasExpires, expires));
+ }
+
+ public JBCefCookie(@NotNull String name,
+ @NotNull String value,
+ @NotNull String domain,
+ @NotNull String path,
+ boolean secure,
+ boolean httponly) {
+ this(name, value, domain, path, secure, httponly, null, null, false, null);
+ }
+
+ @NotNull
+ public CefCookie getCefCookie() {
+ return myCefCookie;
+ }
+
+ @NotNull
+ public String getName() {
+ return myCefCookie.name;
+ }
+
+ @NotNull
+ public String getValue() {
+ return myCefCookie.value;
+ }
+
+ @NotNull
+ public String getDomain() {
+ return myCefCookie.domain;
+ }
+
+ @NotNull
+ public String getPath() {
+ return myCefCookie.path;
+ }
+
+ public boolean isSecure() {
+ return myCefCookie.secure;
+ }
+
+ public boolean isHttpOnly() {
+ return myCefCookie.httponly;
+ }
+
+ @Nullable
+ public Date getCreation() {
+ return myCefCookie.creation;
+ }
+
+ @Nullable
+ public Date getLastAccess() {
+ return myCefCookie.lastAccess;
+ }
+
+ public boolean hasExpires() {
+ return myCefCookie.hasExpires;
+ }
+
+ @Nullable
+ public Date getExpires() {
+ return myCefCookie.expires;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ JBCefCookie cookie = (JBCefCookie)o;
+ return getName().equals(cookie.getName()) &&
+ getValue().equals(cookie.getValue()) &&
+ getDomain().equals(cookie.getDomain()) &&
+ getPath().equals(cookie.getPath()) &&
+ isSecure() == cookie.isSecure() &&
+ isHttpOnly() == cookie.isHttpOnly();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(getName(), getValue(), getDomain(), getPath(), isSecure(), isHttpOnly());
+ }
+}
diff --git a/platform/platform-api/src/com/intellij/ui/jcef/JBCefCookieManager.java b/platform/platform-api/src/com/intellij/ui/jcef/JBCefCookieManager.java
index 0c9cd8790984..997f96831cf0 100644
--- a/platform/platform-api/src/com/intellij/ui/jcef/JBCefCookieManager.java
+++ b/platform/platform-api/src/com/intellij/ui/jcef/JBCefCookieManager.java
@@ -11,6 +11,8 @@ import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
@@ -24,7 +26,7 @@ import static com.intellij.openapi.util.Clock.getTime;
*
* Use {@link #getCookies()} and others for retrieving cookies synchronously.
*
- * Use {@link #setCookie(String, CefCookie, boolean)} and others for setting cookie. Can be used both with synchronization or without one.
+ * Use {@link #setCookie(String, JBCefCookie, boolean)} and others for setting cookie. Can be used both with synchronization or without one.
*
* Use {@link #deleteCookies(boolean)} and others for deleting cookies. Can be used both with synchronization or without one.
*
@@ -57,16 +59,14 @@ public class JBCefCookieManager {
/**
* @see JBCefCookieManager#getCookies(String, Boolean, Integer)
*/
- public @Nullable List getCookies() {
+ public @Nullable List getCookies() {
return getCookies(null, false, null);
}
/**
- * TODO[hatari] Doesn't work now, waiting for JCEF library update
- *
* @see JBCefCookieManager#getCookies(String, Boolean, Integer)
*/
- public @Nullable List getCookies(@NotNull String url) {
+ public @Nullable List getCookies(@NotNull String url) {
return getCookies(url, false, null);
}
@@ -78,9 +78,9 @@ public class JBCefCookieManager {
* @param includeHttpOnly include only true HTTP-only cookies.
* @param maxTimeToWait time to wait getting cookies in ms, default value is
* {@link JBCefCookieManager#DEFAULT_TIMEOUT_FOR_SYNCHRONOUS_FUNCTION}.
- * @return list of {@link CefCookie} or null if cookies cannot be accessed
+ * @return list of {@link JBCefCookie} or null if cookies cannot be accessed
*/
- public @Nullable List getCookies(@Nullable String url, @Nullable Boolean includeHttpOnly, @Nullable Integer maxTimeToWait) {
+ public @Nullable List getCookies(@Nullable String url, @Nullable Boolean includeHttpOnly, @Nullable Integer maxTimeToWait) {
long startTime = getTime();
boolean httpOnly = includeHttpOnly != null ? includeHttpOnly : false;
@@ -91,7 +91,6 @@ public class JBCefCookieManager {
boolean result;
if (url != null) {
- // TODO[hatari] Doesn't work now, waiting for JCEF library update
result = myCefCookieManager.visitUrlCookies(url, httpOnly, cookieVisitor);
}
else {
@@ -123,20 +122,18 @@ public class JBCefCookieManager {
}
/**
- * @see JBCefCookieManager#setCookie(String, CefCookie, Integer)
+ * @see JBCefCookieManager#setCookie(String, JBCefCookie, Integer)
*/
- public boolean setCookie(@NotNull String url, @NotNull CefCookie cefCookie, boolean doSync) {
+ public boolean setCookie(@NotNull String url, @NotNull JBCefCookie jbCefCookie, boolean doSync) {
if (doSync) {
- return setCookie(url, cefCookie, null);
+ return setCookie(url, jbCefCookie, null);
}
else {
- return myCefCookieManager.setCookie(url, cefCookie);
+ return myCefCookieManager.setCookie(url, jbCefCookie.getCefCookie());
}
}
/**
- * TODO[hatari] Doesn't work now, waiting for JCEF library update
- *
* Sets a cookie given a valid URL and explicit user-provided cookie attributes.
* Underlying native method {@link CefCookieManager#setCookie(String, CefCookie)} is asynchronous.
* This method is synchronous and will wait up to `maxTimeToWait` ms.
@@ -145,15 +142,35 @@ public class JBCefCookieManager {
* {@link JBCefCookieManager#DEFAULT_TIMEOUT_FOR_SYNCHRONOUS_FUNCTION} ms.
* @return true if setting the cookie was successful.
*/
- public boolean setCookie(@NotNull String url, @NotNull CefCookie cefCookie, @Nullable Integer maxTimeToWait) {
+ public boolean setCookie(@NotNull String url, @NotNull JBCefCookie jbCefCookie, @Nullable Integer maxTimeToWait) {
+ try {
+ URI uri = new URI(url);
+ String scheme = uri.getScheme();
+ String domain = uri.getHost();
+ domain = domain.startsWith("www") ? domain : "." + domain;
+
+ if (scheme.equals("http") && jbCefCookie.isSecure()) {
+ LOG.warn("Cannot set cookie without secure flag for HTTPS web-site");
+ return false;
+ }
+ if (!domain.contains(jbCefCookie.getDomain())) {
+ LOG.warn("Cookie domain `" + jbCefCookie.getDomain() + "` doesn't match URL host `" + domain + "`");
+ return false;
+ }
+ }
+ catch (URISyntaxException e) {
+ LOG.error(e);
+ return false;
+ }
+
int timeout = maxTimeToWait != null ? maxTimeToWait : DEFAULT_TIMEOUT_FOR_SYNCHRONOUS_FUNCTION;
IntFunction checkFunction = (timeoutForCheck) -> {
- List cookies = getCookies(url, null, timeoutForCheck);
+ List cookies = getCookies(url, null, timeoutForCheck);
if (cookies == null) {
return false;
}
- return cookies.contains(cefCookie);
+ return cookies.contains(jbCefCookie);
};
myLock.lock();
@@ -163,7 +180,7 @@ public class JBCefCookieManager {
LOG.debug("Cookie is already set");
return true;
}
- if (!myCefCookieManager.setCookie(url, cefCookie)) {
+ if (!myCefCookieManager.setCookie(url, jbCefCookie.getCefCookie())) {
LOG.error("Posting task to set cookie is failed");
return false;
}
@@ -204,7 +221,7 @@ public class JBCefCookieManager {
public boolean deleteCookies(boolean doSync) {
if (doSync) {
return deleteCookies("", "", (timeout) -> {
- List cookies = getCookies(null, false, timeout);
+ List cookies = getCookies(null, false, timeout);
if (cookies == null) {
return false;
}
@@ -225,7 +242,7 @@ public class JBCefCookieManager {
public boolean deleteCookies(@NotNull String url, boolean doSync) {
if (doSync) {
return deleteCookies(url, "", (timeout) -> {
- List cookies = getCookies(url, false, timeout);
+ List cookies = getCookies(url, false, timeout);
if (cookies == null) {
return false;
}
@@ -259,11 +276,11 @@ public class JBCefCookieManager {
*/
public boolean deleteCookies(@NotNull String url, @NotNull String cookieName, @Nullable Integer maxTimeToWait) {
IntFunction checkFunction = (timeout) -> {
- List cookies = getCookies(url, false, timeout);
+ List cookies = getCookies(url, false, timeout);
if (cookies == null) {
return false;
}
- return cookies.stream().allMatch(cefCookie -> cefCookie.name != cookieName);
+ return cookies.stream().noneMatch(cefCookie -> cefCookie.getName().equals(cookieName));
};
return deleteCookies(url, cookieName, checkFunction, maxTimeToWait);
@@ -327,7 +344,7 @@ public class JBCefCookieManager {
}
private static class JBCookieVisitor implements CefCookieVisitor {
- final List myCefCookies = new ArrayList<>();
+ final List myCefCookies = new ArrayList<>();
final CountDownLatch myCountDownLatch;
JBCookieVisitor(CountDownLatch countDownLatch) {
@@ -338,7 +355,7 @@ public class JBCefCookieManager {
// TODO[hatari]: This method may never be called if no cookies are found.
// So CountDownLatch can't countDown() well except timeout.
public boolean visit(CefCookie cookie, int count, int total, BoolRef delete) {
- myCefCookies.add(cookie);
+ myCefCookies.add(new JBCefCookie(cookie));
if (count >= total - 1) {
// last element
myCountDownLatch.countDown();
@@ -346,7 +363,7 @@ public class JBCefCookieManager {
return true;
}
- public List getCookies() {
+ public List getCookies() {
return myCefCookies;
}
}
diff --git a/platform/platform-impl/src/com/intellij/internal/jcef/CookieManagerDialog.java b/platform/platform-impl/src/com/intellij/internal/jcef/CookieManagerDialog.java
index acd90c114796..bbd25948b6ff 100644
--- a/platform/platform-impl/src/com/intellij/internal/jcef/CookieManagerDialog.java
+++ b/platform/platform-impl/src/com/intellij/internal/jcef/CookieManagerDialog.java
@@ -4,10 +4,10 @@
package com.intellij.internal.jcef;
import com.intellij.ui.jcef.JBCefBrowser;
+import com.intellij.ui.jcef.JBCefCookie;
import com.intellij.ui.jcef.JBCefCookieManager;
import com.intellij.ui.table.JBTable;
import com.intellij.util.ui.JBUI;
-import org.cef.network.CefCookie;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -22,7 +22,6 @@ import java.util.List;
class CookieManagerDialog extends JDialog {
private static final String myTitle = "Cookie Manager";
private static final String myDeleteCookiesButtonText = "Delete All Cookies";
- private static final String myAdditionalButtonText = "Test SetCookie";
@SuppressWarnings("unused") private final JBCefBrowser myJBCefBrowser;
private final JBCefCookieManager myJBCefCookieManager;
private final CookieTableModel myTableModel = new CookieTableModel();
@@ -46,7 +45,7 @@ class CookieManagerDialog extends JDialog {
@Override
public void actionPerformed(ActionEvent e) {
if (myJBCefCookieManager.deleteCookies(true)) {
- List cookies = myJBCefCookieManager.getCookies();
+ List cookies = myJBCefCookieManager.getCookies();
if (cookies != null) {
update(cookies);
}
@@ -55,41 +54,10 @@ class CookieManagerDialog extends JDialog {
});
controlPanel.add(myDeleteCookiesButton);
- final JButton myAdditionalButton = new JButton(myAdditionalButtonText);
- myAdditionalButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- List cookies = myJBCefCookieManager.getCookies();
- if (cookies == null || cookies.isEmpty()) return;
-
- CefCookie firstCookie = cookies.get(0);
- CefCookie newCookie = new CefCookie(
- "Cookie",
- "Value",
- firstCookie.domain,
- firstCookie.path,
- firstCookie.secure,
- firstCookie.secure,
- firstCookie.creation,
- firstCookie.lastAccess,
- firstCookie.hasExpires,
- firstCookie.expires
- );
-
- if (myJBCefCookieManager.setCookie("http://maps.google.com", newCookie, true)) {
- cookies = myJBCefCookieManager.getCookies();
- if (cookies != null) {
- update(cookies);
- }
- }
- }
- });
- controlPanel.add(myAdditionalButton);
-
add(controlPanel, BorderLayout.SOUTH);
}
- public void update(List cefCookies) {
+ public void update(List cefCookies) {
myTableModel.clear();
myTableModel.show(cefCookies);
}
@@ -99,18 +67,18 @@ class CookieManagerDialog extends JDialog {
new String[]{"Name", "Value", "Domain", "Path", "Secure", "HTTP only", "Created", "Last Access", "Expires"};
private final ArrayList