Merge remote-tracking branch 'origin/jetty-9.4.x' into jetty-9.4.x-ewyk

This commit is contained in:
Greg Wilkins 2017-03-17 08:16:06 +11:00
commit 01349ac935
16 changed files with 459 additions and 88 deletions

View File

@ -14,6 +14,36 @@
<excludes>
<exclude>**/META-INF/**</exclude>
<exclude>*-config.jar</exclude>
<!-- common OS detritus -->
<exclude>**/.DS_Store</exclude>
<exclude>**/Thumbs.db</exclude>
<exclude>**/desktop.ini</exclude>
<!-- common temp files -->
<exclude>**/*~</exclude>
<exclude>**/*.bak</exclude>
<exclude>**/*.backup</exclude>
<exclude>**/*.old</exclude>
<exclude>**/*.swp</exclude>
<exclude>**/*.debug</exclude>
<exclude>**/*.dump</exclude>
<exclude>**/*.log</exclude>
<exclude>**/~*</exclude>
<!-- common git/scm files -->
<exclude>**/*.orig</exclude>
<exclude>**/*.diff</exclude>
<exclude>**/*.patch</exclude>
<exclude>**/.gitignore</exclude>
<!-- various editor files -->
<exclude>**/*.iml</exclude>
<exclude>**/*.ipr</exclude>
<exclude>**/*.iws</exclude>
<exclude>**/*.idea</exclude>
<exclude>**/.classpath</exclude>
<exclude>**/.project</exclude>
<exclude>**/.settings</exclude>
<!-- maven dust -->
<exclude>**/*.versionsBackup</exclude>
<exclude>**/*.releaseBackup</exclude>
</excludes>
</fileSet>
</fileSets>

View File

@ -12,6 +12,36 @@
</includes>
<excludes>
<exclude>**/target/**</exclude>
<!-- common OS detritus -->
<exclude>**/.DS_Store</exclude>
<exclude>**/Thumbs.db</exclude>
<exclude>**/desktop.ini</exclude>
<!-- common temp files -->
<exclude>**/*~</exclude>
<exclude>**/*.bak</exclude>
<exclude>**/*.backup</exclude>
<exclude>**/*.old</exclude>
<exclude>**/*.swp</exclude>
<exclude>**/*.debug</exclude>
<exclude>**/*.dump</exclude>
<exclude>**/*.log</exclude>
<exclude>**/~*</exclude>
<!-- common git/scm files -->
<exclude>**/*.orig</exclude>
<exclude>**/*.diff</exclude>
<exclude>**/*.patch</exclude>
<exclude>**/.gitignore</exclude>
<!-- various editor files -->
<exclude>**/*.iml</exclude>
<exclude>**/*.ipr</exclude>
<exclude>**/*.iws</exclude>
<exclude>**/*.idea</exclude>
<exclude>**/.classpath</exclude>
<exclude>**/.project</exclude>
<exclude>**/.settings</exclude>
<!-- maven dust -->
<exclude>**/*.versionsBackup</exclude>
<exclude>**/*.releaseBackup</exclude>
</excludes>
</fileSet>
</fileSets>

View File

@ -51,7 +51,7 @@ INFO: resources enabled in ${jetty.base}/start.ini
The replacement `logging.mod` performs a number of tasks.
. `mybase` is a `${jetty.base}` directory
. The jetty-distribution is unpacked (and untouched) into `/opt/jetty-dist/ `and becomes the `${jetty.home}` directory for this demonstration.
. The jetty-distribution is unpacked (and untouched) into `/opt/jetty-dist/` and becomes the `${jetty.home}` directory for this demonstration.
. The `curl` command downloads the replacement `logging.mod` and puts it into the `${jetty.base}/modules/` directory for use by `mybase` only.
. The `start.jar --add-to-start=logging` command performs a number of steps to make the logging module available to the `${jetty.base}` configuration.
.. The `--module=logging` command is added to the `${jetty.base}/start.ini` configuration.

View File

@ -81,7 +81,7 @@ INFO: resources enabled in ${jetty.base}/start.ini
The replacement `logging.mod` performs a number of tasks.
. `mybase` is a `${jetty.base}` directory.
. The jetty-distribution is unpacked (and untouched) into `/opt/jetty-dist/ `and becomes the `${jetty.home}` directory for this demonstration.
. The jetty-distribution is unpacked (and untouched) into `/opt/jetty-dist/` and becomes the `${jetty.home}` directory for this demonstration.
. The `curl` command downloads the replacement `logging.mod` and puts it into the `${jetty.base}/modules/` directory for use by mybase only.
. The `start.jar --add-to-start=logging,webapp-logging` command performs a number of steps to make the logging module available to the `${jetty.base}` configuration.
.. Several entries are added to the `${jetty.base}/start.ini` configuration.

View File

@ -47,7 +47,7 @@ DOWNLOAD: https://raw.githubusercontent.com/jetty-project/logging-modules/master
The replacement `logging.mod` performs a number of tasks.
. `mybase` is a `${jetty.base}` directory.
. The jetty-distribution is unpacked (and untouched) into `/opt/jetty-dist/ `and becomes the `${jetty.home}` directory for this demonstration.
. The jetty-distribution is unpacked (and untouched) into `/opt/jetty-dist/` and becomes the `${jetty.home}` directory for this demonstration.
. The `curl` command downloads the replacement `logging.mod` and puts it into the `${jetty.base}/modules/` directory for use by `mybase` only.
. The `start.jar --add-to-start=logging` command performs a number of steps to make the logging module available to the `${jetty.base}` configuration.
.. The `--module=logging` command is added to the `${jetty.base}/start.ini` configuration.

View File

@ -118,7 +118,7 @@ INFO: resources enabled in ${jetty.base}/start.ini
The replacement `logging.mod` performs a number of tasks.
. `mybase` is a `${jetty.base}` directory.
. The jetty-distribution is unpacked (and untouched) into `/opt/jetty-dist/ `and becomes the `${jetty.home}` directory for this demonstration.
. The jetty-distribution is unpacked (and untouched) into `/opt/jetty-dist/` and becomes the `${jetty.home}` directory for this demonstration.
. The `curl` command downloads the replacement `logging.mod` and puts it into the `${jetty.base}/modules/` directory for use by `mybase` only.
. The `start.jar --add-to-start=logging` command performs a number of steps to make the logging module available to the `${jetty.base}` configuration.
.. The `--module=logging` command is added to the `${jetty.base}/start.ini` configuration.

View File

@ -98,6 +98,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
public static final String EXPIRY = "expiry";
public static final String MAXINACTIVE = "maxInactive";
public static final String ATTRIBUTES = "attributes";
public static final String LASTSAVED = "lastSaved";
public static final String KIND = "GCloudSession";
protected String _kind = KIND;
@ -107,6 +108,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
protected String _accessed = ACCESSED;
protected String _lastAccessed = LASTACCESSED;
protected String _lastNode = LASTNODE;
protected String _lastSaved = LASTSAVED;
protected String _createTime = CREATETIME;
protected String _cookieSetTime = COOKIESETTIME;
protected String _expiry = EXPIRY;
@ -302,6 +304,23 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
_attributes = attributes;
}
/**
* @return the lastSaved
*/
public String getLastSaved()
{
return _lastSaved;
}
/**
* @param lastSaved the lastSaved to set
*/
public void setLastSaved(String lastSaved)
{
checkNotNull(lastSaved);
_lastSaved = lastSaved;
}
/**
* @see java.lang.Object#toString()
*/
@ -868,6 +887,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
.set(_model.getLastNode(),session.getLastNode())
.set(_model.getExpiry(), session.getExpiry())
.set(_model.getMaxInactive(), session.getMaxInactiveMs())
.set(_model.getLastSaved(), session.getLastSaved())
.set(_model.getAttributes(), BlobValue.newBuilder(Blob.copyFrom(baos.toByteArray())).setExcludeFromIndexes(true).build()).build();
@ -902,6 +922,17 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
long createTime = entity.getLong(_model.getCreateTime());
long cookieSet = entity.getLong(_model.getCookieSetTime());
String lastNode = entity.getString(_model.getLastNode());
long lastSaved = 0;
//for compatibility with previously saved sessions, lastSaved may not be present
try
{
lastSaved = entity.getLong(_model.getLastSaved());
}
catch (DatastoreException e)
{
LOG.ignore(e);
}
long expiry = entity.getLong(_model.getExpiry());
long maxInactive = entity.getLong(_model.getMaxInactive());
Blob blob = (Blob) entity.getBlob(_model.getAttributes());
@ -912,6 +943,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
session.setVhost(vhost);
session.setCookieSet(cookieSet);
session.setLastNode(lastNode);
session.setLastSaved(lastSaved);
session.setExpiry(expiry);
try (ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(blob.asInputStream()))
{

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.server;
package org.eclipse.jetty.http;
/**
* The compliance for Cookie handling.

View File

@ -0,0 +1,142 @@
//
// ========================================================================
// Copyright (c) 1995-2017 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.http;
import java.util.Objects;
/**
* Collection of Syntax validation methods.
* <p>
* Use in a similar way as you would {@link java.util.Objects#requireNonNull(Object)}
* </p>
*/
public final class Syntax
{
/**
* Per RFC2616: Section 2.2, a token follows these syntax rules
* <pre>
* token = 1*&lt;any CHAR except CTLs or separators&gt;
* CHAR = &lt;any US-ASCII character (octets 0 - 127)&gt;
* CTL = &lt;any US-ASCII control character
* (octets 0 - 31) and DEL (127)&gt;
* separators = "(" | ")" | "&lt;" | "&gt;" | "@"
* | "," | ";" | ":" | "\" | &lt;"&gt;
* | "/" | "[" | "]" | "?" | "="
* | "{" | "}" | SP | HT
* </pre>
*
* @param value the value to test
* @param msg the message to be prefixed if an {@link IllegalArgumentException} is thrown.
* @throws IllegalArgumentException if the value is invalid per spec
*/
public static void requireValidRFC2616Token(String value, String msg)
{
Objects.requireNonNull(msg, "msg cannot be null");
if (value == null)
{
return;
}
int valueLen = value.length();
if (valueLen == 0)
{
return;
}
for (int i = 0; i < valueLen; i++)
{
char c = value.charAt(i);
// 0x00 - 0x1F are low order control characters
// 0x7F is the DEL control character
if ((c <= 0x1F) || (c == 0x7F))
throw new IllegalArgumentException(msg + ": RFC2616 tokens may not contain control characters");
if (c == '(' || c == ')' || c == '<' || c == '>' || c == '@'
|| c == ',' || c == ';' || c == ':' || c == '\\' || c == '"'
|| c == '/' || c == '[' || c == ']' || c == '?' || c == '='
|| c == '{' || c == '}' || c == ' ')
{
throw new IllegalArgumentException(msg + ": RFC2616 tokens may not contain separator character: [" + c + "]");
}
if (c >= 0x80)
throw new IllegalArgumentException(msg + ": RFC2616 tokens characters restricted to US-ASCII: 0x" + Integer.toHexString(c));
}
}
/**
* Per RFC6265, Cookie.value follows these syntax rules
* <pre>
* cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE )
* cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E
* ; US-ASCII characters excluding CTLs,
* ; whitespace DQUOTE, comma, semicolon,
* ; and backslash
* </pre>
*
* @param value the value to test
* @throws IllegalArgumentException if the value is invalid per spec
*/
public static void requireValidRFC6265CookieValue(String value)
{
if (value == null)
{
return;
}
int valueLen = value.length();
if (valueLen == 0)
{
return;
}
int i = 0;
if (value.charAt(0) == '"')
{
// Has starting DQUOTE
if (valueLen <= 1 || (value.charAt(valueLen - 1) != '"'))
{
throw new IllegalArgumentException("RFC6265 Cookie values must have balanced DQUOTES (if used)");
}
// adjust search range to exclude DQUOTES
i++;
valueLen--;
}
for (; i < valueLen; i++)
{
char c = value.charAt(i);
// 0x00 - 0x1F are low order control characters
// 0x7F is the DEL control character
if ((c <= 0x1F) || (c == 0x7F))
throw new IllegalArgumentException("RFC6265 Cookie values may not contain control characters");
if ((c == ' ' /* 0x20 */) ||
(c == '"' /* 0x2C */) ||
(c == ';' /* 0x3B */) ||
(c == '\\' /* 0x5C */))
{
throw new IllegalArgumentException("RFC6265 Cookie values may not contain character: [" + c + "]");
}
if (c >= 0x80)
throw new IllegalArgumentException("RFC6265 Cookie values characters restricted to US-ASCII: 0x" + Integer.toHexString(c));
}
}
}

View File

@ -0,0 +1,134 @@
//
// ========================================================================
// Copyright (c) 1995-2017 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.http;
import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import org.junit.Test;
public class SyntaxTest
{
@Test
public void testRequireValidRFC2616Token_Good()
{
String tokens[] = {
"name",
"",
null,
"n.a.m.e",
"na-me",
"+name",
"na*me",
"na$me",
"#name"
};
for (String token : tokens)
{
Syntax.requireValidRFC2616Token(token, "Test Based");
// No exception should occur here
}
}
@Test
public void testRequireValidRFC2616Token_Bad()
{
String tokens[] = {
"\"name\"",
"name\t",
"na me",
"name\u0082",
"na\tme",
"na;me",
"{name}",
"[name]",
"\""
};
for (String token : tokens)
{
try
{
Syntax.requireValidRFC2616Token(token, "Test Based");
fail("RFC2616 Token [" + token + "] Should have thrown " + IllegalArgumentException.class.getName());
}
catch (IllegalArgumentException e)
{
assertThat("Testing Bad RFC2616 Token [" + token + "]", e.getMessage(),
allOf(containsString("Test Based"),
containsString("RFC2616")));
}
}
}
@Test
public void testRequireValidRFC6265CookieValue_Good()
{
String values[] = {
"value",
"",
null,
"val=ue",
"val-ue",
"\"value\"",
"val/ue",
"v.a.l.u.e"
};
for (String value : values)
{
Syntax.requireValidRFC6265CookieValue(value);
// No exception should occur here
}
}
@Test
public void testRequireValidRFC6265CookieValue_Bad()
{
String values[] = {
"va\tlue",
"\t",
"value\u0000",
"val\u0082ue",
"va lue",
"va;lue",
"\"value",
"value\"",
"val\\ue",
"val\"ue",
"\""
};
for (String value : values)
{
try
{
Syntax.requireValidRFC6265CookieValue(value);
fail("RFC6265 Cookie Value [" + value + "] Should have thrown " + IllegalArgumentException.class.getName());
}
catch (IllegalArgumentException e)
{
assertThat("Testing Bad RFC6265 Cookie Value [" + value + "]", e.getMessage(), containsString("RFC6265"));
}
}
}
}

View File

@ -117,6 +117,12 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
*/
public final static String __VERSION = __METADATA + ".version";
public final static String __LASTSAVED = __METADATA + ".lastSaved";
public final static String __LASTNODE = __METADATA + ".lastNode";
/**
* Last access time of session
*/
@ -202,8 +208,9 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
if (valid == null || !valid)
return;
Object version = getNestedValue(sessionDocument, getContextSubfield(__VERSION));
Long lastSaved = (Long)getNestedValue(sessionDocument, getContextSubfield(__LASTSAVED));
String lastNode = (String)getNestedValue(sessionDocument, getContextSubfield(__LASTNODE));
Long created = (Long)sessionDocument.get(__CREATED);
Long accessed = (Long)sessionDocument.get(__ACCESSED);
@ -228,6 +235,8 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
data.setExpiry(expiry);
data.setContextPath(_context.getCanonicalContextPath());
data.setVhost(_context.getVhost());
data.setLastSaved(lastSaved);
data.setLastNode(lastNode);
HashMap<String, Object> attributes = new HashMap<>();
for (String name : sessionSubDocumentForContext.keySet())
@ -449,12 +458,16 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
sets.put(__CREATED,nsqd.getCreated());
sets.put(__VALID,true);
sets.put(getContextSubfield(__VERSION),version);
sets.put(getContextSubfield(__LASTSAVED), data.getLastSaved());
sets.put(getContextSubfield(__LASTNODE), data.getLastNode());
sets.put(__MAX_IDLE, nsqd.getMaxInactiveMs());
sets.put(__EXPIRY, nsqd.getExpiry());
nsqd.setVersion(version);
}
else
{
sets.put(getContextSubfield(__LASTSAVED), data.getLastSaved());
sets.put(getContextSubfield(__LASTNODE), data.getLastNode());
version = new Long(((Number)version).longValue() + 1);
nsqd.setVersion(version);
update.put("$inc",_version_1);

View File

@ -90,7 +90,7 @@
<Set name="maxErrorDispatches"><Property name="jetty.httpConfig.maxErrorDispatches" default="10"/></Set>
<Set name="blockingTimeout"><Property name="jetty.httpConfig.blockingTimeout" default="-1"/></Set>
<Set name="persistentConnectionsEnabled"><Property name="jetty.httpConfig.persistentConnectionsEnabled" default="true"/></Set>
<Set name="cookieCompliance"><Call class="org.eclipse.jetty.server.CookieCompliance" name="valueOf"><Arg><Property name="jetty.httpConfig.cookieCompliance" default="RFC6265"/></Arg></Call></Set>
<Set name="cookieCompliance"><Call class="org.eclipse.jetty.http.CookieCompliance" name="valueOf"><Arg><Property name="jetty.httpConfig.cookieCompliance" default="RFC6265"/></Arg></Call></Set>
</New>
<!-- =========================================================== -->

View File

@ -23,6 +23,7 @@ import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import org.eclipse.jetty.http.CookieCompliance;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpScheme;
import org.eclipse.jetty.util.Jetty;

View File

@ -35,6 +35,7 @@ import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.eclipse.jetty.http.CookieCompliance;
import org.eclipse.jetty.http.DateGenerator;
import org.eclipse.jetty.http.HttpContent;
import org.eclipse.jetty.http.HttpCookie;
@ -50,6 +51,7 @@ import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.http.PreEncodedHttpField;
import org.eclipse.jetty.http.Syntax;
import org.eclipse.jetty.io.RuntimeIOException;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ErrorHandler;
@ -172,6 +174,11 @@ public class Response implements HttpServletResponse
public void addCookie(HttpCookie cookie)
{
if (StringUtil.isBlank(cookie.getName()))
{
throw new IllegalArgumentException("Cookie.name cannot be blank/null");
}
if (getHttpChannel().getHttpConfiguration().isCookieCompliance(CookieCompliance.RFC2965))
addSetRFC2965Cookie(
cookie.getName(),
@ -212,6 +219,11 @@ public class Response implements HttpServletResponse
}
}
if (StringUtil.isBlank(cookie.getName()))
{
throw new IllegalArgumentException("Cookie.name cannot be blank/null");
}
if (getHttpChannel().getHttpConfiguration().isCookieCompliance(CookieCompliance.RFC2965))
addSetRFC2965Cookie(cookie.getName(),
cookie.getValue(),
@ -259,10 +271,9 @@ public class Response implements HttpServletResponse
// Name is checked for legality by servlet spec, but can also be passed directly so check again for quoting
// Per RFC6265, Cookie.name follows RFC2616 Section 2.2 token rules
if(isQuoteNeededForCookie(name))
throw new IllegalArgumentException("Cookie name not RFC6265 compliant");
Syntax.requireValidRFC2616Token(name, "RFC6265 Cookie name");
// Ensure that Per RFC6265, Cookie.value follows syntax rules
assertRFC6265CookieValue(value);
Syntax.requireValidRFC6265CookieValue(value);
// Format value and params
StringBuilder buf = __cookieBuilder.get();
@ -306,64 +317,6 @@ public class Response implements HttpServletResponse
}
/**
* Per RFC6265, Cookie.value follows these syntax rules
* <pre>
* cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE )
* cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E
* ; US-ASCII characters excluding CTLs,
* ; whitespace DQUOTE, comma, semicolon,
* ; and backslash
* </pre>
* @param value the value to test
* @throws IllegalArgumentException if the value is invalid per spec
*/
public static void assertRFC6265CookieValue(String value)
{
if (value == null)
{
return;
}
int valueLen = value.length();
if (valueLen == 0)
{
return;
}
int i = 0;
if (value.charAt(0) == '"')
{
// Has starting DQUOTE
if (valueLen <= 1 || (value.charAt(valueLen - 1) != '"'))
{
throw new IllegalArgumentException("RFC6265 Cookie value must have balanced DQUOTES (if used)");
}
// adjust search range to exclude DQUOTES
i++;
valueLen--;
}
for(; i<valueLen; i++)
{
char c = value.charAt(i);
// 0x00 - 0x1F are low order control characters
// 0x7F is the DEL control character
if ((c <= 0x1F) || (c == 0x7F))
throw new IllegalArgumentException("Control characters not allowed in RFC6265 Cookie value");
if ((c == ' ' /* 0x20 */) ||
(c == '"' /* 0x2C */) ||
(c == ';' /* 0x3B */) ||
(c == '\\' /* 0x5C */))
{
throw new IllegalArgumentException("RFC6265 Cookie value may not contain character: [" + c + "]");
}
if (c >= 0x80)
throw new IllegalArgumentException("RFC6265 Cookie value characters restricted to US-ASCII range: 0x" + Integer.toHexString(c));
}
}
/**
* Format a set cookie value
*

View File

@ -196,6 +196,7 @@ public class FileSessionDataStore extends AbstractSessionDataStore
try (FileInputStream in = new FileInputStream(file))
{
SessionData data = load(in);
data.setLastSaved(file.lastModified());
//delete restored file
file.delete();
reference.set(data);

View File

@ -18,6 +18,8 @@
package org.eclipse.jetty.server;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
@ -29,19 +31,18 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static java.nio.charset.StandardCharsets.UTF_8;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.PrintWriter;
import java.net.HttpCookie;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.HttpCookie;
import java.net.Socket;
import java.net.UnknownHostException;
import java.net.URLEncoder;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
@ -56,7 +57,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.eclipse.jetty.http.HttpCompliance;
import org.eclipse.jetty.http.CookieCompliance;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
@ -69,8 +70,8 @@ import org.eclipse.jetty.io.RuntimeIOException;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ErrorHandler;
import org.eclipse.jetty.server.session.DefaultSessionIdManager;
import org.eclipse.jetty.server.session.DefaultSessionCache;
import org.eclipse.jetty.server.session.DefaultSessionIdManager;
import org.eclipse.jetty.server.session.NullSessionDataStore;
import org.eclipse.jetty.server.session.Session;
import org.eclipse.jetty.server.session.SessionData;
@ -178,6 +179,7 @@ public class ResponseTest
_server.join();
}
@SuppressWarnings("InjectedReferences") // to allow for invalid encoding strings in this testcase
@Test
public void testContentType() throws Exception
{
@ -1185,15 +1187,31 @@ public class ResponseTest
assertEquals("everything=value;Expires=Thu, 01-Jan-1970 00:00:00 GMT;Max-Age=0;Secure;HttpOnly",e.nextElement());
assertFalse(e.hasMoreElements());
fields.clear();
String badNameExamples[] = {
"\"name\"",
"name\t",
"na me",
"name\u0082",
"na\tme",
"na;me",
"{name}",
"[name]",
"\""
};
try
for (String badNameExample : badNameExamples)
{
response.addSetRFC6265Cookie("ev erything","va lue","do main","pa th",1,true,true);
}
catch(IllegalArgumentException ex)
{
assertThat(ex.getMessage(),Matchers.containsString("RFC6265"));
fields.clear();
try
{
response.addSetRFC6265Cookie(badNameExample, "value", null, "/", 1, true, true);
}
catch (IllegalArgumentException ex)
{
// System.err.printf("%s: %s%n", ex.getClass().getSimpleName(), ex.getMessage());
assertThat("Testing bad name: [" + badNameExample + "]", ex.getMessage(),
allOf(containsString("RFC6265"), containsString("RFC2616")));
}
}
String badValueExamples[] = {
@ -1219,11 +1237,27 @@ public class ResponseTest
}
catch (IllegalArgumentException ex)
{
// System.err.printf("%s: %s%n", ex.getClass().getSimpleName(), ex.getMessage());
assertThat("Testing bad value [" + badValueExample + "]", ex.getMessage(), Matchers.containsString("RFC6265"));
}
}
fields.clear();
String goodNameExamples[] = {
"name",
"n.a.m.e",
"na-me",
"+name",
"na*me",
"na$me",
"#name"
};
for (String goodNameExample : goodNameExamples)
{
fields.clear();
response.addSetRFC6265Cookie(goodNameExample, "value", null, "/", 1, true, true);
// should not throw an exception
}
String goodValueExamples[] = {
"value",
@ -1239,6 +1273,7 @@ public class ResponseTest
{
fields.clear();
response.addSetRFC6265Cookie("name", goodValueExample, null, "/", 1, true, true);
// should not throw an exception
}
fields.clear();