Merge branch 'master' into gcloud-session-manager
This commit is contained in:
commit
022f8e66f6
|
@ -828,14 +828,9 @@ public class AnnotationConfiguration extends AbstractConfiguration
|
|||
|
||||
/**
|
||||
* Get SCIs that are not excluded from consideration
|
||||
* @param context
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
/**
|
||||
* @param context
|
||||
* @return
|
||||
* @throws Exception
|
||||
* @param context the web app context
|
||||
* @return the list of non-excluded servlet container initializers
|
||||
* @throws Exception if unable to get list
|
||||
*/
|
||||
public List<ServletContainerInitializer> getNonExcludedInitializers (WebAppContext context)
|
||||
throws Exception
|
||||
|
|
|
@ -57,6 +57,7 @@ public class ScopeBasicsTest
|
|||
|
||||
/**
|
||||
* Validation of Scope / Inject logic on non-websocket-scoped classes
|
||||
* @throws Exception on test failure
|
||||
*/
|
||||
@Test
|
||||
public void testBasicBehavior() throws Exception
|
||||
|
|
|
@ -61,6 +61,7 @@ public class WebSocketScopeBaselineTest
|
|||
* Test behavior of {@link WebSocketScope} in basic operation.
|
||||
* <p>
|
||||
* Food is declared as part of WebSocketScope, and as such, only 1 instance of it can exist.
|
||||
* @throws Exception on test failure
|
||||
*/
|
||||
@Test
|
||||
public void testScopeBehavior() throws Exception
|
||||
|
|
|
@ -26,7 +26,6 @@ import java.util.concurrent.TimeUnit;
|
|||
import org.eclipse.jetty.client.api.Connection;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.api.Result;
|
||||
import org.eclipse.jetty.client.http.HttpConnectionOverHTTP;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
|
@ -119,7 +118,7 @@ public class HttpProxy extends ProxyConfiguration.Proxy
|
|||
{
|
||||
String message = String.format("Cannot perform requests over SSL, no %s in %s",
|
||||
SslContextFactory.class.getSimpleName(), HttpClient.class.getSimpleName());
|
||||
promise.failed(new IllegalStateException(message));
|
||||
tunnelFailed(new IllegalStateException(message));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -131,7 +130,7 @@ public class HttpProxy extends ProxyConfiguration.Proxy
|
|||
@Override
|
||||
public void failed(Throwable x)
|
||||
{
|
||||
promise.failed(x);
|
||||
tunnelFailed(x);
|
||||
}
|
||||
|
||||
private void tunnel(HttpDestination destination, final Connection connection)
|
||||
|
@ -139,33 +138,31 @@ public class HttpProxy extends ProxyConfiguration.Proxy
|
|||
String target = destination.getOrigin().getAddress().asString();
|
||||
Origin.Address proxyAddress = destination.getConnectAddress();
|
||||
HttpClient httpClient = destination.getHttpClient();
|
||||
long connectTimeout = httpClient.getConnectTimeout();
|
||||
Request connect = httpClient.newRequest(proxyAddress.getHost(), proxyAddress.getPort())
|
||||
.scheme(HttpScheme.HTTP.asString())
|
||||
.method(HttpMethod.CONNECT)
|
||||
.path(target)
|
||||
.header(HttpHeader.HOST, target)
|
||||
.timeout(httpClient.getConnectTimeout(), TimeUnit.MILLISECONDS);
|
||||
.idleTimeout(2 * connectTimeout, TimeUnit.MILLISECONDS)
|
||||
.timeout(connectTimeout, TimeUnit.MILLISECONDS);
|
||||
|
||||
connection.send(connect, new Response.CompleteListener()
|
||||
connection.send(connect, result ->
|
||||
{
|
||||
@Override
|
||||
public void onComplete(Result result)
|
||||
if (result.isFailed())
|
||||
{
|
||||
if (result.isFailed())
|
||||
tunnelFailed(result.getFailure());
|
||||
}
|
||||
else
|
||||
{
|
||||
Response response = result.getResponse();
|
||||
if (response.getStatus() == 200)
|
||||
{
|
||||
tunnelFailed(result.getFailure());
|
||||
tunnelSucceeded();
|
||||
}
|
||||
else
|
||||
{
|
||||
Response response = result.getResponse();
|
||||
if (response.getStatus() == 200)
|
||||
{
|
||||
tunnelSucceeded();
|
||||
}
|
||||
else
|
||||
{
|
||||
tunnelFailed(new HttpResponseException("Received " + response + " for " + result.getRequest(), response));
|
||||
}
|
||||
tunnelFailed(new HttpResponseException("Received " + response + " for " + result.getRequest(), response));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -198,7 +195,7 @@ public class HttpProxy extends ProxyConfiguration.Proxy
|
|||
private void tunnelFailed(Throwable failure)
|
||||
{
|
||||
endPoint.close();
|
||||
failed(failure);
|
||||
promise.failed(failure);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -168,11 +168,11 @@ public abstract class PoolingHttpDestination<C extends Connection> extends HttpD
|
|||
}
|
||||
|
||||
@Override
|
||||
public void close(Connection oldConnection)
|
||||
public void close(Connection connection)
|
||||
{
|
||||
super.close(oldConnection);
|
||||
super.close(connection);
|
||||
|
||||
connectionPool.remove(oldConnection);
|
||||
boolean removed = connectionPool.remove(connection);
|
||||
|
||||
if (getHttpExchanges().isEmpty())
|
||||
{
|
||||
|
@ -192,7 +192,8 @@ public abstract class PoolingHttpDestination<C extends Connection> extends HttpD
|
|||
// We need to execute queued requests even if this connection failed.
|
||||
// We may create a connection that is not needed, but it will eventually
|
||||
// idle timeout, so no worries.
|
||||
process();
|
||||
if (removed)
|
||||
process();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -77,19 +77,12 @@ public class InfinispanSessionIdManager extends AbstractSessionIdManager
|
|||
|
||||
|
||||
|
||||
/**
|
||||
* @param server
|
||||
*/
|
||||
public InfinispanSessionIdManager(Server server)
|
||||
{
|
||||
super();
|
||||
_server = server;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param server
|
||||
* @param random
|
||||
*/
|
||||
public InfinispanSessionIdManager(Server server, Random random)
|
||||
{
|
||||
super(random);
|
||||
|
@ -279,7 +272,7 @@ public class InfinispanSessionIdManager extends AbstractSessionIdManager
|
|||
|
||||
/**
|
||||
* Get the cache.
|
||||
* @return
|
||||
* @return the cache
|
||||
*/
|
||||
public BasicCache<String,Object> getCache()
|
||||
{
|
||||
|
@ -288,7 +281,7 @@ public class InfinispanSessionIdManager extends AbstractSessionIdManager
|
|||
|
||||
/**
|
||||
* Set the cache.
|
||||
* @param cache
|
||||
* @param cache the cache
|
||||
*/
|
||||
public void setCache(BasicCache<String,Object> cache)
|
||||
{
|
||||
|
@ -300,7 +293,7 @@ public class InfinispanSessionIdManager extends AbstractSessionIdManager
|
|||
/**
|
||||
* Do any operation to the session id in the cache to
|
||||
* ensure its idle expiry time moves forward
|
||||
* @param id
|
||||
* @param id the session id
|
||||
*/
|
||||
public void touch (String id)
|
||||
{
|
||||
|
@ -312,8 +305,8 @@ public class InfinispanSessionIdManager extends AbstractSessionIdManager
|
|||
/**
|
||||
* Ask the cluster if a particular id exists.
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
* @param id the session id
|
||||
* @return true if exists
|
||||
*/
|
||||
protected boolean exists (String id)
|
||||
{
|
||||
|
@ -327,7 +320,7 @@ public class InfinispanSessionIdManager extends AbstractSessionIdManager
|
|||
/**
|
||||
* Put a session id into the cluster.
|
||||
*
|
||||
* @param id
|
||||
* @param id the session id
|
||||
*/
|
||||
protected void insert (String id)
|
||||
{
|
||||
|
@ -341,7 +334,8 @@ public class InfinispanSessionIdManager extends AbstractSessionIdManager
|
|||
/**
|
||||
* Put a session id into the cluster with an idle expiry.
|
||||
*
|
||||
* @param id
|
||||
* @param id the session id
|
||||
* @param idleTimeOutSec idle timeout in seconds
|
||||
*/
|
||||
protected void insert (String id, long idleTimeOutSec)
|
||||
{
|
||||
|
@ -355,7 +349,7 @@ public class InfinispanSessionIdManager extends AbstractSessionIdManager
|
|||
/**
|
||||
* Remove a session id from the cluster.
|
||||
*
|
||||
* @param id
|
||||
* @param id the session id
|
||||
*/
|
||||
protected void delete (String id)
|
||||
{
|
||||
|
@ -370,8 +364,8 @@ public class InfinispanSessionIdManager extends AbstractSessionIdManager
|
|||
/**
|
||||
* Generate a unique cache key from the session id.
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
* @param id the session id
|
||||
* @return unique cache id
|
||||
*/
|
||||
protected String makeKey (String id)
|
||||
{
|
||||
|
|
|
@ -267,7 +267,7 @@ public class InfinispanSessionManager extends AbstractSessionManager
|
|||
/**
|
||||
* A new session.
|
||||
*
|
||||
* @param request
|
||||
* @param request the request
|
||||
*/
|
||||
protected Session (HttpServletRequest request)
|
||||
{
|
||||
|
@ -295,10 +295,10 @@ public class InfinispanSessionManager extends AbstractSessionManager
|
|||
/**
|
||||
* A restored session.
|
||||
*
|
||||
* @param sessionId
|
||||
* @param created
|
||||
* @param accessed
|
||||
* @param maxInterval
|
||||
* @param sessionId the session id
|
||||
* @param created time created
|
||||
* @param accessed time last accessed
|
||||
* @param maxInterval max expiry interval
|
||||
*/
|
||||
protected Session (String sessionId, long created, long accessed, long maxInterval)
|
||||
{
|
||||
|
@ -406,8 +406,8 @@ public class InfinispanSessionManager extends AbstractSessionManager
|
|||
}
|
||||
|
||||
/** Test if the session is stale
|
||||
* @param atTime
|
||||
* @return
|
||||
* @param atTime time when stale
|
||||
* @return true if stale
|
||||
*/
|
||||
protected boolean isStale (long atTime)
|
||||
{
|
||||
|
@ -416,7 +416,7 @@ public class InfinispanSessionManager extends AbstractSessionManager
|
|||
|
||||
|
||||
/** Test if the session is dirty
|
||||
* @return
|
||||
* @return true if dirty
|
||||
*/
|
||||
protected boolean isDirty ()
|
||||
{
|
||||
|
@ -711,7 +711,7 @@ public class InfinispanSessionManager extends AbstractSessionManager
|
|||
* often.
|
||||
*
|
||||
*
|
||||
* @param sec
|
||||
* @param sec scavenge interval in seconds
|
||||
*/
|
||||
public void setScavengeInterval (long sec)
|
||||
{
|
||||
|
@ -752,7 +752,7 @@ public class InfinispanSessionManager extends AbstractSessionManager
|
|||
/**
|
||||
* Get the clustered cache instance.
|
||||
*
|
||||
* @return
|
||||
* @return the cache
|
||||
*/
|
||||
public BasicCache<String, Object> getCache()
|
||||
{
|
||||
|
@ -764,7 +764,7 @@ public class InfinispanSessionManager extends AbstractSessionManager
|
|||
/**
|
||||
* Set the clustered cache instance.
|
||||
*
|
||||
* @param cache
|
||||
* @param cache the cache
|
||||
*/
|
||||
public void setCache (BasicCache<String, Object> cache)
|
||||
{
|
||||
|
@ -990,8 +990,8 @@ public class InfinispanSessionManager extends AbstractSessionManager
|
|||
/**
|
||||
* Load a session from the clustered cache.
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
* @param key the session key
|
||||
* @return the session
|
||||
*/
|
||||
protected Session load (String key)
|
||||
{
|
||||
|
@ -1019,8 +1019,8 @@ public class InfinispanSessionManager extends AbstractSessionManager
|
|||
/**
|
||||
* Save or update the session to the cluster cache
|
||||
*
|
||||
* @param session
|
||||
* @throws Exception
|
||||
* @param session the session
|
||||
* @throws Exception if unable to save
|
||||
*/
|
||||
protected void save (InfinispanSessionManager.Session session)
|
||||
throws Exception
|
||||
|
@ -1053,7 +1053,7 @@ public class InfinispanSessionManager extends AbstractSessionManager
|
|||
/**
|
||||
* Remove the session from the cluster cache.
|
||||
*
|
||||
* @param session
|
||||
* @param session the session
|
||||
*/
|
||||
protected void delete (InfinispanSessionManager.Session session)
|
||||
{
|
||||
|
@ -1067,7 +1067,7 @@ public class InfinispanSessionManager extends AbstractSessionManager
|
|||
/**
|
||||
* Invalidate a session for this context with the given id
|
||||
*
|
||||
* @param idInCluster
|
||||
* @param idInCluster session id in cluster
|
||||
*/
|
||||
public void invalidateSession (String idInCluster)
|
||||
{
|
||||
|
|
|
@ -564,7 +564,7 @@ public abstract class AbstractJettyMojo extends AbstractMojo
|
|||
* Run a scanner thread on the given list of files and directories, calling
|
||||
* stop/start on the given list of LifeCycle objects if any of the watched
|
||||
* files change.
|
||||
*
|
||||
* @throws Exception if unable to start scanner
|
||||
*/
|
||||
public void startScanner() throws Exception
|
||||
{
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
|
||||
package org.eclipse.jetty.proxy;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ConnectException;
|
||||
import java.net.Socket;
|
||||
|
@ -64,6 +62,8 @@ import org.junit.Ignore;
|
|||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class ProxyTunnellingTest
|
||||
{
|
||||
@Rule
|
||||
|
@ -278,6 +278,59 @@ public class ProxyTunnellingTest
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShortIdleTimeoutOverriddenByRequest() throws Exception
|
||||
{
|
||||
// Short idle timeout for HttpClient.
|
||||
long idleTimeout = 500;
|
||||
|
||||
startSSLServer(new ServerHandler());
|
||||
startProxy(new ConnectHandler()
|
||||
{
|
||||
@Override
|
||||
protected void handleConnect(Request baseRequest, HttpServletRequest request, HttpServletResponse response, String serverAddress)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Make sure the proxy remains idle enough.
|
||||
Thread.sleep(2 * idleTimeout);
|
||||
super.handleConnect(baseRequest, request, response, serverAddress);
|
||||
}
|
||||
catch (InterruptedException x)
|
||||
{
|
||||
onConnectFailure(request, response, null, x);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
HttpClient httpClient = new HttpClient(sslContextFactory);
|
||||
httpClient.getProxyConfiguration().getProxies().add(new HttpProxy("localhost", proxyPort()));
|
||||
// Short idle timeout for HttpClient.
|
||||
httpClient.setIdleTimeout(idleTimeout);
|
||||
httpClient.start();
|
||||
|
||||
try
|
||||
{
|
||||
String host = "localhost";
|
||||
String body = "BODY";
|
||||
ContentResponse response = httpClient.newRequest(host, serverConnector.getLocalPort())
|
||||
.scheme(HttpScheme.HTTPS.asString())
|
||||
.method(HttpMethod.GET)
|
||||
.path("/echo?body=" + URLEncoder.encode(body, "UTF-8"))
|
||||
// Long idle timeout for the request.
|
||||
.idleTimeout(10 * idleTimeout, TimeUnit.MILLISECONDS)
|
||||
.send();
|
||||
|
||||
assertEquals(HttpStatus.OK_200, response.getStatus());
|
||||
String content = response.getContentAsString();
|
||||
assertEquals(body, content);
|
||||
}
|
||||
finally
|
||||
{
|
||||
httpClient.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProxyDown() throws Exception
|
||||
{
|
||||
|
|
|
@ -88,6 +88,7 @@
|
|||
<Set name="headerCacheSize"><Property name="jetty.httpConfig.headerCacheSize" default="512" /></Set>
|
||||
<Set name="delayDispatchUntilContent"><Property name="jetty.httpConfig.delayDispatchUntilContent" deprecated="jetty.delayDispatchUntilContent" default="true"/></Set>
|
||||
<Set name="maxErrorDispatches"><Property name="jetty.httpConfig.maxErrorDispatches" default="10"/></Set>
|
||||
<Set name="blockingTimeout"><Property name="jetty.httpConfig.blockingTimeout" default="-1"/></Set>
|
||||
<!-- Uncomment to enable handling of X-Forwarded- style headers
|
||||
<Call name="addCustomizer">
|
||||
<Arg><New class="org.eclipse.jetty.server.ForwardedRequestCustomizer"/></Arg>
|
||||
|
|
|
@ -64,6 +64,9 @@ etc/jetty.xml
|
|||
## Maximum number of error dispatches to prevent looping
|
||||
# jetty.httpConfig.maxErrorDispatches=10
|
||||
|
||||
## Maximum time to block in total for a blocking IO operation (default -1 is to use idleTimeout on progress)
|
||||
# jetty.httpConfig.blockingTimeout=-1
|
||||
|
||||
### Server configuration
|
||||
## Whether ctrl+c on the console gracefully stops the Jetty server
|
||||
# jetty.server.stopAtShutdown=true
|
||||
|
@ -73,3 +76,4 @@ etc/jetty.xml
|
|||
|
||||
## Dump the state of the Jetty server, components, and webapps before shutdown
|
||||
# jetty.server.dumpBeforeStop=false
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
package org.eclipse.jetty.websocket.jsr356;
|
||||
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
import java.net.URI;
|
||||
import java.nio.ByteBuffer;
|
||||
|
@ -29,6 +29,7 @@ import javax.websocket.MessageHandler;
|
|||
|
||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||
import org.eclipse.jetty.websocket.common.events.EventDriver;
|
||||
import org.eclipse.jetty.websocket.common.test.DummyConnection;
|
||||
import org.eclipse.jetty.websocket.jsr356.client.EmptyClientEndpointConfig;
|
||||
import org.eclipse.jetty.websocket.jsr356.client.SimpleEndpointMetadata;
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.EndpointInstance;
|
||||
|
@ -37,7 +38,6 @@ import org.eclipse.jetty.websocket.jsr356.handlers.ByteArrayWholeHandler;
|
|||
import org.eclipse.jetty.websocket.jsr356.handlers.ByteBufferPartialHandler;
|
||||
import org.eclipse.jetty.websocket.jsr356.handlers.LongMessageHandler;
|
||||
import org.eclipse.jetty.websocket.jsr356.handlers.StringWholeHandler;
|
||||
import org.eclipse.jetty.websocket.jsr356.samples.DummyConnection;
|
||||
import org.eclipse.jetty.websocket.jsr356.samples.DummyEndpoint;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
|
|
|
@ -1,156 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2015 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.websocket.jsr356.samples;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import org.eclipse.jetty.io.ByteBufferPool;
|
||||
import org.eclipse.jetty.websocket.api.BatchMode;
|
||||
import org.eclipse.jetty.websocket.api.SuspendToken;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||
import org.eclipse.jetty.websocket.api.WriteCallback;
|
||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||
import org.eclipse.jetty.websocket.api.extensions.IncomingFrames;
|
||||
import org.eclipse.jetty.websocket.common.LogicalConnection;
|
||||
import org.eclipse.jetty.websocket.common.WebSocketSession;
|
||||
import org.eclipse.jetty.websocket.common.io.IOState;
|
||||
|
||||
public class DummyConnection implements LogicalConnection
|
||||
{
|
||||
private IOState iostate;
|
||||
|
||||
public DummyConnection()
|
||||
{
|
||||
this.iostate = new IOState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close(int statusCode, String reason)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBufferPool getBufferPool()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Executor getExecutor()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getIdleTimeout()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IOState getIOState()
|
||||
{
|
||||
return this.iostate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InetSocketAddress getLocalAddress()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMaxIdleTimeout()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebSocketPolicy getPolicy()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InetSocketAddress getRemoteAddress()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebSocketSession getSession()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpen()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReading()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void outgoingFrame(Frame frame, WriteCallback callback, BatchMode batchMode)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resume()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxIdleTimeout(long ms)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNextIncomingFrames(IncomingFrames incoming)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSession(WebSocketSession session)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public SuspendToken suspend()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -37,6 +37,7 @@ import org.eclipse.jetty.websocket.common.frames.ContinuationFrame;
|
|||
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
||||
import org.eclipse.jetty.websocket.common.scopes.SimpleContainerScope;
|
||||
import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope;
|
||||
import org.eclipse.jetty.websocket.common.test.DummyConnection;
|
||||
import org.eclipse.jetty.websocket.jsr356.ClientContainer;
|
||||
import org.eclipse.jetty.websocket.jsr356.JsrSession;
|
||||
import org.eclipse.jetty.websocket.jsr356.annotations.AnnotatedEndpointScanner;
|
||||
|
|
|
@ -47,8 +47,6 @@ public class QuoteUtil
|
|||
QUOTE_DOUBLE
|
||||
}
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
private final String input;
|
||||
private final String delims;
|
||||
private StringBuilder token;
|
||||
|
@ -83,14 +81,6 @@ public class QuoteUtil
|
|||
}
|
||||
}
|
||||
|
||||
private void debug(String format, Object... args)
|
||||
{
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.printf(format,args);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext()
|
||||
{
|
||||
|
@ -133,7 +123,7 @@ public class QuoteUtil
|
|||
{
|
||||
if (delims.indexOf(c) >= 0)
|
||||
{
|
||||
debug("hasNext/t: %b [%s]%n",hasToken,token);
|
||||
// System.out.printf("hasNext/t: %b [%s]%n",hasToken,token);
|
||||
return hasToken;
|
||||
}
|
||||
else if (c == '\'')
|
||||
|
@ -192,10 +182,9 @@ public class QuoteUtil
|
|||
break;
|
||||
}
|
||||
}
|
||||
debug("%s <%s> : [%s]%n",state,c,token);
|
||||
// System.out.printf("%s <%s> : [%s]%n",state,c,token);
|
||||
}
|
||||
|
||||
debug("hasNext/e: %b [%s]%n",hasToken,token);
|
||||
// System.out.printf("hasNext/e: %b [%s]%n",hasToken,token);
|
||||
return hasToken;
|
||||
}
|
||||
|
||||
|
|
|
@ -499,6 +499,7 @@ public class WebSocketClient extends ContainerLifeCycle implements SessionListen
|
|||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Session Opened: {}",session);
|
||||
addManaged(session);
|
||||
}
|
||||
|
||||
public void setAsyncWriteTimeout(long ms)
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
package org.eclipse.jetty.websocket.client.io;
|
||||
|
||||
import org.eclipse.jetty.util.FuturePromise;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.websocket.api.Session;
|
||||
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
|
||||
import org.eclipse.jetty.websocket.client.ClientUpgradeResponse;
|
||||
|
@ -32,12 +34,14 @@ import org.eclipse.jetty.websocket.common.events.EventDriver;
|
|||
*/
|
||||
public abstract class ConnectPromise extends FuturePromise<Session> implements Runnable
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(ConnectPromise.class);
|
||||
private final WebSocketClient client;
|
||||
private final EventDriver driver;
|
||||
private final ClientUpgradeRequest request;
|
||||
private final Masker masker;
|
||||
private UpgradeListener upgradeListener;
|
||||
private ClientUpgradeResponse response;
|
||||
private WebSocketSession session;
|
||||
|
||||
public ConnectPromise(WebSocketClient client, EventDriver driver, ClientUpgradeRequest request)
|
||||
{
|
||||
|
@ -97,11 +101,18 @@ public abstract class ConnectPromise extends FuturePromise<Session> implements R
|
|||
this.upgradeListener = upgradeListener;
|
||||
}
|
||||
|
||||
public void succeeded(WebSocketSession session)
|
||||
public void succeeded()
|
||||
{
|
||||
if(LOG.isDebugEnabled())
|
||||
LOG.debug("{}.succeeded()",this.getClass().getSimpleName());
|
||||
session.setUpgradeRequest(request);
|
||||
session.setUpgradeResponse(response);
|
||||
session.open();
|
||||
// session.open();
|
||||
super.succeeded(session);
|
||||
}
|
||||
|
||||
public void setSession(WebSocketSession session)
|
||||
{
|
||||
this.session = session;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,19 +23,13 @@ import java.net.InetSocketAddress;
|
|||
import java.net.SocketAddress;
|
||||
import java.net.URI;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Locale;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
|
||||
import org.eclipse.jetty.websocket.client.WebSocketClient;
|
||||
import org.eclipse.jetty.websocket.common.WebSocketSession;
|
||||
import org.eclipse.jetty.websocket.common.events.EventDriver;
|
||||
|
||||
/**
|
||||
|
@ -136,7 +130,6 @@ public class ConnectionManager extends ContainerLifeCycle
|
|||
return new InetSocketAddress(uri.getHost(),port);
|
||||
}
|
||||
|
||||
private final Queue<WebSocketSession> sessions = new ConcurrentLinkedQueue<>();
|
||||
private final WebSocketClient client;
|
||||
private WebSocketClientSelectorManager selector;
|
||||
|
||||
|
@ -145,31 +138,6 @@ public class ConnectionManager extends ContainerLifeCycle
|
|||
this.client = client;
|
||||
}
|
||||
|
||||
public void addSession(WebSocketSession session)
|
||||
{
|
||||
sessions.add(session);
|
||||
}
|
||||
|
||||
private void shutdownAllConnections()
|
||||
{
|
||||
for (WebSocketSession session : sessions)
|
||||
{
|
||||
if (session.getConnection() != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
session.getConnection().close(
|
||||
StatusCode.SHUTDOWN,
|
||||
"Shutdown");
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
LOG.debug("During Shutdown All Connections",t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ConnectPromise connect(WebSocketClient client, EventDriver driver, ClientUpgradeRequest request)
|
||||
{
|
||||
return new PhysicalConnect(client,driver,request);
|
||||
|
@ -189,8 +157,6 @@ public class ConnectionManager extends ContainerLifeCycle
|
|||
@Override
|
||||
protected void doStop() throws Exception
|
||||
{
|
||||
shutdownAllConnections();
|
||||
sessions.clear();
|
||||
super.doStop();
|
||||
removeBean(selector);
|
||||
}
|
||||
|
@ -200,11 +166,6 @@ public class ConnectionManager extends ContainerLifeCycle
|
|||
return selector;
|
||||
}
|
||||
|
||||
public Collection<WebSocketSession> getSessions()
|
||||
{
|
||||
return Collections.unmodifiableCollection(sessions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for new WebSocketClientSelectorManager (used by other projects like cometd)
|
||||
*
|
||||
|
@ -216,9 +177,4 @@ public class ConnectionManager extends ContainerLifeCycle
|
|||
{
|
||||
return new WebSocketClientSelectorManager(client);
|
||||
}
|
||||
|
||||
public void removeSession(WebSocketSession session)
|
||||
{
|
||||
sessions.remove(session);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -316,8 +316,8 @@ public class UpgradeConnection extends AbstractConnection implements Connection.
|
|||
WebSocketSession session = sessionFactory.createSession(request.getRequestURI(),websocket,connection);
|
||||
session.setPolicy(policy);
|
||||
session.setUpgradeResponse(response);
|
||||
|
||||
connection.setSession(session);
|
||||
connection.addListener(session);
|
||||
connectPromise.setSession(session);
|
||||
|
||||
// Initialize / Negotiate Extensions
|
||||
ExtensionStack extensionStack = new ExtensionStack(connectPromise.getClient().getExtensionFactory());
|
||||
|
@ -334,7 +334,7 @@ public class UpgradeConnection extends AbstractConnection implements Connection.
|
|||
session.setOutgoingHandler(extensionStack);
|
||||
extensionStack.setNextOutgoing(connection);
|
||||
|
||||
session.addBean(extensionStack);
|
||||
session.addManaged(extensionStack);
|
||||
connectPromise.getClient().addManaged(session);
|
||||
|
||||
// Now swap out the connection
|
||||
|
|
|
@ -30,7 +30,6 @@ import org.eclipse.jetty.websocket.api.extensions.Frame;
|
|||
import org.eclipse.jetty.websocket.api.extensions.IncomingFrames;
|
||||
import org.eclipse.jetty.websocket.client.masks.Masker;
|
||||
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
||||
import org.eclipse.jetty.websocket.common.WebSocketSession;
|
||||
import org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection;
|
||||
|
||||
/**
|
||||
|
@ -62,26 +61,15 @@ public class WebSocketClientConnection extends AbstractWebSocketConnection
|
|||
return getEndPoint().getRemoteAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose()
|
||||
{
|
||||
super.onClose();
|
||||
ConnectionManager connectionManager = connectPromise.getClient().getConnectionManager();
|
||||
connectionManager.removeSession(getSession());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpen()
|
||||
{
|
||||
super.onOpen();
|
||||
boolean beenOpened = opened.getAndSet(true);
|
||||
if (!beenOpened)
|
||||
{
|
||||
WebSocketSession session = getSession();
|
||||
ConnectionManager connectionManager = connectPromise.getClient().getConnectionManager();
|
||||
connectionManager.addSession(session);
|
||||
connectPromise.succeeded(session);
|
||||
connectPromise.succeeded();
|
||||
}
|
||||
super.onOpen();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.eclipse.jetty.websocket.client;
|
|||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
@ -81,7 +82,8 @@ public class SessionTest
|
|||
cliSock.assertWasOpened();
|
||||
cliSock.assertNotClosed();
|
||||
|
||||
Assert.assertThat("client.connectionManager.sessions.size",client.getConnectionManager().getSessions().size(),is(1));
|
||||
Collection<WebSocketSession> sessions = client.getBeans(WebSocketSession.class);
|
||||
Assert.assertThat("client.connectionManager.sessions.size",sessions.size(),is(1));
|
||||
|
||||
RemoteEndpoint remote = cliSock.getSession().getRemote();
|
||||
remote.sendStringByFuture("Hello World!");
|
||||
|
|
|
@ -18,14 +18,12 @@
|
|||
|
||||
package org.eclipse.jetty.websocket.client;
|
||||
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.URI;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Future;
|
||||
|
@ -37,6 +35,7 @@ import org.eclipse.jetty.websocket.api.BatchMode;
|
|||
import org.eclipse.jetty.websocket.api.RemoteEndpoint;
|
||||
import org.eclipse.jetty.websocket.api.Session;
|
||||
import org.eclipse.jetty.websocket.api.UpgradeRequest;
|
||||
import org.eclipse.jetty.websocket.common.WebSocketSession;
|
||||
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
||||
import org.eclipse.jetty.websocket.common.io.FutureWriteCallback;
|
||||
import org.eclipse.jetty.websocket.common.test.BlockheadServer;
|
||||
|
@ -118,7 +117,8 @@ public class WebSocketClientTest
|
|||
cliSock.assertWasOpened();
|
||||
cliSock.assertNotClosed();
|
||||
|
||||
Assert.assertThat("client.connectionManager.sessions.size",client.getConnectionManager().getSessions().size(),is(1));
|
||||
Collection<WebSocketSession> sessions = client.getBeans(WebSocketSession.class);
|
||||
Assert.assertThat("client.connectionManager.sessions.size",sessions.size(),is(1));
|
||||
|
||||
RemoteEndpoint remote = cliSock.getSession().getRemote();
|
||||
remote.sendStringByFuture("Hello World!");
|
||||
|
@ -164,7 +164,8 @@ public class WebSocketClientTest
|
|||
cliSock.assertWasOpened();
|
||||
cliSock.assertNotClosed();
|
||||
|
||||
Assert.assertThat("client.connectionManager.sessions.size",client.getConnectionManager().getSessions().size(),is(1));
|
||||
Collection<WebSocketSession> sessions = client.getBeans(WebSocketSession.class);
|
||||
Assert.assertThat("client.connectionManager.sessions.size",sessions.size(),is(1));
|
||||
|
||||
FutureWriteCallback callback = new FutureWriteCallback();
|
||||
|
||||
|
|
|
@ -115,13 +115,6 @@ public interface LogicalConnection extends OutgoingFrames, SuspendToken
|
|||
*/
|
||||
InetSocketAddress getRemoteAddress();
|
||||
|
||||
/**
|
||||
* Get the Session for this connection
|
||||
*
|
||||
* @return the Session for this connection
|
||||
*/
|
||||
WebSocketSession getSession();
|
||||
|
||||
/**
|
||||
* Test if logical connection is still open
|
||||
*
|
||||
|
@ -157,14 +150,6 @@ public interface LogicalConnection extends OutgoingFrames, SuspendToken
|
|||
*/
|
||||
void setNextIncomingFrames(IncomingFrames incoming);
|
||||
|
||||
/**
|
||||
* Set the session associated with this connection
|
||||
*
|
||||
* @param session
|
||||
* the session
|
||||
*/
|
||||
void setSession(WebSocketSession session);
|
||||
|
||||
/**
|
||||
* Suspend a the incoming read events on the connection.
|
||||
* @return the suspend token
|
||||
|
|
|
@ -28,6 +28,7 @@ import java.util.Objects;
|
|||
import java.util.concurrent.Executor;
|
||||
|
||||
import org.eclipse.jetty.io.ByteBufferPool;
|
||||
import org.eclipse.jetty.io.Connection;
|
||||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
||||
|
@ -58,13 +59,14 @@ import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope;
|
|||
import org.eclipse.jetty.websocket.common.scopes.WebSocketSessionScope;
|
||||
|
||||
@ManagedObject("A Jetty WebSocket Session")
|
||||
public class WebSocketSession extends ContainerLifeCycle implements Session, WebSocketSessionScope, IncomingFrames, ConnectionStateListener
|
||||
public class WebSocketSession extends ContainerLifeCycle implements Session, WebSocketSessionScope, IncomingFrames, Connection.Listener, ConnectionStateListener
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(WebSocketSession.class);
|
||||
private static final Logger LOG_OPEN = Log.getLogger(WebSocketSession.class.getName() + "_OPEN");
|
||||
private final WebSocketContainerScope containerScope;
|
||||
private final URI requestURI;
|
||||
private final EventDriver websocket;
|
||||
private final LogicalConnection connection;
|
||||
private final EventDriver websocket;
|
||||
private final SessionListener[] sessionListeners;
|
||||
private final Executor executor;
|
||||
private ClassLoader classLoader;
|
||||
|
@ -93,6 +95,9 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Web
|
|||
this.outgoingHandler = connection;
|
||||
this.incomingHandler = websocket;
|
||||
this.connection.getIOState().addListener(this);
|
||||
|
||||
addBean(this.connection);
|
||||
addBean(this.websocket);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -110,7 +115,7 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Web
|
|||
@Override
|
||||
public void close(int statusCode, String reason)
|
||||
{
|
||||
connection.close(statusCode,CloseStatus.trimMaxReasonLength(reason));
|
||||
connection.close(statusCode,reason);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -130,6 +135,35 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Web
|
|||
executor.execute(runnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStart() throws Exception
|
||||
{
|
||||
if(LOG.isDebugEnabled())
|
||||
LOG.debug("starting - {}",this);
|
||||
|
||||
super.doStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStop() throws Exception
|
||||
{
|
||||
if(LOG.isDebugEnabled())
|
||||
LOG.debug("stopping - {}",this);
|
||||
|
||||
if (getConnection() != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
getConnection().close(StatusCode.SHUTDOWN,"Shutdown");
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
LOG.debug("During Connection Shutdown",t);
|
||||
}
|
||||
}
|
||||
super.doStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(Appendable out, String indent) throws IOException
|
||||
{
|
||||
|
@ -253,6 +287,8 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Web
|
|||
@Override
|
||||
public RemoteEndpoint getRemote()
|
||||
{
|
||||
if(LOG_OPEN.isDebugEnabled())
|
||||
LOG_OPEN.debug("[{}] {}.getRemote()",policy.getBehavior(),this.getClass().getSimpleName());
|
||||
ConnectionState state = connection.getIOState().getConnectionState();
|
||||
|
||||
if ((state == ConnectionState.OPEN) || (state == ConnectionState.CONNECTED))
|
||||
|
@ -373,6 +409,19 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Web
|
|||
{
|
||||
incomingError(cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClosed(Connection connection)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpened(Connection connection)
|
||||
{
|
||||
if(LOG_OPEN.isDebugEnabled())
|
||||
LOG_OPEN.debug("[{}] {}.onOpened()",policy.getBehavior(),this.getClass().getSimpleName());
|
||||
open();
|
||||
}
|
||||
|
||||
@SuppressWarnings("incomplete-switch")
|
||||
@Override
|
||||
|
@ -381,6 +430,11 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Web
|
|||
switch (state)
|
||||
{
|
||||
case CLOSED:
|
||||
IOState ioState = this.connection.getIOState();
|
||||
CloseInfo close = ioState.getCloseInfo();
|
||||
// confirmed close of local endpoint
|
||||
notifyClose(close.getStatusCode(),close.getReason());
|
||||
|
||||
// notify session listeners
|
||||
for (SessionListener listener : sessionListeners)
|
||||
{
|
||||
|
@ -395,10 +449,6 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Web
|
|||
LOG.ignore(t);
|
||||
}
|
||||
}
|
||||
IOState ioState = this.connection.getIOState();
|
||||
CloseInfo close = ioState.getCloseInfo();
|
||||
// confirmed close of local endpoint
|
||||
notifyClose(close.getStatusCode(),close.getReason());
|
||||
break;
|
||||
case CONNECTED:
|
||||
// notify session listeners
|
||||
|
@ -418,12 +468,15 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Web
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Open/Activate the session
|
||||
*/
|
||||
public void open()
|
||||
{
|
||||
if(LOG_OPEN.isDebugEnabled())
|
||||
LOG_OPEN.debug("[{}] {}.open()",policy.getBehavior(),this.getClass().getSimpleName());
|
||||
|
||||
if (remote != null)
|
||||
{
|
||||
// already opened
|
||||
|
@ -437,6 +490,8 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Web
|
|||
|
||||
// Connect remote
|
||||
remote = new WebSocketRemoteEndpoint(connection,outgoingHandler,getBatchMode());
|
||||
if(LOG_OPEN.isDebugEnabled())
|
||||
LOG_OPEN.debug("[{}] {}.open() remote={}",policy.getBehavior(),this.getClass().getSimpleName(),remote);
|
||||
|
||||
// Open WebSocket
|
||||
websocket.openSession(this);
|
||||
|
@ -467,7 +522,7 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Web
|
|||
close(statusCode,t.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setExtensionFactory(ExtensionFactory extensionFactory)
|
||||
{
|
||||
this.extensionFactory = extensionFactory;
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.nio.ByteBuffer;
|
|||
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.Utf8Appendable.NotUtf8Exception;
|
||||
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.websocket.api.BatchMode;
|
||||
|
@ -40,11 +41,11 @@ import org.eclipse.jetty.websocket.common.message.MessageAppender;
|
|||
/**
|
||||
* EventDriver is the main interface between the User's WebSocket POJO and the internal jetty implementation of WebSocket.
|
||||
*/
|
||||
public abstract class AbstractEventDriver implements IncomingFrames, EventDriver
|
||||
public abstract class AbstractEventDriver extends AbstractLifeCycle implements IncomingFrames, EventDriver
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(AbstractEventDriver.class);
|
||||
protected final Logger TARGET_LOG;
|
||||
protected final WebSocketPolicy policy;
|
||||
protected WebSocketPolicy policy;
|
||||
protected final Object websocket;
|
||||
protected WebSocketSession session;
|
||||
protected MessageAppender activeMessage;
|
||||
|
@ -233,6 +234,12 @@ public abstract class AbstractEventDriver implements IncomingFrames, EventDriver
|
|||
throw t;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStop() throws Exception
|
||||
{
|
||||
session = null;
|
||||
}
|
||||
|
||||
protected void terminateConnection(int statusCode, String rawreason)
|
||||
{
|
||||
|
|
|
@ -55,7 +55,8 @@ public class CallableMethod
|
|||
|
||||
if (obj == null)
|
||||
{
|
||||
LOG.warn("Cannot call {} on null object",this.method);
|
||||
String err = String.format("Cannot call %s on null object", this.method);
|
||||
LOG.warn(new RuntimeException(err));
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,6 @@ import org.eclipse.jetty.websocket.common.ConnectionState;
|
|||
import org.eclipse.jetty.websocket.common.Generator;
|
||||
import org.eclipse.jetty.websocket.common.LogicalConnection;
|
||||
import org.eclipse.jetty.websocket.common.Parser;
|
||||
import org.eclipse.jetty.websocket.common.WebSocketSession;
|
||||
import org.eclipse.jetty.websocket.common.io.IOState.ConnectionStateListener;
|
||||
|
||||
/**
|
||||
|
@ -71,7 +70,7 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
|
|||
@Override
|
||||
protected void onFailure(Throwable x)
|
||||
{
|
||||
session.notifyError(x);
|
||||
notifyError(x);
|
||||
|
||||
if (ioState.wasAbnormalClose())
|
||||
{
|
||||
|
@ -200,7 +199,8 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
|
|||
}
|
||||
|
||||
private static final Logger LOG = Log.getLogger(AbstractWebSocketConnection.class);
|
||||
private static final Logger LOG_CLOSE = Log.getLogger(AbstractWebSocketConnection.class.getName() + ".close");
|
||||
private static final Logger LOG_OPEN = Log.getLogger(AbstractWebSocketConnection.class.getName() + "_OPEN");
|
||||
private static final Logger LOG_CLOSE = Log.getLogger(AbstractWebSocketConnection.class.getName() + "_CLOSE");
|
||||
|
||||
/**
|
||||
* Minimum size of a buffer is the determined to be what would be the maximum framing header size (not including payload)
|
||||
|
@ -214,7 +214,6 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
|
|||
private final WebSocketPolicy policy;
|
||||
private final AtomicBoolean suspendToken;
|
||||
private final FrameFlusher flusher;
|
||||
private WebSocketSession session;
|
||||
private List<ExtensionConfig> extensions;
|
||||
private boolean isFilling;
|
||||
private ByteBuffer prefillBuffer;
|
||||
|
@ -389,12 +388,6 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
|
|||
return scheduler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebSocketSession getSession()
|
||||
{
|
||||
return session;
|
||||
}
|
||||
|
||||
public Stats getStats()
|
||||
{
|
||||
return stats;
|
||||
|
@ -544,9 +537,16 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
|
|||
prefillBuffer = prefilled;
|
||||
}
|
||||
|
||||
private void notifyError(Throwable t)
|
||||
{
|
||||
getParser().getIncomingFramesHandler().incomingError(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpen()
|
||||
{
|
||||
if(LOG_OPEN.isDebugEnabled())
|
||||
LOG_OPEN.debug("[{}] {}.onOpened()",policy.getBehavior(),this.getClass().getSimpleName());
|
||||
super.onOpen();
|
||||
this.ioState.onOpened();
|
||||
}
|
||||
|
@ -573,7 +573,7 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
|
|||
|
||||
try
|
||||
{
|
||||
session.notifyError(new SocketTimeoutException("Timeout on Read"));
|
||||
notifyError(new SocketTimeoutException("Timeout on Read"));
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -722,12 +722,6 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
|
|||
getEndPoint().setIdleTimeout(ms);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSession(WebSocketSession session)
|
||||
{
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SuspendToken suspend()
|
||||
{
|
||||
|
|
|
@ -404,6 +404,9 @@ public class IOState
|
|||
*/
|
||||
public void onOpened()
|
||||
{
|
||||
if(LOG.isDebugEnabled())
|
||||
LOG.debug(" onOpened()");
|
||||
|
||||
ConnectionState event = null;
|
||||
synchronized (this)
|
||||
{
|
||||
|
|
|
@ -35,7 +35,6 @@ import org.eclipse.jetty.websocket.api.extensions.IncomingFrames;
|
|||
import org.eclipse.jetty.websocket.common.CloseInfo;
|
||||
import org.eclipse.jetty.websocket.common.ConnectionState;
|
||||
import org.eclipse.jetty.websocket.common.LogicalConnection;
|
||||
import org.eclipse.jetty.websocket.common.WebSocketSession;
|
||||
import org.eclipse.jetty.websocket.common.io.IOState.ConnectionStateListener;
|
||||
import org.junit.rules.TestName;
|
||||
|
||||
|
@ -149,12 +148,6 @@ public class LocalWebSocketConnection implements LogicalConnection, IncomingFram
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebSocketSession getSession()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void incomingError(Throwable e)
|
||||
{
|
||||
|
@ -235,11 +228,6 @@ public class LocalWebSocketConnection implements LogicalConnection, IncomingFram
|
|||
this.policy = policy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSession(WebSocketSession session)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public SuspendToken suspend()
|
||||
{
|
||||
|
|
|
@ -49,7 +49,6 @@ public class MessageInputStreamTest
|
|||
{
|
||||
// Append a single message (simple, short)
|
||||
ByteBuffer payload = BufferUtil.toBuffer("Hello World",StandardCharsets.UTF_8);
|
||||
System.out.printf("payload = %s%n",BufferUtil.toDetailString(payload));
|
||||
boolean fin = true;
|
||||
stream.appendFrame(payload,fin);
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.websocket.jsr356.server;
|
||||
package org.eclipse.jetty.websocket.common.test;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.concurrent.Executor;
|
||||
|
@ -31,7 +31,6 @@ import org.eclipse.jetty.websocket.api.WriteCallback;
|
|||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||
import org.eclipse.jetty.websocket.api.extensions.IncomingFrames;
|
||||
import org.eclipse.jetty.websocket.common.LogicalConnection;
|
||||
import org.eclipse.jetty.websocket.common.WebSocketSession;
|
||||
import org.eclipse.jetty.websocket.common.io.IOState;
|
||||
|
||||
public class DummyConnection implements LogicalConnection
|
||||
|
@ -103,13 +102,6 @@ public class DummyConnection implements LogicalConnection
|
|||
|
||||
@Override
|
||||
public InetSocketAddress getRemoteAddress()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebSocketSession getSession()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
@ -149,11 +141,6 @@ public class DummyConnection implements LogicalConnection
|
|||
LOG.debug("setNextIncomingFrames({})",incoming);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSession(WebSocketSession session)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public SuspendToken suspend()
|
||||
{
|
|
@ -20,7 +20,6 @@ package org.eclipse.jetty.websocket.server;
|
|||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.eclipse.jetty.io.ByteBufferPool;
|
||||
import org.eclipse.jetty.io.Connection;
|
||||
|
@ -32,8 +31,6 @@ import org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection;
|
|||
|
||||
public class WebSocketServerConnection extends AbstractWebSocketConnection implements Connection.UpgradeTo
|
||||
{
|
||||
private final AtomicBoolean opened = new AtomicBoolean(false);
|
||||
|
||||
public WebSocketServerConnection(EndPoint endp, Executor executor, Scheduler scheduler, WebSocketPolicy policy, ByteBufferPool bufferPool)
|
||||
{
|
||||
super(endp,executor,scheduler,policy,bufferPool);
|
||||
|
@ -54,17 +51,6 @@ public class WebSocketServerConnection extends AbstractWebSocketConnection imple
|
|||
{
|
||||
return getEndPoint().getRemoteAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpen()
|
||||
{
|
||||
boolean beenOpened = opened.getAndSet(true);
|
||||
if (!beenOpened)
|
||||
{
|
||||
getSession().open();
|
||||
}
|
||||
super.onOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNextIncomingFrames(IncomingFrames incoming)
|
||||
|
|
|
@ -22,13 +22,12 @@ import java.io.IOException;
|
|||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
@ -53,7 +52,6 @@ import org.eclipse.jetty.util.ssl.SslContextFactory;
|
|||
import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
|
||||
import org.eclipse.jetty.util.thread.Scheduler;
|
||||
import org.eclipse.jetty.websocket.api.InvalidWebSocketException;
|
||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketException;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||
import org.eclipse.jetty.websocket.api.extensions.ExtensionFactory;
|
||||
|
@ -94,7 +92,6 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
|
|||
private final WebSocketExtensionFactory extensionFactory;
|
||||
private Executor executor;
|
||||
private List<SessionFactory> sessionFactories;
|
||||
private Set<WebSocketSession> openSessions = new CopyOnWriteArraySet<>();
|
||||
private WebSocketCreator creator;
|
||||
private List<Class<?>> registeredSocketClasses;
|
||||
private DecoratedObjectFactory objectFactory;
|
||||
|
@ -228,27 +225,6 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
|
|||
}
|
||||
}
|
||||
|
||||
protected void shutdownAllConnections()
|
||||
{
|
||||
for (WebSocketSession session : openSessions)
|
||||
{
|
||||
if (session.getConnection() != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
session.getConnection().close(
|
||||
StatusCode.SHUTDOWN,
|
||||
"Shutdown");
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
LOG.debug("During Shutdown All Connections",t);
|
||||
}
|
||||
}
|
||||
}
|
||||
openSessions.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebSocketServletFactory createFactory(WebSocketPolicy policy)
|
||||
{
|
||||
|
@ -318,13 +294,6 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
|
|||
super.doStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStop() throws Exception
|
||||
{
|
||||
shutdownAllConnections();
|
||||
super.doStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBufferPool getBufferPool()
|
||||
{
|
||||
|
@ -359,9 +328,9 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
|
|||
return extensionFactory;
|
||||
}
|
||||
|
||||
public Set<WebSocketSession> getOpenSessions()
|
||||
public Collection<WebSocketSession> getOpenSessions()
|
||||
{
|
||||
return Collections.unmodifiableSet(this.openSessions);
|
||||
return getBeans(WebSocketSession.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -484,13 +453,13 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
|
|||
@Override
|
||||
public void onSessionClosed(WebSocketSession session)
|
||||
{
|
||||
this.openSessions.remove(session);
|
||||
removeBean(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSessionOpened(WebSocketSession session)
|
||||
{
|
||||
this.openSessions.add(session);
|
||||
addManaged(session);
|
||||
}
|
||||
|
||||
protected String[] parseProtocols(String protocol)
|
||||
|
@ -625,7 +594,7 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
|
|||
// set true negotiated extension list back to response
|
||||
response.setExtensions(extensionStack.getNegotiatedExtensions());
|
||||
session.setUpgradeResponse(response);
|
||||
wsConnection.setSession(session);
|
||||
wsConnection.addListener(session);
|
||||
|
||||
// Setup Incoming Routing
|
||||
wsConnection.setNextIncomingFrames(extensionStack);
|
||||
|
@ -636,24 +605,13 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
|
|||
extensionStack.setNextOutgoing(wsConnection);
|
||||
|
||||
// Start Components
|
||||
session.addBean(extensionStack);
|
||||
this.addBean(session);
|
||||
session.addManaged(extensionStack);
|
||||
this.addManaged(session);
|
||||
|
||||
if (session.isFailed())
|
||||
{
|
||||
throw new IOException("Session failed to start");
|
||||
}
|
||||
else if (!session.isRunning())
|
||||
{
|
||||
try
|
||||
{
|
||||
session.start();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new IOException("Unable to start Session",e);
|
||||
}
|
||||
}
|
||||
|
||||
// Tell jetty about the new upgraded connection
|
||||
request.setServletAttribute(HttpConnection.UPGRADE_CONNECTION_ATTRIBUTE, wsConnection);
|
||||
|
|
|
@ -22,8 +22,8 @@ import static org.hamcrest.Matchers.*;
|
|||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
@ -144,7 +144,7 @@ public class ManyConnectionsCleanupTest
|
|||
calls.incrementAndGet();
|
||||
if (message.equalsIgnoreCase("openSessions"))
|
||||
{
|
||||
Set<WebSocketSession> sessions = container.getOpenSessions();
|
||||
Collection<WebSocketSession> sessions = container.getOpenSessions();
|
||||
|
||||
StringBuilder ret = new StringBuilder();
|
||||
ret.append("openSessions.size=").append(sessions.size()).append('\n');
|
||||
|
@ -336,7 +336,7 @@ public class ManyConnectionsCleanupTest
|
|||
client.sendStandardRequest();
|
||||
client.expectUpgradeResponse();
|
||||
|
||||
client.readFrames(1,1,TimeUnit.SECONDS);
|
||||
// client.readFrames(1,2,TimeUnit.SECONDS);
|
||||
|
||||
CloseInfo close = new CloseInfo(StatusCode.NORMAL,"Normal");
|
||||
client.write(close.asFrame()); // respond with close
|
||||
|
|
|
@ -22,8 +22,8 @@ import static org.hamcrest.Matchers.*;
|
|||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
@ -139,7 +139,7 @@ public class WebSocketCloseTest
|
|||
LOG.debug("onWebSocketText({})",message);
|
||||
if (message.equalsIgnoreCase("openSessions"))
|
||||
{
|
||||
Set<WebSocketSession> sessions = container.getOpenSessions();
|
||||
Collection<WebSocketSession> sessions = container.getOpenSessions();
|
||||
|
||||
StringBuilder ret = new StringBuilder();
|
||||
ret.append("openSessions.size=").append(sessions.size()).append('\n');
|
||||
|
|
|
@ -12,6 +12,11 @@ org.eclipse.jetty.LEVEL=WARN
|
|||
# org.eclipse.jetty.websocket.server.blockhead.LEVEL=DEBUG
|
||||
# org.eclipse.jetty.websocket.server.helper.LEVEL=DEBUG
|
||||
|
||||
# org.eclipse.jetty.websocket.client.io.ConnectPromise.LEVEL=DEBUG
|
||||
# org.eclipse.jetty.websocket.common.WebSocketSession_OPEN.LEVEL=DEBUG
|
||||
# org.eclipse.jetty.websocket.common.io.IOState.LEVEL=DEBUG
|
||||
# org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection_OPEN.LEVEL=DEBUG
|
||||
|
||||
### Show state changes on BrowserDebugTool
|
||||
# -- LEAVE THIS AT DEBUG LEVEL --
|
||||
org.eclipse.jetty.websocket.server.browser.LEVEL=DEBUG
|
||||
|
|
4
pom.xml
4
pom.xml
|
@ -609,14 +609,14 @@
|
|||
<dependency>
|
||||
<groupId>org.apache.taglibs</groupId>
|
||||
<artifactId>taglibs-standard-impl</artifactId>
|
||||
<version>1.2.1</version>
|
||||
<version>1.2.5</version>
|
||||
</dependency>
|
||||
|
||||
<!-- JSTL API -->
|
||||
<dependency>
|
||||
<groupId>org.apache.taglibs</groupId>
|
||||
<artifactId>taglibs-standard-spec</artifactId>
|
||||
<version>1.2.1</version>
|
||||
<version>1.2.5</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue