Merge branch 'jetty-http2' into refset

Conflicts:
	jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackEncoderTest.java
This commit is contained in:
Greg Wilkins 2014-07-25 18:33:10 +10:00
commit c13be6d932
193 changed files with 4560 additions and 3898 deletions

View File

@ -1,6 +1,64 @@
jetty-10.0.0-SNAPSHOT
jetty-9.3.0-SNAPSHOT
jetty-9.2.2-SNAPSHOT
jetty-9.2.3-SNAPSHOT
jetty-9.2.2-v20140723 - 23 July 2014
+ 411323 DosFilter/QoSFilter should use AsyncContext rather than
Continuations.
+ 432815 Fixed selector stop race
+ 434536 Improved Customizer javadoc
+ 435322 Fixed Iterating Callback close
+ 435653 encode async dispatched requestURI
+ 435895 jetty spring module is not in distribution
+ 436874 WebSocket client throwing a NullPointer when handling a pong
+ 436894 GzipFilter code cleanup
+ 436916 CGI: "Search docroot for a matching execCmd" logic is wrong
+ 436987 limited range of default acceptors and selectors
+ 437051 Refactor Filter chain handling of Request.isAsyncSupported
+ 437395 Start / Properties in template sections should be default applied for
enabled modules
+ 437419 Allow scanning of META-INF for resources,fragments,tlds for unpacked
jars
+ 437430 jettyXml not consistent between jetty:run and jetty:run-forked
+ 437462 consistent test failure in jetty-start under windows
+ 437706 ServletTester calls LocalConnector method with hardcoded timeout
+ 437800 URLs with single quote and spaces return 404
+ 437996 avoid async status race by not setting 200 on handled
+ 438079 Review garbage creation in 9.2.x series.
+ 438190 findbug improvements
+ 438204 leave IPv6 addresses [] wrapped in getServerName
+ 438327 Remove hard coded Allow from OPTIONS *
+ 438331 AbstractLogger.debug(String,long) infinite loop
+ 438434 ResourceHandler checks aliases
+ 438895 Add mvn jetty:effective-web-xml goal
+ 439066 javadoc setStopAtShutdown
+ 439067 Improved graceful stop timeout handling
+ 439194 Do not configure fake server for jetty:run-forked
+ 439201 GzipFilter and AsyncGzipFilter should strip charset from Content-Type
before making exclusion comparison in doFilter
+ 439369 Deprecate CrossContextPseudoSession
+ 439387 Ensure empty servlet-class never generated for quickstart
+ 439390 Ensure jsp scratchdir is created same way for quickstart and
non-quickstart
+ 439394 load-on-startup with value 0 not preserved for quickstart
+ 439399 Scan tlds for apache jasper standard taglib with jetty-maven-plugin
+ 439438 DataSourceLoginService does not refresh passwords when changed in
database
+ 439507 Possible timing side-channel when comparing MD5-Credentials
+ 439540 setReuseAddress() in ServerConnector.java is not coded properly
+ 439652 GzipHandler super.doStart
+ 439663 Allow mappings to be declared before servlet/filter
+ 439672 support using Apache commons daemon for managing Jetty
+ 439753 ConstraintSecurityHandler has dead code for processing constraints
+ 439788 CORS filter headers gone between 9.2.0.M0 and 9.2.1 .v20140609 for
ProxyServlet requests.
+ 439809 mvn jetty:jspc cannot find taglibs in dependency jars
+ 439895 No event callback should be invoked after the "failure" callback.
+ 440020 Abort bad proxy responses with sendError(-1)
+ 440038 Content decoding may fail.
+ 440114 ContextHandlerCollection does not skip context wrappers
+ 440122 Remove usages of ForkInvoker.
>>>>>>> origin/master
jetty-9.2.1.v20140609 - 09 June 2014
+ 347110 Supprt ClassFileTransormers in WebAppClassLoader

View File

@ -47,5 +47,6 @@
-->
<module>async-rest</module>
<module>embedded</module>
<module>quickstart</module>
</modules>
</project>

183
examples/quickstart/pom.xml Normal file
View File

@ -0,0 +1,183 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<groupId>org.eclipse.jetty.examples</groupId>
<artifactId>examples-parent</artifactId>
<version>9.3.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>example-jetty-quickstart</artifactId>
<name>Example :: Jetty Quick Start</name>
<description>Jetty Quick Start Example</description>
<url>http://www.eclipse.org/jetty</url>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-webapp</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-jmx</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-plus</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-annotations</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>javax.transaction-api</artifactId>
<version>1.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>test-mock-resources</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.orbit</groupId>
<artifactId>javax.mail.glassfish</artifactId>
<version>1.4.1.v201005082020</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlets</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>test-jndi-webapp</artifactId>
<version>${project.version}</version>
<type>war</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>test-spec-webapp</artifactId>
<version>${project.version}</version>
<type>war</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>test-jetty-webapp</artifactId>
<version>${project.version}</version>
<type>war</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>javax-websocket-server-impl</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-server</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>apache-jsp</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>apache-jstl</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>1.7</version>
<configuration>
<platforms>
<platform>unix</platform>
</platforms>
<programs>
<program>
<id>preconfigure</id>
<mainClass>org.eclipse.jetty.quickstart.PreconfigureQuickStartWar</mainClass>
</program>
<program>
<mainClass>org.eclipse.jetty.quickstart.QuickStartWar</mainClass>
<id>quickstart</id>
</program>
</programs>
</configuration>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-webapp</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy</id>
<phase>generate-resources</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>test-jndi-webapp</artifactId>
<version>${project.version}</version>
<type>war</type>
<overWrite>true</overWrite>
<includes>**</includes>
<outputDirectory>${basedir}/target</outputDirectory>
<destFileName>test-jndi.war</destFileName>
</artifactItem>
<artifactItem>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>test-spec-webapp</artifactId>
<version>${project.version}</version>
<type>war</type>
<overWrite>true</overWrite>
<includes>**</includes>
<outputDirectory>${basedir}/target</outputDirectory>
<destFileName>test-spec.war</destFileName>
</artifactItem>
<artifactItem>
<groupId>org.eclipse.jetty</groupId>
<artifactId>test-jetty-webapp</artifactId>
<version>${project.version}</version>
<type>war</type>
<overWrite>true</overWrite>
<includes>**</includes>
<outputDirectory>${basedir}/target</outputDirectory>
<destFileName>test-standard.war</destFileName>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -43,7 +43,7 @@
</goals>
<configuration>
<instructions>
<Import-Package>javax.servlet.*;version="[2.6.0,3.2)",org.objectweb.asm.*;version=4,*</Import-Package>
<Import-Package>javax.servlet.*;version="[2.6.0,3.2)",org.objectweb.asm.*;version=5,*</Import-Package>
<Require-Capability>osgi.serviceloader; filter:="(osgi.serviceloader=javax.servlet.ServletContainerInitializer)";resolution:=optional;cardinality:=multiple, osgi.extender; filter:="(osgi.extender=osgi.serviceloader.processor)"</Require-Capability>
</instructions>
</configuration>

View File

@ -441,14 +441,14 @@ public class AnnotationConfiguration extends AbstractConfiguration
// Resolve container initializers
List<ContainerInitializer> initializers =
(List<ContainerInitializer>)context.getAttribute(AnnotationConfiguration.CONTAINER_INITIALIZERS);
(List<ContainerInitializer>)context.getAttribute(AnnotationConfiguration.CONTAINER_INITIALIZERS);
if (initializers != null && initializers.size()>0)
{
Map<String, Set<String>> map = ( Map<String, Set<String>>) context.getAttribute(AnnotationConfiguration.CLASS_INHERITANCE_MAP);
if (map == null)
LOG.warn ("ServletContainerInitializers: detected. Class hierarchy: empty");
for (ContainerInitializer i : initializers)
i.resolveClasses(context,map);
i.resolveClasses(context,map);
}
}

View File

@ -251,7 +251,7 @@ public class GZIPContentDecoder implements ContentDecoder
else
{
// Accumulate inflated bytes and loop to see if we have finished
byte[] newOutput = Arrays.copyOf(output, output.length+decoded);
byte[] newOutput = Arrays.copyOf(output, output.length + decoded);
System.arraycopy(bytes, 0, newOutput, output.length, decoded);
output = newOutput;
}

View File

@ -21,6 +21,7 @@ package org.eclipse.jetty.client;
import java.io.IOException;
import java.net.URI;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
@ -49,9 +50,8 @@ import org.eclipse.jetty.util.log.Logger;
* is available</li>
* <li>{@link #responseHeader(HttpExchange, HttpField)}, when a 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; this is the only
* method that may be invoked multiple times with different buffers containing different content</li>
* <li>{@link #responseSuccess(HttpExchange)}, when the response is complete</li>
* <li>{@link #responseContent(HttpExchange, ByteBuffer, Callback)}, when HTTP content is available</li>
* <li>{@link #responseSuccess(HttpExchange)}, when the response is successful</li>
* </ol>
* At any time, subclasses may invoke {@link #responseFailure(Throwable)} to indicate that the response has failed
* (for example, because of I/O exceptions).
@ -69,7 +69,8 @@ public abstract class HttpReceiver
private final AtomicReference<ResponseState> responseState = new AtomicReference<>(ResponseState.IDLE);
private final HttpChannel channel;
private volatile ContentDecoder decoder;
private ContentDecoder decoder;
private Throwable failure;
protected HttpReceiver(HttpChannel channel)
{
@ -104,7 +105,7 @@ public abstract class HttpReceiver
*/
protected boolean responseBegin(HttpExchange exchange)
{
if (!updateResponseState(ResponseState.IDLE, ResponseState.BEGIN))
if (!updateResponseState(ResponseState.IDLE, ResponseState.TRANSIENT))
return false;
HttpConversation conversation = exchange.getConversation();
@ -127,6 +128,9 @@ public abstract class HttpReceiver
ResponseNotifier notifier = destination.getResponseNotifier();
notifier.notifyBegin(conversation.getResponseListeners(), response);
if (!updateResponseState(ResponseState.TRANSIENT, ResponseState.BEGIN))
terminateResponse(exchange, failure);
return true;
}
@ -152,7 +156,7 @@ public abstract class HttpReceiver
case BEGIN:
case HEADER:
{
if (updateResponseState(current, ResponseState.HEADER))
if (updateResponseState(current, ResponseState.TRANSIENT))
break out;
break;
}
@ -188,6 +192,9 @@ public abstract class HttpReceiver
}
}
if (!updateResponseState(ResponseState.TRANSIENT, ResponseState.HEADER))
terminateResponse(exchange, failure);
return true;
}
@ -228,7 +235,7 @@ public abstract class HttpReceiver
case BEGIN:
case HEADER:
{
if (updateResponseState(current, ResponseState.HEADERS))
if (updateResponseState(current, ResponseState.TRANSIENT))
break out;
break;
}
@ -261,6 +268,9 @@ public abstract class HttpReceiver
}
}
if (!updateResponseState(ResponseState.TRANSIENT, ResponseState.HEADERS))
terminateResponse(exchange, failure);
return true;
}
@ -273,7 +283,7 @@ public abstract class HttpReceiver
* @param buffer the response HTTP content buffer
* @return whether the processing should continue
*/
protected boolean responseContent(HttpExchange exchange, ByteBuffer buffer, Callback callback)
protected boolean responseContent(HttpExchange exchange, ByteBuffer buffer, final Callback callback)
{
out: while (true)
{
@ -283,7 +293,7 @@ public abstract class HttpReceiver
case HEADERS:
case CONTENT:
{
if (updateResponseState(current, ResponseState.CONTENT))
if (updateResponseState(current, ResponseState.TRANSIENT))
break out;
break;
}
@ -298,19 +308,49 @@ public abstract class HttpReceiver
if (LOG.isDebugEnabled())
LOG.debug("Response content {}{}{}", response, System.lineSeparator(), BufferUtil.toDetailString(buffer));
ResponseNotifier notifier = getHttpDestination().getResponseNotifier();
List<Response.ResponseListener> listeners = exchange.getConversation().getResponseListeners();
ContentDecoder decoder = this.decoder;
if (decoder != null)
if (decoder == null)
{
buffer = decoder.decode(buffer);
// TODO If the decoder consumes all the content, should we return here?
if (LOG.isDebugEnabled())
LOG.debug("Response content decoded ({}) {}{}{}", decoder, response, System.lineSeparator(), BufferUtil.toDetailString(buffer));
notifier.notifyContent(listeners, response, buffer, callback);
}
else
{
List<ByteBuffer> decodeds = new ArrayList<>(2);
while (buffer.hasRemaining())
{
ByteBuffer decoded = decoder.decode(buffer);
if (!decoded.hasRemaining())
continue;
decodeds.add(decoded);
if (LOG.isDebugEnabled())
LOG.debug("Response content decoded ({}) {}{}{}", decoder, response, System.lineSeparator(), BufferUtil.toDetailString(decoded));
}
if (decodeds.isEmpty())
{
callback.succeeded();
}
else
{
Callback partial = new Callback.Adapter()
{
@Override
public void failed(Throwable x)
{
callback.failed(x);
}
};
for (int i = 1, size = decodeds.size(); i <= size; ++i)
notifier.notifyContent(listeners, response, decodeds.get(i - 1), i < size ? partial : callback);
}
}
ResponseNotifier notifier = getHttpDestination().getResponseNotifier();
notifier.notifyContent(exchange.getConversation().getResponseListeners(), response, buffer, callback);
if (!updateResponseState(ResponseState.TRANSIENT, ResponseState.CONTENT))
terminateResponse(exchange, failure);
return true;
}
@ -332,16 +372,17 @@ public abstract class HttpReceiver
if (!completed)
return false;
// Reset to be ready for another response
responseState.set(ResponseState.IDLE);
// Reset to be ready for another response.
reset();
// Mark atomically the response as terminated and succeeded,
// with respect to concurrency between request and response.
// If there is a non-null result, then both sender and
// receiver are reset and ready to be reused, and the
// connection closed/pooled (depending on the transport).
Result result = exchange.terminateResponse(null);
// It is important to notify *after* we reset and terminate
// because the notification may trigger another request/response.
HttpResponse response = exchange.getResponse();
if (LOG.isDebugEnabled())
LOG.debug("Response success {}", response);
@ -349,17 +390,7 @@ public abstract class HttpReceiver
ResponseNotifier notifier = getHttpDestination().getResponseNotifier();
notifier.notifySuccess(listeners, response);
if (result != null)
{
boolean ordered = getHttpDestination().getHttpClient().isStrictEventOrdering();
if (!ordered)
channel.exchangeTerminated(result);
if (LOG.isDebugEnabled())
LOG.debug("Request/Response succeeded {}", response);
notifier.notifyComplete(listeners, result);
if (ordered)
channel.exchangeTerminated(result);
}
terminateResponse(exchange, result);
return true;
}
@ -388,7 +419,20 @@ public abstract class HttpReceiver
if (!completed)
return false;
// Dispose to avoid further responses
this.failure = failure;
// Update the state to avoid more response processing.
boolean fail;
while (true)
{
ResponseState current = responseState.get();
if (updateResponseState(current, ResponseState.FAILURE))
{
fail = current != ResponseState.TRANSIENT;
break;
}
}
dispose();
// Mark atomically the response as terminated and failed,
@ -402,19 +446,45 @@ public abstract class HttpReceiver
ResponseNotifier notifier = getHttpDestination().getResponseNotifier();
notifier.notifyFailure(listeners, response, failure);
if (fail)
{
terminateResponse(exchange, result);
}
else
{
if (LOG.isDebugEnabled())
LOG.debug("Concurrent failure: response termination skipped, performed by helpers");
}
return true;
}
private void terminateResponse(HttpExchange exchange, Throwable failure)
{
Result result = exchange.terminateResponse(failure);
terminateResponse(exchange, result);
}
private void terminateResponse(HttpExchange exchange, Result result)
{
HttpResponse response = exchange.getResponse();
if (LOG.isDebugEnabled())
LOG.debug("Response complete {}", response);
if (result != null)
{
boolean ordered = getHttpDestination().getHttpClient().isStrictEventOrdering();
if (!ordered)
channel.exchangeTerminated(result);
if (LOG.isDebugEnabled())
LOG.debug("Request/Response failed {}", response);
LOG.debug("Request/Response {} {}", failure == null ? "succeeded" : "failed", response);
List<Response.ResponseListener> listeners = exchange.getConversation().getResponseListeners();
ResponseNotifier notifier = getHttpDestination().getResponseNotifier();
notifier.notifyComplete(listeners, result);
if (ordered)
channel.exchangeTerminated(result);
}
return true;
}
/**
@ -427,7 +497,6 @@ public abstract class HttpReceiver
protected void reset()
{
decoder = null;
responseState.set(ResponseState.IDLE);
}
/**
@ -440,7 +509,6 @@ public abstract class HttpReceiver
protected void dispose()
{
decoder = null;
responseState.set(ResponseState.FAILURE);
}
public boolean abort(Throwable cause)
@ -464,6 +532,10 @@ public abstract class HttpReceiver
*/
private enum ResponseState
{
/**
* One of the response*() methods is being executed.
*/
TRANSIENT,
/**
* The response is not yet received, the initial state
*/

View File

@ -65,7 +65,8 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
private final IteratingCallback contentCallback = new ContentCallback();
private final Callback lastCallback = new LastContentCallback();
private final HttpChannel channel;
private volatile HttpContent content;
private HttpContent content;
private Throwable failure;
protected HttpSender(HttpChannel channel)
{
@ -197,34 +198,40 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
protected boolean queuedToBegin(Request request)
{
if (!updateRequestState(RequestState.QUEUED, RequestState.BEGIN))
if (!updateRequestState(RequestState.QUEUED, RequestState.TRANSIENT))
return false;
if (LOG.isDebugEnabled())
LOG.debug("Request begin {}", request);
RequestNotifier notifier = getHttpChannel().getHttpDestination().getRequestNotifier();
notifier.notifyBegin(request);
if (!updateRequestState(RequestState.TRANSIENT, RequestState.BEGIN))
terminateRequest(getHttpExchange(), failure, false);
return true;
}
protected boolean beginToHeaders(Request request)
{
if (!updateRequestState(RequestState.BEGIN, RequestState.HEADERS))
if (!updateRequestState(RequestState.BEGIN, RequestState.TRANSIENT))
return false;
if (LOG.isDebugEnabled())
LOG.debug("Request headers {}{}{}", request, System.getProperty("line.separator"), request.getHeaders().toString().trim());
RequestNotifier notifier = getHttpChannel().getHttpDestination().getRequestNotifier();
notifier.notifyHeaders(request);
if (!updateRequestState(RequestState.TRANSIENT, RequestState.HEADERS))
terminateRequest(getHttpExchange(), failure, false);
return true;
}
protected boolean headersToCommit(Request request)
{
if (!updateRequestState(RequestState.HEADERS, RequestState.COMMIT))
if (!updateRequestState(RequestState.HEADERS, RequestState.TRANSIENT))
return false;
if (LOG.isDebugEnabled())
LOG.debug("Request committed {}", request);
RequestNotifier notifier = getHttpChannel().getHttpDestination().getRequestNotifier();
notifier.notifyCommit(request);
if (!updateRequestState(RequestState.TRANSIENT, RequestState.COMMIT))
terminateRequest(getHttpExchange(), failure, true);
return true;
}
@ -236,21 +243,19 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
case COMMIT:
case CONTENT:
{
if (!updateRequestState(current, RequestState.CONTENT))
if (!updateRequestState(current, RequestState.TRANSIENT_CONTENT))
return false;
if (LOG.isDebugEnabled())
LOG.debug("Request content {}{}{}", request, System.getProperty("line.separator"), BufferUtil.toDetailString(content));
RequestNotifier notifier = getHttpChannel().getHttpDestination().getRequestNotifier();
notifier.notifyContent(request, content);
if (!updateRequestState(RequestState.TRANSIENT_CONTENT, RequestState.CONTENT))
terminateRequest(getHttpExchange(), failure, true);
return true;
}
case FAILURE:
{
return false;
}
default:
{
throw new IllegalStateException(current.toString());
return false;
}
}
}
@ -269,43 +274,28 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
if (!completed)
return false;
// Reset to be ready for another request
requestState.set(RequestState.QUEUED);
// Reset to be ready for another request.
reset();
// Mark atomically the request as terminated and succeeded,
// with respect to concurrency between request and response.
Result result = exchange.terminateRequest(null);
// It is important to notify completion *after* we reset because
// the notification may trigger another request/response
Request request = exchange.getRequest();
if (LOG.isDebugEnabled())
LOG.debug("Request success {}", request);
HttpDestination destination = getHttpChannel().getHttpDestination();
destination.getRequestNotifier().notifySuccess(exchange.getRequest());
if (result != null)
{
boolean ordered = destination.getHttpClient().isStrictEventOrdering();
if (!ordered)
channel.exchangeTerminated(result);
if (LOG.isDebugEnabled())
LOG.debug("Request/Response succeded {}", request);
HttpConversation conversation = exchange.getConversation();
destination.getResponseNotifier().notifyComplete(conversation.getResponseListeners(), result);
if (ordered)
channel.exchangeTerminated(result);
}
terminateRequest(exchange, null, true, result);
return true;
}
case FAILURE:
{
return false;
}
default:
{
throw new IllegalStateException(current.toString());
return false;
}
}
}
@ -322,8 +312,22 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
if (!completed)
return false;
// Dispose to avoid further requests
RequestState requestState = dispose();
this.failure = failure;
// Update the state to avoid more request processing.
RequestState current;
boolean fail;
while (true)
{
current = requestState.get();
if (updateRequestState(current, RequestState.FAILURE))
{
fail = current != RequestState.TRANSIENT && current != RequestState.TRANSIENT_CONTENT;
break;
}
}
dispose();
// Mark atomically the request as terminated and failed,
// with respect to concurrency between request and response.
@ -335,8 +339,36 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
HttpDestination destination = getHttpChannel().getHttpDestination();
destination.getRequestNotifier().notifyFailure(request, failure);
boolean notCommitted = isBeforeCommit(requestState);
if (result == null && notCommitted && request.getAbortCause() == null)
if (fail)
{
terminateRequest(exchange, failure, !isBeforeCommit(current), result);
}
else
{
if (LOG.isDebugEnabled())
LOG.debug("Concurrent failure: request termination skipped, performed by helpers");
}
return true;
}
private void terminateRequest(HttpExchange exchange, Throwable failure, boolean committed)
{
if (exchange != null)
{
Result result = exchange.terminateRequest(failure);
terminateRequest(exchange, failure, committed, result);
}
}
private void terminateRequest(HttpExchange exchange, Throwable failure, boolean committed, Result result)
{
Request request = exchange.getRequest();
if (LOG.isDebugEnabled())
LOG.debug("Terminating request {}", request);
if (failure != null && !committed && result == null && request.getAbortCause() == null)
{
// Complete the response from here
if (exchange.responseComplete())
@ -349,18 +381,17 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
if (result != null)
{
HttpDestination destination = getHttpChannel().getHttpDestination();
boolean ordered = destination.getHttpClient().isStrictEventOrdering();
if (!ordered)
channel.exchangeTerminated(result);
if (LOG.isDebugEnabled())
LOG.debug("Request/Response failed {}", request);
LOG.debug("Request/Response {} {}", failure == null ? "succeeded" : "failed", request);
HttpConversation conversation = exchange.getConversation();
destination.getResponseNotifier().notifyComplete(conversation.getResponseListeners(), result);
if (ordered)
channel.exchangeTerminated(result);
}
return true;
}
/**
@ -398,23 +429,14 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
{
content.close();
content = null;
requestState.set(RequestState.QUEUED);
senderState.set(SenderState.IDLE);
}
protected RequestState dispose()
protected void dispose()
{
while (true)
{
RequestState current = requestState.get();
if (updateRequestState(current, RequestState.FAILURE))
{
HttpContent content = this.content;
if (content != null)
content.close();
return current;
}
}
HttpContent content = this.content;
if (content != null)
content.close();
}
public void proceed(HttpExchange exchange, Throwable failure)
@ -485,7 +507,7 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
return abortable && anyToFailure(failure);
}
protected boolean updateRequestState(RequestState from, RequestState to)
private boolean updateRequestState(RequestState from, RequestState to)
{
boolean updated = requestState.compareAndSet(from, to);
if (!updated)
@ -505,6 +527,7 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
{
switch (requestState)
{
case TRANSIENT:
case QUEUED:
case BEGIN:
case HEADERS:
@ -518,6 +541,7 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
{
switch (requestState)
{
case TRANSIENT_CONTENT:
case COMMIT:
case CONTENT:
return true;
@ -534,8 +558,16 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
/**
* The request states {@link HttpSender} goes through when sending a request.
*/
protected enum RequestState
private enum RequestState
{
/**
* One of the state transition methods is being executed.
*/
TRANSIENT,
/**
* The content transition method is being executed.
*/
TRANSIENT_CONTENT,
/**
* The request is queued, the initial state
*/

View File

@ -196,12 +196,11 @@ public class HttpSenderOverHTTP extends HttpSender
}
@Override
protected RequestState dispose()
protected void dispose()
{
generator.abort();
RequestState result = super.dispose();
super.dispose();
shutdownOutput();
return result;
}
private void shutdownOutput()

View File

@ -144,28 +144,41 @@ public class InputStreamResponseListener extends Listener.Adapter
}
}
@Override
public void onSuccess(Response response)
{
if (LOG.isDebugEnabled())
LOG.debug("Queuing end of content {}{}", EOF, "");
queue.offer(EOF);
signal();
}
@Override
public void onFailure(Response response, Throwable failure)
{
fail(failure);
signal();
}
@Override
public void onComplete(Result result)
{
if (result.isFailed() && failure == null)
fail(result.getFailure());
this.result = result;
if (result.isSucceeded())
{
if (LOG.isDebugEnabled())
LOG.debug("Queuing end of content {}{}", EOF, "");
queue.offer(EOF);
}
else
{
if (LOG.isDebugEnabled())
LOG.debug("Queuing failure {} {}", FAILURE, failure);
queue.offer(FAILURE);
this.failure = result.getFailure();
responseLatch.countDown();
}
resultLatch.countDown();
signal();
}
private void fail(Throwable failure)
{
if (LOG.isDebugEnabled())
LOG.debug("Queuing failure {} {}", FAILURE, failure);
queue.offer(FAILURE);
this.failure = failure;
responseLatch.countDown();
}
protected boolean await()
{
try

View File

@ -93,7 +93,7 @@ public class HttpClientCustomProxyTest
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
baseRequest.setHandled(true);
if (!URI.create(baseRequest.getUri().toString()).isAbsolute())
if (!URI.create(baseRequest.getHttpURI().toString()).isAbsolute())
response.setStatus(HttpServletResponse.SC_USE_PROXY);
else if (serverHost.equals(request.getServerName()))
response.setStatus(status);

View File

@ -0,0 +1,209 @@
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.client;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import java.util.zip.GZIPOutputStream;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.junit.Assert;
import org.junit.Test;
public class HttpClientGZIPTest extends AbstractHttpClientServerTest
{
public HttpClientGZIPTest(SslContextFactory sslContextFactory)
{
super(sslContextFactory);
}
@Test
public void testGZIPContentEncoding() throws Exception
{
final byte[] data = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
start(new AbstractHandler()
{
@Override
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
baseRequest.setHandled(true);
response.setHeader("Content-Encoding", "gzip");
GZIPOutputStream gzipOutput = new GZIPOutputStream(response.getOutputStream());
gzipOutput.write(data);
gzipOutput.finish();
}
});
ContentResponse response = client.newRequest("localhost", connector.getLocalPort())
.scheme(scheme)
.timeout(5, TimeUnit.SECONDS)
.send();
Assert.assertEquals(200, response.getStatus());
Assert.assertArrayEquals(data, response.getContent());
}
@Test
public void testGZIPContentOneByteAtATime() throws Exception
{
final byte[] data = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
start(new AbstractHandler()
{
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
baseRequest.setHandled(true);
response.setHeader("Content-Encoding", "gzip");
ByteArrayOutputStream gzipData = new ByteArrayOutputStream();
GZIPOutputStream gzipOutput = new GZIPOutputStream(gzipData);
gzipOutput.write(data);
gzipOutput.finish();
ServletOutputStream output = response.getOutputStream();
byte[] gzipBytes = gzipData.toByteArray();
for (byte gzipByte : gzipBytes)
{
output.write(gzipByte);
output.flush();
sleep(100);
}
}
});
ContentResponse response = client.newRequest("localhost", connector.getLocalPort())
.scheme(scheme)
.send();
Assert.assertEquals(200, response.getStatus());
Assert.assertArrayEquals(data, response.getContent());
}
@Test
public void testGZIPContentSentTwiceInOneWrite() throws Exception
{
final byte[] data = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
start(new AbstractHandler()
{
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
baseRequest.setHandled(true);
response.setHeader("Content-Encoding", "gzip");
ByteArrayOutputStream gzipData = new ByteArrayOutputStream();
GZIPOutputStream gzipOutput = new GZIPOutputStream(gzipData);
gzipOutput.write(data);
gzipOutput.finish();
byte[] gzipBytes = gzipData.toByteArray();
byte[] content = Arrays.copyOf(gzipBytes, 2 * gzipBytes.length);
System.arraycopy(gzipBytes, 0, content, gzipBytes.length, gzipBytes.length);
ServletOutputStream output = response.getOutputStream();
output.write(content);
}
});
ContentResponse response = client.newRequest("localhost", connector.getLocalPort())
.scheme(scheme)
.send();
Assert.assertEquals(200, response.getStatus());
byte[] expected = Arrays.copyOf(data, 2 * data.length);
System.arraycopy(data, 0, expected, data.length, data.length);
Assert.assertArrayEquals(expected, response.getContent());
}
@Test
public void testGZIPContentFragmentedBeforeTrailer() throws Exception
{
// There are 8 trailer bytes to gzip encoding.
testGZIPContentFragmented(9);
}
@Test
public void testGZIPContentFragmentedAtTrailer() throws Exception
{
// There are 8 trailer bytes to gzip encoding.
testGZIPContentFragmented(1);
}
private void testGZIPContentFragmented(final int fragment) throws Exception
{
final byte[] data = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
start(new AbstractHandler()
{
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
baseRequest.setHandled(true);
response.setHeader("Content-Encoding", "gzip");
ByteArrayOutputStream gzipData = new ByteArrayOutputStream();
GZIPOutputStream gzipOutput = new GZIPOutputStream(gzipData);
gzipOutput.write(data);
gzipOutput.finish();
byte[] gzipBytes = gzipData.toByteArray();
byte[] chunk1 = Arrays.copyOfRange(gzipBytes, 0, gzipBytes.length - fragment);
byte[] chunk2 = Arrays.copyOfRange(gzipBytes, gzipBytes.length - fragment, gzipBytes.length);
ServletOutputStream output = response.getOutputStream();
output.write(chunk1);
output.flush();
sleep(500);
output.write(chunk2);
output.flush();
}
});
ContentResponse response = client.newRequest("localhost", connector.getLocalPort())
.scheme(scheme)
.send();
Assert.assertEquals(200, response.getStatus());
Assert.assertArrayEquals(data, response.getContent());
}
private static void sleep(long ms) throws IOException
{
try
{
TimeUnit.MILLISECONDS.sleep(ms);
}
catch (InterruptedException x)
{
throw new InterruptedIOException();
}
}
}

View File

@ -58,7 +58,7 @@ public class HttpClientProxyTest extends AbstractHttpClientServerTest
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
baseRequest.setHandled(true);
if (!URI.create(baseRequest.getUri().toString()).isAbsolute())
if (!URI.create(baseRequest.getHttpURI().toString()).isAbsolute())
response.setStatus(HttpServletResponse.SC_USE_PROXY);
else if (serverHost.equals(request.getServerName()))
response.setStatus(status);

View File

@ -43,8 +43,6 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.zip.GZIPOutputStream;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
@ -672,32 +670,6 @@ public class HttpClientTest extends AbstractHttpClientServerTest
Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
}
@Test
public void test_GZIP_ContentEncoding() throws Exception
{
final byte[] data = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
start(new AbstractHandler()
{
@Override
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
baseRequest.setHandled(true);
response.setHeader("Content-Encoding", "gzip");
GZIPOutputStream gzipOutput = new GZIPOutputStream(response.getOutputStream());
gzipOutput.write(data);
gzipOutput.finish();
}
});
ContentResponse response = client.newRequest("localhost", connector.getLocalPort())
.scheme(scheme)
.timeout(5, TimeUnit.SECONDS)
.send();
Assert.assertEquals(200, response.getStatus());
Assert.assertArrayEquals(data, response.getContent());
}
@Slow
@Test
public void test_Request_IdleTimeout() throws Exception

View File

@ -0,0 +1,198 @@
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.client;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.api.Response;
import org.eclipse.jetty.client.api.Result;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.junit.Assert;
import org.junit.Test;
public class HttpResponseConcurrentAbortTest extends AbstractHttpClientServerTest
{
private final CountDownLatch callbackLatch = new CountDownLatch(1);
private final CountDownLatch failureLatch = new CountDownLatch(1);
private final CountDownLatch completeLatch = new CountDownLatch(1);
private final AtomicBoolean success = new AtomicBoolean();
public HttpResponseConcurrentAbortTest(SslContextFactory sslContextFactory)
{
super(sslContextFactory);
}
@Test
public void testAbortOnBegin() throws Exception
{
start(new EmptyServerHandler());
client.newRequest("localhost", connector.getLocalPort())
.scheme(scheme)
.onResponseBegin(new Response.BeginListener()
{
@Override
public void onBegin(Response response)
{
abort(response);
}
})
.send(new TestResponseListener());
Assert.assertTrue(callbackLatch.await(5, TimeUnit.SECONDS));
Assert.assertTrue(completeLatch.await(6, TimeUnit.SECONDS));
Assert.assertTrue(success.get());
}
@Test
public void testAbortOnHeader() throws Exception
{
start(new EmptyServerHandler());
client.newRequest("localhost", connector.getLocalPort())
.scheme(scheme)
.onResponseHeader(new Response.HeaderListener()
{
@Override
public boolean onHeader(Response response, HttpField field)
{
abort(response);
return true;
}
})
.send(new TestResponseListener());
Assert.assertTrue(callbackLatch.await(5, TimeUnit.SECONDS));
Assert.assertTrue(completeLatch.await(5, TimeUnit.SECONDS));
Assert.assertTrue(success.get());
}
@Test
public void testAbortOnHeaders() throws Exception
{
start(new EmptyServerHandler());
client.newRequest("localhost", connector.getLocalPort())
.scheme(scheme)
.onResponseHeaders(new Response.HeadersListener()
{
@Override
public void onHeaders(Response response)
{
abort(response);
}
})
.send(new TestResponseListener());
Assert.assertTrue(callbackLatch.await(5, TimeUnit.SECONDS));
Assert.assertTrue(completeLatch.await(5, TimeUnit.SECONDS));
Assert.assertTrue(success.get());
}
@Test
public void testAbortOnContent() throws Exception
{
start(new AbstractHandler()
{
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
baseRequest.setHandled(true);
OutputStream output = response.getOutputStream();
output.write(1);
output.flush();
}
});
client.newRequest("localhost", connector.getLocalPort())
.scheme(scheme)
.onResponseContent(new Response.ContentListener()
{
@Override
public void onContent(Response response, ByteBuffer content)
{
abort(response);
}
})
.send(new TestResponseListener());
Assert.assertTrue(callbackLatch.await(5, TimeUnit.SECONDS));
Assert.assertTrue(completeLatch.await(5, TimeUnit.SECONDS));
Assert.assertTrue(success.get());
}
private void abort(final Response response)
{
Logger logger = Log.getLogger(getClass());
new Thread("abort")
{
@Override
public void run()
{
response.abort(new Exception());
}
}.start();
try
{
// The failure callback must be executed asynchronously.
boolean latched = failureLatch.await(4, TimeUnit.SECONDS);
success.set(latched);
logger.info("SIMON - STEP 1");
// The complete callback must not be executed
// until we return from this callback.
latched = completeLatch.await(1, TimeUnit.SECONDS);
success.set(!latched);
logger.info("SIMON - STEP 2");
callbackLatch.countDown();
}
catch (InterruptedException x)
{
throw new RuntimeException(x);
}
}
private class TestResponseListener extends Response.Listener.Adapter
{
@Override
public void onFailure(Response response, Throwable failure)
{
failureLatch.countDown();
}
@Override
public void onComplete(Result result)
{
Assert.assertTrue(result.isFailed());
completeLatch.countDown();
}
}
}

View File

@ -18,23 +18,18 @@
package org.eclipse.jetty.client.http;
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.zip.GZIPOutputStream;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.HttpExchange;
import org.eclipse.jetty.client.HttpRequest;
import org.eclipse.jetty.client.HttpResponseException;
import org.eclipse.jetty.client.Origin;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Response;
import org.eclipse.jetty.client.util.FutureResponseListener;
import org.eclipse.jetty.http.HttpFields;
@ -205,62 +200,4 @@ public class HttpReceiverOverHTTPTest
Assert.assertTrue(e.getCause() instanceof HttpResponseException);
}
}
@Test
public void test_Receive_GZIPResponseContent_Fragmented() throws Exception
{
byte[] data = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (GZIPOutputStream gzipOutput = new GZIPOutputStream(baos))
{
gzipOutput.write(data);
}
byte[] gzip = baos.toByteArray();
endPoint.setInput("" +
"HTTP/1.1 200 OK\r\n" +
"Content-Length: " + gzip.length + "\r\n" +
"Content-Encoding: gzip\r\n" +
"\r\n");
HttpRequest request = (HttpRequest)client.newRequest("http://localhost");
final CountDownLatch latch = new CountDownLatch(1);
FutureResponseListener listener = new FutureResponseListener(request)
{
@Override
public void onContent(Response response, ByteBuffer content)
{
boolean hadRemaining=content.hasRemaining();
super.onContent(response, content);
// TODO gzip decoding can pass on empty chunks. Currently ignoring them here, but could be done at the decoder???
if (hadRemaining) // Ignore empty chunks
latch.countDown();
}
};
HttpExchange exchange = new HttpExchange(destination, request, Collections.<Response.ResponseListener>singletonList(listener));
connection.getHttpChannel().associate(exchange);
exchange.requestComplete();
exchange.terminateRequest(null);
connection.getHttpChannel().receive();
endPoint.reset();
ByteBuffer buffer = ByteBuffer.wrap(gzip);
int fragment = buffer.limit() - 1;
buffer.limit(fragment);
endPoint.setInput(buffer);
connection.getHttpChannel().receive();
endPoint.reset();
buffer.limit(gzip.length);
buffer.position(fragment);
endPoint.setInput(buffer);
connection.getHttpChannel().receive();
ContentResponse response = listener.get(5, TimeUnit.SECONDS);
Assert.assertNotNull(response);
Assert.assertEquals(200, response.getStatus());
Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
Assert.assertArrayEquals(data, response.getContent());
}
}

View File

@ -1049,9 +1049,9 @@ public class SslBytesServerTest extends SslBytesTest
@Test
public void testRequestWithBigContentWriteBlockedThenReset() throws Exception
{
// Don't run on Windows (buggy JVM)
Assume.assumeTrue(!OS.IS_WINDOWS);
// Don't run on Windows (buggy JVM)
Assume.assumeTrue(!OS.IS_WINDOWS);
final SSLSocket client = newClient();
SimpleProxy.AutomaticFlow automaticProxyFlow = proxy.startAutomaticFlow();
@ -1110,10 +1110,10 @@ public class SslBytesServerTest extends SslBytesTest
@Test
public void testRequestWithBigContentReadBlockedThenReset() throws Exception
{
// Don't run on Windows (buggy JVM)
Assume.assumeTrue(!OS.IS_WINDOWS);
final SSLSocket client = newClient();
// Don't run on Windows (buggy JVM)
Assume.assumeTrue(!OS.IS_WINDOWS);
final SSLSocket client = newClient();
SimpleProxy.AutomaticFlow automaticProxyFlow = proxy.startAutomaticFlow();
client.startHandshake();

View File

@ -36,10 +36,10 @@ import org.junit.Test;
*/
public class AppLifeCycleTest
{
@Rule
public TestingDir testdir = new TestingDir();
@Rule
public TestingDir testdir = new TestingDir();
private void assertNoPath(String from, String to)
private void assertNoPath(String from, String to)
{
assertPath(from,to,new ArrayList<String>());
}

View File

@ -30,8 +30,8 @@ import org.junit.Test;
*/
public class ScanningAppProviderStartupTest
{
@Rule
public TestingDir testdir = new TestingDir();
@Rule
public TestingDir testdir = new TestingDir();
private static XmlConfiguredJetty jetty;
@Before

View File

@ -23,12 +23,11 @@ import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.jetty.fcgi.FCGI;
import org.eclipse.jetty.http.FinalMetaData;
import org.eclipse.jetty.http.HostPortHttpField;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.HttpScheme;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.io.EndPoint;
@ -88,7 +87,8 @@ public class HttpChannelOverFCGI extends HttpChannel
String uri = path;
if (query != null && query.length() > 0)
uri += "?" + query;
onRequest(new FinalMetaData.Request(HttpVersion.fromString(version), method, new HttpURI(uri), fields, hostPort));
// TODO https?
onRequest(new MetaData.Request(method, HttpScheme.HTTP.asString(), hostPort, uri, HttpVersion.fromString(version), fields));
}
private HttpField convertHeader(HttpField field)

View File

@ -22,6 +22,7 @@ import java.net.URI;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;

View File

@ -24,6 +24,7 @@ import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;

View File

@ -19,6 +19,7 @@
package org.eclipse.jetty.fcgi.server;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

View File

@ -32,6 +32,7 @@ import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.zip.GZIPOutputStream;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
@ -697,7 +698,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
contentLatch.set(new CountDownLatch(1));
callback.succeeded();
Assert.assertTrue(completeLatch.await(555, TimeUnit.SECONDS));
Assert.assertTrue(completeLatch.await(5, TimeUnit.SECONDS));
Assert.assertEquals(2, contentCount.get());
}
}

View File

@ -25,6 +25,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;

View File

@ -20,6 +20,7 @@ package org.eclipse.jetty.fcgi.server.proxy;
import java.io.IOException;
import java.util.EnumSet;
import javax.servlet.DispatcherType;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

View File

@ -21,6 +21,7 @@ package org.eclipse.jetty.fcgi.server.proxy;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.DispatcherType;
import org.eclipse.jetty.server.Server;

View File

@ -97,8 +97,8 @@ public class JettyHttpContext extends com.sun.net.httpserver.HttpContext
@Override
public Authenticator setAuthenticator(Authenticator auth)
{
Authenticator previous = _authenticator;
_authenticator = auth;
Authenticator previous = _authenticator;
_authenticator = auth;
return previous;
}

View File

@ -1,271 +1,271 @@
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.http.spi;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.NetworkConnector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.ThreadPool;
import com.sun.net.httpserver.HttpContext;
import com.sun.net.httpserver.HttpHandler;
/**
* Jetty implementation of {@link com.sun.net.httpserver.HttpServer}.
*/
public class JettyHttpServer extends com.sun.net.httpserver.HttpServer
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.http.spi;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.NetworkConnector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.ThreadPool;
import com.sun.net.httpserver.HttpContext;
import com.sun.net.httpserver.HttpHandler;
/**
* Jetty implementation of {@link com.sun.net.httpserver.HttpServer}.
*/
public class JettyHttpServer extends com.sun.net.httpserver.HttpServer
{
private static final Logger LOG = Log.getLogger(JettyHttpServer.class);
private Server _server;
private boolean _serverShared;
private InetSocketAddress _addr;
private ThreadPoolExecutor _executor;
private Map<String, JettyHttpContext> _contexts = new HashMap<String, JettyHttpContext>();
private Map<String, Connector> _connectors = new HashMap<String, Connector>();
public JettyHttpServer(Server server, boolean shared)
{
this._server = server;
this._serverShared = shared;
}
@Override
public void bind(InetSocketAddress addr, int backlog) throws IOException
{
// check if there is already a connector listening
Collection<NetworkConnector> connectors = _server.getBeans(NetworkConnector.class);
if (connectors != null)
{
for (NetworkConnector connector : connectors)
{
if (connector.getPort() == addr.getPort()) {
if (LOG.isDebugEnabled()) LOG.debug("server already bound to port " + addr.getPort() + ", no need to rebind");
return;
}
}
}
if (_serverShared)
throw new IOException("jetty server is not bound to port " + addr.getPort());
this._addr = addr;
if (LOG.isDebugEnabled()) LOG.debug("binding server to port " + addr.getPort());
ServerConnector connector = new ServerConnector(_server);
connector.setPort(addr.getPort());
connector.setHost(addr.getHostName());
_server.addConnector(connector);
_connectors.put(addr.getHostName() + addr.getPort(), connector);
}
@Override
public InetSocketAddress getAddress()
{
return _addr;
}
@Override
public void start()
{
if (_serverShared) return;
try
{
_server.start();
}
catch (Exception ex)
{
throw new RuntimeException(ex);
}
}
@Override
public void setExecutor(Executor executor)
{
if (executor == null)
throw new IllegalArgumentException("missing required 'executor' argument");
ThreadPool threadPool = _server.getThreadPool();
if (threadPool instanceof DelegatingThreadPool)
((DelegatingThreadPool)_server.getThreadPool()).setExecutor(executor);
else
throw new UnsupportedOperationException("!DelegatingThreadPool");
}
@Override
public Executor getExecutor()
{
ThreadPool threadPool = _server.getThreadPool();
if (threadPool instanceof DelegatingThreadPool)
return ((DelegatingThreadPool)_server.getThreadPool()).getExecutor();
return threadPool;
}
@Override
public void stop(int delay)
{
cleanUpContexts();
cleanUpConnectors();
if (_serverShared) return;
try
{
_server.stop();
}
catch (Exception ex)
{
throw new RuntimeException(ex);
}
}
private void cleanUpContexts()
{
for (Map.Entry<String, JettyHttpContext> stringJettyHttpContextEntry : _contexts.entrySet())
{
JettyHttpContext context = stringJettyHttpContextEntry.getValue();
_server.removeBean(context.getJettyContextHandler());
}
_contexts.clear();
}
private void cleanUpConnectors()
{
for (Map.Entry<String, Connector> stringConnectorEntry : _connectors.entrySet())
{
Connector connector = stringConnectorEntry.getValue();
try
{
connector.stop();
} catch (Exception ex) {
LOG.warn(ex);
}
_server.removeConnector(connector);
}
_connectors.clear();
}
@Override
public HttpContext createContext(String path, HttpHandler httpHandler)
{
checkIfContextIsFree(path);
JettyHttpContext context = new JettyHttpContext(this, path, httpHandler);
HttpSpiContextHandler jettyContextHandler = context.getJettyContextHandler();
ContextHandlerCollection chc = findContextHandlerCollection(_server.getHandlers());
if (chc == null)
throw new RuntimeException("could not find ContextHandlerCollection, you must configure one");
chc.addHandler(jettyContextHandler);
_contexts.put(path, context);
return context;
}
private ContextHandlerCollection findContextHandlerCollection(Handler[] handlers)
{
if (handlers == null)
return null;
for (Handler handler : handlers)
{
if (handler instanceof ContextHandlerCollection)
{
return (ContextHandlerCollection) handler;
}
if (handler instanceof HandlerCollection)
{
HandlerCollection hc = (HandlerCollection) handler;
ContextHandlerCollection chc = findContextHandlerCollection(hc.getHandlers());
if (chc != null)
return chc;
}
}
return null;
}
private void checkIfContextIsFree(String path)
{
Handler serverHandler = _server.getHandler();
if (serverHandler instanceof ContextHandler)
{
ContextHandler ctx = (ContextHandler) serverHandler;
if (ctx.getContextPath().equals(path))
throw new RuntimeException("another context already bound to path " + path);
}
Handler[] handlers = _server.getHandlers();
if (handlers == null) return;
for (Handler handler : handlers)
{
if (handler instanceof ContextHandler) {
ContextHandler ctx = (ContextHandler) handler;
if (ctx.getContextPath().equals(path))
throw new RuntimeException("another context already bound to path " + path);
}
}
}
@Override
public HttpContext createContext(String path)
{
return createContext(path, null);
}
@Override
public void removeContext(String path) throws IllegalArgumentException
{
JettyHttpContext context = _contexts.remove(path);
if (context == null) return;
_server.removeBean(context.getJettyContextHandler());
}
@Override
public void removeContext(HttpContext context)
{
removeContext(context.getPath());
}
}
private Server _server;
private boolean _serverShared;
private InetSocketAddress _addr;
private ThreadPoolExecutor _executor;
private Map<String, JettyHttpContext> _contexts = new HashMap<String, JettyHttpContext>();
private Map<String, Connector> _connectors = new HashMap<String, Connector>();
public JettyHttpServer(Server server, boolean shared)
{
this._server = server;
this._serverShared = shared;
}
@Override
public void bind(InetSocketAddress addr, int backlog) throws IOException
{
// check if there is already a connector listening
Collection<NetworkConnector> connectors = _server.getBeans(NetworkConnector.class);
if (connectors != null)
{
for (NetworkConnector connector : connectors)
{
if (connector.getPort() == addr.getPort()) {
if (LOG.isDebugEnabled()) LOG.debug("server already bound to port " + addr.getPort() + ", no need to rebind");
return;
}
}
}
if (_serverShared)
throw new IOException("jetty server is not bound to port " + addr.getPort());
this._addr = addr;
if (LOG.isDebugEnabled()) LOG.debug("binding server to port " + addr.getPort());
ServerConnector connector = new ServerConnector(_server);
connector.setPort(addr.getPort());
connector.setHost(addr.getHostName());
_server.addConnector(connector);
_connectors.put(addr.getHostName() + addr.getPort(), connector);
}
@Override
public InetSocketAddress getAddress()
{
return _addr;
}
@Override
public void start()
{
if (_serverShared) return;
try
{
_server.start();
}
catch (Exception ex)
{
throw new RuntimeException(ex);
}
}
@Override
public void setExecutor(Executor executor)
{
if (executor == null)
throw new IllegalArgumentException("missing required 'executor' argument");
ThreadPool threadPool = _server.getThreadPool();
if (threadPool instanceof DelegatingThreadPool)
((DelegatingThreadPool)_server.getThreadPool()).setExecutor(executor);
else
throw new UnsupportedOperationException("!DelegatingThreadPool");
}
@Override
public Executor getExecutor()
{
ThreadPool threadPool = _server.getThreadPool();
if (threadPool instanceof DelegatingThreadPool)
return ((DelegatingThreadPool)_server.getThreadPool()).getExecutor();
return threadPool;
}
@Override
public void stop(int delay)
{
cleanUpContexts();
cleanUpConnectors();
if (_serverShared) return;
try
{
_server.stop();
}
catch (Exception ex)
{
throw new RuntimeException(ex);
}
}
private void cleanUpContexts()
{
for (Map.Entry<String, JettyHttpContext> stringJettyHttpContextEntry : _contexts.entrySet())
{
JettyHttpContext context = stringJettyHttpContextEntry.getValue();
_server.removeBean(context.getJettyContextHandler());
}
_contexts.clear();
}
private void cleanUpConnectors()
{
for (Map.Entry<String, Connector> stringConnectorEntry : _connectors.entrySet())
{
Connector connector = stringConnectorEntry.getValue();
try
{
connector.stop();
} catch (Exception ex) {
LOG.warn(ex);
}
_server.removeConnector(connector);
}
_connectors.clear();
}
@Override
public HttpContext createContext(String path, HttpHandler httpHandler)
{
checkIfContextIsFree(path);
JettyHttpContext context = new JettyHttpContext(this, path, httpHandler);
HttpSpiContextHandler jettyContextHandler = context.getJettyContextHandler();
ContextHandlerCollection chc = findContextHandlerCollection(_server.getHandlers());
if (chc == null)
throw new RuntimeException("could not find ContextHandlerCollection, you must configure one");
chc.addHandler(jettyContextHandler);
_contexts.put(path, context);
return context;
}
private ContextHandlerCollection findContextHandlerCollection(Handler[] handlers)
{
if (handlers == null)
return null;
for (Handler handler : handlers)
{
if (handler instanceof ContextHandlerCollection)
{
return (ContextHandlerCollection) handler;
}
if (handler instanceof HandlerCollection)
{
HandlerCollection hc = (HandlerCollection) handler;
ContextHandlerCollection chc = findContextHandlerCollection(hc.getHandlers());
if (chc != null)
return chc;
}
}
return null;
}
private void checkIfContextIsFree(String path)
{
Handler serverHandler = _server.getHandler();
if (serverHandler instanceof ContextHandler)
{
ContextHandler ctx = (ContextHandler) serverHandler;
if (ctx.getContextPath().equals(path))
throw new RuntimeException("another context already bound to path " + path);
}
Handler[] handlers = _server.getHandlers();
if (handlers == null) return;
for (Handler handler : handlers)
{
if (handler instanceof ContextHandler) {
ContextHandler ctx = (ContextHandler) handler;
if (ctx.getContextPath().equals(path))
throw new RuntimeException("another context already bound to path " + path);
}
}
}
@Override
public HttpContext createContext(String path)
{
return createContext(path, null);
}
@Override
public void removeContext(String path) throws IllegalArgumentException
{
JettyHttpContext context = _contexts.remove(path);
if (context == null) return;
_server.removeBean(context.getJettyContextHandler());
}
@Override
public void removeContext(HttpContext context)
{
removeContext(context.getPath());
}
}

View File

@ -43,7 +43,7 @@ public class JettyHttpServerProvider extends HttpServerProvider
public static void setServer(Server server)
{
_server = server;
_server = server;
}
@Override
@ -51,7 +51,7 @@ public class JettyHttpServerProvider extends HttpServerProvider
throws IOException
{
Server server = _server;
boolean shared = true;
boolean shared = true;
if (server == null)
{

View File

@ -1,163 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.http;
import java.util.Iterator;
public abstract class AbstractMetaData implements MetaData
{
@Override
public boolean isRequest()
{
return false;
}
@Override
public boolean isResponse()
{
return false;
}
@Override
public Iterator<HttpField> iterator()
{
return getFields().iterator();
}
@Override
public int hashCode()
{
return 31 * getHttpVersion().hashCode() + getFields().hashCode();
}
@Override
public boolean equals(Object o)
{
if (this == o)
return true;
if (!(o instanceof AbstractMetaData))
return false;
AbstractMetaData that = (AbstractMetaData)o;
if (getHttpVersion() != that.getHttpVersion())
return false;
return getFields().equals(that.getFields());
}
@Override
public String toString()
{
StringBuilder out = new StringBuilder();
for (HttpField field: this)
out.append(field).append(System.lineSeparator());
return out.toString();
}
/* -------------------------------------------------------- */
/* -------------------------------------------------------- */
/* -------------------------------------------------------- */
public abstract static class Request extends AbstractMetaData implements MetaData.Request
{
@Override
public boolean isRequest()
{
return true;
}
@Override
public boolean isResponse()
{
return false;
}
@Override
public int hashCode()
{
int hash = getMethod().hashCode();
hash = 31 * hash + getScheme().hashCode();
hash = 31 * hash + getURI().hashCode();
return 31 * hash + super.hashCode();
}
@Override
public boolean equals(Object o)
{
if (this == o)
return true;
if (!(o instanceof MetaData.Request))
return false;
MetaData.Request that = (MetaData.Request)o;
if (!getMethod().equals(that.getMethod()) ||
!getScheme().equals(that.getScheme()) ||
!getURI().equals(that.getURI()))
return false;
return super.equals(o);
}
@Override
public String toString()
{
return String.format("%s %s://%s:%d%s HTTP/2%s%s",
getMethod(), getScheme(), getHost(), getPort(), getURI(), System.lineSeparator(), super.toString());
}
}
/* -------------------------------------------------------- */
/* -------------------------------------------------------- */
/* -------------------------------------------------------- */
public abstract static class Response extends AbstractMetaData implements MetaData.Response
{
@Override
public boolean isRequest()
{
return false;
}
@Override
public boolean isResponse()
{
return true;
}
@Override
public int hashCode()
{
return 31 * getStatus() + super.hashCode();
}
@Override
public boolean equals(Object o)
{
if (this == o)
return true;
if (!(o instanceof MetaData.Response))
return false;
MetaData.Response that = (MetaData.Response)o;
if (getStatus() != that.getStatus())
return false;
return super.equals(o);
}
@Override
public String toString()
{
return String.format("HTTP/2 %d%s%s", getStatus(), System.lineSeparator(), super.toString());
}
}
}

View File

@ -1,168 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.http;
public class FinalMetaData extends AbstractMetaData
{
private final HttpVersion _version;
private final HttpFields _fields;
public FinalMetaData(HttpVersion version,HttpFields fields)
{
_fields=fields;
_version=version;
}
@Override
public HttpVersion getHttpVersion()
{
return _version;
}
@Override
public HttpFields getFields()
{
return _fields;
}
/* -------------------------------------------------------- */
/* -------------------------------------------------------- */
/* -------------------------------------------------------- */
public static class Request extends AbstractMetaData.Request
{
private final HttpVersion _version;
private final HttpFields _fields;
private final String _method;
private final HttpURI _uri;
private final HostPortHttpField _hostPort;
private final HttpScheme _scheme;
public Request(HttpVersion version, String method, HttpURI uri, HttpFields fields, HostPortHttpField hostPort)
{
_fields=fields;
_version=version;
_method=method;
_uri=uri;
_hostPort = hostPort;
String scheme = uri.getScheme();
if (scheme == null)
{
_scheme = HttpScheme.HTTP;
}
else
{
HttpScheme s = HttpScheme.CACHE.get(scheme);
_scheme = s == null ? HttpScheme.HTTP : s;
}
}
public Request(HttpVersion version, HttpScheme scheme, String method, HostPortHttpField authority, String path, HttpFields fields)
{
this(version,scheme,method,authority,new HttpURI(path),fields);
}
public Request(HttpVersion version, HttpScheme scheme, String method, HostPortHttpField authority, HttpURI path, HttpFields fields)
{
_fields=fields;
_version=version;
_method=method;
_uri=path;
_hostPort = authority;
_scheme=scheme;
}
@Override
public HttpVersion getHttpVersion()
{
return _version;
}
@Override
public HttpFields getFields()
{
return _fields;
}
@Override
public String getMethod()
{
return _method;
}
@Override
public HttpScheme getScheme()
{
return _scheme;
}
@Override
public String getHost()
{
return _hostPort==null?null:_hostPort.getHost();
}
@Override
public int getPort()
{
return _hostPort==null?0:_hostPort.getPort();
}
@Override
public HttpURI getURI()
{
return _uri;
}
}
/* -------------------------------------------------------- */
/* -------------------------------------------------------- */
/* -------------------------------------------------------- */
public static class Response extends AbstractMetaData.Response
{
private final HttpVersion _version;
private final HttpFields _fields;
private final int _status;
public Response(HttpVersion version, int status, HttpFields fields)
{
_fields=fields;
_version=version;
_status=status;
}
@Override
public HttpVersion getHttpVersion()
{
return _version;
}
@Override
public HttpFields getFields()
{
return _fields;
}
public int getStatus()
{
return _status;
}
}
}

View File

@ -564,7 +564,10 @@ public class HttpFields implements Iterable<HttpField>
@Override
public int hashCode()
{
return _fields.hashCode();
int hash=0;
for (HttpField field:_fields)
hash+=field.hashCode();
return hash;
}
@Override

View File

@ -27,6 +27,7 @@ import org.eclipse.jetty.util.ArrayTrie;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Trie;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.Utf8StringBuilder;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@ -142,8 +143,7 @@ public class HttpParser
private HttpMethod _method;
private String _methodString;
private HttpVersion _version;
private ByteBuffer _uri=ByteBuffer.allocate(INITIAL_URI_LENGTH); // Tune?
private HttpURI _httpURI=new HttpURI(StandardCharsets.UTF_8);
private Utf8StringBuilder _uri=new Utf8StringBuilder(INITIAL_URI_LENGTH); // Tune?
private EndOfContent _endOfContent;
private long _contentLength;
private long _contentPosition;
@ -523,7 +523,7 @@ public class HttpParser
}
else
{
_uri.clear();
_uri.reset();
setState(State.URI);
// quick scan for space or EoBuffer
if (buffer.hasArray())
@ -543,18 +543,11 @@ public class HttpParser
LOG.warn("URI is too large >"+_maxHeaderBytes);
throw new BadMessageException(HttpStatus.REQUEST_URI_TOO_LONG_414);
}
if (_uri.remaining()<=len)
{
ByteBuffer uri = ByteBuffer.allocate(_uri.capacity()+2*len);
_uri.flip();
uri.put(_uri);
_uri=uri;
}
_uri.put(array,p-1,len+1);
_uri.append(array,p-1,len+1);
buffer.position(i-buffer.arrayOffset());
}
else
_uri.put(ch);
_uri.append(ch);
}
}
else if (ch < HttpTokens.SPACE)
@ -591,19 +584,11 @@ public class HttpParser
else if (ch < HttpTokens.SPACE && ch>=0)
{
// HTTP/0.9
_uri.flip();
throw new BadMessageException("HTTP/0.9 not supported");
}
else
{
if (!_uri.hasRemaining())
{
ByteBuffer uri = ByteBuffer.allocate(_uri.capacity()*2);
_uri.flip();
uri.put(_uri);
_uri=uri;
}
_uri.put(ch);
_uri.append(ch);
}
break;
@ -634,8 +619,7 @@ public class HttpParser
if (!(_requestHandler instanceof ProxyHandler))
throw new BadMessageException();
_uri.flip();
String protocol=BufferUtil.toString(_uri);
String protocol=_uri.toString();
// This is the proxy protocol, so we can assume entire first line is in buffer else 400
buffer.position(buffer.position()-1);
String sAddr = getProxyField(buffer);
@ -682,7 +666,6 @@ public class HttpParser
else
{
// HTTP/0.9
_uri.flip();
throw new BadMessageException("HTTP/0.9 not supported");
}
}
@ -709,14 +692,8 @@ public class HttpParser
}
setState(State.HEADER);
_uri.flip();
if (_method == HttpMethod.CONNECT)
_httpURI.parseConnect(_uri.array(),_uri.arrayOffset()+_uri.position(),_uri.remaining());
else
_httpURI.parse(_uri.array(),_uri.arrayOffset()+_uri.position(),_uri.remaining());
handle=_requestHandler.startRequest(_methodString,_httpURI, _version)||handle;
handle=_requestHandler.startRequest(_methodString,_uri.toString(), _version)||handle;
continue;
}
else if (ch>=HttpTokens.SPACE)
@ -1185,7 +1162,7 @@ public class HttpParser
if (_headerBytes>_maxHeaderBytes)
{
// Don't want to waste time reading data of a closed request
throw new IllegalStateException("too much data after closed");
throw new IllegalStateException("too much data when seeking close");
}
}
}
@ -1491,7 +1468,6 @@ public class HttpParser
_contentChunk=null;
_headerBytes=0;
_host=false;
_httpURI.clear();
}
/* ------------------------------------------------------------------------------- */
@ -1572,7 +1548,7 @@ public class HttpParser
* @param version
* @return true if handling parsing should return.
*/
public boolean startRequest(String method, HttpURI uri, HttpVersion version);
public boolean startRequest(String method, String uri, HttpVersion version);
}

View File

@ -255,7 +255,7 @@ public class HttpTester
private String _uri;
@Override
public boolean startRequest(String method, HttpURI uri, HttpVersion version)
public boolean startRequest(String method, String uri, HttpVersion version)
{
_method=method;
_uri=uri.toString();

File diff suppressed because it is too large Load Diff

View File

@ -18,30 +18,299 @@
package org.eclipse.jetty.http;
public interface MetaData extends Iterable<HttpField>
import java.util.Iterator;
public class MetaData implements Iterable<HttpField>
{
public HttpVersion getHttpVersion();
public boolean isRequest();
public boolean isResponse();
public HttpFields getFields();
private HttpVersion _httpVersion;
private HttpFields _fields;
/* ------------------------------------------------------------ */
public MetaData()
{
}
/* ------------------------------------------------------------ */
public MetaData(HttpVersion version, HttpFields fields)
{
_httpVersion = version;
_fields = fields;
}
/* ------------------------------------------------------------ */
public boolean isRequest()
{
return false;
}
/* ------------------------------------------------------------ */
public boolean isResponse()
{
return false;
}
/* ------------------------------------------------------------ */
/** Get the httpVersion.
* @return the httpVersion
*/
public HttpVersion getVersion()
{
return _httpVersion;
}
/* ------------------------------------------------------------ */
/** Set the httpVersion.
* @param httpVersion the httpVersion to set
*/
public void setHttpVersion(HttpVersion httpVersion)
{
_httpVersion = httpVersion;
}
/* ------------------------------------------------------------ */
/** Get the fields.
* @return the fields
*/
public HttpFields getFields()
{
return _fields;
}
/* ------------------------------------------------------------ */
/** Set the fields.
* @param fields the fields to set
*/
public void setFields(HttpFields fields)
{
_fields = fields;
}
/* ------------------------------------------------------------ */
public Iterator<HttpField> iterator()
{
return getFields().iterator();
}
/* ------------------------------------------------------------ */
@Override
public int hashCode()
{
return 31 * getVersion().hashCode() + getFields().hashCode();
}
/* ------------------------------------------------------------ */
@Override
public boolean equals(Object o)
{
if (this == o)
return true;
if (!(o instanceof MetaData))
return false;
MetaData that = (MetaData)o;
if (getVersion() != that.getVersion())
return false;
return getFields().equals(that.getFields());
}
/* ------------------------------------------------------------ */
@Override
public String toString()
{
StringBuilder out = new StringBuilder();
for (HttpField field: this)
out.append(field).append(System.lineSeparator());
return out.toString();
}
/* -------------------------------------------------------- */
/* -------------------------------------------------------- */
/* -------------------------------------------------------- */
public interface Request extends MetaData
public static class Request extends MetaData
{
public String getMethod();
public HttpScheme getScheme();
public String getHost();
public int getPort();
public HttpURI getURI();
private String _method;
private HttpURI _uri;
public Request()
{
}
/* ------------------------------------------------------------ */
/**
* @param method
* @param uri
* @param version
* @param fields
*/
public Request(String method, HttpURI uri, HttpVersion version, HttpFields fields)
{
super(version,fields);
_method = method;
_uri = uri;
}
/* ------------------------------------------------------------ */
public Request(String method, HttpScheme scheme, HostPortHttpField hostPort, String uri, HttpVersion version, HttpFields fields)
{
this(method,new HttpURI(scheme==null?null:scheme.asString(),hostPort.getHost(),hostPort.getPort(),uri),version,fields);
}
/* ------------------------------------------------------------ */
public Request(String method, String scheme, HostPortHttpField hostPort, String uri, HttpVersion version, HttpFields fields)
{
this(method,new HttpURI(scheme,hostPort.getHost(),hostPort.getPort(),uri),version,fields);
}
/* ------------------------------------------------------------ */
@Override
public boolean isRequest()
{
return true;
}
/* ------------------------------------------------------------ */
/** Get the method.
* @return the method
*/
public String getMethod()
{
return _method;
}
/* ------------------------------------------------------------ */
/** Set the method.
* @param method the method to set
*/
public void setMethod(String method)
{
_method = method;
}
/* ------------------------------------------------------------ */
/** Get the uri.
* @return the uri
*/
public HttpURI getURI()
{
return _uri;
}
/* ------------------------------------------------------------ */
/** Set the uri.
* @param uri the uri to set
*/
public void setURI(HttpURI uri)
{
_uri = uri;
}
/* ------------------------------------------------------------ */
@Override
public int hashCode()
{
return ((super.hashCode()*31)+_method.hashCode())*31+_uri.hashCode();
}
/* ------------------------------------------------------------ */
@Override
public boolean equals(Object o)
{
if (this == o)
return true;
if (!(o instanceof MetaData.Request))
return false;
MetaData.Request that = (MetaData.Request)o;
if (!getMethod().equals(that.getMethod()) ||
!getURI().equals(that.getURI()))
return false;
return super.equals(o);
}
/* ------------------------------------------------------------ */
@Override
public String toString()
{
return String.format("%s %s %s%s%s",
getMethod(), getURI(), getVersion(), System.lineSeparator(), super.toString());
}
}
/* -------------------------------------------------------- */
/* -------------------------------------------------------- */
/* -------------------------------------------------------- */
public interface Response extends MetaData
public static class Response extends MetaData
{
public int getStatus();
private int _status;
public Response()
{
}
/* ------------------------------------------------------------ */
/**
* @param version
* @param fields
* @param status
*/
public Response(HttpVersion version, int status, HttpFields fields)
{
super(version,fields);
_status=status;
}
/* ------------------------------------------------------------ */
@Override
public boolean isResponse()
{
return true;
}
/* ------------------------------------------------------------ */
/** Get the status.
* @return the status
*/
public int getStatus()
{
return _status;
}
/* ------------------------------------------------------------ */
/** Set the status.
* @param status the status to set
*/
public void setStatus(int status)
{
_status = status;
}
/* ------------------------------------------------------------ */
@Override
public int hashCode()
{
return 31 * getStatus() + super.hashCode();
}
/* ------------------------------------------------------------ */
@Override
public boolean equals(Object o)
{
if (this == o)
return true;
if (!(o instanceof MetaData.Response))
return false;
MetaData.Response that = (MetaData.Response)o;
if (getStatus() != that.getStatus())
return false;
return super.equals(o);
}
/* ------------------------------------------------------------ */
@Override
public String toString()
{
return String.format("%s %d%s%s",getVersion(), getStatus(), System.lineSeparator(), super.toString());
}
}
}

View File

@ -1561,7 +1561,7 @@ public class HttpParserTest
}
@Override
public boolean startRequest(String method, HttpURI uri, HttpVersion version)
public boolean startRequest(String method, String uri, HttpVersion version)
{
_fields.clear();
_headers= -1;

View File

@ -20,9 +20,18 @@
package org.eclipse.jetty.http;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import org.eclipse.jetty.util.MultiMap;
import org.eclipse.jetty.util.Utf8Appendable;
import org.junit.Assert;
import org.junit.Test;
@ -32,10 +41,10 @@ public class HttpURITest
String[][] tests=
{
{"/path/to/context",null,null,"-1","/path/to/context",null,null,null},
{"http://example.com/path/to/context;param?query=%22value%22#fragment","http","example.com","-1","/path/to/context","param","query=%22value%22","fragment"},
{"http://[::1]/path/to/context;param?query=%22value%22#fragment","http","[::1]","-1","/path/to/context","param","query=%22value%22","fragment"},
{"http://example.com:8080/path/to/context;param?query=%22value%22#fragment","http","example.com","8080","/path/to/context","param","query=%22value%22","fragment"},
{"http://[::1]:8080/path/to/context;param?query=%22value%22#fragment","http","[::1]","8080","/path/to/context","param","query=%22value%22","fragment"},
{"http://example.com/path/to/context;param?query=%22value%22#fragment","http","example.com","-1","/path/to/context;param","param","query=%22value%22","fragment"},
{"http://[::1]/path/to/context;param?query=%22value%22#fragment","http","[::1]","-1","/path/to/context;param","param","query=%22value%22","fragment"},
{"http://example.com:8080/path/to/context;param?query=%22value%22#fragment","http","example.com","8080","/path/to/context;param","param","query=%22value%22","fragment"},
{"http://[::1]:8080/path/to/context;param?query=%22value%22#fragment","http","[::1]","8080","/path/to/context;param","param","query=%22value%22","fragment"},
};
public static int
@ -65,7 +74,8 @@ public class HttpURITest
{
for (String[] test:tests)
{
HttpURI uri = new HttpURI(new URI(test[INPUT]));
URI u=new URI(test[INPUT]);
HttpURI uri = new HttpURI(u);
assertEquals(test[SCHEME], uri.getScheme());
assertEquals(test[HOST], uri.getHost());
@ -74,6 +84,211 @@ public class HttpURITest
assertEquals(test[PARAM], uri.getParam());
assertEquals(test[QUERY], uri.getQuery());
assertEquals(test[FRAGMENT], uri.getFragment());
assertEquals(u,uri.toURI());
}
}
private final String[][] path_tests=
{
/* 0*/ {"/path/info",null,null,null,null,"/path/info",null,null,null},
/* 1*/ {"/path/info#fragment",null,null,null,null,"/path/info",null,null,"fragment"},
/* 2*/ {"/path/info?query",null,null,null,null,"/path/info",null,"query",null},
/* 3*/ {"/path/info?query#fragment",null,null,null,null,"/path/info",null,"query","fragment"},
/* 4*/ {"/path/info;param",null,null,null,null,"/path/info;param","param",null,null},
/* 5*/ {"/path/info;param#fragment",null,null,null,null,"/path/info;param","param",null,"fragment"},
/* 6*/ {"/path/info;param?query",null,null,null,null,"/path/info;param","param","query",null},
/* 7*/ {"/path/info;param?query#fragment",null,null,null,null,"/path/info;param","param","query","fragment"},
/* 8*/ {"//host/path/info",null,null,null,null,"//host/path/info",null,null,null},
/* 9*/ {"//user@host/path/info",null,null,null,null,"//user@host/path/info",null,null,null},
/*10*/ {"//user@host:8080/path/info",null,null,null,null,"//user@host:8080/path/info",null,null,null},
/*11*/ {"//host:8080/path/info",null,null,null,null,"//host:8080/path/info",null,null,null},
/*12*/ {"http:/path/info","http",null,null,null,"/path/info",null,null,null},
/*13*/ {"http:/path/info#fragment","http",null,null,null,"/path/info",null,null,"fragment"},
/*14*/ {"http:/path/info?query","http",null,null,null,"/path/info",null,"query",null},
/*15*/ {"http:/path/info?query#fragment","http",null,null,null,"/path/info",null,"query","fragment"},
/*16*/ {"http:/path/info;param","http",null,null,null,"/path/info;param","param",null,null},
/*17*/ {"http:/path/info;param#fragment","http",null,null,null,"/path/info;param","param",null,"fragment"},
/*18*/ {"http:/path/info;param?query","http",null,null,null,"/path/info;param","param","query",null},
/*19*/ {"http:/path/info;param?query#fragment","http",null,null,null,"/path/info;param","param","query","fragment"},
/*20*/ {"http://user@host:8080/path/info;param?query#fragment","http","//user@host:8080","host","8080","/path/info;param","param","query","fragment"},
/*21*/ {"xxxxx://user@host:8080/path/info;param?query#fragment","xxxxx","//user@host:8080","host","8080","/path/info;param","param","query","fragment"},
/*22*/ {"http:///;?#","http","//","",null,"/;","","",""},
/*23*/ {"/path/info?a=?query",null,null,null,null,"/path/info",null,"a=?query",null},
/*24*/ {"/path/info?a=;query",null,null,null,null,"/path/info",null,"a=;query",null},
/*25*/ {"//host:8080//",null,null,null,null,"//host:8080//",null,null,null},
/*26*/ {"file:///path/info","file","//","",null,"/path/info",null,null,null},
/*27*/ {"//",null,null,null,null,"//",null,null,null},
/*28*/ {"http://localhost/","http","//localhost","localhost",null,"/",null,null,null},
/*29*/ {"http://localhost:8080/", "http", "//localhost:8080", "localhost","8080","/", null, null,null},
/*30*/ {"http://localhost/?x=y", "http", "//localhost", "localhost",null,"/", null,"x=y",null},
/*31*/ {"/;param",null, null, null,null,"/;param", "param",null,null},
/*32*/ {"/?x=y",null, null, null,null,"/", null,"x=y",null},
/*33*/ {"/?abc=test",null, null, null,null,"/", null,"abc=test",null},
/*34*/ {"/#fragment",null, null, null,null,"/", null,null,"fragment"},
/*35*/ {"http://192.0.0.1:8080/","http","//192.0.0.1:8080","192.0.0.1","8080","/",null,null,null},
/*36*/ {"http://[2001:db8::1]:8080/","http","//[2001:db8::1]:8080","[2001:db8::1]","8080","/",null,null,null},
/*37*/ {"http://user@[2001:db8::1]:8080/","http","//user@[2001:db8::1]:8080","[2001:db8::1]","8080","/",null,null,null},
/*38*/ {"http://[2001:db8::1]/","http","//[2001:db8::1]","[2001:db8::1]",null,"/",null,null,null},
/*39*/ {"//[2001:db8::1]:8080/",null,null,null,null,"//[2001:db8::1]:8080/",null,null,null},
/*40*/ {"http://user@[2001:db8::1]:8080/","http","//user@[2001:db8::1]:8080","[2001:db8::1]","8080","/",null,null,null},
/*41*/ {"*",null,null,null,null,"*",null, null,null}
};
@Test
public void testPathURIs() throws Exception
{
HttpURI uri = new HttpURI();
for (int t=0;t<path_tests.length;t++)
{
uri.parse(path_tests[t][0]);
assertEquals(t+" "+path_tests[t][0],path_tests[t][1],uri.getScheme());
assertEquals(t+" "+path_tests[t][0],path_tests[t][3],uri.getHost());
assertEquals(t+" "+path_tests[t][0],path_tests[t][4]==null?-1:Integer.parseInt(path_tests[t][4]),uri.getPort());
assertEquals(t+" "+path_tests[t][0],path_tests[t][5],uri.getPath());
assertEquals(t+" "+path_tests[t][0],path_tests[t][6],uri.getParam());
assertEquals(t+" "+path_tests[t][0],path_tests[t][7],uri.getQuery());
assertEquals(t+" "+path_tests[t][0],path_tests[t][8],uri.getFragment());
assertEquals(path_tests[t][0], uri.toString());
}
}
@Test
public void testInvalidAddress() throws Exception
{
assertInvalidURI("http://[ffff::1:8080/", "Invalid URL; no closing ']' -- should throw exception");
assertInvalidURI("**", "only '*', not '**'");
assertInvalidURI("*/", "only '*', not '*/'");
}
private void assertInvalidURI(String invalidURI, String message)
{
HttpURI uri = new HttpURI();
try
{
uri.parse(invalidURI);
fail(message);
}
catch (IllegalArgumentException e)
{
assertTrue(true);
}
}
@Test
public void testUnicodeErrors() throws UnsupportedEncodingException
{
String uri="http://server/path?invalid=data%uXXXXhere%u000";
try
{
URLDecoder.decode(uri,"UTF-8");
Assert.assertTrue(false);
}
catch (IllegalArgumentException e)
{
}
HttpURI huri=new HttpURI(uri);
MultiMap<String> params = new MultiMap<>();
huri.decodeQueryTo(params);
assertEquals("data"+Utf8Appendable.REPLACEMENT+"here"+Utf8Appendable.REPLACEMENT,params.getValue("invalid",0));
huri=new HttpURI(uri);
params = new MultiMap<>();
huri.decodeQueryTo(params,StandardCharsets.UTF_8);
assertEquals("data"+Utf8Appendable.REPLACEMENT+"here"+Utf8Appendable.REPLACEMENT,params.getValue("invalid",0));
}
@Test
public void testExtB() throws Exception
{
for (String value: new String[]{"a","abcdABCD","\u00C0","\u697C","\uD869\uDED5","\uD840\uDC08"} )
{
HttpURI uri = new HttpURI("/path?value="+URLEncoder.encode(value,"UTF-8"));
MultiMap<String> parameters = new MultiMap<>();
uri.decodeQueryTo(parameters,StandardCharsets.UTF_8);
assertEquals(value,parameters.getString("value"));
}
}
@Test
public void testParams() throws Exception
{
HttpURI uri = new HttpURI("/foo/bar");
assertEquals("/foo/bar",uri.getPath());
assertEquals("/foo/bar",uri.getDecodedPath());
assertEquals(null,uri.getParam());
uri = new HttpURI("/foo/bar;jsessionid=12345");
assertEquals("/foo/bar;jsessionid=12345",uri.getPath());
assertEquals("/foo/bar",uri.getDecodedPath());
assertEquals("jsessionid=12345",uri.getParam());
uri = new HttpURI("/foo;abc=123/bar;jsessionid=12345");
assertEquals("/foo;abc=123/bar;jsessionid=12345",uri.getPath());
assertEquals("/foo/bar",uri.getDecodedPath());
assertEquals("jsessionid=12345",uri.getParam());
uri = new HttpURI("/foo;abc=123/bar;jsessionid=12345?name=value");
assertEquals("/foo;abc=123/bar;jsessionid=12345",uri.getPath());
assertEquals("/foo/bar",uri.getDecodedPath());
assertEquals("jsessionid=12345",uri.getParam());
uri = new HttpURI("/foo;abc=123/bar;jsessionid=12345#target");
assertEquals("/foo;abc=123/bar;jsessionid=12345",uri.getPath());
assertEquals("/foo/bar",uri.getDecodedPath());
assertEquals("jsessionid=12345",uri.getParam());
}
@Test
public void testMutableURI()
{
HttpURI uri = new HttpURI("/foo/bar");
assertEquals("/foo/bar",uri.toString());
assertEquals("/foo/bar",uri.getPath());
assertEquals("/foo/bar",uri.getDecodedPath());
uri.setScheme("http");
assertEquals("http:/foo/bar",uri.toString());
assertEquals("/foo/bar",uri.getPath());
assertEquals("/foo/bar",uri.getDecodedPath());
uri.setAuthority("host",0);
assertEquals("http://host/foo/bar",uri.toString());
assertEquals("/foo/bar",uri.getPath());
assertEquals("/foo/bar",uri.getDecodedPath());
uri.setAuthority("host",8888);
assertEquals("http://host:8888/foo/bar",uri.toString());
assertEquals("/foo/bar",uri.getPath());
assertEquals("/foo/bar",uri.getDecodedPath());
uri.setPathQuery("/f%30%30;p0/bar;p1;p2");
assertEquals("http://host:8888/f%30%30;p0/bar;p1;p2",uri.toString());
assertEquals("/f%30%30;p0/bar;p1;p2",uri.getPath());
assertEquals("/f00/bar",uri.getDecodedPath());
assertEquals("p2",uri.getParam());
assertEquals(null,uri.getQuery());
uri.setPathQuery("/f%30%30;p0/bar;p1;p2?name=value");
assertEquals("http://host:8888/f%30%30;p0/bar;p1;p2?name=value",uri.toString());
assertEquals("/f%30%30;p0/bar;p1;p2",uri.getPath());
assertEquals("/f00/bar",uri.getDecodedPath());
assertEquals("p2",uri.getParam());
assertEquals("name=value",uri.getQuery());
uri.setQuery("other=123456");
assertEquals("http://host:8888/f%30%30;p0/bar;p1;p2?other=123456",uri.toString());
assertEquals("/f%30%30;p0/bar;p1;p2",uri.getPath());
assertEquals("/f00/bar",uri.getDecodedPath());
assertEquals("p2",uri.getParam());
assertEquals("other=123456",uri.getQuery());
}
}

View File

@ -23,7 +23,6 @@ import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServlet;
import org.eclipse.jetty.http.FinalMetaData;
import org.eclipse.jetty.http.HostPortHttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpScheme;
@ -109,6 +108,6 @@ public class AbstractTest
String host = "localhost";
int port = connector.getLocalPort();
String authority = host + ":" + port;
return new FinalMetaData.Request(HttpVersion.HTTP_2, HttpScheme.HTTP, method, new HostPortHttpField(authority), path, fields);
return new MetaData.Request(method, HttpScheme.HTTP, new HostPortHttpField(authority), path, HttpVersion.HTTP_2, fields);
}
}

View File

@ -29,7 +29,6 @@ import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.jetty.http.FinalMetaData;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
@ -73,7 +72,7 @@ public class FlowControlTest extends AbstractTest
public Stream.Listener onNewStream(Stream stream, HeadersFrame requestFrame)
{
HttpFields fields = new HttpFields();
MetaData.Response response = new FinalMetaData.Response(HttpVersion.HTTP_2, 200, fields);
MetaData.Response response = new MetaData.Response(HttpVersion.HTTP_2, 200, fields);
HeadersFrame responseFrame = new HeadersFrame(stream.getId(), response, null, true);
stream.headers(responseFrame, Callback.Adapter.INSTANCE);
@ -151,7 +150,7 @@ public class FlowControlTest extends AbstractTest
@Override
public Stream.Listener onNewStream(Stream stream, HeadersFrame requestFrame)
{
MetaData.Response metaData = new FinalMetaData.Response(HttpVersion.HTTP_2, 200, new HttpFields());
MetaData.Response metaData = new MetaData.Response(HttpVersion.HTTP_2, 200, new HttpFields());
HeadersFrame responseFrame = new HeadersFrame(stream.getId(), metaData, null, false);
stream.headers(responseFrame, Callback.Adapter.INSTANCE);
@ -243,7 +242,7 @@ public class FlowControlTest extends AbstractTest
@Override
public Stream.Listener onNewStream(Stream stream, HeadersFrame requestFrame)
{
MetaData.Response metaData = new FinalMetaData.Response(HttpVersion.HTTP_2, 200, new HttpFields());
MetaData.Response metaData = new MetaData.Response(HttpVersion.HTTP_2, 200, new HttpFields());
HeadersFrame responseFrame = new HeadersFrame(stream.getId(), metaData, null, false);
stream.headers(responseFrame, Callback.Adapter.INSTANCE);
return new Stream.Listener.Adapter()
@ -348,7 +347,7 @@ public class FlowControlTest extends AbstractTest
public Stream.Listener onNewStream(Stream stream, HeadersFrame requestFrame)
{
// For every stream, send down half the window size of data.
MetaData.Response metaData = new FinalMetaData.Response(HttpVersion.HTTP_2, 200, new HttpFields());
MetaData.Response metaData = new MetaData.Response(HttpVersion.HTTP_2, 200, new HttpFields());
HeadersFrame responseFrame = new HeadersFrame(stream.getId(), metaData, null, false);
stream.headers(responseFrame, Callback.Adapter.INSTANCE);
DataFrame dataFrame = new DataFrame(stream.getId(), ByteBuffer.allocate(windowSize / 2), true);
@ -430,7 +429,7 @@ public class FlowControlTest extends AbstractTest
@Override
public Stream.Listener onNewStream(Stream stream, HeadersFrame requestFrame)
{
MetaData.Response metaData = new FinalMetaData.Response(HttpVersion.HTTP_2, 200, new HttpFields());
MetaData.Response metaData = new MetaData.Response(HttpVersion.HTTP_2, 200, new HttpFields());
HeadersFrame responseFrame = new HeadersFrame(stream.getId(), metaData, null, false);
stream.headers(responseFrame, Callback.Adapter.INSTANCE);
DataFrame dataFrame = new DataFrame(stream.getId(), ByteBuffer.wrap(data), true);

View File

@ -30,7 +30,6 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.FinalMetaData;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
@ -62,7 +61,7 @@ public class IdleTimeoutTest extends AbstractTest
public Stream.Listener onNewStream(Stream stream, HeadersFrame requestFrame)
{
stream.setIdleTimeout(10 * idleTimeout);
MetaData.Response metaData = new FinalMetaData.Response(HttpVersion.HTTP_2, 200, new HttpFields());
MetaData.Response metaData = new MetaData.Response(HttpVersion.HTTP_2, 200, new HttpFields());
HeadersFrame responseFrame = new HeadersFrame(stream.getId(), metaData, null, true);
stream.headers(responseFrame, Callback.Adapter.INSTANCE);
return null;
@ -145,7 +144,7 @@ public class IdleTimeoutTest extends AbstractTest
{
stream.setIdleTimeout(10 * idleTimeout);
Thread.sleep(2 * idleTimeout);
MetaData.Response metaData = new FinalMetaData.Response(HttpVersion.HTTP_2, 200, new HttpFields());
MetaData.Response metaData = new MetaData.Response(HttpVersion.HTTP_2, 200, new HttpFields());
HeadersFrame responseFrame = new HeadersFrame(stream.getId(), metaData, null, true);
stream.headers(responseFrame, Callback.Adapter.INSTANCE);
return null;
@ -204,7 +203,7 @@ public class IdleTimeoutTest extends AbstractTest
public Stream.Listener onNewStream(Stream stream, HeadersFrame frame)
{
stream.setIdleTimeout(10 * idleTimeout);
MetaData.Response metaData = new FinalMetaData.Response(HttpVersion.HTTP_2, 200, new HttpFields());
MetaData.Response metaData = new MetaData.Response(HttpVersion.HTTP_2, 200, new HttpFields());
HeadersFrame responseFrame = new HeadersFrame(stream.getId(), metaData, null, true);
stream.headers(responseFrame, Callback.Adapter.INSTANCE);
return null;
@ -279,7 +278,7 @@ public class IdleTimeoutTest extends AbstractTest
public Stream.Listener onNewStream(Stream stream, HeadersFrame frame)
{
stream.setIdleTimeout(10 * idleTimeout);
MetaData.Response metaData = new FinalMetaData.Response(HttpVersion.HTTP_2, 200, new HttpFields());
MetaData.Response metaData = new MetaData.Response(HttpVersion.HTTP_2, 200, new HttpFields());
HeadersFrame responseFrame = new HeadersFrame(stream.getId(), metaData, null, true);
stream.headers(responseFrame, Callback.Adapter.INSTANCE);
return null;

View File

@ -23,7 +23,6 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.jetty.http.FinalMetaData;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
@ -100,7 +99,7 @@ public class StreamResetTest extends AbstractTest
@Override
public Stream.Listener onNewStream(Stream stream, HeadersFrame requestFrame)
{
MetaData.Response response = new FinalMetaData.Response(HttpVersion.HTTP_2, 200, new HttpFields());
MetaData.Response response = new MetaData.Response(HttpVersion.HTTP_2, 200, new HttpFields());
HeadersFrame responseFrame = new HeadersFrame(stream.getId(), response, null, false);
stream.headers(responseFrame, Callback.Adapter.INSTANCE);
return new Stream.Listener.Adapter()

View File

@ -153,7 +153,7 @@ public class Parser
catch (Throwable x)
{
LOG.debug(x);
notifyConnectionFailure(ErrorCode.PROTOCOL_ERROR, "parser_error");
notifyConnectionFailure(ErrorCode.PROTOCOL_ERROR, "parser_error: "+x);
return false;
}
}
@ -251,6 +251,7 @@ public class Parser
@Override
public void onConnectionFailure(int error, String reason)
{
LOG.warn("onConnectionFailure {},{}",error,reason);
}
}
}

View File

@ -22,7 +22,6 @@ import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jetty.http.FinalMetaData;
import org.eclipse.jetty.http.HostPortHttpField;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
@ -51,7 +50,7 @@ public class HeadersGenerateParseTest
HttpFields fields = new HttpFields();
fields.put("Accept", "text/html");
fields.put("User-Agent", "Jetty");
MetaData.Request metaData = new FinalMetaData.Request(HttpVersion.HTTP_2, HttpScheme.HTTP, "GET", new HostPortHttpField("localhost:8080"), "/path", fields);
MetaData.Request metaData = new MetaData.Request("GET", HttpScheme.HTTP, new HostPortHttpField("localhost:8080"), "/path", HttpVersion.HTTP_2, fields);
final List<HeadersFrame> frames = new ArrayList<>();
Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
@ -84,10 +83,7 @@ public class HeadersGenerateParseTest
Assert.assertEquals(streamId, frame.getStreamId());
Assert.assertTrue(frame.isEndStream());
MetaData.Request request = (MetaData.Request)frame.getMetaData();
Assert.assertSame(metaData.getScheme(), request.getScheme());
Assert.assertEquals(metaData.getMethod(), request.getMethod());
Assert.assertEquals(metaData.getHost(), request.getHost());
Assert.assertEquals(metaData.getPort(), request.getPort());
Assert.assertEquals(metaData.getURI(), request.getURI());
for (int j = 0; j < fields.size(); ++j)
{
@ -117,7 +113,7 @@ public class HeadersGenerateParseTest
HttpFields fields = new HttpFields();
fields.put("Accept", "text/html");
fields.put("User-Agent", "Jetty");
MetaData.Request metaData = new FinalMetaData.Request(HttpVersion.HTTP_2, HttpScheme.HTTP, "GET", new HostPortHttpField("localhost:8080"), "/path", fields);
MetaData.Request metaData = new MetaData.Request("GET", HttpScheme.HTTP, new HostPortHttpField("localhost:8080"), "/path", HttpVersion.HTTP_2, fields);
ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
generator.generateHeaders(lease, streamId, metaData, false);
@ -135,10 +131,7 @@ public class HeadersGenerateParseTest
Assert.assertEquals(streamId, frame.getStreamId());
Assert.assertTrue(frame.isEndStream());
MetaData.Request request = (MetaData.Request)frame.getMetaData();
Assert.assertSame(metaData.getScheme(), request.getScheme());
Assert.assertEquals(metaData.getMethod(), request.getMethod());
Assert.assertEquals(metaData.getHost(), request.getHost());
Assert.assertEquals(metaData.getPort(), request.getPort());
Assert.assertEquals(metaData.getURI(), request.getURI());
for (int j = 0; j < fields.size(); ++j)
{

View File

@ -22,7 +22,6 @@ import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jetty.http.FinalMetaData;
import org.eclipse.jetty.http.HostPortHttpField;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
@ -63,7 +62,7 @@ public class PushPromiseGenerateParseTest
HttpFields fields = new HttpFields();
fields.put("Accept", "text/html");
fields.put("User-Agent", "Jetty");
MetaData.Request metaData = new FinalMetaData.Request(HttpVersion.HTTP_2, HttpScheme.HTTP, "GET", new HostPortHttpField("localhost:8080"), "/path", fields);
MetaData.Request metaData = new MetaData.Request("GET", HttpScheme.HTTP, new HostPortHttpField("localhost:8080"), "/path", HttpVersion.HTTP_2, fields);
// Iterate a few times to be sure generator and parser are properly reset.
for (int i = 0; i < 2; ++i)
@ -85,10 +84,7 @@ public class PushPromiseGenerateParseTest
Assert.assertEquals(streamId, frame.getStreamId());
Assert.assertEquals(promisedStreamId, frame.getPromisedStreamId());
MetaData.Request request = (MetaData.Request)frame.getMetaData();
Assert.assertSame(metaData.getScheme(), request.getScheme());
Assert.assertEquals(metaData.getMethod(), request.getMethod());
Assert.assertEquals(metaData.getHost(), request.getHost());
Assert.assertEquals(metaData.getPort(), request.getPort());
Assert.assertEquals(metaData.getURI(), request.getURI());
for (int j = 0; j < fields.size(); ++j)
{
@ -119,7 +115,7 @@ public class PushPromiseGenerateParseTest
HttpFields fields = new HttpFields();
fields.put("Accept", "text/html");
fields.put("User-Agent", "Jetty");
MetaData.Request metaData = new FinalMetaData.Request(HttpVersion.HTTP_2, HttpScheme.HTTP, "GET", new HostPortHttpField("localhost:8080"), "/path", fields);
MetaData.Request metaData = new MetaData.Request("GET", HttpScheme.HTTP, new HostPortHttpField("localhost:8080"), "/path", HttpVersion.HTTP_2, fields);
ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
generator.generatePushPromise(lease, streamId, promisedStreamId, metaData);
@ -137,10 +133,7 @@ public class PushPromiseGenerateParseTest
Assert.assertEquals(streamId, frame.getStreamId());
Assert.assertEquals(promisedStreamId, frame.getPromisedStreamId());
MetaData.Request request = (MetaData.Request)frame.getMetaData();
Assert.assertSame(metaData.getScheme(), request.getScheme());
Assert.assertEquals(metaData.getMethod(), request.getMethod());
Assert.assertEquals(metaData.getHost(), request.getHost());
Assert.assertEquals(metaData.getPort(), request.getPort());
Assert.assertEquals(metaData.getURI(), request.getURI());
for (int j = 0; j < fields.size(); ++j)
{

View File

@ -20,8 +20,6 @@
package org.eclipse.jetty.http2.hpack;
import org.eclipse.jetty.http.HostPortHttpField;
import org.eclipse.jetty.http2.hpack.HpackContext;
import org.eclipse.jetty.util.StringUtil;
/* ------------------------------------------------------------ */

View File

@ -27,7 +27,6 @@ import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpScheme;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.http2.hpack.HpackContext.Entry;
import org.eclipse.jetty.util.TypeUtil;
@ -183,9 +182,11 @@ public class HpackDecoder
break;
case ":path":
// TODO is this needed
/*
if (indexed)
field = new StaticValueHttpField(header,name,value,new HttpURI(value));
else
else*/
field = new HttpField(header,name,value);
break;

View File

@ -24,6 +24,7 @@ import java.util.EnumSet;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpScheme;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.http2.hpack.HpackContext.Entry;
@ -139,10 +140,11 @@ public class HpackEncoder
MetaData.Request request = (MetaData.Request)metadata;
// TODO optimise these to avoid HttpField creation
encode(buffer,new HttpField(":scheme",request.getScheme().asString()));
String scheme=request.getURI().getScheme();
encode(buffer,new HttpField(":scheme",scheme==null?HttpScheme.HTTP.asString():scheme));
encode(buffer,new HttpField(":method",request.getMethod()));
encode(buffer,new HttpField(":authority",request.getPort()>0?(request.getHost()+':'+request.getPort()):request.getHost()));
encode(buffer,new HttpField(":path",request.getURI().getPath()));
encode(buffer,new HttpField(":authority",request.getURI().getAuthority()));
encode(buffer,new HttpField(":path",request.getURI().getPathQuery()));
}
else if (metadata.isResponse())

View File

@ -21,13 +21,11 @@ package org.eclipse.jetty.http2.hpack;
import org.eclipse.jetty.http.BadMessageException;
import org.eclipse.jetty.http.FinalMetaData;
import org.eclipse.jetty.http.HostPortHttpField;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpScheme;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
@ -42,7 +40,7 @@ public class MetaDataBuilder
private String _method;
private HttpScheme _scheme;
private HostPortHttpField _authority;
private HttpURI _path;
private String _path;
private HttpFields _fields = new HttpFields(10);
@ -91,12 +89,8 @@ public class MetaDataBuilder
_scheme = (HttpScheme)value.getStaticValue();
break;
case ":path":
_path = (HttpURI)value.getStaticValue();
break;
default:
throw new IllegalArgumentException();
throw new IllegalArgumentException(field.getName());
}
}
else
@ -120,7 +114,7 @@ public class MetaDataBuilder
break;
case ":path":
_path=new HttpURI(field.getValue());
_path=field.getValue();
break;
default:
@ -137,10 +131,10 @@ public class MetaDataBuilder
HttpFields fields = _fields;
_fields = new HttpFields(Math.max(10,fields.size()+5));
if (_method!=null)
return new FinalMetaData.Request(HttpVersion.HTTP_2,_scheme,_method,_authority,_path,fields);
return new MetaData.Request(_method,_scheme,_authority,_path,HttpVersion.HTTP_2,fields);
if (_status!=0)
return new FinalMetaData.Response(HttpVersion.HTTP_2,_status,fields);
return new FinalMetaData(HttpVersion.HTTP_2,fields);
return new MetaData.Response(HttpVersion.HTTP_2,_status,fields);
return new MetaData(HttpVersion.HTTP_2,fields);
}
finally
{

View File

@ -20,6 +20,12 @@
package org.eclipse.jetty.http2.hpack;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.nio.ByteBuffer;
import java.util.HashSet;
import java.util.Iterator;
@ -31,12 +37,6 @@ import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/* ------------------------------------------------------------ */
/**

View File

@ -19,21 +19,20 @@
package org.eclipse.jetty.http2.hpack;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.nio.ByteBuffer;
import java.util.Iterator;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpScheme;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.util.TypeUtil;
import org.junit.Ignore;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/* ------------------------------------------------------------ */
/**
@ -54,9 +53,9 @@ public class HpackDecoderTest
MetaData.Request request = (MetaData.Request)decoder.decode(buffer);
assertEquals("GET", request.getMethod());
assertEquals(HttpScheme.HTTP,request.getScheme());
assertEquals(HttpScheme.HTTP.asString(),request.getURI().getScheme());
assertEquals("/",request.getURI().getPath());
assertEquals("www.example.com",request.getHost());
assertEquals("www.example.com",request.getURI().getHost());
assertFalse(request.iterator().hasNext());
@ -67,9 +66,9 @@ public class HpackDecoderTest
request = (MetaData.Request)decoder.decode(buffer);
assertEquals("GET", request.getMethod());
assertEquals(HttpScheme.HTTP,request.getScheme());
assertEquals(HttpScheme.HTTP.asString(),request.getURI().getScheme());
assertEquals("/",request.getURI().getPath());
assertEquals("www.example.com",request.getHost());
assertEquals("www.example.com",request.getURI().getHost());
Iterator<HttpField> iterator=request.iterator();
assertTrue(iterator.hasNext());
assertEquals(new HttpField("cache-control","no-cache"),iterator.next());
@ -83,9 +82,9 @@ public class HpackDecoderTest
request = (MetaData.Request)decoder.decode(buffer);
assertEquals("GET",request.getMethod());
assertEquals(HttpScheme.HTTPS,request.getScheme());
assertEquals(HttpScheme.HTTPS.asString(),request.getURI().getScheme());
assertEquals("/index.html",request.getURI().getPath());
assertEquals("www.example.com",request.getHost());
assertEquals("www.example.com",request.getURI().getHost());
iterator=request.iterator();
assertTrue(iterator.hasNext());
assertEquals(new HttpField("custom-key","custom-value"),iterator.next());
@ -105,9 +104,9 @@ public class HpackDecoderTest
MetaData.Request request = (MetaData.Request)decoder.decode(buffer);
assertEquals("GET", request.getMethod());
assertEquals(HttpScheme.HTTP,request.getScheme());
assertEquals(HttpScheme.HTTP.asString(),request.getURI().getScheme());
assertEquals("/",request.getURI().getPath());
assertEquals("www.example.com",request.getHost());
assertEquals("www.example.com",request.getURI().getHost());
assertFalse(request.iterator().hasNext());
@ -118,9 +117,9 @@ public class HpackDecoderTest
request = (MetaData.Request)decoder.decode(buffer);
assertEquals("GET", request.getMethod());
assertEquals(HttpScheme.HTTP,request.getScheme());
assertEquals(HttpScheme.HTTP.asString(),request.getURI().getScheme());
assertEquals("/",request.getURI().getPath());
assertEquals("www.example.com",request.getHost());
assertEquals("www.example.com",request.getURI().getHost());
Iterator<HttpField> iterator=request.iterator();
assertTrue(iterator.hasNext());
assertEquals(new HttpField("cache-control","no-cache"),iterator.next());
@ -133,9 +132,9 @@ public class HpackDecoderTest
request = (MetaData.Request)decoder.decode(buffer);
assertEquals("GET",request.getMethod());
assertEquals(HttpScheme.HTTPS,request.getScheme());
assertEquals(HttpScheme.HTTPS.asString(),request.getURI().getScheme());
assertEquals("/index.html",request.getURI().getPath());
assertEquals("www.example.com",request.getHost());
assertEquals("www.example.com",request.getURI().getHost());
iterator=request.iterator();
assertTrue(iterator.hasNext());
assertEquals(new HttpField("custom-key","custom-value"),iterator.next());

View File

@ -20,10 +20,11 @@
package org.eclipse.jetty.http2.hpack;
import static org.junit.Assert.assertThat;
import java.nio.ByteBuffer;
import java.util.HashSet;
import org.eclipse.jetty.http.FinalMetaData;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpVersion;
@ -34,8 +35,6 @@ import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Test;
import static org.junit.Assert.assertThat;
/* ------------------------------------------------------------ */
/**
@ -71,7 +70,7 @@ public class HpackEncoderTest
// encode them
ByteBuffer buffer = BufferUtil.allocate(4096);
int pos = BufferUtil.flipToFill(buffer);
encoder.encode(buffer,new FinalMetaData(HttpVersion.HTTP_2,fields));
encoder.encode(buffer,new MetaData(HttpVersion.HTTP_2,fields));
BufferUtil.flipToFlush(buffer,pos);
// something was encoded!
@ -82,7 +81,7 @@ public class HpackEncoderTest
// encode exact same fields again!
BufferUtil.clearToFill(buffer);
encoder.encode(buffer,new FinalMetaData(HttpVersion.HTTP_2,fields));
encoder.encode(buffer,new MetaData(HttpVersion.HTTP_2,fields));
BufferUtil.flipToFlush(buffer,0);
// All are in the header table
@ -94,7 +93,7 @@ public class HpackEncoderTest
// encode
BufferUtil.clearToFill(buffer);
encoder.encode(buffer,new FinalMetaData(HttpVersion.HTTP_2,fields));
encoder.encode(buffer,new MetaData(HttpVersion.HTTP_2,fields));
BufferUtil.flipToFlush(buffer,0);
// something was encoded!
@ -110,7 +109,7 @@ public class HpackEncoderTest
// encode
BufferUtil.clearToFill(buffer);
encoder.encode(buffer,new FinalMetaData(HttpVersion.HTTP_2,fields));
encoder.encode(buffer,new MetaData(HttpVersion.HTTP_2,fields));
BufferUtil.flipToFlush(buffer,0);
// something was encoded!
@ -125,7 +124,7 @@ public class HpackEncoderTest
// encode
BufferUtil.clearToFill(buffer);
encoder.encode(buffer,new FinalMetaData(HttpVersion.HTTP_2,fields));
encoder.encode(buffer,new MetaData(HttpVersion.HTTP_2,fields));
BufferUtil.flipToFlush(buffer,0);
// something was encoded!
@ -141,7 +140,7 @@ public class HpackEncoderTest
// encode
BufferUtil.clearToFill(buffer);
encoder.encode(buffer,new FinalMetaData(HttpVersion.HTTP_2,fields));
encoder.encode(buffer,new MetaData(HttpVersion.HTTP_2,fields));
BufferUtil.flipToFlush(buffer,0);
// something was encoded!
@ -164,7 +163,7 @@ public class HpackEncoderTest
// encode
BufferUtil.clearToFill(buffer);
encoder.encode(buffer,new FinalMetaData(HttpVersion.HTTP_2,fields));
encoder.encode(buffer,new MetaData(HttpVersion.HTTP_2,fields));
BufferUtil.flipToFlush(buffer,0);
// something was encoded!
@ -176,7 +175,7 @@ public class HpackEncoderTest
// encode again
BufferUtil.clearToFill(buffer);
encoder.encode(buffer,new FinalMetaData(HttpVersion.HTTP_2,fields));
encoder.encode(buffer,new MetaData(HttpVersion.HTTP_2,fields));
BufferUtil.flipToFlush(buffer,0);
// something was encoded!

View File

@ -24,7 +24,6 @@ import static org.junit.Assert.assertEquals;
import java.nio.ByteBuffer;
import org.eclipse.jetty.http.BadMessageException;
import org.eclipse.jetty.http.FinalMetaData;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpStatus;
@ -51,7 +50,7 @@ public class HpackTest
fields0.add(HttpHeader.SERVER,"jetty");
fields0.add(HttpHeader.SET_COOKIE,"abcdefghijklmnopqrstuvwxyz");
fields0.add("custom-key","custom-value");
Response original0 = new FinalMetaData.Response(HttpVersion.HTTP_2,200,fields0);
Response original0 = new MetaData.Response(HttpVersion.HTTP_2,200,fields0);
BufferUtil.clearToFill(buffer);
encoder.encode(buffer,original0);
@ -73,7 +72,7 @@ public class HpackTest
fields1.add(HttpHeader.CONTENT_LENGTH,"1234");
fields1.add(HttpHeader.SERVER,"jetty");
fields1.add("Custom-Key","Other-Value");
Response original1 = new FinalMetaData.Response(HttpVersion.HTTP_2,200,fields1);
Response original1 = new MetaData.Response(HttpVersion.HTTP_2,200,fields1);
// Same again?
BufferUtil.clearToFill(buffer);
@ -97,7 +96,7 @@ public class HpackTest
HttpFields fields0 = new HttpFields();
fields0.add("1234567890","1234567890123456789012345678901234567890");
fields0.add("Cookie","abcdeffhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR");
MetaData original0= new FinalMetaData(HttpVersion.HTTP_2,fields0);
MetaData original0= new MetaData(HttpVersion.HTTP_2,fields0);
BufferUtil.clearToFill(buffer);
encoder.encode(buffer,original0);
@ -110,7 +109,7 @@ public class HpackTest
fields1.add("1234567890","1234567890123456789012345678901234567890");
fields1.add("Cookie","abcdeffhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR");
fields1.add("x","y");
MetaData original1 = new FinalMetaData(HttpVersion.HTTP_2,fields1);
MetaData original1 = new MetaData(HttpVersion.HTTP_2,fields1);
BufferUtil.clearToFill(buffer);
encoder.encode(buffer,original1);

View File

@ -18,6 +18,8 @@
package org.eclipse.jetty.http2.hpack;
import static org.junit.Assert.assertEquals;
import java.nio.ByteBuffer;
import org.eclipse.jetty.util.BufferUtil;
@ -25,8 +27,6 @@ import org.eclipse.jetty.util.TypeUtil;
import org.junit.Assert;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class NBitIntegerTest
{

View File

@ -87,7 +87,7 @@ public class HttpChannelOverHTTP2 extends HttpChannel
if (LOG.isDebugEnabled())
{
LOG.debug("HTTP2 Request #{}:{}{} {} {}{}{}",
stream.getId(), System.lineSeparator(), request.getMethod(), request.getURI(), request.getHttpVersion(), System.lineSeparator(), fields);
stream.getId(), System.lineSeparator(), request.getMethod(), request.getURI(), request.getVersion(), System.lineSeparator(), fields);
}
execute(this);

View File

@ -21,7 +21,6 @@ package org.eclipse.jetty.http2.server;
import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicBoolean;
import org.eclipse.jetty.http.FinalMetaData;
import org.eclipse.jetty.http.HttpGenerator;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpVersion;
@ -82,7 +81,7 @@ public class HttpTransportOverHTTP2 implements HttpTransport
System.lineSeparator(), info.getHttpFields());
}
MetaData metaData = new FinalMetaData.Response(HttpVersion.HTTP_2, info.getStatus(), info.getHttpFields());
MetaData metaData = new MetaData.Response(HttpVersion.HTTP_2, info.getStatus(), info.getHttpFields());
HeadersFrame frame = new HeadersFrame(stream.getId(), metaData, null, endStream);
stream.headers(frame, callback);
}

View File

@ -34,7 +34,6 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.FinalMetaData;
import org.eclipse.jetty.http.HostPortHttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpMethod;
@ -100,8 +99,8 @@ public class HTTP2ServerTest
String host = "localhost";
int port = connector.getLocalPort();
HttpFields fields = new HttpFields();
MetaData.Request metaData = new FinalMetaData.Request(HttpVersion.HTTP_2, HttpScheme.HTTP, HttpMethod.GET.asString(),
new HostPortHttpField(host + ":" + port), path, fields);
MetaData.Request metaData = new MetaData.Request(HttpMethod.GET.asString(), HttpScheme.HTTP, new HostPortHttpField(host + ":" + port),
path, HttpVersion.HTTP_2, fields);
HeadersFrame request = new HeadersFrame(1, metaData, null, true);
ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
generator.control(lease, request);
@ -149,8 +148,8 @@ public class HTTP2ServerTest
String host = "localhost";
int port = connector.getLocalPort();
HttpFields fields = new HttpFields();
MetaData.Request metaData = new FinalMetaData.Request(HttpVersion.HTTP_2, HttpScheme.HTTP, HttpMethod.GET.asString(),
new HostPortHttpField(host + ":" + port), path, fields);
MetaData.Request metaData = new MetaData.Request(HttpMethod.GET.asString(), HttpScheme.HTTP, new HostPortHttpField(host + ":" + port),
path, HttpVersion.HTTP_2, fields);
HeadersFrame request = new HeadersFrame(1, metaData, null, true);
ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
generator.control(lease, request);
@ -212,8 +211,8 @@ public class HTTP2ServerTest
String host = "localhost";
int port = connector.getLocalPort();
HttpFields fields = new HttpFields();
MetaData.Request metaData = new FinalMetaData.Request(HttpVersion.HTTP_2,HttpScheme.HTTP, HttpMethod.GET.asString(),
new HostPortHttpField(host + ":" + port), path, fields);
MetaData.Request metaData = new MetaData.Request(HttpMethod.GET.asString(),HttpScheme.HTTP, new HostPortHttpField(host + ":" + port),
path, HttpVersion.HTTP_2, fields);
HeadersFrame request = new HeadersFrame(1, metaData, null, true);
ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
generator.control(lease, request);

View File

@ -210,7 +210,7 @@ public class JAASLoginService extends AbstractLifeCycle implements LoginService
}
else if (callback instanceof RequestParameterCallback)
{
HttpChannel channel = HttpChannel.getCurrentHttpChannel();
HttpChannel channel = HttpChannel.getCurrentHttpChannel();
if (channel == null)
return;

View File

@ -33,7 +33,6 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.eclipse.jetty.security.CrossContextPsuedoSession;
import org.eclipse.jetty.security.authentication.DeferredAuthentication;
import org.eclipse.jetty.security.authentication.LoginCallbackImpl;
import org.eclipse.jetty.security.authentication.SessionAuthentication;
@ -79,7 +78,6 @@ public class FormAuthModule extends BaseAuthModule
private String _formLoginPath;
private CrossContextPsuedoSession<UserInfo> ssoSource;
public FormAuthModule()
{
@ -92,17 +90,6 @@ public class FormAuthModule extends BaseAuthModule
setErrorPage(errorPage);
}
/**
* @deprecated
*/
public FormAuthModule(CallbackHandler callbackHandler, CrossContextPsuedoSession<UserInfo> ssoSource,
String loginPage, String errorPage)
{
super(callbackHandler);
this.ssoSource = ssoSource;
setLoginPage(loginPage);
setErrorPage(errorPage);
}
@Override
public void initialize(MessagePolicy requestPolicy, MessagePolicy responsePolicy,
@ -112,7 +99,6 @@ public class FormAuthModule extends BaseAuthModule
super.initialize(requestPolicy, responsePolicy, handler, options);
setLoginPage((String) options.get(LOGIN_PAGE_KEY));
setErrorPage((String) options.get(ERROR_PAGE_KEY));
ssoSource = (CrossContextPsuedoSession<UserInfo>) options.get(SSO_SOURCE_KEY);
}
private void setLoginPage(String path)
@ -231,17 +217,7 @@ public class FormAuthModule extends BaseAuthModule
return AuthStatus.SUCCESS;
}
else if (ssoSource != null)
{
UserInfo userInfo = ssoSource.fetch(request);
if (userInfo != null)
{
boolean success = tryLogin(messageInfo, clientSubject, response, session, userInfo.getUserName(), new Password(new String(userInfo.getPassword())));
if (success) { return AuthStatus.SUCCESS; }
}
}
// if we can't send challenge
if (DeferredAuthentication.isDeferred(response))
@ -310,12 +286,6 @@ public class FormAuthModule extends BaseAuthModule
}
}
// Sign-on to SSO mechanism
if (ssoSource != null)
{
UserInfo userInfo = new UserInfo(username, pwdChars);
ssoSource.store(userInfo, response);
}
return true;
}
return false;

View File

@ -82,23 +82,23 @@ public class ConnectorServer extends AbstractLifeCycle
public ConnectorServer(JMXServiceURL svcUrl, Map<String,?> environment, String name)
throws Exception
{
String urlPath = svcUrl.getURLPath();
int idx = urlPath.indexOf("rmi://");
if (idx > 0)
{
String hostPort = urlPath.substring(idx+6, urlPath.indexOf('/', idx+6));
String regHostPort = startRegistry(hostPort);
if (regHostPort != null) {
urlPath = urlPath.replace(hostPort,regHostPort);
svcUrl = new JMXServiceURL(svcUrl.getProtocol(), svcUrl.getHost(), svcUrl.getPort(), urlPath);
}
}
String urlPath = svcUrl.getURLPath();
int idx = urlPath.indexOf("rmi://");
if (idx > 0)
{
String hostPort = urlPath.substring(idx+6, urlPath.indexOf('/', idx+6));
String regHostPort = startRegistry(hostPort);
if (regHostPort != null) {
urlPath = urlPath.replace(hostPort,regHostPort);
svcUrl = new JMXServiceURL(svcUrl.getProtocol(), svcUrl.getHost(), svcUrl.getPort(), urlPath);
}
}
MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
_connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(svcUrl, environment, mbeanServer);
mbeanServer.registerMBean(_connectorServer,new ObjectName(name));
}
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */
/**
* @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
*/

View File

@ -82,6 +82,21 @@ public class JspcMojo extends AbstractMojo
public static final String PRECOMPILED_FLAG = "org.eclipse.jetty.jsp.precompiled";
/**
* JettyJspC
*
* Add some extra setters to standard JspC class to help configure it
* for running in maven.
*/
public static class JettyJspC extends JspC
{
public void setClassLoader (ClassLoader loader)
{
this.loader = loader;
}
}
/**
* Whether or not to include dependencies on the plugin's classpath with &lt;scope&gt;provided&lt;/scope&gt;
* Use WITH CAUTION as you may wind up with duplicate jars/classes.
@ -219,7 +234,7 @@ public class JspcMojo extends AbstractMojo
*
* @parameter
*/
private JspC jspc;
private JettyJspC jspc;
@ -286,19 +301,22 @@ public class JspcMojo extends AbstractMojo
if (i+1<webAppUrls.size())
webAppClassPath.append(System.getProperty("path.separator"));
}
Thread.currentThread().setContextClassLoader(webAppClassLoader);
//Interpose a fake classloader as the webapp class loader. This is because the Apache JspC class
//uses a TldScanner which ignores jars outside of the WEB-INF/lib path on the webapp classloader.
//It will, however, look at all jars on the parents of the webapp classloader.
URLClassLoader fakeWebAppClassLoader = new URLClassLoader(new URL[0], webAppClassLoader);
Thread.currentThread().setContextClassLoader(fakeWebAppClassLoader);
if (jspc == null)
jspc = new JspC();
jspc = new JettyJspC();
jspc.setWebXmlFragment(webXmlFragment);
jspc.setUriroot(webAppSourceDirectory);
jspc.setOutputDir(generatedClasses);
jspc.setClassPath(sysClassPath+System.getProperty("path.separator")+webAppClassPath.toString());
jspc.setClassLoader(fakeWebAppClassLoader);
jspc.setCompile(true);
//jspc.setSystemClassPath(sysClassPath);
// JspC#setExtensions() does not exist, so
// always set concrete list of files that will be processed.

View File

@ -139,7 +139,7 @@ public class JettyWebAppContext extends WebAppContext
}
public void setContainerIncludeJarPattern(String pattern)
{
_containerIncludeJarPattern = pattern;
_containerIncludeJarPattern = pattern;
}
public String getContainerIncludeJarPattern()
@ -150,7 +150,7 @@ public class JettyWebAppContext extends WebAppContext
public String getWebInfIncludeJarPattern()
{
return _webInfIncludeJarPattern;
return _webInfIncludeJarPattern;
}
public void setWebInfIncludeJarPattern(String pattern)
{

View File

@ -82,7 +82,7 @@ public class ServiceConnection
*/
public String getServiceUrl()
{
return _serviceUrl;
return _serviceUrl;
}
/* ------------------------------------------------------------ */

View File

@ -207,7 +207,7 @@ public class NoSqlSession extends MemSession
/* ------------------------------------------------------------ */
public Object getVersion()
{
return _version;
return _version;
}
@Override

View File

@ -654,7 +654,7 @@ public class MongoSessionManager extends NoSqlSessionManager
/*------------------------------------------------------------ */
private String getContextKey()
{
return __CONTEXT + "." + _contextId;
return __CONTEXT + "." + _contextId;
}
/*------------------------------------------------------------ */
@ -664,7 +664,7 @@ public class MongoSessionManager extends NoSqlSessionManager
*/
private String getContextAttributeKey(String attr)
{
return getContextKey()+ "." + attr;
return getContextKey()+ "." + attr;
}
@ManagedOperation(value="purge invalid sessions in the session store based on normal criteria", impact="ACTION")

View File

@ -259,7 +259,7 @@ public class WarBundleManifestGenerator
{
poundIndex = url.length();
}
UrlEncoded.decodeUtf8To(url.getBytes(), questionMarkIndex+1,
UrlEncoded.decodeUtf8To(url, questionMarkIndex+1,
poundIndex - questionMarkIndex - 1, res);
return res;
}

View File

@ -23,9 +23,6 @@ import java.net.URI;
import java.net.URL;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TreeSet;
@ -35,7 +32,6 @@ import org.eclipse.jetty.annotations.ClassNameResolver;
import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelper;
import org.eclipse.jetty.util.ConcurrentHashSet;
import org.eclipse.jetty.util.resource.Resource;
import org.objectweb.asm.Opcodes;
import org.osgi.framework.Bundle;
import org.osgi.framework.Constants;
@ -51,13 +47,6 @@ public class AnnotationParser extends org.eclipse.jetty.annotations.AnnotationPa
private ConcurrentHashMap<Resource, Bundle> _resourceToBundle = new ConcurrentHashMap<Resource, Bundle>();
private ConcurrentHashMap<Bundle,URI> _bundleToUri = new ConcurrentHashMap<Bundle, URI>();
static
{
//As of jetty 9.2.0, the impl of asm visitor classes is compatible with both asm4 and asm5.
//We need to use asm4 with osgi, because we need to use aries spifly to support annotations,
//and currently this only supports asm4. Therefore, we set the asm api version to be 4 for osgi.
ASM_OPCODE_VERSION = Opcodes.ASM4;
}
/**
* Keep track of a jetty URI Resource and its associated OSGi bundle.
@ -212,5 +201,4 @@ public class AnnotationParser extends org.eclipse.jetty.annotations.AnnotationPa
scanClass(handlers, getResource(bundle), classUrl.openStream());
}
}
}

View File

@ -30,16 +30,16 @@ import javax.servlet.http.HttpServlet;
*/
public class HttpServiceErrorHandlerHelper
{
private static HttpServlet _customErrorHandler;
private static HttpServlet _customErrorHandler;
public static HttpServlet getCustomErrorHandler()
{
return _customErrorHandler;
}
public static void setHttpServiceErrorHandler(HttpServlet servlet)
{
_customErrorHandler = servlet;
}
public static HttpServlet getCustomErrorHandler()
{
return _customErrorHandler;
}
public static void setHttpServiceErrorHandler(HttpServlet servlet)
{
_customErrorHandler = servlet;
}
}

View File

@ -35,46 +35,46 @@ import org.eclipse.jetty.servlet.ErrorPageErrorHandler;
public class HttpServiceErrorPageErrorHandler extends ErrorPageErrorHandler
{
private static HttpServiceErrorPageErrorHandler INSTANCE;
public static HttpServiceErrorPageErrorHandler getInstance()
{
return INSTANCE;
}
public HttpServiceErrorPageErrorHandler()
{
INSTANCE = this;
}
private static HttpServiceErrorPageErrorHandler INSTANCE;
public static HttpServiceErrorPageErrorHandler getInstance()
{
return INSTANCE;
}
public HttpServiceErrorPageErrorHandler()
{
INSTANCE = this;
}
@Override
public void handle(String target, Request baseRequest,
HttpServletRequest request, HttpServletResponse response)
throws IOException {
if (HttpServiceErrorHandlerHelper.getCustomErrorHandler() != null)
{
try
{
HttpServiceErrorHandlerHelper.getCustomErrorHandler().service(request, response);
}
catch (ServletException e)
{
//well
}
}
if (!response.isCommitted())
{
super.handle(target, baseRequest, request, response);
}
}
@Override
public void handle(String target, Request baseRequest,
HttpServletRequest request, HttpServletResponse response)
throws IOException {
if (HttpServiceErrorHandlerHelper.getCustomErrorHandler() != null)
{
try
{
HttpServiceErrorHandlerHelper.getCustomErrorHandler().service(request, response);
}
catch (ServletException e)
{
//well
}
}
if (!response.isCommitted())
{
super.handle(target, baseRequest, request, response);
}
}
@Override
protected void doStop() throws Exception
{
INSTANCE = null;
super.doStop();
}
@Override
protected void doStop() throws Exception
{
INSTANCE = null;
super.doStop();
}
}

View File

@ -164,24 +164,10 @@
<dependency>
<groupId>org.apache.aries.spifly</groupId>
<artifactId>org.apache.aries.spifly.dynamic.bundle</artifactId>
<version>1.0.0</version>
<version>1.0.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
<version>4.1</version>
</dependency>
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm-commons</artifactId>
<version>4.1</version>
</dependency>
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm-tree</artifactId>
<version>4.1</version>
</dependency>
<!-- Jetty Deps -->
@ -189,20 +175,6 @@
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-annotations</artifactId>
<scope>runtime</scope>
<exclusions>
<exclusion>
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
</exclusion>
<exclusion>
<groupId>org.ow2.asm</groupId>
<artifactId>asm-commons</artifactId>
</exclusion>
<exclusion>
<groupId>org.ow2.asm</groupId>
<artifactId>asm-tree</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
@ -362,31 +334,6 @@
</dependency>
<!-- Eclipse OSGi Deps -->
<!--
<dependency>
<groupId>org.eclipse.osgi</groupId>
<artifactId>org.eclipse.osgi</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.eclipse.osgi</groupId>
<artifactId>org.eclipse.osgi.services</artifactId>
<scope>runtime</scope>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.eclipse.equinox.http</groupId>
<artifactId>servlet</artifactId>
<scope>runtime</scope>
</dependency>
-->
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>test-jetty-webapp</artifactId>

View File

@ -31,13 +31,12 @@ import javax.inject.Inject;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.ops4j.pax.exam.Configuration;
import org.ops4j.pax.exam.CoreOptions;
import org.ops4j.pax.exam.MavenUtils;
import org.ops4j.pax.exam.Option;
import org.ops4j.pax.exam.Configuration;
import org.ops4j.pax.exam.junit.PaxExam;
import org.ops4j.pax.exam.options.MavenUrlReference.VersionResolver;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
@ -64,7 +63,7 @@ public class TestJettyOSGiBootCore
options.addAll(Arrays.asList(options(systemProperty("pax.exam.logging").value("none"))));
options.addAll(Arrays.asList(options(systemProperty("org.ops4j.pax.logging.DefaultServiceLog.level").value(LOG_LEVEL))));
options.addAll(Arrays.asList(options(systemProperty("org.eclipse.jetty.LEVEL").value(LOG_LEVEL))));
options.addAll(Arrays.asList(options(systemProperty("org.eclipse.jetty.annotations.LEVEL").value("DEBUG"))));
return options.toArray(new Option[options.size()]);
}
@ -82,20 +81,12 @@ public class TestJettyOSGiBootCore
public static List<Option> coreJettyDependencies()
{
List<Option> res = new ArrayList<Option>();
String jdk = System.getProperty("java.version");
int firstdot = jdk.indexOf(".");
jdk = jdk.substring(0,firstdot+2);
double version = Double.parseDouble(jdk);
if (version < 1.8)
{
res.add(mavenBundle().groupId( "org.ow2.asm" ).artifactId( "asm" ).versionAsInProject().start());
res.add(mavenBundle().groupId( "org.ow2.asm" ).artifactId( "asm-commons" ).versionAsInProject().start());
res.add(mavenBundle().groupId( "org.ow2.asm" ).artifactId( "asm-tree" ).versionAsInProject().start());
res.add(mavenBundle().groupId( "org.apache.aries" ).artifactId( "org.apache.aries.util" ).version("1.0.0").start());
res.add(mavenBundle().groupId( "org.apache.aries.spifly" ).artifactId( "org.apache.aries.spifly.dynamic.bundle" ).version("1.0.0").start());
}
res.add(mavenBundle().groupId( "org.ow2.asm" ).artifactId( "asm" ).versionAsInProject().start());
res.add(mavenBundle().groupId( "org.ow2.asm" ).artifactId( "asm-commons" ).versionAsInProject().start());
res.add(mavenBundle().groupId( "org.ow2.asm" ).artifactId( "asm-tree" ).versionAsInProject().start());
res.add(mavenBundle().groupId( "org.apache.aries" ).artifactId( "org.apache.aries.util" ).versionAsInProject().start());
res.add(mavenBundle().groupId( "org.apache.aries.spifly" ).artifactId( "org.apache.aries.spifly.dynamic.bundle" ).versionAsInProject().start());
res.add(mavenBundle().groupId( "javax.servlet" ).artifactId( "javax.servlet-api" ).versionAsInProject().noStart());
res.add(mavenBundle().groupId( "javax.annotation" ).artifactId( "javax.annotation-api" ).versionAsInProject().noStart());
@ -119,10 +110,7 @@ public class TestJettyOSGiBootCore
res.add(mavenBundle().groupId( "org.eclipse.jetty" ).artifactId( "jetty-client" ).versionAsInProject().noStart());
res.add(mavenBundle().groupId( "org.eclipse.jetty" ).artifactId( "jetty-jndi" ).versionAsInProject().noStart());
res.add(mavenBundle().groupId( "org.eclipse.jetty" ).artifactId( "jetty-plus" ).versionAsInProject().noStart());
if (version < 1.8)
{
res.add(mavenBundle().groupId( "org.eclipse.jetty" ).artifactId( "jetty-annotations" ).versionAsInProject().start());
}
res.add(mavenBundle().groupId( "org.eclipse.jetty" ).artifactId( "jetty-annotations" ).versionAsInProject().start());
res.add(mavenBundle().groupId( "org.eclipse.jetty.websocket" ).artifactId( "websocket-api" ).versionAsInProject().noStart());
res.add(mavenBundle().groupId( "org.eclipse.jetty.websocket" ).artifactId( "websocket-common" ).versionAsInProject().noStart());
res.add(mavenBundle().groupId( "org.eclipse.jetty.websocket" ).artifactId( "websocket-servlet" ).versionAsInProject().noStart());

View File

@ -86,7 +86,7 @@ public class OverlayServer
server.setStopAtShutdown(true);
//server.setSendServerVersion(true);
// Uncomment to work with JNDI examples
// Uncomment to work with JNDI examples
// new org.eclipse.jetty.plus.jndi.Transaction(new com.atomikos.icatch.jta.UserTransactionImp());

View File

@ -157,7 +157,7 @@ public class ContainerInitializer
interested.add(c.getName());
}
return String.format("ContainerInitializer{%s,interested=%s,applicable=%s,annotated=%s}",_target.getClass().getName(),interested,_applicableTypeNames,_annotatedTypeNames);
return String.format("ContainerInitializer{%s,interested=%s,applicable=%s,annotated=%s}",_target.getClass().getName(),interested,_applicableTypeNames,_annotatedTypeNames);
}
public void resolveClasses(WebAppContext context, Map<String, Set<String>> classMap)

View File

@ -60,7 +60,8 @@ public class AsyncProxyServlet extends ProxyServlet
{
try
{
_log.debug("{} proxying content to downstream: {} bytes", getRequestId(request), length);
if (_log.isDebugEnabled())
_log.debug("{} proxying content to downstream: {} bytes", getRequestId(request), length);
StreamWriter writeListener = (StreamWriter)request.getAttribute(WRITE_LISTENER_ATTRIBUTE);
if (writeListener == null)
{
@ -130,24 +131,30 @@ public class AsyncProxyServlet extends ProxyServlet
{
int requestId = getRequestId(request);
ServletInputStream input = request.getInputStream();
_log.debug("{} asynchronous read start on {}", requestId, input);
if (_log.isDebugEnabled())
_log.debug("{} asynchronous read start on {}", requestId, input);
// First check for isReady() because it has
// side effects, and then for isFinished().
while (input.isReady() && !input.isFinished())
{
int read = input.read(buffer);
_log.debug("{} asynchronous read {} bytes on {}", requestId, read, input);
if (_log.isDebugEnabled())
_log.debug("{} asynchronous read {} bytes on {}", requestId, read, input);
if (read > 0)
{
_log.debug("{} proxying content to upstream: {} bytes", requestId, read);
if (_log.isDebugEnabled())
_log.debug("{} proxying content to upstream: {} bytes", requestId, read);
onRequestContent(proxyRequest, request, provider, buffer, 0, read, this);
// Do not call isReady() so that we can apply backpressure.
break;
}
}
if (!input.isFinished())
_log.debug("{} asynchronous read pending on {}", requestId, input);
{
if (_log.isDebugEnabled())
_log.debug("{} asynchronous read pending on {}", requestId, input);
}
}
protected void onRequestContent(Request proxyRequest, HttpServletRequest request, DeferredContentProvider provider, byte[] buffer, int offset, int length, Callback callback)
@ -158,7 +165,8 @@ public class AsyncProxyServlet extends ProxyServlet
@Override
public void onAllDataRead() throws IOException
{
_log.debug("{} proxying content to upstream completed", getRequestId(request));
if (_log.isDebugEnabled())
_log.debug("{} proxying content to upstream completed", getRequestId(request));
provider.close();
}
@ -225,23 +233,27 @@ public class AsyncProxyServlet extends ProxyServlet
if (state == WriteState.READY)
{
// There is data to write.
_log.debug("{} asynchronous write start of {} bytes on {}", requestId, length, output);
if (_log.isDebugEnabled())
_log.debug("{} asynchronous write start of {} bytes on {}", requestId, length, output);
output.write(buffer, offset, length);
state = WriteState.PENDING;
if (output.isReady())
{
_log.debug("{} asynchronous write of {} bytes completed on {}", requestId, length, output);
if (_log.isDebugEnabled())
_log.debug("{} asynchronous write of {} bytes completed on {}", requestId, length, output);
complete();
}
else
{
_log.debug("{} asynchronous write of {} bytes pending on {}", requestId, length, output);
if (_log.isDebugEnabled())
_log.debug("{} asynchronous write of {} bytes pending on {}", requestId, length, output);
}
}
else if (state == WriteState.PENDING)
{
// The write blocked but is now complete.
_log.debug("{} asynchronous write of {} bytes completing on {}", requestId, length, output);
if (_log.isDebugEnabled())
_log.debug("{} asynchronous write of {} bytes completing on {}", requestId, length, output);
complete();
}
else

View File

@ -26,7 +26,6 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
import javax.servlet.ServletException;
import javax.servlet.UnavailableException;
import javax.servlet.http.Cookie;
@ -133,7 +132,8 @@ public class BalancerServlet extends ProxyServlet
protected URI rewriteURI(HttpServletRequest request)
{
BalancerMember balancerMember = selectBalancerMember(request);
_log.debug("Selected {}", balancerMember);
if (_log.isDebugEnabled())
_log.debug("Selected {}", balancerMember);
String path = request.getRequestURI();
String query = request.getQueryString();
if (query != null)

View File

@ -195,7 +195,7 @@ public class ConnectHandler extends HandlerWrapper
catch (Exception x)
{
// TODO
LOG.warn("ConnectHandler " + baseRequest.getUri() + " " + x);
LOG.warn("ConnectHandler " + baseRequest.getHttpURI() + " " + x);
LOG.debug(x);
}
}

View File

@ -28,13 +28,13 @@ import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.ForkInvoker;
import org.eclipse.jetty.util.IteratingCallback;
import org.eclipse.jetty.util.log.Logger;
public abstract class ProxyConnection extends AbstractConnection
{
protected static final Logger LOG = ConnectHandler.LOG;
private final ForkInvoker<Void> invoker = new ProxyForkInvoker();
private final IteratingCallback pipe = new ProxyIteratingCallback();
private final ByteBufferPool bufferPool;
private final ConcurrentMap<String, Object> context;
private Connection connection;
@ -69,52 +69,7 @@ public abstract class ProxyConnection extends AbstractConnection
@Override
public void onFillable()
{
final ByteBuffer buffer = getByteBufferPool().acquire(getInputBufferSize(), true);
try
{
final int filled = read(getEndPoint(), buffer);
if (LOG.isDebugEnabled())
LOG.debug("{} filled {} bytes", this, filled);
if (filled > 0)
{
write(getConnection().getEndPoint(), buffer, new Callback()
{
@Override
public void succeeded()
{
if (LOG.isDebugEnabled())
LOG.debug("{} wrote {} bytes", this, filled);
bufferPool.release(buffer);
invoker.invoke(null);
}
@Override
public void failed(Throwable x)
{
LOG.debug(this + " failed to write " + filled + " bytes", x);
bufferPool.release(buffer);
connection.close();
}
});
}
else if (filled == 0)
{
bufferPool.release(buffer);
fillInterested();
}
else
{
bufferPool.release(buffer);
connection.getEndPoint().shutdownOutput();
}
}
catch (IOException x)
{
LOG.debug(this + " could not fill", x);
bufferPool.release(buffer);
close();
connection.close();
}
pipe.iterate();
}
protected abstract int read(EndPoint endPoint, ByteBuffer buffer) throws IOException;
@ -130,29 +85,74 @@ public abstract class ProxyConnection extends AbstractConnection
getEndPoint().getRemoteAddress().getPort());
}
private class ProxyForkInvoker extends ForkInvoker<Void> implements Runnable
private class ProxyIteratingCallback extends IteratingCallback
{
private ProxyForkInvoker()
private ByteBuffer buffer;
private int filled;
@Override
protected Action process() throws Exception
{
super(4);
buffer = bufferPool.acquire(getInputBufferSize(), true);
try
{
int filled = this.filled = read(getEndPoint(), buffer);
if (LOG.isDebugEnabled())
LOG.debug("{} filled {} bytes", ProxyConnection.this, filled);
if (filled > 0)
{
write(connection.getEndPoint(), buffer, this);
return Action.SCHEDULED;
}
else if (filled == 0)
{
bufferPool.release(buffer);
fillInterested();
return Action.IDLE;
}
else
{
bufferPool.release(buffer);
connection.getEndPoint().shutdownOutput();
return Action.SUCCEEDED;
}
}
catch (IOException x)
{
if (LOG.isDebugEnabled())
LOG.debug(ProxyConnection.this + " could not fill", x);
disconnect();
return Action.SUCCEEDED;
}
}
@Override
public void fork(Void arg)
public void succeeded()
{
getExecutor().execute(this);
}
@Override
public void run()
{
onFillable();
if (LOG.isDebugEnabled())
LOG.debug("{} wrote {} bytes", ProxyConnection.this, filled);
bufferPool.release(buffer);
super.succeeded();
}
@Override
public void call(Void arg)
protected void onCompleteSuccess()
{
onFillable();
}
@Override
protected void onCompleteFailure(Throwable x)
{
if (LOG.isDebugEnabled())
LOG.debug(ProxyConnection.this + " failed to write " + filled + " bytes", x);
disconnect();
}
private void disconnect()
{
bufferPool.release(buffer);
ProxyConnection.this.close();
connection.close();
}
}
}

View File

@ -34,6 +34,7 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import javax.servlet.AsyncContext;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.UnavailableException;
import javax.servlet.http.HttpServlet;
@ -200,7 +201,8 @@ public class ProxyServlet extends HttpServlet
}
catch (Exception x)
{
_log.debug(x);
if (_log.isDebugEnabled())
_log.debug(x);
}
}
@ -361,7 +363,8 @@ public class ProxyServlet extends HttpServlet
{
if (!_whiteList.contains(hostPort))
{
_log.debug("Host {}:{} not whitelisted", host, port);
if (_log.isDebugEnabled())
_log.debug("Host {}:{} not whitelisted", host, port);
return false;
}
}
@ -369,7 +372,8 @@ public class ProxyServlet extends HttpServlet
{
if (_blackList.contains(hostPort))
{
_log.debug("Host {}:{} blacklisted", host, port);
if (_log.isDebugEnabled())
_log.debug("Host {}:{} blacklisted", host, port);
return false;
}
}
@ -388,7 +392,8 @@ public class ProxyServlet extends HttpServlet
StringBuffer uri = request.getRequestURL();
if (request.getQueryString() != null)
uri.append("?").append(request.getQueryString());
_log.debug("{} rewriting: {} -> {}", requestId, uri, rewrittenURI);
if (_log.isDebugEnabled())
_log.debug("{} rewriting: {} -> {}", requestId, uri, rewrittenURI);
}
if (rewrittenURI == null)
@ -492,7 +497,8 @@ public class ProxyServlet extends HttpServlet
protected void onClientRequestFailure(Request proxyRequest, HttpServletRequest request, Throwable failure)
{
_log.debug(getRequestId(request) + " client request failure", failure);
if (_log.isDebugEnabled())
_log.debug(getRequestId(request) + " client request failure", failure);
proxyRequest.abort(failure);
}
@ -516,10 +522,6 @@ public class ProxyServlet extends HttpServlet
protected void onResponseHeaders(HttpServletRequest request, HttpServletResponse response, Response proxyResponse)
{
// Clear the response headers in case it comes with predefined ones.
for (String name : response.getHeaderNames())
response.setHeader(name, null);
for (HttpField field : proxyResponse.getHeaders())
{
String headerName = field.getName();
@ -539,7 +541,8 @@ public class ProxyServlet extends HttpServlet
{
try
{
_log.debug("{} proxying content to downstream: {} bytes", getRequestId(request), length);
if (_log.isDebugEnabled())
_log.debug("{} proxying content to downstream: {} bytes", getRequestId(request), length);
response.getOutputStream().write(buffer, offset, length);
callback.succeeded();
}
@ -551,16 +554,34 @@ public class ProxyServlet extends HttpServlet
protected void onResponseSuccess(HttpServletRequest request, HttpServletResponse response, Response proxyResponse)
{
_log.debug("{} proxying successful", getRequestId(request));
if (_log.isDebugEnabled())
_log.debug("{} proxying successful", getRequestId(request));
AsyncContext asyncContext = request.getAsyncContext();
asyncContext.complete();
}
protected void onResponseFailure(HttpServletRequest request, HttpServletResponse response, Response proxyResponse, Throwable failure)
{
_log.debug(getRequestId(request) + " proxying failed", failure);
if (!response.isCommitted())
if (_log.isDebugEnabled())
_log.debug(getRequestId(request) + " proxying failed", failure);
if (response.isCommitted())
{
try
{
// Use Jetty specific behavior to close connection.
response.sendError(-1);
AsyncContext asyncContext = request.getAsyncContext();
asyncContext.complete();
}
catch (IOException x)
{
if (_log.isDebugEnabled())
_log.debug(getRequestId(request) + " could not close the connection", failure);
}
}
else
{
response.resetBuffer();
if (failure instanceof TimeoutException)
response.setStatus(HttpServletResponse.SC_GATEWAY_TIMEOUT);
else
@ -673,7 +694,8 @@ public class ProxyServlet extends HttpServlet
String contextPath = config.getServletContext().getContextPath();
_prefix = _prefix == null ? contextPath : (contextPath + _prefix);
proxyServlet._log.debug(config.getServletName() + " @ " + _prefix + " to " + _proxyTo);
if (proxyServlet._log.isDebugEnabled())
proxyServlet._log.debug(config.getServletName() + " @ " + _prefix + " to " + _proxyTo);
}
protected URI rewriteURI(HttpServletRequest request)
@ -793,7 +815,8 @@ public class ProxyServlet extends HttpServlet
onResponseSuccess(request, response, result.getResponse());
else
onResponseFailure(request, response, result.getResponse(), result.getFailure());
_log.debug("{} proxying complete", getRequestId(request));
if (_log.isDebugEnabled())
_log.debug("{} proxying complete", getRequestId(request));
}
}
@ -818,7 +841,8 @@ public class ProxyServlet extends HttpServlet
@Override
protected ByteBuffer onRead(byte[] buffer, int offset, int length)
{
_log.debug("{} proxying content to upstream: {} bytes", getRequestId(request), length);
if (_log.isDebugEnabled())
_log.debug("{} proxying content to upstream: {} bytes", getRequestId(request), length);
return onRequestContent(proxyRequest, request, buffer, offset, length);
}

View File

@ -19,8 +19,10 @@
package org.eclipse.jetty.proxy;
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ConnectException;
@ -30,6 +32,7 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -42,7 +45,14 @@ import java.util.zip.GZIPOutputStream;
import javax.servlet.AsyncContext;
import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
@ -55,11 +65,16 @@ import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.api.Response;
import org.eclipse.jetty.client.api.Result;
import org.eclipse.jetty.client.http.HttpDestinationOverHTTP;
import org.eclipse.jetty.client.util.BufferingResponseListener;
import org.eclipse.jetty.client.util.BytesContentProvider;
import org.eclipse.jetty.client.util.InputStreamResponseListener;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
@ -95,6 +110,7 @@ public class ProxyServletTest
private HttpClient client;
private Server proxy;
private ServerConnector proxyConnector;
private ServletContextHandler proxyContext;
private ProxyServlet proxyServlet;
private Server server;
private ServerConnector serverConnector;
@ -112,13 +128,20 @@ public class ProxyServletTest
private void prepareProxy(Map<String, String> initParams) throws Exception
{
proxy = new Server();
proxyConnector = new ServerConnector(proxy);
HttpConfiguration configuration = new HttpConfiguration();
configuration.setSendDateHeader(false);
configuration.setSendServerVersion(false);
String value = initParams.get("outputBufferSize");
if (value != null)
configuration.setOutputBufferSize(Integer.valueOf(value));
proxyConnector = new ServerConnector(proxy, new HttpConnectionFactory(configuration));
proxy.addConnector(proxyConnector);
ServletContextHandler proxyCtx = new ServletContextHandler(proxy, "/", true, false);
proxyContext = new ServletContextHandler(proxy, "/", true, false);
ServletHolder proxyServletHolder = new ServletHolder(proxyServlet);
proxyServletHolder.setInitParameters(initParams);
proxyCtx.addServlet(proxyServletHolder, "/*");
proxyContext.addServlet(proxyServletHolder, "/*");
proxy.start();
@ -331,7 +354,7 @@ public class ProxyServletTest
ContentResponse response = client.newRequest("localhost", serverConnector.getLocalPort())
.method(HttpMethod.POST)
.content(new BytesContentProvider(content))
.timeout(555, TimeUnit.SECONDS)
.timeout(5, TimeUnit.SECONDS)
.send();
Assert.assertEquals(200, response.getStatus());
@ -899,5 +922,184 @@ public class ProxyServletTest
Assert.assertTrue(response3.getHeaders().containsKey(PROXIED_HEADER));
}
@Test
public void testProxyRequestFailureInTheMiddleOfProxyingSmallContent() throws Exception
{
final long proxyTimeout = 1000;
Map<String, String> proxyParams = new HashMap<>();
proxyParams.put("timeout", String.valueOf(proxyTimeout));
prepareProxy(proxyParams);
final CountDownLatch chunk1Latch = new CountDownLatch(1);
final int chunk1 = 'q';
final int chunk2 = 'w';
prepareServer(new HttpServlet()
{
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
ServletOutputStream output = response.getOutputStream();
output.write(chunk1);
response.flushBuffer();
// Wait for the client to receive this chunk.
await(chunk1Latch, 5000);
// Send second chunk, must not be received by proxy.
output.write(chunk2);
}
private boolean await(CountDownLatch latch, long ms) throws IOException
{
try
{
return latch.await(ms, TimeUnit.MILLISECONDS);
}
catch (InterruptedException x)
{
throw new InterruptedIOException();
}
}
});
HttpClient client = prepareClient();
InputStreamResponseListener listener = new InputStreamResponseListener();
int port = serverConnector.getLocalPort();
client.newRequest("localhost", port).send(listener);
// Make the proxy request fail; given the small content, the
// proxy-to-client response is not committed yet so it will be reset.
TimeUnit.MILLISECONDS.sleep(2 * proxyTimeout);
Response response = listener.get(5, TimeUnit.SECONDS);
Assert.assertEquals(504, response.getStatus());
// Make sure there is no content, as the proxy-to-client response has been reset.
InputStream input = listener.getInputStream();
Assert.assertEquals(-1, input.read());
chunk1Latch.countDown();
// Result succeeds because a 504 is a valid HTTP response.
Result result = listener.await(5, TimeUnit.SECONDS);
Assert.assertTrue(result.isSucceeded());
// Make sure the proxy does not receive chunk2.
Assert.assertEquals(-1, input.read());
HttpDestinationOverHTTP destination = (HttpDestinationOverHTTP)client.getDestination("http", "localhost", port);
Assert.assertEquals(0, destination.getConnectionPool().getIdleConnections().size());
}
@Test
public void testProxyRequestFailureInTheMiddleOfProxyingBigContent() throws Exception
{
final long proxyTimeout = 1000;
int outputBufferSize = 1024;
Map<String, String> proxyParams = new HashMap<>();
proxyParams.put("timeout", String.valueOf(proxyTimeout));
proxyParams.put("outputBufferSize", String.valueOf(outputBufferSize));
prepareProxy(proxyParams);
final CountDownLatch chunk1Latch = new CountDownLatch(1);
final byte[] chunk1 = new byte[outputBufferSize];
new Random().nextBytes(chunk1);
final int chunk2 = 'w';
prepareServer(new HttpServlet()
{
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
ServletOutputStream output = response.getOutputStream();
output.write(chunk1);
response.flushBuffer();
// Wait for the client to receive this chunk.
await(chunk1Latch, 5000);
// Send second chunk, must not be received by proxy.
output.write(chunk2);
}
private boolean await(CountDownLatch latch, long ms) throws IOException
{
try
{
return latch.await(ms, TimeUnit.MILLISECONDS);
}
catch (InterruptedException x)
{
throw new InterruptedIOException();
}
}
});
HttpClient client = prepareClient();
InputStreamResponseListener listener = new InputStreamResponseListener();
int port = serverConnector.getLocalPort();
client.newRequest("localhost", port).send(listener);
Response response = listener.get(5, TimeUnit.SECONDS);
Assert.assertEquals(200, response.getStatus());
InputStream input = listener.getInputStream();
for (int i = 0; i < chunk1.length; ++i)
Assert.assertEquals(chunk1[i] & 0xFF, input.read());
TimeUnit.MILLISECONDS.sleep(2 * proxyTimeout);
chunk1Latch.countDown();
try
{
// Make sure the proxy does not receive chunk2.
input.read();
Assert.fail();
}
catch (EOFException x)
{
// Expected
}
HttpDestinationOverHTTP destination = (HttpDestinationOverHTTP)client.getDestination("http", "localhost", port);
Assert.assertEquals(0, destination.getConnectionPool().getIdleConnections().size());
}
@Test
public void testResponseHeadersAreNotRemoved() throws Exception
{
prepareProxy();
proxyContext.stop();
final String headerName = "X-Test";
final String headerValue = "test-value";
proxyContext.addFilter(new FilterHolder(new Filter()
{
@Override
public void init(FilterConfig filterConfig) throws ServletException
{
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
((HttpServletResponse)response).addHeader(headerName, headerValue);
chain.doFilter(request, response);
}
@Override
public void destroy()
{
}
}), "/*", EnumSet.of(DispatcherType.REQUEST));
proxyContext.start();
prepareServer(new EmptyHttpServlet());
HttpClient client = prepareClient();
ContentResponse response = client.newRequest("localhost", serverConnector.getLocalPort()).send();
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals(headerValue, response.getHeaders().get(headerName));
}
// TODO: test proxy authentication
}

View File

@ -7,7 +7,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-quickstart</artifactId>
<name>Example :: Jetty Quick Start</name>
<name>Jetty :: Quick Start</name>
<description>Jetty Quick Start</description>
<url>http://www.eclipse.org/jetty</url>
<dependencies>
@ -82,74 +82,6 @@
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>1.7</version>
<configuration>
<platforms>
<platform>unix</platform>
</platforms>
<programs>
<program>
<id>preconfigure</id>
<mainClass>org.eclipse.jetty.quickstart.PreconfigureQuickStartWar</mainClass>
</program>
<program>
<mainClass>org.eclipse.jetty.quickstart.QuickStartWar</mainClass>
<id>quickstart</id>
</program>
</programs>
</configuration>
</plugin>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy</id>
<phase>generate-resources</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>test-jndi-webapp</artifactId>
<version>${project.version}</version>
<type>war</type>
<overWrite>true</overWrite>
<includes>**</includes>
<outputDirectory>${basedir}/target</outputDirectory>
<destFileName>test-jndi.war</destFileName>
</artifactItem>
<artifactItem>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>test-spec-webapp</artifactId>
<version>${project.version}</version>
<type>war</type>
<overWrite>true</overWrite>
<includes>**</includes>
<outputDirectory>${basedir}/target</outputDirectory>
<destFileName>test-spec.war</destFileName>
</artifactItem>
<artifactItem>
<groupId>org.eclipse.jetty</groupId>
<artifactId>test-jetty-webapp</artifactId>
<version>${project.version}</version>
<type>war</type>
<overWrite>true</overWrite>
<includes>**</includes>
<outputDirectory>${basedir}/target</outputDirectory>
<destFileName>test-standard.war</destFileName>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>

View File

@ -43,7 +43,7 @@ public class CompactPathRule extends Rule implements Rule.ApplyURI
String uri = request.getRequestURI();
if (uri.startsWith("/"))
uri = URIUtil.compactPath(uri);
request.setRequestURI(uri);
request.setURIPathQuery(uri);
}
@Override

View File

@ -88,7 +88,7 @@ public class RewritePatternRule extends PatternRule implements Rule.ApplyURI
{
if (_query == null)
{
request.setRequestURI(newURI);
request.setURIPathQuery(newURI);
}
else
{
@ -97,9 +97,7 @@ public class RewritePatternRule extends PatternRule implements Rule.ApplyURI
queryString = queryString + "&" + _query;
else
queryString = _query;
HttpURI uri = new HttpURI(newURI + "?" + queryString);
request.setUri(uri);
request.setRequestURI(newURI);
request.setURIPathQuery(newURI);
request.setQueryString(queryString);
}
}

View File

@ -100,7 +100,7 @@ public class RewriteRegexRule extends RegexRule implements Rule.ApplyURI
{
if (_query==null)
{
request.setRequestURI(newURI);
request.setURIPathQuery(newURI);
}
else
{
@ -108,9 +108,7 @@ public class RewriteRegexRule extends RegexRule implements Rule.ApplyURI
if (!_queryGroup && request.getQueryString()!=null)
query=request.getQueryString()+"&"+query;
HttpURI uri=new HttpURI(newURI+"?"+query);
request.setUri(uri);
request.setRequestURI(newURI);
request.setURIPathQuery(newURI);
request.setQueryString(query);
}
}

View File

@ -216,7 +216,7 @@ public class RuleContainer extends Rule
if (rule instanceof Rule.ApplyURI)
((Rule.ApplyURI)rule).applyURI((Request)request,((Request)request).getRequestURI(), encoded);
else
((Request)request).setRequestURI(encoded);
((Request)request).setURIPathQuery(encoded);
}
if (_rewritePathInfo)

View File

@ -73,11 +73,11 @@ public class ForwardedSchemeHeaderRuleTest extends AbstractRuleTestCase
_rule.matchAndApply("/",_request,_response);
assertEquals("https",_request.getScheme());
_request.setScheme(null);
_request.setScheme("other");
// header value doesn't match rule's value
setRequestHeader("Front-End-Https", "off");
_rule.matchAndApply("/",_request,_response);
assertEquals(null,_request.getScheme());
assertEquals("other",_request.getScheme());
_request.setScheme(null);
// header value can be any value

View File

@ -25,6 +25,10 @@ import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.server.Request;
import org.junit.After;
import org.junit.Before;
@ -138,7 +142,7 @@ public class PatternRuleTest
new Request(null,null)
{
{
setRequestURI(uri);
setMetaData(new MetaData.Request("GET",new HttpURI(uri),HttpVersion.HTTP_1_0,new HttpFields()));
}
}, null
);

View File

@ -85,7 +85,7 @@ public class RewriteHandlerTest extends AbstractRuleTestCase
_handler.setOriginalPathAttribute("/before");
_handler.setRewriteRequestURI(true);
_handler.setRewritePathInfo(true);
_request.setRequestURI("/xxx/bar");
_request.setURIPathQuery("/xxx/bar");
_request.setPathInfo("/xxx/bar");
_handler.handle("/xxx/bar",_request,_request, _response);
assertEquals(201,_response.getStatus());
@ -99,7 +99,7 @@ public class RewriteHandlerTest extends AbstractRuleTestCase
_handler.setOriginalPathAttribute("/before");
_handler.setRewriteRequestURI(false);
_handler.setRewritePathInfo(false);
_request.setRequestURI("/foo/bar");
_request.setURIPathQuery("/foo/bar");
_request.setPathInfo("/foo/bar");
_handler.handle("/foo/bar",_request,_request, _response);
@ -112,7 +112,7 @@ public class RewriteHandlerTest extends AbstractRuleTestCase
_response.setStatus(200);
_request.setHandled(false);
_handler.setOriginalPathAttribute(null);
_request.setRequestURI("/aaa/bar");
_request.setURIPathQuery("/aaa/bar");
_request.setPathInfo("/aaa/bar");
_handler.handle("/aaa/bar",_request,_request, _response);
assertEquals(201,_response.getStatus());
@ -126,7 +126,7 @@ public class RewriteHandlerTest extends AbstractRuleTestCase
_handler.setOriginalPathAttribute("before");
_handler.setRewriteRequestURI(true);
_handler.setRewritePathInfo(true);
_request.setRequestURI("/aaa/bar");
_request.setURIPathQuery("/aaa/bar");
_request.setPathInfo("/aaa/bar");
_handler.handle("/aaa/bar",_request,_request, _response);
assertEquals(201,_response.getStatus());
@ -138,7 +138,7 @@ public class RewriteHandlerTest extends AbstractRuleTestCase
_response.setStatus(200);
_request.setHandled(false);
_rule2.setTerminating(true);
_request.setRequestURI("/aaa/bar");
_request.setURIPathQuery("/aaa/bar");
_request.setPathInfo("/aaa/bar");
_handler.handle("/aaa/bar",_request,_request, _response);
assertEquals(201,_response.getStatus());
@ -154,7 +154,7 @@ public class RewriteHandlerTest extends AbstractRuleTestCase
_request.setAttribute("target",null);
_request.setAttribute("URI",null);
_request.setAttribute("info",null);
_request.setRequestURI("/aaa/bar");
_request.setURIPathQuery("/aaa/bar");
_request.setPathInfo("/aaa/bar");
_handler.handle("/aaa/bar",_request,_request, _response);
assertEquals(200,_response.getStatus());
@ -174,7 +174,7 @@ public class RewriteHandlerTest extends AbstractRuleTestCase
_handler.setOriginalPathAttribute("/before");
_handler.setRewriteRequestURI(true);
_handler.setRewritePathInfo(false);
_request.setRequestURI("/ccc/x%20y");
_request.setURIPathQuery("/ccc/x%20y");
_request.setPathInfo("/ccc/x y");
_handler.handle("/ccc/x y",_request,_request, _response);
assertEquals(201,_response.getStatus());
@ -193,7 +193,7 @@ public class RewriteHandlerTest extends AbstractRuleTestCase
_handler.setOriginalPathAttribute("/before");
_handler.setRewriteRequestURI(true);
_handler.setRewritePathInfo(false);
_request.setRequestURI("/xxx/x%20y");
_request.setURIPathQuery("/xxx/x%20y");
_request.setPathInfo("/xxx/x y");
_handler.handle("/xxx/x y",_request,_request, _response);
assertEquals(201,_response.getStatus());

