Merge branch 'master' into release-9
This commit is contained in:
commit
07830b6f76
|
@ -1,6 +1,5 @@
|
||||||
This is a source checkout of the Jetty webserver.
|
This is a source checkout of the Jetty webserver.
|
||||||
|
|
||||||
|
|
||||||
To build, use:
|
To build, use:
|
||||||
|
|
||||||
mvn clean install
|
mvn clean install
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
jetty-9.2.2-SNAPSHOT
|
||||||
|
|
||||||
jetty-9.2.1.v20140609 - 09 June 2014
|
jetty-9.2.1.v20140609 - 09 June 2014
|
||||||
+ 347110 Supprt ClassFileTransormers in WebAppClassLoader
|
+ 347110 Supprt ClassFileTransormers in WebAppClassLoader
|
||||||
+ 432192 jetty-start / Allow JETTY_LOGS use for start-log-file
|
+ 432192 jetty-start / Allow JETTY_LOGS use for start-log-file
|
||||||
|
|
|
@ -29,6 +29,7 @@ public class SimplestServer
|
||||||
{
|
{
|
||||||
Server server = new Server(8080);
|
Server server = new Server(8080);
|
||||||
server.start();
|
server.start();
|
||||||
|
server.dumpStdErr();
|
||||||
server.join();
|
server.join();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,14 +3,17 @@
|
||||||
|
|
||||||
<Configure id="protonego" class="org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory">
|
<Configure id="protonego" class="org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory">
|
||||||
<Arg name="protocols">
|
<Arg name="protocols">
|
||||||
<Array type="String">
|
<Array type="String">
|
||||||
<Item>spdy/3</Item>
|
<Item>spdy/3</Item>
|
||||||
<Item>spdy/2</Item>
|
<Item>spdy/2</Item>
|
||||||
<Item>http/1.1</Item>
|
<Item>http/1.1</Item>
|
||||||
</Array>
|
</Array>
|
||||||
</Arg>
|
</Arg>
|
||||||
|
|
||||||
<Set name="defaultProtocol">http/1.1</Set>
|
<Set name="defaultProtocol">http/1.1</Set>
|
||||||
|
|
||||||
|
<!-- Enables NPN debugging on System.err -->
|
||||||
|
<!--<Set class="org.eclipse.jetty.alpn.ALPN" name="debug" type="boolean">true</Set>-->
|
||||||
|
|
||||||
</Configure>
|
</Configure>
|
||||||
|
|
||||||
|
|
|
@ -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/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
|
|
@ -62,7 +62,8 @@ public class ALPNServerConnection extends NegotiatingServerConnection implements
|
||||||
{
|
{
|
||||||
negotiated = getDefaultProtocol();
|
negotiated = getDefaultProtocol();
|
||||||
}
|
}
|
||||||
LOG.debug("{} protocol selected {}", this, negotiated);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("{} protocol selected {}", this, negotiated);
|
||||||
setProtocol(negotiated);
|
setProtocol(negotiated);
|
||||||
ALPN.remove(getSSLEngine());
|
ALPN.remove(getSSLEngine());
|
||||||
return negotiated;
|
return negotiated;
|
||||||
|
|
|
@ -36,7 +36,6 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.Semaphore;
|
import java.util.concurrent.Semaphore;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.servlet.ServletContainerInitializer;
|
import javax.servlet.ServletContainerInitializer;
|
||||||
import javax.servlet.annotation.HandlesTypes;
|
import javax.servlet.annotation.HandlesTypes;
|
||||||
|
|
||||||
|
@ -442,14 +441,14 @@ public class AnnotationConfiguration extends AbstractConfiguration
|
||||||
|
|
||||||
// Resolve container initializers
|
// Resolve container initializers
|
||||||
List<ContainerInitializer> initializers =
|
List<ContainerInitializer> initializers =
|
||||||
(List<ContainerInitializer>)context.getAttribute(AnnotationConfiguration.CONTAINER_INITIALIZERS);
|
(List<ContainerInitializer>)context.getAttribute(AnnotationConfiguration.CONTAINER_INITIALIZERS);
|
||||||
if (initializers != null && initializers.size()>0)
|
if (initializers != null && initializers.size()>0)
|
||||||
{
|
{
|
||||||
Map<String, Set<String>> map = ( Map<String, Set<String>>) context.getAttribute(AnnotationConfiguration.CLASS_INHERITANCE_MAP);
|
Map<String, Set<String>> map = ( Map<String, Set<String>>) context.getAttribute(AnnotationConfiguration.CLASS_INHERITANCE_MAP);
|
||||||
if (map == null)
|
if (map == null)
|
||||||
LOG.warn ("ServletContainerInitializers: detected. Class hierarchy: empty");
|
LOG.warn ("ServletContainerInitializers: detected. Class hierarchy: empty");
|
||||||
for (ContainerInitializer i : initializers)
|
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);
|
boolean timeout = !latch.await(getMaxScanWait(context), TimeUnit.SECONDS);
|
||||||
|
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
{
|
{
|
||||||
for (ParserTask p:_parserTasks)
|
for (ParserTask p:_parserTasks)
|
||||||
LOG.debug("Scanned {} in {}ms", p.getResource(), TimeUnit.MILLISECONDS.convert(p.getStatistic().getElapsed(), TimeUnit.NANOSECONDS));
|
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)
|
if (timeout)
|
||||||
me.add(new Exception("Timeout scanning annotations"));
|
me.add(new Exception("Timeout scanning annotations"));
|
||||||
me.ifExceptionThrow();
|
me.ifExceptionThrow();
|
||||||
|
|
|
@ -19,12 +19,8 @@
|
||||||
package org.eclipse.jetty.annotations;
|
package org.eclipse.jetty.annotations;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.plus.annotation.ContainerInitializer;
|
import org.eclipse.jetty.plus.annotation.ContainerInitializer;
|
||||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||||
import org.eclipse.jetty.util.ConcurrentHashSet;
|
|
||||||
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
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.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.util.security.Constraint;
|
import org.eclipse.jetty.util.security.Constraint;
|
||||||
import org.eclipse.jetty.webapp.Origin;
|
|
||||||
import org.eclipse.jetty.webapp.WebAppContext;
|
import org.eclipse.jetty.webapp.WebAppContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -86,7 +86,8 @@ public abstract class AuthenticationProtocolHandler implements ProtocolHandler
|
||||||
if (result.isFailed())
|
if (result.isFailed())
|
||||||
{
|
{
|
||||||
Throwable failure = result.getFailure();
|
Throwable failure = result.getFailure();
|
||||||
LOG.debug("Authentication challenge failed {}", failure);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Authentication challenge failed {}", failure);
|
||||||
forwardFailureComplete(request, result.getRequestFailure(), response, result.getResponseFailure());
|
forwardFailureComplete(request, result.getRequestFailure(), response, result.getResponseFailure());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -95,7 +96,8 @@ public abstract class AuthenticationProtocolHandler implements ProtocolHandler
|
||||||
if (conversation.getAttribute(AUTHENTICATION_ATTRIBUTE) != null)
|
if (conversation.getAttribute(AUTHENTICATION_ATTRIBUTE) != null)
|
||||||
{
|
{
|
||||||
// We have already tried to authenticate, but we failed again
|
// We have already tried to authenticate, but we failed again
|
||||||
LOG.debug("Bad credentials for {}", request);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Bad credentials for {}", request);
|
||||||
forwardSuccessComplete(request, response);
|
forwardSuccessComplete(request, response);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -104,7 +106,8 @@ public abstract class AuthenticationProtocolHandler implements ProtocolHandler
|
||||||
List<Authentication.HeaderInfo> headerInfos = parseAuthenticateHeader(response, header);
|
List<Authentication.HeaderInfo> headerInfos = parseAuthenticateHeader(response, header);
|
||||||
if (headerInfos.isEmpty())
|
if (headerInfos.isEmpty())
|
||||||
{
|
{
|
||||||
LOG.debug("Authentication challenge without {} header", header);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Authentication challenge without {} header", header);
|
||||||
forwardFailureComplete(request, null, response, new HttpResponseException("HTTP protocol violation: Authentication challenge without " + header + " header", response));
|
forwardFailureComplete(request, null, response, new HttpResponseException("HTTP protocol violation: Authentication challenge without " + header + " header", response));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -126,13 +129,15 @@ public abstract class AuthenticationProtocolHandler implements ProtocolHandler
|
||||||
}
|
}
|
||||||
if (authentication == null)
|
if (authentication == null)
|
||||||
{
|
{
|
||||||
LOG.debug("No authentication available for {}", request);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("No authentication available for {}", request);
|
||||||
forwardSuccessComplete(request, response);
|
forwardSuccessComplete(request, response);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final Authentication.Result authnResult = authentication.authenticate(request, response, headerInfo, conversation);
|
final Authentication.Result authnResult = authentication.authenticate(request, response, headerInfo, conversation);
|
||||||
LOG.debug("Authentication result {}", authnResult);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Authentication result {}", authnResult);
|
||||||
if (authnResult == null)
|
if (authnResult == null)
|
||||||
{
|
{
|
||||||
forwardSuccessComplete(request, response);
|
forwardSuccessComplete(request, response);
|
||||||
|
|
|
@ -81,21 +81,24 @@ public class ConnectionPool implements Closeable, Dumpable
|
||||||
|
|
||||||
if (next > maxConnections)
|
if (next > maxConnections)
|
||||||
{
|
{
|
||||||
LOG.debug("Max connections {}/{} reached", current, maxConnections);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Max connections {}/{} reached", current, maxConnections);
|
||||||
// Try again the idle connections
|
// Try again the idle connections
|
||||||
return acquireIdleConnection();
|
return acquireIdleConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connectionCount.compareAndSet(current, next))
|
if (connectionCount.compareAndSet(current, next))
|
||||||
{
|
{
|
||||||
LOG.debug("Connection {}/{} creation", next, maxConnections);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Connection {}/{} creation", next, maxConnections);
|
||||||
|
|
||||||
destination.newConnection(new Promise<Connection>()
|
destination.newConnection(new Promise<Connection>()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void succeeded(Connection connection)
|
public void succeeded(Connection connection)
|
||||||
{
|
{
|
||||||
LOG.debug("Connection {}/{} creation succeeded {}", next, maxConnections, connection);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Connection {}/{} creation succeeded {}", next, maxConnections, connection);
|
||||||
if (activate(connection))
|
if (activate(connection))
|
||||||
connectionPromise.succeeded(connection);
|
connectionPromise.succeeded(connection);
|
||||||
}
|
}
|
||||||
|
@ -103,7 +106,8 @@ public class ConnectionPool implements Closeable, Dumpable
|
||||||
@Override
|
@Override
|
||||||
public void failed(Throwable x)
|
public void failed(Throwable x)
|
||||||
{
|
{
|
||||||
LOG.debug("Connection " + next + "/" + maxConnections + " creation failed", x);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Connection " + next + "/" + maxConnections + " creation failed", x);
|
||||||
connectionCount.decrementAndGet();
|
connectionCount.decrementAndGet();
|
||||||
connectionPromise.failed(x);
|
connectionPromise.failed(x);
|
||||||
}
|
}
|
||||||
|
@ -127,13 +131,15 @@ public class ConnectionPool implements Closeable, Dumpable
|
||||||
{
|
{
|
||||||
if (activeConnections.offer(connection))
|
if (activeConnections.offer(connection))
|
||||||
{
|
{
|
||||||
LOG.debug("Connection active {}", connection);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Connection active {}", connection);
|
||||||
acquired(connection);
|
acquired(connection);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG.debug("Connection active overflow {}", connection);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Connection active overflow {}", connection);
|
||||||
connection.close();
|
connection.close();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -151,12 +157,14 @@ public class ConnectionPool implements Closeable, Dumpable
|
||||||
// Make sure we use "hot" connections first
|
// Make sure we use "hot" connections first
|
||||||
if (idleConnections.offerFirst(connection))
|
if (idleConnections.offerFirst(connection))
|
||||||
{
|
{
|
||||||
LOG.debug("Connection idle {}", connection);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Connection idle {}", connection);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG.debug("Connection idle overflow {}", connection);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Connection idle overflow {}", connection);
|
||||||
connection.close();
|
connection.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -177,7 +185,8 @@ public class ConnectionPool implements Closeable, Dumpable
|
||||||
if (removed)
|
if (removed)
|
||||||
{
|
{
|
||||||
int pooled = connectionCount.decrementAndGet();
|
int pooled = connectionCount.decrementAndGet();
|
||||||
LOG.debug("Connection removed {} - pooled: {}", connection, pooled);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Connection removed {} - pooled: {}", connection, pooled);
|
||||||
}
|
}
|
||||||
return removed;
|
return removed;
|
||||||
}
|
}
|
||||||
|
@ -227,6 +236,11 @@ public class ConnectionPool implements Closeable, Dumpable
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return String.format("%s %d/%d", getClass().getSimpleName(), connectionCount.get(), maxConnections);
|
return String.format("%s[c=%d/%d,a=%d,i=%d]",
|
||||||
|
getClass().getSimpleName(),
|
||||||
|
connectionCount.get(),
|
||||||
|
maxConnections,
|
||||||
|
activeConnections.size(),
|
||||||
|
idleConnections.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -251,7 +251,7 @@ public class GZIPContentDecoder implements ContentDecoder
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Accumulate inflated bytes and loop to see if we have finished
|
// 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);
|
System.arraycopy(bytes, 0, newOutput, output.length, decoded);
|
||||||
output = newOutput;
|
output = newOutput;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,8 @@ public abstract class HttpChannel
|
||||||
if (this.exchange.compareAndSet(null, exchange))
|
if (this.exchange.compareAndSet(null, exchange))
|
||||||
{
|
{
|
||||||
exchange.associate(this);
|
exchange.associate(this);
|
||||||
LOG.debug("{} associated to {}", exchange, this);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("{} associated to {}", exchange, this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -59,7 +60,8 @@ public abstract class HttpChannel
|
||||||
HttpExchange exchange = this.exchange.getAndSet(null);
|
HttpExchange exchange = this.exchange.getAndSet(null);
|
||||||
if (exchange != null)
|
if (exchange != null)
|
||||||
exchange.disassociate(this);
|
exchange.disassociate(this);
|
||||||
LOG.debug("{} disassociated from {}", exchange, this);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("{} disassociated from {}", exchange, this);
|
||||||
return exchange;
|
return exchange;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,6 @@ import java.net.CookiePolicy;
|
||||||
import java.net.CookieStore;
|
import java.net.CookieStore;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.nio.channels.SocketChannel;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -480,9 +479,14 @@ public class HttpClient extends ContainerLifeCycle
|
||||||
{
|
{
|
||||||
HttpDestination existing = destinations.putIfAbsent(origin, destination);
|
HttpDestination existing = destinations.putIfAbsent(origin, destination);
|
||||||
if (existing != null)
|
if (existing != null)
|
||||||
|
{
|
||||||
destination = existing;
|
destination = existing;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
LOG.debug("Created {}", destination);
|
{
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Created {}", destination);
|
||||||
|
}
|
||||||
if (!isRunning())
|
if (!isRunning())
|
||||||
destinations.remove(origin);
|
destinations.remove(origin);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@ import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
import org.eclipse.jetty.client.api.ContentProvider;
|
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.BufferUtil;
|
||||||
import org.eclipse.jetty.util.Callback;
|
import org.eclipse.jetty.util.Callback;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
|
@ -130,7 +129,8 @@ public class HttpContent implements Callback, Closeable
|
||||||
if (content != AFTER)
|
if (content != AFTER)
|
||||||
{
|
{
|
||||||
content = buffer = AFTER;
|
content = buffer = AFTER;
|
||||||
LOG.debug("Advanced content past last chunk");
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Advanced content past last chunk");
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -175,14 +175,16 @@ public abstract class HttpDestination implements Destination, Closeable, Dumpabl
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG.debug("Queued {}", request);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Queued {} for {}", request, this);
|
||||||
requestNotifier.notifyQueued(request);
|
requestNotifier.notifyQueued(request);
|
||||||
send();
|
send();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG.debug("Max queue size {} exceeded by {}", client.getMaxRequestsQueuedPerDestination(), request);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Max queue size {} exceeded by {} for {}", client.getMaxRequestsQueuedPerDestination(), request, this);
|
||||||
request.abort(new RejectedExecutionException("Max requests per destination " + client.getMaxRequestsQueuedPerDestination() + " exceeded for " + this));
|
request.abort(new RejectedExecutionException("Max requests per destination " + client.getMaxRequestsQueuedPerDestination() + " exceeded for " + this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -212,7 +214,8 @@ public abstract class HttpDestination implements Destination, Closeable, Dumpabl
|
||||||
public void close()
|
public void close()
|
||||||
{
|
{
|
||||||
abort(new AsynchronousCloseException());
|
abort(new AsynchronousCloseException());
|
||||||
LOG.debug("Closed {}", this);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Closed {}", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void release(Connection connection)
|
public void release(Connection connection)
|
||||||
|
@ -256,9 +259,10 @@ public abstract class HttpDestination implements Destination, Closeable, Dumpabl
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return String.format("%s(%s)%s",
|
return String.format("%s[%s]%s,queue=%d",
|
||||||
HttpDestination.class.getSimpleName(),
|
HttpDestination.class.getSimpleName(),
|
||||||
asString(),
|
asString(),
|
||||||
proxy == null ? "" : " via " + proxy);
|
proxy == null ? "" : "(via " + proxy + ")",
|
||||||
|
exchanges.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,7 +151,8 @@ public class HttpExchange
|
||||||
if ((current & terminated) == terminated)
|
if ((current & terminated) == terminated)
|
||||||
{
|
{
|
||||||
// Request and response terminated
|
// Request and response terminated
|
||||||
LOG.debug("{} terminated", this);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("{} terminated", this);
|
||||||
return new Result(getRequest(), getRequestFailure(), getResponse(), getResponseFailure());
|
return new Result(getRequest(), getRequestFailure(), getResponse(), getResponseFailure());
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -174,7 +175,8 @@ public class HttpExchange
|
||||||
requestFailure = failure;
|
requestFailure = failure;
|
||||||
if ((code & 0b0100) == 0b0100)
|
if ((code & 0b0100) == 0b0100)
|
||||||
responseFailure = failure;
|
responseFailure = failure;
|
||||||
LOG.debug("{} updated", this);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("{} updated", this);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -185,7 +187,8 @@ public class HttpExchange
|
||||||
{
|
{
|
||||||
if (destination.remove(this))
|
if (destination.remove(this))
|
||||||
{
|
{
|
||||||
LOG.debug("Aborting while queued {}: {}", this, cause);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Aborting while queued {}: {}", this, cause);
|
||||||
return fail(cause);
|
return fail(cause);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -195,7 +198,8 @@ public class HttpExchange
|
||||||
return fail(cause);
|
return fail(cause);
|
||||||
|
|
||||||
boolean aborted = channel.abort(cause);
|
boolean aborted = channel.abort(cause);
|
||||||
LOG.debug("Aborted while active ({}) {}: {}", aborted, this, cause);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Aborted while active ({}) {}: {}", aborted, this, cause);
|
||||||
return aborted;
|
return aborted;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -204,7 +208,8 @@ public class HttpExchange
|
||||||
{
|
{
|
||||||
if (update(0b0101, cause) == 0b0101)
|
if (update(0b0101, cause) == 0b0101)
|
||||||
{
|
{
|
||||||
LOG.debug("Failing {}: {}", this, cause);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Failing {}: {}", this, cause);
|
||||||
destination.getRequestNotifier().notifyFailure(request, cause);
|
destination.getRequestNotifier().notifyFailure(request, cause);
|
||||||
List<Response.ResponseListener> listeners = getConversation().getResponseListeners();
|
List<Response.ResponseListener> listeners = getConversation().getResponseListeners();
|
||||||
ResponseNotifier responseNotifier = destination.getResponseNotifier();
|
ResponseNotifier responseNotifier = destination.getResponseNotifier();
|
||||||
|
|
|
@ -186,7 +186,8 @@ public class HttpProxy extends ProxyConfiguration.Proxy
|
||||||
// Avoid setting fill interest in the old Connection,
|
// Avoid setting fill interest in the old Connection,
|
||||||
// without closing the underlying EndPoint.
|
// without closing the underlying EndPoint.
|
||||||
oldConnection.softClose();
|
oldConnection.softClose();
|
||||||
LOG.debug("HTTP tunnel established: {} over {}", oldConnection, newConnection);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("HTTP tunnel established: {} over {}", oldConnection, newConnection);
|
||||||
}
|
}
|
||||||
catch (Throwable x)
|
catch (Throwable x)
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,6 +21,7 @@ package org.eclipse.jetty.client;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -49,9 +50,8 @@ import org.eclipse.jetty.util.log.Logger;
|
||||||
* is available</li>
|
* is available</li>
|
||||||
* <li>{@link #responseHeader(HttpExchange, HttpField)}, when a HTTP field 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 #responseHeaders(HttpExchange)}, when all HTTP headers are available</li>
|
||||||
* <li>{@link #responseContent(HttpExchange, ByteBuffer, Callback)}, when HTTP content is available; this is the only
|
* <li>{@link #responseContent(HttpExchange, ByteBuffer, Callback)}, when HTTP content is available</li>
|
||||||
* method that may be invoked multiple times with different buffers containing different content</li>
|
* <li>{@link #responseSuccess(HttpExchange)}, when the response is successful</li>
|
||||||
* <li>{@link #responseSuccess(HttpExchange)}, when the response is complete</li>
|
|
||||||
* </ol>
|
* </ol>
|
||||||
* At any time, subclasses may invoke {@link #responseFailure(Throwable)} to indicate that the response has failed
|
* At any time, subclasses may invoke {@link #responseFailure(Throwable)} to indicate that the response has failed
|
||||||
* (for example, because of I/O exceptions).
|
* (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 AtomicReference<ResponseState> responseState = new AtomicReference<>(ResponseState.IDLE);
|
||||||
private final HttpChannel channel;
|
private final HttpChannel channel;
|
||||||
private volatile ContentDecoder decoder;
|
private ContentDecoder decoder;
|
||||||
|
private Throwable failure;
|
||||||
|
|
||||||
protected HttpReceiver(HttpChannel channel)
|
protected HttpReceiver(HttpChannel channel)
|
||||||
{
|
{
|
||||||
|
@ -104,7 +105,7 @@ public abstract class HttpReceiver
|
||||||
*/
|
*/
|
||||||
protected boolean responseBegin(HttpExchange exchange)
|
protected boolean responseBegin(HttpExchange exchange)
|
||||||
{
|
{
|
||||||
if (!updateResponseState(ResponseState.IDLE, ResponseState.BEGIN))
|
if (!updateResponseState(ResponseState.IDLE, ResponseState.TRANSIENT))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
HttpConversation conversation = exchange.getConversation();
|
HttpConversation conversation = exchange.getConversation();
|
||||||
|
@ -117,14 +118,19 @@ public abstract class HttpReceiver
|
||||||
if (protocolHandler != null)
|
if (protocolHandler != null)
|
||||||
{
|
{
|
||||||
handlerListener = protocolHandler.getResponseListener();
|
handlerListener = protocolHandler.getResponseListener();
|
||||||
LOG.debug("Found protocol handler {}", protocolHandler);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Found protocol handler {}", protocolHandler);
|
||||||
}
|
}
|
||||||
exchange.getConversation().updateResponseListeners(handlerListener);
|
exchange.getConversation().updateResponseListeners(handlerListener);
|
||||||
|
|
||||||
LOG.debug("Response begin {}", response);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Response begin {}", response);
|
||||||
ResponseNotifier notifier = destination.getResponseNotifier();
|
ResponseNotifier notifier = destination.getResponseNotifier();
|
||||||
notifier.notifyBegin(conversation.getResponseListeners(), response);
|
notifier.notifyBegin(conversation.getResponseListeners(), response);
|
||||||
|
|
||||||
|
if (!updateResponseState(ResponseState.TRANSIENT, ResponseState.BEGIN))
|
||||||
|
terminateResponse(exchange, failure);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,7 +156,7 @@ public abstract class HttpReceiver
|
||||||
case BEGIN:
|
case BEGIN:
|
||||||
case HEADER:
|
case HEADER:
|
||||||
{
|
{
|
||||||
if (updateResponseState(current, ResponseState.HEADER))
|
if (updateResponseState(current, ResponseState.TRANSIENT))
|
||||||
break out;
|
break out;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -186,6 +192,9 @@ public abstract class HttpReceiver
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!updateResponseState(ResponseState.TRANSIENT, ResponseState.HEADER))
|
||||||
|
terminateResponse(exchange, failure);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,7 +212,8 @@ public abstract class HttpReceiver
|
||||||
}
|
}
|
||||||
catch (IOException x)
|
catch (IOException x)
|
||||||
{
|
{
|
||||||
LOG.debug(x);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug(x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,7 +235,7 @@ public abstract class HttpReceiver
|
||||||
case BEGIN:
|
case BEGIN:
|
||||||
case HEADER:
|
case HEADER:
|
||||||
{
|
{
|
||||||
if (updateResponseState(current, ResponseState.HEADERS))
|
if (updateResponseState(current, ResponseState.TRANSIENT))
|
||||||
break out;
|
break out;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -258,6 +268,9 @@ public abstract class HttpReceiver
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!updateResponseState(ResponseState.TRANSIENT, ResponseState.HEADERS))
|
||||||
|
terminateResponse(exchange, failure);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,7 +283,7 @@ public abstract class HttpReceiver
|
||||||
* @param buffer the response HTTP content buffer
|
* @param buffer the response HTTP content buffer
|
||||||
* @return whether the processing should continue
|
* @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)
|
out: while (true)
|
||||||
{
|
{
|
||||||
|
@ -280,7 +293,7 @@ public abstract class HttpReceiver
|
||||||
case HEADERS:
|
case HEADERS:
|
||||||
case CONTENT:
|
case CONTENT:
|
||||||
{
|
{
|
||||||
if (updateResponseState(current, ResponseState.CONTENT))
|
if (updateResponseState(current, ResponseState.TRANSIENT))
|
||||||
break out;
|
break out;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -295,16 +308,49 @@ public abstract class HttpReceiver
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("Response content {}{}{}", response, System.lineSeparator(), BufferUtil.toDetailString(buffer));
|
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;
|
ContentDecoder decoder = this.decoder;
|
||||||
if (decoder != null)
|
if (decoder == null)
|
||||||
{
|
{
|
||||||
buffer = decoder.decode(buffer);
|
notifier.notifyContent(listeners, response, buffer, callback);
|
||||||
if (LOG.isDebugEnabled())
|
}
|
||||||
LOG.debug("Response content decoded ({}) {}{}{}", decoder, response, System.lineSeparator(), BufferUtil.toDetailString(buffer));
|
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();
|
if (!updateResponseState(ResponseState.TRANSIENT, ResponseState.CONTENT))
|
||||||
notifier.notifyContent(exchange.getConversation().getResponseListeners(), response, buffer, callback);
|
terminateResponse(exchange, failure);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -326,32 +372,25 @@ public abstract class HttpReceiver
|
||||||
if (!completed)
|
if (!completed)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Reset to be ready for another response
|
responseState.set(ResponseState.IDLE);
|
||||||
|
|
||||||
|
// Reset to be ready for another response.
|
||||||
reset();
|
reset();
|
||||||
|
|
||||||
// Mark atomically the response as terminated and succeeded,
|
// Mark atomically the response as terminated and succeeded,
|
||||||
// with respect to concurrency between request and response.
|
// 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);
|
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();
|
HttpResponse response = exchange.getResponse();
|
||||||
LOG.debug("Response success {}", response);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Response success {}", response);
|
||||||
List<Response.ResponseListener> listeners = exchange.getConversation().getResponseListeners();
|
List<Response.ResponseListener> listeners = exchange.getConversation().getResponseListeners();
|
||||||
ResponseNotifier notifier = getHttpDestination().getResponseNotifier();
|
ResponseNotifier notifier = getHttpDestination().getResponseNotifier();
|
||||||
notifier.notifySuccess(listeners, response);
|
notifier.notifySuccess(listeners, response);
|
||||||
|
|
||||||
if (result != null)
|
terminateResponse(exchange, result);
|
||||||
{
|
|
||||||
boolean ordered = getHttpDestination().getHttpClient().isStrictEventOrdering();
|
|
||||||
if (!ordered)
|
|
||||||
channel.exchangeTerminated(result);
|
|
||||||
LOG.debug("Request/Response succeeded {}", response);
|
|
||||||
notifier.notifyComplete(listeners, result);
|
|
||||||
if (ordered)
|
|
||||||
channel.exchangeTerminated(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -380,7 +419,20 @@ public abstract class HttpReceiver
|
||||||
if (!completed)
|
if (!completed)
|
||||||
return false;
|
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();
|
dispose();
|
||||||
|
|
||||||
// Mark atomically the response as terminated and failed,
|
// Mark atomically the response as terminated and failed,
|
||||||
|
@ -388,23 +440,51 @@ public abstract class HttpReceiver
|
||||||
Result result = exchange.terminateResponse(failure);
|
Result result = exchange.terminateResponse(failure);
|
||||||
|
|
||||||
HttpResponse response = exchange.getResponse();
|
HttpResponse response = exchange.getResponse();
|
||||||
LOG.debug("Response failure {} {}", response, failure);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Response failure {} {}", response, failure);
|
||||||
List<Response.ResponseListener> listeners = exchange.getConversation().getResponseListeners();
|
List<Response.ResponseListener> listeners = exchange.getConversation().getResponseListeners();
|
||||||
ResponseNotifier notifier = getHttpDestination().getResponseNotifier();
|
ResponseNotifier notifier = getHttpDestination().getResponseNotifier();
|
||||||
notifier.notifyFailure(listeners, response, failure);
|
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)
|
if (result != null)
|
||||||
{
|
{
|
||||||
boolean ordered = getHttpDestination().getHttpClient().isStrictEventOrdering();
|
boolean ordered = getHttpDestination().getHttpClient().isStrictEventOrdering();
|
||||||
if (!ordered)
|
if (!ordered)
|
||||||
channel.exchangeTerminated(result);
|
channel.exchangeTerminated(result);
|
||||||
LOG.debug("Request/Response failed {}", response);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Request/Response {} {}", failure == null ? "succeeded" : "failed", response);
|
||||||
|
List<Response.ResponseListener> listeners = exchange.getConversation().getResponseListeners();
|
||||||
|
ResponseNotifier notifier = getHttpDestination().getResponseNotifier();
|
||||||
notifier.notifyComplete(listeners, result);
|
notifier.notifyComplete(listeners, result);
|
||||||
if (ordered)
|
if (ordered)
|
||||||
channel.exchangeTerminated(result);
|
channel.exchangeTerminated(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -417,7 +497,6 @@ public abstract class HttpReceiver
|
||||||
protected void reset()
|
protected void reset()
|
||||||
{
|
{
|
||||||
decoder = null;
|
decoder = null;
|
||||||
responseState.set(ResponseState.IDLE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -430,7 +509,6 @@ public abstract class HttpReceiver
|
||||||
protected void dispose()
|
protected void dispose()
|
||||||
{
|
{
|
||||||
decoder = null;
|
decoder = null;
|
||||||
responseState.set(ResponseState.FAILURE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean abort(Throwable cause)
|
public boolean abort(Throwable cause)
|
||||||
|
@ -442,7 +520,10 @@ public abstract class HttpReceiver
|
||||||
{
|
{
|
||||||
boolean updated = responseState.compareAndSet(from, to);
|
boolean updated = responseState.compareAndSet(from, to);
|
||||||
if (!updated)
|
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;
|
return updated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,6 +532,10 @@ public abstract class HttpReceiver
|
||||||
*/
|
*/
|
||||||
private enum ResponseState
|
private enum ResponseState
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* One of the response*() methods is being executed.
|
||||||
|
*/
|
||||||
|
TRANSIENT,
|
||||||
/**
|
/**
|
||||||
* The response is not yet received, the initial state
|
* The response is not yet received, the initial state
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -156,7 +156,8 @@ public class HttpRedirector
|
||||||
URI newURI = extractRedirectURI(response);
|
URI newURI = extractRedirectURI(response);
|
||||||
if (newURI != null)
|
if (newURI != null)
|
||||||
{
|
{
|
||||||
LOG.debug("Redirecting to {} (Location: {})", newURI, location);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Redirecting to {} (Location: {})", newURI, location);
|
||||||
return redirect(request, response, listener, newURI);
|
return redirect(request, response, listener, newURI);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -65,7 +65,8 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
|
||||||
private final IteratingCallback contentCallback = new ContentCallback();
|
private final IteratingCallback contentCallback = new ContentCallback();
|
||||||
private final Callback lastCallback = new LastContentCallback();
|
private final Callback lastCallback = new LastContentCallback();
|
||||||
private final HttpChannel channel;
|
private final HttpChannel channel;
|
||||||
private volatile HttpContent content;
|
private HttpContent content;
|
||||||
|
private Throwable failure;
|
||||||
|
|
||||||
protected HttpSender(HttpChannel channel)
|
protected HttpSender(HttpChannel channel)
|
||||||
{
|
{
|
||||||
|
@ -99,7 +100,8 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
|
||||||
SenderState newSenderState = SenderState.SENDING;
|
SenderState newSenderState = SenderState.SENDING;
|
||||||
if (updateSenderState(current, newSenderState))
|
if (updateSenderState(current, newSenderState))
|
||||||
{
|
{
|
||||||
LOG.debug("Deferred content available, {} -> {}", current, newSenderState);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Deferred content available, {} -> {}", current, newSenderState);
|
||||||
contentCallback.iterate();
|
contentCallback.iterate();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -110,7 +112,8 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
|
||||||
SenderState newSenderState = SenderState.SENDING_WITH_CONTENT;
|
SenderState newSenderState = SenderState.SENDING_WITH_CONTENT;
|
||||||
if (updateSenderState(current, newSenderState))
|
if (updateSenderState(current, newSenderState))
|
||||||
{
|
{
|
||||||
LOG.debug("Deferred content available, {} -> {}", current, newSenderState);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Deferred content available, {} -> {}", current, newSenderState);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -120,7 +123,8 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
|
||||||
SenderState newSenderState = SenderState.EXPECTING_WITH_CONTENT;
|
SenderState newSenderState = SenderState.EXPECTING_WITH_CONTENT;
|
||||||
if (updateSenderState(current, newSenderState))
|
if (updateSenderState(current, newSenderState))
|
||||||
{
|
{
|
||||||
LOG.debug("Deferred content available, {} -> {}", current, newSenderState);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Deferred content available, {} -> {}", current, newSenderState);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -130,7 +134,8 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
|
||||||
SenderState newSenderState = SenderState.PROCEEDING_WITH_CONTENT;
|
SenderState newSenderState = SenderState.PROCEEDING_WITH_CONTENT;
|
||||||
if (updateSenderState(current, newSenderState))
|
if (updateSenderState(current, newSenderState))
|
||||||
{
|
{
|
||||||
LOG.debug("Deferred content available, {} -> {}", current, newSenderState);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Deferred content available, {} -> {}", current, newSenderState);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -140,7 +145,8 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
|
||||||
case PROCEEDING_WITH_CONTENT:
|
case PROCEEDING_WITH_CONTENT:
|
||||||
case WAITING:
|
case WAITING:
|
||||||
{
|
{
|
||||||
LOG.debug("Deferred content available, {}", current);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Deferred content available, {}", current);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -192,32 +198,40 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
|
||||||
|
|
||||||
protected boolean queuedToBegin(Request request)
|
protected boolean queuedToBegin(Request request)
|
||||||
{
|
{
|
||||||
if (!updateRequestState(RequestState.QUEUED, RequestState.BEGIN))
|
if (!updateRequestState(RequestState.QUEUED, RequestState.TRANSIENT))
|
||||||
return false;
|
return false;
|
||||||
LOG.debug("Request begin {}", request);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Request begin {}", request);
|
||||||
RequestNotifier notifier = getHttpChannel().getHttpDestination().getRequestNotifier();
|
RequestNotifier notifier = getHttpChannel().getHttpDestination().getRequestNotifier();
|
||||||
notifier.notifyBegin(request);
|
notifier.notifyBegin(request);
|
||||||
|
if (!updateRequestState(RequestState.TRANSIENT, RequestState.BEGIN))
|
||||||
|
terminateRequest(getHttpExchange(), failure, false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean beginToHeaders(Request request)
|
protected boolean beginToHeaders(Request request)
|
||||||
{
|
{
|
||||||
if (!updateRequestState(RequestState.BEGIN, RequestState.HEADERS))
|
if (!updateRequestState(RequestState.BEGIN, RequestState.TRANSIENT))
|
||||||
return false;
|
return false;
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("Request headers {}{}{}", request, System.getProperty("line.separator"), request.getHeaders().toString().trim());
|
LOG.debug("Request headers {}{}{}", request, System.getProperty("line.separator"), request.getHeaders().toString().trim());
|
||||||
RequestNotifier notifier = getHttpChannel().getHttpDestination().getRequestNotifier();
|
RequestNotifier notifier = getHttpChannel().getHttpDestination().getRequestNotifier();
|
||||||
notifier.notifyHeaders(request);
|
notifier.notifyHeaders(request);
|
||||||
|
if (!updateRequestState(RequestState.TRANSIENT, RequestState.HEADERS))
|
||||||
|
terminateRequest(getHttpExchange(), failure, false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean headersToCommit(Request request)
|
protected boolean headersToCommit(Request request)
|
||||||
{
|
{
|
||||||
if (!updateRequestState(RequestState.HEADERS, RequestState.COMMIT))
|
if (!updateRequestState(RequestState.HEADERS, RequestState.TRANSIENT))
|
||||||
return false;
|
return false;
|
||||||
LOG.debug("Request committed {}", request);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Request committed {}", request);
|
||||||
RequestNotifier notifier = getHttpChannel().getHttpDestination().getRequestNotifier();
|
RequestNotifier notifier = getHttpChannel().getHttpDestination().getRequestNotifier();
|
||||||
notifier.notifyCommit(request);
|
notifier.notifyCommit(request);
|
||||||
|
if (!updateRequestState(RequestState.TRANSIENT, RequestState.COMMIT))
|
||||||
|
terminateRequest(getHttpExchange(), failure, true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,21 +243,19 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
|
||||||
case COMMIT:
|
case COMMIT:
|
||||||
case CONTENT:
|
case CONTENT:
|
||||||
{
|
{
|
||||||
if (!updateRequestState(current, RequestState.CONTENT))
|
if (!updateRequestState(current, RequestState.TRANSIENT_CONTENT))
|
||||||
return false;
|
return false;
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("Request content {}{}{}", request, System.getProperty("line.separator"), BufferUtil.toDetailString(content));
|
LOG.debug("Request content {}{}{}", request, System.getProperty("line.separator"), BufferUtil.toDetailString(content));
|
||||||
RequestNotifier notifier = getHttpChannel().getHttpDestination().getRequestNotifier();
|
RequestNotifier notifier = getHttpChannel().getHttpDestination().getRequestNotifier();
|
||||||
notifier.notifyContent(request, content);
|
notifier.notifyContent(request, content);
|
||||||
|
if (!updateRequestState(RequestState.TRANSIENT_CONTENT, RequestState.CONTENT))
|
||||||
|
terminateRequest(getHttpExchange(), failure, true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case FAILURE:
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
throw new IllegalStateException(current.toString());
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -262,41 +274,28 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
|
||||||
if (!completed)
|
if (!completed)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Reset to be ready for another request
|
requestState.set(RequestState.QUEUED);
|
||||||
|
|
||||||
|
// Reset to be ready for another request.
|
||||||
reset();
|
reset();
|
||||||
|
|
||||||
// Mark atomically the request as terminated and succeeded,
|
// Mark atomically the request as terminated and succeeded,
|
||||||
// with respect to concurrency between request and response.
|
// with respect to concurrency between request and response.
|
||||||
Result result = exchange.terminateRequest(null);
|
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();
|
Request request = exchange.getRequest();
|
||||||
LOG.debug("Request success {}", request);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Request success {}", request);
|
||||||
HttpDestination destination = getHttpChannel().getHttpDestination();
|
HttpDestination destination = getHttpChannel().getHttpDestination();
|
||||||
destination.getRequestNotifier().notifySuccess(exchange.getRequest());
|
destination.getRequestNotifier().notifySuccess(exchange.getRequest());
|
||||||
|
|
||||||
if (result != null)
|
terminateRequest(exchange, null, true, result);
|
||||||
{
|
|
||||||
boolean ordered = destination.getHttpClient().isStrictEventOrdering();
|
|
||||||
if (!ordered)
|
|
||||||
channel.exchangeTerminated(result);
|
|
||||||
LOG.debug("Request/Response succeded {}", request);
|
|
||||||
HttpConversation conversation = exchange.getConversation();
|
|
||||||
destination.getResponseNotifier().notifyComplete(conversation.getResponseListeners(), result);
|
|
||||||
if (ordered)
|
|
||||||
channel.exchangeTerminated(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case FAILURE:
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
throw new IllegalStateException(current.toString());
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -313,42 +312,86 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
|
||||||
if (!completed)
|
if (!completed)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Dispose to avoid further requests
|
this.failure = failure;
|
||||||
RequestState requestState = dispose();
|
|
||||||
|
// 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,
|
// Mark atomically the request as terminated and failed,
|
||||||
// with respect to concurrency between request and response.
|
// with respect to concurrency between request and response.
|
||||||
Result result = exchange.terminateRequest(failure);
|
Result result = exchange.terminateRequest(failure);
|
||||||
|
|
||||||
Request request = exchange.getRequest();
|
Request request = exchange.getRequest();
|
||||||
LOG.debug("Request failure {} {}", exchange, failure);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Request failure {} {}", exchange, failure);
|
||||||
HttpDestination destination = getHttpChannel().getHttpDestination();
|
HttpDestination destination = getHttpChannel().getHttpDestination();
|
||||||
destination.getRequestNotifier().notifyFailure(request, failure);
|
destination.getRequestNotifier().notifyFailure(request, failure);
|
||||||
|
|
||||||
boolean notCommitted = isBeforeCommit(requestState);
|
if (fail)
|
||||||
if (result == null && notCommitted && request.getAbortCause() == null)
|
{
|
||||||
|
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
|
// Complete the response from here
|
||||||
if (exchange.responseComplete())
|
if (exchange.responseComplete())
|
||||||
{
|
{
|
||||||
result = exchange.terminateResponse(failure);
|
result = exchange.terminateResponse(failure);
|
||||||
LOG.debug("Failed response from request {}", exchange);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Failed response from request {}", exchange);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result != null)
|
if (result != null)
|
||||||
{
|
{
|
||||||
|
HttpDestination destination = getHttpChannel().getHttpDestination();
|
||||||
boolean ordered = destination.getHttpClient().isStrictEventOrdering();
|
boolean ordered = destination.getHttpClient().isStrictEventOrdering();
|
||||||
if (!ordered)
|
if (!ordered)
|
||||||
channel.exchangeTerminated(result);
|
channel.exchangeTerminated(result);
|
||||||
LOG.debug("Request/Response failed {}", request);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Request/Response {} {}", failure == null ? "succeeded" : "failed", request);
|
||||||
HttpConversation conversation = exchange.getConversation();
|
HttpConversation conversation = exchange.getConversation();
|
||||||
destination.getResponseNotifier().notifyComplete(conversation.getResponseListeners(), result);
|
destination.getResponseNotifier().notifyComplete(conversation.getResponseListeners(), result);
|
||||||
if (ordered)
|
if (ordered)
|
||||||
channel.exchangeTerminated(result);
|
channel.exchangeTerminated(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -386,23 +429,14 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
|
||||||
{
|
{
|
||||||
content.close();
|
content.close();
|
||||||
content = null;
|
content = null;
|
||||||
requestState.set(RequestState.QUEUED);
|
|
||||||
senderState.set(SenderState.IDLE);
|
senderState.set(SenderState.IDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected RequestState dispose()
|
protected void dispose()
|
||||||
{
|
{
|
||||||
while (true)
|
HttpContent content = this.content;
|
||||||
{
|
if (content != null)
|
||||||
RequestState current = requestState.get();
|
content.close();
|
||||||
if (updateRequestState(current, RequestState.FAILURE))
|
|
||||||
{
|
|
||||||
HttpContent content = this.content;
|
|
||||||
if (content != null)
|
|
||||||
content.close();
|
|
||||||
return current;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void proceed(HttpExchange exchange, Throwable failure)
|
public void proceed(HttpExchange exchange, Throwable failure)
|
||||||
|
@ -426,7 +460,8 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
|
||||||
// We are still sending the headers, but we already got the 100 Continue.
|
// We are still sending the headers, but we already got the 100 Continue.
|
||||||
if (updateSenderState(current, SenderState.PROCEEDING))
|
if (updateSenderState(current, SenderState.PROCEEDING))
|
||||||
{
|
{
|
||||||
LOG.debug("Proceeding while expecting");
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Proceeding while expecting");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -441,7 +476,8 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
|
||||||
// WritePendingException).
|
// WritePendingException).
|
||||||
if (updateSenderState(current, SenderState.PROCEEDING_WITH_CONTENT))
|
if (updateSenderState(current, SenderState.PROCEEDING_WITH_CONTENT))
|
||||||
{
|
{
|
||||||
LOG.debug("Proceeding while scheduled");
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Proceeding while scheduled");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -451,7 +487,8 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
|
||||||
// We received the 100 Continue, now send the content if any.
|
// We received the 100 Continue, now send the content if any.
|
||||||
if (!updateSenderState(current, SenderState.SENDING))
|
if (!updateSenderState(current, SenderState.SENDING))
|
||||||
throw illegalSenderState(current);
|
throw illegalSenderState(current);
|
||||||
LOG.debug("Proceeding while waiting");
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Proceeding while waiting");
|
||||||
contentCallback.iterate();
|
contentCallback.iterate();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -470,7 +507,7 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
|
||||||
return abortable && anyToFailure(failure);
|
return abortable && anyToFailure(failure);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean updateRequestState(RequestState from, RequestState to)
|
private boolean updateRequestState(RequestState from, RequestState to)
|
||||||
{
|
{
|
||||||
boolean updated = requestState.compareAndSet(from, to);
|
boolean updated = requestState.compareAndSet(from, to);
|
||||||
if (!updated)
|
if (!updated)
|
||||||
|
@ -490,6 +527,7 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
|
||||||
{
|
{
|
||||||
switch (requestState)
|
switch (requestState)
|
||||||
{
|
{
|
||||||
|
case TRANSIENT:
|
||||||
case QUEUED:
|
case QUEUED:
|
||||||
case BEGIN:
|
case BEGIN:
|
||||||
case HEADERS:
|
case HEADERS:
|
||||||
|
@ -503,6 +541,7 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
|
||||||
{
|
{
|
||||||
switch (requestState)
|
switch (requestState)
|
||||||
{
|
{
|
||||||
|
case TRANSIENT_CONTENT:
|
||||||
case COMMIT:
|
case COMMIT:
|
||||||
case CONTENT:
|
case CONTENT:
|
||||||
return true;
|
return true;
|
||||||
|
@ -519,8 +558,16 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
|
||||||
/**
|
/**
|
||||||
* The request states {@link HttpSender} goes through when sending a request.
|
* 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
|
* The request is queued, the initial state
|
||||||
*/
|
*/
|
||||||
|
@ -758,15 +805,14 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void failed(Throwable failure)
|
public void onCompleteFailure(Throwable failure)
|
||||||
{
|
{
|
||||||
content.failed(failure);
|
content.failed(failure);
|
||||||
super.failed(failure);
|
|
||||||
anyToFailure(failure);
|
anyToFailure(failure);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void completed()
|
protected void onCompleteSuccess()
|
||||||
{
|
{
|
||||||
// Nothing to do, since we always return false from process().
|
// Nothing to do, since we always return false from process().
|
||||||
// Termination is obtained via LastContentCallback.
|
// Termination is obtained via LastContentCallback.
|
||||||
|
|
|
@ -94,7 +94,8 @@ public abstract class MultiplexHttpDestination<C extends Connection> extends Htt
|
||||||
{
|
{
|
||||||
HttpClient client = getHttpClient();
|
HttpClient client = getHttpClient();
|
||||||
final HttpExchange exchange = getHttpExchanges().poll();
|
final HttpExchange exchange = getHttpExchanges().poll();
|
||||||
LOG.debug("Processing {} on {}", exchange, connection);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Processing {} on {}", exchange, connection);
|
||||||
if (exchange == null)
|
if (exchange == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -102,7 +103,8 @@ public abstract class MultiplexHttpDestination<C extends Connection> extends Htt
|
||||||
Throwable cause = request.getAbortCause();
|
Throwable cause = request.getAbortCause();
|
||||||
if (cause != null)
|
if (cause != null)
|
||||||
{
|
{
|
||||||
LOG.debug("Aborted before processing {}: {}", exchange, cause);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Aborted before processing {}: {}", exchange, cause);
|
||||||
// It may happen that the request is aborted before the exchange
|
// It may happen that the request is aborted before the exchange
|
||||||
// is created. Aborting the exchange a second time will result in
|
// is created. Aborting the exchange a second time will result in
|
||||||
// a no-operation, so we just abort here to cover that edge case.
|
// a no-operation, so we just abort here to cover that edge case.
|
||||||
|
|
|
@ -93,7 +93,8 @@ public abstract class PoolingHttpDestination<C extends Connection> extends HttpD
|
||||||
{
|
{
|
||||||
HttpClient client = getHttpClient();
|
HttpClient client = getHttpClient();
|
||||||
final HttpExchange exchange = getHttpExchanges().poll();
|
final HttpExchange exchange = getHttpExchanges().poll();
|
||||||
LOG.debug("Processing exchange {} on connection {}", exchange, connection);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Processing exchange {} on {} of {}", exchange, connection, this);
|
||||||
if (exchange == null)
|
if (exchange == null)
|
||||||
{
|
{
|
||||||
if (!connectionPool.release(connection))
|
if (!connectionPool.release(connection))
|
||||||
|
@ -101,7 +102,8 @@ public abstract class PoolingHttpDestination<C extends Connection> extends HttpD
|
||||||
|
|
||||||
if (!client.isRunning())
|
if (!client.isRunning())
|
||||||
{
|
{
|
||||||
LOG.debug("{} is stopping", client);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("{} is stopping", client);
|
||||||
connection.close();
|
connection.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,7 +113,8 @@ public abstract class PoolingHttpDestination<C extends Connection> extends HttpD
|
||||||
Throwable cause = request.getAbortCause();
|
Throwable cause = request.getAbortCause();
|
||||||
if (cause != null)
|
if (cause != null)
|
||||||
{
|
{
|
||||||
LOG.debug("Aborted before processing {}: {}", exchange, cause);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Aborted before processing {}: {}", exchange, cause);
|
||||||
// It may happen that the request is aborted before the exchange
|
// It may happen that the request is aborted before the exchange
|
||||||
// is created. Aborting the exchange a second time will result in
|
// is created. Aborting the exchange a second time will result in
|
||||||
// a no-operation, so we just abort here to cover that edge case.
|
// a no-operation, so we just abort here to cover that edge case.
|
||||||
|
@ -145,18 +148,25 @@ public abstract class PoolingHttpDestination<C extends Connection> extends HttpD
|
||||||
{
|
{
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
C connection = (C)c;
|
C connection = (C)c;
|
||||||
LOG.debug("{} released", connection);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("{} released", connection);
|
||||||
HttpClient client = getHttpClient();
|
HttpClient client = getHttpClient();
|
||||||
if (client.isRunning())
|
if (client.isRunning())
|
||||||
{
|
{
|
||||||
if (connectionPool.isActive(connection))
|
if (connectionPool.isActive(connection))
|
||||||
|
{
|
||||||
process(connection, false);
|
process(connection, false);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
LOG.debug("{} explicit", connection);
|
{
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("{} explicit", connection);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG.debug("{} is stopped", client);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("{} is stopped", client);
|
||||||
close(connection);
|
close(connection);
|
||||||
connection.close();
|
connection.close();
|
||||||
}
|
}
|
||||||
|
@ -203,4 +213,10 @@ public abstract class PoolingHttpDestination<C extends Connection> extends HttpD
|
||||||
{
|
{
|
||||||
ContainerLifeCycle.dump(out, indent, Arrays.asList(connectionPool));
|
ContainerLifeCycle.dump(out, indent, Arrays.asList(connectionPool));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return String.format("%s,pool=%s", super.toString(), connectionPool);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,7 +133,8 @@ public class Socks4Proxy extends ProxyConfiguration.Proxy
|
||||||
@Override
|
@Override
|
||||||
public void succeeded()
|
public void succeeded()
|
||||||
{
|
{
|
||||||
LOG.debug("Written SOCKS4 connect request");
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Written SOCKS4 connect request");
|
||||||
fillInterested();
|
fillInterested();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,7 +154,8 @@ public class Socks4Proxy extends ProxyConfiguration.Proxy
|
||||||
{
|
{
|
||||||
ByteBuffer buffer = BufferUtil.allocate(8);
|
ByteBuffer buffer = BufferUtil.allocate(8);
|
||||||
int filled = getEndPoint().fill(buffer);
|
int filled = getEndPoint().fill(buffer);
|
||||||
LOG.debug("Read SOCKS4 connect response, {} bytes", filled);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Read SOCKS4 connect response, {} bytes", filled);
|
||||||
if (filled != 8)
|
if (filled != 8)
|
||||||
throw new IOException("Invalid response from SOCKS4 proxy");
|
throw new IOException("Invalid response from SOCKS4 proxy");
|
||||||
int result = buffer.get(1);
|
int result = buffer.get(1);
|
||||||
|
@ -179,7 +181,8 @@ public class Socks4Proxy extends ProxyConfiguration.Proxy
|
||||||
connectionFactory = new SslClientConnectionFactory(client.getSslContextFactory(), client.getByteBufferPool(), client.getExecutor(), connectionFactory);
|
connectionFactory = new SslClientConnectionFactory(client.getSslContextFactory(), client.getByteBufferPool(), client.getExecutor(), connectionFactory);
|
||||||
org.eclipse.jetty.io.Connection connection = connectionFactory.newConnection(getEndPoint(), context);
|
org.eclipse.jetty.io.Connection connection = connectionFactory.newConnection(getEndPoint(), context);
|
||||||
ClientConnectionFactory.Helper.replaceConnection(this, connection);
|
ClientConnectionFactory.Helper.replaceConnection(this, connection);
|
||||||
LOG.debug("SOCKS4 tunnel established: {} over {}", this, connection);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("SOCKS4 tunnel established: {} over {}", this, connection);
|
||||||
}
|
}
|
||||||
catch (Throwable x)
|
catch (Throwable x)
|
||||||
{
|
{
|
||||||
|
|
|
@ -48,7 +48,8 @@ public class TimeoutCompleteListener implements Response.CompleteListener, Runna
|
||||||
if (task != null)
|
if (task != null)
|
||||||
{
|
{
|
||||||
boolean cancelled = task.cancel();
|
boolean cancelled = task.cancel();
|
||||||
LOG.debug("Cancelled (successfully: {}) timeout task {}", cancelled, task);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Cancelled (successfully: {}) timeout task {}", cancelled, task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,14 +59,16 @@ public class TimeoutCompleteListener implements Response.CompleteListener, Runna
|
||||||
Scheduler.Task task = scheduler.schedule(this, timeout, TimeUnit.MILLISECONDS);
|
Scheduler.Task task = scheduler.schedule(this, timeout, TimeUnit.MILLISECONDS);
|
||||||
if (this.task.getAndSet(task) != null)
|
if (this.task.getAndSet(task) != null)
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
LOG.debug("Scheduled timeout task {} in {} ms for {}", task, timeout, request);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Scheduled timeout task {} in {} ms for {}", task, timeout, request);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
{
|
{
|
||||||
LOG.debug("Executing timeout task {} for {}", task, request);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Executing timeout task {} for {}", task, request);
|
||||||
request.abort(new TimeoutException("Total timeout elapsed"));
|
request.abort(new TimeoutException("Total timeout elapsed"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,8 +20,6 @@ package org.eclipse.jetty.client.api;
|
||||||
|
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.Promise;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link Connection} represent a connection to a {@link Destination} and allow applications to send
|
* {@link Connection} represent a connection to a {@link Destination} and allow applications to send
|
||||||
* requests via {@link #send(Request, Response.CompleteListener)}.
|
* requests via {@link #send(Request, Response.CompleteListener)}.
|
||||||
|
|
|
@ -18,13 +18,7 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.client.api;
|
package org.eclipse.jetty.client.api;
|
||||||
|
|
||||||
import java.io.Closeable;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.nio.ByteBuffer;
|
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.
|
* {@link ContentProvider} provides a source of request content.
|
||||||
|
|
|
@ -18,8 +18,6 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.client.api;
|
package org.eclipse.jetty.client.api;
|
||||||
|
|
||||||
import org.eclipse.jetty.client.HttpClient;
|
|
||||||
import org.eclipse.jetty.util.FuturePromise;
|
|
||||||
import org.eclipse.jetty.util.Promise;
|
import org.eclipse.jetty.util.Promise;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -21,7 +21,6 @@ package org.eclipse.jetty.client.api;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.HttpCookie;
|
import java.net.HttpCookie;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URLEncoder;
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.EventListener;
|
import java.util.EventListener;
|
||||||
|
@ -31,8 +30,6 @@ import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
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.HttpFields;
|
||||||
import org.eclipse.jetty.http.HttpHeader;
|
import org.eclipse.jetty.http.HttpHeader;
|
||||||
import org.eclipse.jetty.http.HttpMethod;
|
import org.eclipse.jetty.http.HttpMethod;
|
||||||
|
|
|
@ -22,7 +22,6 @@ import java.nio.ByteBuffer;
|
||||||
import java.util.EventListener;
|
import java.util.EventListener;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.jetty.client.util.BufferingResponseListener;
|
|
||||||
import org.eclipse.jetty.http.HttpField;
|
import org.eclipse.jetty.http.HttpField;
|
||||||
import org.eclipse.jetty.http.HttpFields;
|
import org.eclipse.jetty.http.HttpFields;
|
||||||
import org.eclipse.jetty.http.HttpVersion;
|
import org.eclipse.jetty.http.HttpVersion;
|
||||||
|
|
|
@ -85,7 +85,8 @@ public class HttpConnectionOverHTTP extends AbstractConnection implements Connec
|
||||||
@Override
|
@Override
|
||||||
protected boolean onReadTimeout()
|
protected boolean onReadTimeout()
|
||||||
{
|
{
|
||||||
LOG.debug("{} idle timeout", this);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("{} idle timeout", this);
|
||||||
close(new TimeoutException());
|
close(new TimeoutException());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -127,9 +128,11 @@ public class HttpConnectionOverHTTP extends AbstractConnection implements Connec
|
||||||
// from an onFailure() handler or by blocking code waiting for completion.
|
// from an onFailure() handler or by blocking code waiting for completion.
|
||||||
getHttpDestination().close(this);
|
getHttpDestination().close(this);
|
||||||
getEndPoint().shutdownOutput();
|
getEndPoint().shutdownOutput();
|
||||||
LOG.debug("{} oshut", this);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("{} oshut", this);
|
||||||
getEndPoint().close();
|
getEndPoint().close();
|
||||||
LOG.debug("{} closed", this);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("{} closed", this);
|
||||||
|
|
||||||
abort(failure);
|
abort(failure);
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,7 +120,8 @@ public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.Res
|
||||||
}
|
}
|
||||||
catch (Throwable x)
|
catch (Throwable x)
|
||||||
{
|
{
|
||||||
LOG.debug(x);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug(x);
|
||||||
failAndClose(x);
|
failAndClose(x);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -230,7 +231,8 @@ public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.Res
|
||||||
@Override
|
@Override
|
||||||
public void resume()
|
public void resume()
|
||||||
{
|
{
|
||||||
LOG.debug("Content consumed asynchronously, resuming processing");
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Content consumed asynchronously, resuming processing");
|
||||||
process();
|
process();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -123,7 +123,8 @@ public class HttpSenderOverHTTP extends HttpSender
|
||||||
}
|
}
|
||||||
catch (Throwable x)
|
catch (Throwable x)
|
||||||
{
|
{
|
||||||
LOG.debug(x);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug(x);
|
||||||
callback.failed(x);
|
callback.failed(x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -181,7 +182,8 @@ public class HttpSenderOverHTTP extends HttpSender
|
||||||
}
|
}
|
||||||
catch (Exception x)
|
catch (Exception x)
|
||||||
{
|
{
|
||||||
LOG.debug(x);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug(x);
|
||||||
callback.failed(x);
|
callback.failed(x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -194,12 +196,11 @@ public class HttpSenderOverHTTP extends HttpSender
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected RequestState dispose()
|
protected void dispose()
|
||||||
{
|
{
|
||||||
generator.abort();
|
generator.abort();
|
||||||
RequestState result = super.dispose();
|
super.dispose();
|
||||||
shutdownOutput();
|
shutdownOutput();
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void shutdownOutput()
|
private void shutdownOutput()
|
||||||
|
|
|
@ -21,9 +21,7 @@ package org.eclipse.jetty.client.util;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
import org.eclipse.jetty.client.HttpClient;
|
|
||||||
import org.eclipse.jetty.client.api.Authentication;
|
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.ContentResponse;
|
||||||
import org.eclipse.jetty.client.api.Request;
|
import org.eclipse.jetty.client.api.Request;
|
||||||
import org.eclipse.jetty.http.HttpHeader;
|
import org.eclipse.jetty.http.HttpHeader;
|
||||||
|
|
|
@ -22,8 +22,6 @@ import java.nio.ByteBuffer;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
import org.eclipse.jetty.client.api.ContentProvider;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link ContentProvider} for {@link ByteBuffer}s.
|
* A {@link ContentProvider} for {@link ByteBuffer}s.
|
||||||
* <p />
|
* <p />
|
||||||
|
|
|
@ -22,8 +22,6 @@ import java.nio.ByteBuffer;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
import org.eclipse.jetty.client.api.ContentProvider;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link ContentProvider} for byte arrays.
|
* A {@link ContentProvider} for byte arrays.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -30,9 +30,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
import org.eclipse.jetty.client.AsyncContentProvider;
|
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.ArrayQueue;
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
import org.eclipse.jetty.util.BufferUtil;
|
||||||
import org.eclipse.jetty.util.Callback;
|
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.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.eclipse.jetty.client.HttpClient;
|
|
||||||
import org.eclipse.jetty.client.api.Authentication;
|
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.ContentResponse;
|
||||||
import org.eclipse.jetty.client.api.Request;
|
import org.eclipse.jetty.client.api.Request;
|
||||||
import org.eclipse.jetty.http.HttpHeader;
|
import org.eclipse.jetty.http.HttpHeader;
|
||||||
|
|
|
@ -24,7 +24,6 @@ import java.nio.charset.Charset;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.charset.UnsupportedCharsetException;
|
import java.nio.charset.UnsupportedCharsetException;
|
||||||
|
|
||||||
import org.eclipse.jetty.client.api.ContentProvider;
|
|
||||||
import org.eclipse.jetty.util.Fields;
|
import org.eclipse.jetty.util.Fields;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -149,7 +149,8 @@ public class InputStreamContentProvider implements ContentProvider
|
||||||
|
|
||||||
byte[] bytes = new byte[bufferSize];
|
byte[] bytes = new byte[bufferSize];
|
||||||
int read = stream.read(bytes);
|
int read = stream.read(bytes);
|
||||||
LOG.debug("Read {} bytes from {}", read, stream);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Read {} bytes from {}", read, stream);
|
||||||
if (read > 0)
|
if (read > 0)
|
||||||
{
|
{
|
||||||
hasNext = Boolean.TRUE;
|
hasNext = Boolean.TRUE;
|
||||||
|
@ -172,7 +173,8 @@ public class InputStreamContentProvider implements ContentProvider
|
||||||
}
|
}
|
||||||
catch (Throwable x)
|
catch (Throwable x)
|
||||||
{
|
{
|
||||||
LOG.debug(x);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug(x);
|
||||||
if (failure == null)
|
if (failure == null)
|
||||||
{
|
{
|
||||||
failure = x;
|
failure = x;
|
||||||
|
|
|
@ -32,7 +32,6 @@ import java.util.concurrent.TimeoutException;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
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;
|
||||||
import org.eclipse.jetty.client.api.Response.Listener;
|
import org.eclipse.jetty.client.api.Response.Listener;
|
||||||
import org.eclipse.jetty.client.api.Result;
|
import org.eclipse.jetty.client.api.Result;
|
||||||
|
@ -116,23 +115,27 @@ public class InputStreamResponseListener extends Listener.Adapter
|
||||||
|
|
||||||
byte[] bytes = new byte[remaining];
|
byte[] bytes = new byte[remaining];
|
||||||
content.get(bytes);
|
content.get(bytes);
|
||||||
LOG.debug("Queuing {}/{} bytes", bytes, remaining);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Queuing {}/{} bytes", bytes, remaining);
|
||||||
queue.offer(bytes);
|
queue.offer(bytes);
|
||||||
|
|
||||||
long newLength = length.addAndGet(remaining);
|
long newLength = length.addAndGet(remaining);
|
||||||
while (newLength >= maxBufferSize)
|
while (newLength >= maxBufferSize)
|
||||||
{
|
{
|
||||||
LOG.debug("Queued bytes limit {}/{} exceeded, waiting", newLength, maxBufferSize);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Queued bytes limit {}/{} exceeded, waiting", newLength, maxBufferSize);
|
||||||
// Block to avoid infinite buffering
|
// Block to avoid infinite buffering
|
||||||
if (!await())
|
if (!await())
|
||||||
break;
|
break;
|
||||||
newLength = length.get();
|
newLength = length.get();
|
||||||
LOG.debug("Queued bytes limit {}/{} exceeded, woken up", newLength, maxBufferSize);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Queued bytes limit {}/{} exceeded, woken up", newLength, maxBufferSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG.debug("Queuing skipped, empty content {}", content);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Queuing skipped, empty content {}", content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -141,26 +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
|
@Override
|
||||||
public void onComplete(Result result)
|
public void onComplete(Result result)
|
||||||
{
|
{
|
||||||
|
if (result.isFailed() && failure == null)
|
||||||
|
fail(result.getFailure());
|
||||||
this.result = result;
|
this.result = result;
|
||||||
if (result.isSucceeded())
|
|
||||||
{
|
|
||||||
LOG.debug("Queuing end of content {}{}", EOF, "");
|
|
||||||
queue.offer(EOF);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG.debug("Queuing failure {} {}", FAILURE, failure);
|
|
||||||
queue.offer(FAILURE);
|
|
||||||
this.failure = result.getFailure();
|
|
||||||
responseLatch.countDown();
|
|
||||||
}
|
|
||||||
resultLatch.countDown();
|
resultLatch.countDown();
|
||||||
signal();
|
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()
|
protected boolean await()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -288,7 +306,8 @@ public class InputStreamResponseListener extends Listener.Adapter
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bytes = take();
|
bytes = take();
|
||||||
LOG.debug("Dequeued {}/{} bytes", bytes, bytes.length);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Dequeued {}/{} bytes", bytes, bytes.length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -319,7 +338,8 @@ public class InputStreamResponseListener extends Listener.Adapter
|
||||||
if (!closed)
|
if (!closed)
|
||||||
{
|
{
|
||||||
super.close();
|
super.close();
|
||||||
LOG.debug("Queuing close {}{}", CLOSED, "");
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Queuing close {}{}", CLOSED, "");
|
||||||
queue.offer(CLOSED);
|
queue.offer(CLOSED);
|
||||||
closed = true;
|
closed = true;
|
||||||
signal();
|
signal();
|
||||||
|
|
|
@ -24,9 +24,6 @@ import java.nio.ByteBuffer;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
import org.eclipse.jetty.client.AsyncContentProvider;
|
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}
|
* 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.Iterator;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
import org.eclipse.jetty.client.api.ContentProvider;
|
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
|
|
||||||
|
@ -107,7 +106,8 @@ public class PathContentProvider extends AbstractTypedContentProvider
|
||||||
if (channel == null)
|
if (channel == null)
|
||||||
{
|
{
|
||||||
channel = Files.newByteChannel(filePath, StandardOpenOption.READ);
|
channel = Files.newByteChannel(filePath, StandardOpenOption.READ);
|
||||||
LOG.debug("Opened file {}", filePath);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Opened file {}", filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer.clear();
|
buffer.clear();
|
||||||
|
|
|
@ -21,8 +21,6 @@ package org.eclipse.jetty.client.util;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
import org.eclipse.jetty.client.api.ContentProvider;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link ContentProvider} for strings.
|
* A {@link ContentProvider} for strings.
|
||||||
* <p />
|
* <p />
|
||||||
|
|
|
@ -116,6 +116,11 @@ public class HostnameVerificationTest
|
||||||
|
|
||||||
// ExecutionException wraps an SSLHandshakeException
|
// ExecutionException wraps an SSLHandshakeException
|
||||||
Throwable cause = x.getCause();
|
Throwable cause = x.getCause();
|
||||||
|
if (cause==null)
|
||||||
|
{
|
||||||
|
x.printStackTrace();
|
||||||
|
Assert.fail("No cause?");
|
||||||
|
}
|
||||||
if (cause instanceof SSLHandshakeException)
|
if (cause instanceof SSLHandshakeException)
|
||||||
Assert.assertThat(cause.getCause().getCause(), Matchers.instanceOf(CertificateException.class));
|
Assert.assertThat(cause.getCause().getCause(), Matchers.instanceOf(CertificateException.class));
|
||||||
else
|
else
|
||||||
|
|
|
@ -25,6 +25,7 @@ import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
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.Server;
|
||||||
import org.eclipse.jetty.server.handler.AbstractHandler;
|
import org.eclipse.jetty.server.handler.AbstractHandler;
|
||||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
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.security.Constraint;
|
||||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
@ -187,7 +189,7 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest
|
||||||
{
|
{
|
||||||
baseRequest.setHandled(true);
|
baseRequest.setHandled(true);
|
||||||
if (requests.incrementAndGet() == 1)
|
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);
|
baseRequest.setHandled(true);
|
||||||
if (request.getRequestURI().endsWith("/redirect"))
|
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.TimeoutException;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.zip.GZIPOutputStream;
|
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.ServletOutputStream;
|
import javax.servlet.ServletOutputStream;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
@ -672,32 +670,6 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
||||||
Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
|
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
|
@Slow
|
||||||
@Test
|
@Test
|
||||||
public void test_Request_IdleTimeout() throws Exception
|
public void test_Request_IdleTimeout() throws Exception
|
||||||
|
|
|
@ -29,6 +29,7 @@ import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import javax.net.ssl.SSLEngine;
|
import javax.net.ssl.SSLEngine;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
@ -56,6 +57,7 @@ import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Assume;
|
import org.junit.Assume;
|
||||||
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class HttpClientTimeoutTest extends AbstractHttpClientServerTest
|
public class HttpClientTimeoutTest extends AbstractHttpClientServerTest
|
||||||
|
@ -299,6 +301,7 @@ public class HttpClientTimeoutTest extends AbstractHttpClientServerTest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Ignore
|
||||||
@Slow
|
@Slow
|
||||||
@Test
|
@Test
|
||||||
public void testConnectTimeoutFailsRequest() throws Exception
|
public void testConnectTimeoutFailsRequest() throws Exception
|
||||||
|
@ -330,6 +333,7 @@ public class HttpClientTimeoutTest extends AbstractHttpClientServerTest
|
||||||
Assert.assertNotNull(request.getAbortCause());
|
Assert.assertNotNull(request.getAbortCause());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Ignore
|
||||||
@Slow
|
@Slow
|
||||||
@Test
|
@Test
|
||||||
public void testConnectTimeoutIsCancelledByShorterTimeout() throws Exception
|
public void testConnectTimeoutIsCancelledByShorterTimeout() 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;
|
package org.eclipse.jetty.client.http;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.EOFException;
|
import java.io.EOFException;
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.concurrent.CountDownLatch;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
import java.util.zip.GZIPOutputStream;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.client.HttpClient;
|
import org.eclipse.jetty.client.HttpClient;
|
||||||
import org.eclipse.jetty.client.HttpExchange;
|
import org.eclipse.jetty.client.HttpExchange;
|
||||||
import org.eclipse.jetty.client.HttpRequest;
|
import org.eclipse.jetty.client.HttpRequest;
|
||||||
import org.eclipse.jetty.client.HttpResponseException;
|
import org.eclipse.jetty.client.HttpResponseException;
|
||||||
import org.eclipse.jetty.client.Origin;
|
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.api.Response;
|
||||||
import org.eclipse.jetty.client.util.FutureResponseListener;
|
import org.eclipse.jetty.client.util.FutureResponseListener;
|
||||||
import org.eclipse.jetty.http.HttpFields;
|
import org.eclipse.jetty.http.HttpFields;
|
||||||
|
@ -205,58 +200,4 @@ public class HttpReceiverOverHTTPTest
|
||||||
Assert.assertTrue(e.getCause() instanceof HttpResponseException);
|
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
|
@Test
|
||||||
public void testRequestWithBigContentWriteBlockedThenReset() throws Exception
|
public void testRequestWithBigContentWriteBlockedThenReset() throws Exception
|
||||||
{
|
{
|
||||||
// Don't run on Windows (buggy JVM)
|
// Don't run on Windows (buggy JVM)
|
||||||
Assume.assumeTrue(!OS.IS_WINDOWS);
|
Assume.assumeTrue(!OS.IS_WINDOWS);
|
||||||
|
|
||||||
final SSLSocket client = newClient();
|
final SSLSocket client = newClient();
|
||||||
|
|
||||||
SimpleProxy.AutomaticFlow automaticProxyFlow = proxy.startAutomaticFlow();
|
SimpleProxy.AutomaticFlow automaticProxyFlow = proxy.startAutomaticFlow();
|
||||||
|
@ -1110,10 +1110,10 @@ public class SslBytesServerTest extends SslBytesTest
|
||||||
@Test
|
@Test
|
||||||
public void testRequestWithBigContentReadBlockedThenReset() throws Exception
|
public void testRequestWithBigContentReadBlockedThenReset() throws Exception
|
||||||
{
|
{
|
||||||
// Don't run on Windows (buggy JVM)
|
// Don't run on Windows (buggy JVM)
|
||||||
Assume.assumeTrue(!OS.IS_WINDOWS);
|
Assume.assumeTrue(!OS.IS_WINDOWS);
|
||||||
|
|
||||||
final SSLSocket client = newClient();
|
final SSLSocket client = newClient();
|
||||||
|
|
||||||
SimpleProxy.AutomaticFlow automaticProxyFlow = proxy.startAutomaticFlow();
|
SimpleProxy.AutomaticFlow automaticProxyFlow = proxy.startAutomaticFlow();
|
||||||
client.startHandshake();
|
client.startHandshake();
|
||||||
|
|
|
@ -18,12 +18,7 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.continuation;
|
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.ServletResponse;
|
||||||
import javax.servlet.ServletResponseWrapper;
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -20,8 +20,6 @@ package org.eclipse.jetty.continuation;
|
||||||
|
|
||||||
import java.util.EventListener;
|
import java.util.EventListener;
|
||||||
|
|
||||||
import javax.servlet.ServletRequestListener;
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/** A Continuation Listener
|
/** A Continuation Listener
|
||||||
|
|
|
@ -18,8 +18,6 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.deploy;
|
package org.eclipse.jetty.deploy;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||||
import org.eclipse.jetty.util.component.LifeCycle;
|
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.App;
|
||||||
import org.eclipse.jetty.deploy.ConfigurationManager;
|
import org.eclipse.jetty.deploy.ConfigurationManager;
|
||||||
import org.eclipse.jetty.deploy.util.FileID;
|
import org.eclipse.jetty.deploy.util.FileID;
|
||||||
import org.eclipse.jetty.server.Server;
|
|
||||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||||
import org.eclipse.jetty.util.URIUtil;
|
import org.eclipse.jetty.util.URIUtil;
|
||||||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||||
|
|
|
@ -36,10 +36,10 @@ import org.junit.Test;
|
||||||
*/
|
*/
|
||||||
public class AppLifeCycleTest
|
public class AppLifeCycleTest
|
||||||
{
|
{
|
||||||
@Rule
|
@Rule
|
||||||
public TestingDir testdir = new TestingDir();
|
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>());
|
assertPath(from,to,new ArrayList<String>());
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,6 @@ import static org.hamcrest.Matchers.not;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.jetty.deploy.providers.ScanningAppProvider;
|
|
||||||
import org.eclipse.jetty.deploy.test.XmlConfiguredJetty;
|
import org.eclipse.jetty.deploy.test.XmlConfiguredJetty;
|
||||||
import org.eclipse.jetty.toolchain.test.IO;
|
import org.eclipse.jetty.toolchain.test.IO;
|
||||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||||
|
|
|
@ -30,8 +30,8 @@ import org.junit.Test;
|
||||||
*/
|
*/
|
||||||
public class ScanningAppProviderStartupTest
|
public class ScanningAppProviderStartupTest
|
||||||
{
|
{
|
||||||
@Rule
|
@Rule
|
||||||
public TestingDir testdir = new TestingDir();
|
public TestingDir testdir = new TestingDir();
|
||||||
private static XmlConfiguredJetty jetty;
|
private static XmlConfiguredJetty jetty;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
|
|
|
@ -302,7 +302,7 @@
|
||||||
<configuration>
|
<configuration>
|
||||||
<includeGroupIds>org.eclipse.jetty</includeGroupIds>
|
<includeGroupIds>org.eclipse.jetty</includeGroupIds>
|
||||||
<excludeGroupIds>org.eclipse.jetty.orbit,org.eclipse.jetty.spdy,org.eclipse.jetty.websocket,org.eclipse.jetty.fcgi,org.eclipse.jetty.toolchain,org.apache.taglibs</excludeGroupIds>
|
<excludeGroupIds>org.eclipse.jetty.orbit,org.eclipse.jetty.spdy,org.eclipse.jetty.websocket,org.eclipse.jetty.fcgi,org.eclipse.jetty.toolchain,org.apache.taglibs</excludeGroupIds>
|
||||||
<excludeArtifactIds>jetty-all,jetty-jsp,apache-jsp,jetty-start,jetty-monitor</excludeArtifactIds>
|
<excludeArtifactIds>jetty-all,jetty-jsp,apache-jsp,jetty-start,jetty-monitor,jetty-spring</excludeArtifactIds>
|
||||||
<includeTypes>jar</includeTypes>
|
<includeTypes>jar</includeTypes>
|
||||||
<outputDirectory>${assembly-directory}/lib</outputDirectory>
|
<outputDirectory>${assembly-directory}/lib</outputDirectory>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
@ -332,6 +332,19 @@
|
||||||
<outputDirectory>${assembly-directory}/lib/fcgi</outputDirectory>
|
<outputDirectory>${assembly-directory}/lib/fcgi</outputDirectory>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>copy-lib-spring-deps</id>
|
||||||
|
<phase>generate-resources</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>copy-dependencies</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<includeGroupIds>org.eclipse.jetty</includeGroupIds>
|
||||||
|
<includeArtifactIds>jetty-spring</includeArtifactIds>
|
||||||
|
<includeTypes>jar</includeTypes>
|
||||||
|
<outputDirectory>${assembly-directory}/lib/spring</outputDirectory>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
<execution>
|
<execution>
|
||||||
<id>copy-lib-monitor-deps</id>
|
<id>copy-lib-monitor-deps</id>
|
||||||
<phase>generate-resources</phase>
|
<phase>generate-resources</phase>
|
||||||
|
@ -765,6 +778,11 @@
|
||||||
<artifactId>fcgi-server</artifactId>
|
<artifactId>fcgi-server</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
<artifactId>jetty-spring</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
<!--
|
<!--
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
|
|
@ -70,7 +70,8 @@ public class HttpClientTransportOverFCGI extends AbstractHttpClientTransport
|
||||||
{
|
{
|
||||||
HttpDestination destination = (HttpDestination)context.get(HTTP_DESTINATION_CONTEXT_KEY);
|
HttpDestination destination = (HttpDestination)context.get(HTTP_DESTINATION_CONTEXT_KEY);
|
||||||
HttpConnectionOverFCGI connection = new HttpConnectionOverFCGI(endPoint, destination, isMultiplexed());
|
HttpConnectionOverFCGI connection = new HttpConnectionOverFCGI(endPoint, destination, isMultiplexed());
|
||||||
LOG.debug("Created {}", connection);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Created {}", connection);
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Promise<Connection> promise = (Promise<Connection>)context.get(HTTP_CONNECTION_PROMISE_CONTEXT_KEY);
|
Promise<Connection> promise = (Promise<Connection>)context.get(HTTP_CONNECTION_PROMISE_CONTEXT_KEY);
|
||||||
promise.succeeded(connection);
|
promise.succeeded(connection);
|
||||||
|
|
|
@ -150,7 +150,8 @@ public class HttpConnectionOverFCGI extends AbstractConnection implements Connec
|
||||||
}
|
}
|
||||||
catch (Exception x)
|
catch (Exception x)
|
||||||
{
|
{
|
||||||
LOG.debug(x);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug(x);
|
||||||
close(x);
|
close(x);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -415,7 +416,8 @@ public class HttpConnectionOverFCGI extends AbstractConnection implements Connec
|
||||||
|
|
||||||
private void noChannel(int request)
|
private void noChannel(int request)
|
||||||
{
|
{
|
||||||
LOG.debug("Channel not found for request {}", request);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Channel not found for request {}", request);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,7 @@ public class Flusher
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void completed()
|
protected void onCompleteSuccess()
|
||||||
{
|
{
|
||||||
// We never return Action.SUCCEEDED, so this method is never called.
|
// We never return Action.SUCCEEDED, so this method is never called.
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
|
@ -98,7 +98,7 @@ public class Flusher
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void failed(Throwable x)
|
public void onCompleteFailure(Throwable x)
|
||||||
{
|
{
|
||||||
if (active != null)
|
if (active != null)
|
||||||
active.failed(x);
|
active.failed(x);
|
||||||
|
@ -111,8 +111,6 @@ public class Flusher
|
||||||
break;
|
break;
|
||||||
result.failed(x);
|
result.failed(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
super.failed(x);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,7 +135,8 @@ public class Flusher
|
||||||
|
|
||||||
private void shutdown()
|
private void shutdown()
|
||||||
{
|
{
|
||||||
LOG.debug("Shutting down {}", endPoint);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Shutting down {}", endPoint);
|
||||||
endPoint.shutdownOutput();
|
endPoint.shutdownOutput();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ import org.eclipse.jetty.util.log.Logger;
|
||||||
|
|
||||||
public class ParamsContentParser extends ContentParser
|
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 final ServerParser.Listener listener;
|
||||||
private State state = State.LENGTH;
|
private State state = State.LENGTH;
|
||||||
|
@ -212,7 +212,8 @@ public class ParamsContentParser extends ContentParser
|
||||||
}
|
}
|
||||||
catch (Throwable x)
|
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)
|
catch (Throwable x)
|
||||||
{
|
{
|
||||||
logger.debug("Exception while invoking listener " + listener, x);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Exception while invoking listener " + listener, x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,8 @@ public class ResponseContentParser extends StreamContentParser
|
||||||
|
|
||||||
public boolean parse(ByteBuffer buffer)
|
public boolean parse(ByteBuffer buffer)
|
||||||
{
|
{
|
||||||
LOG.debug("Response {} {} content {} {}", request, FCGI.StreamType.STD_OUT, state, buffer);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Response {} {} content {} {}", request, FCGI.StreamType.STD_OUT, state, buffer);
|
||||||
|
|
||||||
int remaining = buffer.remaining();
|
int remaining = buffer.remaining();
|
||||||
while (remaining > 0)
|
while (remaining > 0)
|
||||||
|
@ -186,7 +187,8 @@ public class ResponseContentParser extends StreamContentParser
|
||||||
}
|
}
|
||||||
catch (Throwable x)
|
catch (Throwable x)
|
||||||
{
|
{
|
||||||
logger.debug("Exception while invoking listener " + listener, x);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Exception while invoking listener " + listener, x);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -199,7 +201,8 @@ public class ResponseContentParser extends StreamContentParser
|
||||||
}
|
}
|
||||||
catch (Throwable x)
|
catch (Throwable x)
|
||||||
{
|
{
|
||||||
logger.debug("Exception while invoking listener " + listener, x);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Exception while invoking listener " + listener, x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,7 +214,8 @@ public class ResponseContentParser extends StreamContentParser
|
||||||
}
|
}
|
||||||
catch (Throwable x)
|
catch (Throwable x)
|
||||||
{
|
{
|
||||||
logger.debug("Exception while invoking listener " + listener, x);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Exception while invoking listener " + listener, x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,7 +236,8 @@ public class ResponseContentParser extends StreamContentParser
|
||||||
}
|
}
|
||||||
catch (Throwable x)
|
catch (Throwable x)
|
||||||
{
|
{
|
||||||
logger.debug("Exception while invoking listener " + listener, x);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Exception while invoking listener " + listener, x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,7 +269,8 @@ public class ResponseContentParser extends StreamContentParser
|
||||||
}
|
}
|
||||||
catch (Throwable x)
|
catch (Throwable x)
|
||||||
{
|
{
|
||||||
logger.debug("Exception while invoking listener " + listener, x);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Exception while invoking listener " + listener, x);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ import org.eclipse.jetty.util.log.Logger;
|
||||||
|
|
||||||
public class StreamContentParser extends ContentParser
|
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 FCGI.StreamType streamType;
|
||||||
private final Parser.Listener listener;
|
private final Parser.Listener listener;
|
||||||
|
@ -87,7 +87,8 @@ public class StreamContentParser extends ContentParser
|
||||||
}
|
}
|
||||||
catch (Throwable x)
|
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)
|
catch (Throwable x)
|
||||||
{
|
{
|
||||||
logger.debug("Exception while invoking listener " + listener, x);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Exception while invoking listener " + listener, x);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,7 +132,8 @@ public class HttpChannelOverFCGI extends HttpChannel<ByteBuffer>
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
State current = state.get();
|
State current = state.get();
|
||||||
LOG.debug("Dispatching, state={}", current);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Dispatching, state={}", current);
|
||||||
switch (current)
|
switch (current)
|
||||||
{
|
{
|
||||||
case IDLE:
|
case IDLE:
|
||||||
|
@ -167,7 +168,8 @@ public class HttpChannelOverFCGI extends HttpChannel<ByteBuffer>
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
State current = state.get();
|
State current = state.get();
|
||||||
LOG.debug("Running, state={}", current);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Running, state={}", current);
|
||||||
switch (current)
|
switch (current)
|
||||||
{
|
{
|
||||||
case DISPATCH:
|
case DISPATCH:
|
||||||
|
|
|
@ -94,7 +94,8 @@ public class ServerFCGIConnection extends AbstractConnection
|
||||||
}
|
}
|
||||||
catch (Exception x)
|
catch (Exception x)
|
||||||
{
|
{
|
||||||
LOG.debug(x);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug(x);
|
||||||
// TODO: fail and close ?
|
// TODO: fail and close ?
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
|
|
@ -97,8 +97,8 @@ public class JettyHttpContext extends com.sun.net.httpserver.HttpContext
|
||||||
@Override
|
@Override
|
||||||
public Authenticator setAuthenticator(Authenticator auth)
|
public Authenticator setAuthenticator(Authenticator auth)
|
||||||
{
|
{
|
||||||
Authenticator previous = _authenticator;
|
Authenticator previous = _authenticator;
|
||||||
_authenticator = auth;
|
_authenticator = auth;
|
||||||
return previous;
|
return previous;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,271 +1,271 @@
|
||||||
//
|
//
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
|
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// All rights reserved. This program and the accompanying materials
|
// All rights reserved. This program and the accompanying materials
|
||||||
// are made available under the terms of the Eclipse Public License v1.0
|
// are made available under the terms of the Eclipse Public License v1.0
|
||||||
// and Apache License v2.0 which accompanies this distribution.
|
// and Apache License v2.0 which accompanies this distribution.
|
||||||
//
|
//
|
||||||
// The Eclipse Public License is available at
|
// The Eclipse Public License is available at
|
||||||
// http://www.eclipse.org/legal/epl-v10.html
|
// http://www.eclipse.org/legal/epl-v10.html
|
||||||
//
|
//
|
||||||
// The Apache License v2.0 is available at
|
// The Apache License v2.0 is available at
|
||||||
// http://www.opensource.org/licenses/apache2.0.php
|
// http://www.opensource.org/licenses/apache2.0.php
|
||||||
//
|
//
|
||||||
// You may elect to redistribute this code under either of these licenses.
|
// You may elect to redistribute this code under either of these licenses.
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
//
|
//
|
||||||
|
|
||||||
package org.eclipse.jetty.http.spi;
|
package org.eclipse.jetty.http.spi;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
|
||||||
import org.eclipse.jetty.server.Connector;
|
import org.eclipse.jetty.server.Connector;
|
||||||
import org.eclipse.jetty.server.Handler;
|
import org.eclipse.jetty.server.Handler;
|
||||||
import org.eclipse.jetty.server.NetworkConnector;
|
import org.eclipse.jetty.server.NetworkConnector;
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
import org.eclipse.jetty.server.ServerConnector;
|
import org.eclipse.jetty.server.ServerConnector;
|
||||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||||
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
|
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
|
||||||
import org.eclipse.jetty.server.handler.HandlerCollection;
|
import org.eclipse.jetty.server.handler.HandlerCollection;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.util.thread.ThreadPool;
|
import org.eclipse.jetty.util.thread.ThreadPool;
|
||||||
|
|
||||||
import com.sun.net.httpserver.HttpContext;
|
import com.sun.net.httpserver.HttpContext;
|
||||||
import com.sun.net.httpserver.HttpHandler;
|
import com.sun.net.httpserver.HttpHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Jetty implementation of {@link com.sun.net.httpserver.HttpServer}.
|
* Jetty implementation of {@link com.sun.net.httpserver.HttpServer}.
|
||||||
*/
|
*/
|
||||||
public class JettyHttpServer extends com.sun.net.httpserver.HttpServer
|
public class JettyHttpServer extends com.sun.net.httpserver.HttpServer
|
||||||
{
|
{
|
||||||
private static final Logger LOG = Log.getLogger(JettyHttpServer.class);
|
private static final Logger LOG = Log.getLogger(JettyHttpServer.class);
|
||||||
|
|
||||||
|
|
||||||
private Server _server;
|
private Server _server;
|
||||||
|
|
||||||
private boolean _serverShared;
|
private boolean _serverShared;
|
||||||
|
|
||||||
private InetSocketAddress _addr;
|
private InetSocketAddress _addr;
|
||||||
|
|
||||||
private ThreadPoolExecutor _executor;
|
private ThreadPoolExecutor _executor;
|
||||||
|
|
||||||
private Map<String, JettyHttpContext> _contexts = new HashMap<String, JettyHttpContext>();
|
private Map<String, JettyHttpContext> _contexts = new HashMap<String, JettyHttpContext>();
|
||||||
|
|
||||||
private Map<String, Connector> _connectors = new HashMap<String, Connector>();
|
private Map<String, Connector> _connectors = new HashMap<String, Connector>();
|
||||||
|
|
||||||
|
|
||||||
public JettyHttpServer(Server server, boolean shared)
|
public JettyHttpServer(Server server, boolean shared)
|
||||||
{
|
{
|
||||||
this._server = server;
|
this._server = server;
|
||||||
this._serverShared = shared;
|
this._serverShared = shared;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void bind(InetSocketAddress addr, int backlog) throws IOException
|
public void bind(InetSocketAddress addr, int backlog) throws IOException
|
||||||
{
|
{
|
||||||
// check if there is already a connector listening
|
// check if there is already a connector listening
|
||||||
Collection<NetworkConnector> connectors = _server.getBeans(NetworkConnector.class);
|
Collection<NetworkConnector> connectors = _server.getBeans(NetworkConnector.class);
|
||||||
if (connectors != null)
|
if (connectors != null)
|
||||||
{
|
{
|
||||||
for (NetworkConnector connector : connectors)
|
for (NetworkConnector connector : connectors)
|
||||||
{
|
{
|
||||||
if (connector.getPort() == addr.getPort()) {
|
if (connector.getPort() == addr.getPort()) {
|
||||||
if (LOG.isDebugEnabled()) LOG.debug("server already bound to port " + addr.getPort() + ", no need to rebind");
|
if (LOG.isDebugEnabled()) LOG.debug("server already bound to port " + addr.getPort() + ", no need to rebind");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_serverShared)
|
if (_serverShared)
|
||||||
throw new IOException("jetty server is not bound to port " + addr.getPort());
|
throw new IOException("jetty server is not bound to port " + addr.getPort());
|
||||||
|
|
||||||
this._addr = addr;
|
this._addr = addr;
|
||||||
|
|
||||||
if (LOG.isDebugEnabled()) LOG.debug("binding server to port " + addr.getPort());
|
if (LOG.isDebugEnabled()) LOG.debug("binding server to port " + addr.getPort());
|
||||||
ServerConnector connector = new ServerConnector(_server);
|
ServerConnector connector = new ServerConnector(_server);
|
||||||
connector.setPort(addr.getPort());
|
connector.setPort(addr.getPort());
|
||||||
connector.setHost(addr.getHostName());
|
connector.setHost(addr.getHostName());
|
||||||
_server.addConnector(connector);
|
_server.addConnector(connector);
|
||||||
|
|
||||||
_connectors.put(addr.getHostName() + addr.getPort(), connector);
|
_connectors.put(addr.getHostName() + addr.getPort(), connector);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InetSocketAddress getAddress()
|
public InetSocketAddress getAddress()
|
||||||
{
|
{
|
||||||
return _addr;
|
return _addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start()
|
public void start()
|
||||||
{
|
{
|
||||||
if (_serverShared) return;
|
if (_serverShared) return;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_server.start();
|
_server.start();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
throw new RuntimeException(ex);
|
throw new RuntimeException(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setExecutor(Executor executor)
|
public void setExecutor(Executor executor)
|
||||||
{
|
{
|
||||||
if (executor == null)
|
if (executor == null)
|
||||||
throw new IllegalArgumentException("missing required 'executor' argument");
|
throw new IllegalArgumentException("missing required 'executor' argument");
|
||||||
ThreadPool threadPool = _server.getThreadPool();
|
ThreadPool threadPool = _server.getThreadPool();
|
||||||
if (threadPool instanceof DelegatingThreadPool)
|
if (threadPool instanceof DelegatingThreadPool)
|
||||||
((DelegatingThreadPool)_server.getThreadPool()).setExecutor(executor);
|
((DelegatingThreadPool)_server.getThreadPool()).setExecutor(executor);
|
||||||
else
|
else
|
||||||
throw new UnsupportedOperationException("!DelegatingThreadPool");
|
throw new UnsupportedOperationException("!DelegatingThreadPool");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Executor getExecutor()
|
public Executor getExecutor()
|
||||||
{
|
{
|
||||||
ThreadPool threadPool = _server.getThreadPool();
|
ThreadPool threadPool = _server.getThreadPool();
|
||||||
if (threadPool instanceof DelegatingThreadPool)
|
if (threadPool instanceof DelegatingThreadPool)
|
||||||
return ((DelegatingThreadPool)_server.getThreadPool()).getExecutor();
|
return ((DelegatingThreadPool)_server.getThreadPool()).getExecutor();
|
||||||
return threadPool;
|
return threadPool;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stop(int delay)
|
public void stop(int delay)
|
||||||
{
|
{
|
||||||
cleanUpContexts();
|
cleanUpContexts();
|
||||||
cleanUpConnectors();
|
cleanUpConnectors();
|
||||||
|
|
||||||
if (_serverShared) return;
|
if (_serverShared) return;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_server.stop();
|
_server.stop();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
throw new RuntimeException(ex);
|
throw new RuntimeException(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cleanUpContexts()
|
private void cleanUpContexts()
|
||||||
{
|
{
|
||||||
for (Map.Entry<String, JettyHttpContext> stringJettyHttpContextEntry : _contexts.entrySet())
|
for (Map.Entry<String, JettyHttpContext> stringJettyHttpContextEntry : _contexts.entrySet())
|
||||||
{
|
{
|
||||||
JettyHttpContext context = stringJettyHttpContextEntry.getValue();
|
JettyHttpContext context = stringJettyHttpContextEntry.getValue();
|
||||||
_server.removeBean(context.getJettyContextHandler());
|
_server.removeBean(context.getJettyContextHandler());
|
||||||
}
|
}
|
||||||
_contexts.clear();
|
_contexts.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cleanUpConnectors()
|
private void cleanUpConnectors()
|
||||||
{
|
{
|
||||||
for (Map.Entry<String, Connector> stringConnectorEntry : _connectors.entrySet())
|
for (Map.Entry<String, Connector> stringConnectorEntry : _connectors.entrySet())
|
||||||
{
|
{
|
||||||
Connector connector = stringConnectorEntry.getValue();
|
Connector connector = stringConnectorEntry.getValue();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
connector.stop();
|
connector.stop();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
LOG.warn(ex);
|
LOG.warn(ex);
|
||||||
}
|
}
|
||||||
_server.removeConnector(connector);
|
_server.removeConnector(connector);
|
||||||
}
|
}
|
||||||
_connectors.clear();
|
_connectors.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HttpContext createContext(String path, HttpHandler httpHandler)
|
public HttpContext createContext(String path, HttpHandler httpHandler)
|
||||||
{
|
{
|
||||||
checkIfContextIsFree(path);
|
checkIfContextIsFree(path);
|
||||||
|
|
||||||
JettyHttpContext context = new JettyHttpContext(this, path, httpHandler);
|
JettyHttpContext context = new JettyHttpContext(this, path, httpHandler);
|
||||||
HttpSpiContextHandler jettyContextHandler = context.getJettyContextHandler();
|
HttpSpiContextHandler jettyContextHandler = context.getJettyContextHandler();
|
||||||
|
|
||||||
ContextHandlerCollection chc = findContextHandlerCollection(_server.getHandlers());
|
ContextHandlerCollection chc = findContextHandlerCollection(_server.getHandlers());
|
||||||
if (chc == null)
|
if (chc == null)
|
||||||
throw new RuntimeException("could not find ContextHandlerCollection, you must configure one");
|
throw new RuntimeException("could not find ContextHandlerCollection, you must configure one");
|
||||||
|
|
||||||
chc.addHandler(jettyContextHandler);
|
chc.addHandler(jettyContextHandler);
|
||||||
_contexts.put(path, context);
|
_contexts.put(path, context);
|
||||||
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ContextHandlerCollection findContextHandlerCollection(Handler[] handlers)
|
private ContextHandlerCollection findContextHandlerCollection(Handler[] handlers)
|
||||||
{
|
{
|
||||||
if (handlers == null)
|
if (handlers == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
for (Handler handler : handlers)
|
for (Handler handler : handlers)
|
||||||
{
|
{
|
||||||
if (handler instanceof ContextHandlerCollection)
|
if (handler instanceof ContextHandlerCollection)
|
||||||
{
|
{
|
||||||
return (ContextHandlerCollection) handler;
|
return (ContextHandlerCollection) handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handler instanceof HandlerCollection)
|
if (handler instanceof HandlerCollection)
|
||||||
{
|
{
|
||||||
HandlerCollection hc = (HandlerCollection) handler;
|
HandlerCollection hc = (HandlerCollection) handler;
|
||||||
ContextHandlerCollection chc = findContextHandlerCollection(hc.getHandlers());
|
ContextHandlerCollection chc = findContextHandlerCollection(hc.getHandlers());
|
||||||
if (chc != null)
|
if (chc != null)
|
||||||
return chc;
|
return chc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkIfContextIsFree(String path)
|
private void checkIfContextIsFree(String path)
|
||||||
{
|
{
|
||||||
Handler serverHandler = _server.getHandler();
|
Handler serverHandler = _server.getHandler();
|
||||||
if (serverHandler instanceof ContextHandler)
|
if (serverHandler instanceof ContextHandler)
|
||||||
{
|
{
|
||||||
ContextHandler ctx = (ContextHandler) serverHandler;
|
ContextHandler ctx = (ContextHandler) serverHandler;
|
||||||
if (ctx.getContextPath().equals(path))
|
if (ctx.getContextPath().equals(path))
|
||||||
throw new RuntimeException("another context already bound to path " + path);
|
throw new RuntimeException("another context already bound to path " + path);
|
||||||
}
|
}
|
||||||
|
|
||||||
Handler[] handlers = _server.getHandlers();
|
Handler[] handlers = _server.getHandlers();
|
||||||
if (handlers == null) return;
|
if (handlers == null) return;
|
||||||
|
|
||||||
for (Handler handler : handlers)
|
for (Handler handler : handlers)
|
||||||
{
|
{
|
||||||
if (handler instanceof ContextHandler) {
|
if (handler instanceof ContextHandler) {
|
||||||
ContextHandler ctx = (ContextHandler) handler;
|
ContextHandler ctx = (ContextHandler) handler;
|
||||||
if (ctx.getContextPath().equals(path))
|
if (ctx.getContextPath().equals(path))
|
||||||
throw new RuntimeException("another context already bound to path " + path);
|
throw new RuntimeException("another context already bound to path " + path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HttpContext createContext(String path)
|
public HttpContext createContext(String path)
|
||||||
{
|
{
|
||||||
return createContext(path, null);
|
return createContext(path, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeContext(String path) throws IllegalArgumentException
|
public void removeContext(String path) throws IllegalArgumentException
|
||||||
{
|
{
|
||||||
JettyHttpContext context = _contexts.remove(path);
|
JettyHttpContext context = _contexts.remove(path);
|
||||||
if (context == null) return;
|
if (context == null) return;
|
||||||
_server.removeBean(context.getJettyContextHandler());
|
_server.removeBean(context.getJettyContextHandler());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeContext(HttpContext context)
|
public void removeContext(HttpContext context)
|
||||||
{
|
{
|
||||||
removeContext(context.getPath());
|
removeContext(context.getPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ public class JettyHttpServerProvider extends HttpServerProvider
|
||||||
|
|
||||||
public static void setServer(Server server)
|
public static void setServer(Server server)
|
||||||
{
|
{
|
||||||
_server = server;
|
_server = server;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -51,7 +51,7 @@ public class JettyHttpServerProvider extends HttpServerProvider
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
Server server = _server;
|
Server server = _server;
|
||||||
boolean shared = true;
|
boolean shared = true;
|
||||||
|
|
||||||
if (server == null)
|
if (server == null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -287,7 +287,8 @@ public class HttpGenerator
|
||||||
{
|
{
|
||||||
if (BufferUtil.hasContent(content))
|
if (BufferUtil.hasContent(content))
|
||||||
{
|
{
|
||||||
LOG.debug("discarding content in COMPLETING");
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("discarding content in COMPLETING");
|
||||||
BufferUtil.clear(content);
|
BufferUtil.clear(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,7 +311,8 @@ public class HttpGenerator
|
||||||
case END:
|
case END:
|
||||||
if (BufferUtil.hasContent(content))
|
if (BufferUtil.hasContent(content))
|
||||||
{
|
{
|
||||||
LOG.debug("discarding content in COMPLETING");
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("discarding content in COMPLETING");
|
||||||
BufferUtil.clear(content);
|
BufferUtil.clear(content);
|
||||||
}
|
}
|
||||||
return Result.DONE;
|
return Result.DONE;
|
||||||
|
@ -436,7 +438,8 @@ public class HttpGenerator
|
||||||
{
|
{
|
||||||
if (BufferUtil.hasContent(content))
|
if (BufferUtil.hasContent(content))
|
||||||
{
|
{
|
||||||
LOG.debug("discarding content in COMPLETING");
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("discarding content in COMPLETING");
|
||||||
BufferUtil.clear(content);
|
BufferUtil.clear(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -462,7 +465,8 @@ public class HttpGenerator
|
||||||
case END:
|
case END:
|
||||||
if (BufferUtil.hasContent(content))
|
if (BufferUtil.hasContent(content))
|
||||||
{
|
{
|
||||||
LOG.debug("discarding content in COMPLETING");
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("discarding content in COMPLETING");
|
||||||
BufferUtil.clear(content);
|
BufferUtil.clear(content);
|
||||||
}
|
}
|
||||||
return Result.DONE;
|
return Result.DONE;
|
||||||
|
|
|
@ -35,7 +35,7 @@ import org.eclipse.jetty.util.log.Logger;
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/** A Parser for HTTP 0.9, 1.0 and 1.1
|
/** A Parser for HTTP 0.9, 1.0 and 1.1
|
||||||
* <p>
|
* <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
|
* passed in the {@link #parseNext(ByteBuffer)} method. The parsed
|
||||||
* elements of the HTTP message are passed as event calls to the
|
* elements of the HTTP message are passed as event calls to the
|
||||||
* {@link HttpHandler} instance the parser is constructed with.
|
* {@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");
|
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())
|
else if (len!=host.length())
|
||||||
host = host.substring(0,len);
|
host = host.substring(0,len);
|
||||||
|
|
|
@ -612,7 +612,6 @@ package org.eclipse.jetty.http;
|
||||||
*/
|
*/
|
||||||
public class HttpStatus
|
public class HttpStatus
|
||||||
{
|
{
|
||||||
public final static int NOT_SET_000 = 0;
|
|
||||||
public final static int CONTINUE_100 = 100;
|
public final static int CONTINUE_100 = 100;
|
||||||
public final static int SWITCHING_PROTOCOLS_101 = 101;
|
public final static int SWITCHING_PROTOCOLS_101 = 101;
|
||||||
public final static int PROCESSING_102 = 102;
|
public final static int PROCESSING_102 = 102;
|
||||||
|
|
|
@ -539,8 +539,6 @@ public class HttpURI
|
||||||
{
|
{
|
||||||
if (_host==_port)
|
if (_host==_port)
|
||||||
return null;
|
return null;
|
||||||
if (_raw[_host]=='[')
|
|
||||||
return new String(_raw,_host+1,_port-_host-2,_charset);
|
|
||||||
return new String(_raw,_host,_port-_host,_charset);
|
return new String(_raw,_host,_port-_host,_charset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -141,6 +141,7 @@ src=application/x-wais-source
|
||||||
sv4cpio=application/x-sv4cpio
|
sv4cpio=application/x-sv4cpio
|
||||||
sv4crc=application/x-sv4crc
|
sv4crc=application/x-sv4crc
|
||||||
svg=image/svg+xml
|
svg=image/svg+xml
|
||||||
|
svgz=image/svg+xml
|
||||||
swf=application/x-shockwave-flash
|
swf=application/x-shockwave-flash
|
||||||
t=application/x-troff
|
t=application/x-troff
|
||||||
tar=application/x-tar
|
tar=application/x-tar
|
||||||
|
|
|
@ -27,10 +27,6 @@ import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
import org.eclipse.jetty.util.BufferUtil;
|
||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
|
|
@ -1294,7 +1294,7 @@ public class HttpParserTest
|
||||||
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
|
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
|
||||||
HttpParser parser= new HttpParser(handler);
|
HttpParser parser= new HttpParser(handler);
|
||||||
parser.parseNext(buffer);
|
parser.parseNext(buffer);
|
||||||
assertEquals("::1",_host);
|
assertEquals("[::1]",_host);
|
||||||
assertEquals(0,_port);
|
assertEquals(0,_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1372,7 +1372,7 @@ public class HttpParserTest
|
||||||
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
|
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
|
||||||
HttpParser parser= new HttpParser(handler);
|
HttpParser parser= new HttpParser(handler);
|
||||||
parser.parseNext(buffer);
|
parser.parseNext(buffer);
|
||||||
assertEquals("::1",_host);
|
assertEquals("[::1]",_host);
|
||||||
assertEquals(8888,_port);
|
assertEquals(8888,_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,9 +33,9 @@ public class HttpURITest
|
||||||
{
|
{
|
||||||
{"/path/to/context",null,null,"-1","/path/to/context",null,null,null},
|
{"/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://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://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
|
public static int
|
||||||
|
|
|
@ -124,7 +124,8 @@ public abstract class AbstractConnection implements Connection
|
||||||
*/
|
*/
|
||||||
public void fillInterested()
|
public void fillInterested()
|
||||||
{
|
{
|
||||||
LOG.debug("fillInterested {}",this);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("fillInterested {}",this);
|
||||||
|
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
|
@ -136,7 +137,8 @@ public abstract class AbstractConnection implements Connection
|
||||||
|
|
||||||
public void fillInterested(Callback callback)
|
public void fillInterested(Callback callback)
|
||||||
{
|
{
|
||||||
LOG.debug("fillInterested {}",this);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("fillInterested {}",this);
|
||||||
|
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
|
@ -162,7 +164,8 @@ public abstract class AbstractConnection implements Connection
|
||||||
*/
|
*/
|
||||||
protected void onFillInterestedFailed(Throwable cause)
|
protected void onFillInterestedFailed(Throwable cause)
|
||||||
{
|
{
|
||||||
LOG.debug("{} onFillInterestedFailed {}", this, cause);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("{} onFillInterestedFailed {}", this, cause);
|
||||||
if (_endPoint.isOpen())
|
if (_endPoint.isOpen())
|
||||||
{
|
{
|
||||||
boolean close = true;
|
boolean close = true;
|
||||||
|
@ -193,7 +196,8 @@ public abstract class AbstractConnection implements Connection
|
||||||
@Override
|
@Override
|
||||||
public void onOpen()
|
public void onOpen()
|
||||||
{
|
{
|
||||||
LOG.debug("onOpen {}", this);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("onOpen {}", this);
|
||||||
|
|
||||||
for (Listener listener : listeners)
|
for (Listener listener : listeners)
|
||||||
listener.onOpened(this);
|
listener.onOpened(this);
|
||||||
|
@ -202,7 +206,8 @@ public abstract class AbstractConnection implements Connection
|
||||||
@Override
|
@Override
|
||||||
public void onClose()
|
public void onClose()
|
||||||
{
|
{
|
||||||
LOG.debug("onClose {}",this);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("onClose {}",this);
|
||||||
|
|
||||||
for (Listener listener : listeners)
|
for (Listener listener : listeners)
|
||||||
listener.onClosed(this);
|
listener.onClosed(this);
|
||||||
|
@ -262,7 +267,8 @@ public abstract class AbstractConnection implements Connection
|
||||||
return true;
|
return true;
|
||||||
if(_state.compareAndSet(state,next))
|
if(_state.compareAndSet(state,next))
|
||||||
{
|
{
|
||||||
LOG.debug("{}-->{} {}",state,next,this);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("{}-->{} {}",state,next,this);
|
||||||
if (next!=state)
|
if (next!=state)
|
||||||
next.onEnter(AbstractConnection.this);
|
next.onEnter(AbstractConnection.this);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -94,7 +94,8 @@ public abstract class AbstractEndPoint extends IdleTimeout implements EndPoint
|
||||||
@Override
|
@Override
|
||||||
public void onOpen()
|
public void onOpen()
|
||||||
{
|
{
|
||||||
LOG.debug("onOpen {}",this);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("onOpen {}",this);
|
||||||
super.onOpen();
|
super.onOpen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +103,8 @@ public abstract class AbstractEndPoint extends IdleTimeout implements EndPoint
|
||||||
public void onClose()
|
public void onClose()
|
||||||
{
|
{
|
||||||
super.onClose();
|
super.onClose();
|
||||||
LOG.debug("onClose {}",this);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("onClose {}",this);
|
||||||
_writeFlusher.onClose();
|
_writeFlusher.onClose();
|
||||||
_fillInterest.onClose();
|
_fillInterest.onClose();
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,8 @@ public class ChannelEndPoint extends AbstractEndPoint
|
||||||
|
|
||||||
protected void shutdownInput()
|
protected void shutdownInput()
|
||||||
{
|
{
|
||||||
LOG.debug("ishut {}", this);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("ishut {}", this);
|
||||||
_ishut=true;
|
_ishut=true;
|
||||||
if (_oshut)
|
if (_oshut)
|
||||||
close();
|
close();
|
||||||
|
@ -70,7 +71,8 @@ public class ChannelEndPoint extends AbstractEndPoint
|
||||||
@Override
|
@Override
|
||||||
public void shutdownOutput()
|
public void shutdownOutput()
|
||||||
{
|
{
|
||||||
LOG.debug("oshut {}", this);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("oshut {}", this);
|
||||||
_oshut = true;
|
_oshut = true;
|
||||||
if (_channel.isOpen())
|
if (_channel.isOpen())
|
||||||
{
|
{
|
||||||
|
@ -109,7 +111,8 @@ public class ChannelEndPoint extends AbstractEndPoint
|
||||||
public void close()
|
public void close()
|
||||||
{
|
{
|
||||||
super.close();
|
super.close();
|
||||||
LOG.debug("close {}", this);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("close {}", this);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_channel.close();
|
_channel.close();
|
||||||
|
|
|
@ -20,8 +20,6 @@ package org.eclipse.jetty.io;
|
||||||
|
|
||||||
import java.io.Closeable;
|
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
|
* <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>
|
* 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 java.nio.channels.WritePendingException;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.Callback;
|
import org.eclipse.jetty.util.Callback;
|
||||||
import org.eclipse.jetty.util.FutureCallback;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
|
@ -142,13 +142,15 @@ public abstract class IdleTimeout
|
||||||
long idleElapsed = System.currentTimeMillis() - idleTimestamp;
|
long idleElapsed = System.currentTimeMillis() - idleTimestamp;
|
||||||
long idleLeft = idleTimeout - idleElapsed;
|
long idleLeft = idleTimeout - idleElapsed;
|
||||||
|
|
||||||
LOG.debug("{} idle timeout check, elapsed: {} ms, remaining: {} ms", this, idleElapsed, idleLeft);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("{} idle timeout check, elapsed: {} ms, remaining: {} ms", this, idleElapsed, idleLeft);
|
||||||
|
|
||||||
if (idleTimestamp != 0 && idleTimeout > 0)
|
if (idleTimestamp != 0 && idleTimeout > 0)
|
||||||
{
|
{
|
||||||
if (idleLeft <= 0)
|
if (idleLeft <= 0)
|
||||||
{
|
{
|
||||||
LOG.debug("{} idle timeout expired", this);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("{} idle timeout expired", this);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
onIdleExpired(new TimeoutException("Idle timeout expired: " + idleElapsed + "/" + idleTimeout + " ms"));
|
onIdleExpired(new TimeoutException("Idle timeout expired: " + idleElapsed + "/" + idleTimeout + " ms"));
|
||||||
|
|
|
@ -25,7 +25,6 @@ import java.nio.channels.SelectionKey;
|
||||||
import java.nio.channels.SocketChannel;
|
import java.nio.channels.SocketChannel;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.util.thread.Scheduler;
|
import org.eclipse.jetty.util.thread.Scheduler;
|
||||||
|
|
|
@ -132,18 +132,21 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements SelectorMa
|
||||||
{
|
{
|
||||||
if (_interestOps.compareAndSet(oldInterestOps, newInterestOps))
|
if (_interestOps.compareAndSet(oldInterestOps, newInterestOps))
|
||||||
{
|
{
|
||||||
LOG.debug("Local interests updated {} -> {} for {}", oldInterestOps, newInterestOps, this);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Local interests updated {} -> {} for {}", oldInterestOps, newInterestOps, this);
|
||||||
_selector.updateKey(_updateTask);
|
_selector.updateKey(_updateTask);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG.debug("Local interests update conflict: now {}, was {}, attempted {} for {}", _interestOps.get(), oldInterestOps, newInterestOps, this);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Local interests update conflict: now {}, was {}, attempted {} for {}", _interestOps.get(), oldInterestOps, newInterestOps, this);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG.debug("Ignoring local interests update {} -> {} for {}", oldInterestOps, newInterestOps, this);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Ignoring local interests update {} -> {} for {}", oldInterestOps, newInterestOps, this);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -152,7 +155,8 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements SelectorMa
|
||||||
|
|
||||||
private void setKeyInterests(int oldInterestOps, int newInterestOps)
|
private void setKeyInterests(int oldInterestOps, int newInterestOps)
|
||||||
{
|
{
|
||||||
LOG.debug("Key interests updated {} -> {}", oldInterestOps, newInterestOps);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Key interests updated {} -> {}", oldInterestOps, newInterestOps);
|
||||||
_key.interestOps(newInterestOps);
|
_key.interestOps(newInterestOps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,6 @@ package org.eclipse.jetty.io;
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.ConnectException;
|
import java.net.ConnectException;
|
||||||
import java.net.Socket;
|
|
||||||
import java.net.SocketAddress;
|
|
||||||
import java.net.SocketTimeoutException;
|
import java.net.SocketTimeoutException;
|
||||||
import java.nio.channels.CancelledKeyException;
|
import java.nio.channels.CancelledKeyException;
|
||||||
import java.nio.channels.SelectionKey;
|
import java.nio.channels.SelectionKey;
|
||||||
|
@ -377,11 +375,13 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
|
||||||
@Override
|
@Override
|
||||||
protected void doStop() throws Exception
|
protected void doStop() throws Exception
|
||||||
{
|
{
|
||||||
LOG.debug("Stopping {}", this);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Stopping {}", this);
|
||||||
Stop stop = new Stop();
|
Stop stop = new Stop();
|
||||||
submit(stop);
|
submit(stop);
|
||||||
stop.await(getStopTimeout());
|
stop.await(getStopTimeout());
|
||||||
LOG.debug("Stopped {}", this);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Stopped {}", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -419,7 +419,8 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
|
||||||
// change to the queue and process the state.
|
// change to the queue and process the state.
|
||||||
|
|
||||||
_changes.offer(change);
|
_changes.offer(change);
|
||||||
LOG.debug("Queued change {}", change);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Queued change {}", change);
|
||||||
|
|
||||||
out: while (true)
|
out: while (true)
|
||||||
{
|
{
|
||||||
|
@ -463,7 +464,8 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
LOG.debug("Running change {}", change);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Running change {}", change);
|
||||||
change.run();
|
change.run();
|
||||||
}
|
}
|
||||||
catch (Throwable x)
|
catch (Throwable x)
|
||||||
|
@ -480,14 +482,17 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_thread.setName(name + "-selector-" + SelectorManager.this.getClass().getSimpleName()+"@"+Integer.toHexString(SelectorManager.this.hashCode())+"/"+_id);
|
_thread.setName(name + "-selector-" + SelectorManager.this.getClass().getSimpleName()+"@"+Integer.toHexString(SelectorManager.this.hashCode())+"/"+_id);
|
||||||
LOG.debug("Starting {} on {}", _thread, this);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Starting {} on {}", _thread, this);
|
||||||
while (isRunning())
|
while (isRunning())
|
||||||
select();
|
select();
|
||||||
runChanges();
|
while(isStopping())
|
||||||
|
runChanges();
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
LOG.debug("Stopped {} on {}", _thread, this);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Stopped {} on {}", _thread, this);
|
||||||
_thread.setName(name);
|
_thread.setName(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -671,13 +676,15 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
|
||||||
Connection connection = newConnection(channel, endPoint, selectionKey.attachment());
|
Connection connection = newConnection(channel, endPoint, selectionKey.attachment());
|
||||||
endPoint.setConnection(connection);
|
endPoint.setConnection(connection);
|
||||||
connectionOpened(connection);
|
connectionOpened(connection);
|
||||||
LOG.debug("Created {}", endPoint);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Created {}", endPoint);
|
||||||
return endPoint;
|
return endPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void destroyEndPoint(EndPoint endPoint)
|
public void destroyEndPoint(EndPoint endPoint)
|
||||||
{
|
{
|
||||||
LOG.debug("Destroyed {}", endPoint);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Destroyed {}", endPoint);
|
||||||
Connection connection = endPoint.getConnection();
|
Connection connection = endPoint.getConnection();
|
||||||
if (connection != null)
|
if (connection != null)
|
||||||
connectionClosed(connection);
|
connectionClosed(connection);
|
||||||
|
@ -792,7 +799,8 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
SelectionKey key = _channel.register(_selector, SelectionKey.OP_ACCEPT, null);
|
SelectionKey key = _channel.register(_selector, SelectionKey.OP_ACCEPT, null);
|
||||||
LOG.debug("{} acceptor={}", this, key);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("{} acceptor={}", this, key);
|
||||||
}
|
}
|
||||||
catch (Throwable x)
|
catch (Throwable x)
|
||||||
{
|
{
|
||||||
|
@ -881,7 +889,8 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
|
||||||
SocketChannel channel = connect.channel;
|
SocketChannel channel = connect.channel;
|
||||||
if (channel.isConnectionPending())
|
if (channel.isConnectionPending())
|
||||||
{
|
{
|
||||||
LOG.debug("Channel {} timed out while connecting, closing it", channel);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Channel {} timed out while connecting, closing it", channel);
|
||||||
connect.failed(new SocketTimeoutException());
|
connect.failed(new SocketTimeoutException());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,7 +129,8 @@ public class UncheckedPrintWriter extends PrintWriter
|
||||||
_ioException.initCause(th);
|
_ioException.initCause(th);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG.debug(th);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug(th);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,6 @@ import org.eclipse.jetty.io.EndPoint;
|
||||||
import org.eclipse.jetty.io.EofException;
|
import org.eclipse.jetty.io.EofException;
|
||||||
import org.eclipse.jetty.io.FillInterest;
|
import org.eclipse.jetty.io.FillInterest;
|
||||||
import org.eclipse.jetty.io.RuntimeIOException;
|
import org.eclipse.jetty.io.RuntimeIOException;
|
||||||
import org.eclipse.jetty.io.SelectChannelEndPoint;
|
|
||||||
import org.eclipse.jetty.io.WriteFlusher;
|
import org.eclipse.jetty.io.WriteFlusher;
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
import org.eclipse.jetty.util.BufferUtil;
|
||||||
import org.eclipse.jetty.util.Callback;
|
import org.eclipse.jetty.util.Callback;
|
||||||
|
@ -820,7 +819,6 @@ public class SslConnection extends AbstractConnection
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
getEndPoint().close();
|
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
|
|
@ -210,7 +210,7 @@ public class JAASLoginService extends AbstractLifeCycle implements LoginService
|
||||||
}
|
}
|
||||||
else if (callback instanceof RequestParameterCallback)
|
else if (callback instanceof RequestParameterCallback)
|
||||||
{
|
{
|
||||||
HttpChannel channel = HttpChannel.getCurrentHttpChannel();
|
HttpChannel channel = HttpChannel.getCurrentHttpChannel();
|
||||||
|
|
||||||
if (channel == null)
|
if (channel == null)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -92,6 +92,9 @@ public class FormAuthModule extends BaseAuthModule
|
||||||
setErrorPage(errorPage);
|
setErrorPage(errorPage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
public FormAuthModule(CallbackHandler callbackHandler, CrossContextPsuedoSession<UserInfo> ssoSource,
|
public FormAuthModule(CallbackHandler callbackHandler, CrossContextPsuedoSession<UserInfo> ssoSource,
|
||||||
String loginPage, String errorPage)
|
String loginPage, String errorPage)
|
||||||
{
|
{
|
||||||
|
|
|
@ -82,23 +82,23 @@ public class ConnectorServer extends AbstractLifeCycle
|
||||||
public ConnectorServer(JMXServiceURL svcUrl, Map<String,?> environment, String name)
|
public ConnectorServer(JMXServiceURL svcUrl, Map<String,?> environment, String name)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
String urlPath = svcUrl.getURLPath();
|
String urlPath = svcUrl.getURLPath();
|
||||||
int idx = urlPath.indexOf("rmi://");
|
int idx = urlPath.indexOf("rmi://");
|
||||||
if (idx > 0)
|
if (idx > 0)
|
||||||
{
|
{
|
||||||
String hostPort = urlPath.substring(idx+6, urlPath.indexOf('/', idx+6));
|
String hostPort = urlPath.substring(idx+6, urlPath.indexOf('/', idx+6));
|
||||||
String regHostPort = startRegistry(hostPort);
|
String regHostPort = startRegistry(hostPort);
|
||||||
if (regHostPort != null) {
|
if (regHostPort != null) {
|
||||||
urlPath = urlPath.replace(hostPort,regHostPort);
|
urlPath = urlPath.replace(hostPort,regHostPort);
|
||||||
svcUrl = new JMXServiceURL(svcUrl.getProtocol(), svcUrl.getHost(), svcUrl.getPort(), urlPath);
|
svcUrl = new JMXServiceURL(svcUrl.getProtocol(), svcUrl.getHost(), svcUrl.getPort(), urlPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
|
MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
|
||||||
_connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(svcUrl, environment, mbeanServer);
|
_connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(svcUrl, environment, mbeanServer);
|
||||||
mbeanServer.registerMBean(_connectorServer,new ObjectName(name));
|
mbeanServer.registerMBean(_connectorServer,new ObjectName(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
|
* @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -128,7 +128,8 @@ public class MBeanContainer implements Container.InheritedListener, Dumpable
|
||||||
@Override
|
@Override
|
||||||
public void beanAdded(Container parent, Object obj)
|
public void beanAdded(Container parent, Object obj)
|
||||||
{
|
{
|
||||||
LOG.debug("beanAdded {}->{}",parent,obj);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("beanAdded {}->{}",parent,obj);
|
||||||
|
|
||||||
// Is their an object name for the parent
|
// Is their an object name for the parent
|
||||||
ObjectName pname=null;
|
ObjectName pname=null;
|
||||||
|
@ -206,7 +207,8 @@ public class MBeanContainer implements Container.InheritedListener, Dumpable
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectInstance oinstance = _mbeanServer.registerMBean(mbean, oname);
|
ObjectInstance oinstance = _mbeanServer.registerMBean(mbean, oname);
|
||||||
LOG.debug("Registered {}", oinstance.getObjectName());
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Registered {}", oinstance.getObjectName());
|
||||||
_beans.put(obj, oinstance.getObjectName());
|
_beans.put(obj, oinstance.getObjectName());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -219,7 +221,8 @@ public class MBeanContainer implements Container.InheritedListener, Dumpable
|
||||||
@Override
|
@Override
|
||||||
public void beanRemoved(Container parent, Object obj)
|
public void beanRemoved(Container parent, Object obj)
|
||||||
{
|
{
|
||||||
LOG.debug("beanRemoved {}",obj);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("beanRemoved {}",obj);
|
||||||
ObjectName bean = _beans.remove(obj);
|
ObjectName bean = _beans.remove(obj);
|
||||||
|
|
||||||
if (bean != null)
|
if (bean != null)
|
||||||
|
@ -227,7 +230,8 @@ public class MBeanContainer implements Container.InheritedListener, Dumpable
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_mbeanServer.unregisterMBean(bean);
|
_mbeanServer.unregisterMBean(bean);
|
||||||
LOG.debug("Unregistered {}", bean);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Unregistered {}", bean);
|
||||||
}
|
}
|
||||||
catch (javax.management.InstanceNotFoundException e)
|
catch (javax.management.InstanceNotFoundException e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -132,7 +132,8 @@ public class ObjectMBean implements DynamicMBean
|
||||||
{
|
{
|
||||||
Class<?> mClass = (Object.class.equals(oClass))?oClass=ObjectMBean.class:Loader.loadClass(oClass,mName);
|
Class<?> mClass = (Object.class.equals(oClass))?oClass=ObjectMBean.class:Loader.loadClass(oClass,mName);
|
||||||
|
|
||||||
LOG.debug("ObjectMbean: mbeanFor {} mClass={}", o, mClass);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("ObjectMbean: mbeanFor {} mClass={}", o, mClass);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -149,7 +150,8 @@ public class ObjectMBean implements DynamicMBean
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG.debug("mbeanFor {} is {}", o, mbean);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("mbeanFor {} is {}", o, mbean);
|
||||||
|
|
||||||
return mbean;
|
return mbean;
|
||||||
}
|
}
|
||||||
|
@ -241,7 +243,8 @@ public class ObjectMBean implements DynamicMBean
|
||||||
Class<?> o_class=_managed.getClass();
|
Class<?> o_class=_managed.getClass();
|
||||||
List<Class<?>> influences = findInfluences(new ArrayList<Class<?>>(), _managed.getClass());
|
List<Class<?>> influences = findInfluences(new ArrayList<Class<?>>(), _managed.getClass());
|
||||||
|
|
||||||
LOG.debug("Influence Count: {}", influences.size() );
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Influence Count: {}", influences.size() );
|
||||||
|
|
||||||
// Process Type Annotations
|
// Process Type Annotations
|
||||||
ManagedObject primary = o_class.getAnnotation( ManagedObject.class);
|
ManagedObject primary = o_class.getAnnotation( ManagedObject.class);
|
||||||
|
@ -252,7 +255,8 @@ public class ObjectMBean implements DynamicMBean
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG.debug("No @ManagedObject declared on {}", _managed.getClass());
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("No @ManagedObject declared on {}", _managed.getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -263,10 +267,13 @@ public class ObjectMBean implements DynamicMBean
|
||||||
|
|
||||||
ManagedObject typeAnnotation = oClass.getAnnotation( ManagedObject.class );
|
ManagedObject typeAnnotation = oClass.getAnnotation( ManagedObject.class );
|
||||||
|
|
||||||
LOG.debug("Influenced by: " + oClass.getCanonicalName() );
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Influenced by: " + oClass.getCanonicalName() );
|
||||||
|
|
||||||
if ( typeAnnotation == null )
|
if ( typeAnnotation == null )
|
||||||
{
|
{
|
||||||
LOG.debug("Annotations not found for: {}", oClass.getCanonicalName() );
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Annotations not found for: {}", oClass.getCanonicalName() );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,7 +286,8 @@ public class ObjectMBean implements DynamicMBean
|
||||||
if (methodAttributeAnnotation != null)
|
if (methodAttributeAnnotation != null)
|
||||||
{
|
{
|
||||||
// TODO sort out how a proper name could get here, its a method name as an attribute at this point.
|
// TODO sort out how a proper name could get here, its a method name as an attribute at this point.
|
||||||
LOG.debug("Attribute Annotation found for: {}", method.getName());
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Attribute Annotation found for: {}", method.getName());
|
||||||
MBeanAttributeInfo mai = defineAttribute(method,methodAttributeAnnotation);
|
MBeanAttributeInfo mai = defineAttribute(method,methodAttributeAnnotation);
|
||||||
if ( mai != null )
|
if ( mai != null )
|
||||||
{
|
{
|
||||||
|
@ -291,9 +299,9 @@ public class ObjectMBean implements DynamicMBean
|
||||||
|
|
||||||
if (methodOperationAnnotation != null)
|
if (methodOperationAnnotation != null)
|
||||||
{
|
{
|
||||||
LOG.debug("Method Annotation found for: {}", method.getName());
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Method Annotation found for: {}", method.getName());
|
||||||
MBeanOperationInfo oi = defineOperation(method,methodOperationAnnotation);
|
MBeanOperationInfo oi = defineOperation(method,methodOperationAnnotation);
|
||||||
|
|
||||||
if (oi != null)
|
if (oi != null)
|
||||||
{
|
{
|
||||||
operations.add(oi);
|
operations.add(oi);
|
||||||
|
@ -480,7 +488,8 @@ public class ObjectMBean implements DynamicMBean
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
public AttributeList setAttributes(AttributeList attrs)
|
public AttributeList setAttributes(AttributeList attrs)
|
||||||
{
|
{
|
||||||
LOG.debug("setAttributes");
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("setAttributes");
|
||||||
|
|
||||||
AttributeList results = new AttributeList(attrs.size());
|
AttributeList results = new AttributeList(attrs.size());
|
||||||
Iterator<Object> iter = attrs.iterator();
|
Iterator<Object> iter = attrs.iterator();
|
||||||
|
@ -503,7 +512,8 @@ public class ObjectMBean implements DynamicMBean
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
public Object invoke(String name, Object[] params, String[] signature) throws MBeanException, ReflectionException
|
public Object invoke(String name, Object[] params, String[] signature) throws MBeanException, ReflectionException
|
||||||
{
|
{
|
||||||
LOG.debug("ObjectMBean:invoke " + name);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("ObjectMBean:invoke " + name);
|
||||||
|
|
||||||
String methodKey = name + "(";
|
String methodKey = name + "(";
|
||||||
if (signature != null)
|
if (signature != null)
|
||||||
|
@ -562,12 +572,14 @@ public class ObjectMBean implements DynamicMBean
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Class<?> mbeanClazz = Class.forName(mName);
|
Class<?> mbeanClazz = Class.forName(mName);
|
||||||
LOG.debug("MBean Influence found for " + aClass.getSimpleName());
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("MBean Influence found for " + aClass.getSimpleName());
|
||||||
influences.add(mbeanClazz);
|
influences.add(mbeanClazz);
|
||||||
}
|
}
|
||||||
catch (ClassNotFoundException cnfe)
|
catch (ClassNotFoundException cnfe)
|
||||||
{
|
{
|
||||||
LOG.debug("No MBean Influence for " + aClass.getSimpleName());
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("No MBean Influence for " + aClass.getSimpleName());
|
||||||
}
|
}
|
||||||
|
|
||||||
// So are the super classes
|
// So are the super classes
|
||||||
|
@ -637,7 +649,8 @@ public class ObjectMBean implements DynamicMBean
|
||||||
String uName = name.substring(0, 1).toUpperCase(Locale.ENGLISH) + name.substring(1);
|
String uName = name.substring(0, 1).toUpperCase(Locale.ENGLISH) + name.substring(1);
|
||||||
Class<?> oClass = onMBean ? this.getClass() : _managed.getClass();
|
Class<?> oClass = onMBean ? this.getClass() : _managed.getClass();
|
||||||
|
|
||||||
LOG.debug("defineAttribute {} {}:{}:{}:{}",name,onMBean,readonly,oClass,description);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("defineAttribute {} {}:{}:{}:{}",name,onMBean,readonly,oClass,description);
|
||||||
|
|
||||||
Method setter = null;
|
Method setter = null;
|
||||||
|
|
||||||
|
@ -646,7 +659,9 @@ public class ObjectMBean implements DynamicMBean
|
||||||
{
|
{
|
||||||
String declaredSetter = attributeAnnotation.setter();
|
String declaredSetter = attributeAnnotation.setter();
|
||||||
|
|
||||||
LOG.debug("DeclaredSetter: {}", declaredSetter);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("DeclaredSetter: {}", declaredSetter);
|
||||||
|
|
||||||
Method[] methods = oClass.getMethods();
|
Method[] methods = oClass.getMethods();
|
||||||
for (int m = 0; m < methods.length; m++)
|
for (int m = 0; m < methods.length; m++)
|
||||||
{
|
{
|
||||||
|
@ -670,7 +685,8 @@ public class ObjectMBean implements DynamicMBean
|
||||||
LOG.warn("Type conflict for mbean attr {} in {}", name, oClass);
|
LOG.warn("Type conflict for mbean attr {} in {}", name, oClass);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
LOG.debug("Declared Setter: " + declaredSetter);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Declared Setter: " + declaredSetter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -696,16 +712,17 @@ public class ObjectMBean implements DynamicMBean
|
||||||
{
|
{
|
||||||
if (component_type==null)
|
if (component_type==null)
|
||||||
{
|
{
|
||||||
LOG.warn("No mbean type for {} on {}", name, _managed.getClass());
|
LOG.warn("No mbean type for {} on {}", name, _managed.getClass());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (component_type.isPrimitive() && !component_type.isArray())
|
if (component_type.isPrimitive() && !component_type.isArray())
|
||||||
{
|
{
|
||||||
LOG.warn("Cannot convert mbean primative {}", name);
|
LOG.warn("Cannot convert mbean primative {}", name);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
LOG.debug("passed convert checks {} for type {}", name, component_type);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("passed convert checks {} for type {}", name, component_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
|
@ -772,7 +789,8 @@ public class ObjectMBean implements DynamicMBean
|
||||||
|
|
||||||
if ( returnType.isArray() )
|
if ( returnType.isArray() )
|
||||||
{
|
{
|
||||||
LOG.debug("returnType is array, get component type");
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("returnType is array, get component type");
|
||||||
returnType = returnType.getComponentType();
|
returnType = returnType.getComponentType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -783,8 +801,8 @@ public class ObjectMBean implements DynamicMBean
|
||||||
|
|
||||||
String impactName = methodAnnotation.impact();
|
String impactName = methodAnnotation.impact();
|
||||||
|
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("defineOperation {} {}:{}:{}", method.getName(), onMBean, impactName, description);
|
LOG.debug("defineOperation {} {}:{}:{}", method.getName(), onMBean, impactName, description);
|
||||||
|
|
||||||
String signature = method.getName();
|
String signature = method.getName();
|
||||||
|
|
||||||
|
@ -836,7 +854,9 @@ public class ObjectMBean implements DynamicMBean
|
||||||
signature += ")";
|
signature += ")";
|
||||||
|
|
||||||
Class<?> returnClass = method.getReturnType();
|
Class<?> returnClass = method.getReturnType();
|
||||||
LOG.debug("Method Cache: " + signature );
|
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Method Cache: " + signature );
|
||||||
|
|
||||||
if ( _methods.containsKey(signature) )
|
if ( _methods.containsKey(signature) )
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,7 +24,6 @@ import java.sql.Statement;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
|
||||||
import org.eclipse.jetty.util.component.Destroyable;
|
import org.eclipse.jetty.util.component.Destroyable;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
|
|
|
@ -82,6 +82,21 @@ public class JspcMojo extends AbstractMojo
|
||||||
public static final String PRECOMPILED_FLAG = "org.eclipse.jetty.jsp.precompiled";
|
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>
|
* 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.
|
* Use WITH CAUTION as you may wind up with duplicate jars/classes.
|
||||||
|
@ -219,7 +234,7 @@ public class JspcMojo extends AbstractMojo
|
||||||
*
|
*
|
||||||
* @parameter
|
* @parameter
|
||||||
*/
|
*/
|
||||||
private JspC jspc;
|
private JettyJspC jspc;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -286,19 +301,22 @@ public class JspcMojo extends AbstractMojo
|
||||||
if (i+1<webAppUrls.size())
|
if (i+1<webAppUrls.size())
|
||||||
webAppClassPath.append(System.getProperty("path.separator"));
|
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)
|
if (jspc == null)
|
||||||
jspc = new JspC();
|
jspc = new JettyJspC();
|
||||||
|
|
||||||
jspc.setWebXmlFragment(webXmlFragment);
|
jspc.setWebXmlFragment(webXmlFragment);
|
||||||
jspc.setUriroot(webAppSourceDirectory);
|
jspc.setUriroot(webAppSourceDirectory);
|
||||||
jspc.setOutputDir(generatedClasses);
|
jspc.setOutputDir(generatedClasses);
|
||||||
jspc.setClassPath(sysClassPath+System.getProperty("path.separator")+webAppClassPath.toString());
|
jspc.setClassPath(sysClassPath+System.getProperty("path.separator")+webAppClassPath.toString());
|
||||||
|
jspc.setClassLoader(fakeWebAppClassLoader);
|
||||||
jspc.setCompile(true);
|
jspc.setCompile(true);
|
||||||
//jspc.setSystemClassPath(sysClassPath);
|
|
||||||
|
|
||||||
|
|
||||||
// JspC#setExtensions() does not exist, so
|
// JspC#setExtensions() does not exist, so
|
||||||
// always set concrete list of files that will be processed.
|
// always set concrete list of files that will be processed.
|
||||||
|
|
|
@ -80,6 +80,11 @@
|
||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
<artifactId>jetty-quickstart</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
<artifactId>jetty-jaas</artifactId>
|
<artifactId>jetty-jaas</artifactId>
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue