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