From 7060e63b3d224ba658f26842e5dd55f7fd1eef15 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 6 Feb 2026 12:29:29 +0000
Subject: [PATCH 1/8] Initial plan
From 423522dda2a754611a9c6a5469cc81b164478fa0 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 6 Feb 2026 12:35:01 +0000
Subject: [PATCH 2/8] Phase 1: Update dependencies and basic HTTP classes to
HttpClient 5.4.1
Co-authored-by: rbri <2544132+rbri@users.noreply.github.com>
---
pom.xml | 21 ++++++++++++++-----
.../HtmlUnitCookieSpecProvider.java | 10 ++++-----
.../httpclient/HtmlUnitRedirectStrategie.java | 10 ++++-----
.../org/htmlunit/httpclient/HttpDelete.java | 19 ++++++-----------
.../org/htmlunit/httpclient/HttpOptions.java | 19 ++++++-----------
5 files changed, 38 insertions(+), 41 deletions(-)
diff --git a/pom.xml b/pom.xml
index aeff337aca..e50399cb42 100644
--- a/pom.xml
+++ b/pom.xml
@@ -45,7 +45,8 @@
4.21.0
5.0.0-SNAPSHOT
- 4.5.14
+ 5.3.1
+ 5.4.1
3.20.0
2.21.0
1.3.5
@@ -1343,11 +1344,11 @@
-
+
- org.apache.httpcomponents
- httpmime
- ${httpcomponents.version}
+ org.apache.httpcomponents.client5
+ httpclient5
+ ${httpcomponents.client5.version}
commons-logging
@@ -1355,6 +1356,16 @@
+
+ org.apache.httpcomponents.core5
+ httpcore5
+ ${httpcomponents.core5.version}
+
+
+ org.apache.httpcomponents.core5
+ httpcore5-h2
+ ${httpcomponents.core5.version}
+
org.htmlunit
diff --git a/src/main/java/org/htmlunit/httpclient/HtmlUnitCookieSpecProvider.java b/src/main/java/org/htmlunit/httpclient/HtmlUnitCookieSpecProvider.java
index 99ce1f2b3f..ab0d4cc3fd 100644
--- a/src/main/java/org/htmlunit/httpclient/HtmlUnitCookieSpecProvider.java
+++ b/src/main/java/org/htmlunit/httpclient/HtmlUnitCookieSpecProvider.java
@@ -14,17 +14,17 @@
*/
package org.htmlunit.httpclient;
-import org.apache.http.cookie.CookieSpec;
-import org.apache.http.cookie.CookieSpecProvider;
-import org.apache.http.protocol.HttpContext;
+import org.apache.hc.client5.http.cookie.CookieSpec;
+import org.apache.hc.client5.http.cookie.CookieSpecFactory;
+import org.apache.hc.core5.http.protocol.HttpContext;
import org.htmlunit.BrowserVersion;
/**
- * Customized CookieSpecProvider for HtmlUnit.
+ * Customized CookieSpecFactory for HtmlUnit.
*
* @author Ronald Brill
*/
-public final class HtmlUnitCookieSpecProvider implements CookieSpecProvider {
+public final class HtmlUnitCookieSpecProvider implements CookieSpecFactory {
private final BrowserVersion browserVersion_;
diff --git a/src/main/java/org/htmlunit/httpclient/HtmlUnitRedirectStrategie.java b/src/main/java/org/htmlunit/httpclient/HtmlUnitRedirectStrategie.java
index 8672201928..9b67b584ce 100644
--- a/src/main/java/org/htmlunit/httpclient/HtmlUnitRedirectStrategie.java
+++ b/src/main/java/org/htmlunit/httpclient/HtmlUnitRedirectStrategie.java
@@ -14,11 +14,11 @@
*/
package org.htmlunit.httpclient;
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpResponse;
-import org.apache.http.ProtocolException;
-import org.apache.http.impl.client.DefaultRedirectStrategy;
-import org.apache.http.protocol.HttpContext;
+import org.apache.hc.client5.http.impl.DefaultRedirectStrategy;
+import org.apache.hc.core5.http.HttpRequest;
+import org.apache.hc.core5.http.HttpResponse;
+import org.apache.hc.core5.http.ProtocolException;
+import org.apache.hc.core5.http.protocol.HttpContext;
/**
* Customized DefaultRedirectStrategy for HtmlUnit.
diff --git a/src/main/java/org/htmlunit/httpclient/HttpDelete.java b/src/main/java/org/htmlunit/httpclient/HttpDelete.java
index 5b174a69cb..ee28e7b56f 100644
--- a/src/main/java/org/htmlunit/httpclient/HttpDelete.java
+++ b/src/main/java/org/htmlunit/httpclient/HttpDelete.java
@@ -16,14 +16,14 @@
import java.net.URI;
-import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
-
/**
- * Customized HttpDelete for HtmlUnit to be an HttpEntityEnclosingRequestBase.
+ * Customized HttpDelete for HtmlUnit.
+ * In HttpClient 5, HttpDelete natively supports entity bodies, so this class
+ * is kept for backwards compatibility but just extends the standard class.
*
* @author Ronald Brill
*/
-public class HttpDelete extends HttpEntityEnclosingRequestBase {
+public class HttpDelete extends org.apache.hc.client5.http.classic.methods.HttpDelete {
/**
* Ctor.
@@ -37,8 +37,7 @@ public HttpDelete() {
* @param uri the uri
*/
public HttpDelete(final URI uri) {
- super();
- setURI(uri);
+ super(uri);
}
/**
@@ -46,12 +45,6 @@ public HttpDelete(final URI uri) {
* @throws IllegalArgumentException if the uri is invalid.
*/
public HttpDelete(final String uri) {
- super();
- setURI(URI.create(uri));
- }
-
- @Override
- public String getMethod() {
- return org.apache.http.client.methods.HttpDelete.METHOD_NAME;
+ super(uri);
}
}
diff --git a/src/main/java/org/htmlunit/httpclient/HttpOptions.java b/src/main/java/org/htmlunit/httpclient/HttpOptions.java
index 4f91bcd5a0..3630e434bc 100644
--- a/src/main/java/org/htmlunit/httpclient/HttpOptions.java
+++ b/src/main/java/org/htmlunit/httpclient/HttpOptions.java
@@ -16,14 +16,14 @@
import java.net.URI;
-import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
-
/**
- * Customized HttpOptions for HtmlUnit to be an HttpEntityEnclosingRequestBase.
+ * Customized HttpOptions for HtmlUnit.
+ * In HttpClient 5, HttpOptions natively supports entity bodies, so this class
+ * is kept for backwards compatibility but just extends the standard class.
*
* @author Ronald Brill
*/
-public class HttpOptions extends HttpEntityEnclosingRequestBase {
+public class HttpOptions extends org.apache.hc.client5.http.classic.methods.HttpOptions {
/**
* Ctor.
@@ -37,8 +37,7 @@ public HttpOptions() {
* @param uri the uri
*/
public HttpOptions(final URI uri) {
- super();
- setURI(uri);
+ super(uri);
}
/**
@@ -46,12 +45,6 @@ public HttpOptions(final URI uri) {
* @throws IllegalArgumentException if the uri is invalid.
*/
public HttpOptions(final String uri) {
- super();
- setURI(URI.create(uri));
- }
-
- @Override
- public String getMethod() {
- return org.apache.http.client.methods.HttpOptions.METHOD_NAME;
+ super(uri);
}
}
From ca6018b6ed53d7a8d0288eac0a281e379bf87c7b Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 6 Feb 2026 12:37:28 +0000
Subject: [PATCH 3/8] Phase 2: Update cookie handler classes to HttpClient
5.4.1 APIs
Co-authored-by: rbri <2544132+rbri@users.noreply.github.com>
---
.../httpclient/HtmlUnitDomainHandler.java | 14 +++++++-------
.../httpclient/HtmlUnitExpiresHandler.java | 17 ++++++++++-------
.../httpclient/HtmlUnitHttpOnlyHandler.java | 12 ++++++------
.../httpclient/HtmlUnitMaxAgeHandler.java | 12 ++++++------
.../httpclient/HtmlUnitPathHandler.java | 8 ++++----
.../httpclient/HtmlUnitSameSiteHandler.java | 12 ++++++------
.../httpclient/HtmlUnitSecureHandler.java | 8 ++++----
.../HtmlUnitVersionAttributeHandler.java | 12 ++++++------
8 files changed, 49 insertions(+), 46 deletions(-)
diff --git a/src/main/java/org/htmlunit/httpclient/HtmlUnitDomainHandler.java b/src/main/java/org/htmlunit/httpclient/HtmlUnitDomainHandler.java
index dbe13b5cae..52d54fa408 100644
--- a/src/main/java/org/htmlunit/httpclient/HtmlUnitDomainHandler.java
+++ b/src/main/java/org/htmlunit/httpclient/HtmlUnitDomainHandler.java
@@ -20,13 +20,13 @@
import java.net.UnknownHostException;
import java.util.Locale;
-import org.apache.http.cookie.Cookie;
-import org.apache.http.cookie.CookieOrigin;
-import org.apache.http.cookie.MalformedCookieException;
-import org.apache.http.cookie.SetCookie;
-import org.apache.http.impl.cookie.BasicDomainHandler;
-import org.apache.http.util.Args;
-import org.apache.http.util.TextUtils;
+import org.apache.hc.client5.http.cookie.Cookie;
+import org.apache.hc.client5.http.cookie.CookieOrigin;
+import org.apache.hc.client5.http.cookie.MalformedCookieException;
+import org.apache.hc.client5.http.cookie.SetCookie;
+import org.apache.hc.client5.http.impl.cookie.BasicDomainHandler;
+import org.apache.hc.core5.util.Args;
+import org.apache.hc.core5.util.TextUtils;
import org.htmlunit.BrowserVersion;
import org.htmlunit.HttpHeader;
diff --git a/src/main/java/org/htmlunit/httpclient/HtmlUnitExpiresHandler.java b/src/main/java/org/htmlunit/httpclient/HtmlUnitExpiresHandler.java
index 237db1062d..03f73dcb95 100644
--- a/src/main/java/org/htmlunit/httpclient/HtmlUnitExpiresHandler.java
+++ b/src/main/java/org/htmlunit/httpclient/HtmlUnitExpiresHandler.java
@@ -17,12 +17,13 @@
import static org.htmlunit.BrowserVersionFeatures.HTTP_COOKIE_EXTENDED_DATE_PATTERNS_1;
import static org.htmlunit.BrowserVersionFeatures.HTTP_COOKIE_EXTENDED_DATE_PATTERNS_2;
+import java.time.Instant;
import java.util.Date;
-import org.apache.http.client.utils.DateUtils;
-import org.apache.http.cookie.MalformedCookieException;
-import org.apache.http.cookie.SetCookie;
-import org.apache.http.impl.cookie.BasicExpiresHandler;
+import org.apache.hc.client5.http.cookie.MalformedCookieException;
+import org.apache.hc.client5.http.cookie.SetCookie;
+import org.apache.hc.client5.http.impl.cookie.BasicExpiresHandler;
+import org.apache.hc.client5.http.utils.DateUtils;
import org.htmlunit.BrowserVersion;
/**
@@ -91,11 +92,11 @@ public void parse(final SetCookie cookie, String value) throws MalformedCookieEx
}
value = value.replaceAll("[ ,:-]+", " ");
- Date startDate = null;
+ Instant startDate = null;
String[] datePatterns = DEFAULT_DATE_PATTERNS;
if (null != browserVersion_) {
- startDate = HtmlUnitBrowserCompatCookieSpec.DATE_1_1_1970;
+ startDate = HtmlUnitBrowserCompatCookieSpec.DATE_1_1_1970.toInstant();
if (browserVersion_.hasFeature(HTTP_COOKIE_EXTENDED_DATE_PATTERNS_1)) {
datePatterns = EXTENDED_DATE_PATTERNS_1;
@@ -107,6 +108,8 @@ public void parse(final SetCookie cookie, String value) throws MalformedCookieEx
}
final Date expiry = DateUtils.parseDate(value, datePatterns, startDate);
- cookie.setExpiryDate(expiry);
+ if (expiry != null) {
+ cookie.setExpiryDate(expiry.toInstant());
+ }
}
}
diff --git a/src/main/java/org/htmlunit/httpclient/HtmlUnitHttpOnlyHandler.java b/src/main/java/org/htmlunit/httpclient/HtmlUnitHttpOnlyHandler.java
index f40e5c0a26..b114605c09 100644
--- a/src/main/java/org/htmlunit/httpclient/HtmlUnitHttpOnlyHandler.java
+++ b/src/main/java/org/htmlunit/httpclient/HtmlUnitHttpOnlyHandler.java
@@ -14,12 +14,12 @@
*/
package org.htmlunit.httpclient;
-import org.apache.http.cookie.CommonCookieAttributeHandler;
-import org.apache.http.cookie.Cookie;
-import org.apache.http.cookie.CookieOrigin;
-import org.apache.http.cookie.MalformedCookieException;
-import org.apache.http.cookie.SetCookie;
-import org.apache.http.impl.cookie.BasicClientCookie;
+import org.apache.hc.client5.http.cookie.CommonCookieAttributeHandler;
+import org.apache.hc.client5.http.cookie.Cookie;
+import org.apache.hc.client5.http.cookie.CookieOrigin;
+import org.apache.hc.client5.http.cookie.MalformedCookieException;
+import org.apache.hc.client5.http.cookie.SetCookie;
+import org.apache.hc.client5.http.impl.cookie.BasicClientCookie;
/**
* Customized CookieAttributeHandler for handling of the httponly attribute.
diff --git a/src/main/java/org/htmlunit/httpclient/HtmlUnitMaxAgeHandler.java b/src/main/java/org/htmlunit/httpclient/HtmlUnitMaxAgeHandler.java
index e24b699e10..49aefd3304 100644
--- a/src/main/java/org/htmlunit/httpclient/HtmlUnitMaxAgeHandler.java
+++ b/src/main/java/org/htmlunit/httpclient/HtmlUnitMaxAgeHandler.java
@@ -14,12 +14,12 @@
*/
package org.htmlunit.httpclient;
-import java.util.Date;
+import java.time.Instant;
-import org.apache.http.cookie.MalformedCookieException;
-import org.apache.http.cookie.SetCookie;
-import org.apache.http.impl.cookie.BasicMaxAgeHandler;
-import org.apache.http.util.Args;
+import org.apache.hc.client5.http.cookie.MalformedCookieException;
+import org.apache.hc.client5.http.cookie.SetCookie;
+import org.apache.hc.client5.http.impl.cookie.BasicMaxAgeHandler;
+import org.apache.hc.core5.util.Args;
/**
* Customized BasicMaxAgeHandler for HtmlUnit.
@@ -42,7 +42,7 @@ public void parse(final SetCookie cookie, final String value)
catch (final NumberFormatException e) {
throw new MalformedCookieException("Invalid 'max-age' attribute: " + value, e);
}
- cookie.setExpiryDate(new Date(System.currentTimeMillis() + age * 1000L));
+ cookie.setExpiryDate(Instant.ofEpochMilli(System.currentTimeMillis() + age * 1000L));
}
}
diff --git a/src/main/java/org/htmlunit/httpclient/HtmlUnitPathHandler.java b/src/main/java/org/htmlunit/httpclient/HtmlUnitPathHandler.java
index a963a83151..8963d577c3 100644
--- a/src/main/java/org/htmlunit/httpclient/HtmlUnitPathHandler.java
+++ b/src/main/java/org/htmlunit/httpclient/HtmlUnitPathHandler.java
@@ -14,10 +14,10 @@
*/
package org.htmlunit.httpclient;
-import org.apache.http.cookie.Cookie;
-import org.apache.http.cookie.CookieOrigin;
-import org.apache.http.cookie.MalformedCookieException;
-import org.apache.http.impl.cookie.BasicPathHandler;
+import org.apache.hc.client5.http.cookie.Cookie;
+import org.apache.hc.client5.http.cookie.CookieOrigin;
+import org.apache.hc.client5.http.cookie.MalformedCookieException;
+import org.apache.hc.client5.http.impl.cookie.BasicPathHandler;
/**
* Customized BasicPathHandler for HtmlUnit.
diff --git a/src/main/java/org/htmlunit/httpclient/HtmlUnitSameSiteHandler.java b/src/main/java/org/htmlunit/httpclient/HtmlUnitSameSiteHandler.java
index 564b0bee26..7ba879a873 100644
--- a/src/main/java/org/htmlunit/httpclient/HtmlUnitSameSiteHandler.java
+++ b/src/main/java/org/htmlunit/httpclient/HtmlUnitSameSiteHandler.java
@@ -14,12 +14,12 @@
*/
package org.htmlunit.httpclient;
-import org.apache.http.cookie.CommonCookieAttributeHandler;
-import org.apache.http.cookie.Cookie;
-import org.apache.http.cookie.CookieOrigin;
-import org.apache.http.cookie.MalformedCookieException;
-import org.apache.http.cookie.SetCookie;
-import org.apache.http.impl.cookie.BasicClientCookie;
+import org.apache.hc.client5.http.cookie.CommonCookieAttributeHandler;
+import org.apache.hc.client5.http.cookie.Cookie;
+import org.apache.hc.client5.http.cookie.CookieOrigin;
+import org.apache.hc.client5.http.cookie.MalformedCookieException;
+import org.apache.hc.client5.http.cookie.SetCookie;
+import org.apache.hc.client5.http.impl.cookie.BasicClientCookie;
import org.htmlunit.util.StringUtils;
/**
diff --git a/src/main/java/org/htmlunit/httpclient/HtmlUnitSecureHandler.java b/src/main/java/org/htmlunit/httpclient/HtmlUnitSecureHandler.java
index e0798419d2..3d11bc5e78 100644
--- a/src/main/java/org/htmlunit/httpclient/HtmlUnitSecureHandler.java
+++ b/src/main/java/org/htmlunit/httpclient/HtmlUnitSecureHandler.java
@@ -14,10 +14,10 @@
*/
package org.htmlunit.httpclient;
-import org.apache.http.cookie.Cookie;
-import org.apache.http.cookie.CookieOrigin;
-import org.apache.http.impl.cookie.BasicSecureHandler;
-import org.apache.http.util.Args;
+import org.apache.hc.client5.http.cookie.Cookie;
+import org.apache.hc.client5.http.cookie.CookieOrigin;
+import org.apache.hc.client5.http.impl.cookie.BasicSecureHandler;
+import org.apache.hc.core5.util.Args;
/**
* Customized BasicSecureHandler for HtmlUnit.
diff --git a/src/main/java/org/htmlunit/httpclient/HtmlUnitVersionAttributeHandler.java b/src/main/java/org/htmlunit/httpclient/HtmlUnitVersionAttributeHandler.java
index b1348e8feb..2cb1c96ad4 100644
--- a/src/main/java/org/htmlunit/httpclient/HtmlUnitVersionAttributeHandler.java
+++ b/src/main/java/org/htmlunit/httpclient/HtmlUnitVersionAttributeHandler.java
@@ -14,11 +14,11 @@
*/
package org.htmlunit.httpclient;
-import org.apache.http.cookie.ClientCookie;
-import org.apache.http.cookie.CommonCookieAttributeHandler;
-import org.apache.http.cookie.MalformedCookieException;
-import org.apache.http.cookie.SetCookie;
-import org.apache.http.impl.cookie.AbstractCookieAttributeHandler;
+import org.apache.hc.client5.http.cookie.CommonCookieAttributeHandler;
+import org.apache.hc.client5.http.cookie.Cookie;
+import org.apache.hc.client5.http.cookie.MalformedCookieException;
+import org.apache.hc.client5.http.cookie.SetCookie;
+import org.apache.hc.client5.http.impl.cookie.AbstractCookieAttributeHandler;
/**
* VersionAttributeHandler for HtmlUnit.
@@ -48,6 +48,6 @@ public void parse(final SetCookie cookie, final String value) throws MalformedCo
@Override
public String getAttributeName() {
- return ClientCookie.VERSION_ATTR;
+ return Cookie.VERSION_ATTR;
}
}
From 90a061a96c720b90a92ee01b2f5da3ab0d23a03d Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 6 Feb 2026 12:39:30 +0000
Subject: [PATCH 4/8] Phase 3: Update cookie support classes and credentials to
HttpClient 5.4.1
Co-authored-by: rbri <2544132+rbri@users.noreply.github.com>
---
...owserCompatCookieHeaderValueFormatter.java | 2 +-
.../httpclient/HtmlUnitCookieStore.java | 14 +++++------
.../HtmlUnitUsernamePasswordCredentials.java | 10 ++++----
.../httpclient/HttpClientConverter.java | 25 ++++++++++---------
.../htmlunit/httpclient/HttpClientCookie.java | 20 +++++++++------
5 files changed, 38 insertions(+), 33 deletions(-)
diff --git a/src/main/java/org/htmlunit/httpclient/HtmlUnitBrowserCompatCookieHeaderValueFormatter.java b/src/main/java/org/htmlunit/httpclient/HtmlUnitBrowserCompatCookieHeaderValueFormatter.java
index de6750fc46..0578dd63ab 100644
--- a/src/main/java/org/htmlunit/httpclient/HtmlUnitBrowserCompatCookieHeaderValueFormatter.java
+++ b/src/main/java/org/htmlunit/httpclient/HtmlUnitBrowserCompatCookieHeaderValueFormatter.java
@@ -14,7 +14,7 @@
*/
package org.htmlunit.httpclient;
-import org.apache.http.message.BasicHeaderValueFormatter;
+import org.apache.hc.core5.http.message.BasicHeaderValueFormatter;
/**
* Customized BasicHeaderValueFormatter for HtmlUnit.
diff --git a/src/main/java/org/htmlunit/httpclient/HtmlUnitCookieStore.java b/src/main/java/org/htmlunit/httpclient/HtmlUnitCookieStore.java
index 4ddc687773..ca98dff82f 100644
--- a/src/main/java/org/htmlunit/httpclient/HtmlUnitCookieStore.java
+++ b/src/main/java/org/htmlunit/httpclient/HtmlUnitCookieStore.java
@@ -15,16 +15,16 @@
package org.htmlunit.httpclient;
import java.io.Serializable;
+import java.time.Instant;
import java.util.Date;
import java.util.List;
-import org.apache.http.client.CookieStore;
-import org.apache.http.cookie.ClientCookie;
-import org.apache.http.cookie.Cookie;
+import org.apache.hc.client5.http.cookie.Cookie;
+import org.apache.hc.client5.http.cookie.CookieStore;
import org.htmlunit.CookieManager;
/**
- * Implementation of {@link CookieStore} like {@link org.apache.http.impl.client.BasicCookieStore}
+ * Implementation of {@link CookieStore} like {@link org.apache.hc.client5.http.impl.cookie.BasicCookieStore}
* BUT using our own {@link CookieManager} as back end.
*
* @author Marc Guillemot
@@ -47,7 +47,7 @@ public HtmlUnitCookieStore(final CookieManager manager) {
*/
@Override
public synchronized void addCookie(final Cookie cookie) {
- manager_.addCookie(new HttpClientCookie((ClientCookie) cookie));
+ manager_.addCookie(new HttpClientCookie(cookie));
}
/**
@@ -62,8 +62,8 @@ public synchronized List getCookies() {
* {@inheritDoc}
*/
@Override
- public synchronized boolean clearExpired(final Date date) {
- return manager_.clearExpired(date);
+ public synchronized boolean clearExpired(final Instant date) {
+ return manager_.clearExpired(date != null ? Date.from(date) : null);
}
/**
diff --git a/src/main/java/org/htmlunit/httpclient/HtmlUnitUsernamePasswordCredentials.java b/src/main/java/org/htmlunit/httpclient/HtmlUnitUsernamePasswordCredentials.java
index 407d96cce8..be60082c69 100644
--- a/src/main/java/org/htmlunit/httpclient/HtmlUnitUsernamePasswordCredentials.java
+++ b/src/main/java/org/htmlunit/httpclient/HtmlUnitUsernamePasswordCredentials.java
@@ -17,9 +17,9 @@
import java.io.Serializable;
import java.security.Principal;
-import org.apache.http.auth.Credentials;
-import org.apache.http.auth.UsernamePasswordCredentials;
-import org.apache.http.util.LangUtils;
+import org.apache.hc.client5.http.auth.Credentials;
+import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
+import org.apache.hc.core5.util.LangUtils;
/**
* Wrapper for {@link UsernamePasswordCredentials} to avoid direct references spread around.
@@ -40,11 +40,11 @@ public class HtmlUnitUsernamePasswordCredentials implements Credentials, Seriali
public HtmlUnitUsernamePasswordCredentials(final String userName, final char[] password) {
httpClientUsernamePasswordCredentials_ = new UsernamePasswordCredentials(
userName,
- password == null ? null : String.valueOf(password));
+ password);
}
@Override
- public String getPassword() {
+ public char[] getPassword() {
return httpClientUsernamePasswordCredentials_.getPassword();
}
diff --git a/src/main/java/org/htmlunit/httpclient/HttpClientConverter.java b/src/main/java/org/htmlunit/httpclient/HttpClientConverter.java
index 2577074059..0466313263 100644
--- a/src/main/java/org/htmlunit/httpclient/HttpClientConverter.java
+++ b/src/main/java/org/htmlunit/httpclient/HttpClientConverter.java
@@ -21,14 +21,13 @@
import java.util.List;
import java.util.Set;
-import org.apache.http.cookie.ClientCookie;
-import org.apache.http.cookie.Cookie;
-import org.apache.http.cookie.CookieOrigin;
-import org.apache.http.cookie.CookieSpec;
-import org.apache.http.cookie.MalformedCookieException;
-import org.apache.http.impl.cookie.BasicClientCookie;
-import org.apache.http.message.BufferedHeader;
-import org.apache.http.util.CharArrayBuffer;
+import org.apache.hc.client5.http.cookie.Cookie;
+import org.apache.hc.client5.http.cookie.CookieOrigin;
+import org.apache.hc.client5.http.cookie.CookieSpec;
+import org.apache.hc.client5.http.cookie.MalformedCookieException;
+import org.apache.hc.client5.http.impl.cookie.BasicClientCookie;
+import org.apache.hc.core5.http.message.BufferedHeader;
+import org.apache.hc.core5.util.CharArrayBuffer;
import org.htmlunit.BrowserVersion;
import org.htmlunit.util.UrlUtils;
@@ -105,7 +104,7 @@ public static List parseCookie(final String cookieStri
final List htmlUnitCookies = new ArrayList<>(cookies.size());
for (final Cookie cookie : cookies) {
- final org.htmlunit.http.Cookie htmlUnitCookie = new HttpClientCookie((ClientCookie) cookie);
+ final org.htmlunit.http.Cookie htmlUnitCookie = new HttpClientCookie(cookie);
htmlUnitCookies.add(htmlUnitCookie);
}
return htmlUnitCookies;
@@ -145,7 +144,7 @@ public static void addMatching(final Set cookies,
}
}
- private static ClientCookie toHttpClient(final org.htmlunit.http.Cookie cookie) {
+ private static Cookie toHttpClient(final org.htmlunit.http.Cookie cookie) {
if (cookie instanceof HttpClientCookie) {
return ((HttpClientCookie) cookie).getHttpClientCookie();
}
@@ -155,10 +154,12 @@ private static ClientCookie toHttpClient(final org.htmlunit.http.Cookie cookie)
httpClientCookie.setDomain(cookie.getDomain());
// BasicDomainHandler.match(Cookie, CookieOrigin) checks the attribute also (see #333)
- httpClientCookie.setAttribute(ClientCookie.DOMAIN_ATTR, cookie.getDomain());
+ httpClientCookie.setAttribute(Cookie.DOMAIN_ATTR, cookie.getDomain());
httpClientCookie.setPath(cookie.getPath());
- httpClientCookie.setExpiryDate(cookie.getExpires());
+ if (cookie.getExpires() != null) {
+ httpClientCookie.setExpiryDate(cookie.getExpires().toInstant());
+ }
httpClientCookie.setSecure(cookie.isSecure());
if (cookie.isHttpOnly()) {
diff --git a/src/main/java/org/htmlunit/httpclient/HttpClientCookie.java b/src/main/java/org/htmlunit/httpclient/HttpClientCookie.java
index e110c8897b..203b2ec1a7 100644
--- a/src/main/java/org/htmlunit/httpclient/HttpClientCookie.java
+++ b/src/main/java/org/htmlunit/httpclient/HttpClientCookie.java
@@ -14,36 +14,40 @@
*/
package org.htmlunit.httpclient;
-import org.apache.http.cookie.ClientCookie;
+import java.time.Instant;
+
+import org.apache.hc.client5.http.cookie.Cookie;
import org.htmlunit.http.Cookie;
/**
- * Wrapper for {@link ClientCookie}.
+ * Wrapper for {@link Cookie}.
*
* @author Ronald Brill
*/
-public class HttpClientCookie extends Cookie {
+public class HttpClientCookie extends org.htmlunit.http.Cookie {
- private final ClientCookie httpClientCookie_;
+ private final Cookie httpClientCookie_;
/**
* Creates a new HtmlUnit cookie from the HttpClient cookie provided.
* @param clientCookie the HttpClient cookie
*/
- public HttpClientCookie(final ClientCookie clientCookie) {
+ public HttpClientCookie(final Cookie clientCookie) {
// just use this ctor but in fact we will overwrite by setting the httpClient Cookie
super(clientCookie.getDomain(), clientCookie.getName(),
clientCookie.getValue(), clientCookie.getPath(),
- clientCookie.getExpiryDate(), clientCookie.isSecure(),
+ clientCookie.getExpiryInstant() != null
+ ? java.util.Date.from(clientCookie.getExpiryInstant()) : null,
+ clientCookie.isSecure(),
clientCookie.getAttribute("httponly") != null, clientCookie.getAttribute("samesite"));
httpClientCookie_ = clientCookie;
}
/**
- * @return an HttpClient ClientCookie version of this cookie
+ * @return an HttpClient Cookie version of this cookie
*/
- public ClientCookie getHttpClientCookie() {
+ public Cookie getHttpClientCookie() {
return httpClientCookie_;
}
}
From 8093e9d096ae9addfdf038d3fcd7ce45f9ed6d8b Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 6 Feb 2026 12:41:51 +0000
Subject: [PATCH 5/8] Phase 4: Update HtmlUnitBrowserCompatCookieSpec to
HttpClient 5.4.1
Co-authored-by: rbri <2544132+rbri@users.noreply.github.com>
---
.../HtmlUnitBrowserCompatCookieSpec.java | 52 +++++++++----------
1 file changed, 26 insertions(+), 26 deletions(-)
diff --git a/src/main/java/org/htmlunit/httpclient/HtmlUnitBrowserCompatCookieSpec.java b/src/main/java/org/htmlunit/httpclient/HtmlUnitBrowserCompatCookieSpec.java
index 7f0e2b56ca..96d54cdaa3 100644
--- a/src/main/java/org/htmlunit/httpclient/HtmlUnitBrowserCompatCookieSpec.java
+++ b/src/main/java/org/htmlunit/httpclient/HtmlUnitBrowserCompatCookieSpec.java
@@ -22,29 +22,29 @@
import java.util.Date;
import java.util.List;
import java.util.Locale;
-
-import org.apache.http.FormattedHeader;
-import org.apache.http.Header;
-import org.apache.http.HeaderElement;
-import org.apache.http.NameValuePair;
-import org.apache.http.ParseException;
-import org.apache.http.client.utils.DateUtils;
-import org.apache.http.cookie.Cookie;
-import org.apache.http.cookie.CookieAttributeHandler;
-import org.apache.http.cookie.CookieOrigin;
-import org.apache.http.cookie.CookiePathComparator;
-import org.apache.http.cookie.MalformedCookieException;
-import org.apache.http.cookie.SM;
-import org.apache.http.impl.cookie.BasicClientCookie;
-import org.apache.http.impl.cookie.BasicCommentHandler;
-import org.apache.http.impl.cookie.CookieSpecBase;
-import org.apache.http.message.BasicHeader;
-import org.apache.http.message.BasicHeaderElement;
-import org.apache.http.message.BasicNameValuePair;
-import org.apache.http.message.BufferedHeader;
-import org.apache.http.message.ParserCursor;
-import org.apache.http.message.TokenParser;
-import org.apache.http.util.CharArrayBuffer;
+import java.util.TimeZone;
+
+import org.apache.hc.client5.http.cookie.Cookie;
+import org.apache.hc.client5.http.cookie.CookieAttributeHandler;
+import org.apache.hc.client5.http.cookie.CookieOrigin;
+import org.apache.hc.client5.http.cookie.CookiePathComparator;
+import org.apache.hc.client5.http.cookie.MalformedCookieException;
+import org.apache.hc.client5.http.impl.cookie.BasicClientCookie;
+import org.apache.hc.client5.http.impl.cookie.BasicCommentHandler;
+import org.apache.hc.client5.http.impl.cookie.CookieSpecBase;
+import org.apache.hc.core5.http.FormattedHeader;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HeaderElement;
+import org.apache.hc.core5.http.HttpHeaders;
+import org.apache.hc.core5.http.NameValuePair;
+import org.apache.hc.core5.http.ParseException;
+import org.apache.hc.core5.http.message.BasicHeader;
+import org.apache.hc.core5.http.message.BasicHeaderElement;
+import org.apache.hc.core5.http.message.BasicNameValuePair;
+import org.apache.hc.core5.http.message.BufferedHeader;
+import org.apache.hc.core5.http.message.ParserCursor;
+import org.apache.hc.core5.http.message.TokenParser;
+import org.apache.hc.core5.util.CharArrayBuffer;
import org.htmlunit.BrowserVersion;
import org.htmlunit.util.StringUtils;
@@ -89,7 +89,7 @@ public class HtmlUnitBrowserCompatCookieSpec extends CookieSpecBase {
static {
final Calendar calendar = Calendar.getInstance(Locale.ROOT);
- calendar.setTimeZone(DateUtils.GMT);
+ calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
calendar.set(1970, Calendar.JANUARY, 1, 0, 0, 0);
calendar.set(Calendar.MILLISECOND, 0);
DATE_1_1_1970 = calendar.getTime();
@@ -140,7 +140,7 @@ else if (endPos == 0 || StringUtils.isBlank(text.substring(0, endPos))) {
}
final String headername = header.getName();
- if (!SM.SET_COOKIE.equalsIgnoreCase(headername)) {
+ if (!HttpHeaders.SET_COOKIE.equalsIgnoreCase(headername)) {
throw new MalformedCookieException("Unrecognized cookie header '" + header + "'");
}
final HeaderElement[] helems = header.getElements();
@@ -221,7 +221,7 @@ public List formatCookies(final List cookies) {
cookies.sort(COOKIE_COMPARATOR);
final CharArrayBuffer buffer = new CharArrayBuffer(20 * cookies.size());
- buffer.append(SM.COOKIE);
+ buffer.append(HttpHeaders.COOKIE);
buffer.append(": ");
final int size = cookies.size();
for (int i = 0; i < size; i++) {
From 04b01013968c5035caa336012e03923b811e615f Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 6 Feb 2026 12:44:07 +0000
Subject: [PATCH 6/8] Phase 5: Complete SSL/TLS support - update
HtmlUnitSSLConnectionSocketFactory and SocksConnectionSocketFactory
Co-authored-by: rbri <2544132+rbri@users.noreply.github.com>
---
.../HtmlUnitSSLConnectionSocketFactory.java | 19 ++++++++++---------
.../SocksConnectionSocketFactory.java | 8 ++++----
2 files changed, 14 insertions(+), 13 deletions(-)
diff --git a/src/main/java/org/htmlunit/httpclient/HtmlUnitSSLConnectionSocketFactory.java b/src/main/java/org/htmlunit/httpclient/HtmlUnitSSLConnectionSocketFactory.java
index 85873aac81..b6da75fc27 100644
--- a/src/main/java/org/htmlunit/httpclient/HtmlUnitSSLConnectionSocketFactory.java
+++ b/src/main/java/org/htmlunit/httpclient/HtmlUnitSSLConnectionSocketFactory.java
@@ -35,13 +35,14 @@
import javax.net.ssl.SSLSocket;
import javax.net.ssl.X509ExtendedTrustManager;
-import org.apache.http.HttpHost;
-import org.apache.http.conn.ConnectTimeoutException;
-import org.apache.http.conn.ssl.DefaultHostnameVerifier;
-import org.apache.http.conn.ssl.NoopHostnameVerifier;
-import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
-import org.apache.http.protocol.HttpContext;
-import org.apache.http.ssl.SSLContexts;
+import org.apache.hc.client5.http.ConnectTimeoutException;
+import org.apache.hc.client5.http.ssl.DefaultHostnameVerifier;
+import org.apache.hc.client5.http.ssl.NoopHostnameVerifier;
+import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.protocol.HttpContext;
+import org.apache.hc.core5.ssl.SSLContexts;
+import org.apache.hc.core5.util.Timeout;
import org.htmlunit.WebClientOptions;
/**
@@ -145,7 +146,7 @@ private static void configureSocket(final SSLSocket sslSocket, final HttpContext
*/
@Override
public Socket connectSocket(
- final int connectTimeout,
+ final Timeout connectTimeout,
final Socket socket,
final HttpHost host,
final InetSocketAddress remoteAddress,
@@ -158,7 +159,7 @@ public Socket connectSocket(
try {
//underlying.setSoTimeout(soTimeout);
- underlying.connect(remoteAddress, connectTimeout);
+ underlying.connect(remoteAddress, (int) connectTimeout.toMilliseconds());
}
catch (final SocketTimeoutException ex) {
final ConnectTimeoutException cex =
diff --git a/src/main/java/org/htmlunit/httpclient/SocksConnectionSocketFactory.java b/src/main/java/org/htmlunit/httpclient/SocksConnectionSocketFactory.java
index f296127d3e..ca42499457 100644
--- a/src/main/java/org/htmlunit/httpclient/SocksConnectionSocketFactory.java
+++ b/src/main/java/org/htmlunit/httpclient/SocksConnectionSocketFactory.java
@@ -19,12 +19,12 @@
import java.net.Proxy;
import java.net.Socket;
-import org.apache.http.HttpHost;
-import org.apache.http.conn.socket.PlainConnectionSocketFactory;
-import org.apache.http.protocol.HttpContext;
+import org.apache.hc.client5.http.socket.PlainConnectionSocketFactory;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.protocol.HttpContext;
/**
- * SOCKS aware {@link org.apache.http.conn.socket.ConnectionSocketFactory}.
+ * SOCKS aware {@link org.apache.hc.client5.http.socket.ConnectionSocketFactory}.
*
* @author Ahmed Ashour
* @author Ronald Brill
From e1f0732670ae30e32cffd01aef65cd7c54f8627a Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 6 Feb 2026 12:45:26 +0000
Subject: [PATCH 7/8] Phase 6: Update WebRequest, WebClient, and
DefaultCredentialsProvider imports
Co-authored-by: rbri <2544132+rbri@users.noreply.github.com>
---
.../org/htmlunit/DefaultCredentialsProvider.java | 12 ++++++------
src/main/java/org/htmlunit/WebClient.java | 6 +++---
src/main/java/org/htmlunit/WebRequest.java | 2 +-
3 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/src/main/java/org/htmlunit/DefaultCredentialsProvider.java b/src/main/java/org/htmlunit/DefaultCredentialsProvider.java
index 97e9d2147f..e2a07816a5 100644
--- a/src/main/java/org/htmlunit/DefaultCredentialsProvider.java
+++ b/src/main/java/org/htmlunit/DefaultCredentialsProvider.java
@@ -23,11 +23,11 @@
import java.util.HashMap;
import java.util.Map;
-import org.apache.http.auth.AuthScope;
-import org.apache.http.auth.Credentials;
-import org.apache.http.auth.NTCredentials;
-import org.apache.http.auth.UsernamePasswordCredentials;
-import org.apache.http.client.CredentialsProvider;
+import org.apache.hc.client5.http.auth.AuthScope;
+import org.apache.hc.client5.http.auth.Credentials;
+import org.apache.hc.client5.http.auth.CredentialsProvider;
+import org.apache.hc.client5.http.auth.NTCredentials;
+import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
import org.htmlunit.httpclient.HtmlUnitUsernamePasswordCredentials;
/**
@@ -130,7 +130,7 @@ public void addCredentials(final String username, final char[] password, final S
public void addNTLMCredentials(final String username, final char[] password, final String host,
final int port, final String workstation, final String domain) {
final AuthScope authscope = new AuthScope(host, port, ANY_REALM, ANY_SCHEME);
- final NTCredentials credentials = new NTCredentials(username, String.valueOf(password), workstation, domain);
+ final NTCredentials credentials = new NTCredentials(username, password, workstation, domain);
setCredentials(authscope, credentials);
}
diff --git a/src/main/java/org/htmlunit/WebClient.java b/src/main/java/org/htmlunit/WebClient.java
index 18e7fd39d0..0c3bf5517c 100644
--- a/src/main/java/org/htmlunit/WebClient.java
+++ b/src/main/java/org/htmlunit/WebClient.java
@@ -56,9 +56,9 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.http.NoHttpResponseException;
-import org.apache.http.client.CredentialsProvider;
-import org.apache.http.cookie.MalformedCookieException;
+import org.apache.hc.client5.http.auth.CredentialsProvider;
+import org.apache.hc.client5.http.cookie.MalformedCookieException;
+import org.apache.hc.core5.http.NoHttpResponseException;
import org.htmlunit.attachment.Attachment;
import org.htmlunit.attachment.AttachmentHandler;
import org.htmlunit.csp.Policy;
diff --git a/src/main/java/org/htmlunit/WebRequest.java b/src/main/java/org/htmlunit/WebRequest.java
index 33484e9704..18aacab278 100644
--- a/src/main/java/org/htmlunit/WebRequest.java
+++ b/src/main/java/org/htmlunit/WebRequest.java
@@ -32,7 +32,7 @@
import java.util.Set;
import java.util.regex.Pattern;
-import org.apache.http.auth.Credentials;
+import org.apache.hc.client5.http.auth.Credentials;
import org.htmlunit.http.HttpUtils;
import org.htmlunit.httpclient.HtmlUnitUsernamePasswordCredentials;
import org.htmlunit.util.NameValuePair;
From afc4e552a5be71db17f0cd0a9596f38d92cc23a4 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 6 Feb 2026 12:47:27 +0000
Subject: [PATCH 8/8] Security: Update httpclient5 to 5.4.3 to fix domain check
vulnerability
Co-authored-by: rbri <2544132+rbri@users.noreply.github.com>
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index e50399cb42..dca68b0a83 100644
--- a/pom.xml
+++ b/pom.xml
@@ -46,7 +46,7 @@
5.0.0-SNAPSHOT
5.3.1
- 5.4.1
+ 5.4.3
3.20.0
2.21.0
1.3.5