View File

@ -88,7 +88,7 @@ public class RewritePatternRuleTest extends AbstractRuleTestCase
{
String replacement = "/replace";
String queryString = "request=parameter";
_request.setUri(new HttpURI("/old/context"));
_request.setURIPathQuery("/old/context");
_request.setQueryString(queryString);
RewritePatternRule rewritePatternRule = new RewritePatternRule();
@ -111,7 +111,7 @@ public class RewritePatternRuleTest extends AbstractRuleTestCase
String[] split = replacement.split("\\?", 2);
String path = split[0];
String queryString = split[1];
_request.setUri(new HttpURI("/old/context"));
_request.setURIPathQuery("/old/context");
_request.setQueryString(requestQueryString);
RewritePatternRule rewritePatternRule = new RewritePatternRule();

View File

@ -66,15 +66,13 @@ public class RewriteRegexRuleTest extends AbstractRuleTestCase
for (String[] test : _tests)
{
reset();
_request.setRequestURI(null);
_request.setURIPathQuery(null);
String t=test[0]+"?"+test[1]+">"+test[2]+"|"+test[3];
_rule.setRegex(test[2]);
_rule.setReplacement(test[3]);
_request.setUri(new HttpURI(test[0]+(test[1]==null?"":("?"+test[1]))));
_request.getRequestURI();
_request.setURIPathQuery(test[0]+(test[1]==null?"":("?"+test[1])));
String result = _rule.matchAndApply(test[0], _request, _response);
assertEquals(t, test[4], result);
@ -89,7 +87,7 @@ public class RewriteRegexRuleTest extends AbstractRuleTestCase
if (test[5]!=null)
{
MultiMap<String> params=new MultiMap<String>();
UrlEncoded.decodeTo(test[5],params, StandardCharsets.UTF_8,-1);
UrlEncoded.decodeTo(test[5],params, StandardCharsets.UTF_8);
for (String n:params.keySet())
assertEquals(params.getString(n),_request.getParameter(n));
@ -110,7 +108,7 @@ public class RewriteRegexRuleTest extends AbstractRuleTestCase
_rule.setRegex(test[2]);
_rule.setReplacement(test[3]);
_request.setRequestURI(test[0]);
_request.setURIPathQuery(test[0]);
_request.setQueryString(test[1]);
_request.getAttributes().clearAttributes();

View File

@ -41,7 +41,7 @@ public class ValidUrlRuleTest extends AbstractRuleTestCase
public void testValidUrl() throws Exception
{
_rule.setCode("404");
_request.setRequestURI("/valid/uri.html");
_request.setURIPathQuery("/valid/uri.html");
_rule.matchAndApply(_request.getRequestURI(), _request, _response);
@ -52,7 +52,7 @@ public class ValidUrlRuleTest extends AbstractRuleTestCase
public void testInvalidUrl() throws Exception
{
_rule.setCode("404");
_request.setRequestURI("/invalid%0c/uri.html");
_request.setURIPathQuery("/invalid%0c/uri.html");
String result = _rule.matchAndApply(_request.getRequestURI(), _request, _response);
@ -64,7 +64,7 @@ public class ValidUrlRuleTest extends AbstractRuleTestCase
{
_rule.setCode("405");
_rule.setReason("foo");
_request.setRequestURI("/%00/");
_request.setURIPathQuery("/%00/");
String result = _rule.matchAndApply(_request.getRequestURI(), _request, _response);
@ -77,7 +77,7 @@ public class ValidUrlRuleTest extends AbstractRuleTestCase
{
_rule.setCode("405");
_rule.setReason("foo");
_request.setRequestURI("/jsp/bean1.jsp%00");
_request.setURIPathQuery("/jsp/bean1.jsp%00");
String result = _rule.matchAndApply(_request.getRequestURI(), _request, _response);
@ -91,7 +91,7 @@ public class ValidUrlRuleTest extends AbstractRuleTestCase
{
_rule.setCode("405");
_rule.setReason("foo");
_request.setRequestURI("/jsp/shamrock-%00%E2%98%98.jsp");
_request.setURIPathQuery("/jsp/shamrock-%00%E2%98%98.jsp");
String result = _rule.matchAndApply(_request.getRequestURI(), _request, _response);
@ -105,7 +105,7 @@ public class ValidUrlRuleTest extends AbstractRuleTestCase
{
_rule.setCode("405");
_rule.setReason("foo");
_request.setRequestURI("/jsp/shamrock-%E2%98%98.jsp");
_request.setURIPathQuery("/jsp/shamrock-%E2%98%98.jsp");
String result = _rule.matchAndApply(_request.getRequestURI(), _request, _response);

View File

@ -49,7 +49,7 @@ public class VirtualHostRuleContainerTest extends AbstractRuleTestCase
_fooContainerRule.setRules(new Rule[] { _fooRule });
start(false);
_request.setRequestURI("/cheese/bar");
_request.setURIPathQuery("/cheese/bar");
_handler.setServer(_server);
_handler.start();
@ -58,7 +58,7 @@ public class VirtualHostRuleContainerTest extends AbstractRuleTestCase
@Test
public void testArbitraryHost() throws Exception
{
_request.setServerName("cheese.com");
_request.setAuthority("cheese.com",0);
_handler.setRules(new Rule[] { _rule, _fooContainerRule });
handleRequest();
assertEquals("{_rule, _fooContainerRule, Host: cheese.com}: applied _rule", "/rule/bar", _request.getRequestURI());
@ -67,7 +67,7 @@ public class VirtualHostRuleContainerTest extends AbstractRuleTestCase
@Test
public void testVirtualHost() throws Exception
{
_request.setServerName("foo.com");
_request.setAuthority("foo.com",0);
_handler.setRules(new Rule[] { _fooContainerRule });
handleRequest();
assertEquals("{_fooContainerRule, Host: foo.com}: applied _fooRule", "/cheese/fooRule", _request.getRequestURI());
@ -76,8 +76,8 @@ public class VirtualHostRuleContainerTest extends AbstractRuleTestCase
@Test
public void testCascadingRules() throws Exception
{
_request.setServerName("foo.com");
_request.setRequestURI("/cheese/bar");
_request.setAuthority("foo.com",0);
_request.setURIPathQuery("/cheese/bar");
_rule.setTerminating(false);
_fooRule.setTerminating(false);
@ -87,17 +87,17 @@ public class VirtualHostRuleContainerTest extends AbstractRuleTestCase
handleRequest();
assertEquals("{_rule, _fooContainerRule}: applied _rule, didn't match _fooRule", "/rule/bar", _request.getRequestURI());
_request.setRequestURI("/cheese/bar");
_request.setURIPathQuery("/cheese/bar");
_handler.setRules(new Rule[] { _fooContainerRule, _rule });
handleRequest();
assertEquals("{_fooContainerRule, _rule}: applied _fooRule, _rule","/rule/fooRule", _request.getRequestURI());
_request.setRequestURI("/cheese/bar");
_request.setURIPathQuery("/cheese/bar");
_fooRule.setTerminating(true);
handleRequest();
assertEquals("{_fooContainerRule, _rule}: (_fooRule is terminating); applied _fooRule, _rule", "/rule/fooRule", _request.getRequestURI());
_request.setRequestURI("/cheese/bar");
_request.setURIPathQuery("/cheese/bar");
_fooRule.setTerminating(false);
_fooContainerRule.setTerminating(true);
handleRequest();
@ -107,7 +107,7 @@ public class VirtualHostRuleContainerTest extends AbstractRuleTestCase
@Test
public void testCaseInsensitiveHostname() throws Exception
{
_request.setServerName("Foo.com");
_request.setAuthority("Foo.com",0);
_fooContainerRule.setVirtualHosts(new String[] {"foo.com"} );
_handler.setRules(new Rule[]{ _fooContainerRule });
@ -118,21 +118,21 @@ public class VirtualHostRuleContainerTest extends AbstractRuleTestCase
@Test
public void testEmptyVirtualHost() throws Exception
{
_request.setServerName("cheese.com");
_request.setAuthority("cheese.com",0);
_handler.setRules(new Rule[] { _fooContainerRule });
_fooContainerRule.setVirtualHosts(null);
handleRequest();
assertEquals("{_fooContainerRule: virtual hosts array is null, Host: cheese.com}: apply _fooRule", "/cheese/fooRule", _request.getRequestURI());
_request.setRequestURI("/cheese/bar");
_request.setRequestURI("/cheese/bar");
_request.setURIPathQuery("/cheese/bar");
_request.setURIPathQuery("/cheese/bar");
_fooContainerRule.setVirtualHosts(new String[] {});
handleRequest();
assertEquals("{_fooContainerRule: virtual hosts array is empty, Host: cheese.com}: apply _fooRule", "/cheese/fooRule", _request.getRequestURI());
_request.setRequestURI("/cheese/bar");
_request.setRequestURI("/cheese/bar");
_request.setURIPathQuery("/cheese/bar");
_request.setURIPathQuery("/cheese/bar");
_fooContainerRule.setVirtualHosts(new String[] {null});
handleRequest();
assertEquals("{_fooContainerRule: virtual host is null, Host: cheese.com}: apply _fooRule", "/cheese/fooRule", _request.getRequestURI());
@ -142,14 +142,14 @@ public class VirtualHostRuleContainerTest extends AbstractRuleTestCase
@Test
public void testMultipleVirtualHosts() throws Exception
{
_request.setServerName("foo.com");
_request.setAuthority("foo.com",0);
_handler.setRules(new Rule[] {_fooContainerRule });
_fooContainerRule.setVirtualHosts(new String[]{ "cheese.com" });
handleRequest();
assertEquals("{_fooContainerRule: vhosts[cheese.com], Host: foo.com}: no effect", "/cheese/bar", _request.getRequestURI());
_request.setRequestURI("/cheese/bar");
_request.setURIPathQuery("/cheese/bar");
_fooContainerRule.addVirtualHost( "foo.com" );
handleRequest();
assertEquals("{_fooContainerRule: vhosts[cheese.com, foo.com], Host: foo.com}: apply _fooRule", "/cheese/fooRule", _request.getRequestURI());
@ -182,8 +182,8 @@ public class VirtualHostRuleContainerTest extends AbstractRuleTestCase
for(String host: requestHosts)
{
_request.setServerName(host);
_request.setRequestURI("/cheese/bar");
_request.setAuthority(host,0);
_request.setURIPathQuery("/cheese/bar");
handleRequest();
if(succeed)
assertEquals("{_fooContainerRule, Host: "+host+"}: should apply _fooRule", "/cheese/fooRule", _request.getRequestURI());

View File

@ -102,7 +102,7 @@ public class GatewayServer extends Server
public GatewayServer()
{
this("",DFT_EXT_PATH,DFT_CONNECT_PATH,new StandardTargetIdRetriever());
this("",DFT_EXT_PATH,DFT_CONNECT_PATH,new StandardTargetIdRetriever());
}
public GatewayServer(String contextPath, String externalServletPath,String gatewayServletPath, TargetIdRetriever targetIdRetriever)
@ -145,7 +145,7 @@ public class GatewayServer extends Server
public Gateway getGateway()
{
return gateway;
return gateway;
}
public ServletHolder getExternalServlet()

View File

@ -1,37 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2014 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.security;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @version $Rev: 4466 $ $Date: 2009-02-10 23:42:54 +0100 (Tue, 10 Feb 2009) $
* @deprecated
*/
public interface CrossContextPsuedoSession<T>
{
T fetch(HttpServletRequest request);
void store(T data, HttpServletResponse response);
void clear(HttpServletRequest request);
}

View File

@ -1,100 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2014 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.security;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @version $Rev: 4660 $ $Date: 2009-02-25 17:29:53 +0100 (Wed, 25 Feb 2009) $
* @deprecated
*/
public class HashCrossContextPsuedoSession<T> implements CrossContextPsuedoSession<T>
{
private final String _cookieName;
private final String _cookiePath;
private final Random _random = new SecureRandom();
private final Map<String, T> _data = new HashMap<String, T>();
public HashCrossContextPsuedoSession(String cookieName, String cookiePath)
{
this._cookieName = cookieName;
this._cookiePath = cookiePath == null ? "/" : cookiePath;
}
public T fetch(HttpServletRequest request)
{
Cookie[] cookies = request.getCookies();
if (cookies == null)
return null;
for (Cookie cookie : cookies)
{
if (_cookieName.equals(cookie.getName()))
{
String key = cookie.getValue();
return _data.get(key);
}
}
return null;
}
public void store(T datum, HttpServletResponse response)
{
String key;
synchronized (_data)
{
// Create new ID
while (true)
{
key = Long.toString(Math.abs(_random.nextLong()), 30 + (int) (System.currentTimeMillis() % 7));
if (!_data.containsKey(key)) break;
}
_data.put(key, datum);
}
Cookie cookie = new Cookie(_cookieName, key);
cookie.setPath(_cookiePath);
response.addCookie(cookie);
}
public void clear(HttpServletRequest request)
{
for (Cookie cookie : request.getCookies())
{
if (_cookieName.equals(cookie.getName()))
{
String key = cookie.getValue();
_data.remove(key);
break;
}
}
}
}

View File

@ -331,28 +331,28 @@ public class DeferredAuthentication implements Authentication.Deferred
}
@Override
public Collection<String> getHeaderNames()
{
return Collections.emptyList();
}
@Override
public String getHeader(String arg0)
{
return null;
}
@Override
public Collection<String> getHeaders(String arg0)
{
public Collection<String> getHeaderNames()
{
return Collections.emptyList();
}
}
@Override
public int getStatus()
{
return 0;
}
@Override
public String getHeader(String arg0)
{
return null;
}
@Override
public Collection<String> getHeaders(String arg0)
{
return Collections.emptyList();
}
@Override
public int getStatus()
{
return 0;
}
};

View File

@ -50,7 +50,7 @@ public class SpnegoAuthenticator extends LoginAuthenticator
*/
public SpnegoAuthenticator( String authMethod )
{
_authMethod = authMethod;
_authMethod = authMethod;
}
@Override
@ -77,10 +77,10 @@ public class SpnegoAuthenticator extends LoginAuthenticator
{
try
{
if (DeferredAuthentication.isDeferred(res))
{
if (DeferredAuthentication.isDeferred(res))
{
return Authentication.UNAUTHENTICATED;
}
}
LOG.debug("SpengoAuthenticator: sending challenge");
res.setHeader(HttpHeader.WWW_AUTHENTICATE.asString(), HttpHeader.NEGOTIATE.asString());

View File

@ -131,7 +131,7 @@ public abstract class AbstractNCSARequestLog extends AbstractLifeCycle implement
buf.append("] \"");
buf.append(request.getMethod());
buf.append(' ');
buf.append(request.getUri().toString());
buf.append(request.getHttpURI().toString());
buf.append(' ');
buf.append(request.getProtocol());
buf.append("\" ");

View File

@ -22,6 +22,7 @@ import java.io.IOException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import javax.servlet.DispatcherType;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
@ -30,6 +31,7 @@ import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.Attributes;
import org.eclipse.jetty.util.MultiMap;
@ -43,27 +45,24 @@ public class Dispatcher implements RequestDispatcher
public final static String __FORWARD_PREFIX="javax.servlet.forward.";
private final ContextHandler _contextHandler;
private final String _uri;
private final String _path;
private final String _query;
private final HttpURI _uri;
private final String _pathInfo;
private final String _named;
public Dispatcher(ContextHandler contextHandler, String uri, String pathInContext, String query)
public Dispatcher(ContextHandler contextHandler, HttpURI uri, String pathInfo)
{
_contextHandler=contextHandler;
_uri=uri;
_path=pathInContext;
_query=query;
_pathInfo=pathInfo;
_named=null;
}
public Dispatcher(ContextHandler contextHandler, String name) throws IllegalStateException
{
_contextHandler=contextHandler;
_named=name;
_uri=null;
_path=null;
_query=null;
_pathInfo=null;
_named=name;
}
@Override
@ -102,17 +101,17 @@ public class Dispatcher implements RequestDispatcher
{
IncludeAttributes attr = new IncludeAttributes(old_attr);
attr._requestURI=_uri;
attr._requestURI=_uri.getPath();
attr._contextPath=_contextHandler.getContextPath();
attr._servletPath=null; // set by ServletHandler
attr._pathInfo=_path;
attr._query=_query;
attr._pathInfo=_pathInfo;
attr._query=_uri.getQuery();
if (_query!=null)
baseRequest.mergeQueryParameters(_query, false);
if (attr._query!=null)
baseRequest.mergeQueryParameters(baseRequest.getQueryString(),attr._query, false);
baseRequest.setAttributes(attr);
_contextHandler.handle(_path, baseRequest, (HttpServletRequest)request, (HttpServletResponse)response);
_contextHandler.handle(_pathInfo, baseRequest, (HttpServletRequest)request, (HttpServletResponse)response);
}
}
finally
@ -137,11 +136,12 @@ public class Dispatcher implements RequestDispatcher
response = new ServletResponseHttpWrapper(response);
final boolean old_handled=baseRequest.isHandled();
final String old_uri=baseRequest.getRequestURI();
final HttpURI old_uri=baseRequest.getHttpURI();
final String old_context_path=baseRequest.getContextPath();
final String old_servlet_path=baseRequest.getServletPath();
final String old_path_info=baseRequest.getPathInfo();
final String old_query=baseRequest.getQueryString();
final MultiMap<String> old_query_params=baseRequest.getQueryParameters();
final Attributes old_attr=baseRequest.getAttributes();
final DispatcherType old_type=baseRequest.getDispatcherType();
@ -174,21 +174,26 @@ public class Dispatcher implements RequestDispatcher
else
{
attr._pathInfo=old_path_info;
attr._query=old_query;
attr._requestURI=old_uri;
attr._query=old_uri.getQuery();
attr._requestURI=old_uri.getPath();
attr._contextPath=old_context_path;
attr._servletPath=old_servlet_path;
}
baseRequest.setRequestURI(_uri);
HttpURI uri = new HttpURI(old_uri.getScheme(),old_uri.getHost(),old_uri.getPort(),
_uri.getPath(),_uri.getParam(),_uri.getQuery(),_uri.getFragment());
baseRequest.setHttpURI(uri);
baseRequest.setContextPath(_contextHandler.getContextPath());
baseRequest.setServletPath(null);
baseRequest.setPathInfo(_uri);
if (_query!=null)
baseRequest.mergeQueryParameters(_query, true);
baseRequest.setPathInfo(_pathInfo);
if (_uri.getQuery()!=null || old_uri.getQuery()!=null)
baseRequest.mergeQueryParameters(old_uri.getQuery(),_uri.getQuery(), true);
baseRequest.setAttributes(attr);
_contextHandler.handle(_path, baseRequest, (HttpServletRequest)request, (HttpServletResponse)response);
_contextHandler.handle(_pathInfo, baseRequest, (HttpServletRequest)request, (HttpServletResponse)response);
if (!baseRequest.getHttpChannelState().isAsync())
commitResponse(response,baseRequest);
@ -197,11 +202,10 @@ public class Dispatcher implements RequestDispatcher
finally
{
baseRequest.setHandled(old_handled);
baseRequest.setRequestURI(old_uri);
baseRequest.setHttpURI(old_uri);
baseRequest.setContextPath(old_context_path);
baseRequest.setServletPath(old_servlet_path);
baseRequest.setPathInfo(old_path_info);
baseRequest.setQueryString(old_query);
baseRequest.setQueryParameters(old_query_params);
baseRequest.resetParameters();
baseRequest.setAttributes(old_attr);

View File

@ -20,6 +20,7 @@ package org.eclipse.jetty.server;
import java.net.InetSocketAddress;
import org.eclipse.jetty.http.HostPortHttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpScheme;
@ -46,7 +47,7 @@ import org.eclipse.jetty.server.HttpConfiguration.Customizer;
*/
public class ForwardedRequestCustomizer implements Customizer
{
private String _hostHeader;
private HostPortHttpField _hostHeader;
private String _forwardedHostHeader = HttpHeader.X_FORWARDED_HOST.toString();
private String _forwardedServerHeader = HttpHeader.X_FORWARDED_SERVER.toString();
private String _forwardedForHeader = HttpHeader.X_FORWARDED_FOR.toString();
@ -58,7 +59,7 @@ public class ForwardedRequestCustomizer implements Customizer
/* ------------------------------------------------------------ */
public String getHostHeader()
{
return _hostHeader;
return _hostHeader.getValue();
}
/* ------------------------------------------------------------ */
@ -70,7 +71,7 @@ public class ForwardedRequestCustomizer implements Customizer
*/
public void setHostHeader(String hostHeader)
{
_hostHeader = hostHeader;
_hostHeader = new HostPortHttpField(hostHeader);
}
/* ------------------------------------------------------------ */
@ -224,23 +225,20 @@ public class ForwardedRequestCustomizer implements Customizer
if (_hostHeader != null)
{
// Update host header
httpFields.put(HttpHeader.HOST.toString(),_hostHeader);
request.setServerName(null);
request.setServerPort(-1);
request.getServerName();
httpFields.put(_hostHeader);
request.setAuthority(_hostHeader.getHost(),_hostHeader.getPort());
}
else if (forwardedHost != null)
{
// Update host header
httpFields.put(HttpHeader.HOST.toString(),forwardedHost);
request.setServerName(null);
request.setServerPort(-1);
request.getServerName();
HostPortHttpField auth = new HostPortHttpField(forwardedHost);
httpFields.put(auth);
request.setAuthority(auth.getHost(),auth.getPort());
}
else if (forwardedServer != null)
{
// Use provided server name
request.setServerName(forwardedServer);
request.setAuthority(forwardedServer,request.getServerPort());
}
if (forwardedFor != null)

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