diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 000000000..f4538d3c7
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,17 @@
+# To get started with Dependabot version updates, you'll need to specify which
+# package ecosystems to update and where the package manifests are located.
+# Please see the documentation for all configuration options:
+# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
+
+version: 2
+updates:
+ - package-ecosystem: "maven"
+ directories:
+ - "/"
+ schedule:
+ interval: "daily"
+ - package-ecosystem: "github-actions"
+ directories:
+ - "/"
+ schedule:
+ interval: "daily"
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 51dc38f90..4a462dc99 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -27,7 +27,7 @@ jobs:
run: rm -f /home/runner/.m2/settings.xml
- name: Maven Settings
- uses: s4u/maven-settings-action@v2.2.0
+ uses: s4u/maven-settings-action@v3.1.0
with:
servers: |
[{
@@ -37,7 +37,7 @@ jobs:
}]
- name: Import GPG
- uses: crazy-max/ghaction-import-gpg@v5.2.0
+ uses: crazy-max/ghaction-import-gpg@v6.2.0
with:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.GPG_PASSPHRASE }}
diff --git a/README.md b/README.md
index 21a20ebbe..4ae651b75 100644
--- a/README.md
+++ b/README.md
@@ -20,7 +20,7 @@ Maven:
org.asynchttpclient
async-http-client
- 3.0.0
+ 3.0.1
```
@@ -28,7 +28,7 @@ Maven:
Gradle:
```groovy
dependencies {
- implementation 'org.asynchttpclient:async-http-client:3.0.0'
+ implementation 'org.asynchttpclient:async-http-client:3.0.1'
}
```
diff --git a/client/pom.xml b/client/pom.xml
index 7530b50f1..58dcd0aad 100644
--- a/client/pom.xml
+++ b/client/pom.xml
@@ -19,7 +19,7 @@
org.asynchttpclient
async-http-client-project
- 3.0.0
+ 3.0.1
4.0.0
@@ -30,12 +30,12 @@
org.asynchttpclient.client
- 11.0.16
- 10.1.25
- 2.11.0
+ 11.0.24
+ 10.1.33
+ 2.18.0
4.11.0
- 2.2
- 2.0.2
+ 3.0
+ 2.1.0
diff --git a/client/src/main/java/org/asynchttpclient/DefaultAsyncHttpClient.java b/client/src/main/java/org/asynchttpclient/DefaultAsyncHttpClient.java
index 1f616c328..3b417a5a3 100644
--- a/client/src/main/java/org/asynchttpclient/DefaultAsyncHttpClient.java
+++ b/client/src/main/java/org/asynchttpclient/DefaultAsyncHttpClient.java
@@ -235,7 +235,7 @@ public ListenableFuture executeRequest(Request request, AsyncHandler h
if (!cookies.isEmpty()) {
RequestBuilder requestBuilder = request.toBuilder();
for (Cookie cookie : cookies) {
- requestBuilder.addOrReplaceCookie(cookie);
+ requestBuilder.addCookieIfUnset(cookie);
}
request = requestBuilder.build();
}
diff --git a/client/src/main/java/org/asynchttpclient/RequestBuilderBase.java b/client/src/main/java/org/asynchttpclient/RequestBuilderBase.java
index 9f5cf9e5e..dbc5e4144 100644
--- a/client/src/main/java/org/asynchttpclient/RequestBuilderBase.java
+++ b/client/src/main/java/org/asynchttpclient/RequestBuilderBase.java
@@ -323,6 +323,21 @@ public T addCookie(Cookie cookie) {
* @return this
*/
public T addOrReplaceCookie(Cookie cookie) {
+ return maybeAddOrReplaceCookie(cookie, true);
+ }
+
+ /**
+ * Add a cookie based on its name, if it does not exist yet. Cookies that
+ * are already set will be ignored.
+ *
+ * @param cookie the new cookie
+ * @return this
+ */
+ public T addCookieIfUnset(Cookie cookie) {
+ return maybeAddOrReplaceCookie(cookie, false);
+ }
+
+ private T maybeAddOrReplaceCookie(Cookie cookie, boolean allowReplace) {
String cookieKey = cookie.name();
boolean replace = false;
int index = 0;
@@ -335,10 +350,10 @@ public T addOrReplaceCookie(Cookie cookie) {
index++;
}
- if (replace) {
- cookies.set(index, cookie);
- } else {
+ if (!replace) {
cookies.add(cookie);
+ } else if (allowReplace) {
+ cookies.set(index, cookie);
}
return asDerivedType();
}
diff --git a/client/src/main/java/org/asynchttpclient/netty/handler/intercept/Redirect30xInterceptor.java b/client/src/main/java/org/asynchttpclient/netty/handler/intercept/Redirect30xInterceptor.java
index 51e7c8a9b..e60495f80 100644
--- a/client/src/main/java/org/asynchttpclient/netty/handler/intercept/Redirect30xInterceptor.java
+++ b/client/src/main/java/org/asynchttpclient/netty/handler/intercept/Redirect30xInterceptor.java
@@ -142,11 +142,8 @@ public boolean exitAfterHandlingRedirect(Channel channel, NettyResponseFuture>
CookieStore cookieStore = config.getCookieStore();
if (cookieStore != null) {
// Update request's cookies assuming that cookie store is already updated by Interceptors
- List cookies = cookieStore.get(newUri);
- if (!cookies.isEmpty()) {
- for (Cookie cookie : cookies) {
- requestBuilder.addOrReplaceCookie(cookie);
- }
+ for (Cookie cookie : cookieStore.get(newUri)) {
+ requestBuilder.addCookieIfUnset(cookie);
}
}
diff --git a/client/src/test/java/org/asynchttpclient/RequestBuilderTest.java b/client/src/test/java/org/asynchttpclient/RequestBuilderTest.java
index 024fce5f1..34e79121d 100644
--- a/client/src/test/java/org/asynchttpclient/RequestBuilderTest.java
+++ b/client/src/test/java/org/asynchttpclient/RequestBuilderTest.java
@@ -166,6 +166,40 @@ public void testAddOrReplaceCookies() {
assertEquals(requestBuilder.cookies.size(), 2, "cookie size must be 2 after adding 1 more cookie i.e. cookie3");
}
+ @RepeatedIfExceptionsTest(repeats = 5)
+ public void testAddIfUnsetCookies() {
+ RequestBuilder requestBuilder = new RequestBuilder();
+ Cookie cookie = new DefaultCookie("name", "value");
+ cookie.setDomain("google.com");
+ cookie.setPath("/");
+ cookie.setMaxAge(1000);
+ cookie.setSecure(true);
+ cookie.setHttpOnly(true);
+ requestBuilder.addCookieIfUnset(cookie);
+ assertEquals(requestBuilder.cookies.size(), 1, "cookies size should be 1 after adding one cookie");
+ assertEquals(requestBuilder.cookies.get(0), cookie, "cookie does not match");
+
+ Cookie cookie2 = new DefaultCookie("name", "value");
+ cookie2.setDomain("google2.com");
+ cookie2.setPath("/path");
+ cookie2.setMaxAge(1001);
+ cookie2.setSecure(false);
+ cookie2.setHttpOnly(false);
+
+ requestBuilder.addCookieIfUnset(cookie2);
+ assertEquals(requestBuilder.cookies.size(), 1, "cookies size should remain 1 as we just ignored cookie2 because of a cookie with same name");
+ assertEquals(requestBuilder.cookies.get(0), cookie, "cookie does not match");
+
+ Cookie cookie3 = new DefaultCookie("name2", "value");
+ cookie3.setDomain("google.com");
+ cookie3.setPath("/");
+ cookie3.setMaxAge(1000);
+ cookie3.setSecure(true);
+ cookie3.setHttpOnly(true);
+ requestBuilder.addCookieIfUnset(cookie3);
+ assertEquals(requestBuilder.cookies.size(), 2, "cookie size must be 2 after adding 1 more cookie i.e. cookie3");
+ }
+
@RepeatedIfExceptionsTest(repeats = 5)
public void testSettingQueryParamsBeforeUrlShouldNotProduceNPE() {
RequestBuilder requestBuilder = new RequestBuilder();
diff --git a/pom.xml b/pom.xml
index ed8466618..d02f7c7ee 100644
--- a/pom.xml
+++ b/pom.xml
@@ -20,7 +20,7 @@
org.asynchttpclient
async-http-client-project
- 3.0.0
+ 3.0.1
pom
AHC/Project
@@ -45,14 +45,14 @@
11
UTF-8
- 4.1.112.Final
+ 4.1.115.Final
0.0.25.Final
- 1.16.0
- 2.0.13
- 1.5.6-4
+ 1.17.0
+ 2.0.16
+ 1.5.6-8
2.0.1
- 1.4.11
- 24.0.1
+ 1.5.12
+ 26.0.1
@@ -105,7 +105,7 @@
org.junit
junit-bom
- 5.10.2
+ 5.11.3
pom
import
@@ -322,12 +322,12 @@
com.google.errorprone
error_prone_core
- 2.25.0
+ 2.31.0
com.uber.nullaway
nullaway
- 0.10.10
+ 0.12.1
@@ -337,7 +337,7 @@
org.apache.maven.plugins
maven-surefire-plugin
- 3.2.5
+ 3.5.2
@{argLine} --add-exports java.base/jdk.internal.misc=ALL-UNNAMED
@@ -348,7 +348,7 @@
org.jacoco
jacoco-maven-plugin
- 0.8.9
+ 0.8.12
@@ -371,7 +371,6 @@
3.2.1
- attach-sources
jar-no-fork
@@ -382,7 +381,7 @@
org.apache.maven.plugins
maven-javadoc-plugin
- 3.6.3
+ 3.11.1
attach-javadocs
@@ -396,7 +395,7 @@
org.sonatype.plugins
nexus-staging-maven-plugin
- 1.6.13
+ 1.7.0
true
ossrh
@@ -409,7 +408,7 @@
org.apache.maven.plugins
maven-gpg-plugin
- 3.1.0
+ 3.2.7
sign-artifacts