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:
commit
c13be6d932
62
VERSION.txt
62
VERSION.txt
|
@ -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
|
||||
|
|
|
@ -47,5 +47,6 @@
|
|||
-->
|
||||
<module>async-rest</module>
|
||||
<module>embedded</module>
|
||||
<module>quickstart</module>
|
||||
</modules>
|
||||
</project>
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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>());
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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!
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
*/
|
||||
|
|
|
@ -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 <scope>provided</scope>
|
||||
* 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.
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -82,7 +82,7 @@ public class ServiceConnection
|
|||
*/
|
||||
public String getServiceUrl()
|
||||
{
|
||||
return _serviceUrl;
|
||||
return _serviceUrl;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
|
|
@ -207,7 +207,7 @@ public class NoSqlSession extends MemSession
|
|||
/* ------------------------------------------------------------ */
|
||||
public Object getVersion()
|
||||
{
|
||||
return _version;
|
||||
return _version;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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("\" ");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue