diff --git a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/control/HC4CookieHandler.java b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/control/HC4CookieHandler.java index 990b33ecca0..559d4c1022b 100644 --- a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/control/HC4CookieHandler.java +++ b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/control/HC4CookieHandler.java @@ -18,6 +18,7 @@ package org.apache.jmeter.protocol.http.control; import java.net.URL; +import java.time.Instant; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -173,20 +174,38 @@ public void addCookieFromHeader(CookieManager cookieManager, } @Override - public String getCookieHeaderForURL(CollectionProperty cookiesCP, URL url, - boolean allowVariableCookie) { - List c = - getCookiesForUrl(cookiesCP, url, allowVariableCookie); + public String getCookieHeaderForURL(CollectionProperty cookiesCP, URL url, boolean allowVariableCookie) { + List c = getCookiesForUrl(cookiesCP, url, allowVariableCookie); boolean debugEnabled = log.isDebugEnabled(); - if (debugEnabled){ + if (debugEnabled) { log.debug("Found {} cookies for {}", c.size(), url); } + if (c.isEmpty()) { return null; } - List
lstHdr = cookieSpec.formatCookies(c); + // Get current time as an Instant + Instant currentTime = Instant.now(); + List validCookies = new ArrayList<>(); + + for (org.apache.http.cookie.Cookie cookie : c) { + Date expiryDate = cookie.getExpiryDate(); + + // Convert Date to Instant for proper comparison + if (expiryDate == null || expiryDate.toInstant().isAfter(currentTime)) { + validCookies.add(cookie); + } else if (debugEnabled) { + log.info("Skipping expired cookie: {} for URL {}", cookie.getName(), url); + } + } + + if (validCookies.isEmpty()) { + return null; + } + + List
lstHdr = cookieSpec.formatCookies(validCookies); StringBuilder sbHdr = new StringBuilder(); for (Header header : lstHdr) { sbHdr.append(header.getValue()); @@ -195,6 +214,7 @@ public String getCookieHeaderForURL(CollectionProperty cookiesCP, URL url, return sbHdr.toString(); } + /** * Get array of valid HttpClient cookies for the URL * diff --git a/src/protocol/http/src/test/java/org/apache/jmeter/protocol/http/control/TestHC4CookieManager.java b/src/protocol/http/src/test/java/org/apache/jmeter/protocol/http/control/TestHC4CookieManager.java index 8b242540a47..aac190b06d2 100644 --- a/src/protocol/http/src/test/java/org/apache/jmeter/protocol/http/control/TestHC4CookieManager.java +++ b/src/protocol/http/src/test/java/org/apache/jmeter/protocol/http/control/TestHC4CookieManager.java @@ -23,10 +23,13 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import java.net.URL; +import java.util.Date; import java.util.List; import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.cookie.ClientCookie; +import org.apache.http.impl.client.BasicCookieStore; import org.apache.http.impl.cookie.BasicClientCookie; import org.apache.jmeter.junit.JMeterTestCase; import org.apache.jmeter.protocol.http.sampler.HTTPNullSampler; @@ -620,4 +623,45 @@ public void testLoad() throws Exception { assertTrue(man.get(num).getSecure()); assertEquals(0, man.get(num).getExpires()); // Show that maxlong now saved as 0 } + + @Test + void testMultipleCookiesWithDifferentExpiry() throws Exception { + HttpClientContext context = HttpClientContext.create(); + BasicCookieStore cookieStore = new BasicCookieStore(); + context.setCookieStore(cookieStore); + + long now = System.currentTimeMillis(); + + // Create Cookie A (expires in 5 seconds) + org.apache.http.impl.cookie.BasicClientCookie cookieA = + new org.apache.http.impl.cookie.BasicClientCookie("cookieA", "valueA"); + cookieA.setDomain("localhost"); + cookieA.setPath("/"); + cookieA.setExpiryDate(new Date(now + 5000)); + cookieStore.addCookie(cookieA); + + // Create Cookie B (expires in 10 seconds) + org.apache.http.impl.cookie.BasicClientCookie cookieB = + new org.apache.http.impl.cookie.BasicClientCookie("cookieB", "valueB"); + cookieB.setDomain("localhost"); + cookieB.setPath("/"); + cookieB.setExpiryDate(new Date(now + 10000)); + cookieStore.addCookie(cookieB); + + // First run: both cookies should be present + List cookies = cookieStore.getCookies(); + assertEquals(2, cookies.size(), "Both cookies should be present initially"); + + // Simulate time passage (6 seconds) + Thread.sleep(6000); + + // Clear expired manually like HC4CookieHandler does + Date now1 = new Date(); + cookieStore.clearExpired(now1); + + List validCookies = cookieStore.getCookies(); + assertEquals(1, validCookies.size(), "Only cookieB should remain after cookieA expiry"); + assertEquals("cookieB", validCookies.get(0).getName()); + } + }