interims
20
VERSION.txt
|
@ -1,18 +1,34 @@
|
||||||
jetty-9.0.0-SNAPSHOT
|
jetty-9.0.0-SNAPSHOT
|
||||||
|
|
||||||
jetty-9.0.0.M5 - 26 December 2012
|
jetty-9.0.0.M5 - 19 January 2013
|
||||||
+ 367638 throw exception for excess form keys
|
+ 367638 throw exception for excess form keys
|
||||||
|
+ 381521 Only set Vary header when content could be compressed
|
||||||
+ 391623 Making --stop with STOP.WAIT perform graceful shutdown
|
+ 391623 Making --stop with STOP.WAIT perform graceful shutdown
|
||||||
+ 393158 java.lang.IllegalStateException when sending an empty InputStream
|
+ 393158 java.lang.IllegalStateException when sending an empty InputStream
|
||||||
+ 393220 remove dead code from ServletHandler and log ServletExceptions in
|
+ 393220 remove dead code from ServletHandler and log ServletExceptions in
|
||||||
warn instead of debug
|
warn instead of debug
|
||||||
|
+ 393733 WebSocketClient interface should support multiple connections
|
||||||
|
+ 395885 ResourceCache should honor useFileMappedBuffer if set
|
||||||
|
+ 396253 FilterRegistration wrong order
|
||||||
+ 396459 Log specific message for empty request body for multipart mime
|
+ 396459 Log specific message for empty request body for multipart mime
|
||||||
requests
|
requests
|
||||||
|
+ 396500 HttpClient Exchange takes forever to complete when less content sent
|
||||||
|
than Content-Length
|
||||||
+ 396886 MultiPartFilter strips bad escaping on filename="..."
|
+ 396886 MultiPartFilter strips bad escaping on filename="..."
|
||||||
+ 397110 Accept %uXXXX encodings in URIs
|
+ 397110 Accept %uXXXX encodings in URIs
|
||||||
+ 397111 Allow multipart bodies with leading blank lines
|
+ 397111 Tolerate empty or excessive whitespace preceeding MultiParts
|
||||||
+ 397112 Requests with byte-range throws NPE if requested file has no mimetype
|
+ 397112 Requests with byte-range throws NPE if requested file has no mimetype
|
||||||
(eg no file extension)
|
(eg no file extension)
|
||||||
|
+ 397114 run-forked with waitForChild=false can lock up
|
||||||
|
+ 397130 maxFormContentSize set in jetty.xml is ignored
|
||||||
|
+ 397190 improve ValidUrlRule to iterate on codepoints
|
||||||
|
+ 397321 Wrong condition in default start.config for annotations
|
||||||
|
+ 397535 Support pluggable alias checking to support symbolic links
|
||||||
|
+ 397769 TimerScheduler does not relinquish cancelled tasks.
|
||||||
|
+ 398105 Clean up WebSocketPolicy
|
||||||
|
+ 398285 ProxyServlet mixes cookies from different clients.
|
||||||
|
+ 398337 UTF-16 percent encoding in UTF-16 form content
|
||||||
|
+ 398582 Move lib/jta jar into lib/jndi
|
||||||
+ JETTY-1533 handle URL with no path
|
+ JETTY-1533 handle URL with no path
|
||||||
|
|
||||||
jetty-9.0.0.M4 - 21 December 2012
|
jetty-9.0.0.M4 - 21 December 2012
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
<Item>org.eclipse.jetty.webapp.WebXmlConfiguration</Item>
|
<Item>org.eclipse.jetty.webapp.WebXmlConfiguration</Item>
|
||||||
<Item>org.eclipse.jetty.webapp.MetaInfConfiguration</Item>
|
<Item>org.eclipse.jetty.webapp.MetaInfConfiguration</Item>
|
||||||
<Item>org.eclipse.jetty.webapp.FragmentConfiguration</Item>
|
<Item>org.eclipse.jetty.webapp.FragmentConfiguration</Item>
|
||||||
|
<Item>org.eclipse.jetty.plus.webapp.EnvConfiguration</Item>
|
||||||
|
<Item>org.eclipse.jetty.plus.webapp.PlusConfiguration</Item>
|
||||||
<Item>org.eclipse.jetty.annotations.AnnotationConfiguration</Item>
|
<Item>org.eclipse.jetty.annotations.AnnotationConfiguration</Item>
|
||||||
<Item>org.eclipse.jetty.webapp.JettyWebXmlConfiguration</Item>
|
<Item>org.eclipse.jetty.webapp.JettyWebXmlConfiguration</Item>
|
||||||
</Array>
|
</Array>
|
||||||
|
|
|
@ -481,10 +481,6 @@ public class HttpClient extends ContainerLifeCycle
|
||||||
if (!Arrays.asList("http", "https").contains(scheme))
|
if (!Arrays.asList("http", "https").contains(scheme))
|
||||||
throw new IllegalArgumentException("Invalid protocol " + scheme);
|
throw new IllegalArgumentException("Invalid protocol " + scheme);
|
||||||
|
|
||||||
for (Response.ResponseListener listener : listeners)
|
|
||||||
if (listener instanceof Schedulable)
|
|
||||||
((Schedulable)listener).schedule(scheduler);
|
|
||||||
|
|
||||||
HttpDestination destination = provideDestination(scheme, request.getHost(), request.getPort());
|
HttpDestination destination = provideDestination(scheme, request.getHost(), request.getPort());
|
||||||
destination.send(request, listeners);
|
destination.send(request, listeners);
|
||||||
}
|
}
|
||||||
|
@ -875,6 +871,16 @@ public class HttpClient extends ContainerLifeCycle
|
||||||
return encodingField;
|
return encodingField;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected HttpConnection newHttpConnection(HttpClient httpClient, EndPoint endPoint, HttpDestination destination)
|
||||||
|
{
|
||||||
|
return new HttpConnection(httpClient, endPoint, destination);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected SslConnection newSslConnection(HttpClient httpClient, EndPoint endPoint, SSLEngine engine)
|
||||||
|
{
|
||||||
|
return new SslConnection(httpClient.getByteBufferPool(), httpClient.getExecutor(), endPoint, engine);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dump(Appendable out, String indent) throws IOException
|
public void dump(Appendable out, String indent) throws IOException
|
||||||
{
|
{
|
||||||
|
@ -920,12 +926,9 @@ public class HttpClient extends ContainerLifeCycle
|
||||||
SSLEngine engine = sslContextFactory.newSSLEngine(endPoint.getRemoteAddress());
|
SSLEngine engine = sslContextFactory.newSSLEngine(endPoint.getRemoteAddress());
|
||||||
engine.setUseClientMode(true);
|
engine.setUseClientMode(true);
|
||||||
|
|
||||||
SslConnection sslConnection = new SslConnection(getByteBufferPool(), getExecutor(), endPoint, engine);
|
SslConnection sslConnection = newSslConnection(HttpClient.this, endPoint, engine);
|
||||||
// TODO: configureConnection => implies we should use SslConnectionFactory to do it
|
|
||||||
|
|
||||||
EndPoint appEndPoint = sslConnection.getDecryptedEndPoint();
|
EndPoint appEndPoint = sslConnection.getDecryptedEndPoint();
|
||||||
HttpConnection connection = new HttpConnection(HttpClient.this, appEndPoint, destination);
|
HttpConnection connection = newHttpConnection(HttpClient.this, appEndPoint, destination);
|
||||||
// TODO: configureConnection, see above
|
|
||||||
|
|
||||||
appEndPoint.setConnection(connection);
|
appEndPoint.setConnection(connection);
|
||||||
callback.promise.succeeded(connection);
|
callback.promise.succeeded(connection);
|
||||||
|
@ -935,8 +938,7 @@ public class HttpClient extends ContainerLifeCycle
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HttpConnection connection = new HttpConnection(HttpClient.this, endPoint, destination);
|
HttpConnection connection = newHttpConnection(HttpClient.this, endPoint, destination);
|
||||||
// TODO: configureConnection, see above
|
|
||||||
callback.promise.succeeded(connection);
|
callback.promise.succeeded(connection);
|
||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ import java.io.UnsupportedEncodingException;
|
||||||
import java.net.HttpCookie;
|
import java.net.HttpCookie;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.nio.charset.UnsupportedCharsetException;
|
import java.nio.charset.UnsupportedCharsetException;
|
||||||
import java.util.Collections;
|
import java.util.ArrayList;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -108,7 +108,16 @@ public class HttpConnection extends AbstractConnection implements Connection
|
||||||
@Override
|
@Override
|
||||||
public void send(Request request, Response.CompleteListener listener)
|
public void send(Request request, Response.CompleteListener listener)
|
||||||
{
|
{
|
||||||
send(request, Collections.<Response.ResponseListener>singletonList(listener));
|
ArrayList<Response.ResponseListener> listeners = new ArrayList<>(2);
|
||||||
|
if (request.getTimeout() > 0)
|
||||||
|
{
|
||||||
|
TimeoutCompleteListener timeoutListener = new TimeoutCompleteListener(request);
|
||||||
|
timeoutListener.schedule(client.getScheduler());
|
||||||
|
listeners.add(timeoutListener);
|
||||||
|
}
|
||||||
|
if (listener != null)
|
||||||
|
listeners.add(listener);
|
||||||
|
send(request, listeners);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void send(Request request, List<Response.ResponseListener> listeners)
|
public void send(Request request, List<Response.ResponseListener> listeners)
|
||||||
|
@ -125,10 +134,6 @@ public class HttpConnection extends AbstractConnection implements Connection
|
||||||
setExchange(exchange);
|
setExchange(exchange);
|
||||||
conversation.getExchanges().offer(exchange);
|
conversation.getExchanges().offer(exchange);
|
||||||
|
|
||||||
for (Response.ResponseListener listener : listeners)
|
|
||||||
if (listener instanceof Schedulable)
|
|
||||||
((Schedulable)listener).schedule(client.getScheduler());
|
|
||||||
|
|
||||||
sender.send(exchange);
|
sender.send(exchange);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,6 @@ import org.eclipse.jetty.client.api.ProxyConfiguration;
|
||||||
import org.eclipse.jetty.client.api.Request;
|
import org.eclipse.jetty.client.api.Request;
|
||||||
import org.eclipse.jetty.client.api.Response;
|
import org.eclipse.jetty.client.api.Response;
|
||||||
import org.eclipse.jetty.client.api.Result;
|
import org.eclipse.jetty.client.api.Result;
|
||||||
import org.eclipse.jetty.client.util.TimedResponseListener;
|
|
||||||
import org.eclipse.jetty.http.HttpField;
|
import org.eclipse.jetty.http.HttpField;
|
||||||
import org.eclipse.jetty.http.HttpHeader;
|
import org.eclipse.jetty.http.HttpHeader;
|
||||||
import org.eclipse.jetty.http.HttpMethod;
|
import org.eclipse.jetty.http.HttpMethod;
|
||||||
|
@ -509,8 +508,9 @@ public class HttpDestination implements Destination, AutoCloseable, Dumpable
|
||||||
.scheme(HttpScheme.HTTP.asString())
|
.scheme(HttpScheme.HTTP.asString())
|
||||||
.method(HttpMethod.CONNECT)
|
.method(HttpMethod.CONNECT)
|
||||||
.path(target)
|
.path(target)
|
||||||
.header(HttpHeader.HOST.asString(), target);
|
.header(HttpHeader.HOST.asString(), target)
|
||||||
connection.send(connect, new TimedResponseListener(client.getConnectTimeout(), TimeUnit.MILLISECONDS, connect, new Response.CompleteListener()
|
.timeout(client.getConnectTimeout(), TimeUnit.MILLISECONDS);
|
||||||
|
connection.send(connect, new Response.CompleteListener()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void onComplete(Result result)
|
public void onComplete(Result result)
|
||||||
|
@ -534,7 +534,7 @@ public class HttpDestination implements Destination, AutoCloseable, Dumpable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}));
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,14 +178,7 @@ public class HttpExchange
|
||||||
// Request and response completed
|
// Request and response completed
|
||||||
LOG.debug("{} complete", this);
|
LOG.debug("{} complete", this);
|
||||||
if (isLast())
|
if (isLast())
|
||||||
{
|
|
||||||
HttpExchange first = conversation.getExchanges().peekFirst();
|
|
||||||
List<Response.ResponseListener> listeners = first.getResponseListeners();
|
|
||||||
for (Response.ResponseListener listener : listeners)
|
|
||||||
if (listener instanceof Schedulable)
|
|
||||||
((Schedulable)listener).cancel();
|
|
||||||
conversation.complete();
|
conversation.complete();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
result = new Result(getRequest(), getRequestFailure(), getResponse(), getResponseFailure());
|
result = new Result(getRequest(), getRequestFailure(), getResponse(), getResponseFailure());
|
||||||
}
|
}
|
||||||
|
|
|
@ -426,7 +426,7 @@ public class HttpRequest implements Request
|
||||||
public ContentResponse send() throws InterruptedException, TimeoutException, ExecutionException
|
public ContentResponse send() throws InterruptedException, TimeoutException, ExecutionException
|
||||||
{
|
{
|
||||||
FutureResponseListener listener = new FutureResponseListener(this);
|
FutureResponseListener listener = new FutureResponseListener(this);
|
||||||
send(listener);
|
send(this, listener);
|
||||||
|
|
||||||
long timeout = getTimeout();
|
long timeout = getTimeout();
|
||||||
if (timeout <= 0)
|
if (timeout <= 0)
|
||||||
|
@ -447,10 +447,21 @@ public class HttpRequest implements Request
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void send(Response.CompleteListener listener)
|
public void send(Response.CompleteListener listener)
|
||||||
|
{
|
||||||
|
if (getTimeout() > 0)
|
||||||
|
{
|
||||||
|
TimeoutCompleteListener timeoutListener = new TimeoutCompleteListener(this);
|
||||||
|
timeoutListener.schedule(client.getScheduler());
|
||||||
|
responseListeners.add(timeoutListener);
|
||||||
|
}
|
||||||
|
send(this, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void send(Request request, Response.CompleteListener listener)
|
||||||
{
|
{
|
||||||
if (listener != null)
|
if (listener != null)
|
||||||
responseListeners.add(listener);
|
responseListeners.add(listener);
|
||||||
client.send(this, responseListeners);
|
client.send(request, responseListeners);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2013 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.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
|
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.util.log.Log;
|
||||||
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
|
import org.eclipse.jetty.util.thread.Scheduler;
|
||||||
|
|
||||||
|
public class TimeoutCompleteListener implements Response.CompleteListener, Runnable
|
||||||
|
{
|
||||||
|
private static final Logger LOG = Log.getLogger(TimeoutCompleteListener.class);
|
||||||
|
|
||||||
|
private final AtomicReference<Scheduler.Task> task = new AtomicReference<>();
|
||||||
|
private final Request request;
|
||||||
|
|
||||||
|
public TimeoutCompleteListener(Request request)
|
||||||
|
{
|
||||||
|
this.request = request;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onComplete(Result result)
|
||||||
|
{
|
||||||
|
Scheduler.Task task = this.task.getAndSet(null);
|
||||||
|
if (task != null)
|
||||||
|
{
|
||||||
|
boolean cancelled = task.cancel();
|
||||||
|
LOG.debug("Cancelled (successfully: {}) timeout task {}", cancelled, task);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean schedule(Scheduler scheduler)
|
||||||
|
{
|
||||||
|
long timeout = request.getTimeout();
|
||||||
|
Scheduler.Task task = scheduler.schedule(this, timeout, TimeUnit.MILLISECONDS);
|
||||||
|
if (this.task.getAndSet(task) != null)
|
||||||
|
throw new IllegalStateException();
|
||||||
|
LOG.debug("Scheduled timeout task {} in {} ms", task, timeout);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
request.abort(new TimeoutException("Total timeout elapsed"));
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,169 +0,0 @@
|
||||||
//
|
|
||||||
// ========================================================================
|
|
||||||
// Copyright (c) 1995-2013 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.util;
|
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.TimeoutException;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.client.Schedulable;
|
|
||||||
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.http.HttpField;
|
|
||||||
import org.eclipse.jetty.util.log.Log;
|
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
|
||||||
import org.eclipse.jetty.util.thread.Scheduler;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation of {@link Response.Listener} that allows to specify a timeout for asynchronous
|
|
||||||
* operations.
|
|
||||||
* <p />
|
|
||||||
* {@link TimedResponseListener} may be used to decorate a delegate {@link Response.CompleteListener}
|
|
||||||
* provided by the application. Events are forwarded by {@link TimedResponseListener} to the delegate
|
|
||||||
* listener.
|
|
||||||
* Alternatively, {@link TimedResponseListener} may be subclassed to override callbacks that are
|
|
||||||
* interesting to the application, typically {@link #onComplete(Result)}.
|
|
||||||
* <p />
|
|
||||||
* If the timeout specified at the constructor elapses, the request is {@link Request#abort(Throwable) aborted}
|
|
||||||
* with a {@link TimeoutException}.
|
|
||||||
* <p />
|
|
||||||
* Typical usage is:
|
|
||||||
* <pre>
|
|
||||||
* Request request = httpClient.newRequest(...)...;
|
|
||||||
* TimedResponseListener listener = new TimedResponseListener(5, TimeUnit.SECONDS, request, new Response.CompleteListener()
|
|
||||||
* {
|
|
||||||
* public void onComplete(Result result)
|
|
||||||
* {
|
|
||||||
* // Invoked when request/response completes or when timeout elapses
|
|
||||||
*
|
|
||||||
* // Your logic here
|
|
||||||
* }
|
|
||||||
* });
|
|
||||||
* request.send(listener); // Asynchronous send
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
public class TimedResponseListener implements Response.Listener, Schedulable, Runnable
|
|
||||||
{
|
|
||||||
private static final Logger LOG = Log.getLogger(TimedResponseListener.class);
|
|
||||||
|
|
||||||
private final AtomicReference<Scheduler.Task> task = new AtomicReference<>();
|
|
||||||
private final long timeout;
|
|
||||||
private final TimeUnit unit;
|
|
||||||
private final Request request;
|
|
||||||
private final Response.CompleteListener delegate;
|
|
||||||
|
|
||||||
public TimedResponseListener(long timeout, TimeUnit unit, Request request)
|
|
||||||
{
|
|
||||||
this(timeout, unit, request, new Empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
public TimedResponseListener(long timeout, TimeUnit unit, Request request, Response.CompleteListener delegate)
|
|
||||||
{
|
|
||||||
this.timeout = timeout;
|
|
||||||
this.unit = unit;
|
|
||||||
this.request = request;
|
|
||||||
this.delegate = delegate;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBegin(Response response)
|
|
||||||
{
|
|
||||||
if (delegate instanceof Response.BeginListener)
|
|
||||||
((Response.BeginListener)delegate).onBegin(response);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onHeader(Response response, HttpField field)
|
|
||||||
{
|
|
||||||
if (delegate instanceof Response.HeaderListener)
|
|
||||||
return ((Response.HeaderListener)delegate).onHeader(response, field);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onHeaders(Response response)
|
|
||||||
{
|
|
||||||
if (delegate instanceof Response.HeadersListener)
|
|
||||||
((Response.HeadersListener)delegate).onHeaders(response);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onContent(Response response, ByteBuffer content)
|
|
||||||
{
|
|
||||||
if (delegate instanceof Response.ContentListener)
|
|
||||||
((Response.ContentListener)delegate).onContent(response, content);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSuccess(Response response)
|
|
||||||
{
|
|
||||||
if (delegate instanceof Response.SuccessListener)
|
|
||||||
((Response.SuccessListener)delegate).onSuccess(response);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(Response response, Throwable failure)
|
|
||||||
{
|
|
||||||
if (delegate instanceof Response.FailureListener)
|
|
||||||
((Response.FailureListener)delegate).onFailure(response, failure);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onComplete(Result result)
|
|
||||||
{
|
|
||||||
delegate.onComplete(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean schedule(Scheduler scheduler)
|
|
||||||
{
|
|
||||||
Scheduler.Task task = this.task.get();
|
|
||||||
if (task != null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
task = scheduler.schedule(this, timeout, unit);
|
|
||||||
if (this.task.compareAndSet(null, task))
|
|
||||||
{
|
|
||||||
LOG.debug("Scheduled timeout task {} in {} ms", task, unit.toMillis(timeout));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
task.cancel();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
request.abort(new TimeoutException("Total timeout elapsed"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean cancel()
|
|
||||||
{
|
|
||||||
Scheduler.Task task = this.task.get();
|
|
||||||
if (task == null)
|
|
||||||
return false;
|
|
||||||
boolean result = task.cancel();
|
|
||||||
LOG.debug("Cancelled timeout task {}", task);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -23,7 +23,8 @@ import java.io.IOException;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import javax.net.ssl.SSLEngine;
|
||||||
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;
|
||||||
|
@ -35,11 +36,13 @@ import org.eclipse.jetty.client.api.Response;
|
||||||
import org.eclipse.jetty.client.api.Result;
|
import org.eclipse.jetty.client.api.Result;
|
||||||
import org.eclipse.jetty.client.util.BufferingResponseListener;
|
import org.eclipse.jetty.client.util.BufferingResponseListener;
|
||||||
import org.eclipse.jetty.client.util.InputStreamContentProvider;
|
import org.eclipse.jetty.client.util.InputStreamContentProvider;
|
||||||
import org.eclipse.jetty.client.util.TimedResponseListener;
|
import org.eclipse.jetty.io.EndPoint;
|
||||||
|
import org.eclipse.jetty.io.ssl.SslConnection;
|
||||||
import org.eclipse.jetty.server.handler.AbstractHandler;
|
import org.eclipse.jetty.server.handler.AbstractHandler;
|
||||||
import org.eclipse.jetty.toolchain.test.annotation.Slow;
|
import org.eclipse.jetty.toolchain.test.annotation.Slow;
|
||||||
import org.eclipse.jetty.util.IO;
|
import org.eclipse.jetty.util.IO;
|
||||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||||
|
import org.hamcrest.Matchers;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
@ -71,8 +74,10 @@ public class HttpClientTimeoutTest extends AbstractHttpClientServerTest
|
||||||
start(new TimeoutHandler(2 * timeout));
|
start(new TimeoutHandler(2 * timeout));
|
||||||
|
|
||||||
final CountDownLatch latch = new CountDownLatch(1);
|
final CountDownLatch latch = new CountDownLatch(1);
|
||||||
Request request = client.newRequest("localhost", connector.getLocalPort()).scheme(scheme);
|
Request request = client.newRequest("localhost", connector.getLocalPort())
|
||||||
request.send(new TimedResponseListener(timeout, TimeUnit.MILLISECONDS, request)
|
.scheme(scheme)
|
||||||
|
.timeout(timeout, TimeUnit.MILLISECONDS);
|
||||||
|
request.send(new Response.CompleteListener()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void onComplete(Result result)
|
public void onComplete(Result result)
|
||||||
|
@ -96,8 +101,10 @@ public class HttpClientTimeoutTest extends AbstractHttpClientServerTest
|
||||||
|
|
||||||
// The first request has a long timeout
|
// The first request has a long timeout
|
||||||
final CountDownLatch firstLatch = new CountDownLatch(1);
|
final CountDownLatch firstLatch = new CountDownLatch(1);
|
||||||
Request request = client.newRequest("localhost", connector.getLocalPort()).scheme(scheme);
|
Request request = client.newRequest("localhost", connector.getLocalPort())
|
||||||
request.send(new TimedResponseListener(4 * timeout, TimeUnit.MILLISECONDS, request)
|
.scheme(scheme)
|
||||||
|
.timeout(4 * timeout, TimeUnit.MILLISECONDS);
|
||||||
|
request.send(new Response.CompleteListener()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void onComplete(Result result)
|
public void onComplete(Result result)
|
||||||
|
@ -109,8 +116,10 @@ public class HttpClientTimeoutTest extends AbstractHttpClientServerTest
|
||||||
|
|
||||||
// Second request has a short timeout and should fail in the queue
|
// Second request has a short timeout and should fail in the queue
|
||||||
final CountDownLatch secondLatch = new CountDownLatch(1);
|
final CountDownLatch secondLatch = new CountDownLatch(1);
|
||||||
request = client.newRequest("localhost", connector.getLocalPort()).scheme(scheme);
|
request = client.newRequest("localhost", connector.getLocalPort())
|
||||||
request.send(new TimedResponseListener(timeout, TimeUnit.MILLISECONDS, request)
|
.scheme(scheme)
|
||||||
|
.timeout(timeout, TimeUnit.MILLISECONDS);
|
||||||
|
request.send(new Response.CompleteListener()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void onComplete(Result result)
|
public void onComplete(Result result)
|
||||||
|
@ -137,8 +146,9 @@ public class HttpClientTimeoutTest extends AbstractHttpClientServerTest
|
||||||
final byte[] content = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
final byte[] content = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
Request request = client.newRequest("localhost", connector.getLocalPort())
|
Request request = client.newRequest("localhost", connector.getLocalPort())
|
||||||
.scheme(scheme)
|
.scheme(scheme)
|
||||||
.content(new InputStreamContentProvider(new ByteArrayInputStream(content)));
|
.content(new InputStreamContentProvider(new ByteArrayInputStream(content)))
|
||||||
request.send(new TimedResponseListener(2 * timeout, TimeUnit.MILLISECONDS, request, new BufferingResponseListener()
|
.timeout(2 * timeout, TimeUnit.MILLISECONDS);
|
||||||
|
request.send(new BufferingResponseListener()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void onComplete(Result result)
|
public void onComplete(Result result)
|
||||||
|
@ -147,7 +157,7 @@ public class HttpClientTimeoutTest extends AbstractHttpClientServerTest
|
||||||
Assert.assertArrayEquals(content, getContent());
|
Assert.assertArrayEquals(content, getContent());
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
}
|
}
|
||||||
}));
|
});
|
||||||
|
|
||||||
Assert.assertTrue(latch.await(3 * timeout, TimeUnit.MILLISECONDS));
|
Assert.assertTrue(latch.await(3 * timeout, TimeUnit.MILLISECONDS));
|
||||||
|
|
||||||
|
@ -167,8 +177,10 @@ public class HttpClientTimeoutTest extends AbstractHttpClientServerTest
|
||||||
Destination destination = client.getDestination(scheme, "localhost", connector.getLocalPort());
|
Destination destination = client.getDestination(scheme, "localhost", connector.getLocalPort());
|
||||||
try (Connection connection = destination.newConnection().get(5, TimeUnit.SECONDS))
|
try (Connection connection = destination.newConnection().get(5, TimeUnit.SECONDS))
|
||||||
{
|
{
|
||||||
Request request = client.newRequest("localhost", connector.getLocalPort()).scheme(scheme);
|
Request request = client.newRequest("localhost", connector.getLocalPort())
|
||||||
connection.send(request, new TimedResponseListener(timeout, TimeUnit.MILLISECONDS, request)
|
.scheme(scheme)
|
||||||
|
.timeout(timeout, TimeUnit.MILLISECONDS);
|
||||||
|
connection.send(request, new Response.CompleteListener()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void onComplete(Result result)
|
public void onComplete(Result result)
|
||||||
|
@ -193,8 +205,10 @@ public class HttpClientTimeoutTest extends AbstractHttpClientServerTest
|
||||||
Destination destination = client.getDestination(scheme, "localhost", connector.getLocalPort());
|
Destination destination = client.getDestination(scheme, "localhost", connector.getLocalPort());
|
||||||
try (Connection connection = destination.newConnection().get(5, TimeUnit.SECONDS))
|
try (Connection connection = destination.newConnection().get(5, TimeUnit.SECONDS))
|
||||||
{
|
{
|
||||||
Request request = client.newRequest(destination.getHost(), destination.getPort()).scheme(scheme);
|
Request request = client.newRequest(destination.getHost(), destination.getPort())
|
||||||
connection.send(request, new TimedResponseListener(2 * timeout, TimeUnit.MILLISECONDS, request)
|
.scheme(scheme)
|
||||||
|
.timeout(2 * timeout, TimeUnit.MILLISECONDS);
|
||||||
|
connection.send(request, new Response.CompleteListener()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void onComplete(Result result)
|
public void onComplete(Result result)
|
||||||
|
@ -214,6 +228,46 @@ public class HttpClientTimeoutTest extends AbstractHttpClientServerTest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIdleTimeout() throws Throwable
|
||||||
|
{
|
||||||
|
long timeout = 1000;
|
||||||
|
start(new TimeoutHandler(2 * timeout));
|
||||||
|
client.stop();
|
||||||
|
final AtomicBoolean sslIdle = new AtomicBoolean();
|
||||||
|
client = new HttpClient(sslContextFactory)
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
protected SslConnection newSslConnection(HttpClient httpClient, EndPoint endPoint, SSLEngine engine)
|
||||||
|
{
|
||||||
|
return new SslConnection(httpClient.getByteBufferPool(), httpClient.getExecutor(), endPoint, engine)
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
protected boolean onReadTimeout()
|
||||||
|
{
|
||||||
|
sslIdle.set(true);
|
||||||
|
return super.onReadTimeout();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
client.setIdleTimeout(timeout);
|
||||||
|
client.start();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
client.newRequest("localhost", connector.getLocalPort())
|
||||||
|
.scheme(scheme)
|
||||||
|
.send();
|
||||||
|
Assert.fail();
|
||||||
|
}
|
||||||
|
catch (Exception x)
|
||||||
|
{
|
||||||
|
Assert.assertFalse(sslIdle.get());
|
||||||
|
Assert.assertThat(x.getCause(), Matchers.instanceOf(TimeoutException.class));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class TimeoutHandler extends AbstractHandler
|
private class TimeoutHandler extends AbstractHandler
|
||||||
{
|
{
|
||||||
private final long timeout;
|
private final long timeout;
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2013 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.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.client.api.ContentResponse;
|
||||||
|
import org.eclipse.jetty.toolchain.test.annotation.Slow;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IdleTimeoutTest
|
||||||
|
*
|
||||||
|
* Warning - this is a slow test. Uncomment the ignore to run it.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class IdleTimeoutTest
|
||||||
|
{
|
||||||
|
public int _repetitions = 30;
|
||||||
|
|
||||||
|
@Slow
|
||||||
|
@Ignore
|
||||||
|
public void testIdleTimeoutOnBlockingConnector() throws Exception
|
||||||
|
{
|
||||||
|
|
||||||
|
final HttpClient client = new HttpClient();
|
||||||
|
client.setMaxConnectionsPerDestination(4);
|
||||||
|
client.setIdleTimeout(500); // very short idle timeout
|
||||||
|
client.start();
|
||||||
|
|
||||||
|
final CountDownLatch counter = new CountDownLatch(_repetitions);
|
||||||
|
|
||||||
|
Thread runner = new Thread()
|
||||||
|
{
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
for (int i=0; i<_repetitions; i++)
|
||||||
|
{
|
||||||
|
ContentResponse response = client.GET("http://www.google.com/?i="+i);
|
||||||
|
counter.countDown();
|
||||||
|
System.err.println(counter.getCount());
|
||||||
|
Thread.sleep(1000); //wait long enough for idle timeout to expire
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Assert.fail(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
runner.start();
|
||||||
|
if (!counter.await(80, TimeUnit.SECONDS))
|
||||||
|
Assert.fail("Test did not complete in time");
|
||||||
|
}
|
||||||
|
}
|
|
@ -289,7 +289,7 @@
|
||||||
<includeGroupIds>org.eclipse.jetty.orbit</includeGroupIds>
|
<includeGroupIds>org.eclipse.jetty.orbit</includeGroupIds>
|
||||||
<includeArtifactIds>javax.transaction</includeArtifactIds>
|
<includeArtifactIds>javax.transaction</includeArtifactIds>
|
||||||
<includeTypes>jar</includeTypes>
|
<includeTypes>jar</includeTypes>
|
||||||
<outputDirectory>${assembly-directory}/lib/jta</outputDirectory>
|
<outputDirectory>${assembly-directory}/lib/jndi</outputDirectory>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
<execution>
|
<execution>
|
||||||
|
|
|
@ -127,11 +127,11 @@ OPTIONS=jsp
|
||||||
|
|
||||||
|
|
||||||
#===========================================================
|
#===========================================================
|
||||||
# Annotations JNDI JASS processing
|
# Annotations JNDI JAAS processing
|
||||||
#-----------------------------------------------------------
|
#-----------------------------------------------------------
|
||||||
# OPTIONS=annotations
|
|
||||||
# OPTIONS=plus
|
# OPTIONS=plus
|
||||||
# etc/jetty-plus.xml
|
# etc/jetty-plus.xml
|
||||||
|
# OPTIONS=annotations
|
||||||
# etc/jetty-annotations.xml
|
# etc/jetty-annotations.xml
|
||||||
#===========================================================
|
#===========================================================
|
||||||
|
|
||||||
|
|
|
@ -30,12 +30,12 @@ import org.eclipse.jetty.util.thread.Scheduler;
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/** An Abstract implementation of an Idle Timeout.
|
/** An Abstract implementation of an Idle Timeout.
|
||||||
*
|
*
|
||||||
* This implementation is optimised that timeout operations are not cancelled on
|
* This implementation is optimised that timeout operations are not cancelled on
|
||||||
* every operation. Rather timeout are allowed to expire and a check is then made
|
* every operation. Rather timeout are allowed to expire and a check is then made
|
||||||
* to see when the last operation took place. If the idle timeout has not expired,
|
* to see when the last operation took place. If the idle timeout has not expired,
|
||||||
* the timeout is rescheduled for the earliest possible time a timeout could occur.
|
* the timeout is rescheduled for the earliest possible time a timeout could occur.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public abstract class IdleTimeout
|
public abstract class IdleTimeout
|
||||||
{
|
{
|
||||||
|
@ -44,7 +44,7 @@ public abstract class IdleTimeout
|
||||||
private final AtomicReference<Scheduler.Task> _timeout = new AtomicReference<>();
|
private final AtomicReference<Scheduler.Task> _timeout = new AtomicReference<>();
|
||||||
private volatile long _idleTimeout;
|
private volatile long _idleTimeout;
|
||||||
private volatile long _idleTimestamp=System.currentTimeMillis();
|
private volatile long _idleTimestamp=System.currentTimeMillis();
|
||||||
|
|
||||||
private final Runnable _idleTask = new Runnable()
|
private final Runnable _idleTask = new Runnable()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
|
@ -63,12 +63,12 @@ public abstract class IdleTimeout
|
||||||
{
|
{
|
||||||
_scheduler=scheduler;
|
_scheduler=scheduler;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getIdleTimestamp()
|
public long getIdleTimestamp()
|
||||||
{
|
{
|
||||||
return _idleTimestamp;
|
return _idleTimestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getIdleTimeout()
|
public long getIdleTimeout()
|
||||||
{
|
{
|
||||||
return _idleTimeout;
|
return _idleTimeout;
|
||||||
|
@ -78,22 +78,22 @@ public abstract class IdleTimeout
|
||||||
{
|
{
|
||||||
long old=_idleTimeout;
|
long old=_idleTimeout;
|
||||||
_idleTimeout = idleTimeout;
|
_idleTimeout = idleTimeout;
|
||||||
|
|
||||||
// Do we have an old timeout
|
// Do we have an old timeout
|
||||||
if (old>0)
|
if (old>0)
|
||||||
{
|
{
|
||||||
// if the old was less than or equal to the new timeout, then nothing more to do
|
// if the old was less than or equal to the new timeout, then nothing more to do
|
||||||
if (old<=_idleTimeout)
|
if (old<=idleTimeout)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// old timeout is too long, so cancel it.
|
// old timeout is too long, so cancel it.
|
||||||
Scheduler.Task oldTimeout = _timeout.getAndSet(null);
|
Scheduler.Task oldTimeout = _timeout.getAndSet(null);
|
||||||
if (oldTimeout != null)
|
if (oldTimeout != null)
|
||||||
oldTimeout.cancel();
|
oldTimeout.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have a new timeout, then check and reschedule
|
// If we have a new timeout, then check and reschedule
|
||||||
if (_idleTimeout>0 && isOpen())
|
if (idleTimeout>0 && isOpen())
|
||||||
_idleTask.run();
|
_idleTask.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ public abstract class IdleTimeout
|
||||||
{
|
{
|
||||||
_idleTimestamp=System.currentTimeMillis();
|
_idleTimestamp=System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void scheduleIdleTimeout(long delay)
|
private void scheduleIdleTimeout(long delay)
|
||||||
{
|
{
|
||||||
Scheduler.Task newTimeout = null;
|
Scheduler.Task newTimeout = null;
|
||||||
|
@ -113,20 +113,20 @@ public abstract class IdleTimeout
|
||||||
if (oldTimeout != null)
|
if (oldTimeout != null)
|
||||||
oldTimeout.cancel();
|
oldTimeout.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onOpen()
|
public void onOpen()
|
||||||
{
|
{
|
||||||
if (_idleTimeout>0)
|
if (_idleTimeout>0)
|
||||||
_idleTask.run();
|
_idleTask.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void close()
|
protected void close()
|
||||||
{
|
{
|
||||||
Scheduler.Task oldTimeout = _timeout.getAndSet(null);
|
Scheduler.Task oldTimeout = _timeout.getAndSet(null);
|
||||||
if (oldTimeout != null)
|
if (oldTimeout != null)
|
||||||
oldTimeout.cancel();
|
oldTimeout.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected long checkIdleTimeout()
|
protected long checkIdleTimeout()
|
||||||
{
|
{
|
||||||
if (isOpen())
|
if (isOpen())
|
||||||
|
@ -158,14 +158,14 @@ public abstract class IdleTimeout
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/** This abstract method is called when the idle timeout has expired.
|
/** This abstract method is called when the idle timeout has expired.
|
||||||
* @param timeout a TimeoutException
|
* @param timeout a TimeoutException
|
||||||
*/
|
*/
|
||||||
abstract protected void onIdleExpired(TimeoutException timeout);
|
abstract protected void onIdleExpired(TimeoutException timeout);
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/** This abstract method should be called to check if idle timeouts
|
/** This abstract method should be called to check if idle timeouts
|
||||||
* should still be checked.
|
* should still be checked.
|
||||||
|
|
|
@ -100,7 +100,7 @@ public class SslConnection extends AbstractConnection
|
||||||
_decryptedEndPoint.getWriteFlusher().completeWrite();
|
_decryptedEndPoint.getWriteFlusher().completeWrite();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public SslConnection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, SSLEngine sslEngine)
|
public SslConnection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, SSLEngine sslEngine)
|
||||||
{
|
{
|
||||||
// This connection does not execute calls to onfillable, so they will be called by the selector thread.
|
// This connection does not execute calls to onfillable, so they will be called by the selector thread.
|
||||||
|
@ -109,7 +109,7 @@ public class SslConnection extends AbstractConnection
|
||||||
this._bufferPool = byteBufferPool;
|
this._bufferPool = byteBufferPool;
|
||||||
this._sslEngine = sslEngine;
|
this._sslEngine = sslEngine;
|
||||||
this._decryptedEndPoint = newDecryptedEndPoint();
|
this._decryptedEndPoint = newDecryptedEndPoint();
|
||||||
|
|
||||||
if (endPoint instanceof SocketBased)
|
if (endPoint instanceof SocketBased)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -220,7 +220,6 @@ public class SslConnection extends AbstractConnection
|
||||||
// the decrypted readInterest and/or writeFlusher so that they will attempt
|
// the decrypted readInterest and/or writeFlusher so that they will attempt
|
||||||
// to do the fill and/or flush again and these calls will do the actually
|
// to do the fill and/or flush again and these calls will do the actually
|
||||||
// handle the cause.
|
// handle the cause.
|
||||||
|
|
||||||
synchronized(_decryptedEndPoint)
|
synchronized(_decryptedEndPoint)
|
||||||
{
|
{
|
||||||
_decryptedEndPoint.getFillInterest().onFail(cause);
|
_decryptedEndPoint.getFillInterest().onFail(cause);
|
||||||
|
@ -480,13 +479,13 @@ public class SslConnection extends AbstractConnection
|
||||||
LOG.debug("{} filled {} encrypted bytes", SslConnection.this, net_filled);
|
LOG.debug("{} filled {} encrypted bytes", SslConnection.this, net_filled);
|
||||||
if (net_filled > 0)
|
if (net_filled > 0)
|
||||||
_underFlown = false;
|
_underFlown = false;
|
||||||
|
|
||||||
// Let's try the SSL thang even if we have no net data because in that
|
// Let's try the SSL thang even if we have no net data because in that
|
||||||
// case we want to fall through to the handshake handling
|
// case we want to fall through to the handshake handling
|
||||||
int pos = BufferUtil.flipToFill(app_in);
|
int pos = BufferUtil.flipToFill(app_in);
|
||||||
|
|
||||||
SSLEngineResult unwrapResult = _sslEngine.unwrap(_encryptedInput, app_in);
|
SSLEngineResult unwrapResult = _sslEngine.unwrap(_encryptedInput, app_in);
|
||||||
|
|
||||||
BufferUtil.flipToFlush(app_in, pos);
|
BufferUtil.flipToFlush(app_in, pos);
|
||||||
if (DEBUG)
|
if (DEBUG)
|
||||||
LOG.debug("{} unwrap {}", SslConnection.this, unwrapResult);
|
LOG.debug("{} unwrap {}", SslConnection.this, unwrapResult);
|
||||||
|
@ -661,7 +660,7 @@ public class SslConnection extends AbstractConnection
|
||||||
BufferUtil.flipToFlush(_encryptedOutput, pos);
|
BufferUtil.flipToFlush(_encryptedOutput, pos);
|
||||||
if (wrapResult.bytesConsumed()>0)
|
if (wrapResult.bytesConsumed()>0)
|
||||||
consumed+=wrapResult.bytesConsumed();
|
consumed+=wrapResult.bytesConsumed();
|
||||||
|
|
||||||
boolean all_consumed=true;
|
boolean all_consumed=true;
|
||||||
// clear empty buffers to prevent position creeping up the buffer
|
// clear empty buffers to prevent position creeping up the buffer
|
||||||
for (ByteBuffer b : appOuts)
|
for (ByteBuffer b : appOuts)
|
||||||
|
|
|
@ -20,11 +20,9 @@ package org.eclipse.jetty.io;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.SocketChannel;
|
import java.nio.channels.SocketChannel;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import javax.net.ssl.SSLEngine;
|
import javax.net.ssl.SSLEngine;
|
||||||
import javax.net.ssl.SSLEngineResult;
|
import javax.net.ssl.SSLEngineResult;
|
||||||
import javax.net.ssl.SSLEngineResult.HandshakeStatus;
|
import javax.net.ssl.SSLEngineResult.HandshakeStatus;
|
||||||
|
@ -42,9 +40,7 @@ import org.junit.Test;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.greaterThan;
|
import static org.hamcrest.Matchers.greaterThan;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
|
|
||||||
public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest
|
public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest
|
||||||
|
@ -226,51 +222,6 @@ public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest
|
||||||
super.testIdle();
|
super.testIdle();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void testBlockedReadIdle() throws Exception
|
|
||||||
{
|
|
||||||
Socket client = newClient();
|
|
||||||
OutputStream clientOutputStream = client.getOutputStream();
|
|
||||||
|
|
||||||
client.setSoTimeout(5000);
|
|
||||||
|
|
||||||
SocketChannel server = _connector.accept();
|
|
||||||
server.configureBlocking(false);
|
|
||||||
|
|
||||||
_manager.accept(server);
|
|
||||||
|
|
||||||
// Write client to server
|
|
||||||
clientOutputStream.write("HelloWorld".getBytes("UTF-8"));
|
|
||||||
|
|
||||||
// Verify echo server to client
|
|
||||||
for (char c : "HelloWorld".toCharArray())
|
|
||||||
{
|
|
||||||
int b = client.getInputStream().read();
|
|
||||||
assertTrue(b>0);
|
|
||||||
assertEquals(c,(char)b);
|
|
||||||
}
|
|
||||||
|
|
||||||
assertTrue(_lastEndPointLatch.await(1, TimeUnit.SECONDS));
|
|
||||||
_lastEndPoint.setIdleTimeout(500);
|
|
||||||
|
|
||||||
// Write 8 and cause block waiting for 10
|
|
||||||
_blockAt=10;
|
|
||||||
clientOutputStream.write("12345678".getBytes("UTF-8"));
|
|
||||||
clientOutputStream.flush();
|
|
||||||
|
|
||||||
// read until idle shutdown received
|
|
||||||
long start=System.currentTimeMillis();
|
|
||||||
int b=client.getInputStream().read();
|
|
||||||
assertEquals(-1,b);
|
|
||||||
long idle=System.currentTimeMillis()-start;
|
|
||||||
assertTrue(idle>400);
|
|
||||||
assertTrue(idle<2000);
|
|
||||||
|
|
||||||
Thread.sleep(1000);
|
|
||||||
|
|
||||||
assertFalse(_lastEndPoint.isOpen());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Override
|
@Override
|
||||||
@Stress("Requires a relatively idle (network wise) environment")
|
@Stress("Requires a relatively idle (network wise) environment")
|
||||||
|
|
|
@ -18,12 +18,6 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.io;
|
package org.eclipse.jetty.io;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.greaterThan;
|
|
||||||
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertFalse;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.BufferedOutputStream;
|
import java.io.BufferedOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -52,6 +46,12 @@ import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.greaterThan;
|
||||||
|
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
public class SelectChannelEndPointTest
|
public class SelectChannelEndPointTest
|
||||||
{
|
{
|
||||||
private static final Logger LOG = Log.getLogger(SelectChannelEndPointTest.class);
|
private static final Logger LOG = Log.getLogger(SelectChannelEndPointTest.class);
|
||||||
|
@ -220,7 +220,7 @@ public class SelectChannelEndPointTest
|
||||||
{
|
{
|
||||||
Socket client = newClient();
|
Socket client = newClient();
|
||||||
|
|
||||||
client.setSoTimeout(60000);
|
client.setSoTimeout(60000);
|
||||||
|
|
||||||
SocketChannel server = _connector.accept();
|
SocketChannel server = _connector.accept();
|
||||||
server.configureBlocking(false);
|
server.configureBlocking(false);
|
||||||
|
@ -425,6 +425,7 @@ public class SelectChannelEndPointTest
|
||||||
public void testBlockedReadIdle() throws Exception
|
public void testBlockedReadIdle() throws Exception
|
||||||
{
|
{
|
||||||
Socket client = newClient();
|
Socket client = newClient();
|
||||||
|
InputStream clientInputStream = client.getInputStream();
|
||||||
OutputStream clientOutputStream = client.getOutputStream();
|
OutputStream clientOutputStream = client.getOutputStream();
|
||||||
|
|
||||||
client.setSoTimeout(5000);
|
client.setSoTimeout(5000);
|
||||||
|
@ -440,7 +441,7 @@ public class SelectChannelEndPointTest
|
||||||
// Verify echo server to client
|
// Verify echo server to client
|
||||||
for (char c : "HelloWorld".toCharArray())
|
for (char c : "HelloWorld".toCharArray())
|
||||||
{
|
{
|
||||||
int b = client.getInputStream().read();
|
int b = clientInputStream.read();
|
||||||
assertTrue(b > 0);
|
assertTrue(b > 0);
|
||||||
assertEquals(c, (char)b);
|
assertEquals(c, (char)b);
|
||||||
}
|
}
|
||||||
|
@ -456,7 +457,7 @@ public class SelectChannelEndPointTest
|
||||||
|
|
||||||
// read until idle shutdown received
|
// read until idle shutdown received
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
int b = client.getInputStream().read();
|
int b = clientInputStream.read();
|
||||||
assertEquals('E', b);
|
assertEquals('E', b);
|
||||||
long idle = System.currentTimeMillis() - start;
|
long idle = System.currentTimeMillis() - start;
|
||||||
assertTrue(idle > idleTimeout / 2);
|
assertTrue(idle > idleTimeout / 2);
|
||||||
|
@ -464,10 +465,12 @@ public class SelectChannelEndPointTest
|
||||||
|
|
||||||
for (char c : "E: 12345678".toCharArray())
|
for (char c : "E: 12345678".toCharArray())
|
||||||
{
|
{
|
||||||
b = client.getInputStream().read();
|
b = clientInputStream.read();
|
||||||
assertTrue(b > 0);
|
assertTrue(b > 0);
|
||||||
assertEquals(c, (char)b);
|
assertEquals(c, (char)b);
|
||||||
}
|
}
|
||||||
|
b = clientInputStream.read();
|
||||||
|
assertEquals(-1,b);
|
||||||
|
|
||||||
// But endpoint is still open.
|
// But endpoint is still open.
|
||||||
if(_lastEndPoint.isOpen())
|
if(_lastEndPoint.isOpen())
|
||||||
|
|
|
@ -67,9 +67,7 @@
|
||||||
<Item>org.eclipse.jetty.webapp.FragmentConfiguration</Item>
|
<Item>org.eclipse.jetty.webapp.FragmentConfiguration</Item>
|
||||||
<Item>org.eclipse.jetty.plus.webapp.EnvConfiguration</Item>
|
<Item>org.eclipse.jetty.plus.webapp.EnvConfiguration</Item>
|
||||||
<Item>org.eclipse.jetty.plus.webapp.PlusConfiguration</Item>
|
<Item>org.eclipse.jetty.plus.webapp.PlusConfiguration</Item>
|
||||||
<Item>org.eclipse.jetty.annotations.AnnotationConfiguration</Item>
|
|
||||||
<Item>org.eclipse.jetty.webapp.JettyWebXmlConfiguration</Item>
|
<Item>org.eclipse.jetty.webapp.JettyWebXmlConfiguration</Item>
|
||||||
<Item>org.eclipse.jetty.webapp.TagLibConfiguration</Item>
|
|
||||||
</Array>
|
</Array>
|
||||||
|
|
||||||
<!-- =========================================================== -->
|
<!-- =========================================================== -->
|
||||||
|
@ -86,7 +84,6 @@
|
||||||
<Set name="monitoredDirName"><Property name="jetty.home" default="." />/webapps-plus</Set>
|
<Set name="monitoredDirName"><Property name="jetty.home" default="." />/webapps-plus</Set>
|
||||||
<Set name="defaultsDescriptor"><Property name="jetty.home" default="."/>/etc/webdefault.xml</Set>
|
<Set name="defaultsDescriptor"><Property name="jetty.home" default="."/>/etc/webdefault.xml</Set>
|
||||||
<Set name="scanInterval">5</Set>
|
<Set name="scanInterval">5</Set>
|
||||||
<Set name="contextXmlDir"><Property name="jetty.home" default="." />/contexts</Set>
|
|
||||||
<Set name="parentLoaderPriority">false</Set>
|
<Set name="parentLoaderPriority">false</Set>
|
||||||
<Set name="extractWars">true</Set>
|
<Set name="extractWars">true</Set>
|
||||||
<Set name="configurationClasses"><Ref id="plusConfig"/></Set>
|
<Set name="configurationClasses"><Ref id="plusConfig"/></Set>
|
||||||
|
|
|
@ -43,7 +43,6 @@ import org.eclipse.jetty.client.api.Request;
|
||||||
import org.eclipse.jetty.client.api.Response;
|
import org.eclipse.jetty.client.api.Response;
|
||||||
import org.eclipse.jetty.client.api.Result;
|
import org.eclipse.jetty.client.api.Result;
|
||||||
import org.eclipse.jetty.client.util.InputStreamContentProvider;
|
import org.eclipse.jetty.client.util.InputStreamContentProvider;
|
||||||
import org.eclipse.jetty.client.util.TimedResponseListener;
|
|
||||||
import org.eclipse.jetty.http.HttpField;
|
import org.eclipse.jetty.http.HttpField;
|
||||||
import org.eclipse.jetty.http.HttpMethod;
|
import org.eclipse.jetty.http.HttpMethod;
|
||||||
import org.eclipse.jetty.http.HttpVersion;
|
import org.eclipse.jetty.http.HttpVersion;
|
||||||
|
@ -221,7 +220,7 @@ public class ProxyServlet extends HttpServlet
|
||||||
* <tr>
|
* <tr>
|
||||||
* <td>timeout</td>
|
* <td>timeout</td>
|
||||||
* <td>60000</td>
|
* <td>60000</td>
|
||||||
* <td>The total timeout in milliseconds, see {@link TimedResponseListener}</td>
|
* <td>The total timeout in milliseconds, see {@link Request#timeout(long, TimeUnit)}</td>
|
||||||
* </tr>
|
* </tr>
|
||||||
* <tr>
|
* <tr>
|
||||||
* <td>requestBufferSize</td>
|
* <td>requestBufferSize</td>
|
||||||
|
@ -463,7 +462,8 @@ public class ProxyServlet extends HttpServlet
|
||||||
proxyRequest.getHeaders().toString().trim());
|
proxyRequest.getHeaders().toString().trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
proxyRequest.send(new TimedResponseListener(getTimeout(), TimeUnit.MILLISECONDS, proxyRequest, new ProxyResponseListener(request, response)));
|
proxyRequest.timeout(getTimeout(), TimeUnit.MILLISECONDS);
|
||||||
|
proxyRequest.send(new ProxyResponseListener(request, response));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onResponseHeaders(HttpServletRequest request, HttpServletResponse response, Response proxyResponse)
|
protected void onResponseHeaders(HttpServletRequest request, HttpServletResponse response, Response proxyResponse)
|
||||||
|
|
|
@ -109,7 +109,7 @@ public class BalancerServletTest
|
||||||
|
|
||||||
private int getServerPort(Server server)
|
private int getServerPort(Server server)
|
||||||
{
|
{
|
||||||
return ((NetworkConnector)server.getConnectors()[0]).getLocalPort();
|
return server.getURI().getPort();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected byte[] sendRequestToBalancer(String path) throws Exception
|
protected byte[] sendRequestToBalancer(String path) throws Exception
|
||||||
|
|
|
@ -172,21 +172,21 @@ public class Runner
|
||||||
if (error!=null)
|
if (error!=null)
|
||||||
System.err.println("ERROR: "+error);
|
System.err.println("ERROR: "+error);
|
||||||
System.err.println("Usage: java [-Djetty.home=dir] -jar jetty-runner.jar [--help|--version] [ server opts] [[ context opts] context ...] ");
|
System.err.println("Usage: java [-Djetty.home=dir] -jar jetty-runner.jar [--help|--version] [ server opts] [[ context opts] context ...] ");
|
||||||
System.err.println("Server Options:");
|
System.err.println("Server opts:");
|
||||||
System.err.println(" --version - display version and exit");
|
System.err.println(" --version - display version and exit");
|
||||||
System.err.println(" --log file - request log filename (with optional 'yyyy_mm_dd' wildcard");
|
System.err.println(" --log file - request log filename (with optional 'yyyy_mm_dd' wildcard");
|
||||||
System.err.println(" --out file - info/warn/debug log filename (with optional 'yyyy_mm_dd' wildcard");
|
System.err.println(" --out file - info/warn/debug log filename (with optional 'yyyy_mm_dd' wildcard");
|
||||||
System.err.println(" --port n - port to listen on (default 8080)");
|
System.err.println(" --host name|ip - interface to listen on (default is all interfaces)");
|
||||||
System.err.println(" --stop-port n - port to listen for stop command");
|
System.err.println(" --port n - port to listen on (default 8080)");
|
||||||
System.err.println(" --stop-key n - security string for stop command (required if --stop-port is present)");
|
System.err.println(" --stop-port n - port to listen for stop command");
|
||||||
System.err.println(" --jar file - a jar to be added to the classloader");
|
System.err.println(" --stop-key n - security string for stop command (required if --stop-port is present)");
|
||||||
System.err.println(" --lib dir - a directory of jars to be added to the classloader");
|
System.err.println(" [--jar file]*n - each tuple specifies an extra jar to be added to the classloader");
|
||||||
System.err.println(" --classes dir - a directory of classes to be added to the classloader");
|
System.err.println(" [--lib dir]*n - each tuple specifies an extra directory of jars to be added to the classloader");
|
||||||
|
System.err.println(" [--classes dir]*n - each tuple specifies an extra directory of classes to be added to the classloader");
|
||||||
System.err.println(" --stats [unsecure|realm.properties] - enable stats gathering servlet context");
|
System.err.println(" --stats [unsecure|realm.properties] - enable stats gathering servlet context");
|
||||||
System.err.println(" [--config file]*n - each --config parameter specifies the name of a jetty xml config file to apply (in the order defined)");
|
System.err.println(" [--config file]*n - each tuple specifies the name of a jetty xml config file to apply (in the order defined)");
|
||||||
System.err.println("Context Options:");
|
System.err.println("Context opts:");
|
||||||
System.err.println(" --path /path - context path (default /)");
|
System.err.println(" [[--path /path] context]*n - WAR file, web app dir or context xml file, optionally with a context path");
|
||||||
System.err.println(" context - WAR file, web app dir or context xml file");
|
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,6 +246,7 @@ public class Runner
|
||||||
String contextPath = __defaultContextPath;
|
String contextPath = __defaultContextPath;
|
||||||
boolean contextPathSet = false;
|
boolean contextPathSet = false;
|
||||||
int port = __defaultPort;
|
int port = __defaultPort;
|
||||||
|
String host = null;
|
||||||
int stopPort = 0;
|
int stopPort = 0;
|
||||||
String stopKey = null;
|
String stopKey = null;
|
||||||
|
|
||||||
|
@ -255,6 +256,8 @@ public class Runner
|
||||||
{
|
{
|
||||||
if ("--port".equals(args[i]))
|
if ("--port".equals(args[i]))
|
||||||
port=Integer.parseInt(args[++i]);
|
port=Integer.parseInt(args[++i]);
|
||||||
|
else if ("--host".equals(args[i]))
|
||||||
|
host=args[++i];
|
||||||
else if ("--stop-port".equals(args[i]))
|
else if ("--stop-port".equals(args[i]))
|
||||||
stopPort=Integer.parseInt(args[++i]);
|
stopPort=Integer.parseInt(args[++i]);
|
||||||
else if ("--stop-key".equals(args[i]))
|
else if ("--stop-key".equals(args[i]))
|
||||||
|
@ -393,6 +396,8 @@ public class Runner
|
||||||
{
|
{
|
||||||
ServerConnector connector = new ServerConnector(_server);
|
ServerConnector connector = new ServerConnector(_server);
|
||||||
connector.setPort(port);
|
connector.setPort(port);
|
||||||
|
if (host != null)
|
||||||
|
connector.setHost(host);
|
||||||
_server.addConnector(connector);
|
_server.addConnector(connector);
|
||||||
if (_enableStats)
|
if (_enableStats)
|
||||||
connector.addBean(new ConnectorStatistics());
|
connector.addBean(new ConnectorStatistics());
|
||||||
|
|
|
@ -19,7 +19,11 @@
|
||||||
package org.eclipse.jetty.server;
|
package org.eclipse.jetty.server;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.Inet4Address;
|
||||||
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -35,14 +39,18 @@ import javax.servlet.ServletContext;
|
||||||
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;
|
||||||
|
import javax.xml.validation.Schema;
|
||||||
|
|
||||||
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.HttpGenerator;
|
import org.eclipse.jetty.http.HttpGenerator;
|
||||||
import org.eclipse.jetty.http.HttpHeader;
|
import org.eclipse.jetty.http.HttpHeader;
|
||||||
import org.eclipse.jetty.http.HttpMethod;
|
import org.eclipse.jetty.http.HttpMethod;
|
||||||
|
import org.eclipse.jetty.http.HttpScheme;
|
||||||
import org.eclipse.jetty.http.HttpStatus;
|
import org.eclipse.jetty.http.HttpStatus;
|
||||||
import org.eclipse.jetty.http.HttpURI;
|
import org.eclipse.jetty.http.HttpURI;
|
||||||
|
import org.eclipse.jetty.http.HttpVersion;
|
||||||
|
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||||
import org.eclipse.jetty.server.handler.HandlerWrapper;
|
import org.eclipse.jetty.server.handler.HandlerWrapper;
|
||||||
import org.eclipse.jetty.util.Attributes;
|
import org.eclipse.jetty.util.Attributes;
|
||||||
import org.eclipse.jetty.util.AttributesMap;
|
import org.eclipse.jetty.util.AttributesMap;
|
||||||
|
@ -580,6 +588,49 @@ public class Server extends HandlerWrapper implements Attributes
|
||||||
_attributes.setAttribute(name, attribute);
|
_attributes.setAttribute(name, attribute);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @return The URI of the first {@link NetworkConnector} and first {@link ContextHandler}, or null
|
||||||
|
*/
|
||||||
|
public URI getURI()
|
||||||
|
{
|
||||||
|
NetworkConnector connector=null;
|
||||||
|
for (Connector c: _connectors)
|
||||||
|
{
|
||||||
|
if (c instanceof NetworkConnector)
|
||||||
|
{
|
||||||
|
connector=(NetworkConnector)c;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connector==null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
ContextHandler context = getChildHandlerByClass(ContextHandler.class);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String scheme=connector.getDefaultConnectionFactory().getProtocol().startsWith("SSL-")?"https":"http";
|
||||||
|
|
||||||
|
String host=connector.getHost();
|
||||||
|
if (context!=null && context.getVirtualHosts()!=null && context.getVirtualHosts().length>0)
|
||||||
|
host=context.getVirtualHosts()[0];
|
||||||
|
if (host==null)
|
||||||
|
host=InetAddress.getLocalHost().getHostAddress();
|
||||||
|
|
||||||
|
String path=context==null?null:context.getContextPath();
|
||||||
|
if (path==null)
|
||||||
|
path="/";
|
||||||
|
return new URI(scheme,null,host,connector.getLocalPort(),path,null,null);
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
LOG.warn(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
|
|
|
@ -255,7 +255,7 @@ public class ShutdownMonitor extends Thread
|
||||||
{
|
{
|
||||||
if (isAlive())
|
if (isAlive())
|
||||||
{
|
{
|
||||||
System.out.printf("ShutdownMonitor already started");
|
System.err.printf("ShutdownMonitor already started");
|
||||||
return; // cannot start it again
|
return; // cannot start it again
|
||||||
}
|
}
|
||||||
startListenSocket();
|
startListenSocket();
|
||||||
|
@ -270,8 +270,9 @@ public class ShutdownMonitor extends Thread
|
||||||
private void startListenSocket()
|
private void startListenSocket()
|
||||||
{
|
{
|
||||||
if (this.port < 0)
|
if (this.port < 0)
|
||||||
{
|
{
|
||||||
System.out.println("ShutdownMonitor not in use (port < 0): " + port);
|
if (DEBUG)
|
||||||
|
System.err.println("ShutdownMonitor not in use (port < 0): " + port);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -123,23 +123,6 @@ public class HandlerWrapper extends AbstractHandlerContainer
|
||||||
expandHandler(_handler,list,byClass);
|
expandHandler(_handler,list,byClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public <H extends Handler> H getNestedHandlerByClass(Class<H> byclass)
|
|
||||||
{
|
|
||||||
HandlerWrapper h=this;
|
|
||||||
while (h!=null)
|
|
||||||
{
|
|
||||||
if (byclass.isInstance(h))
|
|
||||||
return (H)h;
|
|
||||||
Handler w = h.getHandler();
|
|
||||||
if (w instanceof HandlerWrapper)
|
|
||||||
h=(HandlerWrapper)w;
|
|
||||||
else break;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
@Override
|
@Override
|
||||||
public void destroy()
|
public void destroy()
|
||||||
|
|
|
@ -24,6 +24,7 @@ import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.ObjectInputStream;
|
import java.io.ObjectInputStream;
|
||||||
|
import java.net.URI;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -466,9 +467,11 @@ public class HashSessionManager extends AbstractSessionManager
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
public void setStoreDirectory (File dir)
|
public void setStoreDirectory (File dir) throws IOException
|
||||||
{
|
{
|
||||||
_storeDir=dir;
|
// CanonicalFile is used to capture the base store directory in a way that will
|
||||||
|
// work on Windows. Case differences may through off later checks using this directory.
|
||||||
|
_storeDir=dir.getCanonicalFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@ -526,8 +529,9 @@ public class HashSessionManager extends AbstractSessionManager
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
protected synchronized HashedSession restoreSession(String idInCuster)
|
protected synchronized HashedSession restoreSession(String idInCuster)
|
||||||
{
|
{
|
||||||
File file = new File(_storeDir,idInCuster);
|
File file = new File(_storeDir,idInCuster);
|
||||||
|
|
||||||
FileInputStream in = null;
|
FileInputStream in = null;
|
||||||
Exception error = null;
|
Exception error = null;
|
||||||
try
|
try
|
||||||
|
@ -552,13 +556,15 @@ public class HashSessionManager extends AbstractSessionManager
|
||||||
|
|
||||||
if (error != null)
|
if (error != null)
|
||||||
{
|
{
|
||||||
if (isDeleteUnrestorableSessions() && file.exists())
|
if (isDeleteUnrestorableSessions() && file.exists() && file.getParentFile().equals(_storeDir) )
|
||||||
{
|
{
|
||||||
file.delete();
|
file.delete();
|
||||||
LOG.warn("Deleting file for unrestorable session "+idInCuster, error);
|
LOG.warn("Deleting file for unrestorable session "+idInCuster, error);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LOG.warn("Problem restoring session "+idInCuster, error);
|
{
|
||||||
|
__log.warn("Problem restoring session "+idInCuster, error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
file.delete(); //delete successfully restored file
|
file.delete(); //delete successfully restored file
|
||||||
|
|
|
@ -25,6 +25,7 @@ import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
|
import java.net.URI;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@ -59,7 +60,8 @@ public abstract class ConnectorCloseTestBase extends HttpServerTestFixture
|
||||||
|
|
||||||
configureServer(new HelloWorldHandler());
|
configureServer(new HelloWorldHandler());
|
||||||
|
|
||||||
Socket client = newSocket(HOST,_connector.getLocalPort());
|
URI uri = _server.getURI();
|
||||||
|
Socket client = newSocket(uri.getHost(),uri.getPort());
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
OutputStream os = client.getOutputStream();
|
OutputStream os = client.getOutputStream();
|
||||||
|
@ -101,7 +103,7 @@ public abstract class ConnectorCloseTestBase extends HttpServerTestFixture
|
||||||
|
|
||||||
String request =
|
String request =
|
||||||
"GET /data?writes=1&block=16&id="+pipeline+" HTTP/1.1\r\n"+
|
"GET /data?writes=1&block=16&id="+pipeline+" HTTP/1.1\r\n"+
|
||||||
"host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
|
"host: "+uri.getHost()+":"+uri.getPort()+"\r\n"+
|
||||||
"user-agent: testharness/1.0 (blah foo/bar)\r\n"+
|
"user-agent: testharness/1.0 (blah foo/bar)\r\n"+
|
||||||
"accept-encoding: nothing\r\n"+
|
"accept-encoding: nothing\r\n"+
|
||||||
"cookie: aaa=1234567890\r\n"+
|
"cookie: aaa=1234567890\r\n"+
|
||||||
|
@ -135,7 +137,8 @@ public abstract class ConnectorCloseTestBase extends HttpServerTestFixture
|
||||||
{
|
{
|
||||||
configureServer(new EchoHandler());
|
configureServer(new EchoHandler());
|
||||||
|
|
||||||
Socket client = newSocket(HOST,_connector.getLocalPort());
|
URI uri = _server.getURI();
|
||||||
|
Socket client = newSocket(uri.getHost(),uri.getPort());
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
OutputStream os = client.getOutputStream();
|
OutputStream os = client.getOutputStream();
|
||||||
|
@ -148,7 +151,7 @@ public abstract class ConnectorCloseTestBase extends HttpServerTestFixture
|
||||||
|
|
||||||
os.write((
|
os.write((
|
||||||
"POST /echo?charset=utf-8 HTTP/1.1\r\n"+
|
"POST /echo?charset=utf-8 HTTP/1.1\r\n"+
|
||||||
"host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
|
"host: "+uri.getHost()+":"+uri.getPort()+"\r\n"+
|
||||||
"content-type: text/plain; charset=utf-8\r\n"+
|
"content-type: text/plain; charset=utf-8\r\n"+
|
||||||
"content-length: "+bytes.length+"\r\n"+
|
"content-length: "+bytes.length+"\r\n"+
|
||||||
"\r\n"
|
"\r\n"
|
||||||
|
|
|
@ -60,7 +60,8 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
||||||
public void testMaxIdleWithRequest10() throws Exception
|
public void testMaxIdleWithRequest10() throws Exception
|
||||||
{
|
{
|
||||||
configureServer(new HelloWorldHandler());
|
configureServer(new HelloWorldHandler());
|
||||||
Socket client=newSocket(HOST,_connector.getLocalPort());
|
|
||||||
|
Socket client=newSocket(_serverURI.getHost(),_serverURI.getPort());
|
||||||
client.setSoTimeout(10000);
|
client.setSoTimeout(10000);
|
||||||
|
|
||||||
assertFalse(client.isClosed());
|
assertFalse(client.isClosed());
|
||||||
|
@ -70,7 +71,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
||||||
|
|
||||||
os.write((
|
os.write((
|
||||||
"GET / HTTP/1.0\r\n"+
|
"GET / HTTP/1.0\r\n"+
|
||||||
"host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
|
"host: "+_serverURI.getHost()+":"+_serverURI.getPort()+"\r\n"+
|
||||||
"connection: keep-alive\r\n"+
|
"connection: keep-alive\r\n"+
|
||||||
"\r\n").getBytes("utf-8"));
|
"\r\n").getBytes("utf-8"));
|
||||||
os.flush();
|
os.flush();
|
||||||
|
@ -89,7 +90,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
||||||
public void testMaxIdleWithRequest11() throws Exception
|
public void testMaxIdleWithRequest11() throws Exception
|
||||||
{
|
{
|
||||||
configureServer(new EchoHandler());
|
configureServer(new EchoHandler());
|
||||||
Socket client=newSocket(HOST,_connector.getLocalPort());
|
Socket client=newSocket(_serverURI.getHost(),_serverURI.getPort());
|
||||||
client.setSoTimeout(10000);
|
client.setSoTimeout(10000);
|
||||||
|
|
||||||
assertFalse(client.isClosed());
|
assertFalse(client.isClosed());
|
||||||
|
@ -101,7 +102,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
||||||
byte[] contentB=content.getBytes("utf-8");
|
byte[] contentB=content.getBytes("utf-8");
|
||||||
os.write((
|
os.write((
|
||||||
"POST /echo HTTP/1.1\r\n"+
|
"POST /echo HTTP/1.1\r\n"+
|
||||||
"host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
|
"host: "+_serverURI.getHost()+":"+_serverURI.getPort()+"\r\n"+
|
||||||
"content-type: text/plain; charset=utf-8\r\n"+
|
"content-type: text/plain; charset=utf-8\r\n"+
|
||||||
"content-length: "+contentB.length+"\r\n"+
|
"content-length: "+contentB.length+"\r\n"+
|
||||||
"\r\n").getBytes("utf-8"));
|
"\r\n").getBytes("utf-8"));
|
||||||
|
@ -140,7 +141,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
Socket client=newSocket(HOST,_connector.getLocalPort());
|
Socket client=newSocket(_serverURI.getHost(),_serverURI.getPort());
|
||||||
client.setSoTimeout(10000);
|
client.setSoTimeout(10000);
|
||||||
|
|
||||||
assertFalse(client.isClosed());
|
assertFalse(client.isClosed());
|
||||||
|
@ -150,7 +151,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
||||||
|
|
||||||
os.write((
|
os.write((
|
||||||
"GET / HTTP/1.0\r\n"+
|
"GET / HTTP/1.0\r\n"+
|
||||||
"host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
|
"host: "+_serverURI.getHost()+":"+_serverURI.getPort()+"\r\n"+
|
||||||
"connection: close\r\n"+
|
"connection: close\r\n"+
|
||||||
"\r\n").getBytes("utf-8"));
|
"\r\n").getBytes("utf-8"));
|
||||||
os.flush();
|
os.flush();
|
||||||
|
@ -177,7 +178,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
||||||
{
|
{
|
||||||
os.write((
|
os.write((
|
||||||
"GET / HTTP/1.0\r\n"+
|
"GET / HTTP/1.0\r\n"+
|
||||||
"host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
|
"host: "+_serverURI.getHost()+":"+_serverURI.getPort()+"\r\n"+
|
||||||
"connection: keep-alive\r\n"+
|
"connection: keep-alive\r\n"+
|
||||||
"\r\n").getBytes("utf-8"));
|
"\r\n").getBytes("utf-8"));
|
||||||
os.flush();
|
os.flush();
|
||||||
|
@ -214,7 +215,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
Socket client=newSocket(HOST,_connector.getLocalPort());
|
Socket client=newSocket(_serverURI.getHost(),_serverURI.getPort());
|
||||||
client.setSoTimeout(10000);
|
client.setSoTimeout(10000);
|
||||||
|
|
||||||
assertFalse(client.isClosed());
|
assertFalse(client.isClosed());
|
||||||
|
@ -224,7 +225,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
||||||
|
|
||||||
os.write((
|
os.write((
|
||||||
"GET / HTTP/1.0\r\n"+
|
"GET / HTTP/1.0\r\n"+
|
||||||
"host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
|
"host: "+_serverURI.getHost()+":"+_serverURI.getPort()+"\r\n"+
|
||||||
"connection: close\r\n"+
|
"connection: close\r\n"+
|
||||||
"\r\n").getBytes("utf-8"));
|
"\r\n").getBytes("utf-8"));
|
||||||
os.flush();
|
os.flush();
|
||||||
|
@ -290,7 +291,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
Socket client=newSocket(HOST,_connector.getLocalPort());
|
Socket client=newSocket(_serverURI.getHost(),_serverURI.getPort());
|
||||||
client.setSoTimeout(10000);
|
client.setSoTimeout(10000);
|
||||||
|
|
||||||
assertFalse(client.isClosed());
|
assertFalse(client.isClosed());
|
||||||
|
@ -302,7 +303,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
||||||
byte[] contentB=content.getBytes("utf-8");
|
byte[] contentB=content.getBytes("utf-8");
|
||||||
os.write((
|
os.write((
|
||||||
"POST /echo HTTP/1.1\r\n" +
|
"POST /echo HTTP/1.1\r\n" +
|
||||||
"host: " + HOST + ":" + _connector.getLocalPort() + "\r\n" +
|
"host: " + _serverURI.getHost() + ":" + _serverURI.getPort() + "\r\n" +
|
||||||
"content-type: text/plain; charset=utf-8\r\n" +
|
"content-type: text/plain; charset=utf-8\r\n" +
|
||||||
"content-length: " + contentB.length + "\r\n" +
|
"content-length: " + contentB.length + "\r\n" +
|
||||||
"connection: close\r\n" +
|
"connection: close\r\n" +
|
||||||
|
@ -329,7 +330,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
||||||
{
|
{
|
||||||
os.write((
|
os.write((
|
||||||
"GET / HTTP/1.0\r\n"+
|
"GET / HTTP/1.0\r\n"+
|
||||||
"host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
|
"host: "+_serverURI.getHost()+":"+_serverURI.getPort()+"\r\n"+
|
||||||
"connection: keep-alive\r\n"+
|
"connection: keep-alive\r\n"+
|
||||||
"\r\n").getBytes("utf-8"));
|
"\r\n").getBytes("utf-8"));
|
||||||
os.flush();
|
os.flush();
|
||||||
|
@ -349,7 +350,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
||||||
public void testMaxIdleNoRequest() throws Exception
|
public void testMaxIdleNoRequest() throws Exception
|
||||||
{
|
{
|
||||||
configureServer(new EchoHandler());
|
configureServer(new EchoHandler());
|
||||||
Socket client=newSocket(HOST,_connector.getLocalPort());
|
Socket client=newSocket(_serverURI.getHost(),_serverURI.getPort());
|
||||||
client.setSoTimeout(10000);
|
client.setSoTimeout(10000);
|
||||||
InputStream is=client.getInputStream();
|
InputStream is=client.getInputStream();
|
||||||
assertFalse(client.isClosed());
|
assertFalse(client.isClosed());
|
||||||
|
@ -377,7 +378,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
||||||
public void testMaxIdleWithSlowRequest() throws Exception
|
public void testMaxIdleWithSlowRequest() throws Exception
|
||||||
{
|
{
|
||||||
configureServer(new EchoHandler());
|
configureServer(new EchoHandler());
|
||||||
Socket client=newSocket(HOST,_connector.getLocalPort());
|
Socket client=newSocket(_serverURI.getHost(),_serverURI.getPort());
|
||||||
client.setSoTimeout(10000);
|
client.setSoTimeout(10000);
|
||||||
|
|
||||||
assertFalse(client.isClosed());
|
assertFalse(client.isClosed());
|
||||||
|
@ -389,7 +390,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
||||||
byte[] contentB=content.getBytes("utf-8");
|
byte[] contentB=content.getBytes("utf-8");
|
||||||
os.write((
|
os.write((
|
||||||
"GET / HTTP/1.0\r\n"+
|
"GET / HTTP/1.0\r\n"+
|
||||||
"host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
|
"host: "+_serverURI.getHost()+":"+_serverURI.getPort()+"\r\n"+
|
||||||
"connection: keep-alive\r\n"+
|
"connection: keep-alive\r\n"+
|
||||||
"Content-Length: "+(contentB.length*20)+"\r\n"+
|
"Content-Length: "+(contentB.length*20)+"\r\n"+
|
||||||
"Content-Type: text/plain\r\n"+
|
"Content-Type: text/plain\r\n"+
|
||||||
|
@ -417,7 +418,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
||||||
public void testMaxIdleWithSlowResponse() throws Exception
|
public void testMaxIdleWithSlowResponse() throws Exception
|
||||||
{
|
{
|
||||||
configureServer(new SlowResponseHandler());
|
configureServer(new SlowResponseHandler());
|
||||||
Socket client=newSocket(HOST,_connector.getLocalPort());
|
Socket client=newSocket(_serverURI.getHost(),_serverURI.getPort());
|
||||||
client.setSoTimeout(10000);
|
client.setSoTimeout(10000);
|
||||||
|
|
||||||
assertFalse(client.isClosed());
|
assertFalse(client.isClosed());
|
||||||
|
@ -427,7 +428,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
||||||
|
|
||||||
os.write((
|
os.write((
|
||||||
"GET / HTTP/1.0\r\n"+
|
"GET / HTTP/1.0\r\n"+
|
||||||
"host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
|
"host: "+_serverURI.getHost()+":"+_serverURI.getPort()+"\r\n"+
|
||||||
"connection: keep-alive\r\n"+
|
"connection: keep-alive\r\n"+
|
||||||
"Connection: close\r\n"+
|
"Connection: close\r\n"+
|
||||||
"\r\n").getBytes("utf-8"));
|
"\r\n").getBytes("utf-8"));
|
||||||
|
@ -446,7 +447,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
||||||
public void testMaxIdleWithWait() throws Exception
|
public void testMaxIdleWithWait() throws Exception
|
||||||
{
|
{
|
||||||
configureServer(new WaitHandler());
|
configureServer(new WaitHandler());
|
||||||
Socket client=newSocket(HOST,_connector.getLocalPort());
|
Socket client=newSocket(_serverURI.getHost(),_serverURI.getPort());
|
||||||
client.setSoTimeout(10000);
|
client.setSoTimeout(10000);
|
||||||
|
|
||||||
assertFalse(client.isClosed());
|
assertFalse(client.isClosed());
|
||||||
|
@ -456,7 +457,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
||||||
|
|
||||||
os.write((
|
os.write((
|
||||||
"GET / HTTP/1.0\r\n"+
|
"GET / HTTP/1.0\r\n"+
|
||||||
"host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
|
"host: "+_serverURI.getHost()+":"+_serverURI.getPort()+"\r\n"+
|
||||||
"connection: keep-alive\r\n"+
|
"connection: keep-alive\r\n"+
|
||||||
"Connection: close\r\n"+
|
"Connection: close\r\n"+
|
||||||
"\r\n").getBytes("utf-8"));
|
"\r\n").getBytes("utf-8"));
|
||||||
|
|
|
@ -118,7 +118,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
{
|
{
|
||||||
configureServer(new HelloWorldHandler());
|
configureServer(new HelloWorldHandler());
|
||||||
|
|
||||||
try (Socket client = newSocket(HOST, _connector.getLocalPort()))
|
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||||
{
|
{
|
||||||
((StdErrLog)Log.getLogger(HttpConnection.class)).setHideStacks(true);
|
((StdErrLog)Log.getLogger(HttpConnection.class)).setHideStacks(true);
|
||||||
((StdErrLog)Log.getLogger(HttpConnection.class)).info("expect request is too large, then ISE extra data ...");
|
((StdErrLog)Log.getLogger(HttpConnection.class)).info("expect request is too large, then ISE extra data ...");
|
||||||
|
@ -149,7 +149,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
{
|
{
|
||||||
configureServer(new HelloWorldHandler());
|
configureServer(new HelloWorldHandler());
|
||||||
|
|
||||||
try (Socket client = newSocket(HOST, _connector.getLocalPort()))
|
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||||
{
|
{
|
||||||
((StdErrLog)Log.getLogger(HttpConnection.class)).setHideStacks(true);
|
((StdErrLog)Log.getLogger(HttpConnection.class)).setHideStacks(true);
|
||||||
((StdErrLog)Log.getLogger(HttpConnection.class)).info("expect URI is too large, then ISE extra data ...");
|
((StdErrLog)Log.getLogger(HttpConnection.class)).info("expect URI is too large, then ISE extra data ...");
|
||||||
|
@ -192,7 +192,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
StringBuffer request = new StringBuffer("GET / HTTP/1.0\r\n");
|
StringBuffer request = new StringBuffer("GET / HTTP/1.0\r\n");
|
||||||
request.append("Host: localhost\r\n\r\n");
|
request.append("Host: localhost\r\n\r\n");
|
||||||
|
|
||||||
Socket client = newSocket(HOST, _connector.getLocalPort());
|
Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort());
|
||||||
OutputStream os = client.getOutputStream();
|
OutputStream os = client.getOutputStream();
|
||||||
|
|
||||||
try
|
try
|
||||||
|
@ -246,7 +246,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
request.append("Content-length: 6\n\n");
|
request.append("Content-length: 6\n\n");
|
||||||
request.append("foo");
|
request.append("foo");
|
||||||
|
|
||||||
Socket client = newSocket(HOST, _connector.getLocalPort());
|
Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort());
|
||||||
OutputStream os = client.getOutputStream();
|
OutputStream os = client.getOutputStream();
|
||||||
|
|
||||||
os.write(request.toString().getBytes());
|
os.write(request.toString().getBytes());
|
||||||
|
@ -269,7 +269,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
|
|
||||||
configureServer(new HelloWorldHandler());
|
configureServer(new HelloWorldHandler());
|
||||||
|
|
||||||
try (Socket client = newSocket(HOST, _connector.getLocalPort()))
|
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||||
{
|
{
|
||||||
((StdErrLog)Log.getLogger(HttpConnection.class)).setHideStacks(true);
|
((StdErrLog)Log.getLogger(HttpConnection.class)).setHideStacks(true);
|
||||||
((StdErrLog)Log.getLogger(HttpConnection.class)).info("expect header is too large, then ISE extra data ...");
|
((StdErrLog)Log.getLogger(HttpConnection.class)).info("expect header is too large, then ISE extra data ...");
|
||||||
|
@ -317,7 +317,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
{
|
{
|
||||||
configureServer(new HelloWorldHandler());
|
configureServer(new HelloWorldHandler());
|
||||||
|
|
||||||
try (Socket client = newSocket(HOST, _connector.getLocalPort()))
|
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||||
{
|
{
|
||||||
OutputStream os = client.getOutputStream();
|
OutputStream os = client.getOutputStream();
|
||||||
|
|
||||||
|
@ -337,7 +337,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
{
|
{
|
||||||
configureServer(new EchoHandler());
|
configureServer(new EchoHandler());
|
||||||
|
|
||||||
try (Socket client = newSocket(HOST, _connector.getLocalPort()))
|
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||||
{
|
{
|
||||||
OutputStream os = client.getOutputStream();
|
OutputStream os = client.getOutputStream();
|
||||||
|
|
||||||
|
@ -367,7 +367,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
{
|
{
|
||||||
configureServer(new EchoHandler());
|
configureServer(new EchoHandler());
|
||||||
|
|
||||||
try (Socket client = newSocket(HOST, _connector.getLocalPort()))
|
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||||
{
|
{
|
||||||
OutputStream os = client.getOutputStream();
|
OutputStream os = client.getOutputStream();
|
||||||
|
|
||||||
|
@ -396,7 +396,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
{
|
{
|
||||||
configureServer(new HelloWorldHandler());
|
configureServer(new HelloWorldHandler());
|
||||||
|
|
||||||
try (Socket client = newSocket(HOST, _connector.getLocalPort()))
|
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||||
{
|
{
|
||||||
OutputStream os = client.getOutputStream();
|
OutputStream os = client.getOutputStream();
|
||||||
|
|
||||||
|
@ -426,7 +426,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
byte[] bytes = REQUEST2.getBytes();
|
byte[] bytes = REQUEST2.getBytes();
|
||||||
for (int i = 0; i < LOOPS; i++)
|
for (int i = 0; i < LOOPS; i++)
|
||||||
{
|
{
|
||||||
try (Socket client = newSocket(HOST, _connector.getLocalPort()))
|
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||||
{
|
{
|
||||||
OutputStream os = client.getOutputStream();
|
OutputStream os = client.getOutputStream();
|
||||||
|
|
||||||
|
@ -474,7 +474,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
// Sort the list
|
// Sort the list
|
||||||
Arrays.sort(points);
|
Arrays.sort(points);
|
||||||
|
|
||||||
try (Socket client = newSocket(HOST, _connector.getLocalPort()))
|
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||||
{
|
{
|
||||||
OutputStream os = client.getOutputStream();
|
OutputStream os = client.getOutputStream();
|
||||||
|
|
||||||
|
@ -505,7 +505,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
// Sort the list
|
// Sort the list
|
||||||
Arrays.sort(points);
|
Arrays.sort(points);
|
||||||
|
|
||||||
try (Socket client = newSocket(HOST, _connector.getLocalPort()))
|
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||||
{
|
{
|
||||||
OutputStream os = client.getOutputStream();
|
OutputStream os = client.getOutputStream();
|
||||||
|
|
||||||
|
@ -537,7 +537,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
String test = encoding[e] + "x" + b + "x" + w + "x" + c;
|
String test = encoding[e] + "x" + b + "x" + w + "x" + c;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
URL url = new URL(_scheme + "://" + HOST + ":" + _connector.getLocalPort() + "/?writes=" + w + "&block=" + b + (e == 0 ? "" : ("&encoding=" + encoding[e])) + (c == 0 ? "&chars=true" : ""));
|
URL url = new URL(_scheme + "://" + _serverURI.getHost() + ":" + _serverURI.getPort() + "/?writes=" + w + "&block=" + b + (e == 0 ? "" : ("&encoding=" + encoding[e])) + (c == 0 ? "&chars=true" : ""));
|
||||||
|
|
||||||
InputStream in = (InputStream)url.getContent();
|
InputStream in = (InputStream)url.getContent();
|
||||||
String response = IO.toString(in, e == 0 ? null : encoding[e]);
|
String response = IO.toString(in, e == 0 ? null : encoding[e]);
|
||||||
|
@ -562,14 +562,14 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
configureServer(new DataHandler());
|
configureServer(new DataHandler());
|
||||||
|
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
try (Socket client = newSocket(HOST, _connector.getLocalPort()))
|
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||||
{
|
{
|
||||||
OutputStream os = client.getOutputStream();
|
OutputStream os = client.getOutputStream();
|
||||||
InputStream is = client.getInputStream();
|
InputStream is = client.getInputStream();
|
||||||
|
|
||||||
os.write((
|
os.write((
|
||||||
"GET /data?writes=1024&block=256 HTTP/1.1\r\n" +
|
"GET /data?writes=1024&block=256 HTTP/1.1\r\n" +
|
||||||
"host: " + HOST + ":" + _connector.getLocalPort() + "\r\n" +
|
"host: " + _serverURI.getHost() + ":" + _serverURI.getPort() + "\r\n" +
|
||||||
"connection: close\r\n" +
|
"connection: close\r\n" +
|
||||||
"content-type: unknown\r\n" +
|
"content-type: unknown\r\n" +
|
||||||
"content-length: 30\r\n" +
|
"content-length: 30\r\n" +
|
||||||
|
@ -624,14 +624,14 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
|
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
int total = 0;
|
int total = 0;
|
||||||
try (Socket client = newSocket(HOST, _connector.getLocalPort()))
|
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||||
{
|
{
|
||||||
OutputStream os = client.getOutputStream();
|
OutputStream os = client.getOutputStream();
|
||||||
InputStream is = client.getInputStream();
|
InputStream is = client.getInputStream();
|
||||||
|
|
||||||
os.write((
|
os.write((
|
||||||
"GET /data?writes=256&block=1024 HTTP/1.1\r\n" +
|
"GET /data?writes=256&block=1024 HTTP/1.1\r\n" +
|
||||||
"host: " + HOST + ":" + _connector.getLocalPort() + "\r\n" +
|
"host: " + _serverURI.getHost() + ":" + _serverURI.getPort() + "\r\n" +
|
||||||
"connection: close\r\n" +
|
"connection: close\r\n" +
|
||||||
"content-type: unknown\r\n" +
|
"content-type: unknown\r\n" +
|
||||||
"\r\n"
|
"\r\n"
|
||||||
|
@ -665,7 +665,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
{
|
{
|
||||||
configureServer(new BigBlockHandler());
|
configureServer(new BigBlockHandler());
|
||||||
|
|
||||||
try (Socket client = newSocket(HOST, _connector.getLocalPort()))
|
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||||
{
|
{
|
||||||
client.setSoTimeout(20000);
|
client.setSoTimeout(20000);
|
||||||
|
|
||||||
|
@ -674,10 +674,10 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
|
|
||||||
os.write((
|
os.write((
|
||||||
"GET /r1 HTTP/1.1\r\n" +
|
"GET /r1 HTTP/1.1\r\n" +
|
||||||
"host: " + HOST + ":" + _connector.getLocalPort() + "\r\n" +
|
"host: " + _serverURI.getHost() + ":" + _serverURI.getPort() + "\r\n" +
|
||||||
"\r\n" +
|
"\r\n" +
|
||||||
"GET /r2 HTTP/1.1\r\n" +
|
"GET /r2 HTTP/1.1\r\n" +
|
||||||
"host: " + HOST + ":" + _connector.getLocalPort() + "\r\n" +
|
"host: " + _serverURI.getHost() + ":" + _serverURI.getPort() + "\r\n" +
|
||||||
"connection: close\r\n" +
|
"connection: close\r\n" +
|
||||||
"\r\n"
|
"\r\n"
|
||||||
).getBytes());
|
).getBytes());
|
||||||
|
@ -797,7 +797,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
//for (int pipeline=1;pipeline<32;pipeline++)
|
//for (int pipeline=1;pipeline<32;pipeline++)
|
||||||
for (int pipeline = 1; pipeline < 32; pipeline++)
|
for (int pipeline = 1; pipeline < 32; pipeline++)
|
||||||
{
|
{
|
||||||
try (Socket client = newSocket(HOST, _connector.getLocalPort()))
|
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||||
{
|
{
|
||||||
client.setSoTimeout(5000);
|
client.setSoTimeout(5000);
|
||||||
OutputStream os = client.getOutputStream();
|
OutputStream os = client.getOutputStream();
|
||||||
|
@ -807,7 +807,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
for (int i = 1; i < pipeline; i++)
|
for (int i = 1; i < pipeline; i++)
|
||||||
request +=
|
request +=
|
||||||
"GET /data?writes=1&block=16&id=" + i + " HTTP/1.1\r\n" +
|
"GET /data?writes=1&block=16&id=" + i + " HTTP/1.1\r\n" +
|
||||||
"host: " + HOST + ":" + _connector.getLocalPort() + "\r\n" +
|
"host: " + _serverURI.getHost() + ":" + _serverURI.getPort() + "\r\n" +
|
||||||
"user-agent: testharness/1.0 (blah foo/bar)\r\n" +
|
"user-agent: testharness/1.0 (blah foo/bar)\r\n" +
|
||||||
"accept-encoding: nothing\r\n" +
|
"accept-encoding: nothing\r\n" +
|
||||||
"cookie: aaa=1234567890\r\n" +
|
"cookie: aaa=1234567890\r\n" +
|
||||||
|
@ -815,7 +815,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
|
|
||||||
request +=
|
request +=
|
||||||
"GET /data?writes=1&block=16 HTTP/1.1\r\n" +
|
"GET /data?writes=1&block=16 HTTP/1.1\r\n" +
|
||||||
"host: " + HOST + ":" + _connector.getLocalPort() + "\r\n" +
|
"host: " + _serverURI.getHost() + ":" + _serverURI.getPort() + "\r\n" +
|
||||||
"user-agent: testharness/1.0 (blah foo/bar)\r\n" +
|
"user-agent: testharness/1.0 (blah foo/bar)\r\n" +
|
||||||
"accept-encoding: nothing\r\n" +
|
"accept-encoding: nothing\r\n" +
|
||||||
"cookie: aaa=bbbbbb\r\n" +
|
"cookie: aaa=bbbbbb\r\n" +
|
||||||
|
@ -844,14 +844,14 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
public void testRecycledWriters() throws Exception
|
public void testRecycledWriters() throws Exception
|
||||||
{
|
{
|
||||||
configureServer(new EchoHandler());
|
configureServer(new EchoHandler());
|
||||||
try (Socket client = newSocket(HOST, _connector.getLocalPort()))
|
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||||
{
|
{
|
||||||
OutputStream os = client.getOutputStream();
|
OutputStream os = client.getOutputStream();
|
||||||
InputStream is = client.getInputStream();
|
InputStream is = client.getInputStream();
|
||||||
|
|
||||||
os.write((
|
os.write((
|
||||||
"POST /echo?charset=utf-8 HTTP/1.1\r\n" +
|
"POST /echo?charset=utf-8 HTTP/1.1\r\n" +
|
||||||
"host: " + HOST + ":" + _connector.getLocalPort() + "\r\n" +
|
"host: " + _serverURI.getHost() + ":" + _serverURI.getPort() + "\r\n" +
|
||||||
"content-type: text/plain; charset=utf-8\r\n" +
|
"content-type: text/plain; charset=utf-8\r\n" +
|
||||||
"content-length: 10\r\n" +
|
"content-length: 10\r\n" +
|
||||||
"\r\n").getBytes("iso-8859-1"));
|
"\r\n").getBytes("iso-8859-1"));
|
||||||
|
@ -862,7 +862,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
|
|
||||||
os.write((
|
os.write((
|
||||||
"POST /echo?charset=utf-8 HTTP/1.1\r\n" +
|
"POST /echo?charset=utf-8 HTTP/1.1\r\n" +
|
||||||
"host: " + HOST + ":" + _connector.getLocalPort() + "\r\n" +
|
"host: " + _serverURI.getHost() + ":" + _serverURI.getPort() + "\r\n" +
|
||||||
"content-type: text/plain; charset=utf-8\r\n" +
|
"content-type: text/plain; charset=utf-8\r\n" +
|
||||||
"content-length: 10\r\n" +
|
"content-length: 10\r\n" +
|
||||||
"\r\n"
|
"\r\n"
|
||||||
|
@ -876,7 +876,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
byte[] contentB = content.getBytes("utf-8");
|
byte[] contentB = content.getBytes("utf-8");
|
||||||
os.write((
|
os.write((
|
||||||
"POST /echo?charset=utf-16 HTTP/1.1\r\n" +
|
"POST /echo?charset=utf-16 HTTP/1.1\r\n" +
|
||||||
"host: " + HOST + ":" + _connector.getLocalPort() + "\r\n" +
|
"host: " + _serverURI.getHost() + ":" + _serverURI.getPort() + "\r\n" +
|
||||||
"content-type: text/plain; charset=utf-8\r\n" +
|
"content-type: text/plain; charset=utf-8\r\n" +
|
||||||
"content-length: " + contentB.length + "\r\n" +
|
"content-length: " + contentB.length + "\r\n" +
|
||||||
"connection: close\r\n" +
|
"connection: close\r\n" +
|
||||||
|
@ -928,28 +928,28 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
{
|
{
|
||||||
configureServer(new EchoHandler(false));
|
configureServer(new EchoHandler(false));
|
||||||
|
|
||||||
try (Socket client = newSocket(HOST, _connector.getLocalPort()))
|
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||||
{
|
{
|
||||||
OutputStream os = client.getOutputStream();
|
OutputStream os = client.getOutputStream();
|
||||||
InputStream is = client.getInputStream();
|
InputStream is = client.getInputStream();
|
||||||
|
|
||||||
os.write((
|
os.write((
|
||||||
"POST /R1 HTTP/1.1\015\012" +
|
"POST /R1 HTTP/1.1\015\012" +
|
||||||
"Host: " + HOST + ":" + _connector.getLocalPort() + "\r\n" +
|
"Host: " + _serverURI.getHost() + ":" + _serverURI.getPort() + "\r\n" +
|
||||||
"content-type: text/plain; charset=utf-8\r\n" +
|
"content-type: text/plain; charset=utf-8\r\n" +
|
||||||
"content-length: 10\r\n" +
|
"content-length: 10\r\n" +
|
||||||
"\015\012" +
|
"\015\012" +
|
||||||
"123456789\n" +
|
"123456789\n" +
|
||||||
|
|
||||||
"HEAD /R1 HTTP/1.1\015\012" +
|
"HEAD /R1 HTTP/1.1\015\012" +
|
||||||
"Host: " + HOST + ":" + _connector.getLocalPort() + "\015\012" +
|
"Host: " + _serverURI.getHost() + ":" + _serverURI.getPort() + "\015\012" +
|
||||||
"content-type: text/plain; charset=utf-8\r\n" +
|
"content-type: text/plain; charset=utf-8\r\n" +
|
||||||
"content-length: 10\r\n" +
|
"content-length: 10\r\n" +
|
||||||
"\015\012" +
|
"\015\012" +
|
||||||
"123456789\n" +
|
"123456789\n" +
|
||||||
|
|
||||||
"POST /R1 HTTP/1.1\015\012" +
|
"POST /R1 HTTP/1.1\015\012" +
|
||||||
"Host: " + HOST + ":" + _connector.getLocalPort() + "\015\012" +
|
"Host: " + _serverURI.getHost() + ":" + _serverURI.getPort() + "\015\012" +
|
||||||
"content-type: text/plain; charset=utf-8\r\n" +
|
"content-type: text/plain; charset=utf-8\r\n" +
|
||||||
"content-length: 10\r\n" +
|
"content-length: 10\r\n" +
|
||||||
"Connection: close\015\012" +
|
"Connection: close\015\012" +
|
||||||
|
@ -976,14 +976,14 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
{
|
{
|
||||||
configureServer(new EchoHandler());
|
configureServer(new EchoHandler());
|
||||||
|
|
||||||
try (Socket client = newSocket(HOST, _connector.getLocalPort()))
|
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||||
{
|
{
|
||||||
OutputStream os = client.getOutputStream();
|
OutputStream os = client.getOutputStream();
|
||||||
InputStream is = client.getInputStream();
|
InputStream is = client.getInputStream();
|
||||||
|
|
||||||
os.write((
|
os.write((
|
||||||
"POST /echo?charset=utf-8 HTTP/1.1\r\n" +
|
"POST /echo?charset=utf-8 HTTP/1.1\r\n" +
|
||||||
"host: " + HOST + ":" + _connector.getLocalPort() + "\r\n" +
|
"host: " + _serverURI.getHost() + ":" + _serverURI.getPort() + "\r\n" +
|
||||||
"content-type: text/plain; charset=utf-8\r\n" +
|
"content-type: text/plain; charset=utf-8\r\n" +
|
||||||
"content-length: 10\r\n" +
|
"content-length: 10\r\n" +
|
||||||
"\r\n").getBytes("iso-8859-1"));
|
"\r\n").getBytes("iso-8859-1"));
|
||||||
|
@ -994,7 +994,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
|
|
||||||
os.write((
|
os.write((
|
||||||
"POST /echo?charset=utf-8 HTTP/1.1\r\n" +
|
"POST /echo?charset=utf-8 HTTP/1.1\r\n" +
|
||||||
"host: " + HOST + ":" + _connector.getLocalPort() + "\r\n" +
|
"host: " + _serverURI.getHost() + ":" + _serverURI.getPort() + "\r\n" +
|
||||||
"content-type: text/plain; charset=utf-8\r\n" +
|
"content-type: text/plain; charset=utf-8\r\n" +
|
||||||
"content-length: 10\r\n" +
|
"content-length: 10\r\n" +
|
||||||
"\r\n"
|
"\r\n"
|
||||||
|
@ -1008,7 +1008,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
byte[] contentB = content.getBytes("utf-16");
|
byte[] contentB = content.getBytes("utf-16");
|
||||||
os.write((
|
os.write((
|
||||||
"POST /echo?charset=utf-8 HTTP/1.1\r\n" +
|
"POST /echo?charset=utf-8 HTTP/1.1\r\n" +
|
||||||
"host: " + HOST + ":" + _connector.getLocalPort() + "\r\n" +
|
"host: " + _serverURI.getHost() + ":" + _serverURI.getPort() + "\r\n" +
|
||||||
"content-type: text/plain; charset=utf-16\r\n" +
|
"content-type: text/plain; charset=utf-16\r\n" +
|
||||||
"content-length: " + contentB.length + "\r\n" +
|
"content-length: " + contentB.length + "\r\n" +
|
||||||
"connection: close\r\n" +
|
"connection: close\r\n" +
|
||||||
|
@ -1030,7 +1030,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
{
|
{
|
||||||
configureServer(new HelloWorldHandler());
|
configureServer(new HelloWorldHandler());
|
||||||
|
|
||||||
try (Socket client = newSocket(HOST, _connector.getLocalPort()))
|
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||||
{
|
{
|
||||||
OutputStream os = client.getOutputStream();
|
OutputStream os = client.getOutputStream();
|
||||||
InputStream is = client.getInputStream();
|
InputStream is = client.getInputStream();
|
||||||
|
@ -1038,7 +1038,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
// Send a request with chunked input and expect 100
|
// Send a request with chunked input and expect 100
|
||||||
os.write((
|
os.write((
|
||||||
"GET / HTTP/1.1\r\n" +
|
"GET / HTTP/1.1\r\n" +
|
||||||
"Host: " + HOST + ":" + _connector.getLocalPort() + "\r\n" +
|
"Host: " + _serverURI.getHost() + ":" + _serverURI.getPort() + "\r\n" +
|
||||||
"Transfer-Encoding: chunked\r\n" +
|
"Transfer-Encoding: chunked\r\n" +
|
||||||
"Expect: 100-continue\r\n" +
|
"Expect: 100-continue\r\n" +
|
||||||
"Connection: Keep-Alive\r\n" +
|
"Connection: Keep-Alive\r\n" +
|
||||||
|
@ -1066,7 +1066,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
CommittedErrorHandler handler = new CommittedErrorHandler();
|
CommittedErrorHandler handler = new CommittedErrorHandler();
|
||||||
configureServer(handler);
|
configureServer(handler);
|
||||||
|
|
||||||
Socket client = newSocket(HOST, _connector.getLocalPort());
|
Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort());
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
((StdErrLog)Log.getLogger(HttpChannel.class)).setHideStacks(true);
|
((StdErrLog)Log.getLogger(HttpChannel.class)).setHideStacks(true);
|
||||||
|
@ -1076,7 +1076,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
|
|
||||||
// Send a request
|
// Send a request
|
||||||
os.write(("GET / HTTP/1.1\r\n" +
|
os.write(("GET / HTTP/1.1\r\n" +
|
||||||
"Host: " + HOST + ":" + _connector.getLocalPort() + "\r\n" +
|
"Host: " + _serverURI.getHost() + ":" + _serverURI.getPort() + "\r\n" +
|
||||||
"\r\n"
|
"\r\n"
|
||||||
).getBytes());
|
).getBytes());
|
||||||
os.flush();
|
os.flush();
|
||||||
|
@ -1206,14 +1206,14 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
AvailableHandler ah = new AvailableHandler();
|
AvailableHandler ah = new AvailableHandler();
|
||||||
configureServer(ah);
|
configureServer(ah);
|
||||||
|
|
||||||
try (Socket client = newSocket(HOST, _connector.getLocalPort()))
|
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||||
{
|
{
|
||||||
OutputStream os = client.getOutputStream();
|
OutputStream os = client.getOutputStream();
|
||||||
InputStream is = client.getInputStream();
|
InputStream is = client.getInputStream();
|
||||||
|
|
||||||
os.write((
|
os.write((
|
||||||
"GET /data?writes=1024&block=256 HTTP/1.1\r\n" +
|
"GET /data?writes=1024&block=256 HTTP/1.1\r\n" +
|
||||||
"host: " + HOST + ":" + _connector.getLocalPort() + "\r\n" +
|
"host: " + _serverURI.getHost() + ":" + _serverURI.getPort() + "\r\n" +
|
||||||
"connection: close\r\n" +
|
"connection: close\r\n" +
|
||||||
"content-type: unknown\r\n" +
|
"content-type: unknown\r\n" +
|
||||||
"content-length: 30\r\n" +
|
"content-length: 30\r\n" +
|
||||||
|
@ -1251,7 +1251,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
{
|
{
|
||||||
configureServer(new HelloWorldHandler());
|
configureServer(new HelloWorldHandler());
|
||||||
|
|
||||||
try (Socket client1 = newSocket(HOST, _connector.getLocalPort()); Socket client2 = newSocket(HOST, _connector.getLocalPort()))
|
try (Socket client1 = newSocket(_serverURI.getHost(), _serverURI.getPort()); Socket client2 = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||||
{
|
{
|
||||||
OutputStream os1 = client1.getOutputStream();
|
OutputStream os1 = client1.getOutputStream();
|
||||||
OutputStream os2 = client2.getOutputStream();
|
OutputStream os2 = client2.getOutputStream();
|
||||||
|
@ -1345,7 +1345,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
new String(fill);
|
new String(fill);
|
||||||
final byte[] bytes = content.getBytes();
|
final byte[] bytes = content.getBytes();
|
||||||
|
|
||||||
Socket client = newSocket(HOST, _connector.getLocalPort());
|
Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort());
|
||||||
final OutputStream out = client.getOutputStream();
|
final OutputStream out = client.getOutputStream();
|
||||||
|
|
||||||
new Thread()
|
new Thread()
|
||||||
|
@ -1405,7 +1405,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
configureServer(suspend);
|
configureServer(suspend);
|
||||||
|
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
Socket client = newSocket(HOST, _connector.getLocalPort());
|
Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort());
|
||||||
client.setSoTimeout(5000);
|
client.setSoTimeout(5000);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -1414,7 +1414,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
// write an initial request
|
// write an initial request
|
||||||
os.write((
|
os.write((
|
||||||
"GET / HTTP/1.1\r\n" +
|
"GET / HTTP/1.1\r\n" +
|
||||||
"host: " + HOST + ":" + _connector.getLocalPort() + "\r\n" +
|
"host: " + _serverURI.getHost() + ":" + _serverURI.getPort() + "\r\n" +
|
||||||
"\r\n"
|
"\r\n"
|
||||||
).getBytes());
|
).getBytes());
|
||||||
os.flush();
|
os.flush();
|
||||||
|
@ -1424,7 +1424,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
// write an pipelined request
|
// write an pipelined request
|
||||||
os.write((
|
os.write((
|
||||||
"GET / HTTP/1.1\r\n" +
|
"GET / HTTP/1.1\r\n" +
|
||||||
"host: " + HOST + ":" + _connector.getLocalPort() + "\r\n" +
|
"host: " + _serverURI.getHost() + ":" + _serverURI.getPort() + "\r\n" +
|
||||||
"connection: close\r\n" +
|
"connection: close\r\n" +
|
||||||
"\r\n"
|
"\r\n"
|
||||||
).getBytes());
|
).getBytes());
|
||||||
|
|
|
@ -25,6 +25,7 @@ import java.io.OutputStream;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
import javax.net.ssl.HostnameVerifier;
|
import javax.net.ssl.HostnameVerifier;
|
||||||
import javax.net.ssl.SSLSession;
|
import javax.net.ssl.SSLSession;
|
||||||
|
@ -42,9 +43,9 @@ public class HttpServerTestFixture
|
||||||
{ // Useful constants
|
{ // Useful constants
|
||||||
protected static final long PAUSE=10L;
|
protected static final long PAUSE=10L;
|
||||||
protected static final int LOOPS=50;
|
protected static final int LOOPS=50;
|
||||||
protected static final String HOST="localhost";
|
|
||||||
|
|
||||||
protected Server _server;
|
protected Server _server;
|
||||||
|
protected URI _serverURI;
|
||||||
protected NetworkConnector _connector;
|
protected NetworkConnector _connector;
|
||||||
protected String _scheme="http";
|
protected String _scheme="http";
|
||||||
|
|
||||||
|
@ -69,6 +70,7 @@ public class HttpServerTestFixture
|
||||||
_server.addConnector(_connector);
|
_server.addConnector(_connector);
|
||||||
_server.setHandler(new HandlerWrapper());
|
_server.setHandler(new HandlerWrapper());
|
||||||
_server.start();
|
_server.start();
|
||||||
|
_serverURI = _server.getURI();
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2013 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.server.session;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import junit.framework.Assert;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.server.SessionManager;
|
||||||
|
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||||
|
import org.eclipse.jetty.util.log.Log;
|
||||||
|
import org.eclipse.jetty.util.log.StdErrLog;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class HashSessionManagerTest
|
||||||
|
{
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void enableStacks()
|
||||||
|
{
|
||||||
|
enableStacks(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void quietStacks()
|
||||||
|
{
|
||||||
|
enableStacks(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void enableStacks(boolean enabled)
|
||||||
|
{
|
||||||
|
StdErrLog log = (StdErrLog)Log.getLogger("org.eclipse.jetty.server.session");
|
||||||
|
log.setHideStacks(!enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDangerousSessionIdRemoval() throws Exception
|
||||||
|
{
|
||||||
|
final HashSessionManager manager = new HashSessionManager();
|
||||||
|
manager.setDeleteUnrestorableSessions(true);
|
||||||
|
manager.setLazyLoad(true);
|
||||||
|
File testDir = MavenTestingUtils.getTargetTestingDir("hashes");
|
||||||
|
testDir.mkdirs();
|
||||||
|
manager.setStoreDirectory(testDir);
|
||||||
|
|
||||||
|
MavenTestingUtils.getTargetFile("dangerFile.session").createNewFile();
|
||||||
|
|
||||||
|
Assert.assertTrue("File should exist!", MavenTestingUtils.getTargetFile("dangerFile.session").exists());
|
||||||
|
|
||||||
|
manager.getSession("../../dangerFile.session");
|
||||||
|
|
||||||
|
Assert.assertTrue("File should exist!", MavenTestingUtils.getTargetFile("dangerFile.session").exists());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidSessionIdRemoval() throws Exception
|
||||||
|
{
|
||||||
|
final HashSessionManager manager = new HashSessionManager();
|
||||||
|
manager.setDeleteUnrestorableSessions(true);
|
||||||
|
manager.setLazyLoad(true);
|
||||||
|
File testDir = MavenTestingUtils.getTargetTestingDir("hashes");
|
||||||
|
testDir.mkdirs();
|
||||||
|
manager.setStoreDirectory(testDir);
|
||||||
|
|
||||||
|
new File(testDir, "validFile.session").createNewFile();
|
||||||
|
|
||||||
|
Assert.assertTrue("File should exist!", new File(testDir, "validFile.session").exists());
|
||||||
|
|
||||||
|
manager.getSession("validFile.session");
|
||||||
|
|
||||||
|
Assert.assertTrue("File shouldn't exist!", !new File(testDir,"validFile.session").exists());
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,6 +24,7 @@ import java.io.FileInputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
|
import java.net.URI;
|
||||||
import java.security.KeyStore;
|
import java.security.KeyStore;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
@ -153,7 +154,8 @@ public class SelectChannelServerSslTest extends HttpServerTestBase
|
||||||
// Sort the list
|
// Sort the list
|
||||||
Arrays.sort(points);
|
Arrays.sort(points);
|
||||||
|
|
||||||
Socket client=newSocket(HOST,_connector.getLocalPort());
|
URI uri=_server.getURI();
|
||||||
|
Socket client=newSocket(uri.getHost(),uri.getPort());
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
OutputStream os=client.getOutputStream();
|
OutputStream os=client.getOutputStream();
|
||||||
|
|
|
@ -34,8 +34,10 @@ import javax.servlet.ServletContext;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.ServletRequest;
|
import javax.servlet.ServletRequest;
|
||||||
import javax.servlet.ServletResponse;
|
import javax.servlet.ServletResponse;
|
||||||
|
import javax.servlet.ServletResponseWrapper;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import javax.servlet.http.HttpServletResponseWrapper;
|
||||||
|
|
||||||
import org.eclipse.jetty.continuation.Continuation;
|
import org.eclipse.jetty.continuation.Continuation;
|
||||||
import org.eclipse.jetty.continuation.ContinuationListener;
|
import org.eclipse.jetty.continuation.ContinuationListener;
|
||||||
|
@ -43,6 +45,7 @@ import org.eclipse.jetty.continuation.ContinuationSupport;
|
||||||
import org.eclipse.jetty.http.HttpMethod;
|
import org.eclipse.jetty.http.HttpMethod;
|
||||||
import org.eclipse.jetty.servlets.gzip.AbstractCompressedStream;
|
import org.eclipse.jetty.servlets.gzip.AbstractCompressedStream;
|
||||||
import org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper;
|
import org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper;
|
||||||
|
import org.eclipse.jetty.util.StringUtil;
|
||||||
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;
|
||||||
|
|
||||||
|
@ -101,15 +104,21 @@ import org.eclipse.jetty.util.log.Logger;
|
||||||
* instead.
|
* instead.
|
||||||
*
|
*
|
||||||
* excludePathPatterns Same as excludePath, but accepts regex patterns for more complex matching.
|
* excludePathPatterns Same as excludePath, but accepts regex patterns for more complex matching.
|
||||||
|
*
|
||||||
|
* vary Set to the value of the Vary header sent with responses that could be compressed. By default it is
|
||||||
|
* set to 'Vary: Accept-Encoding, User-Agent' since IE6 is excluded by default from the excludedAgents.
|
||||||
|
* If user-agents are not to be excluded, then this can be set to 'Vary: Accept-Encoding'. Note also
|
||||||
|
* that shared caches may cache copies of a resource that is varied by User-Agent - one per variation of
|
||||||
|
* the User-Agent, unless the cache does some normalization of the UA string.
|
||||||
* </PRE>
|
* </PRE>
|
||||||
*/
|
*/
|
||||||
public class GzipFilter extends UserAgentFilter
|
public class GzipFilter extends UserAgentFilter
|
||||||
{
|
{
|
||||||
private static final Logger LOG = Log.getLogger(GzipFilter.class);
|
private static final Logger LOG = Log.getLogger(GzipFilter.class);
|
||||||
public final static String GZIP="gzip";
|
public final static String GZIP="gzip";
|
||||||
public final static String ETAG_GZIP="-gzip\"";
|
public final static String ETAG_GZIP="--gzip\"";
|
||||||
public final static String DEFLATE="deflate";
|
public final static String DEFLATE="deflate";
|
||||||
public final static String ETAG_DEFLATE="-deflate\"";
|
public final static String ETAG_DEFLATE="--deflate\"";
|
||||||
public final static String ETAG="o.e.j.s.GzipFilter.ETag";
|
public final static String ETAG="o.e.j.s.GzipFilter.ETag";
|
||||||
|
|
||||||
protected ServletContext _context;
|
protected ServletContext _context;
|
||||||
|
@ -122,6 +131,7 @@ public class GzipFilter extends UserAgentFilter
|
||||||
protected Set<Pattern> _excludedAgentPatterns;
|
protected Set<Pattern> _excludedAgentPatterns;
|
||||||
protected Set<String> _excludedPaths;
|
protected Set<String> _excludedPaths;
|
||||||
protected Set<Pattern> _excludedPathPatterns;
|
protected Set<Pattern> _excludedPathPatterns;
|
||||||
|
protected String _vary="Accept-Encoding, User-Agent";
|
||||||
|
|
||||||
private static final int STATE_SEPARATOR = 0;
|
private static final int STATE_SEPARATOR = 0;
|
||||||
private static final int STATE_Q = 1;
|
private static final int STATE_Q = 1;
|
||||||
|
@ -199,6 +209,10 @@ public class GzipFilter extends UserAgentFilter
|
||||||
while (tok.hasMoreTokens())
|
while (tok.hasMoreTokens())
|
||||||
_excludedPathPatterns.add(Pattern.compile(tok.nextToken()));
|
_excludedPathPatterns.add(Pattern.compile(tok.nextToken()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tmp=filterConfig.getInitParameter("vary");
|
||||||
|
if (tmp!=null)
|
||||||
|
_vary=tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@ -220,9 +234,16 @@ public class GzipFilter extends UserAgentFilter
|
||||||
{
|
{
|
||||||
HttpServletRequest request=(HttpServletRequest)req;
|
HttpServletRequest request=(HttpServletRequest)req;
|
||||||
HttpServletResponse response=(HttpServletResponse)res;
|
HttpServletResponse response=(HttpServletResponse)res;
|
||||||
|
|
||||||
|
// If not a GET or an Excluded URI - no Vary because no matter what client, this URI is always excluded
|
||||||
|
String requestURI = request.getRequestURI();
|
||||||
|
if (!HttpMethod.GET.is(request.getMethod()) || isExcludedPath(requestURI))
|
||||||
|
{
|
||||||
|
super.doFilter(request,response,chain);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exclude non compressible mime-types known from URI extension. - no Vary because no matter what client, this URI is always excluded
|
||||||
// Check if mime type of request can ever be compressed.
|
|
||||||
if (_mimeTypes!=null && _mimeTypes.size()>0)
|
if (_mimeTypes!=null && _mimeTypes.size()>0)
|
||||||
{
|
{
|
||||||
String mimeType = _context.getMimeType(request.getRequestURI());
|
String mimeType = _context.getMimeType(request.getRequestURI());
|
||||||
|
@ -234,64 +255,45 @@ public class GzipFilter extends UserAgentFilter
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Excluded User-Agents
|
||||||
|
String ua = getUserAgent(request);
|
||||||
|
boolean ua_excluded=ua!=null&&isExcludedAgent(ua);
|
||||||
|
|
||||||
|
// Acceptable compression type
|
||||||
|
String compressionType = ua_excluded?null:selectCompression(request.getHeader("accept-encoding"));
|
||||||
|
|
||||||
// Inform caches that responses may vary according to Accept-Encoding
|
// Special handling for etags
|
||||||
response.setHeader("Vary","Accept-Encoding");
|
String etag = request.getHeader("If-None-Match");
|
||||||
|
if (etag!=null)
|
||||||
// Should we vary this response according to Accept-Encoding
|
|
||||||
String compressionType = selectCompression(request.getHeader("accept-encoding"));
|
|
||||||
if (compressionType!=null && !response.containsHeader("Content-Encoding") && !HttpMethod.HEAD.is(request.getMethod()))
|
|
||||||
{
|
{
|
||||||
String ua = getUserAgent(request);
|
int dd=etag.indexOf("--");
|
||||||
if (isExcludedAgent(ua))
|
if (dd>0)
|
||||||
{
|
request.setAttribute(ETAG,etag.substring(0,dd)+(etag.endsWith("\"")?"\"":""));
|
||||||
super.doFilter(request,response,chain);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String requestURI = request.getRequestURI();
|
|
||||||
if (isExcludedPath(requestURI))
|
|
||||||
{
|
|
||||||
super.doFilter(request,response,chain);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Special handling for etags
|
|
||||||
String etag = request.getHeader("If-None-Match");
|
|
||||||
if (etag!=null)
|
|
||||||
{
|
|
||||||
if (etag.endsWith(ETAG_GZIP))
|
|
||||||
request.setAttribute(ETAG,etag.substring(0,etag.length()-ETAG_GZIP.length())+'"');
|
|
||||||
else if (etag.endsWith(ETAG_DEFLATE))
|
|
||||||
request.setAttribute(ETAG,etag.substring(0,etag.length()-ETAG_DEFLATE.length())+'"');
|
|
||||||
}
|
|
||||||
|
|
||||||
CompressedResponseWrapper wrappedResponse = createWrappedResponse(request,response,compressionType);
|
|
||||||
|
|
||||||
boolean exceptional=true;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
super.doFilter(request,wrappedResponse,chain);
|
|
||||||
exceptional=false;
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
Continuation continuation = ContinuationSupport.getContinuation(request);
|
|
||||||
if (continuation.isSuspended() && continuation.isResponseWrapped())
|
|
||||||
{
|
|
||||||
continuation.addContinuationListener(new ContinuationListenerWaitingForWrappedResponseToFinish(wrappedResponse));
|
|
||||||
}
|
|
||||||
else if (exceptional && !response.isCommitted())
|
|
||||||
{
|
|
||||||
wrappedResponse.resetBuffer();
|
|
||||||
wrappedResponse.noCompression();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
wrappedResponse.finish();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
CompressedResponseWrapper wrappedResponse = createWrappedResponse(request,response,compressionType);
|
||||||
|
|
||||||
|
boolean exceptional=true;
|
||||||
|
try
|
||||||
{
|
{
|
||||||
super.doFilter(request,response,chain);
|
super.doFilter(request,wrappedResponse,chain);
|
||||||
|
exceptional=false;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Continuation continuation = ContinuationSupport.getContinuation(request);
|
||||||
|
if (continuation.isSuspended() && continuation.isResponseWrapped())
|
||||||
|
{
|
||||||
|
continuation.addContinuationListener(new ContinuationListenerWaitingForWrappedResponseToFinish(wrappedResponse));
|
||||||
|
}
|
||||||
|
else if (exceptional && !response.isCommitted())
|
||||||
|
{
|
||||||
|
wrappedResponse.resetBuffer();
|
||||||
|
wrappedResponse.noCompression();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
wrappedResponse.finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -387,14 +389,32 @@ public class GzipFilter extends UserAgentFilter
|
||||||
protected CompressedResponseWrapper createWrappedResponse(HttpServletRequest request, HttpServletResponse response, final String compressionType)
|
protected CompressedResponseWrapper createWrappedResponse(HttpServletRequest request, HttpServletResponse response, final String compressionType)
|
||||||
{
|
{
|
||||||
CompressedResponseWrapper wrappedResponse = null;
|
CompressedResponseWrapper wrappedResponse = null;
|
||||||
if (compressionType.equals(GZIP))
|
if (compressionType==null)
|
||||||
{
|
{
|
||||||
wrappedResponse = new CompressedResponseWrapper(request,response)
|
wrappedResponse = new CompressedResponseWrapper(request,response)
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response) throws IOException
|
protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response) throws IOException
|
||||||
{
|
{
|
||||||
return new AbstractCompressedStream(compressionType,request,this)
|
return new AbstractCompressedStream(null,request,this,_vary)
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
protected DeflaterOutputStream createStream() throws IOException
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if (compressionType.equals(GZIP))
|
||||||
|
{
|
||||||
|
wrappedResponse = new CompressedResponseWrapper(request,response)
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response) throws IOException
|
||||||
|
{
|
||||||
|
return new AbstractCompressedStream(compressionType,request,this,_vary)
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
protected DeflaterOutputStream createStream() throws IOException
|
protected DeflaterOutputStream createStream() throws IOException
|
||||||
|
@ -412,7 +432,7 @@ public class GzipFilter extends UserAgentFilter
|
||||||
@Override
|
@Override
|
||||||
protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response) throws IOException
|
protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response) throws IOException
|
||||||
{
|
{
|
||||||
return new AbstractCompressedStream(compressionType,request,this)
|
return new AbstractCompressedStream(compressionType,request,this,_vary)
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
protected DeflaterOutputStream createStream() throws IOException
|
protected DeflaterOutputStream createStream() throws IOException
|
||||||
|
@ -422,7 +442,7 @@ public class GzipFilter extends UserAgentFilter
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new IllegalStateException(compressionType + " not supported");
|
throw new IllegalStateException(compressionType + " not supported");
|
||||||
|
@ -438,8 +458,8 @@ public class GzipFilter extends UserAgentFilter
|
||||||
wrappedResponse.setMinCompressSize(_minGzipSize);
|
wrappedResponse.setMinCompressSize(_minGzipSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ContinuationListenerWaitingForWrappedResponseToFinish implements ContinuationListener{
|
private class ContinuationListenerWaitingForWrappedResponseToFinish implements ContinuationListener
|
||||||
|
{
|
||||||
private CompressedResponseWrapper wrappedResponse;
|
private CompressedResponseWrapper wrappedResponse;
|
||||||
|
|
||||||
public ContinuationListenerWaitingForWrappedResponseToFinish(CompressedResponseWrapper wrappedResponse)
|
public ContinuationListenerWaitingForWrappedResponseToFinish(CompressedResponseWrapper wrappedResponse)
|
||||||
|
@ -532,4 +552,51 @@ public class GzipFilter extends UserAgentFilter
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class VaryResponseWrapper extends HttpServletResponseWrapper
|
||||||
|
{
|
||||||
|
public VaryResponseWrapper(HttpServletResponse response)
|
||||||
|
{
|
||||||
|
super(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addHeader(String name, String value)
|
||||||
|
{
|
||||||
|
if ("content-type".equalsIgnoreCase(name))
|
||||||
|
{
|
||||||
|
setContentType(value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
super.addHeader(name,value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHeader(String name, String value)
|
||||||
|
{
|
||||||
|
if ("content-type".equalsIgnoreCase(name))
|
||||||
|
{
|
||||||
|
setContentType(value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
super.setHeader(name,value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setContentType(String ct)
|
||||||
|
{
|
||||||
|
super.setContentType(ct);
|
||||||
|
|
||||||
|
if (ct!=null)
|
||||||
|
{
|
||||||
|
int colon=ct.indexOf(";");
|
||||||
|
if (colon>0)
|
||||||
|
ct=ct.substring(0,colon);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_mimeTypes!=null && _mimeTypes.contains(StringUtil.asciiToLowerCase(ct)))
|
||||||
|
super.setHeader("Vary",_vary);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,14 +70,41 @@ public class IncludableGzipFilter extends GzipFilter
|
||||||
protected CompressedResponseWrapper createWrappedResponse(HttpServletRequest request, HttpServletResponse response, final String compressionType)
|
protected CompressedResponseWrapper createWrappedResponse(HttpServletRequest request, HttpServletResponse response, final String compressionType)
|
||||||
{
|
{
|
||||||
CompressedResponseWrapper wrappedResponse = null;
|
CompressedResponseWrapper wrappedResponse = null;
|
||||||
if (compressionType.equals(GZIP))
|
if (compressionType==null)
|
||||||
{
|
{
|
||||||
wrappedResponse = new IncludableResponseWrapper(request,response)
|
wrappedResponse = new IncludableResponseWrapper(request,response)
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response) throws IOException
|
protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response) throws IOException
|
||||||
{
|
{
|
||||||
return new AbstractCompressedStream(compressionType,request,this)
|
return new AbstractCompressedStream(null,request,this,_vary)
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
protected DeflaterOutputStream createStream() throws IOException
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setHeader(String name, String value)
|
||||||
|
{
|
||||||
|
super.setHeader(name, value);
|
||||||
|
HttpServletResponse response = (HttpServletResponse)getResponse();
|
||||||
|
if (!response.containsHeader(name))
|
||||||
|
response.setHeader("org.eclipse.jetty.server.include." + name, value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if (compressionType.equals(GZIP))
|
||||||
|
{
|
||||||
|
wrappedResponse = new IncludableResponseWrapper(request,response)
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response) throws IOException
|
||||||
|
{
|
||||||
|
return new AbstractCompressedStream(compressionType,request,this,_vary)
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
protected DeflaterOutputStream createStream() throws IOException
|
protected DeflaterOutputStream createStream() throws IOException
|
||||||
|
@ -104,7 +131,7 @@ public class IncludableGzipFilter extends GzipFilter
|
||||||
@Override
|
@Override
|
||||||
protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response) throws IOException
|
protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response) throws IOException
|
||||||
{
|
{
|
||||||
return new AbstractCompressedStream(compressionType,request,this)
|
return new AbstractCompressedStream(compressionType,request,this,_vary)
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
protected DeflaterOutputStream createStream() throws IOException
|
protected DeflaterOutputStream createStream() throws IOException
|
||||||
|
|
|
@ -40,6 +40,7 @@ import org.eclipse.jetty.util.ByteArrayOutputStream2;
|
||||||
public abstract class AbstractCompressedStream extends ServletOutputStream
|
public abstract class AbstractCompressedStream extends ServletOutputStream
|
||||||
{
|
{
|
||||||
private final String _encoding;
|
private final String _encoding;
|
||||||
|
protected final String _vary;
|
||||||
protected final CompressedResponseWrapper _wrapper;
|
protected final CompressedResponseWrapper _wrapper;
|
||||||
protected final HttpServletResponse _response;
|
protected final HttpServletResponse _response;
|
||||||
protected OutputStream _out;
|
protected OutputStream _out;
|
||||||
|
@ -52,12 +53,13 @@ public abstract class AbstractCompressedStream extends ServletOutputStream
|
||||||
* Instantiates a new compressed stream.
|
* Instantiates a new compressed stream.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public AbstractCompressedStream(String encoding,HttpServletRequest request, CompressedResponseWrapper wrapper)
|
public AbstractCompressedStream(String encoding,HttpServletRequest request, CompressedResponseWrapper wrapper,String vary)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
_encoding=encoding;
|
_encoding=encoding;
|
||||||
_wrapper = wrapper;
|
_wrapper = wrapper;
|
||||||
_response = (HttpServletResponse)wrapper.getResponse();
|
_response = (HttpServletResponse)wrapper.getResponse();
|
||||||
|
_vary=vary;
|
||||||
|
|
||||||
if (_wrapper.getMinCompressSize()==0)
|
if (_wrapper.getMinCompressSize()==0)
|
||||||
doCompress();
|
doCompress();
|
||||||
|
@ -106,7 +108,7 @@ public abstract class AbstractCompressedStream extends ServletOutputStream
|
||||||
{
|
{
|
||||||
long length=_wrapper.getContentLength();
|
long length=_wrapper.getContentLength();
|
||||||
if (length > 0 && length < _wrapper.getMinCompressSize())
|
if (length > 0 && length < _wrapper.getMinCompressSize())
|
||||||
doNotCompress();
|
doNotCompress(false);
|
||||||
else
|
else
|
||||||
doCompress();
|
doCompress();
|
||||||
}
|
}
|
||||||
|
@ -137,13 +139,14 @@ public abstract class AbstractCompressedStream extends ServletOutputStream
|
||||||
_wrapper.setContentLength(length);
|
_wrapper.setContentLength(length);
|
||||||
}
|
}
|
||||||
if (length < _wrapper.getMinCompressSize())
|
if (length < _wrapper.getMinCompressSize())
|
||||||
doNotCompress();
|
doNotCompress(false);
|
||||||
else
|
else
|
||||||
doCompress();
|
doCompress();
|
||||||
}
|
}
|
||||||
else if (_out == null)
|
else if (_out == null)
|
||||||
{
|
{
|
||||||
doNotCompress();
|
// No output
|
||||||
|
doNotCompress(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_compressedOutputStream != null)
|
if (_compressedOutputStream != null)
|
||||||
|
@ -168,7 +171,7 @@ public abstract class AbstractCompressedStream extends ServletOutputStream
|
||||||
{
|
{
|
||||||
long length=_wrapper.getContentLength();
|
long length=_wrapper.getContentLength();
|
||||||
if (length > 0 && length < _wrapper.getMinCompressSize())
|
if (length > 0 && length < _wrapper.getMinCompressSize())
|
||||||
doNotCompress();
|
doNotCompress(false);
|
||||||
else
|
else
|
||||||
doCompress();
|
doCompress();
|
||||||
}
|
}
|
||||||
|
@ -226,23 +229,30 @@ public abstract class AbstractCompressedStream extends ServletOutputStream
|
||||||
if (_response.isCommitted())
|
if (_response.isCommitted())
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
|
|
||||||
setHeader("Content-Encoding", _encoding);
|
if (_encoding!=null)
|
||||||
if (_response.containsHeader("Content-Encoding"))
|
|
||||||
{
|
{
|
||||||
_out=_compressedOutputStream=createStream();
|
setHeader("Content-Encoding", _encoding);
|
||||||
|
if (_response.containsHeader("Content-Encoding"))
|
||||||
if (_bOut!=null)
|
|
||||||
{
|
{
|
||||||
_out.write(_bOut.getBuf(),0,_bOut.getCount());
|
setHeader("Vary",_vary);
|
||||||
_bOut=null;
|
_out=_compressedOutputStream=createStream();
|
||||||
|
if (_out!=null)
|
||||||
|
{
|
||||||
|
if (_bOut!=null)
|
||||||
|
{
|
||||||
|
_out.write(_bOut.getBuf(),0,_bOut.getCount());
|
||||||
|
_bOut=null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String etag=_wrapper.getETag();
|
||||||
|
if (etag!=null)
|
||||||
|
setHeader("ETag",etag.substring(0,etag.length()-1)+'-'+_encoding+'"');
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String etag=_wrapper.getETag();
|
|
||||||
if (etag!=null)
|
|
||||||
setHeader("ETag",etag.substring(0,etag.length()-1)+'-'+_encoding+'"');
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
doNotCompress();
|
doNotCompress(true); // Send vary as it could have been compressed if encoding was present
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,12 +262,14 @@ public abstract class AbstractCompressedStream extends ServletOutputStream
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* Signals that an I/O exception has occurred.
|
* Signals that an I/O exception has occurred.
|
||||||
*/
|
*/
|
||||||
public void doNotCompress() throws IOException
|
public void doNotCompress(boolean sendVary) throws IOException
|
||||||
{
|
{
|
||||||
if (_compressedOutputStream != null)
|
if (_compressedOutputStream != null)
|
||||||
throw new IllegalStateException("Compressed output stream is already assigned.");
|
throw new IllegalStateException("Compressed output stream is already assigned.");
|
||||||
if (_out == null || _bOut != null)
|
if (_out == null || _bOut != null)
|
||||||
{
|
{
|
||||||
|
if (sendVary)
|
||||||
|
setHeader("Vary",_vary);
|
||||||
if (_wrapper.getETag()!=null)
|
if (_wrapper.getETag()!=null)
|
||||||
setHeader("ETag",_wrapper.getETag());
|
setHeader("ETag",_wrapper.getETag());
|
||||||
|
|
||||||
|
@ -289,7 +301,7 @@ public abstract class AbstractCompressedStream extends ServletOutputStream
|
||||||
{
|
{
|
||||||
long length=_wrapper.getContentLength();
|
long length=_wrapper.getContentLength();
|
||||||
if (_response.isCommitted() || (length >= 0 && length < _wrapper.getMinCompressSize()))
|
if (_response.isCommitted() || (length >= 0 && length < _wrapper.getMinCompressSize()))
|
||||||
doNotCompress();
|
doNotCompress(false);
|
||||||
else if (lengthToWrite > _wrapper.getMinCompressSize())
|
else if (lengthToWrite > _wrapper.getMinCompressSize())
|
||||||
doCompress();
|
doCompress();
|
||||||
else
|
else
|
||||||
|
@ -299,7 +311,7 @@ public abstract class AbstractCompressedStream extends ServletOutputStream
|
||||||
{
|
{
|
||||||
long length=_wrapper.getContentLength();
|
long length=_wrapper.getContentLength();
|
||||||
if (_response.isCommitted() || (length >= 0 && length < _wrapper.getMinCompressSize()))
|
if (_response.isCommitted() || (length >= 0 && length < _wrapper.getMinCompressSize()))
|
||||||
doNotCompress();
|
doNotCompress(false);
|
||||||
else if (lengthToWrite >= (_bOut.getBuf().length - _bOut.getCount()))
|
else if (lengthToWrite >= (_bOut.getBuf().length - _bOut.getCount()))
|
||||||
doCompress();
|
doCompress();
|
||||||
}
|
}
|
||||||
|
|
|
@ -316,7 +316,7 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_compressedStream.doNotCompress();
|
_compressedStream.doNotCompress(false);
|
||||||
}
|
}
|
||||||
catch (IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -67,6 +67,7 @@ public class GzipHandler extends HandlerWrapper
|
||||||
protected Set<String> _excluded;
|
protected Set<String> _excluded;
|
||||||
protected int _bufferSize = 8192;
|
protected int _bufferSize = 8192;
|
||||||
protected int _minGzipSize = 256;
|
protected int _minGzipSize = 256;
|
||||||
|
protected String _vary = "Accept-Encoding, User-Agent";
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/**
|
/**
|
||||||
|
@ -160,6 +161,31 @@ public class GzipHandler extends HandlerWrapper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @return The value of the Vary header set if a response can be compressed.
|
||||||
|
*/
|
||||||
|
public String getVary()
|
||||||
|
{
|
||||||
|
return _vary;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* Set the value of the Vary header sent with responses that could be compressed.
|
||||||
|
* <p>
|
||||||
|
* By default it is set to 'Accept-Encoding, User-Agent' since IE6 is excluded by
|
||||||
|
* default from the excludedAgents. If user-agents are not to be excluded, then
|
||||||
|
* this can be set to 'Accept-Encoding'. Note also that shared caches may cache
|
||||||
|
* many copies of a resource that is varied by User-Agent - one per variation of the
|
||||||
|
* User-Agent, unless the cache does some normalization of the UA string.
|
||||||
|
* @param vary The value of the Vary header set if a response can be compressed.
|
||||||
|
*/
|
||||||
|
public void setVary(String vary)
|
||||||
|
{
|
||||||
|
_vary = vary;
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/**
|
/**
|
||||||
* Get the buffer size.
|
* Get the buffer size.
|
||||||
|
@ -296,7 +322,7 @@ public class GzipHandler extends HandlerWrapper
|
||||||
@Override
|
@Override
|
||||||
protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response) throws IOException
|
protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response) throws IOException
|
||||||
{
|
{
|
||||||
return new AbstractCompressedStream("gzip",request,this)
|
return new AbstractCompressedStream("gzip",request,this,_vary)
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
protected DeflaterOutputStream createStream() throws IOException
|
protected DeflaterOutputStream createStream() throws IOException
|
||||||
|
|
|
@ -120,15 +120,7 @@ public class GzipWithPipeliningTest
|
||||||
// Start Server
|
// Start Server
|
||||||
server.start();
|
server.start();
|
||||||
|
|
||||||
NetworkConnector conn = (NetworkConnector)server.getConnectors()[0];
|
serverUri = server.getURI();
|
||||||
String host = conn.getHost();
|
|
||||||
if (host == null)
|
|
||||||
{
|
|
||||||
host = "localhost";
|
|
||||||
}
|
|
||||||
int port = conn.getLocalPort();
|
|
||||||
serverUri = new URI(String.format("ws://%s:%d/",host,port));
|
|
||||||
// System.out.printf("Server URI: %s%n",serverUri);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
|
|
@ -73,7 +73,6 @@ public class MultipartFilterTest
|
||||||
@Override
|
@Override
|
||||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
|
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
|
||||||
{
|
{
|
||||||
System.err.println(req.getParameter("field1"));
|
|
||||||
assertNotNull(req.getParameter("fileup"));
|
assertNotNull(req.getParameter("fileup"));
|
||||||
assertNotNull(req.getParameter("fileup"+MultiPartFilter.CONTENT_TYPE_SUFFIX));
|
assertNotNull(req.getParameter("fileup"+MultiPartFilter.CONTENT_TYPE_SUFFIX));
|
||||||
assertEquals(req.getParameter("fileup"+MultiPartFilter.CONTENT_TYPE_SUFFIX), "application/octet-stream");
|
assertEquals(req.getParameter("fileup"+MultiPartFilter.CONTENT_TYPE_SUFFIX), "application/octet-stream");
|
||||||
|
|
|
@ -298,6 +298,7 @@ public class GzipTester
|
||||||
private void assertResponseHeaders(int expectedFilesize, int status, HttpTester.Response response)
|
private void assertResponseHeaders(int expectedFilesize, int status, HttpTester.Response response)
|
||||||
{
|
{
|
||||||
Assert.assertThat("Response.status",response.getStatus(),is(status));
|
Assert.assertThat("Response.status",response.getStatus(),is(status));
|
||||||
|
Assert.assertThat("Response.header[Content-Encoding]",response.get("Content-Encoding"),not(containsString(compressionType)));
|
||||||
if (expectedFilesize != (-1))
|
if (expectedFilesize != (-1))
|
||||||
{
|
{
|
||||||
Assert.assertEquals(expectedFilesize,response.getContentBytes().length);
|
Assert.assertEquals(expectedFilesize,response.getContentBytes().length);
|
||||||
|
@ -456,6 +457,7 @@ public class GzipTester
|
||||||
ServletHolder servletHolder = tester.addServlet(servletClass,"/");
|
ServletHolder servletHolder = tester.addServlet(servletClass,"/");
|
||||||
servletHolder.setInitParameter("baseDir",testdir.getDir().getAbsolutePath());
|
servletHolder.setInitParameter("baseDir",testdir.getDir().getAbsolutePath());
|
||||||
FilterHolder holder = tester.addFilter(gzipFilterClass,"/*",EnumSet.allOf(DispatcherType.class));
|
FilterHolder holder = tester.addFilter(gzipFilterClass,"/*",EnumSet.allOf(DispatcherType.class));
|
||||||
|
holder.setInitParameter("vary","Accept-Encoding");
|
||||||
return holder;
|
return holder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,6 @@ import org.eclipse.jetty.server.Server;
|
||||||
import org.eclipse.jetty.server.ServerConnector;
|
import org.eclipse.jetty.server.ServerConnector;
|
||||||
import org.eclipse.jetty.server.handler.DefaultHandler;
|
import org.eclipse.jetty.server.handler.DefaultHandler;
|
||||||
import org.eclipse.jetty.spdy.api.DataInfo;
|
import org.eclipse.jetty.spdy.api.DataInfo;
|
||||||
import org.eclipse.jetty.spdy.api.GoAwayInfo;
|
|
||||||
import org.eclipse.jetty.spdy.api.GoAwayReceivedInfo;
|
import org.eclipse.jetty.spdy.api.GoAwayReceivedInfo;
|
||||||
import org.eclipse.jetty.spdy.api.PingInfo;
|
import org.eclipse.jetty.spdy.api.PingInfo;
|
||||||
import org.eclipse.jetty.spdy.api.PingResultInfo;
|
import org.eclipse.jetty.spdy.api.PingResultInfo;
|
||||||
|
@ -49,6 +48,7 @@ import org.eclipse.jetty.spdy.api.SynInfo;
|
||||||
import org.eclipse.jetty.spdy.client.SPDYClient;
|
import org.eclipse.jetty.spdy.client.SPDYClient;
|
||||||
import org.eclipse.jetty.spdy.server.http.HTTPSPDYHeader;
|
import org.eclipse.jetty.spdy.server.http.HTTPSPDYHeader;
|
||||||
import org.eclipse.jetty.spdy.server.http.SPDYTestUtils;
|
import org.eclipse.jetty.spdy.server.http.SPDYTestUtils;
|
||||||
|
import org.eclipse.jetty.util.Callback;
|
||||||
import org.eclipse.jetty.util.Fields;
|
import org.eclipse.jetty.util.Fields;
|
||||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
|
@ -180,8 +180,6 @@ public class ProxySPDYToHTTPTest
|
||||||
});
|
});
|
||||||
|
|
||||||
assertThat("Reply is send to SPDY client", replyLatch.await(5, TimeUnit.SECONDS), is(true));
|
assertThat("Reply is send to SPDY client", replyLatch.await(5, TimeUnit.SECONDS), is(true));
|
||||||
|
|
||||||
client.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -227,8 +225,6 @@ public class ProxySPDYToHTTPTest
|
||||||
|
|
||||||
assertThat("reply has been received", replyLatch.await(5, TimeUnit.SECONDS), is(true));
|
assertThat("reply has been received", replyLatch.await(5, TimeUnit.SECONDS), is(true));
|
||||||
assertThat("data has been received", dataLatch.await(5, TimeUnit.SECONDS), is(true));
|
assertThat("data has been received", dataLatch.await(5, TimeUnit.SECONDS), is(true));
|
||||||
|
|
||||||
client.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -272,19 +268,17 @@ public class ProxySPDYToHTTPTest
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
stream.data(new StringDataInfo(data, true));
|
stream.data(new StringDataInfo(data, true), new Callback.Adapter());
|
||||||
|
|
||||||
assertThat("reply has been received", replyLatch.await(5, TimeUnit.SECONDS), is(true));
|
assertThat("reply has been received", replyLatch.await(5, TimeUnit.SECONDS), is(true));
|
||||||
assertThat("data has been received", dataLatch.await(5, TimeUnit.SECONDS), is(true));
|
assertThat("data has been received", dataLatch.await(5, TimeUnit.SECONDS), is(true));
|
||||||
|
|
||||||
client.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSYNWithSplitRequestContentThenREPLYAndDATA() throws Exception
|
public void testSYNWithSplitRequestContentThenREPLYAndDATA() throws Exception
|
||||||
{
|
{
|
||||||
final String data = "0123456789ABCDEF";
|
final String data = "0123456789ABCDEF";
|
||||||
final String data2 = "ABCDEF0123456789";
|
final String data2 = "ABCDEF";
|
||||||
final String header = "foo";
|
final String header = "foo";
|
||||||
|
|
||||||
InetSocketAddress proxyAddress = startProxy(startServer(new TestServerHandler(header, null)), 30000, 30000);
|
InetSocketAddress proxyAddress = startProxy(startServer(new TestServerHandler(header, null)), 30000, 30000);
|
||||||
|
@ -316,19 +310,20 @@ public class ProxySPDYToHTTPTest
|
||||||
result.write(dataInfo.asBytes(true), 0, dataInfo.length());
|
result.write(dataInfo.asBytes(true), 0, dataInfo.length());
|
||||||
if (dataInfo.isClose())
|
if (dataInfo.isClose())
|
||||||
{
|
{
|
||||||
|
System.out.println("client received DATA: " + result);
|
||||||
assertThat("received data matches send data", result.toString(), is(data + data2));
|
assertThat("received data matches send data", result.toString(), is(data + data2));
|
||||||
dataLatch.countDown();
|
dataLatch.countDown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
stream.data(new StringDataInfo(data, false));
|
System.out.println("DATA1 sent!!!!!!!!");
|
||||||
stream.data(new StringDataInfo(data2, true));
|
stream.data(new StringDataInfo(data, false), new Callback.Adapter());
|
||||||
|
System.out.println("DATA2 sent!!!!!!!!");
|
||||||
|
stream.data(new StringDataInfo(data2, true), new Callback.Adapter());
|
||||||
|
|
||||||
assertThat("reply has been received", replyLatch.await(5, TimeUnit.SECONDS), is(true));
|
assertThat("reply has been received", replyLatch.await(5, TimeUnit.SECONDS), is(true));
|
||||||
assertThat("data has been received", dataLatch.await(5, TimeUnit.SECONDS), is(true));
|
assertThat("data has been received", dataLatch.await(5, TimeUnit.SECONDS), is(true));
|
||||||
|
|
||||||
client.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -399,7 +394,7 @@ public class ProxySPDYToHTTPTest
|
||||||
|
|
||||||
assertThat("reply has been received", replyLatch.await(5, TimeUnit.SECONDS), is(true));
|
assertThat("reply has been received", replyLatch.await(5, TimeUnit.SECONDS), is(true));
|
||||||
|
|
||||||
client.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
|
// client.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -425,7 +420,7 @@ public class ProxySPDYToHTTPTest
|
||||||
|
|
||||||
Assert.assertTrue(pingLatch.await(5, TimeUnit.SECONDS));
|
Assert.assertTrue(pingLatch.await(5, TimeUnit.SECONDS));
|
||||||
|
|
||||||
client.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
|
// client.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TestServerHandler extends DefaultHandler
|
private class TestServerHandler extends DefaultHandler
|
||||||
|
@ -443,6 +438,7 @@ public class ProxySPDYToHTTPTest
|
||||||
public void handle(String target, Request baseRequest, HttpServletRequest request,
|
public void handle(String target, Request baseRequest, HttpServletRequest request,
|
||||||
HttpServletResponse response) throws IOException, ServletException
|
HttpServletResponse response) throws IOException, ServletException
|
||||||
{
|
{
|
||||||
|
System.out.println("HANDLER CALLED!!!");
|
||||||
assertThat("Via Header is set", baseRequest.getHeader("X-Forwarded-For"), is(notNullValue()));
|
assertThat("Via Header is set", baseRequest.getHeader("X-Forwarded-For"), is(notNullValue()));
|
||||||
assertThat("X-Forwarded-For Header is set", baseRequest.getHeader("X-Forwarded-For"),
|
assertThat("X-Forwarded-For Header is set", baseRequest.getHeader("X-Forwarded-For"),
|
||||||
is(notNullValue()));
|
is(notNullValue()));
|
||||||
|
|
|
@ -3,5 +3,5 @@ org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
|
||||||
#org.eclipse.jetty.server.LEVEL=DEBUG
|
#org.eclipse.jetty.server.LEVEL=DEBUG
|
||||||
#org.eclipse.jetty.io.ssl.LEVEL=DEBUG
|
#org.eclipse.jetty.io.ssl.LEVEL=DEBUG
|
||||||
org.eclipse.jetty.spdy.LEVEL=DEBUG
|
org.eclipse.jetty.spdy.LEVEL=DEBUG
|
||||||
#org.eclipse.jetty.client.LEVEL=DEBUG
|
org.eclipse.jetty.client.LEVEL=DEBUG
|
||||||
#org.mortbay.LEVEL=DEBUG
|
#org.mortbay.LEVEL=DEBUG
|
||||||
|
|
|
@ -61,10 +61,11 @@ public class PingTest extends AbstractTest
|
||||||
@Test
|
@Test
|
||||||
public void testServerPingPong() throws Exception
|
public void testServerPingPong() throws Exception
|
||||||
{
|
{
|
||||||
final CountDownLatch pingLatch = new CountDownLatch(1);
|
final CountDownLatch pingReceived = new CountDownLatch(1);
|
||||||
ServerSessionFrameListener serverSessionFrameListener = new ServerSessionFrameListener.Adapter()
|
ServerSessionFrameListener serverSessionFrameListener = new ServerSessionFrameListener.Adapter()
|
||||||
{
|
{
|
||||||
public volatile int pingId;
|
private final CountDownLatch pingSent = new CountDownLatch(1);
|
||||||
|
private int pingId;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onConnect(Session session)
|
public void onConnect(Session session)
|
||||||
|
@ -75,6 +76,7 @@ public class PingTest extends AbstractTest
|
||||||
public void succeeded(PingResultInfo pingInfo)
|
public void succeeded(PingResultInfo pingInfo)
|
||||||
{
|
{
|
||||||
pingId = pingInfo.getPingId();
|
pingId = pingInfo.getPingId();
|
||||||
|
pingSent.countDown();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -82,13 +84,23 @@ public class PingTest extends AbstractTest
|
||||||
@Override
|
@Override
|
||||||
public void onPing(Session session, PingResultInfo pingInfo)
|
public void onPing(Session session, PingResultInfo pingInfo)
|
||||||
{
|
{
|
||||||
Assert.assertEquals(0, pingInfo.getPingId() % 2);
|
try
|
||||||
Assert.assertEquals(pingId, pingInfo.getPingId());
|
{
|
||||||
pingLatch.countDown();
|
// This callback may be notified before the promise above,
|
||||||
|
// so make sure we wait here to know the pingId
|
||||||
|
Assert.assertTrue(pingSent.await(5, TimeUnit.SECONDS));
|
||||||
|
Assert.assertEquals(0, pingInfo.getPingId() % 2);
|
||||||
|
Assert.assertEquals(pingId, pingInfo.getPingId());
|
||||||
|
pingReceived.countDown();
|
||||||
|
}
|
||||||
|
catch (InterruptedException x)
|
||||||
|
{
|
||||||
|
Assert.fail();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
startClient(startServer(serverSessionFrameListener), null);
|
startClient(startServer(serverSessionFrameListener), null);
|
||||||
|
|
||||||
Assert.assertTrue(pingLatch.await(5, TimeUnit.SECONDS));
|
Assert.assertTrue(pingReceived.await(5, TimeUnit.SECONDS));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,8 +86,12 @@ import org.eclipse.jetty.util.log.Logger;
|
||||||
* . These convertors are looked up by class, interface and super class by
|
* . These convertors are looked up by class, interface and super class by
|
||||||
* {@link #getConvertor(Class)}.
|
* {@link #getConvertor(Class)}.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
* <p>If a JSON object has a "class" field, then a java class for that name is
|
||||||
*
|
* looked up and the method {@link convertTo(Class,Map)} is used to find a
|
||||||
|
* Convertor for that class. If a JSON object has a "x-class" field then a
|
||||||
|
* direct lookup for a Convertor for that named x-class is done, so that none
|
||||||
|
* java classes may be converted.
|
||||||
|
* </p>
|
||||||
*/
|
*/
|
||||||
public class JSON
|
public class JSON
|
||||||
{
|
{
|
||||||
|
@ -945,6 +949,15 @@ public class JSON
|
||||||
next = seekTo("\"}",source);
|
next = seekTo("\"}",source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String xclassname = (String)map.get("x-class");
|
||||||
|
if (xclassname != null)
|
||||||
|
{
|
||||||
|
Convertor c = getConvertorFor(xclassname);
|
||||||
|
if (c != null)
|
||||||
|
return c.fromJSON(map);
|
||||||
|
LOG.warn("no Convertor for xclassname '%s'", xclassname);
|
||||||
|
}
|
||||||
|
|
||||||
String classname = (String)map.get("class");
|
String classname = (String)map.get("class");
|
||||||
if (classname != null)
|
if (classname != null)
|
||||||
{
|
{
|
||||||
|
@ -955,9 +968,10 @@ public class JSON
|
||||||
}
|
}
|
||||||
catch (ClassNotFoundException e)
|
catch (ClassNotFoundException e)
|
||||||
{
|
{
|
||||||
LOG.warn(e);
|
LOG.warn("no Class for classname '%s'", classname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -208,7 +208,7 @@ public class SslContextFactory extends AbstractLifeCycle
|
||||||
*/
|
*/
|
||||||
public SslContextFactory()
|
public SslContextFactory()
|
||||||
{
|
{
|
||||||
this(true);
|
this(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -27,7 +27,7 @@ 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;
|
||||||
|
|
||||||
public class TimerScheduler extends AbstractLifeCycle implements Scheduler
|
public class TimerScheduler extends AbstractLifeCycle implements Scheduler, Runnable
|
||||||
{
|
{
|
||||||
private static final Logger LOG = Log.getLogger(TimerScheduler.class);
|
private static final Logger LOG = Log.getLogger(TimerScheduler.class);
|
||||||
|
|
||||||
|
@ -49,14 +49,15 @@ public class TimerScheduler extends AbstractLifeCycle implements Scheduler
|
||||||
|
|
||||||
public TimerScheduler(String name, boolean daemon)
|
public TimerScheduler(String name, boolean daemon)
|
||||||
{
|
{
|
||||||
_name=name;
|
_name = name;
|
||||||
_daemon=daemon;
|
_daemon = daemon;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doStart() throws Exception
|
protected void doStart() throws Exception
|
||||||
{
|
{
|
||||||
_timer=_name==null?new Timer():new Timer(_name,_daemon);
|
_timer = _name == null ? new Timer() : new Timer(_name, _daemon);
|
||||||
|
run();
|
||||||
super.doStart();
|
super.doStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,18 +66,29 @@ public class TimerScheduler extends AbstractLifeCycle implements Scheduler
|
||||||
{
|
{
|
||||||
_timer.cancel();
|
_timer.cancel();
|
||||||
super.doStop();
|
super.doStop();
|
||||||
_timer=null;
|
_timer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Task schedule(final Runnable task, final long delay, final TimeUnit units)
|
public Task schedule(final Runnable task, final long delay, final TimeUnit units)
|
||||||
{
|
{
|
||||||
Timer timer=_timer;
|
Timer timer = _timer;
|
||||||
if (timer==null)
|
if (timer == null)
|
||||||
throw new RejectedExecutionException("STOPPED: "+this);
|
throw new RejectedExecutionException("STOPPED: " + this);
|
||||||
SimpleTask t = new SimpleTask(task);
|
SimpleTask t = new SimpleTask(task);
|
||||||
timer.schedule(t,units.toMillis(delay));
|
timer.schedule(t, units.toMillis(delay));
|
||||||
return t;
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
Timer timer = _timer;
|
||||||
|
if (timer != null)
|
||||||
|
{
|
||||||
|
timer.purge();
|
||||||
|
schedule(this, 1, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class SimpleTask extends TimerTask implements Task
|
private static class SimpleTask extends TimerTask implements Task
|
||||||
|
@ -85,7 +97,7 @@ public class TimerScheduler extends AbstractLifeCycle implements Scheduler
|
||||||
|
|
||||||
private SimpleTask(Runnable runnable)
|
private SimpleTask(Runnable runnable)
|
||||||
{
|
{
|
||||||
_task=runnable;
|
_task = runnable;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -97,7 +109,7 @@ public class TimerScheduler extends AbstractLifeCycle implements Scheduler
|
||||||
}
|
}
|
||||||
catch (Throwable x)
|
catch (Throwable x)
|
||||||
{
|
{
|
||||||
LOG.debug("Exception while executing task "+_task,x);
|
LOG.debug("Exception while executing task " + _task, x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,309 +0,0 @@
|
||||||
//
|
|
||||||
// ========================================================================
|
|
||||||
// Copyright (c) 1995-2013 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.dummy;
|
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.*;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.net.ServerSocket;
|
|
||||||
import java.net.Socket;
|
|
||||||
import java.net.SocketException;
|
|
||||||
import java.net.URI;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.util.IO;
|
|
||||||
import org.eclipse.jetty.util.log.Log;
|
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
|
||||||
import org.eclipse.jetty.websocket.WebSocketConnectionRFC6455;
|
|
||||||
import org.junit.Assert;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simple ServerSocket server used to test oddball server scenarios encountered in the real world.
|
|
||||||
*/
|
|
||||||
public class DummyServer
|
|
||||||
{
|
|
||||||
public static class ServerConnection
|
|
||||||
{
|
|
||||||
private static final Logger LOG = Log.getLogger(ServerConnection.class);
|
|
||||||
private final Socket socket;
|
|
||||||
private InputStream in;
|
|
||||||
private OutputStream out;
|
|
||||||
|
|
||||||
public ServerConnection(Socket socket)
|
|
||||||
{
|
|
||||||
this.socket = socket;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int read(ByteBuffer buf) throws IOException
|
|
||||||
{
|
|
||||||
int len = 0;
|
|
||||||
while ((in.available() > 0) && (buf.remaining() > 0))
|
|
||||||
{
|
|
||||||
buf.put((byte)in.read());
|
|
||||||
len++;
|
|
||||||
}
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void disconnect()
|
|
||||||
{
|
|
||||||
LOG.debug("disconnect");
|
|
||||||
IO.close(in);
|
|
||||||
IO.close(out);
|
|
||||||
if (socket != null)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
socket.close();
|
|
||||||
}
|
|
||||||
catch (IOException ignore)
|
|
||||||
{
|
|
||||||
/* ignore */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public InputStream getInputStream() throws IOException
|
|
||||||
{
|
|
||||||
if (in == null)
|
|
||||||
{
|
|
||||||
in = socket.getInputStream();
|
|
||||||
}
|
|
||||||
return in;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OutputStream getOutputStream() throws IOException
|
|
||||||
{
|
|
||||||
if (out == null)
|
|
||||||
{
|
|
||||||
out = socket.getOutputStream();
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void flush() throws IOException
|
|
||||||
{
|
|
||||||
LOG.debug("flush()");
|
|
||||||
getOutputStream().flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String readRequest() throws IOException
|
|
||||||
{
|
|
||||||
LOG.debug("Reading client request");
|
|
||||||
StringBuilder request = new StringBuilder();
|
|
||||||
BufferedReader in = new BufferedReader(new InputStreamReader(getInputStream()));
|
|
||||||
for (String line = in.readLine(); line != null; line = in.readLine())
|
|
||||||
{
|
|
||||||
if (line.length() == 0)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
request.append(line).append("\r\n");
|
|
||||||
LOG.debug("read line: {}",line);
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG.debug("Client Request:{}{}","\n",request);
|
|
||||||
return request.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void respond(String rawstr) throws IOException
|
|
||||||
{
|
|
||||||
LOG.debug("respond(){}{}","\n",rawstr);
|
|
||||||
getOutputStream().write(rawstr.getBytes());
|
|
||||||
flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSoTimeout(int ms) throws SocketException
|
|
||||||
{
|
|
||||||
socket.setSoTimeout(ms);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void upgrade(Map<String, String> extraResponseHeaders) throws IOException
|
|
||||||
{
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
Pattern patExts = Pattern.compile("^Sec-WebSocket-Extensions: (.*)$",Pattern.CASE_INSENSITIVE);
|
|
||||||
Pattern patKey = Pattern.compile("^Sec-WebSocket-Key: (.*)$",Pattern.CASE_INSENSITIVE);
|
|
||||||
|
|
||||||
LOG.debug("(Upgrade) Reading HTTP Request");
|
|
||||||
Matcher mat;
|
|
||||||
String key = "not sent";
|
|
||||||
BufferedReader in = new BufferedReader(new InputStreamReader(getInputStream()));
|
|
||||||
for (String line = in.readLine(); line != null; line = in.readLine())
|
|
||||||
{
|
|
||||||
if (line.length() == 0)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Check for extensions
|
|
||||||
// mat = patExts.matcher(line);
|
|
||||||
// if (mat.matches())
|
|
||||||
|
|
||||||
// Check for Key
|
|
||||||
mat = patKey.matcher(line);
|
|
||||||
if (mat.matches())
|
|
||||||
{
|
|
||||||
key = mat.group(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG.debug("(Upgrade) Writing HTTP Response");
|
|
||||||
// TODO: handle extensions?
|
|
||||||
|
|
||||||
// Setup Response
|
|
||||||
StringBuilder resp = new StringBuilder();
|
|
||||||
resp.append("HTTP/1.1 101 Upgrade\r\n");
|
|
||||||
resp.append("Upgrade: websocket\r\n");
|
|
||||||
resp.append("Connection: upgrade\r\n");
|
|
||||||
resp.append("Sec-WebSocket-Accept: ");
|
|
||||||
resp.append(WebSocketConnectionRFC6455.hashKey(key)).append("\r\n");
|
|
||||||
// extra response headers.
|
|
||||||
if (extraResponseHeaders != null)
|
|
||||||
{
|
|
||||||
for (Map.Entry<String,String> header : extraResponseHeaders.entrySet())
|
|
||||||
{
|
|
||||||
resp.append(header.getKey());
|
|
||||||
resp.append(": ");
|
|
||||||
resp.append(header.getValue());
|
|
||||||
resp.append("\r\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
resp.append("\r\n");
|
|
||||||
|
|
||||||
// Write Response
|
|
||||||
getOutputStream().write(resp.toString().getBytes());
|
|
||||||
flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void write(byte[] bytes) throws IOException
|
|
||||||
{
|
|
||||||
LOG.debug("Writing {} bytes", bytes.length);
|
|
||||||
getOutputStream().write(bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void write(byte[] buf, int offset, int length) throws IOException
|
|
||||||
{
|
|
||||||
LOG.debug("Writing bytes[{}], offset={}, length={}", buf.length, offset, length);
|
|
||||||
getOutputStream().write(buf,offset,length);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void write(int b) throws IOException
|
|
||||||
{
|
|
||||||
LOG.debug("Writing int={}", b);
|
|
||||||
getOutputStream().write(b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Logger LOG = Log.getLogger(DummyServer.class);
|
|
||||||
private ServerSocket serverSocket;
|
|
||||||
private URI wsUri;
|
|
||||||
|
|
||||||
public ServerConnection accept() throws IOException
|
|
||||||
{
|
|
||||||
LOG.debug(".accept()");
|
|
||||||
assertIsStarted();
|
|
||||||
Socket socket = serverSocket.accept();
|
|
||||||
return new ServerConnection(socket);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertIsStarted()
|
|
||||||
{
|
|
||||||
Assert.assertThat("ServerSocket",serverSocket,notNullValue());
|
|
||||||
Assert.assertThat("ServerSocket.isBound",serverSocket.isBound(),is(true));
|
|
||||||
Assert.assertThat("ServerSocket.isClosed",serverSocket.isClosed(),is(false));
|
|
||||||
|
|
||||||
Assert.assertThat("WsUri",wsUri,notNullValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
public URI getWsUri()
|
|
||||||
{
|
|
||||||
return wsUri;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void respondToClient(Socket connection, String serverResponse) throws IOException
|
|
||||||
{
|
|
||||||
InputStream in = null;
|
|
||||||
InputStreamReader isr = null;
|
|
||||||
BufferedReader buf = null;
|
|
||||||
OutputStream out = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
in = connection.getInputStream();
|
|
||||||
isr = new InputStreamReader(in);
|
|
||||||
buf = new BufferedReader(isr);
|
|
||||||
String line;
|
|
||||||
while ((line = buf.readLine()) != null)
|
|
||||||
{
|
|
||||||
// System.err.println(line);
|
|
||||||
if (line.length() == 0)
|
|
||||||
{
|
|
||||||
// Got the "\r\n" line.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// System.out.println("[Server-Out] " + serverResponse);
|
|
||||||
out = connection.getOutputStream();
|
|
||||||
out.write(serverResponse.getBytes());
|
|
||||||
out.flush();
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
IO.close(buf);
|
|
||||||
IO.close(isr);
|
|
||||||
IO.close(in);
|
|
||||||
IO.close(out);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void start() throws IOException
|
|
||||||
{
|
|
||||||
serverSocket = new ServerSocket();
|
|
||||||
InetAddress addr = InetAddress.getByName("localhost");
|
|
||||||
InetSocketAddress endpoint = new InetSocketAddress(addr,0);
|
|
||||||
serverSocket.bind(endpoint);
|
|
||||||
int port = serverSocket.getLocalPort();
|
|
||||||
String uri = String.format("ws://%s:%d/",addr.getHostAddress(),port);
|
|
||||||
wsUri = URI.create(uri);
|
|
||||||
LOG.debug("Server Started on {} -> {}",endpoint,wsUri);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void stop()
|
|
||||||
{
|
|
||||||
LOG.debug("Stopping Server");
|
|
||||||
try
|
|
||||||
{
|
|
||||||
serverSocket.close();
|
|
||||||
}
|
|
||||||
catch (IOException ignore)
|
|
||||||
{
|
|
||||||
/* ignore */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
# Setup default logging implementation for during testing
|
|
||||||
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
|
|
||||||
#org.eclipse.jetty.websocket.LEVEL=DEBUG
|
|
|
@ -35,33 +35,26 @@ public class WebSocketPolicy
|
||||||
return new WebSocketPolicy(WebSocketBehavior.SERVER);
|
return new WebSocketPolicy(WebSocketBehavior.SERVER);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* The maximum allowed payload size (validated in both directions)
|
|
||||||
* <p>
|
|
||||||
* Default: 65536 (64K)
|
|
||||||
*/
|
|
||||||
private int maxPayloadSize = 64 * KB;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The maximum size of a text message during parsing/generating.
|
* The maximum size of a text message during parsing/generating.
|
||||||
* <p>
|
* <p>
|
||||||
* Default: 16384 (16 K)
|
* Default: 65536 (64 K)
|
||||||
*/
|
*/
|
||||||
private int maxTextMessageSize = 64 * KB;
|
private long maxMessageSize = 64 * KB;
|
||||||
|
|
||||||
/**
|
|
||||||
* The maximum size of a binary message during parsing/generating.
|
|
||||||
* <p>
|
|
||||||
* Default: -1 (no validation)
|
|
||||||
*/
|
|
||||||
private int maxBinaryMessageSize = 64 * KB;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The time in ms (milliseconds) that a websocket may be idle before closing.
|
* The time in ms (milliseconds) that a websocket may be idle before closing.
|
||||||
* <p>
|
* <p>
|
||||||
* Default: 300000 (ms)
|
* Default: 300000 (ms)
|
||||||
*/
|
*/
|
||||||
private int idleTimeout = 300000;
|
private long idleTimeout = 300000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The size of the input (read from network layer) buffer size.
|
||||||
|
* <p>
|
||||||
|
* Default: 4096 (4 K)
|
||||||
|
*/
|
||||||
|
private int inputBufferSize = 4 * KB;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Behavior of the websockets
|
* Behavior of the websockets
|
||||||
|
@ -73,35 +66,14 @@ public class WebSocketPolicy
|
||||||
this.behavior = behavior;
|
this.behavior = behavior;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void assertValidBinaryMessageSize(int requestedSize)
|
public void assertValidMessageSize(int requestedSize)
|
||||||
{
|
{
|
||||||
if (maxBinaryMessageSize > 0)
|
if (maxMessageSize > 0)
|
||||||
{
|
{
|
||||||
// validate it
|
// validate it
|
||||||
if (requestedSize > maxBinaryMessageSize)
|
if (requestedSize > maxMessageSize)
|
||||||
{
|
{
|
||||||
throw new MessageTooLargeException("Requested binary message size [" + requestedSize + "] exceeds maximum size [" + maxBinaryMessageSize + "]");
|
throw new MessageTooLargeException("Requested message size [" + requestedSize + "] exceeds maximum size [" + maxMessageSize + "]");
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void assertValidPayloadLength(int payloadLength)
|
|
||||||
{
|
|
||||||
// validate to buffer sizes
|
|
||||||
if (payloadLength > maxPayloadSize)
|
|
||||||
{
|
|
||||||
throw new MessageTooLargeException("Requested payload length [" + payloadLength + "] exceeds maximum size [" + maxPayloadSize + "]");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void assertValidTextMessageSize(int requestedSize)
|
|
||||||
{
|
|
||||||
if (maxTextMessageSize > 0)
|
|
||||||
{
|
|
||||||
// validate it
|
|
||||||
if (requestedSize > maxTextMessageSize)
|
|
||||||
{
|
|
||||||
throw new MessageTooLargeException("Requested text message size [" + requestedSize + "] exceeds maximum size [" + maxTextMessageSize + "]");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,9 +82,8 @@ public class WebSocketPolicy
|
||||||
{
|
{
|
||||||
WebSocketPolicy clone = new WebSocketPolicy(this.behavior);
|
WebSocketPolicy clone = new WebSocketPolicy(this.behavior);
|
||||||
clone.idleTimeout = this.idleTimeout;
|
clone.idleTimeout = this.idleTimeout;
|
||||||
clone.maxPayloadSize = this.maxPayloadSize;
|
clone.maxMessageSize = this.maxMessageSize;
|
||||||
clone.maxBinaryMessageSize = this.maxBinaryMessageSize;
|
clone.inputBufferSize = this.inputBufferSize;
|
||||||
clone.maxTextMessageSize = this.maxTextMessageSize;
|
|
||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,47 +92,33 @@ public class WebSocketPolicy
|
||||||
return behavior;
|
return behavior;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getIdleTimeout()
|
public long getIdleTimeout()
|
||||||
{
|
{
|
||||||
return idleTimeout;
|
return idleTimeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMaxBinaryMessageSize()
|
public int getInputBufferSize()
|
||||||
{
|
{
|
||||||
return maxBinaryMessageSize;
|
return inputBufferSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMaxPayloadSize()
|
public long getMaxMessageSize()
|
||||||
{
|
{
|
||||||
return maxPayloadSize;
|
return maxMessageSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMaxTextMessageSize()
|
public void setIdleTimeout(long idleTimeout)
|
||||||
{
|
|
||||||
return maxTextMessageSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIdleTimeout(int idleTimeout)
|
|
||||||
{
|
{
|
||||||
this.idleTimeout = idleTimeout;
|
this.idleTimeout = idleTimeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMaxBinaryMessageSize(int maxBinaryMessageSize)
|
public void setInputBufferSize(int inputBufferSize)
|
||||||
{
|
{
|
||||||
this.maxBinaryMessageSize = maxBinaryMessageSize;
|
this.inputBufferSize = inputBufferSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMaxPayloadSize(int maxPayloadSize)
|
public void setMaxMessageSize(long maxMessageSize)
|
||||||
{
|
{
|
||||||
if (maxPayloadSize < 0)
|
this.maxMessageSize = maxMessageSize;
|
||||||
{
|
|
||||||
throw new IllegalStateException("Cannot have payload size be a negative number");
|
|
||||||
}
|
|
||||||
this.maxPayloadSize = maxPayloadSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMaxTextMessageSize(int maxTextMessageSize)
|
|
||||||
{
|
|
||||||
this.maxTextMessageSize = maxTextMessageSize;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,11 +33,9 @@ import java.lang.annotation.Target;
|
||||||
{ ElementType.TYPE })
|
{ ElementType.TYPE })
|
||||||
public @interface WebSocket
|
public @interface WebSocket
|
||||||
{
|
{
|
||||||
int maxBinarySize() default -2;
|
int inputBufferSize() default -2;
|
||||||
|
|
||||||
int maxBufferSize() default -2;
|
|
||||||
|
|
||||||
int maxIdleTime() default -2;
|
int maxIdleTime() default -2;
|
||||||
|
|
||||||
int maxTextSize() default -2;
|
int maxMessageSize() default -2;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,15 +16,8 @@
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
//
|
//
|
||||||
|
|
||||||
package org.eclipse.jetty.websocket.core.api;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connection suspend token
|
* Jetty WebSocket API : WebSocket POJO Annotations
|
||||||
*/
|
*/
|
||||||
public interface SuspendToken
|
package org.eclipse.jetty.websocket.api.annotations;
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Resume a previously suspended connection.
|
|
||||||
*/
|
|
||||||
void resume();
|
|
||||||
}
|
|
|
@ -16,13 +16,8 @@
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
//
|
//
|
||||||
|
|
||||||
package org.eclipse.jetty.client;
|
/**
|
||||||
|
* Jetty WebSocket API : WebSocket Extension API
|
||||||
|
*/
|
||||||
|
package org.eclipse.jetty.websocket.api.extensions;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.thread.Scheduler;
|
|
||||||
|
|
||||||
public interface Schedulable
|
|
||||||
{
|
|
||||||
public boolean schedule(Scheduler scheduler);
|
|
||||||
|
|
||||||
public boolean cancel();
|
|
||||||
}
|
|
|
@ -16,16 +16,8 @@
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
//
|
//
|
||||||
|
|
||||||
package org.eclipse.jetty.websocket.client.internal.mux;
|
/**
|
||||||
|
* Jetty WebSocket API : I/O Classes
|
||||||
|
*/
|
||||||
|
package org.eclipse.jetty.websocket.api.io;
|
||||||
|
|
||||||
import org.eclipse.jetty.websocket.common.extensions.mux.AbstractMuxExtension;
|
|
||||||
import org.eclipse.jetty.websocket.common.extensions.mux.Muxer;
|
|
||||||
|
|
||||||
public class MuxClientExtension extends AbstractMuxExtension
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void configureMuxer(Muxer muxer)
|
|
||||||
{
|
|
||||||
muxer.setAddClient(new MuxClientAddHandler());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -16,18 +16,8 @@
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
//
|
//
|
||||||
|
|
||||||
package org.eclipse.jetty.websocket.core.io;
|
/**
|
||||||
|
* Jetty WebSocket API
|
||||||
|
*/
|
||||||
|
package org.eclipse.jetty.websocket.api;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.websocket.core.api.Extension;
|
|
||||||
import org.eclipse.jetty.websocket.core.api.LogicalConnection;
|
|
||||||
|
|
||||||
public interface InternalConnection extends LogicalConnection
|
|
||||||
{
|
|
||||||
void configureFromExtensions(List<Extension> extensions);
|
|
||||||
|
|
||||||
void setIncoming(IncomingFrames incoming);
|
|
||||||
|
|
||||||
void setSession(WebSocketSession session);
|
|
||||||
}
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2013 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.
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Jetty WebSocket API : Utility Classes
|
||||||
|
*/
|
||||||
|
package org.eclipse.jetty.websocket.api.util;
|
||||||
|
|
|
@ -44,27 +44,39 @@
|
||||||
<artifactId>maven-enforcer-plugin</artifactId>
|
<artifactId>maven-enforcer-plugin</artifactId>
|
||||||
<version>1.1</version>
|
<version>1.1</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>ban-java-servlet-api</id>
|
<id>ban-java-servlet-api</id>
|
||||||
<goals>
|
<goals>
|
||||||
<goal>enforce</goal>
|
<goal>enforce</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
<rules>
|
<rules>
|
||||||
<bannedDependencies>
|
<bannedDependencies>
|
||||||
<includes>
|
<includes>
|
||||||
<include>javax.servlet</include>
|
<include>javax.servlet</include>
|
||||||
<include>servletapi</include>
|
<include>servletapi</include>
|
||||||
<include>org.eclipse.jetty.orbit:javax.servlet</include>
|
<include>org.eclipse.jetty.orbit:javax.servlet</include>
|
||||||
<include>org.mortbay.jetty:servlet-api</include>
|
<include>org.mortbay.jetty:servlet-api</include>
|
||||||
<include>jetty:servlet-api</include>
|
<include>jetty:servlet-api</include>
|
||||||
</includes>
|
</includes>
|
||||||
<searchTransitive>true</searchTransitive>
|
<searchTransitive>true</searchTransitive>
|
||||||
<message>The servlet-api dependency is banned in websocket-client as it causes problems in apps that use client only.</message>
|
<message>The servlet-api dependency is banned in websocket-client as it causes problems in apps that use client only.</message>
|
||||||
</bannedDependencies>
|
</bannedDependencies>
|
||||||
</rules>
|
</rules>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>tests-jar</id>
|
||||||
|
<goals>
|
||||||
|
<goal>test-jar</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
|
|
|
@ -43,8 +43,8 @@ import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Extension;
|
import org.eclipse.jetty.websocket.api.extensions.Extension;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.ExtensionFactory;
|
import org.eclipse.jetty.websocket.api.extensions.ExtensionFactory;
|
||||||
import org.eclipse.jetty.websocket.client.internal.ConnectPromise;
|
import org.eclipse.jetty.websocket.client.io.ConnectPromise;
|
||||||
import org.eclipse.jetty.websocket.client.internal.ConnectionManager;
|
import org.eclipse.jetty.websocket.client.io.ConnectionManager;
|
||||||
import org.eclipse.jetty.websocket.client.masks.Masker;
|
import org.eclipse.jetty.websocket.client.masks.Masker;
|
||||||
import org.eclipse.jetty.websocket.client.masks.RandomMasker;
|
import org.eclipse.jetty.websocket.client.masks.RandomMasker;
|
||||||
import org.eclipse.jetty.websocket.common.events.EventDriver;
|
import org.eclipse.jetty.websocket.common.events.EventDriver;
|
||||||
|
@ -290,13 +290,8 @@ public class WebSocketClient extends ContainerLifeCycle
|
||||||
this.bufferPool = bufferPool;
|
this.bufferPool = bufferPool;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setConnectTimeout(int connectTimeout)
|
public void setConnectTimeout(long connectTimeout)
|
||||||
{
|
{
|
||||||
if (isStarted())
|
|
||||||
{
|
|
||||||
throw new IllegalStateException("Cannot change connect timeout, WebSocketClient is already started");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (connectTimeout < 0)
|
if (connectTimeout < 0)
|
||||||
{
|
{
|
||||||
throw new IllegalStateException("Connect Timeout cannot be negative");
|
throw new IllegalStateException("Connect Timeout cannot be negative");
|
||||||
|
@ -318,4 +313,4 @@ public class WebSocketClient extends ContainerLifeCycle
|
||||||
{
|
{
|
||||||
this.masker = masker;
|
this.masker = masker;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
//
|
|
||||||
// ========================================================================
|
|
||||||
// Copyright (c) 1995-2013 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.client.internal.mux;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.websocket.common.WebSocketSession;
|
|
||||||
import org.eclipse.jetty.websocket.common.extensions.mux.add.MuxAddClient;
|
|
||||||
import org.eclipse.jetty.websocket.common.extensions.mux.op.MuxAddChannelResponse;
|
|
||||||
|
|
||||||
public class MuxClientAddHandler implements MuxAddClient
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public WebSocketSession createSession(MuxAddChannelResponse response)
|
|
||||||
{
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -16,7 +16,7 @@
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
//
|
//
|
||||||
|
|
||||||
package org.eclipse.jetty.websocket.client.internal;
|
package org.eclipse.jetty.websocket.client.io;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.FuturePromise;
|
import org.eclipse.jetty.util.FuturePromise;
|
||||||
import org.eclipse.jetty.websocket.api.Session;
|
import org.eclipse.jetty.websocket.api.Session;
|
|
@ -16,7 +16,7 @@
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
//
|
//
|
||||||
|
|
||||||
package org.eclipse.jetty.websocket.client.internal;
|
package org.eclipse.jetty.websocket.client.io;
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
|
@ -34,7 +34,6 @@ import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.websocket.api.UpgradeException;
|
import org.eclipse.jetty.websocket.api.UpgradeException;
|
||||||
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
|
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
|
||||||
import org.eclipse.jetty.websocket.client.WebSocketClient;
|
import org.eclipse.jetty.websocket.client.WebSocketClient;
|
||||||
import org.eclipse.jetty.websocket.client.internal.io.WebSocketClientSelectorManager;
|
|
||||||
import org.eclipse.jetty.websocket.common.WebSocketSession;
|
import org.eclipse.jetty.websocket.common.WebSocketSession;
|
||||||
import org.eclipse.jetty.websocket.common.events.EventDriver;
|
import org.eclipse.jetty.websocket.common.events.EventDriver;
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
//
|
//
|
||||||
|
|
||||||
package org.eclipse.jetty.websocket.client.internal.io;
|
package org.eclipse.jetty.websocket.client.io;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
|
@ -16,7 +16,7 @@
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
//
|
//
|
||||||
|
|
||||||
package org.eclipse.jetty.websocket.client.internal.io;
|
package org.eclipse.jetty.websocket.client.io;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
@ -39,7 +39,6 @@ import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
||||||
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
|
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
|
||||||
import org.eclipse.jetty.websocket.client.ClientUpgradeResponse;
|
import org.eclipse.jetty.websocket.client.ClientUpgradeResponse;
|
||||||
import org.eclipse.jetty.websocket.client.internal.ConnectPromise;
|
|
||||||
import org.eclipse.jetty.websocket.common.AcceptHash;
|
import org.eclipse.jetty.websocket.common.AcceptHash;
|
||||||
import org.eclipse.jetty.websocket.common.WebSocketSession;
|
import org.eclipse.jetty.websocket.common.WebSocketSession;
|
||||||
import org.eclipse.jetty.websocket.common.events.EventDriver;
|
import org.eclipse.jetty.websocket.common.events.EventDriver;
|
|
@ -16,7 +16,7 @@
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
//
|
//
|
||||||
|
|
||||||
package org.eclipse.jetty.websocket.client.internal.io;
|
package org.eclipse.jetty.websocket.client.io;
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
@ -28,8 +28,6 @@ import org.eclipse.jetty.websocket.api.ProtocolException;
|
||||||
import org.eclipse.jetty.websocket.api.WriteCallback;
|
import org.eclipse.jetty.websocket.api.WriteCallback;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.IncomingFrames;
|
import org.eclipse.jetty.websocket.api.extensions.IncomingFrames;
|
||||||
import org.eclipse.jetty.websocket.client.internal.ConnectPromise;
|
|
||||||
import org.eclipse.jetty.websocket.client.internal.ConnectionManager;
|
|
||||||
import org.eclipse.jetty.websocket.client.masks.Masker;
|
import org.eclipse.jetty.websocket.client.masks.Masker;
|
||||||
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
||||||
import org.eclipse.jetty.websocket.common.WebSocketSession;
|
import org.eclipse.jetty.websocket.common.WebSocketSession;
|
|
@ -16,7 +16,7 @@
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
//
|
//
|
||||||
|
|
||||||
package org.eclipse.jetty.websocket.client.internal.io;
|
package org.eclipse.jetty.websocket.client.io;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.channels.SelectionKey;
|
import java.nio.channels.SelectionKey;
|
||||||
|
@ -37,7 +37,6 @@ import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||||
import org.eclipse.jetty.util.thread.Scheduler;
|
import org.eclipse.jetty.util.thread.Scheduler;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||||
import org.eclipse.jetty.websocket.client.WebSocketClient;
|
import org.eclipse.jetty.websocket.client.WebSocketClient;
|
||||||
import org.eclipse.jetty.websocket.client.internal.ConnectPromise;
|
|
||||||
|
|
||||||
public class WebSocketClientSelectorManager extends SelectorManager
|
public class WebSocketClientSelectorManager extends SelectorManager
|
||||||
{
|
{
|
|
@ -0,0 +1,23 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2013 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.
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Jetty WebSocket Client : I/O Implementation [<em>Internal Use Only</em>]
|
||||||
|
*/
|
||||||
|
package org.eclipse.jetty.websocket.client.io;
|
||||||
|
|
|
@ -20,7 +20,18 @@ package org.eclipse.jetty.websocket.client.masks;
|
||||||
|
|
||||||
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for various Masker implementations.
|
||||||
|
*/
|
||||||
public interface Masker
|
public interface Masker
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Set the mask on the provided {@link WebSocketFrame}.
|
||||||
|
* <p>
|
||||||
|
* Implementations MUST set the mask on the frame.
|
||||||
|
*
|
||||||
|
* @param frame
|
||||||
|
* the frame to set the mask on.
|
||||||
|
*/
|
||||||
void setMask(WebSocketFrame frame);
|
void setMask(WebSocketFrame frame);
|
||||||
}
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2013 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.
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Jetty WebSocket Client : Frame Masking Implementations
|
||||||
|
*/
|
||||||
|
package org.eclipse.jetty.websocket.client.masks;
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2013 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.
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Jetty WebSocket Client : MUX Extension [<em>Unstable Early Draft</em>]
|
||||||
|
*/
|
||||||
|
package org.eclipse.jetty.websocket.client.mux;
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2013 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.
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Jetty WebSocket Client API
|
||||||
|
* <p>
|
||||||
|
* The core class is {@link WebSocketClient}, which acts as a central configuration object (for example
|
||||||
|
* for {@link WebSocketClient#setConnectTimeout(int) connect timeouts}, {@link WebSocketClient#setCookieStore(CookieStore)
|
||||||
|
* request cookie store}, etc.) and as a factory for WebSocket {@link org.eclipse.jetty.websocket.api.Session} objects.
|
||||||
|
* <p>
|
||||||
|
* The <a href="https://tools.ietf.org/html/rfc6455">WebSocket protocol</a> is based on a framing protocol built
|
||||||
|
* around an upgraded HTTP connection. It is primarily focused on the sending of messages (text or binary), with an
|
||||||
|
* occasional control frame (close, ping, pong) that this implementation uses.
|
||||||
|
* <p />
|
||||||
|
* {@link WebSocketClient} holds a number of {@link org.eclipse.jetty.websocket.api.Session Sessions}, which in turn
|
||||||
|
* is used to manage physical vs virtual connection handling (mux extension).
|
||||||
|
*/
|
||||||
|
package org.eclipse.jetty.websocket.client;
|
||||||
|
|
|
@ -16,88 +16,90 @@
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
//
|
//
|
||||||
|
|
||||||
package org.eclipse.jetty.websocket;
|
package org.eclipse.jetty.websocket.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.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
import org.eclipse.jetty.websocket.api.WebSocketAdapter;
|
||||||
import org.eclipse.jetty.websocket.dummy.DummyServer;
|
import org.eclipse.jetty.websocket.api.WebSocketConnection;
|
||||||
import org.eclipse.jetty.websocket.dummy.DummyServer.ServerConnection;
|
import org.eclipse.jetty.websocket.client.blockhead.BlockheadServer;
|
||||||
|
import org.eclipse.jetty.websocket.client.blockhead.BlockheadServer.ServerConnection;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Ignore;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class TomcatServerQuirksTest
|
public class TomcatServerQuirksTest
|
||||||
{
|
{
|
||||||
|
public static class LatchedSocket extends WebSocketAdapter
|
||||||
|
{
|
||||||
|
final CountDownLatch openLatch = new CountDownLatch(1);
|
||||||
|
final CountDownLatch dataLatch = new CountDownLatch(1);
|
||||||
|
final CountDownLatch closeLatch = new CountDownLatch(1);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onWebSocketClose(int statusCode, String reason)
|
||||||
|
{
|
||||||
|
closeLatch.countDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onWebSocketConnect(WebSocketConnection connection)
|
||||||
|
{
|
||||||
|
openLatch.countDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onWebSocketText(String message)
|
||||||
|
{
|
||||||
|
dataLatch.countDown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test for when encountering a "Transfer-Encoding: chunked" on a Upgrade Response header.
|
* Test for when encountering a "Transfer-Encoding: chunked" on a Upgrade Response header.
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=393075">Eclipse Jetty Bug #393075</a></li>
|
* <li><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=393075">Eclipse Jetty Bug #393075</a></li>
|
||||||
* <li><a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=54067">Apache Tomcat Bug #54067</a></li>
|
* <li><a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=54067">Apache Tomcat Bug #54067</a></li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* @throws IOException
|
*
|
||||||
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testTomcat7_0_32_WithTransferEncoding() throws Exception
|
public void testTomcat7_0_32_WithTransferEncoding() throws Exception
|
||||||
{
|
{
|
||||||
DummyServer server = new DummyServer();
|
BlockheadServer server = new BlockheadServer();
|
||||||
int bufferSize = 512;
|
WebSocketClient client = new WebSocketClient();
|
||||||
QueuedThreadPool threadPool = new QueuedThreadPool();
|
|
||||||
WebSocketClientFactory factory = new WebSocketClientFactory(threadPool, new ZeroMaskGen(), bufferSize);
|
try
|
||||||
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
|
int bufferSize = 512;
|
||||||
|
|
||||||
server.start();
|
server.start();
|
||||||
|
|
||||||
// Setup Client Factory
|
// Setup Client Factory
|
||||||
threadPool.start();
|
client.start();
|
||||||
factory.start();
|
|
||||||
|
|
||||||
// Create Client
|
|
||||||
WebSocketClient client = new WebSocketClient(factory);
|
|
||||||
|
|
||||||
// Create End User WebSocket Class
|
// Create End User WebSocket Class
|
||||||
final CountDownLatch openLatch = new CountDownLatch(1);
|
LatchedSocket websocket = new LatchedSocket();
|
||||||
final CountDownLatch dataLatch = new CountDownLatch(1);
|
|
||||||
WebSocket.OnTextMessage websocket = new WebSocket.OnTextMessage()
|
|
||||||
{
|
|
||||||
public void onOpen(Connection connection)
|
|
||||||
{
|
|
||||||
openLatch.countDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onMessage(String data)
|
|
||||||
{
|
|
||||||
// System.out.println("data = " + data);
|
|
||||||
dataLatch.countDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onClose(int closeCode, String message)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Open connection
|
// Open connection
|
||||||
URI wsURI = server.getWsUri();
|
URI wsURI = server.getWsUri();
|
||||||
client.open(wsURI, websocket);
|
client.connect(websocket,wsURI);
|
||||||
|
|
||||||
// Accept incoming connection
|
// Accept incoming connection
|
||||||
ServerConnection socket = server.accept();
|
ServerConnection socket = server.accept();
|
||||||
socket.setSoTimeout(2000); // timeout
|
socket.setSoTimeout(2000); // timeout
|
||||||
|
|
||||||
// Issue upgrade
|
// Issue upgrade
|
||||||
Map<String,String> extraResponseHeaders = new HashMap<String, String>();
|
// Add the extra problematic header that triggers bug found in jetty-io
|
||||||
extraResponseHeaders.put("Transfer-Encoding", "chunked"); // !! The problem !!
|
socket.addResponseHeader("Transfer-Encoding","chunked");
|
||||||
socket.upgrade(extraResponseHeaders);
|
socket.upgrade();
|
||||||
|
|
||||||
// Wait for proper upgrade
|
// Wait for proper upgrade
|
||||||
Assert.assertTrue("Timed out waiting for Client side WebSocket open event", openLatch.await(1, TimeUnit.SECONDS));
|
Assert.assertTrue("Timed out waiting for Client side WebSocket open event",websocket.openLatch.await(1,TimeUnit.SECONDS));
|
||||||
|
|
||||||
// Have server write frame.
|
// Have server write frame.
|
||||||
int length = bufferSize / 2;
|
int length = bufferSize / 2;
|
||||||
|
@ -107,18 +109,19 @@ public class TomcatServerQuirksTest
|
||||||
serverFrame.put((byte)(length >> 8)); // first length byte
|
serverFrame.put((byte)(length >> 8)); // first length byte
|
||||||
serverFrame.put((byte)(length & 0xFF)); // second length byte
|
serverFrame.put((byte)(length & 0xFF)); // second length byte
|
||||||
for (int i = 0; i < length; ++i)
|
for (int i = 0; i < length; ++i)
|
||||||
|
{
|
||||||
serverFrame.put((byte)'x');
|
serverFrame.put((byte)'x');
|
||||||
|
}
|
||||||
serverFrame.flip();
|
serverFrame.flip();
|
||||||
byte buf[] = serverFrame.array();
|
byte buf[] = serverFrame.array();
|
||||||
socket.write(buf,0,buf.length);
|
socket.write(buf,0,buf.length);
|
||||||
socket.flush();
|
socket.flush();
|
||||||
|
|
||||||
Assert.assertTrue(dataLatch.await(1000, TimeUnit.SECONDS));
|
Assert.assertTrue(websocket.dataLatch.await(1000,TimeUnit.SECONDS));
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
factory.stop();
|
client.stop();
|
||||||
threadPool.stop();
|
|
||||||
server.stop();
|
server.stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -33,7 +33,9 @@ import java.net.SocketException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.TimeUnit;
|
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;
|
||||||
|
@ -87,6 +89,7 @@ public class BlockheadServer
|
||||||
private OutputStream out;
|
private OutputStream out;
|
||||||
private InputStream in;
|
private InputStream in;
|
||||||
|
|
||||||
|
private Map<String, String> extraResponseHeaders = new HashMap<>();
|
||||||
private OutgoingFrames outgoing = this;
|
private OutgoingFrames outgoing = this;
|
||||||
|
|
||||||
public ServerConnection(Socket socket)
|
public ServerConnection(Socket socket)
|
||||||
|
@ -101,6 +104,14 @@ public class BlockheadServer
|
||||||
this.extensionRegistry = new WebSocketExtensionFactory(policy,bufferPool);
|
this.extensionRegistry = new WebSocketExtensionFactory(policy,bufferPool);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an extra header for the upgrade response (from the server). No extra work is done to ensure the key and value are sane for http.
|
||||||
|
*/
|
||||||
|
public void addResponseHeader(String rawkey, String rawvalue)
|
||||||
|
{
|
||||||
|
extraResponseHeaders.put(rawkey,rawvalue);
|
||||||
|
}
|
||||||
|
|
||||||
public void close() throws IOException
|
public void close() throws IOException
|
||||||
{
|
{
|
||||||
write(new WebSocketFrame(OpCode.CLOSE));
|
write(new WebSocketFrame(OpCode.CLOSE));
|
||||||
|
@ -412,6 +423,16 @@ public class BlockheadServer
|
||||||
}
|
}
|
||||||
resp.append("\r\n");
|
resp.append("\r\n");
|
||||||
}
|
}
|
||||||
|
if (extraResponseHeaders.size() > 0)
|
||||||
|
{
|
||||||
|
for (Map.Entry<String, String> xheader : extraResponseHeaders.entrySet())
|
||||||
|
{
|
||||||
|
resp.append(xheader.getKey());
|
||||||
|
resp.append(": ");
|
||||||
|
resp.append(xheader.getValue());
|
||||||
|
resp.append("\r\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
resp.append("\r\n");
|
resp.append("\r\n");
|
||||||
|
|
||||||
// Write Response
|
// Write Response
|
||||||
|
|
|
@ -25,6 +25,7 @@ import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
|
||||||
import org.eclipse.jetty.toolchain.test.TestTracker;
|
import org.eclipse.jetty.toolchain.test.TestTracker;
|
||||||
|
import org.eclipse.jetty.websocket.client.io.ConnectionManager;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
|
@ -28,6 +28,7 @@ import org.eclipse.jetty.toolchain.test.TestTracker;
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
import org.eclipse.jetty.util.BufferUtil;
|
||||||
import org.eclipse.jetty.util.StringUtil;
|
import org.eclipse.jetty.util.StringUtil;
|
||||||
import org.eclipse.jetty.websocket.api.UpgradeResponse;
|
import org.eclipse.jetty.websocket.api.UpgradeResponse;
|
||||||
|
import org.eclipse.jetty.websocket.client.io.HttpResponseHeaderParser;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
|
@ -97,7 +97,7 @@ public class Parser
|
||||||
// OMG! Sanity Check! DO NOT WANT! Won't anyone think of the memory!
|
// OMG! Sanity Check! DO NOT WANT! Won't anyone think of the memory!
|
||||||
throw new MessageTooLargeException("[int-sane!] cannot handle payload lengths larger than " + Integer.MAX_VALUE);
|
throw new MessageTooLargeException("[int-sane!] cannot handle payload lengths larger than " + Integer.MAX_VALUE);
|
||||||
}
|
}
|
||||||
policy.assertValidPayloadLength((int)len);
|
policy.assertValidMessageSize((int)len);
|
||||||
|
|
||||||
switch (frame.getOpCode())
|
switch (frame.getOpCode())
|
||||||
{
|
{
|
||||||
|
@ -540,7 +540,6 @@ public class Parser
|
||||||
{
|
{
|
||||||
if (payload == null)
|
if (payload == null)
|
||||||
{
|
{
|
||||||
getPolicy().assertValidPayloadLength(payloadLength);
|
|
||||||
frame.assertValid();
|
frame.assertValid();
|
||||||
payload = bufferPool.acquire(payloadLength,false);
|
payload = bufferPool.acquire(payloadLength,false);
|
||||||
BufferUtil.clearToFill(payload);
|
BufferUtil.clearToFill(payload);
|
||||||
|
|
|
@ -49,13 +49,13 @@ public class AnnotatedEventDriver extends EventDriver
|
||||||
|
|
||||||
WebSocket anno = websocket.getClass().getAnnotation(WebSocket.class);
|
WebSocket anno = websocket.getClass().getAnnotation(WebSocket.class);
|
||||||
// Setup the policy
|
// Setup the policy
|
||||||
if (anno.maxBinarySize() > 0)
|
if (anno.maxMessageSize() > 0)
|
||||||
{
|
{
|
||||||
this.policy.setMaxBinaryMessageSize(anno.maxBinarySize());
|
this.policy.setMaxMessageSize(anno.maxMessageSize());
|
||||||
}
|
}
|
||||||
if (anno.maxTextSize() > 0)
|
if (anno.maxMessageSize() > 0)
|
||||||
{
|
{
|
||||||
this.policy.setMaxTextMessageSize(anno.maxTextSize());
|
this.policy.setInputBufferSize(anno.inputBufferSize());
|
||||||
}
|
}
|
||||||
if (anno.maxIdleTime() > 0)
|
if (anno.maxIdleTime() > 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2013 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.
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Jetty WebSocket Common : Event Driver for WebSocket Object
|
||||||
|
*/
|
||||||
|
package org.eclipse.jetty.websocket.common.events;
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2013 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.
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Jetty WebSocket Common : Frame & Message Compression Extension Implementations
|
||||||
|
*/
|
||||||
|
package org.eclipse.jetty.websocket.common.extensions.compress;
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2013 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.
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Jetty WebSocket Common : Auto Fragment Extension Implementation
|
||||||
|
*/
|
||||||
|
package org.eclipse.jetty.websocket.common.extensions.fragment;
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2013 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.
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Jetty WebSocket Common : Identity Extension Implementation
|
||||||
|
*/
|
||||||
|
package org.eclipse.jetty.websocket.common.extensions.identity;
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2013 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.
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Jetty WebSocket Common : MUX Extension Add Channel Handling [<em>Unstable Early Draft</em>]
|
||||||
|
*/
|
||||||
|
package org.eclipse.jetty.websocket.common.extensions.mux.add;
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2013 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.
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Jetty WebSocket Common : MUX Extension OpCode Handling [<em>Unstable Early Draft</em>]
|
||||||
|
*/
|
||||||
|
package org.eclipse.jetty.websocket.common.extensions.mux.op;
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2013 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.
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Jetty WebSocket Common : MUX Extension Core [<em>Unstable Early Draft</em>]
|
||||||
|
*/
|
||||||
|
package org.eclipse.jetty.websocket.common.extensions.mux;
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2013 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.
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Jetty WebSocket Common : Extension Implementations
|
||||||
|
*/
|
||||||
|
package org.eclipse.jetty.websocket.common.extensions;
|
||||||
|
|
|
@ -140,7 +140,7 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
|
||||||
|
|
||||||
public AbstractWebSocketConnection(EndPoint endp, Executor executor, Scheduler scheduler, WebSocketPolicy policy, ByteBufferPool bufferPool)
|
public AbstractWebSocketConnection(EndPoint endp, Executor executor, Scheduler scheduler, WebSocketPolicy policy, ByteBufferPool bufferPool)
|
||||||
{
|
{
|
||||||
super(endp,executor,EXECUTE_ONFILLABLE); // TODO review if this is best. Specially with MUX
|
super(endp,executor,EXECUTE_ONFILLABLE); // TODO review if this is best. Specifically with MUX
|
||||||
this.policy = policy;
|
this.policy = policy;
|
||||||
this.bufferPool = bufferPool;
|
this.bufferPool = bufferPool;
|
||||||
this.generator = new Generator(policy,bufferPool);
|
this.generator = new Generator(policy,bufferPool);
|
||||||
|
@ -151,6 +151,7 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
|
||||||
this.ioState = new IOState();
|
this.ioState = new IOState();
|
||||||
this.ioState.setState(ConnectionState.CONNECTING);
|
this.ioState.setState(ConnectionState.CONNECTING);
|
||||||
this.writeBytes = new WriteBytesProvider(generator,new FlushCallback());
|
this.writeBytes = new WriteBytesProvider(generator,new FlushCallback());
|
||||||
|
this.setInputBufferSize(policy.getInputBufferSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2013 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.
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Jetty WebSocket Common : I/O Implementation
|
||||||
|
*/
|
||||||
|
package org.eclipse.jetty.websocket.common.io;
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2013 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.
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Jetty WebSocket Common : I/O : Frame Payload Handling
|
||||||
|
*/
|
||||||
|
package org.eclipse.jetty.websocket.common.io.payload;
|
||||||
|
|
|
@ -67,7 +67,7 @@ public class MessageInputStream extends InputStream implements MessageAppender
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
driver.getPolicy().assertValidBinaryMessageSize(size + payload.remaining());
|
driver.getPolicy().assertValidMessageSize(size + payload.remaining());
|
||||||
size += payload.remaining();
|
size += payload.remaining();
|
||||||
|
|
||||||
synchronized (buf)
|
synchronized (buf)
|
||||||
|
|
|
@ -61,7 +61,7 @@ public class MessageReader extends Reader implements MessageAppender
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
driver.getPolicy().assertValidTextMessageSize(size + payload.remaining());
|
driver.getPolicy().assertValidMessageSize(size + payload.remaining());
|
||||||
size += payload.remaining();
|
size += payload.remaining();
|
||||||
|
|
||||||
synchronized (utf)
|
synchronized (utf)
|
||||||
|
|
|
@ -54,7 +54,7 @@ public class SimpleBinaryMessage implements MessageAppender
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
onEvent.getPolicy().assertValidBinaryMessageSize(size + payload.remaining());
|
onEvent.getPolicy().assertValidMessageSize(size + payload.remaining());
|
||||||
size += payload.remaining();
|
size += payload.remaining();
|
||||||
|
|
||||||
BufferUtil.writeTo(payload,out);
|
BufferUtil.writeTo(payload,out);
|
||||||
|
|
|
@ -53,7 +53,7 @@ public class SimpleTextMessage implements MessageAppender
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
onEvent.getPolicy().assertValidTextMessageSize(size + payload.remaining());
|
onEvent.getPolicy().assertValidMessageSize(size + payload.remaining());
|
||||||
size += payload.remaining();
|
size += payload.remaining();
|
||||||
|
|
||||||
// allow for fast fail of BAD utf (incomplete utf will trigger on messageComplete)
|
// allow for fast fail of BAD utf (incomplete utf will trigger on messageComplete)
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2013 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.
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Jetty WebSocket Common : Message Handling
|
||||||
|
*/
|
||||||
|
package org.eclipse.jetty.websocket.common.message;
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2013 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.
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Jetty WebSocket Common : Implementation [<em>Internal Use Only</em>]
|
||||||
|
* <p>
|
||||||
|
* A core set of internal implementation classes for the Jetty WebSocket API.
|
||||||
|
* <p>
|
||||||
|
* Note: do not reference or use classes present in this package space in your code. <br />
|
||||||
|
* Restrict your usage to the Jetty WebSocket API classes, the Jetty WebSocket Client API,
|
||||||
|
* or the Jetty WebSocket Servlet API.
|
||||||
|
*/
|
||||||
|
package org.eclipse.jetty.websocket.common;
|
||||||
|
|
After Width: | Height: | Size: 70 KiB |
|
@ -0,0 +1,434 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="645"
|
||||||
|
height="350"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.3.1 r9886"
|
||||||
|
sodipodi:docname="websocket-stack-extensions.svg"
|
||||||
|
inkscape:export-filename="/home/joakim/code/intalio/org.eclipse.jetty9.project/jetty-websocket/websocket-core/src/main/javadoc/org/eclipse/jetty/websocket/doc-files/websocket-stack-extensions.png"
|
||||||
|
inkscape:export-xdpi="111.63"
|
||||||
|
inkscape:export-ydpi="111.63">
|
||||||
|
<defs
|
||||||
|
id="defs4" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="1.5972939"
|
||||||
|
inkscape:cx="332.46256"
|
||||||
|
inkscape:cy="171.52658"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1024"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="27"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
showguides="true"
|
||||||
|
inkscape:guide-bbox="true"
|
||||||
|
borderlayer="true">
|
||||||
|
<inkscape:grid
|
||||||
|
type="xygrid"
|
||||||
|
id="grid3006"
|
||||||
|
empspacing="5"
|
||||||
|
dotted="true"
|
||||||
|
visible="true"
|
||||||
|
enabled="true"
|
||||||
|
snapvisiblegridlinesonly="true"
|
||||||
|
spacingx="5px"
|
||||||
|
spacingy="5px" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer2"
|
||||||
|
inkscape:label="Background"
|
||||||
|
sodipodi:insensitive="true">
|
||||||
|
<rect
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:none"
|
||||||
|
id="rect3046"
|
||||||
|
width="645"
|
||||||
|
height="350"
|
||||||
|
x="9.2142858e-07"
|
||||||
|
y="5.0000006e-07" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(0,-702.36218)">
|
||||||
|
<rect
|
||||||
|
y="952.36218"
|
||||||
|
x="40.000004"
|
||||||
|
height="70"
|
||||||
|
width="560"
|
||||||
|
id="rect3977"
|
||||||
|
style="fill:#bdbdbd;fill-opacity:1;stroke:none" />
|
||||||
|
<rect
|
||||||
|
style="fill:#d1d1d1;fill-opacity:1;stroke:none"
|
||||||
|
id="rect3975"
|
||||||
|
width="560"
|
||||||
|
height="170"
|
||||||
|
x="40.000004"
|
||||||
|
y="782.36218" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#858585;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 1;stroke-dashoffset:0"
|
||||||
|
d="m 25.000004,952.36217 594.999996,0"
|
||||||
|
id="path4004"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<rect
|
||||||
|
y="732.36218"
|
||||||
|
x="40.000004"
|
||||||
|
height="50"
|
||||||
|
width="560"
|
||||||
|
id="rect3973"
|
||||||
|
style="fill:#e7e7e7;fill-opacity:1;stroke:none" />
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="cc"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3999"
|
||||||
|
d="m 25.000004,782.36217 594.999996,0"
|
||||||
|
style="fill:none;stroke:#858585;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 1;stroke-dashoffset:0" />
|
||||||
|
<g
|
||||||
|
transform="translate(24.999996,-35.000005)"
|
||||||
|
id="g4031">
|
||||||
|
<rect
|
||||||
|
style="fill:#caf3f6;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-opacity:1"
|
||||||
|
id="rect3008"
|
||||||
|
width="400"
|
||||||
|
height="25.000031"
|
||||||
|
x="25"
|
||||||
|
y="1047.3622" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||||
|
x="224.91454"
|
||||||
|
y="1063.7245"
|
||||||
|
id="text3778"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3780"
|
||||||
|
x="224.91454"
|
||||||
|
y="1063.7245">Physical Connection</tspan></text>
|
||||||
|
</g>
|
||||||
|
<rect
|
||||||
|
style="fill:#caf3f6;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-opacity:1"
|
||||||
|
id="rect3797"
|
||||||
|
width="400"
|
||||||
|
height="25"
|
||||||
|
x="49.999996"
|
||||||
|
y="987.36218" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||||
|
x="249.91455"
|
||||||
|
y="1003.7245"
|
||||||
|
id="text3799"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3801"
|
||||||
|
x="249.91455"
|
||||||
|
y="1003.7245">Jetty I/O EndPoint</tspan></text>
|
||||||
|
<rect
|
||||||
|
y="927.36212"
|
||||||
|
x="49.999996"
|
||||||
|
height="59.999992"
|
||||||
|
width="400"
|
||||||
|
id="rect3805"
|
||||||
|
style="fill:#caf3f6;fill-opacity:1;stroke:#000000;stroke-width:0.99999988;stroke-opacity:1" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text3807"
|
||||||
|
y="978.72449"
|
||||||
|
x="249.91455"
|
||||||
|
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="978.72449"
|
||||||
|
x="249.91455"
|
||||||
|
id="tspan3809"
|
||||||
|
sodipodi:role="line">Jetty WebSocketConnection</tspan></text>
|
||||||
|
<rect
|
||||||
|
style="color:#000000;fill:#000000;fill-opacity:0.12328766;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.56470588;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||||
|
id="rect3786"
|
||||||
|
width="190"
|
||||||
|
height="25"
|
||||||
|
x="60"
|
||||||
|
y="937.36218" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||||
|
x="149.31982"
|
||||||
|
y="954.86609"
|
||||||
|
id="text3815"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
id="tspan3822"
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="149.31982"
|
||||||
|
y="954.86609">Parser</tspan></text>
|
||||||
|
<rect
|
||||||
|
y="937.36218"
|
||||||
|
x="250"
|
||||||
|
height="25"
|
||||||
|
width="190"
|
||||||
|
id="rect3788"
|
||||||
|
style="color:#000000;fill:#000000;fill-opacity:0.12328766;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.56470588;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text3826"
|
||||||
|
y="954.95837"
|
||||||
|
x="314.03955"
|
||||||
|
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
id="tspan3830"
|
||||||
|
y="954.95837"
|
||||||
|
x="314.03955"
|
||||||
|
sodipodi:role="line">Generator</tspan></text>
|
||||||
|
<rect
|
||||||
|
style="fill:#caf3f6;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-opacity:1"
|
||||||
|
id="rect3849"
|
||||||
|
width="400"
|
||||||
|
height="59.999996"
|
||||||
|
x="50"
|
||||||
|
y="742.36218" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||||
|
x="249.91455"
|
||||||
|
y="758.72449"
|
||||||
|
id="text3851"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3853"
|
||||||
|
x="249.91455"
|
||||||
|
y="758.72449">WebSocket Session</tspan></text>
|
||||||
|
<rect
|
||||||
|
style="fill:#caf3f6;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-opacity:1"
|
||||||
|
id="rect3865"
|
||||||
|
width="400"
|
||||||
|
height="25"
|
||||||
|
x="50"
|
||||||
|
y="717.36218" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||||
|
x="249.91455"
|
||||||
|
y="733.72449"
|
||||||
|
id="text3867"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3869"
|
||||||
|
x="249.91455"
|
||||||
|
y="733.72449">WebSocket POJO</tspan></text>
|
||||||
|
<rect
|
||||||
|
y="767.36218"
|
||||||
|
x="60"
|
||||||
|
height="25"
|
||||||
|
width="190"
|
||||||
|
id="rect3881"
|
||||||
|
style="color:#000000;fill:#000000;fill-opacity:0.12328766;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.56470588;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||||
|
<text
|
||||||
|
transform="scale(0.9746794,1.0259784)"
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text3883"
|
||||||
|
y="765.2027"
|
||||||
|
x="158.80678"
|
||||||
|
style="font-size:13.64551163px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="765.2027"
|
||||||
|
x="158.80678"
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3885">EventDriver</tspan></text>
|
||||||
|
<rect
|
||||||
|
style="fill:#000000;fill-opacity:0.12328766;stroke:#000000;stroke-width:1;stroke-opacity:0.56470588"
|
||||||
|
id="rect3905"
|
||||||
|
width="190"
|
||||||
|
height="25"
|
||||||
|
x="250"
|
||||||
|
y="767.36218" />
|
||||||
|
<text
|
||||||
|
transform="scale(0.97467941,1.0259784)"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:13.64551163px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||||
|
x="353.74265"
|
||||||
|
y="765.2027"
|
||||||
|
id="text3907"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
id="tspan3909"
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="353.74265"
|
||||||
|
y="765.2027">RemoteEndpoint</tspan></text>
|
||||||
|
<rect
|
||||||
|
y="812.36218"
|
||||||
|
x="49.999996"
|
||||||
|
height="104.99999"
|
||||||
|
width="400"
|
||||||
|
id="rect4036"
|
||||||
|
style="fill:#fdff14;fill-opacity:0.37442926;stroke:#87882d;stroke-width:0.99999994;stroke-opacity:1" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text3979"
|
||||||
|
y="970.67273"
|
||||||
|
x="470"
|
||||||
|
style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="970.67273"
|
||||||
|
x="470"
|
||||||
|
id="tspan3981"
|
||||||
|
sodipodi:role="line">Network</tspan><tspan
|
||||||
|
id="tspan3983"
|
||||||
|
y="985.67273"
|
||||||
|
x="470"
|
||||||
|
sodipodi:role="line">(ByteBuffers)</tspan></text>
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text3985"
|
||||||
|
y="802.36218"
|
||||||
|
x="470"
|
||||||
|
style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="802.36218"
|
||||||
|
x="470"
|
||||||
|
id="tspan3987"
|
||||||
|
sodipodi:role="line">Internal</tspan><tspan
|
||||||
|
id="tspan3989"
|
||||||
|
y="817.36218"
|
||||||
|
x="470"
|
||||||
|
sodipodi:role="line">(WebSocket Frame)</tspan></text>
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text3991"
|
||||||
|
y="752.98816"
|
||||||
|
x="470"
|
||||||
|
style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="752.98816"
|
||||||
|
x="470"
|
||||||
|
id="tspan3993"
|
||||||
|
sodipodi:role="line">Message</tspan><tspan
|
||||||
|
id="tspan3995"
|
||||||
|
y="767.98816"
|
||||||
|
x="470"
|
||||||
|
sodipodi:role="line">(Text or Binary)</tspan></text>
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text3867-0"
|
||||||
|
y="827.36218"
|
||||||
|
x="249.34033"
|
||||||
|
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="827.36218"
|
||||||
|
x="249.34033"
|
||||||
|
id="tspan3869-0"
|
||||||
|
sodipodi:role="line">ExtensionStack</tspan></text>
|
||||||
|
<g
|
||||||
|
id="g4630"
|
||||||
|
transform="translate(0,10.000122)">
|
||||||
|
<rect
|
||||||
|
y="837.36218"
|
||||||
|
x="60"
|
||||||
|
height="20.000149"
|
||||||
|
width="380"
|
||||||
|
id="rect4588"
|
||||||
|
style="fill:#fdff14;fill-opacity:0.37442926;stroke:#87882d;stroke-width:0.99999994;stroke-opacity:1" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||||
|
x="249.91455"
|
||||||
|
y="851.22449"
|
||||||
|
id="text3867-0-6"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3869-0-8"
|
||||||
|
x="249.91455"
|
||||||
|
y="851.22449">Message Compression Extension</tspan></text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g4635"
|
||||||
|
transform="translate(0,29.999997)">
|
||||||
|
<rect
|
||||||
|
style="fill:#fdff14;fill-opacity:0.37442926;stroke:#87882d;stroke-width:0.99999994;stroke-opacity:1"
|
||||||
|
id="rect4637"
|
||||||
|
width="380"
|
||||||
|
height="20.000149"
|
||||||
|
x="60"
|
||||||
|
y="837.36218" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text4639"
|
||||||
|
y="851.22449"
|
||||||
|
x="249.91455"
|
||||||
|
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="851.22449"
|
||||||
|
x="249.91455"
|
||||||
|
id="tspan4641"
|
||||||
|
sodipodi:role="line">Fragmentation Extension</tspan></text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g4648">
|
||||||
|
<path
|
||||||
|
style="fill:#f7d1d1;fill-opacity:1;stroke:#dd9191;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
||||||
|
d="m 95.031248,947.36218 0,-141.74193 7.656252,0 -17.656252,-18.25807 -17.6875,18.25807 7.6875,0 0,141.74193 20,0 z"
|
||||||
|
id="rect3934"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||||
|
x="-925.48132"
|
||||||
|
y="88.87793"
|
||||||
|
id="text3948"
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
transform="matrix(0,-1,1,0,0,0)"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3950"
|
||||||
|
x="-925.48132"
|
||||||
|
y="88.87793">IncomingFrames</tspan></text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g4643">
|
||||||
|
<path
|
||||||
|
style="fill:#f7d1d1;fill-opacity:1;stroke:#dd9191;stroke-width:0.99999988;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
||||||
|
d="m 419.96875,947.3621 17.6875,-20.96294 -7.6875,0 0,-139.03698 -20,0 0,139.03698 -7.65625,0 17.65625,20.96294 z"
|
||||||
|
id="rect3954"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text3969"
|
||||||
|
y="-416.12207"
|
||||||
|
x="809.57794"
|
||||||
|
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||||
|
xml:space="preserve"
|
||||||
|
transform="matrix(0,1,-1,0,0,0)"><tspan
|
||||||
|
y="-416.12207"
|
||||||
|
x="809.57794"
|
||||||
|
id="tspan3971"
|
||||||
|
sodipodi:role="line">OutgoingFrames</tspan></text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 59 KiB |
|
@ -0,0 +1,384 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="645"
|
||||||
|
height="350"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.3.1 r9886"
|
||||||
|
sodipodi:docname="websocket-stack-simple.svg"
|
||||||
|
inkscape:export-filename="/home/joakim/code/intalio/org.eclipse.jetty9.project/jetty-websocket/websocket-common/src/main/javadoc/org/eclipse/jetty/websocket/common/doc-files/websocket-stack-simple.png"
|
||||||
|
inkscape:export-xdpi="111.63"
|
||||||
|
inkscape:export-ydpi="111.63">
|
||||||
|
<defs
|
||||||
|
id="defs4" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="1.6652639"
|
||||||
|
inkscape:cx="375.14499"
|
||||||
|
inkscape:cy="194.35762"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1024"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="27"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
showguides="true"
|
||||||
|
inkscape:guide-bbox="true"
|
||||||
|
borderlayer="true">
|
||||||
|
<inkscape:grid
|
||||||
|
type="xygrid"
|
||||||
|
id="grid3006"
|
||||||
|
empspacing="5"
|
||||||
|
dotted="true"
|
||||||
|
visible="true"
|
||||||
|
enabled="true"
|
||||||
|
snapvisiblegridlinesonly="true"
|
||||||
|
spacingx="5px"
|
||||||
|
spacingy="5px" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer2"
|
||||||
|
inkscape:label="Background"
|
||||||
|
sodipodi:insensitive="true">
|
||||||
|
<rect
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:none"
|
||||||
|
id="rect3089"
|
||||||
|
width="645"
|
||||||
|
height="350"
|
||||||
|
x="0"
|
||||||
|
y="0" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(0,-702.36218)">
|
||||||
|
<rect
|
||||||
|
style="fill:#bdbdbd;fill-opacity:1;stroke:none"
|
||||||
|
id="rect3977"
|
||||||
|
width="560"
|
||||||
|
height="70"
|
||||||
|
x="40.000004"
|
||||||
|
y="952.36218" />
|
||||||
|
<rect
|
||||||
|
y="782.36218"
|
||||||
|
x="40.000004"
|
||||||
|
height="170"
|
||||||
|
width="560"
|
||||||
|
id="rect3975"
|
||||||
|
style="fill:#d1d1d1;fill-opacity:1;stroke:none" />
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="cc"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4004"
|
||||||
|
d="m 25.000004,952.36217 594.999996,0"
|
||||||
|
style="fill:none;stroke:#858585;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 1;stroke-dashoffset:0" />
|
||||||
|
<rect
|
||||||
|
style="fill:#e7e7e7;fill-opacity:1;stroke:none"
|
||||||
|
id="rect3973"
|
||||||
|
width="560"
|
||||||
|
height="50"
|
||||||
|
x="40.000004"
|
||||||
|
y="732.36218" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#858585;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 1;stroke-dashoffset:0"
|
||||||
|
d="m 25.000004,782.36217 594.999996,0"
|
||||||
|
id="path3999"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<g
|
||||||
|
id="g4031"
|
||||||
|
transform="translate(24.999996,-35.000005)">
|
||||||
|
<rect
|
||||||
|
y="1047.3622"
|
||||||
|
x="25"
|
||||||
|
height="25.000031"
|
||||||
|
width="400"
|
||||||
|
id="rect3008"
|
||||||
|
style="fill:#caf3f6;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-opacity:1" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text3778"
|
||||||
|
y="1063.7245"
|
||||||
|
x="224.91454"
|
||||||
|
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="1063.7245"
|
||||||
|
x="224.91454"
|
||||||
|
id="tspan3780"
|
||||||
|
sodipodi:role="line">Physical Connection</tspan></text>
|
||||||
|
</g>
|
||||||
|
<rect
|
||||||
|
y="987.36218"
|
||||||
|
x="49.999996"
|
||||||
|
height="25"
|
||||||
|
width="400"
|
||||||
|
id="rect3797"
|
||||||
|
style="fill:#caf3f6;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-opacity:1" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text3799"
|
||||||
|
y="1003.7245"
|
||||||
|
x="249.91455"
|
||||||
|
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="1003.7245"
|
||||||
|
x="249.91455"
|
||||||
|
id="tspan3801"
|
||||||
|
sodipodi:role="line">Jetty I/O EndPoint</tspan></text>
|
||||||
|
<rect
|
||||||
|
style="fill:#caf3f6;fill-opacity:1;stroke:#000000;stroke-width:0.99999988;stroke-opacity:1"
|
||||||
|
id="rect3805"
|
||||||
|
width="400"
|
||||||
|
height="59.999992"
|
||||||
|
x="49.999996"
|
||||||
|
y="927.36212" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||||
|
x="249.91455"
|
||||||
|
y="978.72449"
|
||||||
|
id="text3807"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3809"
|
||||||
|
x="249.91455"
|
||||||
|
y="978.72449">Jetty WebSocketConnection</tspan></text>
|
||||||
|
<rect
|
||||||
|
y="937.36218"
|
||||||
|
x="60"
|
||||||
|
height="25"
|
||||||
|
width="190"
|
||||||
|
id="rect3786"
|
||||||
|
style="fill:#000000;fill-opacity:0.12328765999999999;stroke:#000000;stroke-width:1;stroke-opacity:0.56470587999999999;color:#000000;fill-rule:nonzero;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text3815"
|
||||||
|
y="954.86609"
|
||||||
|
x="149.31982"
|
||||||
|
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="954.86609"
|
||||||
|
x="149.31982"
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3822">Parser</tspan></text>
|
||||||
|
<rect
|
||||||
|
style="fill:#000000;fill-opacity:0.12328765999999999;stroke:#000000;stroke-width:1;stroke-opacity:0.56470587999999999;color:#000000;fill-rule:nonzero;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||||
|
id="rect3788"
|
||||||
|
width="190"
|
||||||
|
height="25"
|
||||||
|
x="250"
|
||||||
|
y="937.36218" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||||
|
x="314.03955"
|
||||||
|
y="954.95837"
|
||||||
|
id="text3826"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="314.03955"
|
||||||
|
y="954.95837"
|
||||||
|
id="tspan3830">Generator</tspan></text>
|
||||||
|
<rect
|
||||||
|
y="742.36218"
|
||||||
|
x="50"
|
||||||
|
height="59.999996"
|
||||||
|
width="400"
|
||||||
|
id="rect3849"
|
||||||
|
style="fill:#caf3f6;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-opacity:1" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text3851"
|
||||||
|
y="758.72449"
|
||||||
|
x="249.91455"
|
||||||
|
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="758.72449"
|
||||||
|
x="249.91455"
|
||||||
|
id="tspan3853"
|
||||||
|
sodipodi:role="line">WebSocket Session</tspan></text>
|
||||||
|
<rect
|
||||||
|
y="717.36218"
|
||||||
|
x="50"
|
||||||
|
height="25"
|
||||||
|
width="400"
|
||||||
|
id="rect3865"
|
||||||
|
style="fill:#caf3f6;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-opacity:1" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text3867"
|
||||||
|
y="733.72449"
|
||||||
|
x="249.91455"
|
||||||
|
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="733.72449"
|
||||||
|
x="249.91455"
|
||||||
|
id="tspan3869"
|
||||||
|
sodipodi:role="line">WebSocket POJO</tspan></text>
|
||||||
|
<rect
|
||||||
|
style="fill:#000000;fill-opacity:0.12328765999999999;stroke:#000000;stroke-width:1;stroke-opacity:0.56470587999999999;color:#000000;fill-rule:nonzero;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||||
|
id="rect3881"
|
||||||
|
width="190"
|
||||||
|
height="25"
|
||||||
|
x="60"
|
||||||
|
y="767.36218" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:13.64551163px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||||
|
x="158.80678"
|
||||||
|
y="765.2027"
|
||||||
|
id="text3883"
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
transform="scale(0.97467942,1.0259784)"><tspan
|
||||||
|
id="tspan3885"
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="158.80678"
|
||||||
|
y="765.2027">EventDriver</tspan></text>
|
||||||
|
<rect
|
||||||
|
y="767.36218"
|
||||||
|
x="250"
|
||||||
|
height="25"
|
||||||
|
width="190"
|
||||||
|
id="rect3905"
|
||||||
|
style="fill:#000000;fill-opacity:0.12328767000000000;stroke:#000000;stroke-width:1;stroke-opacity:0.56470591" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text3907"
|
||||||
|
y="765.2027"
|
||||||
|
x="353.74265"
|
||||||
|
style="font-size:13.64551163px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||||
|
xml:space="preserve"
|
||||||
|
transform="scale(0.97467943,1.0259784)"><tspan
|
||||||
|
y="765.2027"
|
||||||
|
x="353.74265"
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3909">RemoteEndpoint</tspan></text>
|
||||||
|
<rect
|
||||||
|
style="fill:#fdff14;fill-opacity:0.37442925999999999;stroke:#87882d;stroke-width:0.99999994000000003;stroke-opacity:1"
|
||||||
|
id="rect4036"
|
||||||
|
width="400"
|
||||||
|
height="104.99999"
|
||||||
|
x="49.999996"
|
||||||
|
y="812.36218" />
|
||||||
|
<path
|
||||||
|
style="fill:#f7d1d1;fill-opacity:1;stroke:#dd9191;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
||||||
|
d="m 95.031248,947.36218 0,-141.74193 7.656252,0 -17.656252,-18.25807 -17.6875,18.25807 7.6875,0 0,141.74193 20,0 z"
|
||||||
|
id="rect3934"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||||
|
x="-925.48132"
|
||||||
|
y="88.87793"
|
||||||
|
id="text3948"
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
transform="matrix(0,-1,1,0,0,0)"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3950"
|
||||||
|
x="-925.48132"
|
||||||
|
y="88.87793">IncomingFrames</tspan></text>
|
||||||
|
<path
|
||||||
|
style="fill:#f7d1d1;fill-opacity:1;stroke:#dd9191;stroke-width:0.99999988;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
||||||
|
d="m 419.96875,947.3621 17.6875,-20.96294 -7.6875,0 0,-139.03698 -20,0 0,139.03698 -7.65625,0 17.65625,20.96294 z"
|
||||||
|
id="rect3954"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text3969"
|
||||||
|
y="-416.12207"
|
||||||
|
x="809.57794"
|
||||||
|
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||||
|
xml:space="preserve"
|
||||||
|
transform="matrix(0,1,-1,0,0,0)"><tspan
|
||||||
|
y="-416.12207"
|
||||||
|
x="809.57794"
|
||||||
|
id="tspan3971"
|
||||||
|
sodipodi:role="line">OutgoingFrames</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||||
|
x="470"
|
||||||
|
y="970.67273"
|
||||||
|
id="text3979"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3981"
|
||||||
|
x="470"
|
||||||
|
y="970.67273">Network</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="470"
|
||||||
|
y="985.67273"
|
||||||
|
id="tspan3983">(ByteBuffers)</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||||
|
x="470"
|
||||||
|
y="802.36218"
|
||||||
|
id="text3985"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3987"
|
||||||
|
x="470"
|
||||||
|
y="802.36218">Internal</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="470"
|
||||||
|
y="817.36218"
|
||||||
|
id="tspan3989">(WebSocket Frame)</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||||
|
x="470"
|
||||||
|
y="752.98816"
|
||||||
|
id="text3991"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3993"
|
||||||
|
x="470"
|
||||||
|
y="752.98816">Message</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="470"
|
||||||
|
y="767.98816"
|
||||||
|
id="tspan3995">(Text or Binary)</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||||
|
x="249.34033"
|
||||||
|
y="827.36218"
|
||||||
|
id="text3867-0"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3869-0"
|
||||||
|
x="249.34033"
|
||||||
|
y="827.36218">ExtensionStack</tspan></text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 94 KiB |
|
@ -1,802 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
width="645"
|
|
||||||
height="350"
|
|
||||||
id="svg2"
|
|
||||||
version="1.1"
|
|
||||||
inkscape:version="0.48.3.1 r9886"
|
|
||||||
sodipodi:docname="javax.net.websocket-stack-extensions.svg"
|
|
||||||
inkscape:export-filename="/home/joakim/code/intalio/org.eclipse.jetty9.project/jetty-websocket/websocket-common/src/main/javadoc/org/eclipse/jetty/websocket/doc-files/javax.net.websocket-stack-extensions.png"
|
|
||||||
inkscape:export-xdpi="111.63"
|
|
||||||
inkscape:export-ydpi="111.63">
|
|
||||||
<defs
|
|
||||||
id="defs4">
|
|
||||||
<linearGradient
|
|
||||||
inkscape:collect="always"
|
|
||||||
id="linearGradient3965">
|
|
||||||
<stop
|
|
||||||
style="stop-color:#caf3f6;stop-opacity:1;"
|
|
||||||
offset="0"
|
|
||||||
id="stop3967" />
|
|
||||||
<stop
|
|
||||||
style="stop-color:#caf3f6;stop-opacity:0;"
|
|
||||||
offset="1"
|
|
||||||
id="stop3969" />
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient
|
|
||||||
inkscape:collect="always"
|
|
||||||
xlink:href="#linearGradient3965"
|
|
||||||
id="linearGradient3971"
|
|
||||||
x1="250"
|
|
||||||
y1="772.36218"
|
|
||||||
x2="250"
|
|
||||||
y2="927.36218"
|
|
||||||
gradientUnits="userSpaceOnUse" />
|
|
||||||
</defs>
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="2.1472868"
|
|
||||||
inkscape:cx="304.93654"
|
|
||||||
inkscape:cy="184.92979"
|
|
||||||
inkscape:document-units="px"
|
|
||||||
inkscape:current-layer="layer1"
|
|
||||||
showgrid="true"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1024"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="27"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
showguides="true"
|
|
||||||
inkscape:guide-bbox="true"
|
|
||||||
borderlayer="true"
|
|
||||||
inkscape:snap-grids="true">
|
|
||||||
<inkscape:grid
|
|
||||||
type="xygrid"
|
|
||||||
id="grid3006"
|
|
||||||
empspacing="5"
|
|
||||||
dotted="true"
|
|
||||||
visible="true"
|
|
||||||
enabled="true"
|
|
||||||
snapvisiblegridlinesonly="true"
|
|
||||||
spacingx="5px"
|
|
||||||
spacingy="5px" />
|
|
||||||
</sodipodi:namedview>
|
|
||||||
<metadata
|
|
||||||
id="metadata7">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title></dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer2"
|
|
||||||
inkscape:label="Background"
|
|
||||||
sodipodi:insensitive="true">
|
|
||||||
<rect
|
|
||||||
style="fill:#ffffff;fill-opacity:1;stroke:none"
|
|
||||||
id="rect3089"
|
|
||||||
width="645"
|
|
||||||
height="350"
|
|
||||||
x="0"
|
|
||||||
y="0" />
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(0,-702.36218)">
|
|
||||||
<rect
|
|
||||||
style="fill:#b9b9b9;fill-opacity:1;stroke:none"
|
|
||||||
id="rect3977"
|
|
||||||
width="560"
|
|
||||||
height="70.000008"
|
|
||||||
x="40.000004"
|
|
||||||
y="957.36218" />
|
|
||||||
<rect
|
|
||||||
y="812.36218"
|
|
||||||
x="40.000004"
|
|
||||||
height="145"
|
|
||||||
width="560"
|
|
||||||
id="rect3975"
|
|
||||||
style="fill:#d1d1d1;fill-opacity:1;stroke:none" />
|
|
||||||
<rect
|
|
||||||
style="fill:#ececec;fill-opacity:1;stroke:none"
|
|
||||||
id="rect3973"
|
|
||||||
width="560"
|
|
||||||
height="75"
|
|
||||||
x="40.000004"
|
|
||||||
y="737.24573" />
|
|
||||||
<path
|
|
||||||
style="fill:none;stroke:#858585;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 1;stroke-dashoffset:0"
|
|
||||||
d="m 25.000004,812.36217 594.999996,0"
|
|
||||||
id="path3999"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
sodipodi:nodetypes="cc" />
|
|
||||||
<g
|
|
||||||
id="g3132"
|
|
||||||
transform="translate(0,79.999997)">
|
|
||||||
<rect
|
|
||||||
y="937.36218"
|
|
||||||
x="50"
|
|
||||||
height="25.000031"
|
|
||||||
width="400"
|
|
||||||
id="rect3008"
|
|
||||||
style="fill:#caf3f6;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-opacity:1" />
|
|
||||||
<text
|
|
||||||
sodipodi:linespacing="125%"
|
|
||||||
id="text3778"
|
|
||||||
y="953.72449"
|
|
||||||
x="249.91454"
|
|
||||||
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
|
||||||
xml:space="preserve"><tspan
|
|
||||||
y="953.72449"
|
|
||||||
x="249.91454"
|
|
||||||
id="tspan3780"
|
|
||||||
sodipodi:role="line">Physical Connection</tspan></text>
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g3137"
|
|
||||||
transform="translate(0,29.999997)">
|
|
||||||
<rect
|
|
||||||
style="fill:#caf3f6;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-opacity:1"
|
|
||||||
id="rect3797"
|
|
||||||
width="400"
|
|
||||||
height="25"
|
|
||||||
x="50"
|
|
||||||
y="962.36218" />
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
|
||||||
x="249.91455"
|
|
||||||
y="978.72449"
|
|
||||||
id="text3799"
|
|
||||||
sodipodi:linespacing="125%"><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
id="tspan3801"
|
|
||||||
x="249.91455"
|
|
||||||
y="978.72449">AsyncEndPoint</tspan></text>
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g3142"
|
|
||||||
transform="translate(0,-20.000003)">
|
|
||||||
<rect
|
|
||||||
y="987.36218"
|
|
||||||
x="50"
|
|
||||||
height="24.999996"
|
|
||||||
width="400"
|
|
||||||
id="rect3805"
|
|
||||||
style="fill:#caf3f6;fill-opacity:1;stroke:#000000;stroke-width:0.99999994;stroke-opacity:1" />
|
|
||||||
<text
|
|
||||||
sodipodi:linespacing="125%"
|
|
||||||
id="text3807"
|
|
||||||
y="1003.7245"
|
|
||||||
x="249.91455"
|
|
||||||
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
|
||||||
xml:space="preserve"><tspan
|
|
||||||
y="1003.7245"
|
|
||||||
x="249.91455"
|
|
||||||
id="tspan3809"
|
|
||||||
sodipodi:role="line">WebSocketAsyncConnection</tspan></text>
|
|
||||||
</g>
|
|
||||||
<path
|
|
||||||
sodipodi:nodetypes="cc"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path4004"
|
|
||||||
d="m 25.000004,957.36218 594.999996,0"
|
|
||||||
style="fill:none;stroke:#858585;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 1;stroke-dashoffset:0" />
|
|
||||||
<g
|
|
||||||
id="g3152"
|
|
||||||
transform="translate(0,-70.000003)">
|
|
||||||
<rect
|
|
||||||
style="fill:#caf3f6;fill-opacity:1;stroke:#000000;stroke-width:0.99999994;stroke-opacity:1"
|
|
||||||
id="rect3786"
|
|
||||||
width="200"
|
|
||||||
height="25"
|
|
||||||
x="50"
|
|
||||||
y="1012.3622" />
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
|
||||||
x="149.31982"
|
|
||||||
y="1029.8661"
|
|
||||||
id="text3815"
|
|
||||||
sodipodi:linespacing="125%"><tspan
|
|
||||||
id="tspan3822"
|
|
||||||
sodipodi:role="line"
|
|
||||||
x="149.31982"
|
|
||||||
y="1029.8661">Parser</tspan></text>
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g3147"
|
|
||||||
transform="translate(0,-70.000003)">
|
|
||||||
<rect
|
|
||||||
y="1012.3622"
|
|
||||||
x="250"
|
|
||||||
height="25"
|
|
||||||
width="200"
|
|
||||||
id="rect3788"
|
|
||||||
style="fill:#caf3f6;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-opacity:1" />
|
|
||||||
<text
|
|
||||||
sodipodi:linespacing="125%"
|
|
||||||
id="text3826"
|
|
||||||
y="1029.9584"
|
|
||||||
x="314.03955"
|
|
||||||
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
|
||||||
xml:space="preserve"><tspan
|
|
||||||
id="tspan3830"
|
|
||||||
y="1029.9584"
|
|
||||||
x="314.03955"
|
|
||||||
sodipodi:role="line">Generator</tspan></text>
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g3954"
|
|
||||||
transform="translate(-0.0854492,38.643061)">
|
|
||||||
<rect
|
|
||||||
style="fill:#caf3f6;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-opacity:1"
|
|
||||||
id="rect3849"
|
|
||||||
width="400"
|
|
||||||
height="25"
|
|
||||||
x="50.085449"
|
|
||||||
y="710.99988" />
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
|
||||||
x="250"
|
|
||||||
y="727.36218"
|
|
||||||
id="text3851"
|
|
||||||
sodipodi:linespacing="125%"><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
id="tspan3853"
|
|
||||||
x="250"
|
|
||||||
y="727.36218">WebSocketEndPoint</tspan></text>
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g3949"
|
|
||||||
transform="translate(-0.0854492,-36.356939)">
|
|
||||||
<rect
|
|
||||||
style="fill:#caf3f6;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-opacity:1"
|
|
||||||
id="rect3865"
|
|
||||||
width="400"
|
|
||||||
height="25"
|
|
||||||
x="50.085449"
|
|
||||||
y="760.99988" />
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
|
||||||
x="250"
|
|
||||||
y="777.36218"
|
|
||||||
id="text3867"
|
|
||||||
sodipodi:linespacing="125%"><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
id="tspan3869"
|
|
||||||
x="250"
|
|
||||||
y="777.36218">WebSocket Object</tspan></text>
|
|
||||||
</g>
|
|
||||||
<rect
|
|
||||||
style="fill:url(#linearGradient3971);fill-opacity:1;stroke:#000000;stroke-width:1;stroke-opacity:1"
|
|
||||||
id="rect3961"
|
|
||||||
width="400"
|
|
||||||
height="152.71928"
|
|
||||||
x="50"
|
|
||||||
y="774.64294" />
|
|
||||||
<rect
|
|
||||||
style="fill:#caf3f6;fill-opacity:1;stroke:#000000;stroke-width:0.90829504;stroke-opacity:1"
|
|
||||||
id="rect3881"
|
|
||||||
width="164.99998"
|
|
||||||
height="25"
|
|
||||||
x="60"
|
|
||||||
y="799.64294" />
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
|
||||||
x="136.81982"
|
|
||||||
y="817.36218"
|
|
||||||
id="text3883"
|
|
||||||
sodipodi:linespacing="125%"><tspan
|
|
||||||
id="tspan3885"
|
|
||||||
sodipodi:role="line"
|
|
||||||
x="136.81982"
|
|
||||||
y="817.36218">EventDriver</tspan></text>
|
|
||||||
<rect
|
|
||||||
y="799.64294"
|
|
||||||
x="229.99998"
|
|
||||||
height="25"
|
|
||||||
width="209.99998"
|
|
||||||
id="rect3905"
|
|
||||||
style="fill:#caf3f6;fill-opacity:1;stroke:#000000;stroke-width:1.03682196;stroke-opacity:1" />
|
|
||||||
<text
|
|
||||||
sodipodi:linespacing="125%"
|
|
||||||
id="text3907"
|
|
||||||
y="817.36218"
|
|
||||||
x="334.93845"
|
|
||||||
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
|
||||||
xml:space="preserve"><tspan
|
|
||||||
y="817.36218"
|
|
||||||
x="334.93845"
|
|
||||||
sodipodi:role="line"
|
|
||||||
id="tspan3909">WebSocketRemoteEndpoint</tspan></text>
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
|
||||||
x="249.91455"
|
|
||||||
y="791.00525"
|
|
||||||
id="text3963"
|
|
||||||
sodipodi:linespacing="125%"><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
id="tspan3965"
|
|
||||||
x="249.91455"
|
|
||||||
y="791.00525">WebSocketSession</tspan></text>
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
|
||||||
x="484.2207"
|
|
||||||
y="987.36218"
|
|
||||||
id="text3979"
|
|
||||||
sodipodi:linespacing="125%"><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
id="tspan3981"
|
|
||||||
x="484.2207"
|
|
||||||
y="987.36218">Network</tspan><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
x="484.2207"
|
|
||||||
y="1002.3622"
|
|
||||||
id="tspan3983">ByteBuffers</tspan></text>
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
|
||||||
x="485"
|
|
||||||
y="847.36218"
|
|
||||||
id="text3985"
|
|
||||||
sodipodi:linespacing="125%"><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
id="tspan3987"
|
|
||||||
x="485"
|
|
||||||
y="847.36218">Internal</tspan><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
x="485"
|
|
||||||
y="862.36218"
|
|
||||||
id="tspan3989">WebSocketFrame</tspan></text>
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
|
||||||
x="485.43359"
|
|
||||||
y="762.36218"
|
|
||||||
id="text3991"
|
|
||||||
sodipodi:linespacing="125%"><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
id="tspan3993"
|
|
||||||
x="485.43359"
|
|
||||||
y="762.36218">Message</tspan><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
x="485.43359"
|
|
||||||
y="777.36218"
|
|
||||||
id="tspan3995">Text or Binary</tspan></text>
|
|
||||||
<rect
|
|
||||||
style="fill:#e84400;fill-opacity:1;stroke:none"
|
|
||||||
id="rect4032"
|
|
||||||
width="65.063103"
|
|
||||||
height="11.709856"
|
|
||||||
x="414.50586"
|
|
||||||
y="757.07648"
|
|
||||||
ry="5.854928" />
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-size:10.80251503px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans"
|
|
||||||
x="421.08868"
|
|
||||||
y="766.78979"
|
|
||||||
id="text4034"
|
|
||||||
sodipodi:linespacing="125%"><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
id="tspan4036"
|
|
||||||
x="421.08868"
|
|
||||||
y="766.78979"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#ffffff;fill-opacity:1;font-family:Droid Sans Mono;-inkscape-font-specification:Droid Sans Mono">EndPoint</tspan></text>
|
|
||||||
<rect
|
|
||||||
ry="5.854928"
|
|
||||||
y="781.06757"
|
|
||||||
x="418.32745"
|
|
||||||
height="11.709856"
|
|
||||||
width="59.474655"
|
|
||||||
id="rect4045"
|
|
||||||
style="fill:#e84400;fill-opacity:1;stroke:none" />
|
|
||||||
<text
|
|
||||||
sodipodi:linespacing="125%"
|
|
||||||
id="text4047"
|
|
||||||
y="790.78094"
|
|
||||||
x="425.44174"
|
|
||||||
style="font-size:10.80251503px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans"
|
|
||||||
xml:space="preserve"><tspan
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#ffffff;fill-opacity:1;font-family:Droid Sans Mono;-inkscape-font-specification:Droid Sans Mono"
|
|
||||||
y="790.78094"
|
|
||||||
x="425.44174"
|
|
||||||
id="tspan4049"
|
|
||||||
sodipodi:role="line">Session</tspan></text>
|
|
||||||
<g
|
|
||||||
id="g3979"
|
|
||||||
transform="translate(-6.9855596,-6.0541516)">
|
|
||||||
<rect
|
|
||||||
ry="5.854928"
|
|
||||||
y="804.20941"
|
|
||||||
x="439.77084"
|
|
||||||
height="11.709856"
|
|
||||||
width="103.94939"
|
|
||||||
id="rect4053"
|
|
||||||
style="fill:#e84400;fill-opacity:1;stroke:none" />
|
|
||||||
<text
|
|
||||||
sodipodi:linespacing="125%"
|
|
||||||
id="text4055"
|
|
||||||
y="813.92279"
|
|
||||||
x="446.44672"
|
|
||||||
style="font-size:10.80251503px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans"
|
|
||||||
xml:space="preserve"><tspan
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#ffffff;fill-opacity:1;font-family:Droid Sans Mono;-inkscape-font-specification:Droid Sans Mono"
|
|
||||||
y="813.92279"
|
|
||||||
x="446.44672"
|
|
||||||
id="tspan4057"
|
|
||||||
sodipodi:role="line">RemoteEndpoint</tspan></text>
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g4070"
|
|
||||||
transform="translate(3.6030325,-99.6839)">
|
|
||||||
<rect
|
|
||||||
ry="5.854928"
|
|
||||||
y="921.58582"
|
|
||||||
x="85.647453"
|
|
||||||
height="11.709856"
|
|
||||||
width="88.274292"
|
|
||||||
id="rect4061"
|
|
||||||
style="fill:#e84400;fill-opacity:1;stroke:none" />
|
|
||||||
<text
|
|
||||||
sodipodi:linespacing="125%"
|
|
||||||
id="text4063"
|
|
||||||
y="931.29919"
|
|
||||||
x="90.723061"
|
|
||||||
style="font-size:10.80251503px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans"
|
|
||||||
xml:space="preserve"><tspan
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#ffffff;fill-opacity:1;font-family:Droid Sans Mono;-inkscape-font-specification:Droid Sans Mono"
|
|
||||||
y="931.29919"
|
|
||||||
x="90.723061"
|
|
||||||
id="tspan4065"
|
|
||||||
sodipodi:role="line">FrameHandler</tspan></text>
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
transform="translate(228.00221,11.948808)"
|
|
||||||
id="g4075">
|
|
||||||
<rect
|
|
||||||
style="fill:#e84400;fill-opacity:1;stroke:none"
|
|
||||||
id="rect4077"
|
|
||||||
width="88.274292"
|
|
||||||
height="11.709856"
|
|
||||||
x="85.647453"
|
|
||||||
y="921.58582"
|
|
||||||
ry="5.854928" />
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-size:10.80251503px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans"
|
|
||||||
x="90.723061"
|
|
||||||
y="931.29919"
|
|
||||||
id="text4079"
|
|
||||||
sodipodi:linespacing="125%"><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
id="tspan4081"
|
|
||||||
x="90.723061"
|
|
||||||
y="931.29919"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#ffffff;fill-opacity:1;font-family:Droid Sans Mono;-inkscape-font-specification:Droid Sans Mono">FrameHandler</tspan></text>
|
|
||||||
</g>
|
|
||||||
<rect
|
|
||||||
ry="5.854928"
|
|
||||||
y="780.36169"
|
|
||||||
x="59.872288"
|
|
||||||
height="11.709856"
|
|
||||||
width="107.44216"
|
|
||||||
id="rect4112"
|
|
||||||
style="fill:#e84400;fill-opacity:1;stroke:none" />
|
|
||||||
<text
|
|
||||||
sodipodi:linespacing="125%"
|
|
||||||
id="text4114"
|
|
||||||
y="790.07501"
|
|
||||||
x="66.455116"
|
|
||||||
style="font-size:10.80251503px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans"
|
|
||||||
xml:space="preserve"><tspan
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#ffffff;fill-opacity:1;font-family:Droid Sans Mono;-inkscape-font-specification:Droid Sans Mono"
|
|
||||||
y="790.07501"
|
|
||||||
x="66.455116"
|
|
||||||
id="tspan4116"
|
|
||||||
sodipodi:role="line">MessageHandler</tspan></text>
|
|
||||||
<rect
|
|
||||||
style="fill:#e84400;fill-opacity:1;stroke:none"
|
|
||||||
id="rect4118"
|
|
||||||
width="63.665989"
|
|
||||||
height="11.709856"
|
|
||||||
x="328.81635"
|
|
||||||
y="780.59454"
|
|
||||||
ry="5.854928" />
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-size:10.80251503px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans"
|
|
||||||
x="337.85223"
|
|
||||||
y="790.30786"
|
|
||||||
id="text4120"
|
|
||||||
sodipodi:linespacing="125%"><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
id="tspan4122"
|
|
||||||
x="337.85223"
|
|
||||||
y="790.30786"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#ffffff;fill-opacity:1;font-family:Droid Sans Mono;-inkscape-font-specification:Droid Sans Mono">Encoder</tspan></text>
|
|
||||||
<g
|
|
||||||
id="g3856"
|
|
||||||
transform="translate(-0.81398971,4.1913356)">
|
|
||||||
<rect
|
|
||||||
y="848.0545"
|
|
||||||
x="191.13927"
|
|
||||||
height="25"
|
|
||||||
width="112.82959"
|
|
||||||
id="rect3072"
|
|
||||||
style="fill:#f6f4ca;fill-opacity:1;stroke:#000000;stroke-width:0.53110641;stroke-opacity:1" />
|
|
||||||
<text
|
|
||||||
sodipodi:linespacing="125%"
|
|
||||||
id="text3074"
|
|
||||||
y="865.77374"
|
|
||||||
x="247.57115"
|
|
||||||
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
|
||||||
xml:space="preserve"><tspan
|
|
||||||
y="865.77374"
|
|
||||||
x="247.57115"
|
|
||||||
id="tspan3076"
|
|
||||||
sodipodi:role="line">Extension 2</tspan></text>
|
|
||||||
</g>
|
|
||||||
<rect
|
|
||||||
y="841.53467"
|
|
||||||
x="72.885246"
|
|
||||||
height="25"
|
|
||||||
width="129.32132"
|
|
||||||
id="rect3850"
|
|
||||||
style="fill:#f6f4ca;fill-opacity:1;stroke:#000000;stroke-width:0.56859767;stroke-opacity:1" />
|
|
||||||
<text
|
|
||||||
sodipodi:linespacing="125%"
|
|
||||||
id="text3852"
|
|
||||||
y="857.89697"
|
|
||||||
x="126.25812"
|
|
||||||
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
|
||||||
xml:space="preserve"><tspan
|
|
||||||
y="857.89697"
|
|
||||||
x="126.25812"
|
|
||||||
id="tspan3854"
|
|
||||||
sodipodi:role="line">Incoming</tspan></text>
|
|
||||||
<rect
|
|
||||||
style="fill:#f6f4ca;fill-opacity:1;stroke:#000000;stroke-width:0.56353527;stroke-opacity:1"
|
|
||||||
id="rect3861"
|
|
||||||
width="127.02879"
|
|
||||||
height="25"
|
|
||||||
x="295.69891"
|
|
||||||
y="860.62854" />
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
|
||||||
x="370.28702"
|
|
||||||
y="876.99084"
|
|
||||||
id="text3863"
|
|
||||||
sodipodi:linespacing="125%"><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
id="tspan3865"
|
|
||||||
x="370.28702"
|
|
||||||
y="876.99084">Outgoing</tspan></text>
|
|
||||||
<g
|
|
||||||
transform="translate(-0.81398971,41.913358)"
|
|
||||||
id="g3877">
|
|
||||||
<rect
|
|
||||||
style="fill:#f6f4ca;fill-opacity:1;stroke:#000000;stroke-width:0.53110641;stroke-opacity:1"
|
|
||||||
id="rect3879"
|
|
||||||
width="112.82959"
|
|
||||||
height="25"
|
|
||||||
x="191.13927"
|
|
||||||
y="848.0545" />
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
|
||||||
x="247.57115"
|
|
||||||
y="865.77374"
|
|
||||||
id="text3881"
|
|
||||||
sodipodi:linespacing="125%"><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
id="tspan3883"
|
|
||||||
x="247.57115"
|
|
||||||
y="865.77374">Extension 1</tspan></text>
|
|
||||||
</g>
|
|
||||||
<rect
|
|
||||||
style="fill:#f6f4ca;fill-opacity:1;stroke:#000000;stroke-width:0.56359768;stroke-opacity:1"
|
|
||||||
id="rect3887"
|
|
||||||
width="127.05691"
|
|
||||||
height="25"
|
|
||||||
x="75.149658"
|
|
||||||
y="879.25665" />
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
|
||||||
x="126.25812"
|
|
||||||
y="895.61896"
|
|
||||||
id="text3889"
|
|
||||||
sodipodi:linespacing="125%"><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
id="tspan3891"
|
|
||||||
x="126.25812"
|
|
||||||
y="895.61896">Incoming</tspan></text>
|
|
||||||
<rect
|
|
||||||
y="898.35059"
|
|
||||||
x="295.69891"
|
|
||||||
height="25"
|
|
||||||
width="125.62177"
|
|
||||||
id="rect3895"
|
|
||||||
style="fill:#f6f4ca;fill-opacity:1;stroke:#000000;stroke-width:0.56040561;stroke-opacity:1" />
|
|
||||||
<text
|
|
||||||
sodipodi:linespacing="125%"
|
|
||||||
id="text3897"
|
|
||||||
y="914.71289"
|
|
||||||
x="370.28702"
|
|
||||||
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
|
||||||
xml:space="preserve"><tspan
|
|
||||||
y="914.71289"
|
|
||||||
x="370.28702"
|
|
||||||
id="tspan3899"
|
|
||||||
sodipodi:role="line">Outgoing</tspan></text>
|
|
||||||
<g
|
|
||||||
id="g3925"
|
|
||||||
transform="matrix(-1,0,0,-1,156.93219,1775.5293)">
|
|
||||||
<path
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="rect3934"
|
|
||||||
d="m 75.000004,817.36217 0,137.3125 -7.65625,0 17.65625,17.6875 17.687496,-17.6875 -7.687496,0 0,-137.3125 -20,0 z"
|
|
||||||
style="fill:#f7d1d1;fill-opacity:1;stroke:#dd9191;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
|
||||||
<text
|
|
||||||
transform="matrix(0,1,-1,0,0,0)"
|
|
||||||
sodipodi:linespacing="125%"
|
|
||||||
id="text3948"
|
|
||||||
y="-81.15332"
|
|
||||||
x="822.36218"
|
|
||||||
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
|
||||||
xml:space="preserve"><tspan
|
|
||||||
y="-81.15332"
|
|
||||||
x="822.36218"
|
|
||||||
id="tspan3950"
|
|
||||||
sodipodi:role="line">IncomingFrames</tspan></text>
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g3930"
|
|
||||||
transform="matrix(-1,0,0,-1,842.97235,1773.7812)">
|
|
||||||
<path
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="rect3954"
|
|
||||||
d="m 420,817.36217 -17.6875,17.6875 7.6875,0 0,117.3125 20,0 0,-117.3125 7.65625,0 L 420,817.36217 z"
|
|
||||||
style="fill:#f7d1d1;fill-opacity:1;stroke:#dd9191;stroke-width:0.99999994;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
|
||||||
x="-942.64636"
|
|
||||||
y="423.84668"
|
|
||||||
id="text3969"
|
|
||||||
sodipodi:linespacing="125%"
|
|
||||||
transform="matrix(0,-1,1,0,0,0)"><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
id="tspan3971"
|
|
||||||
x="-942.64636"
|
|
||||||
y="423.84668">OutgoingFrames</tspan></text>
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
transform="translate(3.6030325,-60.564766)"
|
|
||||||
id="g3901">
|
|
||||||
<rect
|
|
||||||
style="fill:#e84400;fill-opacity:1;stroke:none"
|
|
||||||
id="rect3903"
|
|
||||||
width="88.274292"
|
|
||||||
height="11.709856"
|
|
||||||
x="85.647453"
|
|
||||||
y="921.58582"
|
|
||||||
ry="5.854928" />
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-size:10.80251503px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans"
|
|
||||||
x="90.723061"
|
|
||||||
y="931.29919"
|
|
||||||
id="text3905"
|
|
||||||
sodipodi:linespacing="125%"><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
id="tspan3907"
|
|
||||||
x="90.723061"
|
|
||||||
y="931.29919"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#ffffff;fill-opacity:1;font-family:Droid Sans Mono;-inkscape-font-specification:Droid Sans Mono">FrameHandler</tspan></text>
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g3909"
|
|
||||||
transform="translate(3.6030325,-20.979928)">
|
|
||||||
<rect
|
|
||||||
ry="5.854928"
|
|
||||||
y="921.58582"
|
|
||||||
x="85.647453"
|
|
||||||
height="11.709856"
|
|
||||||
width="88.274292"
|
|
||||||
id="rect3911"
|
|
||||||
style="fill:#e84400;fill-opacity:1;stroke:none" />
|
|
||||||
<text
|
|
||||||
sodipodi:linespacing="125%"
|
|
||||||
id="text3913"
|
|
||||||
y="931.29919"
|
|
||||||
x="90.723061"
|
|
||||||
style="font-size:10.80251503px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans"
|
|
||||||
xml:space="preserve"><tspan
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#ffffff;fill-opacity:1;font-family:Droid Sans Mono;-inkscape-font-specification:Droid Sans Mono"
|
|
||||||
y="931.29919"
|
|
||||||
x="90.723061"
|
|
||||||
id="tspan3915"
|
|
||||||
sodipodi:role="line">FrameHandler</tspan></text>
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g3917"
|
|
||||||
transform="translate(228.00221,-31.827366)">
|
|
||||||
<rect
|
|
||||||
ry="5.854928"
|
|
||||||
y="921.58582"
|
|
||||||
x="85.647453"
|
|
||||||
height="11.709856"
|
|
||||||
width="88.274292"
|
|
||||||
id="rect3919"
|
|
||||||
style="fill:#e84400;fill-opacity:1;stroke:none" />
|
|
||||||
<text
|
|
||||||
sodipodi:linespacing="125%"
|
|
||||||
id="text3921"
|
|
||||||
y="931.29919"
|
|
||||||
x="90.723061"
|
|
||||||
style="font-size:10.80251503px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans"
|
|
||||||
xml:space="preserve"><tspan
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#ffffff;fill-opacity:1;font-family:Droid Sans Mono;-inkscape-font-specification:Droid Sans Mono"
|
|
||||||
y="931.29919"
|
|
||||||
x="90.723061"
|
|
||||||
id="tspan3923"
|
|
||||||
sodipodi:role="line">FrameHandler</tspan></text>
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
transform="translate(228.00221,-69.549388)"
|
|
||||||
id="g3926">
|
|
||||||
<rect
|
|
||||||
style="fill:#e84400;fill-opacity:1;stroke:none"
|
|
||||||
id="rect3928"
|
|
||||||
width="88.274292"
|
|
||||||
height="11.709856"
|
|
||||||
x="85.647453"
|
|
||||||
y="921.58582"
|
|
||||||
ry="5.854928" />
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-size:10.80251503px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans"
|
|
||||||
x="90.723061"
|
|
||||||
y="931.29919"
|
|
||||||
id="text3930"
|
|
||||||
sodipodi:linespacing="125%"><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
id="tspan3932"
|
|
||||||
x="90.723061"
|
|
||||||
y="931.29919"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#ffffff;fill-opacity:1;font-family:Droid Sans Mono;-inkscape-font-specification:Droid Sans Mono">FrameHandler</tspan></text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 74 KiB |
|
@ -1,575 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
width="645"
|
|
||||||
height="350"
|
|
||||||
id="svg2"
|
|
||||||
version="1.1"
|
|
||||||
inkscape:version="0.48.3.1 r9886"
|
|
||||||
sodipodi:docname="javax.net.websocket-stack-simple.svg"
|
|
||||||
inkscape:export-filename="/home/joakim/code/intalio/org.eclipse.jetty9.project/jetty-websocket/websocket-common/src/main/javadoc/org/eclipse/jetty/websocket/doc-files/javax.net.websocket-stack-simple.png"
|
|
||||||
inkscape:export-xdpi="111.63"
|
|
||||||
inkscape:export-ydpi="111.63">
|
|
||||||
<defs
|
|
||||||
id="defs4" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="2.1472868"
|
|
||||||
inkscape:cx="290.96542"
|
|
||||||
inkscape:cy="172.35578"
|
|
||||||
inkscape:document-units="px"
|
|
||||||
inkscape:current-layer="layer1"
|
|
||||||
showgrid="true"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1024"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="27"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
showguides="true"
|
|
||||||
inkscape:guide-bbox="true"
|
|
||||||
borderlayer="true"
|
|
||||||
inkscape:snap-grids="false">
|
|
||||||
<inkscape:grid
|
|
||||||
type="xygrid"
|
|
||||||
id="grid3006"
|
|
||||||
empspacing="5"
|
|
||||||
dotted="true"
|
|
||||||
visible="true"
|
|
||||||
enabled="true"
|
|
||||||
snapvisiblegridlinesonly="true"
|
|
||||||
spacingx="5px"
|
|
||||||
spacingy="5px" />
|
|
||||||
</sodipodi:namedview>
|
|
||||||
<metadata
|
|
||||||
id="metadata7">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title></dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer2"
|
|
||||||
inkscape:label="Background"
|
|
||||||
sodipodi:insensitive="true">
|
|
||||||
<rect
|
|
||||||
style="fill:#ffffff;fill-opacity:1;stroke:none"
|
|
||||||
id="rect3089"
|
|
||||||
width="645"
|
|
||||||
height="350"
|
|
||||||
x="0"
|
|
||||||
y="0" />
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(0,-702.36218)">
|
|
||||||
<rect
|
|
||||||
style="fill:#b9b9b9;fill-opacity:1;stroke:none"
|
|
||||||
id="rect3977"
|
|
||||||
width="560"
|
|
||||||
height="70.000008"
|
|
||||||
x="40.000004"
|
|
||||||
y="957.36218" />
|
|
||||||
<rect
|
|
||||||
y="812.36218"
|
|
||||||
x="40.000004"
|
|
||||||
height="145"
|
|
||||||
width="560"
|
|
||||||
id="rect3975"
|
|
||||||
style="fill:#d1d1d1;fill-opacity:1;stroke:none" />
|
|
||||||
<rect
|
|
||||||
style="fill:#ececec;fill-opacity:1;stroke:none"
|
|
||||||
id="rect3973"
|
|
||||||
width="560"
|
|
||||||
height="75"
|
|
||||||
x="40.000004"
|
|
||||||
y="737.24573" />
|
|
||||||
<path
|
|
||||||
style="fill:none;stroke:#858585;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 1;stroke-dashoffset:0"
|
|
||||||
d="m 25.000004,812.36217 594.999996,0"
|
|
||||||
id="path3999"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
sodipodi:nodetypes="cc" />
|
|
||||||
<g
|
|
||||||
id="g3132"
|
|
||||||
transform="translate(0,79.999997)">
|
|
||||||
<rect
|
|
||||||
y="937.36218"
|
|
||||||
x="50"
|
|
||||||
height="25.000031"
|
|
||||||
width="400"
|
|
||||||
id="rect3008"
|
|
||||||
style="fill:#caf3f6;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-opacity:1" />
|
|
||||||
<text
|
|
||||||
sodipodi:linespacing="125%"
|
|
||||||
id="text3778"
|
|
||||||
y="953.72449"
|
|
||||||
x="249.91454"
|
|
||||||
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
|
||||||
xml:space="preserve"><tspan
|
|
||||||
y="953.72449"
|
|
||||||
x="249.91454"
|
|
||||||
id="tspan3780"
|
|
||||||
sodipodi:role="line">Physical Connection</tspan></text>
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g3137"
|
|
||||||
transform="translate(0,29.999997)">
|
|
||||||
<rect
|
|
||||||
style="fill:#caf3f6;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-opacity:1"
|
|
||||||
id="rect3797"
|
|
||||||
width="400"
|
|
||||||
height="25"
|
|
||||||
x="50"
|
|
||||||
y="962.36218" />
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
|
||||||
x="249.91455"
|
|
||||||
y="978.72449"
|
|
||||||
id="text3799"
|
|
||||||
sodipodi:linespacing="125%"><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
id="tspan3801"
|
|
||||||
x="249.91455"
|
|
||||||
y="978.72449">AsyncEndPoint</tspan></text>
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g3142"
|
|
||||||
transform="translate(0,-20.000003)">
|
|
||||||
<rect
|
|
||||||
y="987.36218"
|
|
||||||
x="50"
|
|
||||||
height="24.999996"
|
|
||||||
width="400"
|
|
||||||
id="rect3805"
|
|
||||||
style="fill:#caf3f6;fill-opacity:1;stroke:#000000;stroke-width:0.99999994;stroke-opacity:1" />
|
|
||||||
<text
|
|
||||||
sodipodi:linespacing="125%"
|
|
||||||
id="text3807"
|
|
||||||
y="1003.7245"
|
|
||||||
x="249.91455"
|
|
||||||
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
|
||||||
xml:space="preserve"><tspan
|
|
||||||
y="1003.7245"
|
|
||||||
x="249.91455"
|
|
||||||
id="tspan3809"
|
|
||||||
sodipodi:role="line">WebSocketAsyncConnection</tspan></text>
|
|
||||||
</g>
|
|
||||||
<path
|
|
||||||
sodipodi:nodetypes="cc"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path4004"
|
|
||||||
d="m 25.000004,957.36218 594.999996,0"
|
|
||||||
style="fill:none;stroke:#858585;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 1;stroke-dashoffset:0" />
|
|
||||||
<g
|
|
||||||
id="g3152"
|
|
||||||
transform="translate(0,-70.000003)">
|
|
||||||
<rect
|
|
||||||
style="fill:#caf3f6;fill-opacity:1;stroke:#000000;stroke-width:0.99999994;stroke-opacity:1"
|
|
||||||
id="rect3786"
|
|
||||||
width="200"
|
|
||||||
height="25"
|
|
||||||
x="50"
|
|
||||||
y="1012.3622" />
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
|
||||||
x="149.31982"
|
|
||||||
y="1029.8661"
|
|
||||||
id="text3815"
|
|
||||||
sodipodi:linespacing="125%"><tspan
|
|
||||||
id="tspan3822"
|
|
||||||
sodipodi:role="line"
|
|
||||||
x="149.31982"
|
|
||||||
y="1029.8661">Parser</tspan></text>
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g3147"
|
|
||||||
transform="translate(0,-70.000003)">
|
|
||||||
<rect
|
|
||||||
y="1012.3622"
|
|
||||||
x="250"
|
|
||||||
height="25"
|
|
||||||
width="200"
|
|
||||||
id="rect3788"
|
|
||||||
style="fill:#caf3f6;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-opacity:1" />
|
|
||||||
<text
|
|
||||||
sodipodi:linespacing="125%"
|
|
||||||
id="text3826"
|
|
||||||
y="1029.9584"
|
|
||||||
x="314.03955"
|
|
||||||
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
|
||||||
xml:space="preserve"><tspan
|
|
||||||
id="tspan3830"
|
|
||||||
y="1029.9584"
|
|
||||||
x="314.03955"
|
|
||||||
sodipodi:role="line">Generator</tspan></text>
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g3954"
|
|
||||||
transform="translate(-0.0854492,38.643061)">
|
|
||||||
<rect
|
|
||||||
style="fill:#caf3f6;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-opacity:1"
|
|
||||||
id="rect3849"
|
|
||||||
width="400"
|
|
||||||
height="25"
|
|
||||||
x="50.085449"
|
|
||||||
y="710.99988" />
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
|
||||||
x="250"
|
|
||||||
y="727.36218"
|
|
||||||
id="text3851"
|
|
||||||
sodipodi:linespacing="125%"><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
id="tspan3853"
|
|
||||||
x="250"
|
|
||||||
y="727.36218">WebSocketEndPoint</tspan></text>
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g3949"
|
|
||||||
transform="translate(-0.0854492,-36.356939)">
|
|
||||||
<rect
|
|
||||||
style="fill:#caf3f6;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-opacity:1"
|
|
||||||
id="rect3865"
|
|
||||||
width="400"
|
|
||||||
height="25"
|
|
||||||
x="50.085449"
|
|
||||||
y="760.99988" />
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
|
||||||
x="250"
|
|
||||||
y="777.36218"
|
|
||||||
id="text3867"
|
|
||||||
sodipodi:linespacing="125%"><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
id="tspan3869"
|
|
||||||
x="250"
|
|
||||||
y="777.36218">WebSocket Object</tspan></text>
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g3973"
|
|
||||||
transform="translate(0,17.280759)">
|
|
||||||
<rect
|
|
||||||
y="782.36218"
|
|
||||||
x="49.999996"
|
|
||||||
height="25"
|
|
||||||
width="175"
|
|
||||||
id="rect3881"
|
|
||||||
style="fill:#caf3f6;fill-opacity:1;stroke:#000000;stroke-width:0.93541425;stroke-opacity:1" />
|
|
||||||
<text
|
|
||||||
sodipodi:linespacing="125%"
|
|
||||||
id="text3883"
|
|
||||||
y="800.08142"
|
|
||||||
x="136.81982"
|
|
||||||
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
|
||||||
xml:space="preserve"><tspan
|
|
||||||
y="800.08142"
|
|
||||||
x="136.81982"
|
|
||||||
sodipodi:role="line"
|
|
||||||
id="tspan3885">EventDriver</tspan></text>
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g3978"
|
|
||||||
transform="translate(0,17.280759)">
|
|
||||||
<rect
|
|
||||||
style="fill:#caf3f6;fill-opacity:1;stroke:#000000;stroke-width:1.06066012;stroke-opacity:1"
|
|
||||||
id="rect3905"
|
|
||||||
width="225"
|
|
||||||
height="25"
|
|
||||||
x="225"
|
|
||||||
y="782.36218" />
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
|
||||||
x="337.43848"
|
|
||||||
y="798.72449"
|
|
||||||
id="text3907"
|
|
||||||
sodipodi:linespacing="125%"><tspan
|
|
||||||
id="tspan3909"
|
|
||||||
sodipodi:role="line"
|
|
||||||
x="337.43848"
|
|
||||||
y="798.72449">WebSocketRemoteEndpoint</tspan></text>
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
transform="translate(-0.0854492,63.643061)"
|
|
||||||
id="g3959">
|
|
||||||
<rect
|
|
||||||
y="710.99988"
|
|
||||||
x="50.085449"
|
|
||||||
height="25"
|
|
||||||
width="400"
|
|
||||||
id="rect3961"
|
|
||||||
style="fill:#caf3f6;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-opacity:1" />
|
|
||||||
<text
|
|
||||||
sodipodi:linespacing="125%"
|
|
||||||
id="text3963"
|
|
||||||
y="727.36218"
|
|
||||||
x="250"
|
|
||||||
style="font-size:14px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
|
||||||
xml:space="preserve"><tspan
|
|
||||||
y="727.36218"
|
|
||||||
x="250"
|
|
||||||
id="tspan3965"
|
|
||||||
sodipodi:role="line">WebSocketSession</tspan></text>
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g3930"
|
|
||||||
transform="matrix(-1,0,0,-1,842.97235,1773.7812)">
|
|
||||||
<path
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="rect3954"
|
|
||||||
d="m 420,817.36217 -17.6875,17.6875 7.6875,0 0,117.3125 20,0 0,-117.3125 7.65625,0 L 420,817.36217 z"
|
|
||||||
style="fill:#f7d1d1;fill-opacity:1;stroke:#dd9191;stroke-width:0.99999994;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
|
||||||
x="-942.64636"
|
|
||||||
y="423.84668"
|
|
||||||
id="text3969"
|
|
||||||
sodipodi:linespacing="125%"
|
|
||||||
transform="matrix(0,-1,1,0,0,0)"><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
id="tspan3971"
|
|
||||||
x="-942.64636"
|
|
||||||
y="423.84668">OutgoingFrames</tspan></text>
|
|
||||||
</g>
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
|
||||||
x="484.2207"
|
|
||||||
y="987.36218"
|
|
||||||
id="text3979"
|
|
||||||
sodipodi:linespacing="125%"><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
id="tspan3981"
|
|
||||||
x="484.2207"
|
|
||||||
y="987.36218">Network</tspan><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
x="484.2207"
|
|
||||||
y="1002.3622"
|
|
||||||
id="tspan3983">ByteBuffers</tspan></text>
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
|
||||||
x="485"
|
|
||||||
y="847.36218"
|
|
||||||
id="text3985"
|
|
||||||
sodipodi:linespacing="125%"><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
id="tspan3987"
|
|
||||||
x="485"
|
|
||||||
y="847.36218">Internal</tspan><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
x="485"
|
|
||||||
y="862.36218"
|
|
||||||
id="tspan3989">WebSocketFrame</tspan></text>
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
|
||||||
x="485.43359"
|
|
||||||
y="762.36218"
|
|
||||||
id="text3991"
|
|
||||||
sodipodi:linespacing="125%"><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
id="tspan3993"
|
|
||||||
x="485.43359"
|
|
||||||
y="762.36218">Message</tspan><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
x="485.43359"
|
|
||||||
y="777.36218"
|
|
||||||
id="tspan3995">Text or Binary</tspan></text>
|
|
||||||
<rect
|
|
||||||
style="fill:#e84400;fill-opacity:1;stroke:none"
|
|
||||||
id="rect4032"
|
|
||||||
width="65.063103"
|
|
||||||
height="11.709856"
|
|
||||||
x="414.50586"
|
|
||||||
y="757.07648"
|
|
||||||
ry="5.854928" />
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-size:10.80251503px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans"
|
|
||||||
x="421.08868"
|
|
||||||
y="766.78979"
|
|
||||||
id="text4034"
|
|
||||||
sodipodi:linespacing="125%"><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
id="tspan4036"
|
|
||||||
x="421.08868"
|
|
||||||
y="766.78979"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#ffffff;fill-opacity:1;font-family:Droid Sans Mono;-inkscape-font-specification:Droid Sans Mono">EndPoint</tspan></text>
|
|
||||||
<rect
|
|
||||||
ry="5.854928"
|
|
||||||
y="781.06757"
|
|
||||||
x="418.32745"
|
|
||||||
height="11.709856"
|
|
||||||
width="59.474655"
|
|
||||||
id="rect4045"
|
|
||||||
style="fill:#e84400;fill-opacity:1;stroke:none" />
|
|
||||||
<text
|
|
||||||
sodipodi:linespacing="125%"
|
|
||||||
id="text4047"
|
|
||||||
y="790.78094"
|
|
||||||
x="425.44174"
|
|
||||||
style="font-size:10.80251503px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans"
|
|
||||||
xml:space="preserve"><tspan
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#ffffff;fill-opacity:1;font-family:Droid Sans Mono;-inkscape-font-specification:Droid Sans Mono"
|
|
||||||
y="790.78094"
|
|
||||||
x="425.44174"
|
|
||||||
id="tspan4049"
|
|
||||||
sodipodi:role="line">Session</tspan></text>
|
|
||||||
<rect
|
|
||||||
style="fill:#e84400;fill-opacity:1;stroke:none"
|
|
||||||
id="rect4053"
|
|
||||||
width="103.94939"
|
|
||||||
height="11.709856"
|
|
||||||
x="439.77084"
|
|
||||||
y="804.20941"
|
|
||||||
ry="5.854928" />
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-size:10.80251503px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans"
|
|
||||||
x="446.44672"
|
|
||||||
y="813.92279"
|
|
||||||
id="text4055"
|
|
||||||
sodipodi:linespacing="125%"><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
id="tspan4057"
|
|
||||||
x="446.44672"
|
|
||||||
y="813.92279"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#ffffff;fill-opacity:1;font-family:Droid Sans Mono;-inkscape-font-specification:Droid Sans Mono">RemoteEndpoint</tspan></text>
|
|
||||||
<g
|
|
||||||
id="g4070"
|
|
||||||
transform="translate(3.6030325,-99.6839)">
|
|
||||||
<rect
|
|
||||||
ry="5.854928"
|
|
||||||
y="921.58582"
|
|
||||||
x="85.647453"
|
|
||||||
height="11.709856"
|
|
||||||
width="88.274292"
|
|
||||||
id="rect4061"
|
|
||||||
style="fill:#e84400;fill-opacity:1;stroke:none" />
|
|
||||||
<text
|
|
||||||
sodipodi:linespacing="125%"
|
|
||||||
id="text4063"
|
|
||||||
y="931.29919"
|
|
||||||
x="90.723061"
|
|
||||||
style="font-size:10.80251503px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans"
|
|
||||||
xml:space="preserve"><tspan
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#ffffff;fill-opacity:1;font-family:Droid Sans Mono;-inkscape-font-specification:Droid Sans Mono"
|
|
||||||
y="931.29919"
|
|
||||||
x="90.723061"
|
|
||||||
id="tspan4065"
|
|
||||||
sodipodi:role="line">FrameHandler</tspan></text>
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g3925"
|
|
||||||
transform="matrix(-1,0,0,-1,156.93219,1775.5293)">
|
|
||||||
<path
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="rect3934"
|
|
||||||
d="m 75.000004,817.36217 0,137.3125 -7.65625,0 17.65625,17.6875 17.687496,-17.6875 -7.687496,0 0,-137.3125 -20,0 z"
|
|
||||||
style="fill:#f7d1d1;fill-opacity:1;stroke:#dd9191;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
|
||||||
<text
|
|
||||||
transform="matrix(0,1,-1,0,0,0)"
|
|
||||||
sodipodi:linespacing="125%"
|
|
||||||
id="text3948"
|
|
||||||
y="-81.15332"
|
|
||||||
x="822.36218"
|
|
||||||
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
|
||||||
xml:space="preserve"><tspan
|
|
||||||
y="-81.15332"
|
|
||||||
x="822.36218"
|
|
||||||
id="tspan3950"
|
|
||||||
sodipodi:role="line">IncomingFrames</tspan></text>
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
transform="translate(220.08524,13.811624)"
|
|
||||||
id="g4075">
|
|
||||||
<rect
|
|
||||||
style="fill:#e84400;fill-opacity:1;stroke:none"
|
|
||||||
id="rect4077"
|
|
||||||
width="88.274292"
|
|
||||||
height="11.709856"
|
|
||||||
x="85.647453"
|
|
||||||
y="921.58582"
|
|
||||||
ry="5.854928" />
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-size:10.80251503px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans"
|
|
||||||
x="90.723061"
|
|
||||||
y="931.29919"
|
|
||||||
id="text4079"
|
|
||||||
sodipodi:linespacing="125%"><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
id="tspan4081"
|
|
||||||
x="90.723061"
|
|
||||||
y="931.29919"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#ffffff;fill-opacity:1;font-family:Droid Sans Mono;-inkscape-font-specification:Droid Sans Mono">FrameHandler</tspan></text>
|
|
||||||
</g>
|
|
||||||
<rect
|
|
||||||
ry="5.854928"
|
|
||||||
y="780.36169"
|
|
||||||
x="59.872288"
|
|
||||||
height="11.709856"
|
|
||||||
width="107.44216"
|
|
||||||
id="rect4112"
|
|
||||||
style="fill:#e84400;fill-opacity:1;stroke:none" />
|
|
||||||
<text
|
|
||||||
sodipodi:linespacing="125%"
|
|
||||||
id="text4114"
|
|
||||||
y="790.07501"
|
|
||||||
x="66.455116"
|
|
||||||
style="font-size:10.80251503px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans"
|
|
||||||
xml:space="preserve"><tspan
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#ffffff;fill-opacity:1;font-family:Droid Sans Mono;-inkscape-font-specification:Droid Sans Mono"
|
|
||||||
y="790.07501"
|
|
||||||
x="66.455116"
|
|
||||||
id="tspan4116"
|
|
||||||
sodipodi:role="line">MessageHandler</tspan></text>
|
|
||||||
<rect
|
|
||||||
style="fill:#e84400;fill-opacity:1;stroke:none"
|
|
||||||
id="rect4118"
|
|
||||||
width="63.665989"
|
|
||||||
height="11.709856"
|
|
||||||
x="328.81635"
|
|
||||||
y="780.59454"
|
|
||||||
ry="5.854928" />
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-size:10.80251503px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans"
|
|
||||||
x="337.85223"
|
|
||||||
y="790.30786"
|
|
||||||
id="text4120"
|
|
||||||
sodipodi:linespacing="125%"><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
id="tspan4122"
|
|
||||||
x="337.85223"
|
|
||||||
y="790.30786"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#ffffff;fill-opacity:1;font-family:Droid Sans Mono;-inkscape-font-specification:Droid Sans Mono">Encoder</tspan></text>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 66 KiB |