Merge branch 'master' into pathresource
Conflicts: jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceTest.java
This commit is contained in:
commit
252933891c
|
@ -1,6 +1,5 @@
|
|||
This is a source checkout of the Jetty webserver.
|
||||
|
||||
|
||||
To build, use:
|
||||
|
||||
mvn clean install
|
||||
|
|
59
VERSION.txt
59
VERSION.txt
|
@ -1,4 +1,61 @@
|
|||
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.
|
||||
|
||||
jetty-9.2.1.v20140609 - 09 June 2014
|
||||
+ 347110 Supprt ClassFileTransormers in WebAppClassLoader
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.2.2-SNAPSHOT</version>
|
||||
<version>9.2.3-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.2.2-SNAPSHOT</version>
|
||||
<version>9.2.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>apache-jsp</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.2.2-SNAPSHOT</version>
|
||||
<version>9.2.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>apache-jstl</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>example-async-rest</artifactId>
|
||||
<version>9.2.2-SNAPSHOT</version>
|
||||
<version>9.2.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.eclipse.jetty.example-async-rest</groupId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>example-async-rest</artifactId>
|
||||
<version>9.2.2-SNAPSHOT</version>
|
||||
<version>9.2.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.eclipse.jetty.example-async-rest</groupId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.examples</groupId>
|
||||
<artifactId>examples-parent</artifactId>
|
||||
<version>9.2.2-SNAPSHOT</version>
|
||||
<version>9.2.3-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.examples</groupId>
|
||||
<artifactId>examples-parent</artifactId>
|
||||
<version>9.2.2-SNAPSHOT</version>
|
||||
<version>9.2.3-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -29,6 +29,7 @@ public class SimplestServer
|
|||
{
|
||||
Server server = new Server(8080);
|
||||
server.start();
|
||||
server.dumpStdErr();
|
||||
server.join();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.2.2-SNAPSHOT</version>
|
||||
<version>9.2.3-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<groupId>org.eclipse.jetty.examples</groupId>
|
||||
|
@ -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.2.3-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>
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-alpn-parent</artifactId>
|
||||
<version>9.2.2-SNAPSHOT</version>
|
||||
<version>9.2.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-alpn-client</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-alpn-parent</artifactId>
|
||||
<version>9.2.2-SNAPSHOT</version>
|
||||
<version>9.2.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-alpn-server</artifactId>
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
[name]
|
||||
protonego-boot
|
||||
|
||||
[files]
|
||||
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/7.0.0.v20140317/alpn-boot-7.0.0.v20140317.jar|lib/alpn/alpn-boot-7.0.0.v20140317.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-7.0.0.v20140317.jar
|
|
@ -0,0 +1,8 @@
|
|||
[name]
|
||||
protonego-boot
|
||||
|
||||
[files]
|
||||
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.0.0.v20140317/alpn-boot-8.0.0.v20140317.jar|lib/alpn/alpn-boot-8.0.0.v20140317.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.0.0.v20140317.jar
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.2.2-SNAPSHOT</version>
|
||||
<version>9.2.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-alpn-parent</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.2.2-SNAPSHOT</version>
|
||||
<version>9.2.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-annotations</artifactId>
|
||||
|
@ -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>
|
||||
|
|
|
@ -36,7 +36,6 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.servlet.ServletContainerInitializer;
|
||||
import javax.servlet.annotation.HandlesTypes;
|
||||
|
||||
|
@ -442,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -557,16 +556,16 @@ public class AnnotationConfiguration extends AbstractConfiguration
|
|||
boolean timeout = !latch.await(getMaxScanWait(context), TimeUnit.SECONDS);
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
{
|
||||
for (ParserTask p:_parserTasks)
|
||||
LOG.debug("Scanned {} in {}ms", p.getResource(), TimeUnit.MILLISECONDS.convert(p.getStatistic().getElapsed(), TimeUnit.NANOSECONDS));
|
||||
|
||||
LOG.debug("Scanned {} container path jars, {} WEB-INF/lib jars, {} WEB-INF/classes dirs in {}ms for context {}",
|
||||
_containerPathStats.getTotal(), _webInfLibStats.getTotal(), _webInfClassesStats.getTotal(),
|
||||
(TimeUnit.MILLISECONDS.convert(System.nanoTime()-start, TimeUnit.NANOSECONDS)),
|
||||
context);
|
||||
}
|
||||
|
||||
LOG.debug("Scanned {} container path jars, {} WEB-INF/lib jars, {} WEB-INF/classes dirs in {}ms for context {}",
|
||||
_containerPathStats.getTotal(), _webInfLibStats.getTotal(), _webInfClassesStats.getTotal(),
|
||||
(TimeUnit.MILLISECONDS.convert(System.nanoTime()-start, TimeUnit.NANOSECONDS)),
|
||||
context);
|
||||
|
||||
|
||||
if (timeout)
|
||||
me.add(new Exception("Timeout scanning annotations"));
|
||||
me.ifExceptionThrow();
|
||||
|
|
|
@ -19,12 +19,8 @@
|
|||
package org.eclipse.jetty.annotations;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.eclipse.jetty.plus.annotation.ContainerInitializer;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.util.ConcurrentHashSet;
|
||||
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
|
|
@ -35,7 +35,6 @@ import org.eclipse.jetty.servlet.ServletMapping;
|
|||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.security.Constraint;
|
||||
import org.eclipse.jetty.webapp.Origin;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.2.2-SNAPSHOT</version>
|
||||
<version>9.2.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-ant</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.2.2-SNAPSHOT</version>
|
||||
<version>9.2.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@ import java.net.CookiePolicy;
|
|||
import java.net.CookieStore;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.URI;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
|
|
|
@ -24,7 +24,6 @@ import java.util.Collections;
|
|||
import java.util.Iterator;
|
||||
|
||||
import org.eclipse.jetty.client.api.ContentProvider;
|
||||
import org.eclipse.jetty.client.util.DeferredContentProvider;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
|
|
|
@ -214,7 +214,8 @@ public abstract class HttpDestination implements Destination, Closeable, Dumpabl
|
|||
public void close()
|
||||
{
|
||||
abort(new AsynchronousCloseException());
|
||||
LOG.debug("Closed {}", this);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Closed {}", this);
|
||||
}
|
||||
|
||||
public void release(Connection connection)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -205,7 +212,8 @@ public abstract class HttpReceiver
|
|||
}
|
||||
catch (IOException x)
|
||||
{
|
||||
LOG.debug(x);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug(x);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -227,7 +235,7 @@ public abstract class HttpReceiver
|
|||
case BEGIN:
|
||||
case HEADER:
|
||||
{
|
||||
if (updateResponseState(current, ResponseState.HEADERS))
|
||||
if (updateResponseState(current, ResponseState.TRANSIENT))
|
||||
break out;
|
||||
break;
|
||||
}
|
||||
|
@ -260,6 +268,9 @@ public abstract class HttpReceiver
|
|||
}
|
||||
}
|
||||
|
||||
if (!updateResponseState(ResponseState.TRANSIENT, ResponseState.HEADERS))
|
||||
terminateResponse(exchange, failure);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -272,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)
|
||||
{
|
||||
|
@ -282,7 +293,7 @@ public abstract class HttpReceiver
|
|||
case HEADERS:
|
||||
case CONTENT:
|
||||
{
|
||||
if (updateResponseState(current, ResponseState.CONTENT))
|
||||
if (updateResponseState(current, ResponseState.TRANSIENT))
|
||||
break out;
|
||||
break;
|
||||
}
|
||||
|
@ -297,16 +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);
|
||||
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;
|
||||
}
|
||||
|
@ -328,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);
|
||||
|
@ -345,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;
|
||||
}
|
||||
|
@ -384,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,
|
||||
|
@ -398,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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -423,7 +497,6 @@ public abstract class HttpReceiver
|
|||
protected void reset()
|
||||
{
|
||||
decoder = null;
|
||||
responseState.set(ResponseState.IDLE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -436,7 +509,6 @@ public abstract class HttpReceiver
|
|||
protected void dispose()
|
||||
{
|
||||
decoder = null;
|
||||
responseState.set(ResponseState.FAILURE);
|
||||
}
|
||||
|
||||
public boolean abort(Throwable cause)
|
||||
|
@ -448,7 +520,10 @@ public abstract class HttpReceiver
|
|||
{
|
||||
boolean updated = responseState.compareAndSet(from, to);
|
||||
if (!updated)
|
||||
LOG.debug("State update failed: {} -> {}: {}", from, to, responseState.get());
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("State update failed: {} -> {}: {}", from, to, responseState.get());
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
|
||||
|
@ -457,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
|
||||
*/
|
||||
|
|
|
@ -20,8 +20,6 @@ package org.eclipse.jetty.client.api;
|
|||
|
||||
import java.io.Closeable;
|
||||
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
|
||||
/**
|
||||
* {@link Connection} represent a connection to a {@link Destination} and allow applications to send
|
||||
* requests via {@link #send(Request, Response.CompleteListener)}.
|
||||
|
|
|
@ -18,13 +18,7 @@
|
|||
|
||||
package org.eclipse.jetty.client.api;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.eclipse.jetty.client.util.ByteBufferContentProvider;
|
||||
import org.eclipse.jetty.client.util.PathContentProvider;
|
||||
|
||||
/**
|
||||
* {@link ContentProvider} provides a source of request content.
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
|
||||
package org.eclipse.jetty.client.api;
|
||||
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.util.FuturePromise;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
|
||||
/**
|
||||
|
|
|
@ -21,7 +21,6 @@ package org.eclipse.jetty.client.api;
|
|||
import java.io.IOException;
|
||||
import java.net.HttpCookie;
|
||||
import java.net.URI;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.file.Path;
|
||||
import java.util.EventListener;
|
||||
|
@ -31,8 +30,6 @@ import java.util.concurrent.ExecutionException;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.util.InputStreamResponseListener;
|
||||
import org.eclipse.jetty.http.HttpFields;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
|
|
|
@ -22,7 +22,6 @@ import java.nio.ByteBuffer;
|
|||
import java.util.EventListener;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.client.util.BufferingResponseListener;
|
||||
import org.eclipse.jetty.http.HttpField;
|
||||
import org.eclipse.jetty.http.HttpFields;
|
||||
import org.eclipse.jetty.http.HttpVersion;
|
||||
|
|
|
@ -120,7 +120,8 @@ public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.Res
|
|||
}
|
||||
catch (Throwable x)
|
||||
{
|
||||
LOG.debug(x);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug(x);
|
||||
failAndClose(x);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -123,7 +123,8 @@ public class HttpSenderOverHTTP extends HttpSender
|
|||
}
|
||||
catch (Throwable x)
|
||||
{
|
||||
LOG.debug(x);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug(x);
|
||||
callback.failed(x);
|
||||
}
|
||||
}
|
||||
|
@ -181,7 +182,8 @@ public class HttpSenderOverHTTP extends HttpSender
|
|||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
LOG.debug(x);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug(x);
|
||||
callback.failed(x);
|
||||
}
|
||||
}
|
||||
|
@ -194,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()
|
||||
|
|
|
@ -21,9 +21,7 @@ package org.eclipse.jetty.client.util;
|
|||
import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.api.Authentication;
|
||||
import org.eclipse.jetty.client.api.AuthenticationStore;
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
|
|
|
@ -22,8 +22,6 @@ import java.nio.ByteBuffer;
|
|||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import org.eclipse.jetty.client.api.ContentProvider;
|
||||
|
||||
/**
|
||||
* A {@link ContentProvider} for {@link ByteBuffer}s.
|
||||
* <p />
|
||||
|
|
|
@ -22,8 +22,6 @@ import java.nio.ByteBuffer;
|
|||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import org.eclipse.jetty.client.api.ContentProvider;
|
||||
|
||||
/**
|
||||
* A {@link ContentProvider} for byte arrays.
|
||||
*/
|
||||
|
|
|
@ -30,9 +30,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.eclipse.jetty.client.AsyncContentProvider;
|
||||
import org.eclipse.jetty.client.api.ContentProvider;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.util.ArrayQueue;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
|
|
|
@ -33,9 +33,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.api.Authentication;
|
||||
import org.eclipse.jetty.client.api.AuthenticationStore;
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
|
|
|
@ -24,7 +24,6 @@ import java.nio.charset.Charset;
|
|||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.charset.UnsupportedCharsetException;
|
||||
|
||||
import org.eclipse.jetty.client.api.ContentProvider;
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
|
||||
/**
|
||||
|
|
|
@ -173,7 +173,8 @@ public class InputStreamContentProvider implements ContentProvider
|
|||
}
|
||||
catch (Throwable x)
|
||||
{
|
||||
LOG.debug(x);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug(x);
|
||||
if (failure == null)
|
||||
{
|
||||
failure = x;
|
||||
|
|
|
@ -32,7 +32,6 @@ import java.util.concurrent.TimeoutException;
|
|||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.api.Response.Listener;
|
||||
import org.eclipse.jetty.client.api.Result;
|
||||
|
@ -145,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
|
||||
|
|
|
@ -24,9 +24,6 @@ import java.nio.ByteBuffer;
|
|||
import java.util.Iterator;
|
||||
|
||||
import org.eclipse.jetty.client.AsyncContentProvider;
|
||||
import org.eclipse.jetty.client.api.ContentProvider;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
|
||||
/**
|
||||
* A {@link ContentProvider} that provides content asynchronously through an {@link OutputStream}
|
||||
|
|
|
@ -30,7 +30,6 @@ import java.nio.file.StandardOpenOption;
|
|||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import org.eclipse.jetty.client.api.ContentProvider;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
|
|
|
@ -21,8 +21,6 @@ package org.eclipse.jetty.client.util;
|
|||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.eclipse.jetty.client.api.ContentProvider;
|
||||
|
||||
/**
|
||||
* A {@link ContentProvider} for strings.
|
||||
* <p />
|
||||
|
|
|
@ -116,6 +116,11 @@ public class HostnameVerificationTest
|
|||
|
||||
// ExecutionException wraps an SSLHandshakeException
|
||||
Throwable cause = x.getCause();
|
||||
if (cause==null)
|
||||
{
|
||||
x.printStackTrace();
|
||||
Assert.fail("No cause?");
|
||||
}
|
||||
if (cause instanceof SSLHandshakeException)
|
||||
Assert.assertThat(cause.getCause().getCause(), Matchers.instanceOf(CertificateException.class));
|
||||
else
|
||||
|
|
|
@ -25,6 +25,7 @@ import java.util.concurrent.CountDownLatch;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
@ -46,6 +47,7 @@ import org.eclipse.jetty.server.Handler;
|
|||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.handler.AbstractHandler;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.security.Constraint;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
import org.junit.Assert;
|
||||
|
@ -187,7 +189,7 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest
|
|||
{
|
||||
baseRequest.setHandled(true);
|
||||
if (requests.incrementAndGet() == 1)
|
||||
response.sendRedirect(scheme + "://" + request.getServerName() + ":" + request.getServerPort() + request.getRequestURI());
|
||||
response.sendRedirect(URIUtil.newURI(scheme,request.getServerName(),request.getServerPort(),request.getRequestURI(),null));
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -226,7 +228,7 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest
|
|||
{
|
||||
baseRequest.setHandled(true);
|
||||
if (request.getRequestURI().endsWith("/redirect"))
|
||||
response.sendRedirect(scheme + "://" + request.getServerName() + ":" + request.getServerPort() + "/secure");
|
||||
response.sendRedirect(URIUtil.newURI(scheme,request.getServerName(),request.getServerPort(),"/secure",null));
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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,58 +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)
|
||||
{
|
||||
super.onContent(response, content);
|
||||
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();
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.2.2-SNAPSHOT</version>
|
||||
<version>9.2.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-continuation</artifactId>
|
||||
|
|
|
@ -18,12 +18,7 @@
|
|||
|
||||
package org.eclipse.jetty.continuation;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.Servlet;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.ServletResponseWrapper;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
|
|
|
@ -20,8 +20,6 @@ package org.eclipse.jetty.continuation;
|
|||
|
||||
import java.util.EventListener;
|
||||
|
||||
import javax.servlet.ServletRequestListener;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** A Continuation Listener
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.2.2-SNAPSHOT</version>
|
||||
<version>9.2.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-deploy</artifactId>
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
|
||||
package org.eclipse.jetty.deploy;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.util.component.LifeCycle;
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@ import java.util.Locale;
|
|||
import org.eclipse.jetty.deploy.App;
|
||||
import org.eclipse.jetty.deploy.ConfigurationManager;
|
||||
import org.eclipse.jetty.deploy.util.FileID;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||
|
|
|
@ -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>());
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@ import static org.hamcrest.Matchers.not;
|
|||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.deploy.providers.ScanningAppProvider;
|
||||
import org.eclipse.jetty.deploy.test.XmlConfiguredJetty;
|
||||
import org.eclipse.jetty.toolchain.test.IO;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.2.2-SNAPSHOT</version>
|
||||
<version>9.2.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>jetty-distribution</artifactId>
|
||||
<name>Jetty :: Distribution Assemblies</name>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.fcgi</groupId>
|
||||
<artifactId>fcgi-parent</artifactId>
|
||||
<version>9.2.2-SNAPSHOT</version>
|
||||
<version>9.2.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -150,7 +150,8 @@ public class HttpConnectionOverFCGI extends AbstractConnection implements Connec
|
|||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
LOG.debug(x);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug(x);
|
||||
close(x);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
|
||||
public class ParamsContentParser extends ContentParser
|
||||
{
|
||||
private static final Logger logger = Log.getLogger(ParamsContentParser.class);
|
||||
private static final Logger LOG = Log.getLogger(ParamsContentParser.class);
|
||||
|
||||
private final ServerParser.Listener listener;
|
||||
private State state = State.LENGTH;
|
||||
|
@ -212,7 +212,8 @@ public class ParamsContentParser extends ContentParser
|
|||
}
|
||||
catch (Throwable x)
|
||||
{
|
||||
logger.debug("Exception while invoking listener " + listener, x);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Exception while invoking listener " + listener, x);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -224,7 +225,8 @@ public class ParamsContentParser extends ContentParser
|
|||
}
|
||||
catch (Throwable x)
|
||||
{
|
||||
logger.debug("Exception while invoking listener " + listener, x);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Exception while invoking listener " + listener, x);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -187,7 +187,8 @@ public class ResponseContentParser extends StreamContentParser
|
|||
}
|
||||
catch (Throwable x)
|
||||
{
|
||||
logger.debug("Exception while invoking listener " + listener, x);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Exception while invoking listener " + listener, x);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -200,7 +201,8 @@ public class ResponseContentParser extends StreamContentParser
|
|||
}
|
||||
catch (Throwable x)
|
||||
{
|
||||
logger.debug("Exception while invoking listener " + listener, x);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Exception while invoking listener " + listener, x);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -212,7 +214,8 @@ public class ResponseContentParser extends StreamContentParser
|
|||
}
|
||||
catch (Throwable x)
|
||||
{
|
||||
logger.debug("Exception while invoking listener " + listener, x);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Exception while invoking listener " + listener, x);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -233,7 +236,8 @@ public class ResponseContentParser extends StreamContentParser
|
|||
}
|
||||
catch (Throwable x)
|
||||
{
|
||||
logger.debug("Exception while invoking listener " + listener, x);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Exception while invoking listener " + listener, x);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -265,7 +269,8 @@ public class ResponseContentParser extends StreamContentParser
|
|||
}
|
||||
catch (Throwable x)
|
||||
{
|
||||
logger.debug("Exception while invoking listener " + listener, x);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Exception while invoking listener " + listener, x);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
|
||||
public class StreamContentParser extends ContentParser
|
||||
{
|
||||
protected static final Logger logger = Log.getLogger(StreamContentParser.class);
|
||||
private static final Logger LOG = Log.getLogger(StreamContentParser.class);
|
||||
|
||||
private final FCGI.StreamType streamType;
|
||||
private final Parser.Listener listener;
|
||||
|
@ -87,7 +87,8 @@ public class StreamContentParser extends ContentParser
|
|||
}
|
||||
catch (Throwable x)
|
||||
{
|
||||
logger.debug("Exception while invoking listener " + listener, x);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Exception while invoking listener " + listener, x);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,7 +100,8 @@ public class StreamContentParser extends ContentParser
|
|||
}
|
||||
catch (Throwable x)
|
||||
{
|
||||
logger.debug("Exception while invoking listener " + listener, x);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Exception while invoking listener " + listener, x);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.fcgi</groupId>
|
||||
<artifactId>fcgi-parent</artifactId>
|
||||
<version>9.2.2-SNAPSHOT</version>
|
||||
<version>9.2.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -94,7 +94,8 @@ public class ServerFCGIConnection extends AbstractConnection
|
|||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
LOG.debug(x);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug(x);
|
||||
// TODO: fail and close ?
|
||||
}
|
||||
finally
|
||||
|
|
|
@ -697,7 +697,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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.2.2-SNAPSHOT</version>
|
||||
<version>9.2.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.2.2-SNAPSHOT</version>
|
||||
<version>9.2.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-http-spi</artifactId>
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<version>9.2.2-SNAPSHOT</version>
|
||||
<version>9.2.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-http</artifactId>
|
||||
|
|
|
@ -35,7 +35,7 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
/* ------------------------------------------------------------ */
|
||||
/** A Parser for HTTP 0.9, 1.0 and 1.1
|
||||
* <p>
|
||||
* The is parser parses HTTP client and server messages from buffers
|
||||
* This parser parses HTTP client and server messages from buffers
|
||||
* passed in the {@link #parseNext(ByteBuffer)} method. The parsed
|
||||
* elements of the HTTP message are passed as event calls to the
|
||||
* {@link HttpHandler} instance the parser is constructed with.
|
||||
|
@ -860,7 +860,7 @@ public class HttpParser
|
|||
{
|
||||
throw new BadMessage(HttpStatus.BAD_REQUEST_400,"Bad IPv6 Host header");
|
||||
}
|
||||
host = host.substring(1,len-1);
|
||||
host = host.substring(0,len);
|
||||
}
|
||||
else if (len!=host.length())
|
||||
host = host.substring(0,len);
|
||||
|
|
|
@ -539,8 +539,6 @@ public class HttpURI
|
|||
{
|
||||
if (_host==_port)
|
||||
return null;
|
||||
if (_raw[_host]=='[')
|
||||
return new String(_raw,_host+1,_port-_host-2,_charset);
|
||||
return new String(_raw,_host,_port-_host,_charset);
|
||||
}
|
||||
|
||||
|
|
|
@ -27,10 +27,6 @@ import static org.junit.Assert.assertTrue;
|
|||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Assert;
|
||||
|
|
|
@ -1294,7 +1294,7 @@ public class HttpParserTest
|
|||
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
|
||||
HttpParser parser= new HttpParser(handler);
|
||||
parser.parseNext(buffer);
|
||||
assertEquals("::1",_host);
|
||||
assertEquals("[::1]",_host);
|
||||
assertEquals(0,_port);
|
||||
}
|
||||
|
||||
|
@ -1372,7 +1372,7 @@ public class HttpParserTest
|
|||
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
|
||||
HttpParser parser= new HttpParser(handler);
|
||||
parser.parseNext(buffer);
|
||||
assertEquals("::1",_host);
|
||||
assertEquals("[::1]",_host);
|
||||
assertEquals(8888,_port);
|
||||
}
|
||||
|
||||
|
|
|
@ -33,9 +33,9 @@ public class HttpURITest
|
|||
{
|
||||
{"/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://[::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://[::1]:8080/path/to/context;param?query=%22value%22#fragment","http","[::1]","8080","/path/to/context","param","query=%22value%22","fragment"},
|
||||
};
|
||||
|
||||
public static int
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<version>9.2.2-SNAPSHOT</version>
|
||||
<version>9.2.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-io</artifactId>
|
||||
|
|
|
@ -20,8 +20,6 @@ package org.eclipse.jetty.io;
|
|||
|
||||
import java.io.Closeable;
|
||||
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
|
||||
/**
|
||||
* <p>A {@link Connection} is associated to an {@link EndPoint} so that I/O events
|
||||
* happening on the {@link EndPoint} can be processed by the {@link Connection}.</p>
|
||||
|
|
|
@ -26,8 +26,6 @@ import java.nio.channels.ReadPendingException;
|
|||
import java.nio.channels.WritePendingException;
|
||||
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.FutureCallback;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
@ -25,7 +25,6 @@ import java.nio.channels.SelectionKey;
|
|||
import java.nio.channels.SocketChannel;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.thread.Scheduler;
|
||||
|
|
|
@ -21,8 +21,6 @@ package org.eclipse.jetty.io;
|
|||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.net.ConnectException;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.nio.channels.CancelledKeyException;
|
||||
import java.nio.channels.SelectionKey;
|
||||
|
@ -488,7 +486,8 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
|
|||
LOG.debug("Starting {} on {}", _thread, this);
|
||||
while (isRunning())
|
||||
select();
|
||||
runChanges();
|
||||
while(isStopping())
|
||||
runChanges();
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
|
|
@ -38,7 +38,6 @@ import org.eclipse.jetty.io.EndPoint;
|
|||
import org.eclipse.jetty.io.EofException;
|
||||
import org.eclipse.jetty.io.FillInterest;
|
||||
import org.eclipse.jetty.io.RuntimeIOException;
|
||||
import org.eclipse.jetty.io.SelectChannelEndPoint;
|
||||
import org.eclipse.jetty.io.WriteFlusher;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
|
@ -820,7 +819,6 @@ public class SslConnection extends AbstractConnection
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
getEndPoint().close();
|
||||
throw e;
|
||||
}
|
||||
finally
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.2.2-SNAPSHOT</version>
|
||||
<version>9.2.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-jaas</artifactId>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.2.2-SNAPSHOT</version>
|
||||
<version>9.2.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-jaspi</artifactId>
|
||||
|
|
|
@ -92,6 +92,9 @@ public class FormAuthModule extends BaseAuthModule
|
|||
setErrorPage(errorPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public FormAuthModule(CallbackHandler callbackHandler, CrossContextPsuedoSession<UserInfo> ssoSource,
|
||||
String loginPage, String errorPage)
|
||||
{
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.2.2-SNAPSHOT</version>
|
||||
<version>9.2.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-jmx</artifactId>
|
||||
|
|
|
@ -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()
|
||||
*/
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.2.2-SNAPSHOT</version>
|
||||
<version>9.2.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-jndi</artifactId>
|
||||
|
|
|
@ -24,7 +24,6 @@ import java.sql.Statement;
|
|||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
||||
import org.eclipse.jetty.util.component.Destroyable;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.2.2-SNAPSHOT</version>
|
||||
<version>9.2.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-jsp</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.2.2-SNAPSHOT</version>
|
||||
<version>9.2.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-jspc-maven-plugin</artifactId>
|
||||
|
|
|
@ -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.
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue