interims
20
VERSION.txt
|
@ -1,18 +1,34 @@
|
|||
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
|
||||
+ 381521 Only set Vary header when content could be compressed
|
||||
+ 391623 Making --stop with STOP.WAIT perform graceful shutdown
|
||||
+ 393158 java.lang.IllegalStateException when sending an empty InputStream
|
||||
+ 393220 remove dead code from ServletHandler and log ServletExceptions in
|
||||
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
|
||||
requests
|
||||
+ 396500 HttpClient Exchange takes forever to complete when less content sent
|
||||
than Content-Length
|
||||
+ 396886 MultiPartFilter strips bad escaping on filename="..."
|
||||
+ 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
|
||||
(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-9.0.0.M4 - 21 December 2012
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
<Item>org.eclipse.jetty.webapp.WebXmlConfiguration</Item>
|
||||
<Item>org.eclipse.jetty.webapp.MetaInfConfiguration</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.webapp.JettyWebXmlConfiguration</Item>
|
||||
</Array>
|
||||
|
|
|
@ -481,10 +481,6 @@ public class HttpClient extends ContainerLifeCycle
|
|||
if (!Arrays.asList("http", "https").contains(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());
|
||||
destination.send(request, listeners);
|
||||
}
|
||||
|
@ -875,6 +871,16 @@ public class HttpClient extends ContainerLifeCycle
|
|||
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
|
||||
public void dump(Appendable out, String indent) throws IOException
|
||||
{
|
||||
|
@ -920,12 +926,9 @@ public class HttpClient extends ContainerLifeCycle
|
|||
SSLEngine engine = sslContextFactory.newSSLEngine(endPoint.getRemoteAddress());
|
||||
engine.setUseClientMode(true);
|
||||
|
||||
SslConnection sslConnection = new SslConnection(getByteBufferPool(), getExecutor(), endPoint, engine);
|
||||
// TODO: configureConnection => implies we should use SslConnectionFactory to do it
|
||||
|
||||
SslConnection sslConnection = newSslConnection(HttpClient.this, endPoint, engine);
|
||||
EndPoint appEndPoint = sslConnection.getDecryptedEndPoint();
|
||||
HttpConnection connection = newHttpConnection(HttpClient.this, appEndPoint, destination);
|
||||
// TODO: configureConnection, see above
|
||||
|
||||
appEndPoint.setConnection(connection);
|
||||
callback.promise.succeeded(connection);
|
||||
|
@ -936,7 +939,6 @@ public class HttpClient extends ContainerLifeCycle
|
|||
else
|
||||
{
|
||||
HttpConnection connection = newHttpConnection(HttpClient.this, endPoint, destination);
|
||||
// TODO: configureConnection, see above
|
||||
callback.promise.succeeded(connection);
|
||||
return connection;
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ import java.io.UnsupportedEncodingException;
|
|||
import java.net.HttpCookie;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.UnsupportedCharsetException;
|
||||
import java.util.Collections;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
@ -108,7 +108,16 @@ public class HttpConnection extends AbstractConnection implements Connection
|
|||
@Override
|
||||
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)
|
||||
|
@ -125,10 +134,6 @@ public class HttpConnection extends AbstractConnection implements Connection
|
|||
setExchange(exchange);
|
||||
conversation.getExchanges().offer(exchange);
|
||||
|
||||
for (Response.ResponseListener listener : listeners)
|
||||
if (listener instanceof Schedulable)
|
||||
((Schedulable)listener).schedule(client.getScheduler());
|
||||
|
||||
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.Response;
|
||||
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.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
|
@ -509,8 +508,9 @@ public class HttpDestination implements Destination, AutoCloseable, Dumpable
|
|||
.scheme(HttpScheme.HTTP.asString())
|
||||
.method(HttpMethod.CONNECT)
|
||||
.path(target)
|
||||
.header(HttpHeader.HOST.asString(), target);
|
||||
connection.send(connect, new TimedResponseListener(client.getConnectTimeout(), TimeUnit.MILLISECONDS, connect, new Response.CompleteListener()
|
||||
.header(HttpHeader.HOST.asString(), target)
|
||||
.timeout(client.getConnectTimeout(), TimeUnit.MILLISECONDS);
|
||||
connection.send(connect, new Response.CompleteListener()
|
||||
{
|
||||
@Override
|
||||
public void onComplete(Result result)
|
||||
|
@ -534,7 +534,7 @@ public class HttpDestination implements Destination, AutoCloseable, Dumpable
|
|||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -178,15 +178,8 @@ public class HttpExchange
|
|||
// Request and response completed
|
||||
LOG.debug("{} complete", this);
|
||||
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();
|
||||
}
|
||||
}
|
||||
result = new Result(getRequest(), getRequestFailure(), getResponse(), getResponseFailure());
|
||||
}
|
||||
|
||||
|
|
|
@ -426,7 +426,7 @@ public class HttpRequest implements Request
|
|||
public ContentResponse send() throws InterruptedException, TimeoutException, ExecutionException
|
||||
{
|
||||
FutureResponseListener listener = new FutureResponseListener(this);
|
||||
send(listener);
|
||||
send(this, listener);
|
||||
|
||||
long timeout = getTimeout();
|
||||
if (timeout <= 0)
|
||||
|
@ -447,10 +447,21 @@ public class HttpRequest implements Request
|
|||
|
||||
@Override
|
||||
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)
|
||||
responseListeners.add(listener);
|
||||
client.send(this, responseListeners);
|
||||
client.send(request, responseListeners);
|
||||
}
|
||||
|
||||
@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.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import javax.net.ssl.SSLEngine;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
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.util.BufferingResponseListener;
|
||||
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.toolchain.test.annotation.Slow;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -71,8 +74,10 @@ public class HttpClientTimeoutTest extends AbstractHttpClientServerTest
|
|||
start(new TimeoutHandler(2 * timeout));
|
||||
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
Request request = client.newRequest("localhost", connector.getLocalPort()).scheme(scheme);
|
||||
request.send(new TimedResponseListener(timeout, TimeUnit.MILLISECONDS, request)
|
||||
Request request = client.newRequest("localhost", connector.getLocalPort())
|
||||
.scheme(scheme)
|
||||
.timeout(timeout, TimeUnit.MILLISECONDS);
|
||||
request.send(new Response.CompleteListener()
|
||||
{
|
||||
@Override
|
||||
public void onComplete(Result result)
|
||||
|
@ -96,8 +101,10 @@ public class HttpClientTimeoutTest extends AbstractHttpClientServerTest
|
|||
|
||||
// The first request has a long timeout
|
||||
final CountDownLatch firstLatch = new CountDownLatch(1);
|
||||
Request request = client.newRequest("localhost", connector.getLocalPort()).scheme(scheme);
|
||||
request.send(new TimedResponseListener(4 * timeout, TimeUnit.MILLISECONDS, request)
|
||||
Request request = client.newRequest("localhost", connector.getLocalPort())
|
||||
.scheme(scheme)
|
||||
.timeout(4 * timeout, TimeUnit.MILLISECONDS);
|
||||
request.send(new Response.CompleteListener()
|
||||
{
|
||||
@Override
|
||||
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
|
||||
final CountDownLatch secondLatch = new CountDownLatch(1);
|
||||
request = client.newRequest("localhost", connector.getLocalPort()).scheme(scheme);
|
||||
request.send(new TimedResponseListener(timeout, TimeUnit.MILLISECONDS, request)
|
||||
request = client.newRequest("localhost", connector.getLocalPort())
|
||||
.scheme(scheme)
|
||||
.timeout(timeout, TimeUnit.MILLISECONDS);
|
||||
request.send(new Response.CompleteListener()
|
||||
{
|
||||
@Override
|
||||
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};
|
||||
Request request = client.newRequest("localhost", connector.getLocalPort())
|
||||
.scheme(scheme)
|
||||
.content(new InputStreamContentProvider(new ByteArrayInputStream(content)));
|
||||
request.send(new TimedResponseListener(2 * timeout, TimeUnit.MILLISECONDS, request, new BufferingResponseListener()
|
||||
.content(new InputStreamContentProvider(new ByteArrayInputStream(content)))
|
||||
.timeout(2 * timeout, TimeUnit.MILLISECONDS);
|
||||
request.send(new BufferingResponseListener()
|
||||
{
|
||||
@Override
|
||||
public void onComplete(Result result)
|
||||
|
@ -147,7 +157,7 @@ public class HttpClientTimeoutTest extends AbstractHttpClientServerTest
|
|||
Assert.assertArrayEquals(content, getContent());
|
||||
latch.countDown();
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
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());
|
||||
try (Connection connection = destination.newConnection().get(5, TimeUnit.SECONDS))
|
||||
{
|
||||
Request request = client.newRequest("localhost", connector.getLocalPort()).scheme(scheme);
|
||||
connection.send(request, new TimedResponseListener(timeout, TimeUnit.MILLISECONDS, request)
|
||||
Request request = client.newRequest("localhost", connector.getLocalPort())
|
||||
.scheme(scheme)
|
||||
.timeout(timeout, TimeUnit.MILLISECONDS);
|
||||
connection.send(request, new Response.CompleteListener()
|
||||
{
|
||||
@Override
|
||||
public void onComplete(Result result)
|
||||
|
@ -193,8 +205,10 @@ public class HttpClientTimeoutTest extends AbstractHttpClientServerTest
|
|||
Destination destination = client.getDestination(scheme, "localhost", connector.getLocalPort());
|
||||
try (Connection connection = destination.newConnection().get(5, TimeUnit.SECONDS))
|
||||
{
|
||||
Request request = client.newRequest(destination.getHost(), destination.getPort()).scheme(scheme);
|
||||
connection.send(request, new TimedResponseListener(2 * timeout, TimeUnit.MILLISECONDS, request)
|
||||
Request request = client.newRequest(destination.getHost(), destination.getPort())
|
||||
.scheme(scheme)
|
||||
.timeout(2 * timeout, TimeUnit.MILLISECONDS);
|
||||
connection.send(request, new Response.CompleteListener()
|
||||
{
|
||||
@Override
|
||||
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 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>
|
||||
<includeArtifactIds>javax.transaction</includeArtifactIds>
|
||||
<includeTypes>jar</includeTypes>
|
||||
<outputDirectory>${assembly-directory}/lib/jta</outputDirectory>
|
||||
<outputDirectory>${assembly-directory}/lib/jndi</outputDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
|
|
|
@ -127,11 +127,11 @@ OPTIONS=jsp
|
|||
|
||||
|
||||
#===========================================================
|
||||
# Annotations JNDI JASS processing
|
||||
# Annotations JNDI JAAS processing
|
||||
#-----------------------------------------------------------
|
||||
# OPTIONS=annotations
|
||||
# OPTIONS=plus
|
||||
# etc/jetty-plus.xml
|
||||
# OPTIONS=annotations
|
||||
# etc/jetty-annotations.xml
|
||||
#===========================================================
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ public abstract class IdleTimeout
|
|||
if (old>0)
|
||||
{
|
||||
// if the old was less than or equal to the new timeout, then nothing more to do
|
||||
if (old<=_idleTimeout)
|
||||
if (old<=idleTimeout)
|
||||
return;
|
||||
|
||||
// old timeout is too long, so cancel it.
|
||||
|
@ -93,7 +93,7 @@ public abstract class IdleTimeout
|
|||
}
|
||||
|
||||
// If we have a new timeout, then check and reschedule
|
||||
if (_idleTimeout>0 && isOpen())
|
||||
if (idleTimeout>0 && isOpen())
|
||||
_idleTask.run();
|
||||
}
|
||||
|
||||
|
|
|
@ -220,7 +220,6 @@ public class SslConnection extends AbstractConnection
|
|||
// 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
|
||||
// handle the cause.
|
||||
|
||||
synchronized(_decryptedEndPoint)
|
||||
{
|
||||
_decryptedEndPoint.getFillInterest().onFail(cause);
|
||||
|
|
|
@ -20,11 +20,9 @@ package org.eclipse.jetty.io;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.Socket;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.net.ssl.SSLEngine;
|
||||
import javax.net.ssl.SSLEngineResult;
|
||||
import javax.net.ssl.SSLEngineResult.HandshakeStatus;
|
||||
|
@ -42,9 +40,7 @@ import org.junit.Test;
|
|||
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
|
||||
public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest
|
||||
|
@ -226,51 +222,6 @@ public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest
|
|||
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
|
||||
@Override
|
||||
@Stress("Requires a relatively idle (network wise) environment")
|
||||
|
|
|
@ -18,12 +18,6 @@
|
|||
|
||||
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.BufferedOutputStream;
|
||||
import java.io.IOException;
|
||||
|
@ -52,6 +46,12 @@ import org.junit.Assert;
|
|||
import org.junit.Before;
|
||||
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
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(SelectChannelEndPointTest.class);
|
||||
|
@ -425,6 +425,7 @@ public class SelectChannelEndPointTest
|
|||
public void testBlockedReadIdle() throws Exception
|
||||
{
|
||||
Socket client = newClient();
|
||||
InputStream clientInputStream = client.getInputStream();
|
||||
OutputStream clientOutputStream = client.getOutputStream();
|
||||
|
||||
client.setSoTimeout(5000);
|
||||
|
@ -440,7 +441,7 @@ public class SelectChannelEndPointTest
|
|||
// Verify echo server to client
|
||||
for (char c : "HelloWorld".toCharArray())
|
||||
{
|
||||
int b = client.getInputStream().read();
|
||||
int b = clientInputStream.read();
|
||||
assertTrue(b > 0);
|
||||
assertEquals(c, (char)b);
|
||||
}
|
||||
|
@ -456,7 +457,7 @@ public class SelectChannelEndPointTest
|
|||
|
||||
// read until idle shutdown received
|
||||
long start = System.currentTimeMillis();
|
||||
int b = client.getInputStream().read();
|
||||
int b = clientInputStream.read();
|
||||
assertEquals('E', b);
|
||||
long idle = System.currentTimeMillis() - start;
|
||||
assertTrue(idle > idleTimeout / 2);
|
||||
|
@ -464,10 +465,12 @@ public class SelectChannelEndPointTest
|
|||
|
||||
for (char c : "E: 12345678".toCharArray())
|
||||
{
|
||||
b = client.getInputStream().read();
|
||||
b = clientInputStream.read();
|
||||
assertTrue(b > 0);
|
||||
assertEquals(c, (char)b);
|
||||
}
|
||||
b = clientInputStream.read();
|
||||
assertEquals(-1,b);
|
||||
|
||||
// But endpoint is still open.
|
||||
if(_lastEndPoint.isOpen())
|
||||
|
|
|
@ -67,9 +67,7 @@
|
|||
<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.webapp.JettyWebXmlConfiguration</Item>
|
||||
<Item>org.eclipse.jetty.webapp.TagLibConfiguration</Item>
|
||||
</Array>
|
||||
|
||||
<!-- =========================================================== -->
|
||||
|
@ -86,7 +84,6 @@
|
|||
<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="scanInterval">5</Set>
|
||||
<Set name="contextXmlDir"><Property name="jetty.home" default="." />/contexts</Set>
|
||||
<Set name="parentLoaderPriority">false</Set>
|
||||
<Set name="extractWars">true</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.Result;
|
||||
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.HttpMethod;
|
||||
import org.eclipse.jetty.http.HttpVersion;
|
||||
|
@ -221,7 +220,7 @@ public class ProxyServlet extends HttpServlet
|
|||
* <tr>
|
||||
* <td>timeout</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>
|
||||
* <td>requestBufferSize</td>
|
||||
|
@ -463,7 +462,8 @@ public class ProxyServlet extends HttpServlet
|
|||
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)
|
||||
|
|
|
@ -109,7 +109,7 @@ public class BalancerServletTest
|
|||
|
||||
private int getServerPort(Server server)
|
||||
{
|
||||
return ((NetworkConnector)server.getConnectors()[0]).getLocalPort();
|
||||
return server.getURI().getPort();
|
||||
}
|
||||
|
||||
protected byte[] sendRequestToBalancer(String path) throws Exception
|
||||
|
|
|
@ -172,21 +172,21 @@ public class Runner
|
|||
if (error!=null)
|
||||
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("Server Options:");
|
||||
System.err.println("Server opts:");
|
||||
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(" --out file - info/warn/debug log filename (with optional 'yyyy_mm_dd' wildcard");
|
||||
System.err.println(" --host name|ip - interface to listen on (default is all interfaces)");
|
||||
System.err.println(" --port n - port to listen on (default 8080)");
|
||||
System.err.println(" --stop-port n - port to listen for stop command");
|
||||
System.err.println(" --stop-key n - security string for stop command (required if --stop-port is present)");
|
||||
System.err.println(" --jar file - a jar to be added to the classloader");
|
||||
System.err.println(" --lib dir - a directory of jars to be added to the classloader");
|
||||
System.err.println(" --classes dir - a directory of classes 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(" [--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(" [--config file]*n - each --config parameter specifies the name of a jetty xml config file to apply (in the order defined)");
|
||||
System.err.println("Context Options:");
|
||||
System.err.println(" --path /path - context path (default /)");
|
||||
System.err.println(" context - WAR file, web app dir or context xml file");
|
||||
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 opts:");
|
||||
System.err.println(" [[--path /path] context]*n - WAR file, web app dir or context xml file, optionally with a context path");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
|
@ -246,6 +246,7 @@ public class Runner
|
|||
String contextPath = __defaultContextPath;
|
||||
boolean contextPathSet = false;
|
||||
int port = __defaultPort;
|
||||
String host = null;
|
||||
int stopPort = 0;
|
||||
String stopKey = null;
|
||||
|
||||
|
@ -255,6 +256,8 @@ public class Runner
|
|||
{
|
||||
if ("--port".equals(args[i]))
|
||||
port=Integer.parseInt(args[++i]);
|
||||
else if ("--host".equals(args[i]))
|
||||
host=args[++i];
|
||||
else if ("--stop-port".equals(args[i]))
|
||||
stopPort=Integer.parseInt(args[++i]);
|
||||
else if ("--stop-key".equals(args[i]))
|
||||
|
@ -393,6 +396,8 @@ public class Runner
|
|||
{
|
||||
ServerConnector connector = new ServerConnector(_server);
|
||||
connector.setPort(port);
|
||||
if (host != null)
|
||||
connector.setHost(host);
|
||||
_server.addConnector(connector);
|
||||
if (_enableStats)
|
||||
connector.addBean(new ConnectorStatistics());
|
||||
|
|
|
@ -19,7 +19,11 @@
|
|||
package org.eclipse.jetty.server;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Inet4Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
@ -35,14 +39,18 @@ import javax.servlet.ServletContext;
|
|||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.xml.validation.Schema;
|
||||
|
||||
import org.eclipse.jetty.http.HttpField;
|
||||
import org.eclipse.jetty.http.HttpFields;
|
||||
import org.eclipse.jetty.http.HttpGenerator;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.eclipse.jetty.http.HttpScheme;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.http.HttpURI;
|
||||
import org.eclipse.jetty.http.HttpVersion;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.server.handler.HandlerWrapper;
|
||||
import org.eclipse.jetty.util.Attributes;
|
||||
import org.eclipse.jetty.util.AttributesMap;
|
||||
|
@ -580,6 +588,49 @@ public class Server extends HandlerWrapper implements Attributes
|
|||
_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
|
||||
public String toString()
|
||||
|
|
|
@ -255,7 +255,7 @@ public class ShutdownMonitor extends Thread
|
|||
{
|
||||
if (isAlive())
|
||||
{
|
||||
System.out.printf("ShutdownMonitor already started");
|
||||
System.err.printf("ShutdownMonitor already started");
|
||||
return; // cannot start it again
|
||||
}
|
||||
startListenSocket();
|
||||
|
@ -271,7 +271,8 @@ public class ShutdownMonitor extends Thread
|
|||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -123,23 +123,6 @@ public class HandlerWrapper extends AbstractHandlerContainer
|
|||
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
|
||||
public void destroy()
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.io.FileInputStream;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
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();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -528,6 +531,7 @@ public class HashSessionManager extends AbstractSessionManager
|
|||
protected synchronized HashedSession restoreSession(String idInCuster)
|
||||
{
|
||||
File file = new File(_storeDir,idInCuster);
|
||||
|
||||
FileInputStream in = null;
|
||||
Exception error = null;
|
||||
try
|
||||
|
@ -552,13 +556,15 @@ public class HashSessionManager extends AbstractSessionManager
|
|||
|
||||
if (error != null)
|
||||
{
|
||||
if (isDeleteUnrestorableSessions() && file.exists())
|
||||
if (isDeleteUnrestorableSessions() && file.exists() && file.getParentFile().equals(_storeDir) )
|
||||
{
|
||||
file.delete();
|
||||
LOG.warn("Deleting file for unrestorable session "+idInCuster, error);
|
||||
}
|
||||
else
|
||||
LOG.warn("Problem restoring session "+idInCuster, error);
|
||||
{
|
||||
__log.warn("Problem restoring session "+idInCuster, error);
|
||||
}
|
||||
}
|
||||
else
|
||||
file.delete(); //delete successfully restored file
|
||||
|
|
|
@ -25,6 +25,7 @@ import java.io.IOException;
|
|||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.net.Socket;
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
@ -59,7 +60,8 @@ public abstract class ConnectorCloseTestBase extends HttpServerTestFixture
|
|||
|
||||
configureServer(new HelloWorldHandler());
|
||||
|
||||
Socket client = newSocket(HOST,_connector.getLocalPort());
|
||||
URI uri = _server.getURI();
|
||||
Socket client = newSocket(uri.getHost(),uri.getPort());
|
||||
try
|
||||
{
|
||||
OutputStream os = client.getOutputStream();
|
||||
|
@ -101,7 +103,7 @@ public abstract class ConnectorCloseTestBase extends HttpServerTestFixture
|
|||
|
||||
String request =
|
||||
"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"+
|
||||
"accept-encoding: nothing\r\n"+
|
||||
"cookie: aaa=1234567890\r\n"+
|
||||
|
@ -135,7 +137,8 @@ public abstract class ConnectorCloseTestBase extends HttpServerTestFixture
|
|||
{
|
||||
configureServer(new EchoHandler());
|
||||
|
||||
Socket client = newSocket(HOST,_connector.getLocalPort());
|
||||
URI uri = _server.getURI();
|
||||
Socket client = newSocket(uri.getHost(),uri.getPort());
|
||||
try
|
||||
{
|
||||
OutputStream os = client.getOutputStream();
|
||||
|
@ -148,7 +151,7 @@ public abstract class ConnectorCloseTestBase extends HttpServerTestFixture
|
|||
|
||||
os.write((
|
||||
"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-length: "+bytes.length+"\r\n"+
|
||||
"\r\n"
|
||||
|
|
|
@ -60,7 +60,8 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
|||
public void testMaxIdleWithRequest10() throws Exception
|
||||
{
|
||||
configureServer(new HelloWorldHandler());
|
||||
Socket client=newSocket(HOST,_connector.getLocalPort());
|
||||
|
||||
Socket client=newSocket(_serverURI.getHost(),_serverURI.getPort());
|
||||
client.setSoTimeout(10000);
|
||||
|
||||
assertFalse(client.isClosed());
|
||||
|
@ -70,7 +71,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
|||
|
||||
os.write((
|
||||
"GET / HTTP/1.0\r\n"+
|
||||
"host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
|
||||
"host: "+_serverURI.getHost()+":"+_serverURI.getPort()+"\r\n"+
|
||||
"connection: keep-alive\r\n"+
|
||||
"\r\n").getBytes("utf-8"));
|
||||
os.flush();
|
||||
|
@ -89,7 +90,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
|||
public void testMaxIdleWithRequest11() throws Exception
|
||||
{
|
||||
configureServer(new EchoHandler());
|
||||
Socket client=newSocket(HOST,_connector.getLocalPort());
|
||||
Socket client=newSocket(_serverURI.getHost(),_serverURI.getPort());
|
||||
client.setSoTimeout(10000);
|
||||
|
||||
assertFalse(client.isClosed());
|
||||
|
@ -101,7 +102,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
|||
byte[] contentB=content.getBytes("utf-8");
|
||||
os.write((
|
||||
"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-length: "+contentB.length+"\r\n"+
|
||||
"\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);
|
||||
|
||||
assertFalse(client.isClosed());
|
||||
|
@ -150,7 +151,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
|||
|
||||
os.write((
|
||||
"GET / HTTP/1.0\r\n"+
|
||||
"host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
|
||||
"host: "+_serverURI.getHost()+":"+_serverURI.getPort()+"\r\n"+
|
||||
"connection: close\r\n"+
|
||||
"\r\n").getBytes("utf-8"));
|
||||
os.flush();
|
||||
|
@ -177,7 +178,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
|||
{
|
||||
os.write((
|
||||
"GET / HTTP/1.0\r\n"+
|
||||
"host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
|
||||
"host: "+_serverURI.getHost()+":"+_serverURI.getPort()+"\r\n"+
|
||||
"connection: keep-alive\r\n"+
|
||||
"\r\n").getBytes("utf-8"));
|
||||
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);
|
||||
|
||||
assertFalse(client.isClosed());
|
||||
|
@ -224,7 +225,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
|||
|
||||
os.write((
|
||||
"GET / HTTP/1.0\r\n"+
|
||||
"host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
|
||||
"host: "+_serverURI.getHost()+":"+_serverURI.getPort()+"\r\n"+
|
||||
"connection: close\r\n"+
|
||||
"\r\n").getBytes("utf-8"));
|
||||
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);
|
||||
|
||||
assertFalse(client.isClosed());
|
||||
|
@ -302,7 +303,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
|||
byte[] contentB=content.getBytes("utf-8");
|
||||
os.write((
|
||||
"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-length: " + contentB.length + "\r\n" +
|
||||
"connection: close\r\n" +
|
||||
|
@ -329,7 +330,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
|||
{
|
||||
os.write((
|
||||
"GET / HTTP/1.0\r\n"+
|
||||
"host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
|
||||
"host: "+_serverURI.getHost()+":"+_serverURI.getPort()+"\r\n"+
|
||||
"connection: keep-alive\r\n"+
|
||||
"\r\n").getBytes("utf-8"));
|
||||
os.flush();
|
||||
|
@ -349,7 +350,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
|||
public void testMaxIdleNoRequest() throws Exception
|
||||
{
|
||||
configureServer(new EchoHandler());
|
||||
Socket client=newSocket(HOST,_connector.getLocalPort());
|
||||
Socket client=newSocket(_serverURI.getHost(),_serverURI.getPort());
|
||||
client.setSoTimeout(10000);
|
||||
InputStream is=client.getInputStream();
|
||||
assertFalse(client.isClosed());
|
||||
|
@ -377,7 +378,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
|||
public void testMaxIdleWithSlowRequest() throws Exception
|
||||
{
|
||||
configureServer(new EchoHandler());
|
||||
Socket client=newSocket(HOST,_connector.getLocalPort());
|
||||
Socket client=newSocket(_serverURI.getHost(),_serverURI.getPort());
|
||||
client.setSoTimeout(10000);
|
||||
|
||||
assertFalse(client.isClosed());
|
||||
|
@ -389,7 +390,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
|||
byte[] contentB=content.getBytes("utf-8");
|
||||
os.write((
|
||||
"GET / HTTP/1.0\r\n"+
|
||||
"host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
|
||||
"host: "+_serverURI.getHost()+":"+_serverURI.getPort()+"\r\n"+
|
||||
"connection: keep-alive\r\n"+
|
||||
"Content-Length: "+(contentB.length*20)+"\r\n"+
|
||||
"Content-Type: text/plain\r\n"+
|
||||
|
@ -417,7 +418,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
|||
public void testMaxIdleWithSlowResponse() throws Exception
|
||||
{
|
||||
configureServer(new SlowResponseHandler());
|
||||
Socket client=newSocket(HOST,_connector.getLocalPort());
|
||||
Socket client=newSocket(_serverURI.getHost(),_serverURI.getPort());
|
||||
client.setSoTimeout(10000);
|
||||
|
||||
assertFalse(client.isClosed());
|
||||
|
@ -427,7 +428,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
|||
|
||||
os.write((
|
||||
"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: close\r\n"+
|
||||
"\r\n").getBytes("utf-8"));
|
||||
|
@ -446,7 +447,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
|||
public void testMaxIdleWithWait() throws Exception
|
||||
{
|
||||
configureServer(new WaitHandler());
|
||||
Socket client=newSocket(HOST,_connector.getLocalPort());
|
||||
Socket client=newSocket(_serverURI.getHost(),_serverURI.getPort());
|
||||
client.setSoTimeout(10000);
|
||||
|
||||
assertFalse(client.isClosed());
|
||||
|
@ -456,7 +457,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
|||
|
||||
os.write((
|
||||
"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: close\r\n"+
|
||||
"\r\n").getBytes("utf-8"));
|
||||
|
|
|
@ -118,7 +118,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
{
|
||||
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)).info("expect request is too large, then ISE extra data ...");
|
||||
|
@ -149,7 +149,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
{
|
||||
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)).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");
|
||||
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();
|
||||
|
||||
try
|
||||
|
@ -246,7 +246,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
request.append("Content-length: 6\n\n");
|
||||
request.append("foo");
|
||||
|
||||
Socket client = newSocket(HOST, _connector.getLocalPort());
|
||||
Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort());
|
||||
OutputStream os = client.getOutputStream();
|
||||
|
||||
os.write(request.toString().getBytes());
|
||||
|
@ -269,7 +269,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
|
||||
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)).info("expect header is too large, then ISE extra data ...");
|
||||
|
@ -317,7 +317,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
{
|
||||
configureServer(new HelloWorldHandler());
|
||||
|
||||
try (Socket client = newSocket(HOST, _connector.getLocalPort()))
|
||||
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||
{
|
||||
OutputStream os = client.getOutputStream();
|
||||
|
||||
|
@ -337,7 +337,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
{
|
||||
configureServer(new EchoHandler());
|
||||
|
||||
try (Socket client = newSocket(HOST, _connector.getLocalPort()))
|
||||
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||
{
|
||||
OutputStream os = client.getOutputStream();
|
||||
|
||||
|
@ -367,7 +367,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
{
|
||||
configureServer(new EchoHandler());
|
||||
|
||||
try (Socket client = newSocket(HOST, _connector.getLocalPort()))
|
||||
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||
{
|
||||
OutputStream os = client.getOutputStream();
|
||||
|
||||
|
@ -396,7 +396,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
{
|
||||
configureServer(new HelloWorldHandler());
|
||||
|
||||
try (Socket client = newSocket(HOST, _connector.getLocalPort()))
|
||||
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||
{
|
||||
OutputStream os = client.getOutputStream();
|
||||
|
||||
|
@ -426,7 +426,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
byte[] bytes = REQUEST2.getBytes();
|
||||
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();
|
||||
|
||||
|
@ -474,7 +474,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
// Sort the list
|
||||
Arrays.sort(points);
|
||||
|
||||
try (Socket client = newSocket(HOST, _connector.getLocalPort()))
|
||||
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||
{
|
||||
OutputStream os = client.getOutputStream();
|
||||
|
||||
|
@ -505,7 +505,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
// Sort the list
|
||||
Arrays.sort(points);
|
||||
|
||||
try (Socket client = newSocket(HOST, _connector.getLocalPort()))
|
||||
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||
{
|
||||
OutputStream os = client.getOutputStream();
|
||||
|
||||
|
@ -537,7 +537,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
String test = encoding[e] + "x" + b + "x" + w + "x" + c;
|
||||
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();
|
||||
String response = IO.toString(in, e == 0 ? null : encoding[e]);
|
||||
|
@ -562,14 +562,14 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
configureServer(new DataHandler());
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
try (Socket client = newSocket(HOST, _connector.getLocalPort()))
|
||||
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||
{
|
||||
OutputStream os = client.getOutputStream();
|
||||
InputStream is = client.getInputStream();
|
||||
|
||||
os.write((
|
||||
"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" +
|
||||
"content-type: unknown\r\n" +
|
||||
"content-length: 30\r\n" +
|
||||
|
@ -624,14 +624,14 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
|
||||
long start = System.currentTimeMillis();
|
||||
int total = 0;
|
||||
try (Socket client = newSocket(HOST, _connector.getLocalPort()))
|
||||
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||
{
|
||||
OutputStream os = client.getOutputStream();
|
||||
InputStream is = client.getInputStream();
|
||||
|
||||
os.write((
|
||||
"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" +
|
||||
"content-type: unknown\r\n" +
|
||||
"\r\n"
|
||||
|
@ -665,7 +665,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
{
|
||||
configureServer(new BigBlockHandler());
|
||||
|
||||
try (Socket client = newSocket(HOST, _connector.getLocalPort()))
|
||||
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||
{
|
||||
client.setSoTimeout(20000);
|
||||
|
||||
|
@ -674,10 +674,10 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
|
||||
os.write((
|
||||
"GET /r1 HTTP/1.1\r\n" +
|
||||
"host: " + HOST + ":" + _connector.getLocalPort() + "\r\n" +
|
||||
"host: " + _serverURI.getHost() + ":" + _serverURI.getPort() + "\r\n" +
|
||||
"\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" +
|
||||
"\r\n"
|
||||
).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++)
|
||||
{
|
||||
try (Socket client = newSocket(HOST, _connector.getLocalPort()))
|
||||
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||
{
|
||||
client.setSoTimeout(5000);
|
||||
OutputStream os = client.getOutputStream();
|
||||
|
@ -807,7 +807,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
for (int i = 1; i < pipeline; i++)
|
||||
request +=
|
||||
"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" +
|
||||
"accept-encoding: nothing\r\n" +
|
||||
"cookie: aaa=1234567890\r\n" +
|
||||
|
@ -815,7 +815,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
|
||||
request +=
|
||||
"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" +
|
||||
"accept-encoding: nothing\r\n" +
|
||||
"cookie: aaa=bbbbbb\r\n" +
|
||||
|
@ -844,14 +844,14 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
public void testRecycledWriters() throws Exception
|
||||
{
|
||||
configureServer(new EchoHandler());
|
||||
try (Socket client = newSocket(HOST, _connector.getLocalPort()))
|
||||
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||
{
|
||||
OutputStream os = client.getOutputStream();
|
||||
InputStream is = client.getInputStream();
|
||||
|
||||
os.write((
|
||||
"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-length: 10\r\n" +
|
||||
"\r\n").getBytes("iso-8859-1"));
|
||||
|
@ -862,7 +862,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
|
||||
os.write((
|
||||
"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-length: 10\r\n" +
|
||||
"\r\n"
|
||||
|
@ -876,7 +876,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
byte[] contentB = content.getBytes("utf-8");
|
||||
os.write((
|
||||
"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-length: " + contentB.length + "\r\n" +
|
||||
"connection: close\r\n" +
|
||||
|
@ -928,28 +928,28 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
{
|
||||
configureServer(new EchoHandler(false));
|
||||
|
||||
try (Socket client = newSocket(HOST, _connector.getLocalPort()))
|
||||
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||
{
|
||||
OutputStream os = client.getOutputStream();
|
||||
InputStream is = client.getInputStream();
|
||||
|
||||
os.write((
|
||||
"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-length: 10\r\n" +
|
||||
"\015\012" +
|
||||
"123456789\n" +
|
||||
|
||||
"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-length: 10\r\n" +
|
||||
"\015\012" +
|
||||
"123456789\n" +
|
||||
|
||||
"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-length: 10\r\n" +
|
||||
"Connection: close\015\012" +
|
||||
|
@ -976,14 +976,14 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
{
|
||||
configureServer(new EchoHandler());
|
||||
|
||||
try (Socket client = newSocket(HOST, _connector.getLocalPort()))
|
||||
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||
{
|
||||
OutputStream os = client.getOutputStream();
|
||||
InputStream is = client.getInputStream();
|
||||
|
||||
os.write((
|
||||
"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-length: 10\r\n" +
|
||||
"\r\n").getBytes("iso-8859-1"));
|
||||
|
@ -994,7 +994,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
|
||||
os.write((
|
||||
"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-length: 10\r\n" +
|
||||
"\r\n"
|
||||
|
@ -1008,7 +1008,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
byte[] contentB = content.getBytes("utf-16");
|
||||
os.write((
|
||||
"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-length: " + contentB.length + "\r\n" +
|
||||
"connection: close\r\n" +
|
||||
|
@ -1030,7 +1030,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
{
|
||||
configureServer(new HelloWorldHandler());
|
||||
|
||||
try (Socket client = newSocket(HOST, _connector.getLocalPort()))
|
||||
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||
{
|
||||
OutputStream os = client.getOutputStream();
|
||||
InputStream is = client.getInputStream();
|
||||
|
@ -1038,7 +1038,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
// Send a request with chunked input and expect 100
|
||||
os.write((
|
||||
"GET / HTTP/1.1\r\n" +
|
||||
"Host: " + HOST + ":" + _connector.getLocalPort() + "\r\n" +
|
||||
"Host: " + _serverURI.getHost() + ":" + _serverURI.getPort() + "\r\n" +
|
||||
"Transfer-Encoding: chunked\r\n" +
|
||||
"Expect: 100-continue\r\n" +
|
||||
"Connection: Keep-Alive\r\n" +
|
||||
|
@ -1066,7 +1066,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
CommittedErrorHandler handler = new CommittedErrorHandler();
|
||||
configureServer(handler);
|
||||
|
||||
Socket client = newSocket(HOST, _connector.getLocalPort());
|
||||
Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort());
|
||||
try
|
||||
{
|
||||
((StdErrLog)Log.getLogger(HttpChannel.class)).setHideStacks(true);
|
||||
|
@ -1076,7 +1076,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
|
||||
// Send a request
|
||||
os.write(("GET / HTTP/1.1\r\n" +
|
||||
"Host: " + HOST + ":" + _connector.getLocalPort() + "\r\n" +
|
||||
"Host: " + _serverURI.getHost() + ":" + _serverURI.getPort() + "\r\n" +
|
||||
"\r\n"
|
||||
).getBytes());
|
||||
os.flush();
|
||||
|
@ -1206,14 +1206,14 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
AvailableHandler ah = new AvailableHandler();
|
||||
configureServer(ah);
|
||||
|
||||
try (Socket client = newSocket(HOST, _connector.getLocalPort()))
|
||||
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||
{
|
||||
OutputStream os = client.getOutputStream();
|
||||
InputStream is = client.getInputStream();
|
||||
|
||||
os.write((
|
||||
"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" +
|
||||
"content-type: unknown\r\n" +
|
||||
"content-length: 30\r\n" +
|
||||
|
@ -1251,7 +1251,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
{
|
||||
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 os2 = client2.getOutputStream();
|
||||
|
@ -1345,7 +1345,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
new String(fill);
|
||||
final byte[] bytes = content.getBytes();
|
||||
|
||||
Socket client = newSocket(HOST, _connector.getLocalPort());
|
||||
Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort());
|
||||
final OutputStream out = client.getOutputStream();
|
||||
|
||||
new Thread()
|
||||
|
@ -1405,7 +1405,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
configureServer(suspend);
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
Socket client = newSocket(HOST, _connector.getLocalPort());
|
||||
Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort());
|
||||
client.setSoTimeout(5000);
|
||||
try
|
||||
{
|
||||
|
@ -1414,7 +1414,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
// write an initial request
|
||||
os.write((
|
||||
"GET / HTTP/1.1\r\n" +
|
||||
"host: " + HOST + ":" + _connector.getLocalPort() + "\r\n" +
|
||||
"host: " + _serverURI.getHost() + ":" + _serverURI.getPort() + "\r\n" +
|
||||
"\r\n"
|
||||
).getBytes());
|
||||
os.flush();
|
||||
|
@ -1424,7 +1424,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
// write an pipelined request
|
||||
os.write((
|
||||
"GET / HTTP/1.1\r\n" +
|
||||
"host: " + HOST + ":" + _connector.getLocalPort() + "\r\n" +
|
||||
"host: " + _serverURI.getHost() + ":" + _serverURI.getPort() + "\r\n" +
|
||||
"connection: close\r\n" +
|
||||
"\r\n"
|
||||
).getBytes());
|
||||
|
|
|
@ -25,6 +25,7 @@ import java.io.OutputStream;
|
|||
import java.io.PrintWriter;
|
||||
import java.io.Writer;
|
||||
import java.net.Socket;
|
||||
import java.net.URI;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.SSLSession;
|
||||
|
@ -42,9 +43,9 @@ public class HttpServerTestFixture
|
|||
{ // Useful constants
|
||||
protected static final long PAUSE=10L;
|
||||
protected static final int LOOPS=50;
|
||||
protected static final String HOST="localhost";
|
||||
|
||||
protected Server _server;
|
||||
protected URI _serverURI;
|
||||
protected NetworkConnector _connector;
|
||||
protected String _scheme="http";
|
||||
|
||||
|
@ -69,6 +70,7 @@ public class HttpServerTestFixture
|
|||
_server.addConnector(_connector);
|
||||
_server.setHandler(new HandlerWrapper());
|
||||
_server.start();
|
||||
_serverURI = _server.getURI();
|
||||
}
|
||||
|
||||
@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.net.Socket;
|
||||
import java.net.SocketException;
|
||||
import java.net.URI;
|
||||
import java.security.KeyStore;
|
||||
import java.util.Arrays;
|
||||
|
||||
|
@ -153,7 +154,8 @@ public class SelectChannelServerSslTest extends HttpServerTestBase
|
|||
// Sort the list
|
||||
Arrays.sort(points);
|
||||
|
||||
Socket client=newSocket(HOST,_connector.getLocalPort());
|
||||
URI uri=_server.getURI();
|
||||
Socket client=newSocket(uri.getHost(),uri.getPort());
|
||||
try
|
||||
{
|
||||
OutputStream os=client.getOutputStream();
|
||||
|
|
|
@ -34,8 +34,10 @@ import javax.servlet.ServletContext;
|
|||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.ServletResponseWrapper;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpServletResponseWrapper;
|
||||
|
||||
import org.eclipse.jetty.continuation.Continuation;
|
||||
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.servlets.gzip.AbstractCompressedStream;
|
||||
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.Logger;
|
||||
|
||||
|
@ -101,15 +104,21 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
* instead.
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
public class GzipFilter extends UserAgentFilter
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(GzipFilter.class);
|
||||
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 ETAG_DEFLATE="-deflate\"";
|
||||
public final static String ETAG_DEFLATE="--deflate\"";
|
||||
public final static String ETAG="o.e.j.s.GzipFilter.ETag";
|
||||
|
||||
protected ServletContext _context;
|
||||
|
@ -122,6 +131,7 @@ public class GzipFilter extends UserAgentFilter
|
|||
protected Set<Pattern> _excludedAgentPatterns;
|
||||
protected Set<String> _excludedPaths;
|
||||
protected Set<Pattern> _excludedPathPatterns;
|
||||
protected String _vary="Accept-Encoding, User-Agent";
|
||||
|
||||
private static final int STATE_SEPARATOR = 0;
|
||||
private static final int STATE_Q = 1;
|
||||
|
@ -199,6 +209,10 @@ public class GzipFilter extends UserAgentFilter
|
|||
while (tok.hasMoreTokens())
|
||||
_excludedPathPatterns.add(Pattern.compile(tok.nextToken()));
|
||||
}
|
||||
|
||||
tmp=filterConfig.getInitParameter("vary");
|
||||
if (tmp!=null)
|
||||
_vary=tmp;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -221,8 +235,15 @@ public class GzipFilter extends UserAgentFilter
|
|||
HttpServletRequest request=(HttpServletRequest)req;
|
||||
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;
|
||||
}
|
||||
|
||||
// Check if mime type of request can ever be compressed.
|
||||
// Exclude non compressible mime-types known from URI extension. - no Vary because no matter what client, this URI is always excluded
|
||||
if (_mimeTypes!=null && _mimeTypes.size()>0)
|
||||
{
|
||||
String mimeType = _context.getMimeType(request.getRequestURI());
|
||||
|
@ -235,34 +256,20 @@ public class GzipFilter extends UserAgentFilter
|
|||
}
|
||||
}
|
||||
|
||||
// Inform caches that responses may vary according to Accept-Encoding
|
||||
response.setHeader("Vary","Accept-Encoding");
|
||||
|
||||
// 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()))
|
||||
{
|
||||
// Excluded User-Agents
|
||||
String ua = getUserAgent(request);
|
||||
if (isExcludedAgent(ua))
|
||||
{
|
||||
super.doFilter(request,response,chain);
|
||||
return;
|
||||
}
|
||||
String requestURI = request.getRequestURI();
|
||||
if (isExcludedPath(requestURI))
|
||||
{
|
||||
super.doFilter(request,response,chain);
|
||||
return;
|
||||
}
|
||||
boolean ua_excluded=ua!=null&&isExcludedAgent(ua);
|
||||
|
||||
// Acceptable compression type
|
||||
String compressionType = ua_excluded?null:selectCompression(request.getHeader("accept-encoding"));
|
||||
|
||||
// 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())+'"');
|
||||
int dd=etag.indexOf("--");
|
||||
if (dd>0)
|
||||
request.setAttribute(ETAG,etag.substring(0,dd)+(etag.endsWith("\"")?"\"":""));
|
||||
}
|
||||
|
||||
CompressedResponseWrapper wrappedResponse = createWrappedResponse(request,response,compressionType);
|
||||
|
@ -289,11 +296,6 @@ public class GzipFilter extends UserAgentFilter
|
|||
wrappedResponse.finish();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
super.doFilter(request,response,chain);
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
private String selectCompression(String encodingHeader)
|
||||
|
@ -387,14 +389,32 @@ public class GzipFilter extends UserAgentFilter
|
|||
protected CompressedResponseWrapper createWrappedResponse(HttpServletRequest request, HttpServletResponse response, final String compressionType)
|
||||
{
|
||||
CompressedResponseWrapper wrappedResponse = null;
|
||||
if (compressionType.equals(GZIP))
|
||||
if (compressionType==null)
|
||||
{
|
||||
wrappedResponse = new CompressedResponseWrapper(request,response)
|
||||
{
|
||||
@Override
|
||||
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
|
||||
protected DeflaterOutputStream createStream() throws IOException
|
||||
|
@ -412,7 +432,7 @@ public class GzipFilter extends UserAgentFilter
|
|||
@Override
|
||||
protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response) throws IOException
|
||||
{
|
||||
return new AbstractCompressedStream(compressionType,request,this)
|
||||
return new AbstractCompressedStream(compressionType,request,this,_vary)
|
||||
{
|
||||
@Override
|
||||
protected DeflaterOutputStream createStream() throws IOException
|
||||
|
@ -438,8 +458,8 @@ public class GzipFilter extends UserAgentFilter
|
|||
wrappedResponse.setMinCompressSize(_minGzipSize);
|
||||
}
|
||||
|
||||
private class ContinuationListenerWaitingForWrappedResponseToFinish implements ContinuationListener{
|
||||
|
||||
private class ContinuationListenerWaitingForWrappedResponseToFinish implements ContinuationListener
|
||||
{
|
||||
private CompressedResponseWrapper wrappedResponse;
|
||||
|
||||
public ContinuationListenerWaitingForWrappedResponseToFinish(CompressedResponseWrapper wrappedResponse)
|
||||
|
@ -532,4 +552,51 @@ public class GzipFilter extends UserAgentFilter
|
|||
}
|
||||
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)
|
||||
{
|
||||
CompressedResponseWrapper wrappedResponse = null;
|
||||
if (compressionType.equals(GZIP))
|
||||
if (compressionType==null)
|
||||
{
|
||||
wrappedResponse = new IncludableResponseWrapper(request,response)
|
||||
{
|
||||
@Override
|
||||
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
|
||||
protected DeflaterOutputStream createStream() throws IOException
|
||||
|
@ -104,7 +131,7 @@ public class IncludableGzipFilter extends GzipFilter
|
|||
@Override
|
||||
protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response) throws IOException
|
||||
{
|
||||
return new AbstractCompressedStream(compressionType,request,this)
|
||||
return new AbstractCompressedStream(compressionType,request,this,_vary)
|
||||
{
|
||||
@Override
|
||||
protected DeflaterOutputStream createStream() throws IOException
|
||||
|
|
|
@ -40,6 +40,7 @@ import org.eclipse.jetty.util.ByteArrayOutputStream2;
|
|||
public abstract class AbstractCompressedStream extends ServletOutputStream
|
||||
{
|
||||
private final String _encoding;
|
||||
protected final String _vary;
|
||||
protected final CompressedResponseWrapper _wrapper;
|
||||
protected final HttpServletResponse _response;
|
||||
protected OutputStream _out;
|
||||
|
@ -52,12 +53,13 @@ public abstract class AbstractCompressedStream extends ServletOutputStream
|
|||
* 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
|
||||
{
|
||||
_encoding=encoding;
|
||||
_wrapper = wrapper;
|
||||
_response = (HttpServletResponse)wrapper.getResponse();
|
||||
_vary=vary;
|
||||
|
||||
if (_wrapper.getMinCompressSize()==0)
|
||||
doCompress();
|
||||
|
@ -106,7 +108,7 @@ public abstract class AbstractCompressedStream extends ServletOutputStream
|
|||
{
|
||||
long length=_wrapper.getContentLength();
|
||||
if (length > 0 && length < _wrapper.getMinCompressSize())
|
||||
doNotCompress();
|
||||
doNotCompress(false);
|
||||
else
|
||||
doCompress();
|
||||
}
|
||||
|
@ -137,13 +139,14 @@ public abstract class AbstractCompressedStream extends ServletOutputStream
|
|||
_wrapper.setContentLength(length);
|
||||
}
|
||||
if (length < _wrapper.getMinCompressSize())
|
||||
doNotCompress();
|
||||
doNotCompress(false);
|
||||
else
|
||||
doCompress();
|
||||
}
|
||||
else if (_out == null)
|
||||
{
|
||||
doNotCompress();
|
||||
// No output
|
||||
doNotCompress(false);
|
||||
}
|
||||
|
||||
if (_compressedOutputStream != null)
|
||||
|
@ -168,7 +171,7 @@ public abstract class AbstractCompressedStream extends ServletOutputStream
|
|||
{
|
||||
long length=_wrapper.getContentLength();
|
||||
if (length > 0 && length < _wrapper.getMinCompressSize())
|
||||
doNotCompress();
|
||||
doNotCompress(false);
|
||||
else
|
||||
doCompress();
|
||||
}
|
||||
|
@ -226,11 +229,15 @@ public abstract class AbstractCompressedStream extends ServletOutputStream
|
|||
if (_response.isCommitted())
|
||||
throw new IllegalStateException();
|
||||
|
||||
if (_encoding!=null)
|
||||
{
|
||||
setHeader("Content-Encoding", _encoding);
|
||||
if (_response.containsHeader("Content-Encoding"))
|
||||
{
|
||||
setHeader("Vary",_vary);
|
||||
_out=_compressedOutputStream=createStream();
|
||||
|
||||
if (_out!=null)
|
||||
{
|
||||
if (_bOut!=null)
|
||||
{
|
||||
_out.write(_bOut.getBuf(),0,_bOut.getCount());
|
||||
|
@ -240,9 +247,12 @@ public abstract class AbstractCompressedStream extends ServletOutputStream
|
|||
String etag=_wrapper.getETag();
|
||||
if (etag!=null)
|
||||
setHeader("ETag",etag.substring(0,etag.length()-1)+'-'+_encoding+'"');
|
||||
return;
|
||||
}
|
||||
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
|
||||
* Signals that an I/O exception has occurred.
|
||||
*/
|
||||
public void doNotCompress() throws IOException
|
||||
public void doNotCompress(boolean sendVary) throws IOException
|
||||
{
|
||||
if (_compressedOutputStream != null)
|
||||
throw new IllegalStateException("Compressed output stream is already assigned.");
|
||||
if (_out == null || _bOut != null)
|
||||
{
|
||||
if (sendVary)
|
||||
setHeader("Vary",_vary);
|
||||
if (_wrapper.getETag()!=null)
|
||||
setHeader("ETag",_wrapper.getETag());
|
||||
|
||||
|
@ -289,7 +301,7 @@ public abstract class AbstractCompressedStream extends ServletOutputStream
|
|||
{
|
||||
long length=_wrapper.getContentLength();
|
||||
if (_response.isCommitted() || (length >= 0 && length < _wrapper.getMinCompressSize()))
|
||||
doNotCompress();
|
||||
doNotCompress(false);
|
||||
else if (lengthToWrite > _wrapper.getMinCompressSize())
|
||||
doCompress();
|
||||
else
|
||||
|
@ -299,7 +311,7 @@ public abstract class AbstractCompressedStream extends ServletOutputStream
|
|||
{
|
||||
long length=_wrapper.getContentLength();
|
||||
if (_response.isCommitted() || (length >= 0 && length < _wrapper.getMinCompressSize()))
|
||||
doNotCompress();
|
||||
doNotCompress(false);
|
||||
else if (lengthToWrite >= (_bOut.getBuf().length - _bOut.getCount()))
|
||||
doCompress();
|
||||
}
|
||||
|
|
|
@ -316,7 +316,7 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp
|
|||
{
|
||||
try
|
||||
{
|
||||
_compressedStream.doNotCompress();
|
||||
_compressedStream.doNotCompress(false);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
|
|
|
@ -67,6 +67,7 @@ public class GzipHandler extends HandlerWrapper
|
|||
protected Set<String> _excluded;
|
||||
protected int _bufferSize = 8192;
|
||||
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.
|
||||
|
@ -296,7 +322,7 @@ public class GzipHandler extends HandlerWrapper
|
|||
@Override
|
||||
protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response) throws IOException
|
||||
{
|
||||
return new AbstractCompressedStream("gzip",request,this)
|
||||
return new AbstractCompressedStream("gzip",request,this,_vary)
|
||||
{
|
||||
@Override
|
||||
protected DeflaterOutputStream createStream() throws IOException
|
||||
|
|
|
@ -120,15 +120,7 @@ public class GzipWithPipeliningTest
|
|||
// Start Server
|
||||
server.start();
|
||||
|
||||
NetworkConnector conn = (NetworkConnector)server.getConnectors()[0];
|
||||
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);
|
||||
serverUri = server.getURI();
|
||||
}
|
||||
|
||||
@After
|
||||
|
|
|
@ -73,7 +73,6 @@ public class MultipartFilterTest
|
|||
@Override
|
||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
|
||||
{
|
||||
System.err.println(req.getParameter("field1"));
|
||||
assertNotNull(req.getParameter("fileup"));
|
||||
assertNotNull(req.getParameter("fileup"+MultiPartFilter.CONTENT_TYPE_SUFFIX));
|
||||
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)
|
||||
{
|
||||
Assert.assertThat("Response.status",response.getStatus(),is(status));
|
||||
Assert.assertThat("Response.header[Content-Encoding]",response.get("Content-Encoding"),not(containsString(compressionType)));
|
||||
if (expectedFilesize != (-1))
|
||||
{
|
||||
Assert.assertEquals(expectedFilesize,response.getContentBytes().length);
|
||||
|
@ -456,6 +457,7 @@ public class GzipTester
|
|||
ServletHolder servletHolder = tester.addServlet(servletClass,"/");
|
||||
servletHolder.setInitParameter("baseDir",testdir.getDir().getAbsolutePath());
|
||||
FilterHolder holder = tester.addFilter(gzipFilterClass,"/*",EnumSet.allOf(DispatcherType.class));
|
||||
holder.setInitParameter("vary","Accept-Encoding");
|
||||
return holder;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,6 @@ import org.eclipse.jetty.server.Server;
|
|||
import org.eclipse.jetty.server.ServerConnector;
|
||||
import org.eclipse.jetty.server.handler.DefaultHandler;
|
||||
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.PingInfo;
|
||||
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.server.http.HTTPSPDYHeader;
|
||||
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.ssl.SslContextFactory;
|
||||
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));
|
||||
|
||||
client.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -227,8 +225,6 @@ public class ProxySPDYToHTTPTest
|
|||
|
||||
assertThat("reply has been received", replyLatch.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
|
||||
|
@ -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("data has been received", dataLatch.await(5, TimeUnit.SECONDS), is(true));
|
||||
|
||||
client.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSYNWithSplitRequestContentThenREPLYAndDATA() throws Exception
|
||||
{
|
||||
final String data = "0123456789ABCDEF";
|
||||
final String data2 = "ABCDEF0123456789";
|
||||
final String data2 = "ABCDEF";
|
||||
final String header = "foo";
|
||||
|
||||
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());
|
||||
if (dataInfo.isClose())
|
||||
{
|
||||
System.out.println("client received DATA: " + result);
|
||||
assertThat("received data matches send data", result.toString(), is(data + data2));
|
||||
dataLatch.countDown();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
stream.data(new StringDataInfo(data, false));
|
||||
stream.data(new StringDataInfo(data2, true));
|
||||
System.out.println("DATA1 sent!!!!!!!!");
|
||||
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("data has been received", dataLatch.await(5, TimeUnit.SECONDS), is(true));
|
||||
|
||||
client.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -399,7 +394,7 @@ public class ProxySPDYToHTTPTest
|
|||
|
||||
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
|
||||
|
@ -425,7 +420,7 @@ public class ProxySPDYToHTTPTest
|
|||
|
||||
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
|
||||
|
@ -443,6 +438,7 @@ public class ProxySPDYToHTTPTest
|
|||
public void handle(String target, Request baseRequest, HttpServletRequest request,
|
||||
HttpServletResponse response) throws IOException, ServletException
|
||||
{
|
||||
System.out.println("HANDLER CALLED!!!");
|
||||
assertThat("Via Header is set", baseRequest.getHeader("X-Forwarded-For"), is(notNullValue()));
|
||||
assertThat("X-Forwarded-For Header is set", baseRequest.getHeader("X-Forwarded-For"),
|
||||
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.io.ssl.LEVEL=DEBUG
|
||||
org.eclipse.jetty.spdy.LEVEL=DEBUG
|
||||
#org.eclipse.jetty.client.LEVEL=DEBUG
|
||||
org.eclipse.jetty.client.LEVEL=DEBUG
|
||||
#org.mortbay.LEVEL=DEBUG
|
||||
|
|
|
@ -61,10 +61,11 @@ public class PingTest extends AbstractTest
|
|||
@Test
|
||||
public void testServerPingPong() throws Exception
|
||||
{
|
||||
final CountDownLatch pingLatch = new CountDownLatch(1);
|
||||
final CountDownLatch pingReceived = new CountDownLatch(1);
|
||||
ServerSessionFrameListener serverSessionFrameListener = new ServerSessionFrameListener.Adapter()
|
||||
{
|
||||
public volatile int pingId;
|
||||
private final CountDownLatch pingSent = new CountDownLatch(1);
|
||||
private int pingId;
|
||||
|
||||
@Override
|
||||
public void onConnect(Session session)
|
||||
|
@ -75,6 +76,7 @@ public class PingTest extends AbstractTest
|
|||
public void succeeded(PingResultInfo pingInfo)
|
||||
{
|
||||
pingId = pingInfo.getPingId();
|
||||
pingSent.countDown();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -82,13 +84,23 @@ public class PingTest extends AbstractTest
|
|||
@Override
|
||||
public void onPing(Session session, PingResultInfo pingInfo)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 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());
|
||||
pingLatch.countDown();
|
||||
pingReceived.countDown();
|
||||
}
|
||||
catch (InterruptedException x)
|
||||
{
|
||||
Assert.fail();
|
||||
}
|
||||
}
|
||||
};
|
||||
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
|
||||
* {@link #getConvertor(Class)}.
|
||||
* </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
|
||||
{
|
||||
|
@ -945,6 +949,15 @@ public class JSON
|
|||
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");
|
||||
if (classname != null)
|
||||
{
|
||||
|
@ -955,9 +968,10 @@ public class JSON
|
|||
}
|
||||
catch (ClassNotFoundException e)
|
||||
{
|
||||
LOG.warn(e);
|
||||
LOG.warn("no Class for classname '%s'", classname);
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
|
|
|
@ -208,7 +208,7 @@ public class SslContextFactory extends AbstractLifeCycle
|
|||
*/
|
||||
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.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);
|
||||
|
||||
|
@ -57,6 +57,7 @@ public class TimerScheduler extends AbstractLifeCycle implements Scheduler
|
|||
protected void doStart() throws Exception
|
||||
{
|
||||
_timer = _name == null ? new Timer() : new Timer(_name, _daemon);
|
||||
run();
|
||||
super.doStart();
|
||||
}
|
||||
|
||||
|
@ -79,6 +80,17 @@ public class TimerScheduler extends AbstractLifeCycle implements Scheduler
|
|||
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 final Runnable _task;
|
||||
|
|
|
@ -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
|
|
@ -36,32 +36,25 @@ public class WebSocketPolicy
|
|||
}
|
||||
|
||||
/**
|
||||
* The maximum allowed payload size (validated in both directions)
|
||||
* The maximum size of a text message during parsing/generating.
|
||||
* <p>
|
||||
* Default: 65536 (64 K)
|
||||
*/
|
||||
private int maxPayloadSize = 64 * KB;
|
||||
|
||||
/**
|
||||
* The maximum size of a text message during parsing/generating.
|
||||
* <p>
|
||||
* Default: 16384 (16 K)
|
||||
*/
|
||||
private int maxTextMessageSize = 64 * KB;
|
||||
|
||||
/**
|
||||
* The maximum size of a binary message during parsing/generating.
|
||||
* <p>
|
||||
* Default: -1 (no validation)
|
||||
*/
|
||||
private int maxBinaryMessageSize = 64 * KB;
|
||||
private long maxMessageSize = 64 * KB;
|
||||
|
||||
/**
|
||||
* The time in ms (milliseconds) that a websocket may be idle before closing.
|
||||
* <p>
|
||||
* 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
|
||||
|
@ -73,35 +66,14 @@ public class WebSocketPolicy
|
|||
this.behavior = behavior;
|
||||
}
|
||||
|
||||
public void assertValidBinaryMessageSize(int requestedSize)
|
||||
public void assertValidMessageSize(int requestedSize)
|
||||
{
|
||||
if (maxBinaryMessageSize > 0)
|
||||
if (maxMessageSize > 0)
|
||||
{
|
||||
// validate it
|
||||
if (requestedSize > maxBinaryMessageSize)
|
||||
if (requestedSize > maxMessageSize)
|
||||
{
|
||||
throw new MessageTooLargeException("Requested binary message size [" + requestedSize + "] exceeds maximum size [" + maxBinaryMessageSize + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 + "]");
|
||||
throw new MessageTooLargeException("Requested message size [" + requestedSize + "] exceeds maximum size [" + maxMessageSize + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -110,9 +82,8 @@ public class WebSocketPolicy
|
|||
{
|
||||
WebSocketPolicy clone = new WebSocketPolicy(this.behavior);
|
||||
clone.idleTimeout = this.idleTimeout;
|
||||
clone.maxPayloadSize = this.maxPayloadSize;
|
||||
clone.maxBinaryMessageSize = this.maxBinaryMessageSize;
|
||||
clone.maxTextMessageSize = this.maxTextMessageSize;
|
||||
clone.maxMessageSize = this.maxMessageSize;
|
||||
clone.inputBufferSize = this.inputBufferSize;
|
||||
return clone;
|
||||
}
|
||||
|
||||
|
@ -121,47 +92,33 @@ public class WebSocketPolicy
|
|||
return behavior;
|
||||
}
|
||||
|
||||
public int getIdleTimeout()
|
||||
public long getIdleTimeout()
|
||||
{
|
||||
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()
|
||||
{
|
||||
return maxTextMessageSize;
|
||||
}
|
||||
|
||||
public void setIdleTimeout(int idleTimeout)
|
||||
public void setIdleTimeout(long 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)
|
||||
{
|
||||
throw new IllegalStateException("Cannot have payload size be a negative number");
|
||||
}
|
||||
this.maxPayloadSize = maxPayloadSize;
|
||||
}
|
||||
|
||||
public void setMaxTextMessageSize(int maxTextMessageSize)
|
||||
{
|
||||
this.maxTextMessageSize = maxTextMessageSize;
|
||||
this.maxMessageSize = maxMessageSize;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,11 +33,9 @@ import java.lang.annotation.Target;
|
|||
{ ElementType.TYPE })
|
||||
public @interface WebSocket
|
||||
{
|
||||
int maxBinarySize() default -2;
|
||||
|
||||
int maxBufferSize() default -2;
|
||||
int inputBufferSize() 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;
|
||||
/**
|
||||
* Jetty WebSocket API : WebSocket POJO Annotations
|
||||
*/
|
||||
package org.eclipse.jetty.websocket.api.annotations;
|
||||
|
||||
/**
|
||||
* Connection suspend token
|
||||
*/
|
||||
public interface SuspendToken
|
||||
{
|
||||
/**
|
||||
* 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;
|
||||
|
|
@ -67,6 +67,18 @@
|
|||
</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>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
|
@ -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.ExtensionConfig;
|
||||
import org.eclipse.jetty.websocket.api.extensions.ExtensionFactory;
|
||||
import org.eclipse.jetty.websocket.client.internal.ConnectPromise;
|
||||
import org.eclipse.jetty.websocket.client.internal.ConnectionManager;
|
||||
import org.eclipse.jetty.websocket.client.io.ConnectPromise;
|
||||
import org.eclipse.jetty.websocket.client.io.ConnectionManager;
|
||||
import org.eclipse.jetty.websocket.client.masks.Masker;
|
||||
import org.eclipse.jetty.websocket.client.masks.RandomMasker;
|
||||
import org.eclipse.jetty.websocket.common.events.EventDriver;
|
||||
|
@ -290,13 +290,8 @@ public class WebSocketClient extends ContainerLifeCycle
|
|||
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)
|
||||
{
|
||||
throw new IllegalStateException("Connect Timeout cannot be negative");
|
||||
|
|
|
@ -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.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.SocketAddress;
|
||||
|
@ -34,7 +34,6 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
import org.eclipse.jetty.websocket.api.UpgradeException;
|
||||
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
|
||||
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.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.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.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.client.ClientUpgradeRequest;
|
||||
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.WebSocketSession;
|
||||
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.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.extensions.Frame;
|
||||
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.common.WebSocketFrame;
|
||||
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.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.websocket.api.WebSocketPolicy;
|
||||
import org.eclipse.jetty.websocket.client.WebSocketClient;
|
||||
import org.eclipse.jetty.websocket.client.internal.ConnectPromise;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* Interface for various Masker implementations.
|
||||
*/
|
||||
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);
|
||||
}
|
|
@ -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.net.URI;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||
import org.eclipse.jetty.websocket.dummy.DummyServer;
|
||||
import org.eclipse.jetty.websocket.dummy.DummyServer.ServerConnection;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketAdapter;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketConnection;
|
||||
import org.eclipse.jetty.websocket.client.blockhead.BlockheadServer;
|
||||
import org.eclipse.jetty.websocket.client.blockhead.BlockheadServer.ServerConnection;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
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.
|
||||
* <ul>
|
||||
* <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>
|
||||
* </ul>
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void testTomcat7_0_32_WithTransferEncoding() throws Exception
|
||||
{
|
||||
DummyServer server = new DummyServer();
|
||||
int bufferSize = 512;
|
||||
QueuedThreadPool threadPool = new QueuedThreadPool();
|
||||
WebSocketClientFactory factory = new WebSocketClientFactory(threadPool, new ZeroMaskGen(), bufferSize);
|
||||
BlockheadServer server = new BlockheadServer();
|
||||
WebSocketClient client = new WebSocketClient();
|
||||
|
||||
try
|
||||
{
|
||||
int bufferSize = 512;
|
||||
|
||||
server.start();
|
||||
|
||||
// Setup Client Factory
|
||||
threadPool.start();
|
||||
factory.start();
|
||||
|
||||
// Create Client
|
||||
WebSocketClient client = new WebSocketClient(factory);
|
||||
client.start();
|
||||
|
||||
// Create End User WebSocket Class
|
||||
final CountDownLatch openLatch = new CountDownLatch(1);
|
||||
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)
|
||||
{
|
||||
}
|
||||
};
|
||||
LatchedSocket websocket = new LatchedSocket();
|
||||
|
||||
// Open connection
|
||||
URI wsURI = server.getWsUri();
|
||||
client.open(wsURI, websocket);
|
||||
client.connect(websocket,wsURI);
|
||||
|
||||
// Accept incoming connection
|
||||
ServerConnection socket = server.accept();
|
||||
socket.setSoTimeout(2000); // timeout
|
||||
|
||||
// Issue upgrade
|
||||
Map<String,String> extraResponseHeaders = new HashMap<String, String>();
|
||||
extraResponseHeaders.put("Transfer-Encoding", "chunked"); // !! The problem !!
|
||||
socket.upgrade(extraResponseHeaders);
|
||||
// Add the extra problematic header that triggers bug found in jetty-io
|
||||
socket.addResponseHeader("Transfer-Encoding","chunked");
|
||||
socket.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.
|
||||
int length = bufferSize / 2;
|
||||
|
@ -107,18 +109,19 @@ public class TomcatServerQuirksTest
|
|||
serverFrame.put((byte)(length >> 8)); // first length byte
|
||||
serverFrame.put((byte)(length & 0xFF)); // second length byte
|
||||
for (int i = 0; i < length; ++i)
|
||||
{
|
||||
serverFrame.put((byte)'x');
|
||||
}
|
||||
serverFrame.flip();
|
||||
byte buf[] = serverFrame.array();
|
||||
socket.write(buf,0,buf.length);
|
||||
socket.flush();
|
||||
|
||||
Assert.assertTrue(dataLatch.await(1000, TimeUnit.SECONDS));
|
||||
Assert.assertTrue(websocket.dataLatch.await(1000,TimeUnit.SECONDS));
|
||||
}
|
||||
finally
|
||||
{
|
||||
factory.stop();
|
||||
threadPool.stop();
|
||||
client.stop();
|
||||
server.stop();
|
||||
}
|
||||
}
|
|
@ -33,7 +33,9 @@ import java.net.SocketException;
|
|||
import java.net.URI;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
@ -87,6 +89,7 @@ public class BlockheadServer
|
|||
private OutputStream out;
|
||||
private InputStream in;
|
||||
|
||||
private Map<String, String> extraResponseHeaders = new HashMap<>();
|
||||
private OutgoingFrames outgoing = this;
|
||||
|
||||
public ServerConnection(Socket socket)
|
||||
|
@ -101,6 +104,14 @@ public class BlockheadServer
|
|||
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
|
||||
{
|
||||
write(new WebSocketFrame(OpCode.CLOSE));
|
||||
|
@ -412,6 +423,16 @@ public class BlockheadServer
|
|||
}
|
||||
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");
|
||||
|
||||
// Write Response
|
||||
|
|
|
@ -25,6 +25,7 @@ import java.net.URI;
|
|||
import java.net.URISyntaxException;
|
||||
|
||||
import org.eclipse.jetty.toolchain.test.TestTracker;
|
||||
import org.eclipse.jetty.websocket.client.io.ConnectionManager;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Rule;
|
||||
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.StringUtil;
|
||||
import org.eclipse.jetty.websocket.api.UpgradeResponse;
|
||||
import org.eclipse.jetty.websocket.client.io.HttpResponseHeaderParser;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
|
|
@ -97,7 +97,7 @@ public class Parser
|
|||
// 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);
|
||||
}
|
||||
policy.assertValidPayloadLength((int)len);
|
||||
policy.assertValidMessageSize((int)len);
|
||||
|
||||
switch (frame.getOpCode())
|
||||
{
|
||||
|
@ -540,7 +540,6 @@ public class Parser
|
|||
{
|
||||
if (payload == null)
|
||||
{
|
||||
getPolicy().assertValidPayloadLength(payloadLength);
|
||||
frame.assertValid();
|
||||
payload = bufferPool.acquire(payloadLength,false);
|
||||
BufferUtil.clearToFill(payload);
|
||||
|
|
|
@ -49,13 +49,13 @@ public class AnnotatedEventDriver extends EventDriver
|
|||
|
||||
WebSocket anno = websocket.getClass().getAnnotation(WebSocket.class);
|
||||
// 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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
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.bufferPool = bufferPool;
|
||||
this.generator = new Generator(policy,bufferPool);
|
||||
|
@ -151,6 +151,7 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
|
|||
this.ioState = new IOState();
|
||||
this.ioState.setState(ConnectionState.CONNECTING);
|
||||
this.writeBytes = new WriteBytesProvider(generator,new FlushCallback());
|
||||
this.setInputBufferSize(policy.getInputBufferSize());
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
driver.getPolicy().assertValidBinaryMessageSize(size + payload.remaining());
|
||||
driver.getPolicy().assertValidMessageSize(size + payload.remaining());
|
||||
size += payload.remaining();
|
||||
|
||||
synchronized (buf)
|
||||
|
|
|
@ -61,7 +61,7 @@ public class MessageReader extends Reader implements MessageAppender
|
|||
return;
|
||||
}
|
||||
|
||||
driver.getPolicy().assertValidTextMessageSize(size + payload.remaining());
|
||||
driver.getPolicy().assertValidMessageSize(size + payload.remaining());
|
||||
size += payload.remaining();
|
||||
|
||||
synchronized (utf)
|
||||
|
|
|
@ -54,7 +54,7 @@ public class SimpleBinaryMessage implements MessageAppender
|
|||
return;
|
||||
}
|
||||
|
||||
onEvent.getPolicy().assertValidBinaryMessageSize(size + payload.remaining());
|
||||
onEvent.getPolicy().assertValidMessageSize(size + payload.remaining());
|
||||
size += payload.remaining();
|
||||
|
||||
BufferUtil.writeTo(payload,out);
|
||||
|
|
|
@ -53,7 +53,7 @@ public class SimpleTextMessage implements MessageAppender
|
|||
return;
|
||||
}
|
||||
|
||||
onEvent.getPolicy().assertValidTextMessageSize(size + payload.remaining());
|
||||
onEvent.getPolicy().assertValidMessageSize(size + payload.remaining());
|
||||
size += payload.remaining();
|
||||
|
||||
// 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 |