Merged branch 'jetty-9.4.x' into 'jetty-9.4.x-3978-http2_vulnerabilities'.

This commit is contained in:
Simone Bordet 2019-09-05 23:12:35 +02:00
commit 4e67e8594e
329 changed files with 7944 additions and 4170 deletions

3
Jenkinsfile vendored
View File

@ -111,7 +111,6 @@ pipeline {
}
}
def slackNotif() {
script {
try
@ -132,7 +131,6 @@ def slackNotif() {
}
}
/**
* To other developers, if you are using this method above, please use the following syntax.
*
@ -158,4 +156,5 @@ def mavenBuild(jdk, cmdline, mvnName, junitPublishDisabled) {
}
}
// vim: et:ts=2:sw=2:ft=groovy

View File

@ -38,7 +38,7 @@ import javax.servlet.http.HttpSession;
@WebFilter(filterName = "CFilter", dispatcherTypes = {DispatcherType.REQUEST}, urlPatterns = {"/*"}, initParams = {
@WebInitParam(name = "a", value = "99")
}, asyncSupported = false)
}, asyncSupported = false)
@RunAs("admin")
public class FilterC implements Filter
{

View File

@ -38,7 +38,7 @@ import javax.servlet.http.HttpServletResponse;
@DeclareRoles({"alice"})
@WebServlet(urlPatterns = {"/foo/*", "/bah/*"}, name = "CServlet", initParams = {
@WebInitParam(name = "x", value = "y")
}, loadOnStartup = 2, asyncSupported = false)
}, loadOnStartup = 2, asyncSupported = false)
@MultipartConfig(fileSizeThreshold = 1000, maxFileSize = 2000, maxRequestSize = 3000)
@RunAs("admin")
@ServletSecurity(value = @HttpConstraint(rolesAllowed = {"fred", "bill", "dorothy"}), httpMethodConstraints = {

View File

@ -24,8 +24,8 @@ import javax.servlet.http.HttpServlet;
@WebServlet(urlPatterns = {"/", "/bah/*"}, name = "DServlet", initParams = {
@WebInitParam(name = "x", value = "y")
}, loadOnStartup = 1, asyncSupported = false)
}, loadOnStartup = 1, asyncSupported = false)
public class ServletD extends HttpServlet
{
// no op
}

View File

@ -63,16 +63,14 @@ public class TestSecurityAnnotationConversions
@ServletSecurity(value = @HttpConstraint(value = EmptyRoleSemantic.PERMIT, transportGuarantee = TransportGuarantee.CONFIDENTIAL, rolesAllowed = {
"tom", "dick", "harry"
}), httpMethodConstraints =
{@HttpMethodConstraint(value = "GET")})
}), httpMethodConstraints = {@HttpMethodConstraint(value = "GET")})
public static class Method1Servlet extends HttpServlet
{
}
@ServletSecurity(value = @HttpConstraint(value = EmptyRoleSemantic.PERMIT, transportGuarantee = TransportGuarantee.CONFIDENTIAL, rolesAllowed = {
"tom", "dick", "harry"
}), httpMethodConstraints =
{@HttpMethodConstraint(value = "GET", transportGuarantee = TransportGuarantee.CONFIDENTIAL)})
}), httpMethodConstraints = {@HttpMethodConstraint(value = "GET", transportGuarantee = TransportGuarantee.CONFIDENTIAL)})
public static class Method2Servlet extends HttpServlet
{
}
@ -175,7 +173,7 @@ public class TestSecurityAnnotationConversions
public void testMethodAnnotation() throws Exception
{
//ServletSecurity annotation with HttpConstraint of TransportGuarantee.CONFIDENTIAL, and a list of rolesAllowed, and
//a HttpMethodConstraint for GET method that permits all and has TransportGuarantee.NONE (ie is default)
//an HttpMethodConstraint for GET method that permits all and has TransportGuarantee.NONE (ie is default)
WebAppContext wac = makeWebAppContext(Method1Servlet.class.getCanonicalName(), "method1Servlet", new String[]{
"/foo/*", "*.foo"

View File

@ -171,7 +171,8 @@ public class AntBuild
Matcher mat = pat.getMatcher(line);
if (mat.find())
{
int num = 0, count = mat.groupCount();
int num = 0;
int count = mat.groupCount();
String[] match = new String[count];
while (num++ < count)
{

View File

@ -28,7 +28,7 @@ import org.eclipse.jetty.io.ClientConnectionFactory;
* in order to plug-in a different transport for {@link HttpClient}.
* <p>
* While the {@link HttpClient} APIs define the HTTP semantic (request, response, headers, etc.)
* <em>how</em> a HTTP exchange is carried over the network depends on implementations of this class.
* <em>how</em> an HTTP exchange is carried over the network depends on implementations of this class.
* <p>
* The default implementation uses the HTTP protocol to carry over the network the HTTP exchange,
* but the HTTP exchange may also be carried using the FCGI protocol, the HTTP/2 protocol or,

View File

@ -32,7 +32,7 @@ import org.eclipse.jetty.util.log.Logger;
/**
* {@link HttpContent} is a stateful, linear representation of the request content provided
* by a {@link ContentProvider} that can be traversed one-way to obtain content buffers to
* send to a HTTP server.
* send to an HTTP server.
* <p>
* {@link HttpContent} offers the notion of a one-way cursor to traverse the content.
* The cursor starts in a virtual "before" position and can be advanced using {@link #advance()}

View File

@ -51,7 +51,7 @@ import org.eclipse.jetty.util.log.Logger;
* <ol>
* <li>{@link #responseBegin(HttpExchange)}, when the HTTP response data containing the HTTP status code
* is available</li>
* <li>{@link #responseHeader(HttpExchange, HttpField)}, when a HTTP field is available</li>
* <li>{@link #responseHeader(HttpExchange, HttpField)}, when an HTTP field is available</li>
* <li>{@link #responseHeaders(HttpExchange)}, when all HTTP headers are available</li>
* <li>{@link #responseContent(HttpExchange, ByteBuffer, Callback)}, when HTTP content is available</li>
* <li>{@link #responseSuccess(HttpExchange)}, when the response is successful</li>

View File

@ -82,7 +82,7 @@ public class HttpRedirector
/**
* @param response the response to check for redirects
* @return whether the response code is a HTTP redirect code
* @return whether the response code is an HTTP redirect code
*/
public boolean isRedirect(Response response)
{

View File

@ -869,7 +869,7 @@ public class HttpRequest implements Request
}
catch (URISyntaxException x)
{
// The "path" of a HTTP request may not be a URI,
// The "path" of an HTTP request may not be a URI,
// for example for CONNECT 127.0.0.1:8080.
return null;
}

View File

@ -40,7 +40,7 @@ import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.util.Fields;
/**
* <p>{@link Request} represents a HTTP request, and offers a fluent interface to customize
* <p>{@link Request} represents an HTTP request, and offers a fluent interface to customize
* various attributes such as the path, the headers, the content, etc.</p>
* <p>You can create {@link Request} objects via {@link HttpClient#newRequest(String)} and
* you can send them using either {@link #send()} for a blocking semantic, or

View File

@ -29,7 +29,7 @@ import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.util.Callback;
/**
* <p>{@link Response} represents a HTTP response and offers methods to retrieve status code, HTTP version
* <p>{@link Response} represents an HTTP response and offers methods to retrieve status code, HTTP version
* and headers.</p>
* <p>{@link Response} objects are passed as parameters to {@link Response.Listener} callbacks, or as
* future result of {@link Request#send()}.</p>

View File

@ -161,7 +161,7 @@ public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.Res
}
/**
* Parses a HTTP response in the receivers buffer.
* Parses an HTTP response in the receivers buffer.
*
* @return true to indicate that parsing should be interrupted (and will be resumed by another thread).
*/

View File

@ -100,7 +100,7 @@ public class HostnameVerificationTest
/**
* This test is supposed to verify that hostname verification works as described in:
* http://www.ietf.org/rfc/rfc2818.txt section 3.1. It uses a certificate with a common name different to localhost
* and sends a request to localhost. This should fail with a SSLHandshakeException.
* and sends a request to localhost. This should fail with an SSLHandshakeException.
*
* @throws Exception on test failure
*/

View File

@ -657,10 +657,10 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest
assertEquals("1523430383", headerInfo.getParameter("nonce"));
// test multiple authentications
List<HeaderInfo> headerInfoList = aph.getHeaderInfo("Digest qop=\"auth\", realm=\"thermostat\", nonce=\"1523430383\", "
+ "Digest realm=\"thermostat2\", qop=\"auth2\", nonce=\"4522530354\", "
+ "Digest qop=\"auth3\", nonce=\"9523570528\", realm=\"thermostat3\", "
+ "Digest qop=\"auth4\", nonce=\"3526435321\"");
List<HeaderInfo> headerInfoList = aph.getHeaderInfo("Digest qop=\"auth\", realm=\"thermostat\", nonce=\"1523430383\", " +
"Digest realm=\"thermostat2\", qop=\"auth2\", nonce=\"4522530354\", " +
"Digest qop=\"auth3\", nonce=\"9523570528\", realm=\"thermostat3\", " +
"Digest qop=\"auth4\", nonce=\"3526435321\"");
assertTrue(headerInfoList.get(0).getType().equalsIgnoreCase("Digest"));
assertEquals("auth", headerInfoList.get(0).getParameter("qop"));
@ -744,8 +744,8 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest
assertTrue(headerInfo.getType().equalsIgnoreCase("Negotiate"));
assertEquals("TlRMTVNTUAABAAAAB4IIogAAAAAAAAAAAAAAAAAAAAAFAs4OAAAADw==", headerInfo.getBase64());
headerInfos = aph.getHeaderInfo("Negotiate TlRMTVNTUAABAAAAAAAAAFAs4OAAAADw==, "
+ "Negotiate YIIJvwYGKwYBBQUCoIIJszCCCa+gJDAi=");
headerInfos = aph.getHeaderInfo("Negotiate TlRMTVNTUAABAAAAAAAAAFAs4OAAAADw==, " +
"Negotiate YIIJvwYGKwYBBQUCoIIJszCCCa+gJDAi=");
assertTrue(headerInfos.get(0).getType().equalsIgnoreCase("Negotiate"));
assertEquals("TlRMTVNTUAABAAAAAAAAAFAs4OAAAADw==", headerInfos.get(0).getBase64());
@ -766,9 +766,9 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest
assertEquals("=1523430383=", headerInfo.getParameter("nonce"));
// test multiple authentications
List<HeaderInfo> headerInfoList = aph.getHeaderInfo("Digest qop=\"=au=th=\", realm=\"=ther=mostat=\", nonce=\"=152343=0383=\", "
+ "Digest realm=\"=thermostat2\", qop=\"=auth2\", nonce=\"=4522530354\", "
+ "Digest qop=\"auth3=\", nonce=\"9523570528=\", realm=\"thermostat3=\", ");
List<HeaderInfo> headerInfoList = aph.getHeaderInfo("Digest qop=\"=au=th=\", realm=\"=ther=mostat=\", nonce=\"=152343=0383=\", " +
"Digest realm=\"=thermostat2\", qop=\"=auth2\", nonce=\"=4522530354\", " +
"Digest qop=\"auth3=\", nonce=\"9523570528=\", realm=\"thermostat3=\", ");
assertTrue(headerInfoList.get(0).getType().equalsIgnoreCase("Digest"));
assertEquals("=au=th=", headerInfoList.get(0).getParameter("qop"));

View File

@ -67,6 +67,8 @@ public class HttpClientTLSTest
private ServerConnector connector;
private HttpClient client;
private SSLSocket sslSocket;
private void startServer(SslContextFactory sslContextFactory, Handler handler) throws Exception
{
ExecutorThreadPool serverThreads = new ExecutorThreadPool();
@ -419,7 +421,7 @@ public class HttpClientTLSTest
String host = "localhost";
int port = connector.getLocalPort();
Socket socket = new Socket(host, port);
SSLSocket sslSocket = (SSLSocket)clientTLSFactory.getSslContext().getSocketFactory().createSocket(socket, host, port, true);
sslSocket = (SSLSocket)clientTLSFactory.getSslContext().getSocketFactory().createSocket(socket, host, port, true);
CountDownLatch handshakeLatch1 = new CountDownLatch(1);
AtomicReference<byte[]> session1 = new AtomicReference<>();
sslSocket.addHandshakeCompletedListener(event ->
@ -432,14 +434,12 @@ public class HttpClientTLSTest
// In TLS 1.3 the server sends a NewSessionTicket post-handshake message
// to enable session resumption and without a read, the message is not processed.
try
assertThrows(SocketTimeoutException.class, () ->
{
sslSocket.setSoTimeout(1000);
sslSocket.getInputStream().read();
}
catch (SocketTimeoutException expected)
{
}
});
// The client closes abruptly.
socket.close();

View File

@ -1810,7 +1810,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
}
}
public static abstract class RetryListener implements Response.CompleteListener
public abstract static class RetryListener implements Response.CompleteListener
{
private final HttpClient client;
private final String scheme;

View File

@ -494,7 +494,7 @@ public class HttpConnectionLifecycleTest extends AbstractHttpClientServerTest
.scheme(scenario.getScheme())
.onResponseBegin(response1 ->
{
// Simulate a HTTP 1.0 response has been received.
// Simulate an HTTP 1.0 response has been received.
((HttpResponse)response1).version(HttpVersion.HTTP_1_0);
})
.send();

View File

@ -45,8 +45,8 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNotSame;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
public class HttpDestinationOverHTTPTest extends AbstractHttpClientServerTest
{
@ -298,14 +298,7 @@ public class HttpDestinationOverHTTPTest extends AbstractHttpClientServerTest
server.stop();
Request request = client.newRequest(host, port).scheme(scenario.getScheme());
try
{
request.send();
fail("Request to a closed port must fail");
}
catch (Exception expected)
{
}
assertThrows(Exception.class, () -> request.send());
long deadline = System.nanoTime() + TimeUnit.SECONDS.toNanos(1);
while (!client.getDestinations().isEmpty() && System.nanoTime() < deadline)

View File

@ -1397,6 +1397,7 @@ public class SslBytesServerTest extends SslBytesTest
{
case APPLICATION:
fail("application data not allows after renegotiate");
return; // this is just to avoid checkstyle warning
case ALERT:
break loop;
default:
@ -1802,7 +1803,7 @@ public class SslBytesServerTest extends SslBytesTest
assertTrue(latch.await(idleTimeout * 2, TimeUnit.MILLISECONDS));
// Be sure that the server sent a SSL close alert
// Be sure that the server sent an SSL close alert
TLSRecord record = proxy.readFromServer();
assertNotNull(record);
assertEquals(TLSRecord.Type.ALERT, record.getType());

View File

@ -435,7 +435,7 @@ public class MultiPartContentProviderTest extends AbstractHttpClientServerTest
assertTrue(responseLatch.await(5, TimeUnit.SECONDS));
}
private static abstract class AbstractMultiPartHandler extends AbstractHandler
private abstract static class AbstractMultiPartHandler extends AbstractHandler
{
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException

View File

@ -26,7 +26,7 @@ import javax.servlet.ServletResponseWrapper;
/**
* Continuation.
* <p>
* A continuation is a mechanism by which a HTTP Request can be suspended and
* A continuation is a mechanism by which an HTTP Request can be suspended and
* restarted after a timeout or an asynchronous event has occurred.
* <p>
* The continuation mechanism is a portable mechanism that will work

View File

@ -1,10 +1,10 @@
<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<!-- ============================================================= --><!-- Configure the Jetty Server instance with an ID "Server" --><!-- by adding a HTTP connector. --><!-- This configuration must be used in conjunction with jetty.xml --><!-- ============================================================= -->
<!-- ============================================================= --><!-- Configure the Jetty Server instance with an ID "Server" --><!-- by adding an HTTP connector. --><!-- This configuration must be used in conjunction with jetty.xml --><!-- ============================================================= -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<!-- =========================================================== -->
<!-- Add a HTTP Connector. -->
<!-- Add an HTTP Connector. -->
<!-- Configure an o.e.j.server.ServerConnector with a single -->
<!-- HttpConnectionFactory instance using the common httpConfig -->
<!-- instance defined in jetty.xml -->

View File

@ -743,7 +743,7 @@ If you are using Conscrypt with Java 8, you must exclude `TLSv1.3` protocol as i
==== Configuring SNI
From Java 8, the JVM contains support for the http://en.wikipedia.org/wiki/Server_Name_Indication[Server Name Indicator (SNI)] extension, which allows a SSL connection handshake to indicate one or more DNS names that it applies to.
From Java 8, the JVM contains support for the http://en.wikipedia.org/wiki/Server_Name_Indication[Server Name Indicator (SNI)] extension, which allows an SSL connection handshake to indicate one or more DNS names that it applies to.
To support this, the `SslContextFactory` is used.
The `SslContextFactory` will look for multiple X509 certificates within the keystore, each of which may have multiple DNS names (including wildcards) associated with the http://en.wikipedia.org/wiki/SubjectAltName[Subject Alternate Name] extension.

View File

@ -44,7 +44,7 @@ import org.eclipse.jetty.util.ProcessorUtils;
/**
* Specific implementation of {@link org.eclipse.jetty.proxy.AsyncProxyServlet.Transparent} for FastCGI.
* <p>
* This servlet accepts a HTTP request and transforms it into a FastCGI request
* This servlet accepts an HTTP request and transforms it into a FastCGI request
* that is sent to the FastCGI server specified in the {@code proxyTo}
* init-param.
* <p>

View File

@ -21,7 +21,7 @@ package org.eclipse.jetty.http;
import org.eclipse.jetty.util.HostPort;
/**
* A HttpField holding a preparsed Host and port number
* An HttpField holding a preparsed Host and port number
*
* @see HostPort
*/

View File

@ -22,6 +22,7 @@ import java.util.List;
import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.util.QuotedStringTokenizer;
import org.eclipse.jetty.util.StringUtil;
// TODO consider replacing this with java.net.HttpCookie
public class HttpCookie
@ -29,6 +30,35 @@ public class HttpCookie
private static final String __COOKIE_DELIM = "\",;\\ \t";
private static final String __01Jan1970_COOKIE = DateGenerator.formatCookieDate(0).trim();
/**
*If this string is found within the comment parsed with {@link #isHttpOnlyInComment(String)} the check will return true
**/
private static final String HTTP_ONLY_COMMENT = "__HTTP_ONLY__";
/**
*These strings are used by {@link #getSameSiteFromComment(String)} to check for a SameSite specifier in the comment
**/
private static final String SAME_SITE_COMMENT = "__SAME_SITE_";
private static final String SAME_SITE_NONE_COMMENT = SAME_SITE_COMMENT + "NONE__";
private static final String SAME_SITE_LAX_COMMENT = SAME_SITE_COMMENT + "LAX__";
private static final String SAME_SITE_STRICT_COMMENT = SAME_SITE_COMMENT + "STRICT__";
public enum SameSite
{
NONE("None"), STRICT("Strict"), LAX("Lax");
private String attributeValue;
SameSite(String attributeValue)
{
this.attributeValue = attributeValue;
}
public String getAttributeValue()
{
return this.attributeValue;
}
}
private final String _name;
private final String _value;
private final String _comment;
@ -39,6 +69,7 @@ public class HttpCookie
private final int _version;
private final boolean _httpOnly;
private final long _expiration;
private final SameSite _sameSite;
public HttpCookie(String name, String value)
{
@ -61,6 +92,11 @@ public class HttpCookie
}
public HttpCookie(String name, String value, String domain, String path, long maxAge, boolean httpOnly, boolean secure, String comment, int version)
{
this(name, value, domain, path, maxAge, httpOnly, secure, comment, version, null);
}
public HttpCookie(String name, String value, String domain, String path, long maxAge, boolean httpOnly, boolean secure, String comment, int version, SameSite sameSite)
{
_name = name;
_value = value;
@ -72,6 +108,7 @@ public class HttpCookie
_comment = comment;
_version = version;
_expiration = maxAge < 0 ? -1 : System.nanoTime() + TimeUnit.SECONDS.toNanos(maxAge);
_sameSite = sameSite;
}
public HttpCookie(String setCookie)
@ -92,6 +129,8 @@ public class HttpCookie
_comment = cookie.getComment();
_version = cookie.getVersion();
_expiration = _maxAge < 0 ? -1 : System.nanoTime() + TimeUnit.SECONDS.toNanos(_maxAge);
// support for SameSite values has not yet been added to java.net.HttpCookie
_sameSite = getSameSiteFromComment(cookie.getComment());
}
/**
@ -158,6 +197,14 @@ public class HttpCookie
return _version;
}
/**
* @return the cookie SameSite enum attribute
*/
public SameSite getSameSite()
{
return _sameSite;
}
/**
* @return whether the cookie is valid for the http protocol only
*/
@ -366,9 +413,58 @@ public class HttpCookie
buf.append("; Secure");
if (_httpOnly)
buf.append("; HttpOnly");
if (_sameSite != null)
{
buf.append("; SameSite=");
buf.append(_sameSite.getAttributeValue());
}
return buf.toString();
}
public static boolean isHttpOnlyInComment(String comment)
{
return comment != null && comment.contains(HTTP_ONLY_COMMENT);
}
public static SameSite getSameSiteFromComment(String comment)
{
if (comment != null)
{
if (comment.contains(SAME_SITE_NONE_COMMENT))
{
return SameSite.NONE;
}
if (comment.contains(SAME_SITE_LAX_COMMENT))
{
return SameSite.LAX;
}
if (comment.contains(SAME_SITE_STRICT_COMMENT))
{
return SameSite.STRICT;
}
}
return null;
}
public static String getCommentWithoutAttributes(String comment)
{
if (comment == null)
{
return null;
}
String strippedComment = comment.trim();
strippedComment = StringUtil.strip(strippedComment, HTTP_ONLY_COMMENT);
strippedComment = StringUtil.strip(strippedComment, SAME_SITE_NONE_COMMENT);
strippedComment = StringUtil.strip(strippedComment, SAME_SITE_LAX_COMMENT);
strippedComment = StringUtil.strip(strippedComment, SAME_SITE_STRICT_COMMENT);
return strippedComment.length() == 0 ? null : strippedComment;
}
public static class SetCookieHttpField extends HttpField
{
final HttpCookie _cookie;

View File

@ -23,7 +23,7 @@ import java.util.Objects;
import org.eclipse.jetty.util.StringUtil;
/**
* A HTTP Field
* An HTTP Field
*/
public class HttpField
{
@ -37,7 +37,10 @@ public class HttpField
public HttpField(HttpHeader header, String name, String value)
{
_header = header;
_name = name;
if (_header != null && name == null)
_name = _header.asString();
else
_name = Objects.requireNonNull(name);
_value = value;
}
@ -325,8 +328,6 @@ public class HttpField
return false;
if (!_name.equalsIgnoreCase(field.getName()))
return false;
if (_value == null && field.getValue() != null)
return false;
return Objects.equals(_value, field.getValue());
}

View File

@ -48,7 +48,7 @@ public enum HttpMethod
* @param bytes Array containing ISO-8859-1 characters
* @param position The first valid index
* @param limit The first non valid index
* @return A HttpMethod if a match or null if no easy match.
* @return An HttpMethod if a match or null if no easy match.
*/
public static HttpMethod lookAheadGet(byte[] bytes, final int position, int limit)
{
@ -110,7 +110,7 @@ public enum HttpMethod
* Optimized lookup to find a method name and trailing space in a byte array.
*
* @param buffer buffer containing ISO-8859-1 characters, it is not modified.
* @return A HttpMethod if a match or null if no easy match.
* @return An HttpMethod if a match or null if no easy match.
*/
public static HttpMethod lookAheadGet(ByteBuffer buffer)
{

View File

@ -477,7 +477,7 @@ public class HttpParser
return t;
}
/* Quick lookahead for the start state looking for a request method or a HTTP version,
/* Quick lookahead for the start state looking for a request method or an HTTP version,
* otherwise skip white space until something else to parse.
*/
private boolean quickStart(ByteBuffer buffer)
@ -1873,14 +1873,14 @@ public class HttpParser
boolean messageComplete();
/**
* This is the method called by parser when a HTTP Header name and value is found
* This is the method called by parser when an HTTP Header name and value is found
*
* @param field The field parsed
*/
void parsedHeader(HttpField field);
/**
* This is the method called by parser when a HTTP Trailer name and value is found
* This is the method called by parser when an HTTP Trailer name and value is found
*
* @param field The field parsed
*/
@ -1890,7 +1890,7 @@ public class HttpParser
/**
* Called to signal that an EOF was received unexpectedly
* during the parsing of a HTTP message
* during the parsing of an HTTP message
*/
void earlyEOF();

View File

@ -320,6 +320,20 @@ public class HttpStatus
}
}
public static boolean hasNoBody(int status)
{
switch (status)
{
case NO_CONTENT_204:
case NOT_MODIFIED_304:
case PARTIAL_CONTENT_206:
return true;
default:
return status < OK_200;
}
}
/**
* Simple test against an code to determine if it falls into the
* <code>Informational</code> message category as defined in the <a

View File

@ -31,7 +31,7 @@ import org.eclipse.jetty.util.UrlEncoded;
/**
* Http URI.
* Parse a HTTP URI from a string or byte array. Given a URI
* Parse an HTTP URI from a string or byte array. Given a URI
* <code>http://user@host:port/path/info;param?query#fragment</code>
* this class will split it into the following undecoded optional elements:<ul>
* <li>{@link #getScheme()} - http:</li>

View File

@ -42,12 +42,12 @@ public enum HttpVersion
}
/**
* Optimised lookup to find a Http Version and whitespace in a byte array.
* Optimised lookup to find an Http Version and whitespace in a byte array.
*
* @param bytes Array containing ISO-8859-1 characters
* @param position The first valid index
* @param limit The first non valid index
* @return A HttpMethod if a match or null if no easy match.
* @return An HttpMethod if a match or null if no easy match.
*/
public static HttpVersion lookAheadGet(byte[] bytes, int position, int limit)
{
@ -84,10 +84,10 @@ public enum HttpVersion
}
/**
* Optimised lookup to find a HTTP Version and trailing white space in a byte array.
* Optimised lookup to find an HTTP Version and trailing white space in a byte array.
*
* @param buffer buffer containing ISO-8859-1 characters
* @return A HttpVersion if a match or null if no easy match.
* @return An HttpVersion if a match or null if no easy match.
*/
public static HttpVersion lookAheadGet(ByteBuffer buffer)
{

View File

@ -205,7 +205,8 @@ public class MultiPartFormInputStream
@Override
public Collection<String> getHeaders(String name)
{
return _headers.getValues(name);
Collection<String> headers = _headers.getValues(name);
return headers == null ? Collections.emptyList() : headers;
}
@Override

View File

@ -29,7 +29,7 @@ import org.eclipse.jetty.util.log.Logger;
/**
* Pre encoded HttpField.
* <p>A HttpField that will be cached and used many times can be created as
* <p>An HttpField that will be cached and used many times can be created as
* a {@link PreEncodedHttpField}, which will use the {@link HttpFieldPreEncoder}
* instances discovered by the {@link ServiceLoader} to pre-encode the header
* for each version of HTTP in use. This will save garbage

View File

@ -25,6 +25,9 @@ import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.containsString;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
public class HttpCookieTest
@ -90,6 +93,16 @@ public class HttpCookieTest
httpCookie = new HttpCookie("everything", "value", "domain", "path", 0, true, true, null, -1);
assertEquals("everything=value; Path=path; Domain=domain; Expires=Thu, 01-Jan-1970 00:00:00 GMT; Max-Age=0; Secure; HttpOnly", httpCookie.getRFC6265SetCookie());
httpCookie = new HttpCookie("everything", "value", "domain", "path", 0, true, true, null, -1, HttpCookie.SameSite.NONE);
assertEquals("everything=value; Path=path; Domain=domain; Expires=Thu, 01-Jan-1970 00:00:00 GMT; Max-Age=0; Secure; HttpOnly; SameSite=None", httpCookie.getRFC6265SetCookie());
httpCookie = new HttpCookie("everything", "value", "domain", "path", 0, true, true, null, -1, HttpCookie.SameSite.LAX);
assertEquals("everything=value; Path=path; Domain=domain; Expires=Thu, 01-Jan-1970 00:00:00 GMT; Max-Age=0; Secure; HttpOnly; SameSite=Lax", httpCookie.getRFC6265SetCookie());
httpCookie = new HttpCookie("everything", "value", "domain", "path", 0, true, true, null, -1, HttpCookie.SameSite.STRICT);
assertEquals("everything=value; Path=path; Domain=domain; Expires=Thu, 01-Jan-1970 00:00:00 GMT; Max-Age=0; Secure; HttpOnly; SameSite=Strict", httpCookie.getRFC6265SetCookie());
String[] badNameExamples = {
"\"name\"",
"name\t",
@ -179,4 +192,30 @@ public class HttpCookieTest
// should not throw an exception
}
}
@Test
public void testGetHttpOnlyFromComment()
{
assertTrue(HttpCookie.isHttpOnlyInComment("__HTTP_ONLY__"));
assertTrue(HttpCookie.isHttpOnlyInComment("__HTTP_ONLY__comment"));
assertFalse(HttpCookie.isHttpOnlyInComment("comment"));
}
@Test
public void testGetSameSiteFromComment()
{
assertEquals(HttpCookie.getSameSiteFromComment("__SAME_SITE_NONE__"), HttpCookie.SameSite.NONE);
assertEquals(HttpCookie.getSameSiteFromComment("__SAME_SITE_LAX__"), HttpCookie.SameSite.LAX);
assertEquals(HttpCookie.getSameSiteFromComment("__SAME_SITE_STRICT__"), HttpCookie.SameSite.STRICT);
assertEquals(HttpCookie.getSameSiteFromComment("__SAME_SITE_NONE____SAME_SITE_STRICT__"), HttpCookie.SameSite.NONE);
assertNull(HttpCookie.getSameSiteFromComment("comment"));
}
@Test
public void getCommentWithoutAttributes()
{
assertEquals(HttpCookie.getCommentWithoutAttributes("comment__SAME_SITE_NONE__"), "comment");
assertEquals(HttpCookie.getCommentWithoutAttributes("comment__HTTP_ONLY____SAME_SITE_NONE__"), "comment");
assertNull(HttpCookie.getCommentWithoutAttributes("__SAME_SITE_LAX__"));
}
}

View File

@ -30,6 +30,8 @@ import java.util.NoSuchElementException;
import org.eclipse.jetty.util.BufferUtil;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
@ -666,6 +668,41 @@ public class HttpFieldsTest
assertFalse(header.containsKey("n11"));
}
@ParameterizedTest
@ValueSource(strings = {"Host", "host", "HOST", "HoSt", "Connection", "CONNECTION", "connection", "CoNnEcTiOn"})
public void testContainsKeyTrue(String keyName)
{
HttpFields fields = new HttpFields();
fields.put("Host", "localhost");
HttpField namelessField = new HttpField(HttpHeader.CONNECTION, null, "bogus");
fields.put(namelessField);
assertTrue(fields.containsKey(keyName), "containsKey('" + keyName + "')");
}
@ParameterizedTest
@ValueSource(strings = {"Content-Type", "Content-Length", "X-Bogus", ""})
public void testContainsKeyFalse(String keyName)
{
HttpFields fields = new HttpFields();
fields.add("Host", "localhost");
HttpField namelessField = new HttpField(HttpHeader.CONNECTION, null, "bogus");
fields.put(namelessField);
assertFalse(fields.containsKey(keyName), "containsKey('" + keyName + "')");
}
@Test
public void testPreventNullField()
{
HttpFields fields = new HttpFields();
assertThrows(NullPointerException.class, () ->
{
HttpField nullNullField = new HttpField(null, null, "bogus");
fields.put(nullNullField);
});
}
@Test
public void testIteration() throws Exception
{

View File

@ -97,7 +97,7 @@ public class HttpParserTest
}
@Test
public void testLineParse_Mock_IP() throws Exception
public void testLineParseMockIP() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer("POST /mock/127.0.0.1 HTTP/1.1\r\n" + "\r\n");
@ -125,7 +125,7 @@ public class HttpParserTest
}
@Test
public void testLineParse1_RFC2616() throws Exception
public void testLineParse1RFC2616() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer("GET /999\r\n");
@ -154,7 +154,7 @@ public class HttpParserTest
}
@Test
public void testLineParse2_RFC2616() throws Exception
public void testLineParse2RFC2616() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer("POST /222 \r\n");
@ -376,7 +376,7 @@ public class HttpParserTest
HttpCompliance.RFC7230, HttpCompliance.RFC2616
};
String whitespaces[][] = new String[][]
String[][] whitespaces = new String[][]
{
{" ", "Illegal character SPACE"},
{"\t", "Illegal character HTAB"},
@ -802,9 +802,9 @@ public class HttpParserTest
public void testBadHeaderEncoding() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"GET / HTTP/1.0\r\n"
+ "H\u00e6der0: value0\r\n"
+ "\n\n");
"GET / HTTP/1.0\r\n" +
"H\u00e6der0: value0\r\n" +
"\n\n");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
@ -832,7 +832,7 @@ public class HttpParserTest
"Foo/Bar: value\r\n",
"Foo]Bar: value\r\n",
"Foo[Bar: value\r\n",
};
};
for (int i = 0; i < bad.length; i++)
{
@ -1003,16 +1003,16 @@ public class HttpParserTest
public void testChunkParse() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"GET /chunk HTTP/1.0\r\n"
+ "Header1: value1\r\n"
+ "Transfer-Encoding: chunked\r\n"
+ "\r\n"
+ "a;\r\n"
+ "0123456789\r\n"
+ "1a\r\n"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n"
+ "0\r\n"
+ "\r\n");
"GET /chunk HTTP/1.0\r\n" +
"Header1: value1\r\n" +
"Transfer-Encoding: chunked\r\n" +
"\r\n" +
"a;\r\n" +
"0123456789\r\n" +
"1a\r\n" +
"ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n" +
"0\r\n" +
"\r\n");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
parseAll(parser, buffer);
@ -1033,16 +1033,16 @@ public class HttpParserTest
public void testBadChunkParse() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"GET /chunk HTTP/1.0\r\n"
+ "Header1: value1\r\n"
+ "Transfer-Encoding: chunked, identity\r\n"
+ "\r\n"
+ "a;\r\n"
+ "0123456789\r\n"
+ "1a\r\n"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n"
+ "0\r\n"
+ "\r\n");
"GET /chunk HTTP/1.0\r\n" +
"Header1: value1\r\n" +
"Transfer-Encoding: chunked, identity\r\n" +
"\r\n" +
"a;\r\n" +
"0123456789\r\n" +
"1a\r\n" +
"ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n" +
"0\r\n" +
"\r\n");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
parseAll(parser, buffer);
@ -1057,17 +1057,17 @@ public class HttpParserTest
public void testChunkParseTrailer() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"GET /chunk HTTP/1.0\r\n"
+ "Header1: value1\r\n"
+ "Transfer-Encoding: chunked\r\n"
+ "\r\n"
+ "a;\r\n"
+ "0123456789\r\n"
+ "1a\r\n"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n"
+ "0\r\n"
+ "Trailer: value\r\n"
+ "\r\n");
"GET /chunk HTTP/1.0\r\n" +
"Header1: value1\r\n" +
"Transfer-Encoding: chunked\r\n" +
"\r\n" +
"a;\r\n" +
"0123456789\r\n" +
"1a\r\n" +
"ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n" +
"0\r\n" +
"Trailer: value\r\n" +
"\r\n");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
parseAll(parser, buffer);
@ -1092,17 +1092,17 @@ public class HttpParserTest
public void testChunkParseTrailers() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"GET /chunk HTTP/1.0\r\n"
+ "Transfer-Encoding: chunked\r\n"
+ "\r\n"
+ "a;\r\n"
+ "0123456789\r\n"
+ "1a\r\n"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n"
+ "0\r\n"
+ "Trailer: value\r\n"
+ "Foo: bar\r\n"
+ "\r\n");
"GET /chunk HTTP/1.0\r\n" +
"Transfer-Encoding: chunked\r\n" +
"\r\n" +
"a;\r\n" +
"0123456789\r\n" +
"1a\r\n" +
"ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n" +
"0\r\n" +
"Trailer: value\r\n" +
"Foo: bar\r\n" +
"\r\n");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
parseAll(parser, buffer);
@ -1130,16 +1130,16 @@ public class HttpParserTest
public void testChunkParseBadTrailer() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"GET /chunk HTTP/1.0\r\n"
+ "Header1: value1\r\n"
+ "Transfer-Encoding: chunked\r\n"
+ "\r\n"
+ "a;\r\n"
+ "0123456789\r\n"
+ "1a\r\n"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n"
+ "0\r\n"
+ "Trailer: value");
"GET /chunk HTTP/1.0\r\n" +
"Header1: value1\r\n" +
"Transfer-Encoding: chunked\r\n" +
"\r\n" +
"a;\r\n" +
"0123456789\r\n" +
"1a\r\n" +
"ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n" +
"0\r\n" +
"Trailer: value");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
parseAll(parser, buffer);
@ -1162,15 +1162,15 @@ public class HttpParserTest
public void testChunkParseNoTrailer() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"GET /chunk HTTP/1.0\r\n"
+ "Header1: value1\r\n"
+ "Transfer-Encoding: chunked\r\n"
+ "\r\n"
+ "a;\r\n"
+ "0123456789\r\n"
+ "1a\r\n"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n"
+ "0\r\n");
"GET /chunk HTTP/1.0\r\n" +
"Header1: value1\r\n" +
"Transfer-Encoding: chunked\r\n" +
"\r\n" +
"a;\r\n" +
"0123456789\r\n" +
"1a\r\n" +
"ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n" +
"0\r\n");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
parseAll(parser, buffer);
@ -1205,10 +1205,10 @@ public class HttpParserTest
public void testEarlyEOF() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"GET /uri HTTP/1.0\r\n"
+ "Content-Length: 20\r\n"
+ "\r\n"
+ "0123456789");
"GET /uri HTTP/1.0\r\n" +
"Content-Length: 20\r\n" +
"\r\n" +
"0123456789");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
parser.atEOF();
@ -1226,12 +1226,12 @@ public class HttpParserTest
public void testChunkEarlyEOF() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"GET /chunk HTTP/1.0\r\n"
+ "Header1: value1\r\n"
+ "Transfer-Encoding: chunked\r\n"
+ "\r\n"
+ "a;\r\n"
+ "0123456789\r\n");
"GET /chunk HTTP/1.0\r\n" +
"Header1: value1\r\n" +
"Transfer-Encoding: chunked\r\n" +
"\r\n" +
"a;\r\n" +
"0123456789\r\n");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
parser.atEOF();
@ -1252,31 +1252,31 @@ public class HttpParserTest
public void testMultiParse() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"GET /mp HTTP/1.0\r\n"
+ "Connection: Keep-Alive\r\n"
+ "Header1: value1\r\n"
+ "Transfer-Encoding: chunked\r\n"
+ "\r\n"
+ "a;\r\n"
+ "0123456789\r\n"
+ "1a\r\n"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n"
+ "0\r\n"
"GET /mp HTTP/1.0\r\n" +
"Connection: Keep-Alive\r\n" +
"Header1: value1\r\n" +
"Transfer-Encoding: chunked\r\n" +
"\r\n" +
"a;\r\n" +
"0123456789\r\n" +
"1a\r\n" +
"ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n" +
"0\r\n" +
+ "\r\n"
"\r\n" +
+ "POST /foo HTTP/1.0\r\n"
+ "Connection: Keep-Alive\r\n"
+ "Header2: value2\r\n"
+ "Content-Length: 0\r\n"
+ "\r\n"
"POST /foo HTTP/1.0\r\n" +
"Connection: Keep-Alive\r\n" +
"Header2: value2\r\n" +
"Content-Length: 0\r\n" +
"\r\n" +
+ "PUT /doodle HTTP/1.0\r\n"
+ "Connection: close\r\n"
+ "Header3: value3\r\n"
+ "Content-Length: 10\r\n"
+ "\r\n"
+ "0123456789\r\n");
"PUT /doodle HTTP/1.0\r\n" +
"Connection: close\r\n" +
"Header3: value3\r\n" +
"Content-Length: 10\r\n" +
"\r\n" +
"0123456789\r\n");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
@ -1317,32 +1317,31 @@ public class HttpParserTest
public void testMultiParseEarlyEOF() throws Exception
{
ByteBuffer buffer0 = BufferUtil.toBuffer(
"GET /mp HTTP/1.0\r\n"
+ "Connection: Keep-Alive\r\n");
"GET /mp HTTP/1.0\r\n" +
"Connection: Keep-Alive\r\n");
ByteBuffer buffer1 = BufferUtil.toBuffer("Header1: value1\r\n"
+ "Transfer-Encoding: chunked\r\n"
+ "\r\n"
+ "a;\r\n"
+ "0123456789\r\n"
+ "1a\r\n"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n"
+ "0\r\n"
ByteBuffer buffer1 = BufferUtil.toBuffer("Header1: value1\r\n" +
"Transfer-Encoding: chunked\r\n" +
"\r\n" +
"a;\r\n" +
"0123456789\r\n" +
"1a\r\n" +
"ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n" +
"0\r\n" +
+ "\r\n"
"\r\n" +
+ "POST /foo HTTP/1.0\r\n"
+ "Connection: Keep-Alive\r\n"
+ "Header2: value2\r\n"
+ "Content-Length: 0\r\n"
+ "\r\n"
"POST /foo HTTP/1.0\r\n" +
"Connection: Keep-Alive\r\n" +
"Header2: value2\r\n" +
"Content-Length: 0\r\n" +
"\r\n" +
+ "PUT /doodle HTTP/1.0\r\n"
+ "Connection: close\r\n"
+ "Header3: value3\r\n"
+ "Content-Length: 10\r\n"
+ "\r\n"
+ "0123456789\r\n");
"PUT /doodle HTTP/1.0\r\n" +
"Connection: close\r\n" + "Header3: value3\r\n" +
"Content-Length: 10\r\n" +
"\r\n" +
"0123456789\r\n");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
@ -1384,11 +1383,11 @@ public class HttpParserTest
public void testResponseParse0() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"HTTP/1.1 200 Correct\r\n"
+ "Content-Length: 10\r\n"
+ "Content-Type: text/plain\r\n"
+ "\r\n"
+ "0123456789\r\n");
"HTTP/1.1 200 Correct\r\n" +
"Content-Length: 10\r\n" +
"Content-Type: text/plain\r\n" +
"\r\n" +
"0123456789\r\n");
HttpParser.ResponseHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
@ -1405,9 +1404,9 @@ public class HttpParserTest
public void testResponseParse1() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"HTTP/1.1 304 Not-Modified\r\n"
+ "Connection: close\r\n"
+ "\r\n");
"HTTP/1.1 304 Not-Modified\r\n" +
"Connection: close\r\n" +
"\r\n");
HttpParser.ResponseHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
@ -1423,15 +1422,15 @@ public class HttpParserTest
public void testResponseParse2() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"HTTP/1.1 204 No-Content\r\n"
+ "Header: value\r\n"
+ "\r\n"
"HTTP/1.1 204 No-Content\r\n" +
"Header: value\r\n" +
"\r\n" +
+ "HTTP/1.1 200 Correct\r\n"
+ "Content-Length: 10\r\n"
+ "Content-Type: text/plain\r\n"
+ "\r\n"
+ "0123456789\r\n");
"HTTP/1.1 200 Correct\r\n" +
"Content-Length: 10\r\n" +
"Content-Type: text/plain\r\n" +
"\r\n" +
"0123456789\r\n");
HttpParser.ResponseHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
@ -1459,11 +1458,11 @@ public class HttpParserTest
public void testResponseParse3() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"HTTP/1.1 200\r\n"
+ "Content-Length: 10\r\n"
+ "Content-Type: text/plain\r\n"
+ "\r\n"
+ "0123456789\r\n");
"HTTP/1.1 200\r\n" +
"Content-Length: 10\r\n" +
"Content-Type: text/plain\r\n" +
"\r\n" +
"0123456789\r\n");
HttpParser.ResponseHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
@ -1480,11 +1479,11 @@ public class HttpParserTest
public void testResponseParse4() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"HTTP/1.1 200 \r\n"
+ "Content-Length: 10\r\n"
+ "Content-Type: text/plain\r\n"
+ "\r\n"
+ "0123456789\r\n");
"HTTP/1.1 200 \r\n" +
"Content-Length: 10\r\n" +
"Content-Type: text/plain\r\n" +
"\r\n" +
"0123456789\r\n");
HttpParser.ResponseHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
@ -1501,10 +1500,10 @@ public class HttpParserTest
public void testResponseEOFContent() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"HTTP/1.1 200 \r\n"
+ "Content-Type: text/plain\r\n"
+ "\r\n"
+ "0123456789\r\n");
"HTTP/1.1 200 \r\n" +
"Content-Type: text/plain\r\n" +
"\r\n" +
"0123456789\r\n");
HttpParser.ResponseHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
@ -1524,9 +1523,9 @@ public class HttpParserTest
public void testResponse304WithContentLength() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"HTTP/1.1 304 found\r\n"
+ "Content-Length: 10\r\n"
+ "\r\n");
"HTTP/1.1 304 found\r\n" +
"Content-Length: 10\r\n" +
"\r\n");
HttpParser.ResponseHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
@ -1543,9 +1542,9 @@ public class HttpParserTest
public void testResponse101WithTransferEncoding() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"HTTP/1.1 101 switching protocols\r\n"
+ "Transfer-Encoding: chunked\r\n"
+ "\r\n");
"HTTP/1.1 101 switching protocols\r\n" +
"Transfer-Encoding: chunked\r\n" +
"\r\n");
HttpParser.ResponseHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
@ -1562,9 +1561,9 @@ public class HttpParserTest
public void testResponseReasonIso8859_1() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"HTTP/1.1 302 déplacé temporairement\r\n"
+ "Content-Length: 0\r\n"
+ "\r\n", StandardCharsets.ISO_8859_1);
"HTTP/1.1 302 déplacé temporairement\r\n" +
"Content-Length: 0\r\n" +
"\r\n", StandardCharsets.ISO_8859_1);
HttpParser.ResponseHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
@ -1578,12 +1577,12 @@ public class HttpParserTest
public void testSeekEOF() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"HTTP/1.1 200 OK\r\n"
+ "Content-Length: 0\r\n"
+ "Connection: close\r\n"
+ "\r\n"
+ "\r\n" // extra CRLF ignored
+ "HTTP/1.1 400 OK\r\n"); // extra data causes close ??
"HTTP/1.1 200 OK\r\n" +
"Content-Length: 0\r\n" +
"Connection: close\r\n" +
"\r\n" +
"\r\n" + // extra CRLF ignored
"HTTP/1.1 400 OK\r\n"); // extra data causes close ??
HttpParser.ResponseHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
@ -1610,10 +1609,10 @@ public class HttpParserTest
public void testNoURI() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"GET\r\n"
+ "Content-Length: 0\r\n"
+ "Connection: close\r\n"
+ "\r\n");
"GET\r\n" +
"Content-Length: 0\r\n" +
"Connection: close\r\n" +
"\r\n");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
@ -1632,10 +1631,10 @@ public class HttpParserTest
public void testNoURI2() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"GET \r\n"
+ "Content-Length: 0\r\n"
+ "Connection: close\r\n"
+ "\r\n");
"GET \r\n" +
"Content-Length: 0\r\n" +
"Connection: close\r\n" +
"\r\n");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
@ -1654,10 +1653,10 @@ public class HttpParserTest
public void testUnknownReponseVersion() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"HPPT/7.7 200 OK\r\n"
+ "Content-Length: 0\r\n"
+ "Connection: close\r\n"
+ "\r\n");
"HPPT/7.7 200 OK\r\n" +
"Content-Length: 0\r\n" +
"Connection: close\r\n" +
"\r\n");
HttpParser.ResponseHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
@ -1676,10 +1675,10 @@ public class HttpParserTest
public void testNoStatus() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"HTTP/1.1\r\n"
+ "Content-Length: 0\r\n"
+ "Connection: close\r\n"
+ "\r\n");
"HTTP/1.1\r\n" +
"Content-Length: 0\r\n" +
"Connection: close\r\n" +
"\r\n");
HttpParser.ResponseHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
@ -1698,10 +1697,10 @@ public class HttpParserTest
public void testNoStatus2() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"HTTP/1.1 \r\n"
+ "Content-Length: 0\r\n"
+ "Connection: close\r\n"
+ "\r\n");
"HTTP/1.1 \r\n" +
"Content-Length: 0\r\n" +
"Connection: close\r\n" +
"\r\n");
HttpParser.ResponseHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
@ -1720,10 +1719,10 @@ public class HttpParserTest
public void testBadRequestVersion() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"GET / HPPT/7.7\r\n"
+ "Content-Length: 0\r\n"
+ "Connection: close\r\n"
+ "\r\n");
"GET / HPPT/7.7\r\n" +
"Content-Length: 0\r\n" +
"Connection: close\r\n" +
"\r\n");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
@ -1738,10 +1737,10 @@ public class HttpParserTest
assertEquals(HttpParser.State.CLOSED, parser.getState());
buffer = BufferUtil.toBuffer(
"GET / HTTP/1.01\r\n"
+ "Content-Length: 0\r\n"
+ "Connection: close\r\n"
+ "\r\n");
"GET / HTTP/1.01\r\n" +
"Content-Length: 0\r\n" +
"Connection: close\r\n" +
"\r\n");
handler = new Handler();
parser = new HttpParser(handler);
@ -1760,10 +1759,10 @@ public class HttpParserTest
public void testBadCR() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"GET / HTTP/1.0\r\n"
+ "Content-Length: 0\r"
+ "Connection: close\r"
+ "\r");
"GET / HTTP/1.0\r\n" +
"Content-Length: 0\r" +
"Connection: close\r" +
"\r");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
@ -1777,10 +1776,10 @@ public class HttpParserTest
assertEquals(HttpParser.State.CLOSED, parser.getState());
buffer = BufferUtil.toBuffer(
"GET / HTTP/1.0\r"
+ "Content-Length: 0\r"
+ "Connection: close\r"
+ "\r");
"GET / HTTP/1.0\r" +
"Content-Length: 0\r" +
"Connection: close\r" +
"\r");
handler = new Handler();
parser = new HttpParser(handler);
@ -1798,10 +1797,10 @@ public class HttpParserTest
public void testBadContentLength0() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"GET / HTTP/1.0\r\n"
+ "Content-Length: abc\r\n"
+ "Connection: close\r\n"
+ "\r\n");
"GET / HTTP/1.0\r\n" +
"Content-Length: abc\r\n" +
"Connection: close\r\n" +
"\r\n");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
@ -1820,10 +1819,10 @@ public class HttpParserTest
public void testBadContentLength1() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"GET / HTTP/1.0\r\n"
+ "Content-Length: 9999999999999999999999999999999999999999999999\r\n"
+ "Connection: close\r\n"
+ "\r\n");
"GET / HTTP/1.0\r\n" +
"Content-Length: 9999999999999999999999999999999999999999999999\r\n" +
"Connection: close\r\n" +
"\r\n");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
@ -1842,10 +1841,10 @@ public class HttpParserTest
public void testBadContentLength2() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"GET / HTTP/1.0\r\n"
+ "Content-Length: 1.5\r\n"
+ "Connection: close\r\n"
+ "\r\n");
"GET / HTTP/1.0\r\n" +
"Content-Length: 1.5\r\n" +
"Connection: close\r\n" +
"\r\n");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
@ -1864,12 +1863,12 @@ public class HttpParserTest
public void testMultipleContentLengthWithLargerThenCorrectValue()
{
ByteBuffer buffer = BufferUtil.toBuffer(
"POST / HTTP/1.1\r\n"
+ "Content-Length: 2\r\n"
+ "Content-Length: 1\r\n"
+ "Connection: close\r\n"
+ "\r\n"
+ "X");
"POST / HTTP/1.1\r\n" +
"Content-Length: 2\r\n" +
"Content-Length: 1\r\n" +
"Connection: close\r\n" +
"\r\n" +
"X");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
@ -1888,12 +1887,12 @@ public class HttpParserTest
public void testMultipleContentLengthWithCorrectThenLargerValue()
{
ByteBuffer buffer = BufferUtil.toBuffer(
"POST / HTTP/1.1\r\n"
+ "Content-Length: 1\r\n"
+ "Content-Length: 2\r\n"
+ "Connection: close\r\n"
+ "\r\n"
+ "X");
"POST / HTTP/1.1\r\n" +
"Content-Length: 1\r\n" +
"Content-Length: 2\r\n" +
"Connection: close\r\n" +
"\r\n" +
"X");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
@ -1912,15 +1911,15 @@ public class HttpParserTest
public void testTransferEncodingChunkedThenContentLength()
{
ByteBuffer buffer = BufferUtil.toBuffer(
"POST /chunk HTTP/1.1\r\n"
+ "Host: localhost\r\n"
+ "Transfer-Encoding: chunked\r\n"
+ "Content-Length: 1\r\n"
+ "\r\n"
+ "1\r\n"
+ "X\r\n"
+ "0\r\n"
+ "\r\n");
"POST /chunk HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"Transfer-Encoding: chunked\r\n" +
"Content-Length: 1\r\n" +
"\r\n" +
"1\r\n" +
"X\r\n" +
"0\r\n" +
"\r\n");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler, HttpCompliance.RFC2616_LEGACY);
@ -1941,15 +1940,16 @@ public class HttpParserTest
public void testContentLengthThenTransferEncodingChunked()
{
ByteBuffer buffer = BufferUtil.toBuffer(
"POST /chunk HTTP/1.1\r\n"
+ "Host: localhost\r\n"
+ "Content-Length: 1\r\n"
+ "Transfer-Encoding: chunked\r\n"
+ "\r\n"
+ "1\r\n"
+ "X\r\n"
+ "0\r\n"
+ "\r\n");
"POST /chunk HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"Content-Length: 1\r\n" +
"Transfer-Encoding: chunked\r\n" +
"\r\n" +
"1\r\n" +
"X\r\n" +
"0\r\n" +
"\r\n");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler, HttpCompliance.RFC2616_LEGACY);
@ -1970,10 +1970,10 @@ public class HttpParserTest
public void testHost() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"GET / HTTP/1.1\r\n"
+ "Host: host\r\n"
+ "Connection: close\r\n"
+ "\r\n");
"GET / HTTP/1.1\r\n" +
"Host: host\r\n" +
"Connection: close\r\n" +
"\r\n");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
@ -1986,9 +1986,9 @@ public class HttpParserTest
public void testUriHost11() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"GET http://host/ HTTP/1.1\r\n"
+ "Connection: close\r\n"
+ "\r\n");
"GET http://host/ HTTP/1.1\r\n" +
"Connection: close\r\n" +
"\r\n");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
@ -2002,8 +2002,8 @@ public class HttpParserTest
public void testUriHost10() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"GET http://host/ HTTP/1.0\r\n"
+ "\r\n");
"GET http://host/ HTTP/1.0\r\n" +
"\r\n");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
@ -2017,9 +2017,9 @@ public class HttpParserTest
public void testNoHost() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"GET / HTTP/1.1\r\n"
+ "Connection: close\r\n"
+ "\r\n");
"GET / HTTP/1.1\r\n" +
"Connection: close\r\n" +
"\r\n");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
@ -2031,10 +2031,10 @@ public class HttpParserTest
public void testIPHost() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"GET / HTTP/1.1\r\n"
+ "Host: 192.168.0.1\r\n"
+ "Connection: close\r\n"
+ "\r\n");
"GET / HTTP/1.1\r\n" +
"Host: 192.168.0.1\r\n" +
"Connection: close\r\n" +
"\r\n");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
@ -2048,10 +2048,10 @@ public class HttpParserTest
{
Assumptions.assumeTrue(Net.isIpv6InterfaceAvailable());
ByteBuffer buffer = BufferUtil.toBuffer(
"GET / HTTP/1.1\r\n"
+ "Host: [::1]\r\n"
+ "Connection: close\r\n"
+ "\r\n");
"GET / HTTP/1.1\r\n" +
"Host: [::1]\r\n" +
"Connection: close\r\n" +
"\r\n");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
@ -2066,10 +2066,10 @@ public class HttpParserTest
try (StacklessLogging s = new StacklessLogging(HttpParser.class))
{
ByteBuffer buffer = BufferUtil.toBuffer(
"GET / HTTP/1.1\r\n"
+ "Host: [::1\r\n"
+ "Connection: close\r\n"
+ "\r\n");
"GET / HTTP/1.1\r\n" +
"Host: [::1\r\n" +
"Connection: close\r\n" +
"\r\n");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
@ -2082,10 +2082,10 @@ public class HttpParserTest
public void testHostPort() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"GET / HTTP/1.1\r\n"
+ "Host: myhost:8888\r\n"
+ "Connection: close\r\n"
+ "\r\n");
"GET / HTTP/1.1\r\n" +
"Host: myhost:8888\r\n" +
"Connection: close\r\n" +
"\r\n");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
@ -2098,10 +2098,10 @@ public class HttpParserTest
public void testHostBadPort() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"GET / HTTP/1.1\r\n"
+ "Host: myhost:testBadPort\r\n"
+ "Connection: close\r\n"
+ "\r\n");
"GET / HTTP/1.1\r\n" +
"Host: myhost:testBadPort\r\n" +
"Connection: close\r\n" +
"\r\n");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
@ -2113,10 +2113,10 @@ public class HttpParserTest
public void testIPHostPort() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"GET / HTTP/1.1\r\n"
+ "Host: 192.168.0.1:8888\r\n"
+ "Connection: close\r\n"
+ "\r\n");
"GET / HTTP/1.1\r\n" +
"Host: 192.168.0.1:8888\r\n" +
"Connection: close\r\n" +
"\r\n");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
@ -2130,10 +2130,10 @@ public class HttpParserTest
{
Assumptions.assumeTrue(Net.isIpv6InterfaceAvailable());
ByteBuffer buffer = BufferUtil.toBuffer(
"GET / HTTP/1.1\r\n"
+ "Host: [::1]:8888\r\n"
+ "Connection: close\r\n"
+ "\r\n");
"GET / HTTP/1.1\r\n" +
"Host: [::1]:8888\r\n" +
"Connection: close\r\n" +
"\r\n");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
@ -2146,10 +2146,10 @@ public class HttpParserTest
public void testEmptyHostPort() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"GET / HTTP/1.1\r\n"
+ "Host:\r\n"
+ "Connection: close\r\n"
+ "\r\n");
"GET / HTTP/1.1\r\n" +
"Host:\r\n" +
"Connection: close\r\n" +
"\r\n");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);

View File

@ -32,7 +32,7 @@ import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
/**
* A HTTP Testing helper class.
* An HTTP Testing helper class.
*
* Example usage:
* <pre>
@ -493,7 +493,7 @@ public class HttpTester
}
}
abstract public MetaData getInfo();
public abstract MetaData getInfo();
@Override
public int getHeaderCacheSize()

View File

@ -77,9 +77,9 @@ public class MultiPartFormInputStreamTest
"Content-Disposition: form-data; name=\"fileup\"; filename=\"test.upload\"\r\n" +
"Content-Type: application/octet-stream\r\n\r\n" +
"How now brown cow." +
"\r\n--" + boundary + "-\r\n"
+ "Content-Disposition: form-data; name=\"fileup\"; filename=\"test.upload\"\r\n"
+ "\r\n";
"\r\n--" + boundary + "-\r\n" +
"Content-Disposition: form-data; name=\"fileup\"; filename=\"test.upload\"\r\n" +
"\r\n";
MultipartConfigElement config = new MultipartConfigElement(_dirname, 1024, 3072, 50);
MultiPartFormInputStream mpis = new MultiPartFormInputStream(new ByteArrayInputStream(str.getBytes()),
@ -786,6 +786,8 @@ public class MultiPartFormInputStreamTest
assertThat(stuff.getContentType(), is("text/plain"));
assertThat(stuff.getHeader("Content-Type"), is("text/plain"));
assertThat(stuff.getHeaders("content-type").size(), is(1));
assertNotNull(stuff.getHeaders("non existing part"));
assertThat(stuff.getHeaders("non existing part").size(), is(0));
assertThat(stuff.getHeader("content-disposition"), is("form-data; name=\"stuff\"; filename=\"" + filename + "\""));
assertThat(stuff.getHeaderNames().size(), is(2));
assertThat(stuff.getSize(), is(51L));

View File

@ -173,13 +173,13 @@ public class MultiPartParserTest
};
MultiPartParser parser = new MultiPartParser(handler, "BOUNDARY");
ByteBuffer data = BufferUtil.toBuffer("--BOUNDARY\r\n"
+ "name0: value0\r\n"
+ "name1 :value1 \r\n"
+ "name2:value\r\n"
+ " 2\r\n"
+ "\r\n"
+ "Content");
ByteBuffer data = BufferUtil.toBuffer("--BOUNDARY\r\n" +
"name0: value0\r\n" +
"name1 :value1 \r\n" +
"name2:value\r\n" +
" 2\r\n" +
"\r\n" +
"Content");
parser.parse(data, false);
assertThat(parser.getState(), is(State.FIRST_OCTETS));
@ -193,11 +193,11 @@ public class MultiPartParserTest
TestHandler handler = new TestHandler();
MultiPartParser parser = new MultiPartParser(handler, "BOUNDARY");
ByteBuffer data = BufferUtil.toBuffer("--BOUNDARY\r\n"
+ "name: value\r\n"
+ "\r\n"
+ "\r\n"
+ "--BOUNDARY");
ByteBuffer data = BufferUtil.toBuffer("--BOUNDARY\r\n" +
"name: value\r\n" +
"\r\n" +
"\r\n" +
"--BOUNDARY");
parser.parse(data, false);
assertThat(parser.getState(), is(State.DELIMITER));
assertThat(data.remaining(), is(0));
@ -211,10 +211,10 @@ public class MultiPartParserTest
TestHandler handler = new TestHandler();
MultiPartParser parser = new MultiPartParser(handler, "BOUNDARY");
ByteBuffer data = BufferUtil.toBuffer("--BOUNDARY\r\n"
+ "name: value\r\n"
+ "\r\n"
+ "--BOUNDARY");
ByteBuffer data = BufferUtil.toBuffer("--BOUNDARY\r\n" +
"name: value\r\n" +
"\r\n" +
"--BOUNDARY");
parser.parse(data, false);
assertThat(parser.getState(), is(State.DELIMITER));
assertThat(data.remaining(), is(0));
@ -228,10 +228,10 @@ public class MultiPartParserTest
TestHandler handler = new TestHandler();
MultiPartParser parser = new MultiPartParser(handler, "BOUNDARY");
ByteBuffer data = BufferUtil.toBuffer("--BOUNDARY\r\n"
+ "name: value\r\n"
+ "\r\n"
+ "-");
ByteBuffer data = BufferUtil.toBuffer("--BOUNDARY\r\n" +
"name: value\r\n" +
"\r\n" +
"-");
parser.parse(data, false);
data = BufferUtil.toBuffer("Content!");
parser.parse(data, false);
@ -248,10 +248,10 @@ public class MultiPartParserTest
TestHandler handler = new TestHandler();
MultiPartParser parser = new MultiPartParser(handler, "BOUNDARY");
ByteBuffer data = BufferUtil.toBuffer("--BOUNDARY\r\n"
+ "name: value\n"
+ "\r\n"
+ "Hello\r\n");
ByteBuffer data = BufferUtil.toBuffer("--BOUNDARY\r\n" +
"name: value\n" +
"\r\n" +
"Hello\r\n");
parser.parse(data, false);
assertThat(parser.getState(), is(State.OCTETS));
assertThat(data.remaining(), is(0));
@ -259,18 +259,18 @@ public class MultiPartParserTest
assertThat(handler.content, Matchers.contains("Hello"));
data = BufferUtil.toBuffer(
"Now is the time for all good ment to come to the aid of the party.\r\n"
+ "How now brown cow.\r\n"
+ "The quick brown fox jumped over the lazy dog.\r\n"
+ "this is not a --BOUNDARY\r\n");
"Now is the time for all good ment to come to the aid of the party.\r\n" +
"How now brown cow.\r\n" +
"The quick brown fox jumped over the lazy dog.\r\n" +
"this is not a --BOUNDARY\r\n");
parser.parse(data, false);
assertThat(parser.getState(), is(State.OCTETS));
assertThat(data.remaining(), is(0));
assertThat(handler.fields, Matchers.contains("name: value", "<<COMPLETE>>"));
assertThat(handler.content, Matchers.contains("Hello", "\r\n", "Now is the time for all good ment to come to the aid of the party.\r\n"
+ "How now brown cow.\r\n"
+ "The quick brown fox jumped over the lazy dog.\r\n"
+ "this is not a --BOUNDARY"));
assertThat(handler.content, Matchers.contains("Hello", "\r\n", "Now is the time for all good ment to come to the aid of the party.\r\n" +
"How now brown cow.\r\n" +
"The quick brown fox jumped over the lazy dog.\r\n" +
"this is not a --BOUNDARY"));
}
@Test
@ -279,11 +279,11 @@ public class MultiPartParserTest
TestHandler handler = new TestHandler();
MultiPartParser parser = new MultiPartParser(handler, "BOUNDARY");
ByteBuffer data = BufferUtil.toBuffer("--BOUNDARY\r\n"
+ "name: value\n"
+ "\r\n"
+ "Hello\r\n"
+ "--BOUNDARY");
ByteBuffer data = BufferUtil.toBuffer("--BOUNDARY\r\n" +
"name: value\n" +
"\r\n" +
"Hello\r\n" +
"--BOUNDARY");
parser.parse(data, false);
assertThat(parser.getState(), is(State.DELIMITER));
assertThat(data.remaining(), is(0));
@ -297,21 +297,21 @@ public class MultiPartParserTest
TestHandler handler = new TestHandler();
MultiPartParser parser = new MultiPartParser(handler, "BOUNDARY");
ByteBuffer data = BufferUtil.toBuffer("--BOUNDARY\r\n"
+ "name: value\n"
+ "\r\n"
+ "Now is the time for all good ment to come to the aid of the party.\r\n"
+ "How now brown cow.\r\n"
+ "The quick brown fox jumped over the lazy dog.\r\n"
+ "\r\n"
+ "--BOUNDARY");
ByteBuffer data = BufferUtil.toBuffer("--BOUNDARY\r\n" +
"name: value\n" +
"\r\n" +
"Now is the time for all good ment to come to the aid of the party.\r\n" +
"How now brown cow.\r\n" +
"The quick brown fox jumped over the lazy dog.\r\n" +
"\r\n" +
"--BOUNDARY");
parser.parse(data, false);
assertThat(parser.getState(), is(State.DELIMITER));
assertThat(data.remaining(), is(0));
assertThat(handler.fields, Matchers.contains("name: value", "<<COMPLETE>>"));
assertThat(handler.content, Matchers.contains("Now is the time for all good ment to come to the aid of the party.\r\n"
+ "How now brown cow.\r\n"
+ "The quick brown fox jumped over the lazy dog.\r\n", "<<LAST>>"));
assertThat(handler.content, Matchers.contains("Now is the time for all good ment to come to the aid of the party.\r\n" +
"How now brown cow.\r\n" +
"The quick brown fox jumped over the lazy dog.\r\n", "<<LAST>>"));
}
@Test
@ -321,21 +321,21 @@ public class MultiPartParserTest
MultiPartParser parser = new MultiPartParser(handler, "BOUNDARY");
//boundary still requires carriage return
ByteBuffer data = BufferUtil.toBuffer("--BOUNDARY\n"
+ "name: value\n"
+ "\n"
+ "Now is the time for all good men to come to the aid of the party.\n"
+ "How now brown cow.\n"
+ "The quick brown fox jumped over the lazy dog.\n"
+ "\r\n"
+ "--BOUNDARY");
ByteBuffer data = BufferUtil.toBuffer("--BOUNDARY\n" +
"name: value\n" +
"\n" +
"Now is the time for all good men to come to the aid of the party.\n" +
"How now brown cow.\n" +
"The quick brown fox jumped over the lazy dog.\n" +
"\r\n" +
"--BOUNDARY");
parser.parse(data, false);
assertThat(parser.getState(), is(State.DELIMITER));
assertThat(data.remaining(), is(0));
assertThat(handler.fields, Matchers.contains("name: value", "<<COMPLETE>>"));
assertThat(handler.content, Matchers.contains("Now is the time for all good men to come to the aid of the party.\n"
+ "How now brown cow.\n"
+ "The quick brown fox jumped over the lazy dog.\n", "<<LAST>>"));
assertThat(handler.content, Matchers.contains("Now is the time for all good men to come to the aid of the party.\n" +
"How now brown cow.\n" +
"The quick brown fox jumped over the lazy dog.\n", "<<LAST>>"));
}
@Test
@ -377,17 +377,17 @@ public class MultiPartParserTest
TestHandler handler = new TestHandler();
MultiPartParser parser = new MultiPartParser(handler, "BOUNDARY");
ByteBuffer data = BufferUtil.toBuffer(""
+ "--BOUNDARY\r\n"
+ "name: value\n"
+ "\r\n"
+ "Hello\r\n"
+ "--BOUNDARY--"
+ "epilogue here:"
+ "\r\n"
+ "--BOUNDARY--"
+ "\r\n"
+ "--BOUNDARY");
ByteBuffer data = BufferUtil.toBuffer("" +
"--BOUNDARY\r\n" +
"name: value\n" +
"\r\n" +
"Hello\r\n" +
"--BOUNDARY--" +
"epilogue here:" +
"\r\n" +
"--BOUNDARY--" +
"\r\n" +
"--BOUNDARY");
parser.parse(data, false);
assertThat(parser.getState(), is(State.DELIMITER));
@ -404,20 +404,20 @@ public class MultiPartParserTest
TestHandler handler = new TestHandler();
MultiPartParser parser = new MultiPartParser(handler, "BOUNDARY");
ByteBuffer data = BufferUtil.toBuffer(""
+ "--BOUNDARY\r\n"
+ "name: value\n"
+ "\r\n"
+ "Hello"
+ "\r\n"
+ "--BOUNDARY\r\n"
+ "powerLevel: 9001\n"
+ "\r\n"
+ "secondary"
+ "\r\n"
+ "content"
+ "\r\n--BOUNDARY--"
+ "epilogue here");
ByteBuffer data = BufferUtil.toBuffer("" +
"--BOUNDARY\r\n" +
"name: value\n" +
"\r\n" +
"Hello" +
"\r\n" +
"--BOUNDARY\r\n" +
"powerLevel: 9001\n" +
"\r\n" +
"secondary" +
"\r\n" +
"content" +
"\r\n--BOUNDARY--" +
"epilogue here");
/* Test First Content Section */
parser.parse(data, false);
@ -612,21 +612,21 @@ public class MultiPartParserTest
dataSeg.limit(length);
assertThat("Third " + i, parser.parse(dataSeg, true), is(true));
assertThat(handler.fields, Matchers.contains("Content-Disposition: form-data; name=\"text\"", "<<COMPLETE>>"
, "Content-Disposition: form-data; name=\"file1\"; filename=\"a.txt\""
, "Content-Type: text/plain", "<<COMPLETE>>"
, "Content-Disposition: form-data; name=\"file2\"; filename=\"a.html\""
, "Content-Type: text/html", "<<COMPLETE>>"
, "Field1: value1", "Field2: value2", "Field3: value3"
, "Field4: value4", "Field5: value5", "Field6: value6"
, "Field7: value7", "Field8: value8", "Field9: value 9", "<<COMPLETE>>"
, "Field1: value1", "<<COMPLETE>>"));
assertThat(handler.fields, Matchers.contains("Content-Disposition: form-data; name=\"text\"", "<<COMPLETE>>",
"Content-Disposition: form-data; name=\"file1\"; filename=\"a.txt\"",
"Content-Type: text/plain", "<<COMPLETE>>",
"Content-Disposition: form-data; name=\"file2\"; filename=\"a.html\"",
"Content-Type: text/html", "<<COMPLETE>>",
"Field1: value1", "Field2: value2", "Field3: value3",
"Field4: value4", "Field5: value5", "Field6: value6",
"Field7: value7", "Field8: value8", "Field9: value 9", "<<COMPLETE>>",
"Field1: value1", "<<COMPLETE>>"));
assertThat(handler.contentString(), is("text default" + "<<LAST>>"
+ "Content of a.txt.\n" + "<<LAST>>"
+ "<!DOCTYPE html><title>Content of a.html.</title>\n" + "<<LAST>>"
+ "<<LAST>>"
+ "But the amount of denudation which the strata have\n" +
assertThat(handler.contentString(), is("text default" + "<<LAST>>" +
"Content of a.txt.\n" + "<<LAST>>" +
"<!DOCTYPE html><title>Content of a.html.</title>\n" + "<<LAST>>" +
"<<LAST>>" +
"But the amount of denudation which the strata have\n" +
"in many places suffered, independently of the rate\n" +
"of accumulation of the degraded matter, probably\n" +
"offers the best evidence of the lapse of time. I remember\n" +
@ -670,18 +670,18 @@ public class MultiPartParserTest
};
MultiPartParser parser = new MultiPartParser(handler, "WebKitFormBoundary7MA4YWf7OaKlSxkTrZu0gW");
ByteBuffer data = BufferUtil.toBuffer(""
+ "Content-Type: multipart/form-data; boundary=WebKitFormBoundary7MA4YWf7OaKlSxkTrZu0gW\r\n" +
"\r\n" +
"--WebKitFormBoundary7MA4YWf7OaKlSxkTrZu0gW\r\n" +
"Content-Disposition: form-data; name=\"part1\"\r\n" +
"\n" +
"wNfミxVam﾿t\r\n" +
"--WebKitFormBoundary7MA4YWf7OaKlSxkTrZu0gW\n" +
"Content-Disposition: form-data; name=\"part2\"\r\n" +
"\r\n" +
"&ᄈᄎ￙ᅱᅢO\r\n" +
"--WebKitFormBoundary7MA4YWf7OaKlSxkTrZu0gW--");
ByteBuffer data = BufferUtil.toBuffer("" +
"Content-Type: multipart/form-data; boundary=WebKitFormBoundary7MA4YWf7OaKlSxkTrZu0gW\r\n" +
"\r\n" +
"--WebKitFormBoundary7MA4YWf7OaKlSxkTrZu0gW\r\n" +
"Content-Disposition: form-data; name=\"part1\"\r\n" +
"\n" +
"wNfミxVam﾿t\r\n" +
"--WebKitFormBoundary7MA4YWf7OaKlSxkTrZu0gW\n" +
"Content-Disposition: form-data; name=\"part2\"\r\n" +
"\r\n" +
"&ᄈᄎ￙ᅱᅢO\r\n" +
"--WebKitFormBoundary7MA4YWf7OaKlSxkTrZu0gW--");
parser.parse(data, true);
assertThat(parser.getState(), is(State.END));

View File

@ -881,7 +881,7 @@ public class StreamResetTest extends AbstractTest
// Try to write again, must fail immediately.
output.write(0xFF);
}
catch (IOException xx)
catch (IOException e)
{
writeLatch2.countDown();
}

View File

@ -170,7 +170,7 @@ public class BufferingFlowControlStrategy extends AbstractFlowControlStrategy
// and here we keep track of its max value.
// Updating the max session recv window is done here
// so that if a peer decides to send an unilateral
// so that if a peer decides to send a unilateral
// window update to enlarge the session window,
// without the corresponding data consumption, here
// we can track it.

View File

@ -40,7 +40,7 @@ public enum ErrorCode
*/
INTERNAL_ERROR(2),
/**
* Indicates a HTTP/2 flow control violation.
* Indicates an HTTP/2 flow control violation.
*/
FLOW_CONTROL_ERROR(3),
/**
@ -68,7 +68,7 @@ public enum ErrorCode
*/
COMPRESSION_ERROR(9),
/**
* Indicates that the connection established by a HTTP CONNECT was abnormally closed.
* Indicates that the connection established by an HTTP CONNECT was abnormally closed.
*/
HTTP_CONNECT_ERROR(10),
/**

View File

@ -30,7 +30,7 @@ import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.Promise;
/**
* <p>The SPI interface for implementing a HTTP/2 session.</p>
* <p>The SPI interface for implementing an HTTP/2 session.</p>
* <p>This class extends {@link Session} by adding the methods required to
* implement the HTTP/2 session functionalities.</p>
*/

View File

@ -25,7 +25,7 @@ import org.eclipse.jetty.http2.frames.Frame;
import org.eclipse.jetty.util.Callback;
/**
* <p>The SPI interface for implementing a HTTP/2 stream.</p>
* <p>The SPI interface for implementing an HTTP/2 stream.</p>
* <p>This class extends {@link Stream} by adding the methods required to
* implement the HTTP/2 stream functionalities.</p>
*/

View File

@ -32,7 +32,7 @@ import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.Promise;
/**
* <p>A {@link Session} represents the client-side endpoint of a HTTP/2 connection to a single origin server.</p>
* <p>A {@link Session} represents the client-side endpoint of an HTTP/2 connection to a single origin server.</p>
* <p>Once a {@link Session} has been obtained, it can be used to open HTTP/2 streams:</p>
* <pre>
* Session session = ...;
@ -127,7 +127,7 @@ public interface Session
/**
* <p>A {@link Listener} is the passive counterpart of a {@link Session} and
* receives events happening on a HTTP/2 connection.</p>
* receives events happening on an HTTP/2 connection.</p>
*
* @see Session
*/
@ -151,9 +151,9 @@ public interface Session
/**
* <p>Callback method invoked when a new stream is being created upon
* receiving a HEADERS frame representing a HTTP request.</p>
* receiving a HEADERS frame representing an HTTP request.</p>
* <p>Applications should implement this method to process HTTP requests,
* typically providing a HTTP response via
* typically providing an HTTP response via
* {@link Stream#headers(HeadersFrame, Callback)}.</p>
* <p>Applications can detect whether request DATA frames will be arriving
* by testing {@link HeadersFrame#isEndStream()}. If the application is

View File

@ -29,8 +29,8 @@ import org.eclipse.jetty.util.Promise;
* <p>A {@link Stream} represents a bidirectional exchange of data on top of a {@link Session}.</p>
* <p>Differently from socket streams, where the input and output streams are permanently associated
* with the socket (and hence with the connection that the socket represents), there can be multiple
* HTTP/2 streams present concurrent for a HTTP/2 session.</p>
* <p>A {@link Stream} maps to a HTTP request/response cycle, and after the request/response cycle is
* HTTP/2 streams present concurrent for an HTTP/2 session.</p>
* <p>A {@link Stream} maps to an HTTP request/response cycle, and after the request/response cycle is
* completed, the stream is closed and removed from the session.</p>
* <p>Like {@link Session}, {@link Stream} is the active part and by calling its API applications
* can generate events on the stream; conversely, {@link Stream.Listener} is the passive part, and
@ -51,7 +51,7 @@ public interface Stream
Session getSession();
/**
* <p>Sends the given HEADERS {@code frame} representing a HTTP response.</p>
* <p>Sends the given HEADERS {@code frame} representing an HTTP response.</p>
*
* @param frame the HEADERS frame to send
* @param callback the callback that gets notified when the frame has been sent
@ -131,7 +131,7 @@ public interface Stream
/**
* <p>A {@link Stream.Listener} is the passive counterpart of a {@link Stream} and receives
* events happening on a HTTP/2 stream.</p>
* events happening on an HTTP/2 stream.</p>
*
* @see Stream
*/

View File

@ -42,7 +42,7 @@ public class PrefaceParser
* <p>Advances this parser after the {@link PrefaceFrame#PREFACE_PREAMBLE_BYTES}.</p>
* <p>This allows the HTTP/1.1 parser to parse the preamble of the preface,
* which is a legal HTTP/1.1 request, and this parser will parse the remaining
* bytes, that are not parseable by a HTTP/1.1 parser.</p>
* bytes, that are not parseable by an HTTP/1.1 parser.</p>
*/
protected void directUpgrade()
{

View File

@ -104,7 +104,7 @@ public class HpackContextTest
new HttpField("name", "v3"),
new HttpField("name", "v4"),
new HttpField("name", "v5"),
};
};
Entry[] entry = new Entry[field.length];
@ -197,7 +197,7 @@ public class HpackContextTest
new HttpField("fo8", "b8r"),
new HttpField("fo9", "b9r"),
new HttpField("foA", "bAr"),
};
};
Entry[] entry = new Entry[100];
@ -324,7 +324,7 @@ public class HpackContextTest
new HttpField("fo8", "b8r"),
new HttpField("fo9", "b9r"),
new HttpField("foA", "bAr"),
};
};
Entry[] entry = new Entry[field.length];
// Add 5 entries

View File

@ -56,7 +56,7 @@ public class HpackEncoderTest
new HttpField("fo8", "b8r"),
new HttpField("fo9", "b9r"),
new HttpField("foA", "bAr"),
};
};
// Add 4 entries
for (int i = 0; i <= 3; i++)

View File

@ -198,7 +198,7 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest
.onRequestBegin(request ->
{
if (request.getVersion() != HttpVersion.HTTP_2)
request.abort(new Exception("Not a HTTP/2 request"));
request.abort(new Exception("Not an HTTP/2 request"));
})
.send();

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<!-- ============================================================= --><!-- Configure a HTTP2 on the ssl connector. --><!-- ============================================================= -->
<!-- ============================================================= --><!-- Configure an HTTP2 on the ssl connector. --><!-- ============================================================= -->
<Configure id="sslConnector" class="org.eclipse.jetty.server.ServerConnector">
<Call name="addConnectionFactory">
<Arg>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<!-- ============================================================= --><!-- Configure a HTTP2 on the ssl connector. --><!-- ============================================================= -->
<!-- ============================================================= --><!-- Configure an HTTP2 on the ssl connector. --><!-- ============================================================= -->
<Configure id="httpConnector" class="org.eclipse.jetty.server.ServerConnector">
<Call name="addConnectionFactory">
<Arg>

View File

@ -39,8 +39,8 @@ import org.eclipse.jetty.util.log.Logger;
* </p>
* <p>If used in combination with a {@link HttpConnectionFactory} as the
* default protocol, this factory can support the non-standard direct
* update mechanism, where a HTTP1 request of the form "PRI * HTTP/2.0"
* is used to trigger a switch to a HTTP2 connection. This approach
* update mechanism, where an HTTP1 request of the form "PRI * HTTP/2.0"
* is used to trigger a switch to an HTTP2 connection. This approach
* allows a single port to accept either HTTP/1 or HTTP/2 direct
* connections.
*/

View File

@ -64,7 +64,7 @@ import org.eclipse.jetty.util.TypeUtil;
public class HTTP2ServerConnection extends HTTP2Connection implements Connection.UpgradeTo
{
/**
* @param protocol A HTTP2 protocol variant
* @param protocol An HTTP2 protocol variant
* @return True if the protocol version is supported
*/
public static boolean isSupportedProtocol(String protocol)

View File

@ -188,7 +188,7 @@ public class HTTP2CServerTest extends AbstractServerTest
assertThat(content, containsString("Hello from Jetty using HTTP/1.1"));
assertThat(content, containsString("uri=/one"));
// Send a HTTP/2 request.
// Send an HTTP/2 request.
headersRef.set(null);
dataRef.set(null);
latchRef.set(new CountDownLatch(2));
@ -319,7 +319,7 @@ public class HTTP2CServerTest extends AbstractServerTest
connector.setDefaultProtocol(connectionFactory.getProtocol());
connector.start();
// Now send a HTTP/2 direct request, which
// Now send an HTTP/2 direct request, which
// will have the PRI * HTTP/2.0 preface.
byteBufferPool = new MappedByteBufferPool();
@ -336,7 +336,7 @@ public class HTTP2CServerTest extends AbstractServerTest
output.write(BufferUtil.toArray(buffer));
}
// We sent a HTTP/2 preface, but the server has no "h2c" connection
// We sent an HTTP/2 preface, but the server has no "h2c" connection
// factory so it does not know how to handle this request.
InputStream input = client.getInputStream();

View File

@ -0,0 +1,62 @@
//
// ========================================================================
// Copyright (c) 1995-2019 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.io;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import org.eclipse.jetty.util.BufferUtil;
/**
* Simple wrapper of a ByteBuffer as an OutputStream.
* The buffer does not grow and this class will throw an
* {@link java.nio.BufferOverflowException} if the buffer capacity is exceeded.
*/
public class ByteBufferOutputStream extends OutputStream
{
final ByteBuffer _buffer;
public ByteBufferOutputStream(ByteBuffer buffer)
{
_buffer = buffer;
}
public void close()
{
}
public void flush()
{
}
public void write(byte[] b)
{
write(b, 0, b.length);
}
public void write(byte[] b, int off, int len)
{
BufferUtil.append(_buffer, b, off, len);
}
public void write(int b)
{
BufferUtil.append(_buffer, (byte)b);
}
}

View File

@ -35,6 +35,7 @@ public interface SslHandshakeListener extends EventListener
* <p>Callback method invoked when the TLS handshake succeeds.</p>
*
* @param event the event object carrying information about the TLS handshake event
* @throws SSLException if any error happen during handshake
*/
default void handshakeSucceeded(Event event) throws SSLException
{

View File

@ -43,6 +43,7 @@ import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.IO;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.OS;
@ -93,14 +94,8 @@ public class IOTest
assertEquals(-1, server.getInputStream().read());
// but cannot write
try
{
client.getOutputStream().write(1);
fail("exception expected");
}
catch (SocketException expected)
{
}
Assertions.assertThrows(SocketException.class, () -> client.getOutputStream().write(1));
// but can still write in opposite direction.
server.getOutputStream().write(1);
@ -110,14 +105,7 @@ public class IOTest
server.shutdownInput();
// now we EOF instead of reading -1
try
{
server.getInputStream().read();
fail("exception expected");
}
catch (SocketException expected)
{
}
Assertions.assertThrows(SocketException.class, () -> server.getInputStream().read());
// but can still write in opposite direction.
server.getOutputStream().write(1);
@ -127,14 +115,7 @@ public class IOTest
client.shutdownInput();
// now we EOF instead of reading -1
try
{
client.getInputStream().read();
fail("exception expected");
}
catch (SocketException expected)
{
}
Assertions.assertThrows(SocketException.class, () -> client.getInputStream().read());
// But we can still write at the server (data which will never be read)
server.getOutputStream().write(1);
@ -146,14 +127,7 @@ public class IOTest
server.shutdownOutput();
// and now we can't write
try
{
server.getOutputStream().write(1);
fail("exception expected");
}
catch (SocketException expected)
{
}
Assertions.assertThrows(SocketException.class, () -> server.getOutputStream().write(1));
// but the sockets are still open
assertFalse(client.isClosed());

View File

@ -461,6 +461,7 @@ public class SslConnectionTest
}
catch (SocketTimeoutException e)
{
// no op
}
assertTrue(__onIncompleteFlush.get());
@ -507,6 +508,7 @@ public class SslConnectionTest
}
catch (SocketTimeoutException e)
{
// no op
}
__blockFor.set(0);

View File

@ -18,12 +18,6 @@
package org.eclipse.jetty.jaas.spi;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.not;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.io.File;
import java.util.HashMap;
@ -33,6 +27,12 @@ import org.eclipse.jetty.jaas.callback.DefaultCallbackHandler;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.not;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class PropertyFileLoginModuleTest
{
@Test

View File

@ -472,9 +472,9 @@ public class TestJNDI
((Context)zzz.lookup("java:comp")).bind("crud2", "xxx2");
fail("Should not be able to write to locked context");
}
catch (NamingException ne)
catch (NamingException e)
{
assertThat(ne.getMessage(), Matchers.containsString("immutable"));
assertThat(e.getMessage(), Matchers.containsString("immutable"));
}
finally
{
@ -492,9 +492,9 @@ public class TestJNDI
((Context)zzz.lookup("java:comp")).bind("foo", "bar");
fail("Should not be able to write to locked context");
}
catch (NamingException ne)
catch (NamingException e)
{
assertThat(ne.getMessage(), Matchers.containsString("immutable"));
assertThat(e.getMessage(), Matchers.containsString("immutable"));
}
finally
{

View File

@ -73,8 +73,8 @@ public class TestGetContent
url += pathToCheck;
}
String response = httpClient.GET(url).getContentAsString();
assertTrue(response.contains(contentCheck), "it test " + System.getProperty("maven.it.name")
+ ", response not contentCheck: " + contentCheck + ", response:" + response);
assertTrue(response.contains(contentCheck), "it test " + System.getProperty("maven.it.name") +
", response not contentCheck: " + contentCheck + ", response:" + response);
System.out.println("contentCheck");
}
if (Boolean.getBoolean("helloTestServlet"))

View File

@ -1,10 +1,10 @@
<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<!-- ============================================================= --><!-- Configure the Jetty Server instance with an ID "Server" --><!-- by adding a HTTP connector. --><!-- This configuration must be used in conjunction with jetty.xml --><!-- ============================================================= -->
<!-- ============================================================= --><!-- Configure the Jetty Server instance with an ID "Server" --><!-- by adding an HTTP connector. --><!-- This configuration must be used in conjunction with jetty.xml --><!-- ============================================================= -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<!-- =========================================================== -->
<!-- Add a HTTP Connector. -->
<!-- Add an HTTP Connector. -->
<!-- Configure an o.e.j.server.ServerConnector with a single -->
<!-- HttpConnectionFactory instance using the common httpConfig -->
<!-- instance defined in jetty.xml -->

View File

@ -1,10 +1,10 @@
<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<!-- ============================================================= --><!-- Configure the Jetty Server instance with an ID "Server" --><!-- by adding a HTTP connector. --><!-- This configuration must be used in conjunction with jetty.xml --><!-- ============================================================= -->
<!-- ============================================================= --><!-- Configure the Jetty Server instance with an ID "Server" --><!-- by adding an HTTP connector. --><!-- This configuration must be used in conjunction with jetty.xml --><!-- ============================================================= -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<!-- =========================================================== -->
<!-- Add a HTTP Connector. -->
<!-- Add an HTTP Connector. -->
<!-- Configure an o.e.j.server.ServerConnector with a single -->
<!-- HttpConnectionFactory instance using the common httpConfig -->
<!-- instance defined in jetty.xml -->

View File

@ -1,10 +1,10 @@
<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<!-- ============================================================= --><!-- Configure the Jetty Server instance with an ID "Server" --><!-- by adding a HTTP connector. --><!-- This configuration must be used in conjunction with jetty.xml --><!-- ============================================================= -->
<!-- ============================================================= --><!-- Configure the Jetty Server instance with an ID "Server" --><!-- by adding an HTTP connector. --><!-- This configuration must be used in conjunction with jetty.xml --><!-- ============================================================= -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<!-- =========================================================== -->
<!-- Add a HTTP Connector. -->
<!-- Add an HTTP Connector. -->
<!-- Configure an o.e.j.server.ServerConnector with a single -->
<!-- HttpConnectionFactory instance using the common httpConfig -->
<!-- instance defined in jetty.xml -->

View File

@ -1,10 +1,10 @@
<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<!-- ============================================================= --><!-- Configure the Jetty Server instance with an ID "Server" --><!-- by adding a HTTP connector. --><!-- This configuration must be used in conjunction with jetty.xml --><!-- ============================================================= -->
<!-- ============================================================= --><!-- Configure the Jetty Server instance with an ID "Server" --><!-- by adding an HTTP connector. --><!-- This configuration must be used in conjunction with jetty.xml --><!-- ============================================================= -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<!-- =========================================================== -->
<!-- Add a HTTP Connector. -->
<!-- Add an HTTP Connector. -->
<!-- Configure an o.e.j.server.ServerConnector with a single -->
<!-- HttpConnectionFactory instance using the common httpConfig -->
<!-- instance defined in jetty.xml -->

View File

@ -1,10 +1,10 @@
<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<!-- ============================================================= --><!-- Configure the Jetty Server instance with an ID "Server" --><!-- by adding a HTTP connector. --><!-- This configuration must be used in conjunction with jetty.xml --><!-- ============================================================= -->
<!-- ============================================================= --><!-- Configure the Jetty Server instance with an ID "Server" --><!-- by adding an HTTP connector. --><!-- This configuration must be used in conjunction with jetty.xml --><!-- ============================================================= -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<!-- =========================================================== -->
<!-- Add a HTTP Connector. -->
<!-- Add an HTTP Connector. -->
<!-- Configure an o.e.j.server.ServerConnector with a single -->
<!-- HttpConnectionFactory instance using the common httpConfig -->
<!-- instance defined in jetty.xml -->

View File

@ -1,10 +1,10 @@
<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<!-- ============================================================= --><!-- Configure the Jetty Server instance with an ID "Server" --><!-- by adding a HTTP connector. --><!-- This configuration must be used in conjunction with jetty.xml --><!-- ============================================================= -->
<!-- ============================================================= --><!-- Configure the Jetty Server instance with an ID "Server" --><!-- by adding an HTTP connector. --><!-- This configuration must be used in conjunction with jetty.xml --><!-- ============================================================= -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<!-- =========================================================== -->
<!-- Add a HTTP Connector. -->
<!-- Add an HTTP Connector. -->
<!-- Configure an o.e.j.server.ServerConnector with a single -->
<!-- HttpConnectionFactory instance using the common httpConfig -->
<!-- instance defined in jetty.xml -->

View File

@ -1,10 +1,10 @@
<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<!-- ============================================================= --><!-- Configure the Jetty Server instance with an ID "Server" --><!-- by adding a HTTP connector. --><!-- This configuration must be used in conjunction with jetty.xml --><!-- ============================================================= -->
<!-- ============================================================= --><!-- Configure the Jetty Server instance with an ID "Server" --><!-- by adding an HTTP connector. --><!-- This configuration must be used in conjunction with jetty.xml --><!-- ============================================================= -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<!-- =========================================================== -->
<!-- Add a HTTP Connector. -->
<!-- Add an HTTP Connector. -->
<!-- Configure an o.e.j.server.ServerConnector with a single -->
<!-- HttpConnectionFactory instance using the common httpConfig -->
<!-- instance defined in jetty.xml -->

View File

@ -1,10 +1,10 @@
<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<!-- ============================================================= --><!-- Configure the Jetty Server instance with an ID "Server" --><!-- by adding a HTTP connector. --><!-- This configuration must be used in conjunction with jetty.xml --><!-- ============================================================= -->
<!-- ============================================================= --><!-- Configure the Jetty Server instance with an ID "Server" --><!-- by adding an HTTP connector. --><!-- This configuration must be used in conjunction with jetty.xml --><!-- ============================================================= -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<!-- =========================================================== -->
<!-- Add a HTTP Connector. -->
<!-- Add an HTTP Connector. -->
<!-- Configure an o.e.j.server.ServerConnector with a single -->
<!-- HttpConnectionFactory instance using the common httpConfig -->
<!-- instance defined in jetty.xml -->

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<!-- ============================================================= --><!-- Configure a HTTP2 on the ssl connector. --><!-- ============================================================= -->
<!-- ============================================================= --><!-- Configure an HTTP2 on the ssl connector. --><!-- ============================================================= -->
<Configure id="sslConnector" class="org.eclipse.jetty.server.ServerConnector">
<Call name="addConnectionFactory">
<Arg>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<!-- ============================================================= --><!-- Configure a HTTP2 on the ssl connector. --><!-- ============================================================= -->
<!-- ============================================================= --><!-- Configure an HTTP2 on the ssl connector. --><!-- ============================================================= -->
<Configure id="sslConnector" class="org.eclipse.jetty.server.ServerConnector">
<Call name="addConnectionFactory">
<Arg>

View File

@ -1,6 +1,6 @@
<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<!-- ============================================================= --><!-- Configure a HTTPS connector. --><!-- This configuration must be used in conjunction with jetty.xml --><!-- and jetty-ssl.xml. --><!-- ============================================================= -->
<!-- ============================================================= --><!-- Configure an HTTPS connector. --><!-- This configuration must be used in conjunction with jetty.xml --><!-- and jetty-ssl.xml. --><!-- ============================================================= -->
<Configure id="sslConnector" class="org.eclipse.jetty.server.ServerConnector">
<Call name="addIfAbsentConnectionFactory">

View File

@ -9,7 +9,7 @@
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<!-- =========================================================== -->
<!-- Add a SSL Connector with no protocol factories -->
<!-- Add an SSL Connector with no protocol factories -->
<!-- =========================================================== -->
<Call name="addConnector">
<Arg>

View File

@ -24,6 +24,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
@ -113,15 +114,15 @@ public class TestOSGiUtil
String mavenRepoPath = System.getProperty("mavenRepoPath");
if (!StringUtil.isBlank(mavenRepoPath))
{
res.add( systemProperty( "org.ops4j.pax.url.mvn.localRepository" ).value( mavenRepoPath ) );
res.add( systemProperty( "org.ops4j.pax.url.mvn.defaultRepositories" ).value( "file://" + mavenRepoPath + "@id=local.repo") );
res.add( systemProperty( "org.ops4j.pax.url.mvn.useFallbackRepositories").value( Boolean.FALSE.toString() ) );
res.add( systemProperty( "org.ops4j.pax.url.mvn.repositories").value( "+https://repo1.maven.org/maven2@id=maven.central.repo" ) );
res.add(systemProperty("org.ops4j.pax.url.mvn.localRepository").value(mavenRepoPath));
res.add(systemProperty("org.ops4j.pax.url.mvn.defaultRepositories").value("file://" + mavenRepoPath + "@id=local.repo"));
res.add(systemProperty("org.ops4j.pax.url.mvn.useFallbackRepositories").value(Boolean.FALSE.toString()));
res.add(systemProperty("org.ops4j.pax.url.mvn.repositories").value("+https://repo1.maven.org/maven2@id=maven.central.repo"));
}
String settingsFilePath = System.getProperty("settingsFilePath");
if (!StringUtil.isBlank(settingsFilePath))
{
res.add( systemProperty( "org.ops4j.pax.url.mvn.settings" ).value( System.getProperty( "settingsFilePath" ) ) );
res.add(systemProperty("org.ops4j.pax.url.mvn.settings").value(System.getProperty("settingsFilePath")));
}
res.add(mavenBundle().groupId("org.ow2.asm").artifactId("asm").versionAsInProject().start());
res.add(mavenBundle().groupId("org.ow2.asm").artifactId("asm-commons").versionAsInProject().start());
@ -194,11 +195,11 @@ public class TestOSGiUtil
for (Bundle b : bundleContext.getBundles())
{
Bundle prevBundle = _bundles.put(b.getSymbolicName(), b);
String err = prevBundle != null ? "2 versions of the bundle " + b.getSymbolicName()
+ " "
+ b.getHeaders().get("Bundle-Version")
+ " and "
+ prevBundle.getHeaders().get("Bundle-Version") : "";
String err = prevBundle != null ? "2 versions of the bundle " + b.getSymbolicName() +
" " +
b.getHeaders().get("Bundle-Version") +
" and " +
prevBundle.getHeaders().get("Bundle-Version") : "";
assertNull(err, prevBundle);
}
return _bundles.get(symbolicName);
@ -229,16 +230,16 @@ public class TestOSGiUtil
{
diagnoseNonActiveOrNonResolvedBundle(b);
}
assertTrue("Bundle: " + b
+ " (state should be "
+ "ACTIVE["
+ Bundle.ACTIVE
+ "] or RESOLVED["
+ Bundle.RESOLVED
+ "]"
+ ", but was ["
+ b.getState()
+ "])", (b.getState() == Bundle.ACTIVE) || (b.getState() == Bundle.RESOLVED));
assertTrue("Bundle: " + b +
" (state should be " +
"ACTIVE[" +
Bundle.ACTIVE +
"] or RESOLVED[" +
Bundle.RESOLVED +
"]" +
", but was [" +
b.getState() +
"])", (b.getState() == Bundle.ACTIVE) || (b.getState() == Bundle.RESOLVED));
}
}

View File

@ -18,20 +18,15 @@
package org.eclipse.jetty.plus.annotation;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.anEmptyMap;
import static org.hamcrest.Matchers.hasEntry;
import static org.hamcrest.Matchers.hasKey;
import static org.hamcrest.Matchers.hasSize;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.fail;
import java.lang.reflect.Method;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;
import static org.junit.jupiter.api.Assertions.fail;
public class LifeCycleCallbackCollectionTest
{

View File

@ -680,6 +680,14 @@ public abstract class AbstractProxyServlet extends HttpServlet
catch (Exception e)
{
_log.ignore(e);
try
{
proxyResponse.sendError(-1);
}
catch (Exception e2)
{
_log.ignore(e2);
}
}
finally
{

View File

@ -1533,7 +1533,7 @@ public class AsyncMiddleManServletTest
return out.toByteArray();
}
private static abstract class HrefTransformer implements AsyncMiddleManServlet.ContentTransformer
private abstract static class HrefTransformer implements AsyncMiddleManServlet.ContentTransformer
{
private static final String PREFIX = "http://localhost/q=";
private final HrefParser parser = new HrefParser();

View File

@ -141,9 +141,11 @@ public class ReverseProxyTest
}
});
startProxy(new HashMap<String, String>()
{{
put("preserveHost", "true");
}});
{
{
put("preserveHost", "true");
}
});
startClient();
ContentResponse response = client.newRequest("localhost", proxyConnector.getLocalPort()).send();

View File

@ -22,6 +22,8 @@ import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.annotation.Name;
/**
@ -79,11 +81,20 @@ public class ResponsePatternRule extends PatternRule
// status code 400 and up are error codes
if (code >= 400)
{
response.sendError(code, _reason);
if (!StringUtil.isBlank(_reason))
{
// use both setStatusWithReason (to set the reason) and sendError to set the message
Request.getBaseRequest(request).getResponse().setStatusWithReason(code, _reason);
response.sendError(code, _reason);
}
else
{
response.sendError(code);
}
}
else
{
response.setStatus(code);
response.setStatus(code, _reason);
}
return target;
}

View File

@ -22,6 +22,8 @@ import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@ -88,7 +90,13 @@ public class ValidUrlRule extends Rule
// status code 400 and up are error codes so include a reason
if (code >= 400)
{
response.sendError(code, _reason);
if (StringUtil.isBlank(_reason))
response.sendError(code);
else
{
Request.getBaseRequest(request).getResponse().setStatusWithReason(code, _reason);
response.sendError(code, _reason);
}
}
else
{

View File

@ -42,7 +42,7 @@ public class HeaderPatternRuleTest extends AbstractRuleTestCase
public void testHeaderWithTextValues() throws IOException
{
// different keys
String headers[][] = {
String[][] headers = {
{"hnum#1", "test1"},
{"hnum#2", "2test2"},
{"hnum#3", "test3"}
@ -53,7 +53,7 @@ public class HeaderPatternRuleTest extends AbstractRuleTestCase
@Test
public void testHeaderWithNumberValues() throws IOException
{
String headers[][] = {
String[][] headers = {
{"hello", "1"},
{"hello", "-1"},
{"hello", "100"},
@ -70,7 +70,7 @@ public class HeaderPatternRuleTest extends AbstractRuleTestCase
@Test
public void testHeaderOverwriteValues() throws IOException
{
String headers[][] = {
String[][] headers = {
{"size", "100"},
{"size", "200"},
{"size", "300"},
@ -100,7 +100,7 @@ public class HeaderPatternRuleTest extends AbstractRuleTestCase
assertEquals("abba1", _response.getHeader("title1"));
}
private void assertHeaders(String headers[][]) throws IOException
private void assertHeaders(String[][] headers) throws IOException
{
for (String[] header : headers)
{

View File

@ -43,7 +43,7 @@ public class HeaderRegexRuleTest extends AbstractRuleTestCase
public void testHeaderWithTextValues() throws IOException
{
// different keys
String headers[][] =
String[][] headers =
{
{"hnum#1", "test1"},
{"hnum#2", "2test2"},
@ -55,7 +55,7 @@ public class HeaderRegexRuleTest extends AbstractRuleTestCase
@Test
public void testHeaderWithNumberValues() throws IOException
{
String headers[][] =
String[][] headers =
{
{"hello", "1"},
{"hello", "-1"},
@ -72,7 +72,7 @@ public class HeaderRegexRuleTest extends AbstractRuleTestCase
@Test
public void testHeaderOverwriteValues() throws IOException
{
String headers[][] =
String[][] headers =
{
{"size", "100"},
{"size", "200"},
@ -122,7 +122,7 @@ public class HeaderRegexRuleTest extends AbstractRuleTestCase
assertEquals(null, _response.getHeader("cache-control"));
}
private void assertHeaders(String headers[][]) throws IOException
private void assertHeaders(String[][] headers) throws IOException
{
for (String[] header : headers)
{

View File

@ -20,6 +20,8 @@ package org.eclipse.jetty.rewrite.handler;
import java.io.IOException;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.server.Dispatcher;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@ -59,7 +61,7 @@ public class ResponsePatternRuleTest extends AbstractRuleTestCase
_rule.apply(null, _request, _response);
assertEquals(i, _response.getStatus());
assertEquals(null, _response.getReason());
assertEquals("reason" + i, _response.getReason());
}
}
@ -72,7 +74,7 @@ public class ResponsePatternRuleTest extends AbstractRuleTestCase
_rule.apply(null, _request, _response);
assertEquals(i, _response.getStatus());
assertEquals("", _response.getReason());
assertEquals(HttpStatus.getMessage(i), _request.getAttribute(Dispatcher.ERROR_MESSAGE));
super.reset();
}
}
@ -87,7 +89,7 @@ public class ResponsePatternRuleTest extends AbstractRuleTestCase
_rule.apply(null, _request, _response);
assertEquals(i, _response.getStatus());
assertEquals("reason-" + i, _response.getReason());
assertEquals("reason-" + i, _request.getAttribute(Dispatcher.ERROR_MESSAGE));
super.reset();
}
}

View File

@ -37,7 +37,7 @@ public class RewritePatternRuleTest extends AbstractRuleTestCase
{"/foo/bar", "/foo/bar", "/replace"},
{"/foo/bar.txt", "*.txt", "/replace"},
{"/foo/bar/%20x", "/foo/*", "/replace/bar/%20x"},
};
};
private RewritePatternRule _rule;
@BeforeEach

View File

@ -119,7 +119,9 @@ public class ValidUrlRuleTest extends AbstractRuleTestCase
// space
assertTrue(_rule.isValidChar("\u0020".charAt(0)));
// form feed
//@checkstyle-disable-check : IllegalTokenText
assertFalse(_rule.isValidChar("\u000c".charAt(0)));
//@checkstyle-enable-check : IllegalTokenText
}
}

View File

@ -40,7 +40,7 @@
</Call>
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- To add a HTTPS SSL listener -->
<!-- To add an HTTPS SSL listener -->
<!-- see jetty-ssl.xml to add an ssl connector. use -->
<!-- java -jar start.jar etc/jetty-ssl.xml -->
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->

View File

@ -51,7 +51,7 @@ import org.ietf.jgss.Oid;
* of the {@link #getServiceName() service name} and the {@link #getHostName() host name},
* for example {@code HTTP/wonder.com}, using a {@code keyTab} file as the service principal
* credentials.</p>
* <p>Upon receiving a HTTP request, the server tries to authenticate the client
* <p>Upon receiving an HTTP request, the server tries to authenticate the client
* calling {@link #login(String, Object, ServletRequest)} where the GSS APIs are used to
* verify client tokens and (perhaps after a few round-trips) a {@code GSSContext} is
* established.</p>

View File

@ -806,7 +806,7 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr
{
//an exact method name
if (!hasOmissions)
//a http-method does not have http-method-omission to cover the other method names
//an http-method does not have http-method-omission to cover the other method names
uncoveredPaths.add(path);
}
}

View File

@ -39,7 +39,7 @@ import org.eclipse.jetty.util.log.Logger;
*
* When a user has been successfully authenticated with some types
* of Authenticator, the Authenticator stashes a SessionAuthentication
* into a HttpSession to remember that the user is authenticated.
* into an HttpSession to remember that the user is authenticated.
*/
public class SessionAuthentication extends AbstractUserAuthentication
implements Serializable, HttpSessionActivationListener, HttpSessionBindingListener

View File

@ -423,7 +423,7 @@ public class ConstraintTest
assertEquals(1, uncoveredPaths.size());
assertThat("/user/*", is(in(uncoveredPaths)));
//Test an explicitly named method with a http-method-omission to cover all other methods
//Test an explicitly named method with an http-method-omission to cover all other methods
Constraint constraint2a = new Constraint();
constraint2a.setAuthenticate(true);
constraint2a.setName("forbid constraint");
@ -437,7 +437,7 @@ public class ConstraintTest
assertNotNull(uncoveredPaths);
assertEquals(0, uncoveredPaths.size());
//Test a http-method-omission only
//Test an http-method-omission only
Constraint constraint3 = new Constraint();
constraint3.setAuthenticate(true);
constraint3.setName("omit constraint");
@ -1708,7 +1708,7 @@ public class ConstraintTest
{
request.login("admin", "fail");
}
catch (ServletException se)
catch (ServletException e)
{
request.login("admin", "password");
}

View File

@ -44,6 +44,7 @@ import org.junit.jupiter.api.Test;
import static java.nio.charset.StandardCharsets.ISO_8859_1;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
@ -321,7 +322,8 @@ public class SpecExampleConstraintTest
response = _connector.getResponse("POST /ctx/acme/wholesale/index.html HTTP/1.0\r\n" +
"Authorization: Basic " + encodedChris + "\r\n" +
"\r\n");
assertThat(response, startsWith("HTTP/1.1 403 !"));
assertThat(response, startsWith("HTTP/1.1 403 Forbidden"));
assertThat(response, containsString("!Secure"));
//a user in role HOMEOWNER can do a GET
response = _connector.getResponse("GET /ctx/acme/retail/index.html HTTP/1.0\r\n" +

View File

@ -18,14 +18,17 @@
package org.eclipse.jetty.security.authentication;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.server.AbstractConnector;
import org.eclipse.jetty.server.Authentication;
import org.eclipse.jetty.server.HttpChannel;
import org.eclipse.jetty.server.HttpChannelState;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpOutput;
import org.eclipse.jetty.server.Request;
@ -34,6 +37,8 @@ import org.eclipse.jetty.server.Server;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
@ -54,28 +59,34 @@ public class SpnegoAuthenticatorTest
@Test
public void testChallengeSentWithNoAuthorization() throws Exception
{
HttpChannel channel = new HttpChannel(null, new HttpConfiguration(), null, null)
HttpChannel channel = new HttpChannel(new MockConnector(), new HttpConfiguration(), null, null)
{
@Override
public Server getServer()
{
return null;
}
};
Request req = new Request(channel, null);
HttpOutput out = new HttpOutput(channel)
{
@Override
public void close()
protected HttpOutput newHttpOutput()
{
return;
return new HttpOutput(this)
{
@Override
public void close() {}
@Override
public void flush() throws IOException {}
};
}
};
Response res = new Response(channel, out);
Request req = channel.getRequest();
Response res = channel.getResponse();
MetaData.Request metadata = new MetaData.Request(new HttpFields());
metadata.setURI(new HttpURI("http://localhost"));
req.setMetaData(metadata);
assertThat(channel.getState().handling(), is(HttpChannelState.Action.DISPATCH));
assertEquals(Authentication.SEND_CONTINUE, _authenticator.validateRequest(req, res, true));
assertEquals(HttpHeader.NEGOTIATE.asString(), res.getHeader(HttpHeader.WWW_AUTHENTICATE.asString()));
assertEquals(HttpServletResponse.SC_UNAUTHORIZED, res.getStatus());
@ -84,24 +95,29 @@ public class SpnegoAuthenticatorTest
@Test
public void testChallengeSentWithUnhandledAuthorization() throws Exception
{
HttpChannel channel = new HttpChannel(null, new HttpConfiguration(), null, null)
HttpChannel channel = new HttpChannel(new MockConnector(), new HttpConfiguration(), null, null)
{
@Override
public Server getServer()
{
return null;
}
};
Request req = new Request(channel, null);
HttpOutput out = new HttpOutput(channel)
{
@Override
public void close()
protected HttpOutput newHttpOutput()
{
return;
return new HttpOutput(this)
{
@Override
public void close() {}
@Override
public void flush() throws IOException {}
};
}
};
Response res = new Response(channel, out);
Request req = channel.getRequest();
Response res = channel.getResponse();
HttpFields http_fields = new HttpFields();
// Create a bogus Authorization header. We don't care about the actual credentials.
http_fields.add(HttpHeader.AUTHORIZATION, "Basic asdf");
@ -109,6 +125,7 @@ public class SpnegoAuthenticatorTest
metadata.setURI(new HttpURI("http://localhost"));
req.setMetaData(metadata);
assertThat(channel.getState().handling(), is(HttpChannelState.Action.DISPATCH));
assertEquals(Authentication.SEND_CONTINUE, _authenticator.validateRequest(req, res, true));
assertEquals(HttpHeader.NEGOTIATE.asString(), res.getHeader(HttpHeader.WWW_AUTHENTICATE.asString()));
assertEquals(HttpServletResponse.SC_UNAUTHORIZED, res.getStatus());
@ -146,4 +163,29 @@ public class SpnegoAuthenticatorTest
assertEquals("negotiate", _authenticator.getAuthSchemeFromHeader(" negotiate asdfasdf"));
assertEquals("negotiated", _authenticator.getAuthSchemeFromHeader(" negotiated asdfasdf"));
}
class MockConnector extends AbstractConnector
{
public MockConnector()
{
super(new Server() , null, null, null, 0);
}
@Override
protected void accept(int acceptorID) throws IOException, InterruptedException
{
}
@Override
public Object getTransport()
{
return null;
}
@Override
public String dumpSelf()
{
return null;
}
}
}

View File

@ -1,10 +1,10 @@
<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<!-- ============================================================= --><!-- Configure the Jetty Server instance with an ID "Server" --><!-- by adding a HTTP connector. --><!-- This configuration must be used in conjunction with jetty.xml --><!-- ============================================================= -->
<!-- ============================================================= --><!-- Configure the Jetty Server instance with an ID "Server" --><!-- by adding an HTTP connector. --><!-- This configuration must be used in conjunction with jetty.xml --><!-- ============================================================= -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<!-- =========================================================== -->
<!-- Add a HTTP Connector. -->
<!-- Add an HTTP Connector. -->
<!-- Configure an o.e.j.server.ServerConnector with a single -->
<!-- HttpConnectionFactory instance using the common httpConfig -->
<!-- instance defined in jetty.xml -->

View File

@ -1,6 +1,6 @@
<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<!-- ============================================================= --><!-- Configure a HTTPS connector. --><!-- This configuration must be used in conjunction with jetty.xml --><!-- and jetty-ssl.xml. --><!-- ============================================================= -->
<!-- ============================================================= --><!-- Configure an HTTPS connector. --><!-- This configuration must be used in conjunction with jetty.xml --><!-- and jetty-ssl.xml. --><!-- ============================================================= -->
<Configure id="sslConnector" class="org.eclipse.jetty.server.ServerConnector">
<Call name="addIfAbsentConnectionFactory">

View File

@ -4,7 +4,7 @@
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<!-- =========================================================== -->
<!-- Add a SSL Connector with no protocol factories -->
<!-- Add an SSL Connector with no protocol factories -->
<!-- =========================================================== -->
<Call name="addConnector">
<Arg>

View File

@ -11,6 +11,11 @@
<New class="org.eclipse.jetty.server.session.NullSessionCacheFactory">
<Set name="saveOnCreate"><Property name="jetty.session.saveOnCreate" default="false" /></Set>
<Set name="removeUnloadableSessions"><Property name="jetty.session.removeUnloadableSessions" default="false"/></Set>
<Set name="writeThroughMode">
<Call class="org.eclipse.jetty.server.session.NullSessionCache$WriteThroughMode" name="valueOf">
<Arg><Property name="jetty.session.writeThroughMode" default="ON_EXIT"/></Arg>
</Call>
</Set>
</New>
</Arg>
</Call>

Some files were not shown because too many files have changed in this diff Show More