jetty-9 - HTTP client: implemented cookie functionalities.

This commit is contained in:
Simone Bordet 2012-09-06 22:54:56 +02:00
parent 3ba074ecc8
commit 8b7e1463a1
11 changed files with 774 additions and 103 deletions

View File

@ -36,6 +36,7 @@ import javax.net.ssl.SSLEngine;
import org.eclipse.jetty.client.api.Connection;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.CookieStore;
import org.eclipse.jetty.client.api.Destination;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.api.Response;
@ -94,6 +95,7 @@ public class HttpClient extends AggregateLifeCycle
private final ConcurrentMap<String, Destination> destinations = new ConcurrentHashMap<>();
private final ConcurrentMap<Long, HttpConversation> conversations = new ConcurrentHashMap<>();
private final CookieStore cookieStore = new HttpCookieStore();
private volatile Executor executor;
private volatile ByteBufferPool byteBufferPool;
private volatile Scheduler scheduler;
@ -155,6 +157,11 @@ public class HttpClient extends AggregateLifeCycle
LOG.info("Stopped {}", this);
}
public CookieStore getCookieStore()
{
return cookieStore;
}
public long getIdleTimeout()
{
return idleTimeout;

View File

@ -18,12 +18,14 @@
package org.eclipse.jetty.client;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.jetty.client.api.Connection;
import org.eclipse.jetty.client.api.ContentProvider;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.api.Response;
import org.eclipse.jetty.http.HttpCookie;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpMethod;
@ -57,6 +59,11 @@ public class HttpConnection extends AbstractConnection implements Connection
return client;
}
public HttpDestination getDestination()
{
return destination;
}
@Override
public void onOpen()
{
@ -109,7 +116,6 @@ public class HttpConnection extends AbstractConnection implements Connection
request.idleTimeout(client.getIdleTimeout());
// TODO: follow redirects
// TODO: cookies
HttpVersion version = request.version();
HttpFields headers = request.headers();
@ -136,6 +142,21 @@ public class HttpConnection extends AbstractConnection implements Connection
}
}
// Cookies
List<HttpCookie> cookies = client.getCookieStore().getCookies(getDestination(), request.path());
StringBuilder cookieString = null;
for (int i = 0; i < cookies.size(); ++i)
{
if (cookieString == null)
cookieString = new StringBuilder();
if (i > 0)
cookieString.append("; ");
HttpCookie cookie = cookies.get(i);
cookieString.append(cookie.getName()).append("=").append(cookie.getValue());
}
if (cookieString != null)
request.header(HttpHeader.COOKIE.asString(), cookieString.toString());
// TODO: decoder headers
// If we are HTTP 1.1, add the Host header

View File

@ -0,0 +1,192 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.client;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.http.HttpCookie;
public class HttpCookieParser
{
private static final String[] DATE_PATTERNS = new String[]
{
"EEE',' dd-MMM-yyyy HH:mm:ss 'GMT'",
"EEE',' dd MMM yyyy HH:mm:ss 'GMT'",
"EEE MMM dd yyyy HH:mm:ss 'GMT'Z"
};
private HttpCookieParser()
{
}
public static List<HttpCookie> parseCookies(String headerValue)
{
if (headerValue.toLowerCase().contains("expires="))
{
HttpCookie cookie = parseCookie(headerValue, 0);
if (cookie != null)
return Collections.singletonList(cookie);
else
return Collections.emptyList();
}
else
{
List<HttpCookie> result = new ArrayList<>();
List<String> cookieStrings = splitCookies(headerValue);
for (String cookieString : cookieStrings)
{
HttpCookie cookie = parseCookie(cookieString, 1);
if (cookie != null)
result.add(cookie);
}
return result;
}
}
private static List<String> splitCookies(String headerValue)
{
// The comma is the separator, but only if it's outside double quotes
List<String> result = new ArrayList<>();
int start = 0;
int quotes = 0;
for (int i = 0; i < headerValue.length(); ++i)
{
char c = headerValue.charAt(i);
if (c == ',' && quotes % 2 == 0)
{
result.add(headerValue.substring(start, i));
start = i + 1;
}
else if (c == '"')
{
++quotes;
}
}
result.add(headerValue.substring(start));
return result;
}
private static HttpCookie parseCookie(String cookieString, int version)
{
String[] cookieParts = cookieString.split(";");
String nameValue = cookieParts[0];
int equal = nameValue.indexOf('=');
if (equal < 1)
return null;
String name = nameValue.substring(0, equal).trim();
String value = nameValue.substring(equal + 1);
String domain = null;
String path = "/";
long maxAge = -1;
boolean httpOnly = false;
boolean secure = false;
String comment = null;
for (int i = 1; i < cookieParts.length; ++i)
{
try
{
String[] attributeParts = cookieParts[i].split("=", 2);
String attributeName = attributeParts[0].trim().toLowerCase();
String attributeValue = attributeParts.length < 2 ? "" : attributeParts[1].trim();
switch (attributeName)
{
case "domain":
{
domain = attributeValue;
break;
}
case "path":
{
path = attributeValue;
break;
}
case "max-age":
{
maxAge = Long.parseLong(attributeValue);
break;
}
case "expires":
{
maxAge = parseDate(attributeValue);
break;
}
case "secure":
{
secure = true;
break;
}
case "httponly":
{
httpOnly = true;
}
case "comment":
{
comment = attributeValue;
break;
}
case "version":
{
version = Integer.parseInt(attributeValue);
break;
}
default:
{
// Ignore
break;
}
}
}
catch (NumberFormatException x)
{
// Ignore
}
}
return new HttpCookie(name, value, domain, path, maxAge, httpOnly, secure, comment, version);
}
private static long parseDate(String attributeValue)
{
for (String pattern : DATE_PATTERNS)
{
try
{
SimpleDateFormat dateFormat = new SimpleDateFormat(pattern, Locale.US);
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
long result = TimeUnit.MILLISECONDS.toSeconds(dateFormat.parse(attributeValue).getTime() - System.currentTimeMillis());
if (result < 0)
return 0;
}
catch (ParseException x)
{
// Ignore and continue
}
}
return 0;
}
}

View File

@ -0,0 +1,127 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.client;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.eclipse.jetty.client.api.CookieStore;
import org.eclipse.jetty.client.api.Destination;
import org.eclipse.jetty.http.HttpCookie;
public class HttpCookieStore implements CookieStore
{
private final ConcurrentMap<String, Map<String, HttpCookie>> allCookies = new ConcurrentHashMap<>();
@Override
public List<HttpCookie> getCookies(Destination destination, String path)
{
List<HttpCookie> result = new ArrayList<>();
String host = destination.host();
int port = destination.port();
String key = host + ":" + port + path;
// First lookup: direct hit
Map<String, HttpCookie> cookies = allCookies.get(key);
if (cookies != null)
accumulateCookies(destination, cookies, result);
// Second lookup: root path
if (!"/".equals(path))
{
key = host + ":" + port + "/";
cookies = allCookies.get(key);
if (cookies != null)
accumulateCookies(destination, cookies, result);
}
// Third lookup: parent domains
int domains = host.split("\\.").length - 1;
for (int i = 2; i <= domains; ++i)
{
String[] hostParts = host.split("\\.", i);
host = hostParts[hostParts.length - 1];
key = host + ":" + port + "/";
cookies = allCookies.get(key);
if (cookies != null)
accumulateCookies(destination, cookies, result);
}
return result;
}
private void accumulateCookies(Destination destination, Map<String, HttpCookie> cookies, List<HttpCookie> result)
{
for (Iterator<HttpCookie> iterator = cookies.values().iterator(); iterator.hasNext(); )
{
HttpCookie cookie = iterator.next();
if (cookie.isExpired(System.nanoTime()))
{
iterator.remove();
}
else
{
if (!"https".equalsIgnoreCase(destination.scheme()) && cookie.isSecure())
continue;
result.add(cookie);
}
}
}
@Override
public boolean addCookie(Destination destination, HttpCookie cookie)
{
String destinationDomain = destination.host() + ":" + destination.port();
// Check whether it is the same domain
String domain = cookie.getDomain();
if (domain == null)
domain = destinationDomain;
if (domain.indexOf(':') < 0)
domain += ":" + ("https".equalsIgnoreCase(destination.scheme()) ? 443 : 80);
// Cookie domains may start with a ".", like ".domain.com"
// This also avoids that a request to sub.domain.com sets a cookie for domain.com
if (!domain.endsWith(destinationDomain))
return false;
// Normalize the path
String path = cookie.getPath();
if (path == null || path.length() == 0)
path = "/";
String key = destination.host() + ":" + destination.port() + path;
Map<String, HttpCookie> cookies = allCookies.get(key);
if (cookies == null)
{
cookies = new ConcurrentHashMap<>();
Map<String, HttpCookie> existing = allCookies.putIfAbsent(key, cookies);
if (existing != null)
cookies = existing;
}
cookies.put(path, cookie);
return true;
}
}

View File

@ -21,10 +21,13 @@ package org.eclipse.jetty.client;
import java.io.EOFException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
import org.eclipse.jetty.client.api.CookieStore;
import org.eclipse.jetty.client.api.Response;
import org.eclipse.jetty.http.HttpCookie;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpParser;
import org.eclipse.jetty.http.HttpVersion;
@ -115,6 +118,25 @@ public class HttpReceiver implements HttpParser.ResponseHandler<ByteBuffer>
{
HttpExchange exchange = connection.getExchange();
exchange.response().headers().put(name, value);
switch (name.toLowerCase())
{
case "set-cookie":
case "set-cookie2":
{
CookieStore cookieStore = connection.getHttpClient().getCookieStore();
HttpDestination destination = connection.getDestination();
List<HttpCookie> cookies = HttpCookieParser.parseCookies(value);
for (HttpCookie cookie : cookies)
cookieStore.addCookie(destination, cookie);
break;
}
default:
{
break;
}
}
return false;
}

View File

@ -0,0 +1,30 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.client.api;
import java.util.List;
import org.eclipse.jetty.http.HttpCookie;
public interface CookieStore
{
List<HttpCookie> getCookies(Destination destination, String path);
boolean addCookie(Destination destination, HttpCookie cookie);
}

View File

@ -0,0 +1,60 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.client;
import java.util.List;
import junit.framework.Assert;
import org.eclipse.jetty.http.HttpCookie;
import org.junit.Test;
public class HttpCookieParserTest
{
@Test
public void testParseCookie1() throws Exception
{
String value = "wd=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/; domain=.domain.com; httponly; secure";
List<HttpCookie> cookies = HttpCookieParser.parseCookies(value);
Assert.assertEquals(1, cookies.size());
HttpCookie cookie = cookies.get(0);
Assert.assertEquals("wd", cookie.getName());
Assert.assertEquals("deleted", cookie.getValue());
Assert.assertEquals(".domain.com", cookie.getDomain());
Assert.assertEquals("/", cookie.getPath());
Assert.assertTrue(cookie.isHttpOnly());
Assert.assertTrue(cookie.isSecure());
Assert.assertTrue(cookie.isExpired(System.nanoTime()));
}
@Test
public void testParseCookie2() throws Exception
{
String value = "wd=deleted; max-Age=0; path=/; domain=.domain.com; httponly; version=3";
List<HttpCookie> cookies = HttpCookieParser.parseCookies(value);
Assert.assertEquals(1, cookies.size());
HttpCookie cookie = cookies.get(0);
Assert.assertEquals("wd", cookie.getName());
Assert.assertEquals("deleted", cookie.getValue());
Assert.assertEquals(".domain.com", cookie.getDomain());
Assert.assertEquals("/", cookie.getPath());
Assert.assertTrue(cookie.isHttpOnly());
Assert.assertEquals(3, cookie.getVersion());
Assert.assertTrue(cookie.isExpired(System.nanoTime()));
}
}

View File

@ -0,0 +1,139 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.client;
import java.util.List;
import org.eclipse.jetty.client.api.CookieStore;
import org.eclipse.jetty.client.api.Destination;
import org.eclipse.jetty.http.HttpCookie;
import org.junit.Assert;
import org.junit.Test;
public class HttpCookieStoreTest
{
private HttpClient client = new HttpClient();
@Test
public void testCookieStoredIsRetrieved() throws Exception
{
CookieStore cookies = new HttpCookieStore();
Destination destination = new HttpDestination(client, "http", "localhost", 80);
Assert.assertTrue(cookies.addCookie(destination, new HttpCookie("a", "1")));
List<HttpCookie> result = cookies.getCookies(destination, "/");
Assert.assertNotNull(result);
Assert.assertEquals(1, result.size());
HttpCookie cookie = result.get(0);
Assert.assertEquals("a", cookie.getName());
Assert.assertEquals("1", cookie.getValue());
}
@Test
public void testCookieWithChildDomainIsStored() throws Exception
{
CookieStore cookies = new HttpCookieStore();
Destination destination = new HttpDestination(client, "http", "localhost", 80);
Assert.assertTrue(cookies.addCookie(destination, new HttpCookie("a", "1", "child.localhost", "/")));
List<HttpCookie> result = cookies.getCookies(destination, "/");
Assert.assertNotNull(result);
Assert.assertEquals(1, result.size());
HttpCookie cookie = result.get(0);
Assert.assertEquals("a", cookie.getName());
Assert.assertEquals("1", cookie.getValue());
}
@Test
public void testCookieWithParentDomainIsNotStored() throws Exception
{
CookieStore cookies = new HttpCookieStore();
Destination destination = new HttpDestination(client, "http", "child.localhost", 80);
Assert.assertFalse(cookies.addCookie(destination, new HttpCookie("a", "1", "localhost", "/")));
}
@Test
public void testCookieStoredWithPathIsNotRetrievedWithRootPath() throws Exception
{
CookieStore cookies = new HttpCookieStore();
Destination destination = new HttpDestination(client, "http", "localhost", 80);
Assert.assertTrue(cookies.addCookie(destination, new HttpCookie("a", "1", null, "/path")));
List<HttpCookie> result = cookies.getCookies(destination, "/");
Assert.assertNotNull(result);
Assert.assertEquals(0, result.size());
}
@Test
public void testCookieStoredWithRootPathIsRetrievedWithPath() throws Exception
{
CookieStore cookies = new HttpCookieStore();
Destination destination = new HttpDestination(client, "http", "localhost", 80);
Assert.assertTrue(cookies.addCookie(destination, new HttpCookie("a", "1", null, "/")));
List<HttpCookie> result = cookies.getCookies(destination, "/path");
Assert.assertNotNull(result);
Assert.assertEquals(1, result.size());
HttpCookie cookie = result.get(0);
Assert.assertEquals("a", cookie.getName());
Assert.assertEquals("1", cookie.getValue());
}
@Test
public void testCookieStoredWithParentDomainIsRetrievedWithChildDomain() throws Exception
{
CookieStore cookies = new HttpCookieStore();
Destination parentDestination = new HttpDestination(client, "http", "localhost.org", 80);
Assert.assertTrue(cookies.addCookie(parentDestination, new HttpCookie("a", "1", null, "/")));
Destination childDestination = new HttpDestination(client, "http", "child.localhost.org", 80);
Assert.assertTrue(cookies.addCookie(childDestination, new HttpCookie("b", "2", null, "/")));
Destination grandChildDestination = new HttpDestination(client, "http", "grand.child.localhost.org", 80);
Assert.assertTrue(cookies.addCookie(grandChildDestination, new HttpCookie("b", "2", null, "/")));
List<HttpCookie> result = cookies.getCookies(grandChildDestination, "/path");
Assert.assertNotNull(result);
Assert.assertEquals(2, result.size());
}
@Test
public void testExpiredCookieIsNotRetrieved() throws Exception
{
CookieStore cookies = new HttpCookieStore();
Destination destination = new HttpDestination(client, "http", "localhost.org", 80);
Assert.assertTrue(cookies.addCookie(destination, new HttpCookie("a", "1", null, "/", 0, false, false)));
List<HttpCookie> result = cookies.getCookies(destination, "/");
Assert.assertNotNull(result);
Assert.assertEquals(0, result.size());
}
@Test
public void testSecureCookieIsNotRetrieved() throws Exception
{
CookieStore cookies = new HttpCookieStore();
Destination destination = new HttpDestination(client, "http", "localhost.org", 80);
Assert.assertTrue(cookies.addCookie(destination, new HttpCookie("a", "1", null, "/", 0, false, true)));
List<HttpCookie> result = cookies.getCookies(destination, "/");
Assert.assertNotNull(result);
Assert.assertEquals(0, result.size());
}
}

View File

@ -0,0 +1,99 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.client;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.api.Destination;
import org.eclipse.jetty.client.api.Response;
import org.eclipse.jetty.http.HttpCookie;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.junit.Assert;
import org.junit.Test;
public class HttpCookieTest extends AbstractHttpClientServerTest
{
@Test
public void test_CookieIsStored() throws Exception
{
final String name = "foo";
final String value = "bar";
start(new AbstractHandler()
{
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
response.addCookie(new Cookie(name, value));
baseRequest.setHandled(true);
}
});
String scheme = "http";
String host = "localhost";
int port = connector.getLocalPort();
String path = "/path";
Response response = client.GET(scheme + "://" + host + ":" + port + path).get(5, TimeUnit.SECONDS);
Assert.assertEquals(200, response.status());
Destination destination = client.getDestination(scheme, host, port);
List<HttpCookie> cookies = client.getCookieStore().getCookies(destination, path);
Assert.assertNotNull(cookies);
Assert.assertEquals(1, cookies.size());
HttpCookie cookie = cookies.get(0);
Assert.assertEquals(name, cookie.getName());
Assert.assertEquals(value, cookie.getValue());
}
@Test
public void test_CookieIsSent() throws Exception
{
final String name = "foo";
final String value = "bar";
start(new AbstractHandler()
{
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
Cookie[] cookies = request.getCookies();
Assert.assertEquals(1, cookies.length);
Cookie cookie = cookies[0];
Assert.assertEquals(name, cookie.getName());
Assert.assertEquals(value, cookie.getValue());
baseRequest.setHandled(true);
}
});
String scheme = "http";
String host = "localhost";
int port = connector.getLocalPort();
String path = "/path";
Destination destination = client.getDestination(scheme, host, port);
client.getCookieStore().addCookie(destination, new HttpCookie(name, value, null, path));
Response response = client.GET(scheme + "://" + host + ":" + port + path).get(5, TimeUnit.SECONDS);
Assert.assertEquals(200, response.status());
}
}

View File

@ -130,21 +130,22 @@ public class HttpDestinationTest extends AbstractHttpClientServerTest
client.setIdleTimeout(idleTimeout);
HttpDestination destination = new HttpDestination(client, "http", "localhost", connector.getLocalPort());
destination.acquire();
// There are no queued requests, so the newly created connection will be idle
Connection connection1 = null;
long start = System.nanoTime();
while (connection1 == null && TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - start) < 5)
Connection connection1 = destination.acquire();
if (connection1 == null)
{
connection1 = destination.idleConnections().peek();
TimeUnit.MILLISECONDS.sleep(50);
// There are no queued requests, so the newly created connection will be idle
long start = System.nanoTime();
while (connection1 == null && TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - start) < 5)
{
connection1 = destination.idleConnections().peek();
TimeUnit.MILLISECONDS.sleep(50);
}
Assert.assertNotNull(connection1);
TimeUnit.MILLISECONDS.sleep(2 * idleTimeout);
connection1 = destination.idleConnections().poll();
Assert.assertNull(connection1);
}
Assert.assertNotNull(connection1);
TimeUnit.MILLISECONDS.sleep(2 * idleTimeout);
connection1 = destination.idleConnections().poll();
Assert.assertNull(connection1);
}
}

View File

@ -18,174 +18,147 @@
package org.eclipse.jetty.http;
import java.util.concurrent.TimeUnit;
public class HttpCookie
{
private final String _name;
private final String _value;
private final String _comment;
private final String _domain;
private final int _maxAge;
private final long _maxAge;
private final String _path;
private final boolean _secure;
private final int _version;
private final boolean _httpOnly;
private final long _expiration;
/* ------------------------------------------------------------ */
public HttpCookie(String name, String value)
{
super();
_name = name;
_value = value;
_comment = null;
_domain = null;
_httpOnly = false;
_maxAge = -1;
_path = null;
_secure = false;
_version = 0;
this(name, value, -1);
}
/* ------------------------------------------------------------ */
public HttpCookie(String name, String value, String domain, String path)
{
super();
this(name, value, domain, path, -1, false, false);
}
public HttpCookie(String name, String value, long maxAge)
{
this(name, value, null, null, maxAge, false, false);
}
public HttpCookie(String name, String value, String domain, String path, long maxAge, boolean httpOnly, boolean secure)
{
this(name, value, domain, path, maxAge, httpOnly, secure, null, 0);
}
public HttpCookie(String name, String value, String domain, String path, long maxAge, boolean httpOnly, boolean secure, String comment, int version)
{
_name = name;
_value = value;
_comment = null;
_domain = domain;
_httpOnly = false;
_maxAge = -1;
_path = path;
_secure = false;
_version = 0;
}
/* ------------------------------------------------------------ */
public HttpCookie(String name, String value, int maxAge)
{
super();
_name = name;
_value = value;
_comment = null;
_domain = null;
_httpOnly = false;
_maxAge = maxAge;
_path = null;
_secure = false;
_version = 0;
}
/* ------------------------------------------------------------ */
public HttpCookie(String name, String value, String domain, String path, int maxAge, boolean httpOnly, boolean secure)
{
super();
_comment = null;
_domain = domain;
_httpOnly = httpOnly;
_maxAge = maxAge;
_name = name;
_path = path;
_secure = secure;
_value = value;
_version = 0;
}
/* ------------------------------------------------------------ */
public HttpCookie(String name, String value, String domain, String path, int maxAge, boolean httpOnly, boolean secure, String comment, int version)
{
super();
_comment = comment;
_domain = domain;
_httpOnly = httpOnly;
_maxAge = maxAge;
_name = name;
_path = path;
_secure = secure;
_value = value;
_version = version;
_expiration = maxAge < 0 ? -1 : System.nanoTime() + TimeUnit.SECONDS.toNanos(maxAge);
}
/* ------------------------------------------------------------ */
/** Get the name.
* @return the name
/**
* @return the cookie name
*/
public String getName()
{
return _name;
}
/* ------------------------------------------------------------ */
/** Get the value.
* @return the value
/**
* @return the cookie value
*/
public String getValue()
{
return _value;
}
/* ------------------------------------------------------------ */
/** Get the comment.
* @return the comment
/**
* @return the cookie comment
*/
public String getComment()
{
return _comment;
}
/* ------------------------------------------------------------ */
/** Get the domain.
* @return the domain
/**
* @return the cookie domain
*/
public String getDomain()
{
return _domain;
}
/* ------------------------------------------------------------ */
/** Get the maxAge.
* @return the maxAge
/**
* @return the cookie max age in seconds
*/
public int getMaxAge()
public long getMaxAge()
{
return _maxAge;
}
/* ------------------------------------------------------------ */
/** Get the path.
* @return the path
/**
* @return the cookie path
*/
public String getPath()
{
return _path;
}
/* ------------------------------------------------------------ */
/** Get the secure.
* @return the secure
/**
* @return whether the cookie is valid for secure domains
*/
public boolean isSecure()
{
return _secure;
}
/* ------------------------------------------------------------ */
/** Get the version.
* @return the version
/**
* @return the cookie version
*/
public int getVersion()
{
return _version;
}
/* ------------------------------------------------------------ */
/** Get the isHttpOnly.
* @return the isHttpOnly
/**
* @return whether the cookie is valid for the http protocol only
*/
public boolean isHttpOnly()
{
return _httpOnly;
}
/**
* @param timeNanos the time to check for cookie expiration, in nanoseconds
* @return whether the cookie is expired by the given time
*/
public boolean isExpired(long timeNanos)
{
return _expiration >= 0 && timeNanos >= _expiration;
}
/**
* @return a string representation of this cookie
*/
public String asString()
{
StringBuilder builder = new StringBuilder();
builder.append(getName()).append("=").append(getValue());
if (getDomain() != null)
builder.append(";$Domain=").append(getDomain());
if (getPath() != null)
builder.append(";$Path=").append(getPath());
return builder.toString();
}
}