Merge branch 'master' of ssh://git.eclipse.org/gitroot/jetty/org.eclipse.jetty.project
This commit is contained in:
commit
c7b6ed72e8
|
@ -24,7 +24,6 @@ import java.nio.channels.AsynchronousCloseException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
|
@ -42,6 +41,7 @@ import org.eclipse.jetty.http.HttpField;
|
|||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.eclipse.jetty.http.HttpScheme;
|
||||
import org.eclipse.jetty.util.BlockingArrayQueue;
|
||||
import org.eclipse.jetty.util.FuturePromise;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
||||
|
@ -72,9 +72,16 @@ public class HttpDestination implements Destination, AutoCloseable, Dumpable
|
|||
this.scheme = scheme;
|
||||
this.host = host;
|
||||
this.address = new InetSocketAddress(host, port);
|
||||
this.requests = new ArrayBlockingQueue<>(client.getMaxRequestsQueuedPerDestination());
|
||||
this.idleConnections = new ArrayBlockingQueue<>(client.getMaxConnectionsPerDestination());
|
||||
this.activeConnections = new ArrayBlockingQueue<>(client.getMaxConnectionsPerDestination());
|
||||
|
||||
int maxRequestsQueued = client.getMaxRequestsQueuedPerDestination();
|
||||
int capacity = Math.min(32, maxRequestsQueued);
|
||||
this.requests = new BlockingArrayQueue<>(capacity, capacity, maxRequestsQueued);
|
||||
|
||||
int maxConnections = client.getMaxConnectionsPerDestination();
|
||||
capacity = Math.min(8, maxConnections);
|
||||
this.idleConnections = new BlockingArrayQueue<>(capacity, capacity, maxConnections);
|
||||
this.activeConnections = new BlockingArrayQueue<>(capacity, capacity, maxConnections);
|
||||
|
||||
this.requestNotifier = new RequestNotifier(client);
|
||||
this.responseNotifier = new ResponseNotifier(client);
|
||||
|
||||
|
|
|
@ -41,8 +41,10 @@ import org.eclipse.jetty.io.SelectorManager;
|
|||
import org.eclipse.jetty.io.ssl.SslConnection;
|
||||
import org.eclipse.jetty.io.ssl.SslConnection.DecryptedEndPoint;
|
||||
import org.eclipse.jetty.spdy.FlowControlStrategy;
|
||||
import org.eclipse.jetty.spdy.api.GoAwayInfo;
|
||||
import org.eclipse.jetty.spdy.api.Session;
|
||||
import org.eclipse.jetty.spdy.api.SessionFrameListener;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.FuturePromise;
|
||||
import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
|
@ -265,7 +267,7 @@ public class SPDYClient
|
|||
private void closeConnections()
|
||||
{
|
||||
for (Session session : sessions)
|
||||
session.goAway();
|
||||
session.goAway(new GoAwayInfo(), new Callback.Adapter());
|
||||
sessions.clear();
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ import org.eclipse.jetty.io.RuntimeIOException;
|
|||
import org.eclipse.jetty.spdy.Controller;
|
||||
import org.eclipse.jetty.spdy.ISession;
|
||||
import org.eclipse.jetty.spdy.IdleListener;
|
||||
import org.eclipse.jetty.spdy.api.GoAwayInfo;
|
||||
import org.eclipse.jetty.spdy.parser.Parser;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
|
@ -46,10 +47,10 @@ public class SPDYConnection extends AbstractConnection implements Controller, Id
|
|||
|
||||
public SPDYConnection(EndPoint endPoint, ByteBufferPool bufferPool, Parser parser, Executor executor)
|
||||
{
|
||||
this(endPoint,bufferPool,parser,executor,8192);
|
||||
this(endPoint, bufferPool, parser, executor, 8192);
|
||||
}
|
||||
|
||||
public SPDYConnection(EndPoint endPoint, ByteBufferPool bufferPool, Parser parser, Executor executor,int bufferSize)
|
||||
public SPDYConnection(EndPoint endPoint, ByteBufferPool bufferPool, Parser parser, Executor executor, int bufferSize)
|
||||
{
|
||||
// Since SPDY is multiplexed, onFillable() must never block
|
||||
// while calling application code. In fact, onFillable()
|
||||
|
@ -60,7 +61,7 @@ public class SPDYConnection extends AbstractConnection implements Controller, Id
|
|||
this.bufferPool = bufferPool;
|
||||
this.parser = parser;
|
||||
onIdle(true);
|
||||
this.bufferSize=bufferSize;
|
||||
this.bufferSize = bufferSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -165,7 +166,7 @@ public class SPDYConnection extends AbstractConnection implements Controller, Id
|
|||
protected void goAway(ISession session)
|
||||
{
|
||||
if (session != null)
|
||||
session.goAway();
|
||||
session.goAway(new GoAwayInfo(), new Callback.Adapter());
|
||||
}
|
||||
|
||||
private void shutdown(ISession session)
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
package org.eclipse.jetty.spdy;
|
||||
|
||||
import org.eclipse.jetty.spdy.api.PushInfo;
|
||||
import org.eclipse.jetty.spdy.api.SynInfo;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -30,8 +31,8 @@ public class PushSynInfo extends SynInfo
|
|||
|
||||
private int associatedStreamId;
|
||||
|
||||
public PushSynInfo(int associatedStreamId, SynInfo synInfo){
|
||||
super(synInfo.getHeaders(), synInfo.isClose(), synInfo.getPriority());
|
||||
public PushSynInfo(int associatedStreamId, PushInfo pushInfo){
|
||||
super(pushInfo.getHeaders(), pushInfo.isClose());
|
||||
this.associatedStreamId = associatedStreamId;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,9 +33,10 @@ import java.util.Set;
|
|||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
|
@ -44,7 +45,9 @@ import org.eclipse.jetty.io.EndPoint;
|
|||
import org.eclipse.jetty.spdy.api.ByteBufferDataInfo;
|
||||
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;
|
||||
import org.eclipse.jetty.spdy.api.RstInfo;
|
||||
import org.eclipse.jetty.spdy.api.SPDYException;
|
||||
import org.eclipse.jetty.spdy.api.Session;
|
||||
|
@ -148,15 +151,18 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
|
|||
}
|
||||
|
||||
@Override
|
||||
public Future<Stream> syn(SynInfo synInfo, StreamFrameListener listener)
|
||||
public Stream syn(SynInfo synInfo, StreamFrameListener listener) throws ExecutionException, InterruptedException, TimeoutException
|
||||
{
|
||||
FuturePromise<Stream> result = new FuturePromise<>();
|
||||
syn(synInfo,listener,0,TimeUnit.MILLISECONDS,result);
|
||||
return result;
|
||||
syn(synInfo, listener, result);
|
||||
if (synInfo.getTimeout() > 0)
|
||||
return result.get(synInfo.getTimeout(), synInfo.getUnit());
|
||||
else
|
||||
return result.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void syn(SynInfo synInfo, StreamFrameListener listener, long timeout, TimeUnit unit, Promise<Stream> promise)
|
||||
public void syn(SynInfo synInfo, StreamFrameListener listener, Promise<Stream> promise)
|
||||
{
|
||||
// Synchronization is necessary.
|
||||
// SPEC v3, 2.3.1 requires that the stream creation be monotonically crescent
|
||||
|
@ -174,21 +180,24 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
|
|||
// TODO: for SPDYv3 we need to support the "slot" argument
|
||||
SynStreamFrame synStream = new SynStreamFrame(version, synInfo.getFlags(), streamId, associatedStreamId, synInfo.getPriority(), (short)0, synInfo.getHeaders());
|
||||
IStream stream = createStream(synStream, listener, true, promise);
|
||||
generateAndEnqueueControlFrame(stream, synStream, timeout, unit, stream);
|
||||
generateAndEnqueueControlFrame(stream, synStream, synInfo.getTimeout(), synInfo.getUnit(), stream);
|
||||
}
|
||||
flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Future<Void> rst(RstInfo rstInfo)
|
||||
public void rst(RstInfo rstInfo) throws InterruptedException, ExecutionException, TimeoutException
|
||||
{
|
||||
FutureCallback result = new FutureCallback();
|
||||
rst(rstInfo,0,TimeUnit.MILLISECONDS,result);
|
||||
return result;
|
||||
rst(rstInfo, result);
|
||||
if (rstInfo.getTimeout() > 0)
|
||||
result.get(rstInfo.getTimeout(), rstInfo.getUnit());
|
||||
else
|
||||
result.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rst(RstInfo rstInfo, long timeout, TimeUnit unit, Callback callback)
|
||||
public void rst(RstInfo rstInfo, Callback callback)
|
||||
{
|
||||
// SPEC v3, 2.2.2
|
||||
if (goAwaySent.get())
|
||||
|
@ -199,8 +208,8 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
|
|||
{
|
||||
int streamId = rstInfo.getStreamId();
|
||||
IStream stream = streams.get(streamId);
|
||||
RstStreamFrame frame = new RstStreamFrame(version,streamId,rstInfo.getStreamStatus().getCode(version));
|
||||
control(stream,frame,timeout,unit,callback);
|
||||
RstStreamFrame frame = new RstStreamFrame(version, streamId, rstInfo.getStreamStatus().getCode(version));
|
||||
control(stream, frame, rstInfo.getTimeout(), rstInfo.getUnit(), callback);
|
||||
if (stream != null)
|
||||
{
|
||||
stream.process(frame);
|
||||
|
@ -210,64 +219,74 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
|
|||
}
|
||||
|
||||
@Override
|
||||
public Future<Void> settings(SettingsInfo settingsInfo)
|
||||
public void settings(SettingsInfo settingsInfo) throws ExecutionException, InterruptedException, TimeoutException
|
||||
{
|
||||
FutureCallback result = new FutureCallback();
|
||||
settings(settingsInfo, 0, TimeUnit.MILLISECONDS, result);
|
||||
return result;
|
||||
settings(settingsInfo, result);
|
||||
if (settingsInfo.getTimeout() > 0)
|
||||
result.get(settingsInfo.getTimeout(), settingsInfo.getUnit());
|
||||
else
|
||||
result.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void settings(SettingsInfo settingsInfo, long timeout, TimeUnit unit, Callback callback)
|
||||
public void settings(SettingsInfo settingsInfo, Callback callback)
|
||||
{
|
||||
SettingsFrame frame = new SettingsFrame(version,settingsInfo.getFlags(),settingsInfo.getSettings());
|
||||
control(null, frame, timeout, unit, callback);
|
||||
SettingsFrame frame = new SettingsFrame(version, settingsInfo.getFlags(), settingsInfo.getSettings());
|
||||
control(null, frame, settingsInfo.getTimeout(), settingsInfo.getUnit(), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Future<PingInfo> ping()
|
||||
public PingResultInfo ping(PingInfo pingInfo) throws ExecutionException, InterruptedException, TimeoutException
|
||||
{
|
||||
FuturePromise<PingInfo> result = new FuturePromise<>();
|
||||
ping(0, TimeUnit.MILLISECONDS, result);
|
||||
return result;
|
||||
//TODO: find a better name for PingResultInfo
|
||||
FuturePromise<PingResultInfo> result = new FuturePromise<>();
|
||||
ping(pingInfo, result);
|
||||
if (pingInfo.getTimeout() > 0)
|
||||
return result.get(pingInfo.getTimeout(), pingInfo.getUnit());
|
||||
else
|
||||
return result.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ping(long timeout, TimeUnit unit, Promise<PingInfo> promise)
|
||||
public void ping(PingInfo pingInfo, Promise<PingResultInfo> promise)
|
||||
{
|
||||
int pingId = pingIds.getAndAdd(2);
|
||||
PingInfoCallback pingInfo = new PingInfoCallback(pingId, promise);
|
||||
PingInfoCallback pingInfoCallback = new PingInfoCallback(pingId, promise);
|
||||
PingFrame frame = new PingFrame(version, pingId);
|
||||
control(null, frame, timeout, unit, pingInfo);
|
||||
control(null, frame, pingInfo.getTimeout(), pingInfo.getUnit(), pingInfoCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Future<Void> goAway()
|
||||
public void goAway(GoAwayInfo goAwayInfo) throws ExecutionException, InterruptedException, TimeoutException
|
||||
{
|
||||
return goAway(SessionStatus.OK);
|
||||
goAway(goAwayInfo, SessionStatus.OK);
|
||||
}
|
||||
|
||||
private Future<Void> goAway(SessionStatus sessionStatus)
|
||||
private void goAway(GoAwayInfo goAwayInfo, SessionStatus sessionStatus) throws ExecutionException, InterruptedException, TimeoutException
|
||||
{
|
||||
FutureCallback result = new FutureCallback();
|
||||
goAway(sessionStatus, 0, TimeUnit.MILLISECONDS, result);
|
||||
return result;
|
||||
goAway(sessionStatus, goAwayInfo.getTimeout(), goAwayInfo.getUnit(), result);
|
||||
if (goAwayInfo.getTimeout() > 0)
|
||||
result.get(goAwayInfo.getTimeout(), goAwayInfo.getUnit());
|
||||
else
|
||||
result.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void goAway(long timeout, TimeUnit unit, Callback callback)
|
||||
public void goAway(GoAwayInfo goAwayInfo, Callback callback)
|
||||
{
|
||||
goAway(SessionStatus.OK, timeout, unit, callback);
|
||||
goAway(SessionStatus.OK, goAwayInfo.getTimeout(), goAwayInfo.getUnit(), callback);
|
||||
}
|
||||
|
||||
private void goAway(SessionStatus sessionStatus, long timeout, TimeUnit unit, Callback callback)
|
||||
{
|
||||
if (goAwaySent.compareAndSet(false,true))
|
||||
if (goAwaySent.compareAndSet(false, true))
|
||||
{
|
||||
if (!goAwayReceived.get())
|
||||
{
|
||||
GoAwayFrame frame = new GoAwayFrame(version,lastStreamId.get(),sessionStatus.getCode());
|
||||
control(null,frame,timeout,unit,callback);
|
||||
GoAwayFrame frame = new GoAwayFrame(version, lastStreamId.get(), sessionStatus.getCode());
|
||||
control(null, frame, timeout, unit, callback);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -416,7 +435,7 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
|
|||
{
|
||||
RstInfo rstInfo = new RstInfo(streamId, StreamStatus.INVALID_STREAM);
|
||||
LOG.debug("Unknown stream {}", rstInfo);
|
||||
rst(rstInfo);
|
||||
rst(rstInfo, new Callback.Adapter());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -437,7 +456,7 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
|
|||
|
||||
private void processData(final IStream stream, DataFrame frame, ByteBuffer data)
|
||||
{
|
||||
ByteBufferDataInfo dataInfo = new ByteBufferDataInfo(data, frame.isClose(), frame.isCompress())
|
||||
ByteBufferDataInfo dataInfo = new ByteBufferDataInfo(data, frame.isClose())
|
||||
{
|
||||
@Override
|
||||
public void consume(int delta)
|
||||
|
@ -456,15 +475,15 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
|
|||
public void onStreamException(StreamException x)
|
||||
{
|
||||
notifyOnException(listener, x);
|
||||
rst(new RstInfo(x.getStreamId(),x.getStreamStatus()));
|
||||
rst(new RstInfo(x.getStreamId(), x.getStreamStatus()), new Callback.Adapter());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSessionException(SessionException x)
|
||||
{
|
||||
Throwable cause = x.getCause();
|
||||
notifyOnException(listener,cause == null?x:cause);
|
||||
goAway(x.getSessionStatus());
|
||||
notifyOnException(listener, cause == null ? x : cause);
|
||||
goAway(x.getSessionStatus(), 0, TimeUnit.SECONDS, new Callback.Adapter());
|
||||
}
|
||||
|
||||
private void onSyn(SynStreamFrame frame)
|
||||
|
@ -479,8 +498,8 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
|
|||
stream.process(frame);
|
||||
// Update the last stream id before calling the application (which may send a GO_AWAY)
|
||||
updateLastStreamId(stream);
|
||||
SynInfo synInfo = new SynInfo(frame.getHeaders(),frame.isClose(),frame.getPriority());
|
||||
StreamFrameListener streamListener = notifyOnSyn(listener,stream,synInfo);
|
||||
SynInfo synInfo = new SynInfo(frame.getHeaders(), frame.isClose(), frame.getPriority());
|
||||
StreamFrameListener streamListener = notifyOnSyn(listener, stream, synInfo);
|
||||
stream.setStreamFrameListener(streamListener);
|
||||
flush();
|
||||
// The onSyn() listener may have sent a frame that closed the stream
|
||||
|
@ -512,7 +531,14 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
|
|||
throw new IllegalStateException("Duplicate stream id " + streamId);
|
||||
RstInfo rstInfo = new RstInfo(streamId, StreamStatus.PROTOCOL_ERROR);
|
||||
LOG.debug("Duplicate stream, {}", rstInfo);
|
||||
rst(rstInfo);
|
||||
try
|
||||
{
|
||||
rst(rstInfo);
|
||||
}
|
||||
catch (InterruptedException | ExecutionException | TimeoutException e)
|
||||
{
|
||||
e.printStackTrace(); // TODO: really catch???
|
||||
}
|
||||
return null;
|
||||
}
|
||||
else
|
||||
|
@ -589,13 +615,13 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
|
|||
IStream stream = streams.get(streamId);
|
||||
if (stream == null)
|
||||
{
|
||||
RstInfo rstInfo = new RstInfo(streamId,StreamStatus.INVALID_STREAM);
|
||||
LOG.debug("Unknown stream {}",rstInfo);
|
||||
rst(rstInfo);
|
||||
RstInfo rstInfo = new RstInfo(streamId, StreamStatus.INVALID_STREAM);
|
||||
LOG.debug("Unknown stream {}", rstInfo);
|
||||
rst(rstInfo, new Callback.Adapter());
|
||||
}
|
||||
else
|
||||
{
|
||||
processReply(stream,frame);
|
||||
processReply(stream, frame);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -613,7 +639,7 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
|
|||
if (stream != null)
|
||||
stream.process(frame);
|
||||
|
||||
RstInfo rstInfo = new RstInfo(frame.getStreamId(),StreamStatus.from(frame.getVersion(),frame.getStatusCode()));
|
||||
RstInfo rstInfo = new RstInfo(frame.getStreamId(), StreamStatus.from(frame.getVersion(), frame.getStatusCode()));
|
||||
notifyOnRst(listener, rstInfo);
|
||||
flush();
|
||||
|
||||
|
@ -640,8 +666,8 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
|
|||
int pingId = frame.getPingId();
|
||||
if (pingId % 2 == pingIds.get() % 2)
|
||||
{
|
||||
PingInfo pingInfo = new PingInfo(frame.getPingId());
|
||||
notifyOnPing(listener, pingInfo);
|
||||
PingResultInfo pingResultInfo = new PingResultInfo(frame.getPingId());
|
||||
notifyOnPing(listener, pingResultInfo);
|
||||
flush();
|
||||
}
|
||||
else
|
||||
|
@ -654,8 +680,9 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
|
|||
{
|
||||
if (goAwayReceived.compareAndSet(false, true))
|
||||
{
|
||||
GoAwayInfo goAwayInfo = new GoAwayInfo(frame.getLastStreamId(),SessionStatus.from(frame.getStatusCode()));
|
||||
notifyOnGoAway(listener,goAwayInfo);
|
||||
//TODO: Find a better name for GoAwayReceivedInfo
|
||||
GoAwayReceivedInfo goAwayReceivedInfo = new GoAwayReceivedInfo(frame.getLastStreamId(), SessionStatus.from(frame.getStatusCode()));
|
||||
notifyOnGoAway(listener, goAwayReceivedInfo);
|
||||
flush();
|
||||
// SPDY does not require to send back a response to a GO_AWAY.
|
||||
// We notified the application of the last good stream id and
|
||||
|
@ -669,13 +696,13 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
|
|||
IStream stream = streams.get(streamId);
|
||||
if (stream == null)
|
||||
{
|
||||
RstInfo rstInfo = new RstInfo(streamId,StreamStatus.INVALID_STREAM);
|
||||
LOG.debug("Unknown stream, {}",rstInfo);
|
||||
rst(rstInfo);
|
||||
RstInfo rstInfo = new RstInfo(streamId, StreamStatus.INVALID_STREAM);
|
||||
LOG.debug("Unknown stream, {}", rstInfo);
|
||||
rst(rstInfo, new Callback.Adapter());
|
||||
}
|
||||
else
|
||||
{
|
||||
processHeaders(stream,frame);
|
||||
processHeaders(stream, frame);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -713,7 +740,7 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
|
|||
{
|
||||
if (listener != null)
|
||||
{
|
||||
LOG.debug("Invoking callback with {} on listener {}",x,listener);
|
||||
LOG.debug("Invoking callback with {} on listener {}", x, listener);
|
||||
listener.onException(x);
|
||||
}
|
||||
}
|
||||
|
@ -734,12 +761,12 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
|
|||
{
|
||||
if (listener == null)
|
||||
return null;
|
||||
LOG.debug("Invoking callback with {} on listener {}",synInfo,listener);
|
||||
return listener.onSyn(stream,synInfo);
|
||||
LOG.debug("Invoking callback with {} on listener {}", synInfo, listener);
|
||||
return listener.onSyn(stream, synInfo);
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
LOG.info("Exception while notifying listener " + listener,x);
|
||||
LOG.info("Exception while notifying listener " + listener, x);
|
||||
return null;
|
||||
}
|
||||
catch (Error x)
|
||||
|
@ -755,8 +782,8 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
|
|||
{
|
||||
if (listener != null)
|
||||
{
|
||||
LOG.debug("Invoking callback with {} on listener {}",rstInfo,listener);
|
||||
listener.onRst(this,rstInfo);
|
||||
LOG.debug("Invoking callback with {} on listener {}", rstInfo, listener);
|
||||
listener.onRst(this, rstInfo);
|
||||
}
|
||||
}
|
||||
catch (Exception x)
|
||||
|
@ -776,7 +803,7 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
|
|||
{
|
||||
if (listener != null)
|
||||
{
|
||||
LOG.debug("Invoking callback with {} on listener {}",settingsInfo,listener);
|
||||
LOG.debug("Invoking callback with {} on listener {}", settingsInfo, listener);
|
||||
listener.onSettings(this, settingsInfo);
|
||||
}
|
||||
}
|
||||
|
@ -791,14 +818,14 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
|
|||
}
|
||||
}
|
||||
|
||||
private void notifyOnPing(SessionFrameListener listener, PingInfo pingInfo)
|
||||
private void notifyOnPing(SessionFrameListener listener, PingResultInfo pingResultInfo)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (listener != null)
|
||||
{
|
||||
LOG.debug("Invoking callback with {} on listener {}",pingInfo,listener);
|
||||
listener.onPing(this, pingInfo);
|
||||
LOG.debug("Invoking callback with {} on listener {}", pingResultInfo, listener);
|
||||
listener.onPing(this, pingResultInfo);
|
||||
}
|
||||
}
|
||||
catch (Exception x)
|
||||
|
@ -812,14 +839,14 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
|
|||
}
|
||||
}
|
||||
|
||||
private void notifyOnGoAway(SessionFrameListener listener, GoAwayInfo goAwayInfo)
|
||||
private void notifyOnGoAway(SessionFrameListener listener, GoAwayReceivedInfo goAwayReceivedInfo)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (listener != null)
|
||||
{
|
||||
LOG.debug("Invoking callback with {} on listener {}",goAwayInfo,listener);
|
||||
listener.onGoAway(this, goAwayInfo);
|
||||
LOG.debug("Invoking callback with {} on listener {}", goAwayReceivedInfo, listener);
|
||||
listener.onGoAway(this, goAwayReceivedInfo);
|
||||
}
|
||||
}
|
||||
catch (Exception x)
|
||||
|
@ -879,10 +906,10 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
|
|||
@Override
|
||||
public void data(IStream stream, DataInfo dataInfo, long timeout, TimeUnit unit, Callback callback)
|
||||
{
|
||||
LOG.debug("Queuing {} on {}",dataInfo,stream);
|
||||
DataFrameBytes frameBytes = new DataFrameBytes(stream,callback,dataInfo);
|
||||
LOG.debug("Queuing {} on {}", dataInfo, stream);
|
||||
DataFrameBytes frameBytes = new DataFrameBytes(stream, callback, dataInfo);
|
||||
if (timeout > 0)
|
||||
frameBytes.task = scheduler.schedule(frameBytes,timeout,unit);
|
||||
frameBytes.task = scheduler.schedule(frameBytes, timeout, unit);
|
||||
append(frameBytes);
|
||||
flush();
|
||||
}
|
||||
|
@ -909,7 +936,7 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
|
|||
{
|
||||
if (flushing || queue.isEmpty())
|
||||
return;
|
||||
|
||||
|
||||
Set<IStream> stalledStreams = null;
|
||||
for (int i = 0; i < queue.size(); ++i)
|
||||
{
|
||||
|
@ -937,14 +964,14 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
|
|||
if (stream != null)
|
||||
stalledStreams.add(stream);
|
||||
|
||||
LOG.debug("Flush stalled for {}, {} frame(s) in queue",frameBytes,queue.size());
|
||||
LOG.debug("Flush stalled for {}, {} frame(s) in queue", frameBytes, queue.size());
|
||||
}
|
||||
|
||||
if (buffer == null)
|
||||
return;
|
||||
|
||||
flushing = true;
|
||||
LOG.debug("Flushing {}, {} frame(s) in queue",frameBytes,queue.size());
|
||||
LOG.debug("Flushing {}, {} frame(s) in queue", frameBytes, queue.size());
|
||||
}
|
||||
write(buffer, frameBytes);
|
||||
}
|
||||
|
@ -996,7 +1023,7 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
|
|||
break;
|
||||
++index;
|
||||
}
|
||||
queue.add(index,frameBytes);
|
||||
queue.add(index, frameBytes);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1008,8 +1035,8 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
|
|||
{
|
||||
if (controller != null)
|
||||
{
|
||||
LOG.debug("Writing {} frame bytes of {}",buffer.remaining());
|
||||
controller.write(buffer,callback);
|
||||
LOG.debug("Writing {} frame bytes of {}", buffer.remaining(), buffer.limit());
|
||||
controller.write(buffer, callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1053,7 +1080,8 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
|
|||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("%s@%x{v%d,queuSize=%d,windowSize=%d,streams=%d}", getClass().getSimpleName(), hashCode(), version, queue.size(), getWindowSize(), streams.size());
|
||||
return String.format("%s@%x{v%d,queueSize=%d,windowSize=%d,streams=%d}", getClass().getSimpleName(),
|
||||
hashCode(), version, queue.size(), getWindowSize(), streams.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1065,8 +1093,8 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
|
|||
@Override
|
||||
public void dump(Appendable out, String indent) throws IOException
|
||||
{
|
||||
ContainerLifeCycle.dumpObject(out,this);
|
||||
ContainerLifeCycle.dump(out,indent,Collections.singletonList(controller),streams.values());
|
||||
ContainerLifeCycle.dumpObject(out, this);
|
||||
ContainerLifeCycle.dump(out, indent, Collections.singletonList(controller), streams.values());
|
||||
}
|
||||
|
||||
private class SessionInvoker extends ForkInvoker<Callback>
|
||||
|
@ -1177,7 +1205,7 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
|
|||
synchronized (queue)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Completed write of {}, {} frame(s) in queue",this,queue.size());
|
||||
LOG.debug("Completed write of {}, {} frame(s) in queue", this, queue.size());
|
||||
flushing = false;
|
||||
}
|
||||
complete();
|
||||
|
@ -1194,8 +1222,8 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
|
|||
failure = x;
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
String logMessage = String.format("Failed write of %s, failing all %d frame(s) in queue",this,queue.size());
|
||||
LOG.debug(logMessage,x);
|
||||
String logMessage = String.format("Failed write of %s, failing all %d frame(s) in queue", this, queue.size());
|
||||
LOG.debug(logMessage, x);
|
||||
}
|
||||
frameBytesToFail.addAll(queue);
|
||||
queue.clear();
|
||||
|
@ -1214,7 +1242,7 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
|
|||
|
||||
private ControlFrameBytes(IStream stream, Callback callback, ControlFrame frame, ByteBuffer buffer)
|
||||
{
|
||||
super(stream,callback);
|
||||
super(stream, callback);
|
||||
this.frame = frame;
|
||||
this.buffer = buffer;
|
||||
}
|
||||
|
@ -1276,7 +1304,7 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
|
|||
if (size > windowSize)
|
||||
size = windowSize;
|
||||
|
||||
buffer = generator.data(stream.getId(),size,dataInfo);
|
||||
buffer = generator.data(stream.getId(), size, dataInfo);
|
||||
return buffer;
|
||||
}
|
||||
catch (Throwable x)
|
||||
|
@ -1303,7 +1331,7 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
|
|||
else
|
||||
{
|
||||
super.complete();
|
||||
stream.updateCloseState(dataInfo.isClose(),true);
|
||||
stream.updateCloseState(dataInfo.isClose(), true);
|
||||
if (stream.isClosed())
|
||||
removeStream(stream);
|
||||
}
|
||||
|
@ -1337,14 +1365,14 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
|
|||
}
|
||||
}
|
||||
|
||||
private static class PingInfoCallback extends PingInfo implements Callback
|
||||
private static class PingInfoCallback extends PingResultInfo implements Callback
|
||||
{
|
||||
private final Promise<PingInfo> promise;
|
||||
private final Promise<PingResultInfo> promise;
|
||||
|
||||
public PingInfoCallback(int pingId, Promise<PingInfo> promise)
|
||||
public PingInfoCallback(int pingId, Promise<PingResultInfo> promise)
|
||||
{
|
||||
super(pingId);
|
||||
this.promise=promise;
|
||||
this.promise = promise;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -22,18 +22,18 @@ import java.util.Collections;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.eclipse.jetty.spdy.api.DataInfo;
|
||||
import org.eclipse.jetty.spdy.api.HeadersInfo;
|
||||
import org.eclipse.jetty.spdy.api.PushInfo;
|
||||
import org.eclipse.jetty.spdy.api.ReplyInfo;
|
||||
import org.eclipse.jetty.spdy.api.RstInfo;
|
||||
import org.eclipse.jetty.spdy.api.Stream;
|
||||
import org.eclipse.jetty.spdy.api.StreamFrameListener;
|
||||
import org.eclipse.jetty.spdy.api.StreamStatus;
|
||||
import org.eclipse.jetty.spdy.api.SynInfo;
|
||||
import org.eclipse.jetty.spdy.frames.ControlFrame;
|
||||
import org.eclipse.jetty.spdy.frames.HeadersFrame;
|
||||
import org.eclipse.jetty.spdy.frames.SynReplyFrame;
|
||||
|
@ -133,7 +133,7 @@ public class StandardStream implements IStream
|
|||
@Override
|
||||
public void setAttribute(String key, Object value)
|
||||
{
|
||||
attributes.put(key,value);
|
||||
attributes.put(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -156,7 +156,7 @@ public class StandardStream implements IStream
|
|||
@Override
|
||||
public void updateCloseState(boolean close, boolean local)
|
||||
{
|
||||
LOG.debug("{} close={} local={}",this,close,local);
|
||||
LOG.debug("{} close={} local={}", this, close, local);
|
||||
if (close)
|
||||
{
|
||||
switch (closeState)
|
||||
|
@ -184,7 +184,7 @@ public class StandardStream implements IStream
|
|||
}
|
||||
default:
|
||||
{
|
||||
LOG.warn("Already CLOSED! {} local={}",this,local);
|
||||
LOG.warn("Already CLOSED! {} local={}", this, local);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -243,8 +243,8 @@ public class StandardStream implements IStream
|
|||
|
||||
if (!canReceive())
|
||||
{
|
||||
LOG.debug("Protocol error receiving {}, resetting" + dataInfo);
|
||||
session.rst(new RstInfo(getId(), StreamStatus.PROTOCOL_ERROR));
|
||||
LOG.debug("Protocol error receiving {}, resetting", dataInfo);
|
||||
session.rst(new RstInfo(getId(), StreamStatus.PROTOCOL_ERROR), new Adapter());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -335,15 +335,18 @@ public class StandardStream implements IStream
|
|||
}
|
||||
|
||||
@Override
|
||||
public Future<Stream> syn(SynInfo synInfo)
|
||||
public Stream push(PushInfo pushInfo) throws InterruptedException, ExecutionException, TimeoutException
|
||||
{
|
||||
FuturePromise<Stream> result = new FuturePromise<>();
|
||||
syn(synInfo,0,TimeUnit.MILLISECONDS,result);
|
||||
return result;
|
||||
push(pushInfo, result);
|
||||
if (pushInfo.getTimeout() > 0)
|
||||
return result.get(pushInfo.getTimeout(), pushInfo.getUnit());
|
||||
else
|
||||
return result.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void syn(SynInfo synInfo, long timeout, TimeUnit unit, Promise<Stream> promise)
|
||||
public void push(PushInfo pushInfo, Promise<Stream> promise)
|
||||
{
|
||||
if (isClosed() || isReset())
|
||||
{
|
||||
|
@ -351,81 +354,90 @@ public class StandardStream implements IStream
|
|||
"Stream: " + this + " already closed or reset!"));
|
||||
return;
|
||||
}
|
||||
PushSynInfo pushSynInfo = new PushSynInfo(getId(), synInfo);
|
||||
session.syn(pushSynInfo, null, timeout, unit, promise);
|
||||
PushSynInfo pushSynInfo = new PushSynInfo(getId(), pushInfo);
|
||||
session.syn(pushSynInfo, null, promise);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Future<Void> reply(ReplyInfo replyInfo)
|
||||
public void reply(ReplyInfo replyInfo) throws InterruptedException, ExecutionException, TimeoutException
|
||||
{
|
||||
FutureCallback result = new FutureCallback();
|
||||
reply(replyInfo, 0, TimeUnit.MILLISECONDS, result);
|
||||
return result;
|
||||
reply(replyInfo, result);
|
||||
if (replyInfo.getTimeout() > 0)
|
||||
result.get(replyInfo.getTimeout(), replyInfo.getUnit());
|
||||
else
|
||||
result.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reply(ReplyInfo replyInfo, long timeout, TimeUnit unit, Callback callback)
|
||||
public void reply(ReplyInfo replyInfo, Callback callback)
|
||||
{
|
||||
if (isUnidirectional())
|
||||
throw new IllegalStateException("Protocol violation: cannot send SYN_REPLY frames in unidirectional streams");
|
||||
openState = OpenState.REPLY_SENT;
|
||||
updateCloseState(replyInfo.isClose(), true);
|
||||
SynReplyFrame frame = new SynReplyFrame(session.getVersion(), replyInfo.getFlags(), getId(), replyInfo.getHeaders());
|
||||
session.control(this, frame, timeout, unit, callback);
|
||||
session.control(this, frame, replyInfo.getTimeout(), replyInfo.getUnit(), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Future<Void> data(DataInfo dataInfo)
|
||||
public void data(DataInfo dataInfo) throws InterruptedException, ExecutionException, TimeoutException
|
||||
{
|
||||
FutureCallback result = new FutureCallback();
|
||||
data(dataInfo, 0, TimeUnit.MILLISECONDS, result);
|
||||
return result;
|
||||
data(dataInfo, result);
|
||||
if (dataInfo.getTimeout() > 0)
|
||||
result.get(dataInfo.getTimeout(), dataInfo.getUnit());
|
||||
else
|
||||
result.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void data(DataInfo dataInfo, long timeout, TimeUnit unit, Callback callback)
|
||||
public void data(DataInfo dataInfo, Callback callback)
|
||||
{
|
||||
if (!canSend())
|
||||
{
|
||||
session.rst(new RstInfo(getId(), StreamStatus.PROTOCOL_ERROR));
|
||||
session.rst(new RstInfo(getId(), StreamStatus.PROTOCOL_ERROR), new Adapter());
|
||||
throw new IllegalStateException("Protocol violation: cannot send a DATA frame before a SYN_REPLY frame");
|
||||
}
|
||||
if (isLocallyClosed())
|
||||
{
|
||||
session.rst(new RstInfo(getId(), StreamStatus.PROTOCOL_ERROR));
|
||||
session.rst(new RstInfo(getId(), StreamStatus.PROTOCOL_ERROR), new Adapter());
|
||||
throw new IllegalStateException("Protocol violation: cannot send a DATA frame on a closed stream");
|
||||
}
|
||||
|
||||
// Cannot update the close state here, because the data that we send may
|
||||
// be flow controlled, so we need the stream to update the window size.
|
||||
session.data(this, dataInfo, timeout, unit, callback);
|
||||
session.data(this, dataInfo, dataInfo.getTimeout(), dataInfo.getUnit(), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Future<Void> headers(HeadersInfo headersInfo)
|
||||
public void headers(HeadersInfo headersInfo) throws InterruptedException, ExecutionException, TimeoutException
|
||||
{
|
||||
FutureCallback result = new FutureCallback();
|
||||
headers(headersInfo, 0, TimeUnit.MILLISECONDS, result);
|
||||
return result;
|
||||
headers(headersInfo, result);
|
||||
if (headersInfo.getTimeout() > 0)
|
||||
result.get(headersInfo.getTimeout(), headersInfo.getUnit());
|
||||
else
|
||||
result.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void headers(HeadersInfo headersInfo, long timeout, TimeUnit unit, Callback callback)
|
||||
public void headers(HeadersInfo headersInfo, Callback callback)
|
||||
{
|
||||
if (!canSend())
|
||||
{
|
||||
session.rst(new RstInfo(getId(), StreamStatus.PROTOCOL_ERROR));
|
||||
session.rst(new RstInfo(getId(), StreamStatus.PROTOCOL_ERROR), new Adapter());
|
||||
throw new IllegalStateException("Protocol violation: cannot send a HEADERS frame before a SYN_REPLY frame");
|
||||
}
|
||||
if (isLocallyClosed())
|
||||
{
|
||||
session.rst(new RstInfo(getId(), StreamStatus.PROTOCOL_ERROR));
|
||||
session.rst(new RstInfo(getId(), StreamStatus.PROTOCOL_ERROR), new Adapter());
|
||||
throw new IllegalStateException("Protocol violation: cannot send a HEADERS frame on a closed stream");
|
||||
}
|
||||
|
||||
updateCloseState(headersInfo.isClose(), true);
|
||||
HeadersFrame frame = new HeadersFrame(session.getVersion(), headersInfo.getFlags(), getId(), headersInfo.getHeaders());
|
||||
session.control(this, frame, timeout, unit, callback);
|
||||
session.control(this, frame, headersInfo.getTimeout(), headersInfo.getUnit(), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
package org.eclipse.jetty.spdy.api;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* <p>Specialized {@link DataInfo} for {@link ByteBuffer} content.</p>
|
||||
|
@ -30,12 +31,12 @@ public class ByteBufferDataInfo extends DataInfo
|
|||
|
||||
public ByteBufferDataInfo(ByteBuffer buffer, boolean close)
|
||||
{
|
||||
this(buffer, close, false);
|
||||
this(0, TimeUnit.SECONDS, buffer, close);
|
||||
}
|
||||
|
||||
public ByteBufferDataInfo(ByteBuffer buffer, boolean close, boolean compress)
|
||||
public ByteBufferDataInfo(long timeout, TimeUnit unit, ByteBuffer buffer, boolean close)
|
||||
{
|
||||
super(close, compress);
|
||||
super(timeout, unit, close);
|
||||
this.buffer = buffer;
|
||||
this.length = buffer.remaining();
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
package org.eclipse.jetty.spdy.api;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* <p>Specialized {@link DataInfo} for byte array content.</p>
|
||||
|
@ -32,12 +33,17 @@ public class BytesDataInfo extends DataInfo
|
|||
|
||||
public BytesDataInfo(byte[] bytes, boolean close)
|
||||
{
|
||||
this(bytes, 0, bytes.length, close);
|
||||
this(0, TimeUnit.SECONDS, bytes, close);
|
||||
}
|
||||
|
||||
public BytesDataInfo(byte[] bytes, int offset, int length, boolean close)
|
||||
public BytesDataInfo(long timeout, TimeUnit unit, byte[] bytes, boolean close)
|
||||
{
|
||||
super(close, false);
|
||||
this(timeout, unit, bytes, 0, bytes.length, close);
|
||||
}
|
||||
|
||||
public BytesDataInfo(long timeout, TimeUnit unit, byte[] bytes, int offset, int length, boolean close)
|
||||
{
|
||||
super(timeout, unit, close);
|
||||
this.bytes = bytes;
|
||||
this.offset = offset;
|
||||
this.length = length;
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.eclipse.jetty.spdy.api;
|
|||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
|
@ -41,7 +42,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||
* <p>Consuming the data bytes can be done only via {@link #consumeInto(ByteBuffer)} or by a combination
|
||||
* of {@link #readInto(ByteBuffer)} and {@link #consume(int)} (possibly at different times).</p>
|
||||
*/
|
||||
public abstract class DataInfo
|
||||
public abstract class DataInfo extends Info
|
||||
{
|
||||
/**
|
||||
* <p>Flag that indicates that this {@link DataInfo} is the last frame in the stream.</p>
|
||||
|
@ -50,17 +51,9 @@ public abstract class DataInfo
|
|||
* @see #getFlags()
|
||||
*/
|
||||
public final static byte FLAG_CLOSE = 1;
|
||||
/**
|
||||
* <p>Flag that indicates that this {@link DataInfo}'s data is compressed.</p>
|
||||
*
|
||||
* @see #isCompress()
|
||||
* @see #getFlags()
|
||||
*/
|
||||
public final static byte FLAG_COMPRESS = 2;
|
||||
|
||||
private final AtomicInteger consumed = new AtomicInteger();
|
||||
private boolean close;
|
||||
private boolean compress;
|
||||
|
||||
/**
|
||||
* <p>Creates a new {@link DataInfo} with the given close flag and no compression flag.</p>
|
||||
|
@ -73,33 +66,16 @@ public abstract class DataInfo
|
|||
}
|
||||
|
||||
/**
|
||||
* <p>Creates a new {@link DataInfo} with the given close flag and given compression flag.</p>
|
||||
* <p>Creates a new {@link DataInfo} with the given close flag and no compression flag.</p>
|
||||
*
|
||||
* @param close the close flag
|
||||
* @param compress the compress flag
|
||||
* @param timeout
|
||||
* @param unit
|
||||
* @param close the value of the close flag
|
||||
*/
|
||||
public DataInfo(boolean close, boolean compress)
|
||||
protected DataInfo(long timeout, TimeUnit unit, boolean close)
|
||||
{
|
||||
setClose(close);
|
||||
setCompress(compress);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the value of the compress flag
|
||||
* @see #setCompress(boolean)
|
||||
*/
|
||||
public boolean isCompress()
|
||||
{
|
||||
return compress;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param compress the value of the compress flag
|
||||
* @see #isCompress()
|
||||
*/
|
||||
public void setCompress(boolean compress)
|
||||
{
|
||||
this.compress = compress;
|
||||
super(timeout, unit);
|
||||
this.close = close;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -123,13 +99,10 @@ public abstract class DataInfo
|
|||
/**
|
||||
* @return the close and compress flags as integer
|
||||
* @see #FLAG_CLOSE
|
||||
* @see #FLAG_COMPRESS
|
||||
*/
|
||||
public byte getFlags()
|
||||
{
|
||||
byte flags = isClose() ? FLAG_CLOSE : 0;
|
||||
flags |= isCompress() ? FLAG_COMPRESS : 0;
|
||||
return flags;
|
||||
return isClose() ? FLAG_CLOSE : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -275,6 +248,6 @@ public abstract class DataInfo
|
|||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("DATA @%x available=%d consumed=%d close=%b compress=%b", hashCode(), available(), consumed(), isClose(), isCompress());
|
||||
return String.format("DATA @%x available=%d consumed=%d close=%b", hashCode(), available(), consumed(), isClose());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,40 +18,21 @@
|
|||
|
||||
package org.eclipse.jetty.spdy.api;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* <p>A container for GOAWAY frames metadata: the last good stream id and
|
||||
* the session status.</p>
|
||||
* A GoAwayInfo container. Currently adding nothing to it's base class, but serves to keep the api unchanged in
|
||||
* future versions when we need to pass more info to the methods having a {@link GoAwayInfo} parameter.
|
||||
*/
|
||||
public class GoAwayInfo
|
||||
public class GoAwayInfo extends Info
|
||||
{
|
||||
private final int lastStreamId;
|
||||
private final SessionStatus sessionStatus;
|
||||
|
||||
/**
|
||||
* <p>Creates a new {@link GoAwayInfo} with the given last good stream id and session status</p>
|
||||
*
|
||||
* @param lastStreamId the last good stream id
|
||||
* @param sessionStatus the session status
|
||||
*/
|
||||
public GoAwayInfo(int lastStreamId, SessionStatus sessionStatus)
|
||||
public GoAwayInfo(long timeout, TimeUnit unit)
|
||||
{
|
||||
this.lastStreamId = lastStreamId;
|
||||
this.sessionStatus = sessionStatus;
|
||||
super(timeout, unit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the last good stream id
|
||||
*/
|
||||
public int getLastStreamId()
|
||||
public GoAwayInfo()
|
||||
{
|
||||
return lastStreamId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the session status
|
||||
*/
|
||||
public SessionStatus getSessionStatus()
|
||||
{
|
||||
return sessionStatus;
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2012 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.spdy.api;
|
||||
|
||||
/**
|
||||
* <p>A container for GOAWAY frames metadata: the last good stream id and
|
||||
* the session status.</p>
|
||||
*/
|
||||
public class GoAwayReceivedInfo
|
||||
{
|
||||
private final int lastStreamId;
|
||||
private final SessionStatus sessionStatus;
|
||||
|
||||
/**
|
||||
* <p>Creates a new {@link GoAwayReceivedInfo} with the given last good stream id and session status</p>
|
||||
*
|
||||
* @param lastStreamId the last good stream id
|
||||
* @param sessionStatus the session status
|
||||
*/
|
||||
public GoAwayReceivedInfo(int lastStreamId, SessionStatus sessionStatus)
|
||||
{
|
||||
this.lastStreamId = lastStreamId;
|
||||
this.sessionStatus = sessionStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the last good stream id
|
||||
*/
|
||||
public int getLastStreamId()
|
||||
{
|
||||
return lastStreamId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the session status
|
||||
*/
|
||||
public SessionStatus getSessionStatus()
|
||||
{
|
||||
return sessionStatus;
|
||||
}
|
||||
}
|
|
@ -18,12 +18,14 @@
|
|||
|
||||
package org.eclipse.jetty.spdy.api;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
|
||||
/**
|
||||
* <p>A container for HEADERS frame metadata and headers.</p>
|
||||
*/
|
||||
public class HeadersInfo
|
||||
public class HeadersInfo extends Info
|
||||
{
|
||||
/**
|
||||
* <p>Flag that indicates that this {@link HeadersInfo} is the last frame in the stream.</p>
|
||||
|
@ -45,11 +47,11 @@ public class HeadersInfo
|
|||
private final Fields headers;
|
||||
|
||||
/**
|
||||
* <p>Creates a new {@link HeadersInfo} instance with the given headers,
|
||||
* the given close flag and no reset compression flag</p>
|
||||
* <p>Creates a new {@link HeadersInfo} instance with the given headers, the given close flag and no reset
|
||||
* compression flag</p>
|
||||
*
|
||||
* @param headers the {@link Fields}
|
||||
* @param close the value of the close flag
|
||||
* @param close the value of the close flag
|
||||
*/
|
||||
public HeadersInfo(Fields headers, boolean close)
|
||||
{
|
||||
|
@ -57,11 +59,11 @@ public class HeadersInfo
|
|||
}
|
||||
|
||||
/**
|
||||
* <p>Creates a new {@link HeadersInfo} instance with the given headers,
|
||||
* the given close flag and the given reset compression flag</p>
|
||||
* <p>Creates a new {@link HeadersInfo} instance with the given headers, the given close flag and the given reset
|
||||
* compression flag</p>
|
||||
*
|
||||
* @param headers the {@link Fields}
|
||||
* @param close the value of the close flag
|
||||
* @param headers the {@link Fields}
|
||||
* @param close the value of the close flag
|
||||
* @param resetCompression the value of the reset compression flag
|
||||
*/
|
||||
public HeadersInfo(Fields headers, boolean close, boolean resetCompression)
|
||||
|
@ -71,6 +73,24 @@ public class HeadersInfo
|
|||
this.resetCompression = resetCompression;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Creates a new {@link HeadersInfo} instance with the given headers, the given close flag and the given reset
|
||||
* compression flag</p>
|
||||
*
|
||||
* @param timeout the operation's timeout
|
||||
* @param unit the timeout's unit
|
||||
* @param headers the {@link Fields}
|
||||
* @param close the value of the close flag
|
||||
* @param resetCompression the value of the reset compression flag
|
||||
*/
|
||||
public HeadersInfo(long timeout, TimeUnit unit, boolean close, boolean resetCompression, Fields headers)
|
||||
{
|
||||
super(timeout, unit);
|
||||
this.close = close;
|
||||
this.resetCompression = resetCompression;
|
||||
this.headers = headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the value of the close flag
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2012 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.spdy.api;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* A base class for all *Info classes providing timeout and unit and api to access them
|
||||
*/
|
||||
public class Info
|
||||
{
|
||||
private final long timeout;
|
||||
private final TimeUnit unit;
|
||||
|
||||
public Info(long timeout, TimeUnit unit)
|
||||
{
|
||||
this.timeout = timeout;
|
||||
this.unit = unit;
|
||||
}
|
||||
|
||||
public Info()
|
||||
{
|
||||
timeout = 0;
|
||||
unit = TimeUnit.SECONDS;
|
||||
}
|
||||
|
||||
public long getTimeout()
|
||||
{
|
||||
return timeout;
|
||||
}
|
||||
|
||||
public TimeUnit getUnit()
|
||||
{
|
||||
return unit;
|
||||
}
|
||||
}
|
|
@ -18,27 +18,21 @@
|
|||
|
||||
package org.eclipse.jetty.spdy.api;
|
||||
|
||||
/**
|
||||
* <p>A container for PING frames data.</p>
|
||||
*/
|
||||
public class PingInfo
|
||||
{
|
||||
private final int pingId;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* <p>Creates a {@link PingInfo} with the given ping id</p>
|
||||
* @param pingId the ping id
|
||||
*/
|
||||
public PingInfo(int pingId)
|
||||
/**
|
||||
* A PingInfo container. Currently adding nothing to it's base class, but serves to keep the api unchanged in
|
||||
* future versions when we need to pass more info to the methods having a {@link PingInfo} parameter.
|
||||
*/
|
||||
public class PingInfo extends Info
|
||||
{
|
||||
public PingInfo(long timeout, TimeUnit unit)
|
||||
{
|
||||
this.pingId = pingId;
|
||||
super(timeout, unit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the ping id
|
||||
*/
|
||||
public int getPingId()
|
||||
public PingInfo()
|
||||
{
|
||||
return pingId;
|
||||
this(0, TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2012 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.spdy.api;
|
||||
|
||||
/**
|
||||
* <p>A container for PING frames data.</p>
|
||||
*/
|
||||
public class PingResultInfo
|
||||
{
|
||||
private final int pingId;
|
||||
|
||||
/**
|
||||
* <p>Creates a {@link PingResultInfo} with the given ping id</p>
|
||||
* @param pingId the ping id
|
||||
*/
|
||||
public PingResultInfo(int pingId)
|
||||
{
|
||||
this.pingId = pingId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the ping id
|
||||
*/
|
||||
public int getPingId()
|
||||
{
|
||||
return pingId;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2012 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.spdy.api;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
|
||||
/**
|
||||
* <p>A container for PUSH_SYN_STREAM frames metadata and data.</p>
|
||||
*/
|
||||
public class PushInfo extends Info
|
||||
{
|
||||
/**
|
||||
* <p>Flag that indicates that this {@link PushInfo} is the last frame in the stream.</p>
|
||||
*
|
||||
* @see #isClose()
|
||||
* @see #getFlags()
|
||||
*/
|
||||
public static final byte FLAG_CLOSE = 1;
|
||||
|
||||
private final boolean close;
|
||||
private final Fields headers;
|
||||
|
||||
/**
|
||||
* <p>Creates a {@link PushInfo} instance with the given headers and the given close flag,
|
||||
* not unidirectional, without associated stream, and with default priority.</p>
|
||||
*
|
||||
* @param headers the {@link Fields}
|
||||
* @param close the value of the close flag
|
||||
*/
|
||||
public PushInfo(Fields headers, boolean close)
|
||||
{
|
||||
this(0, TimeUnit.SECONDS, headers, close);
|
||||
// either builder or setters for timeout
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Creates a {@link PushInfo} instance with the given headers, the given close flag and with the given priority.
|
||||
* </p>
|
||||
* @param timeout the timeout value
|
||||
* @param unit the TimeUnit of the timeout
|
||||
* @param headers
|
||||
* the {@link Fields}
|
||||
* @param close
|
||||
*/
|
||||
public PushInfo(long timeout, TimeUnit unit, Fields headers, boolean close)
|
||||
{
|
||||
super(timeout, unit);
|
||||
this.close = close;
|
||||
this.headers = headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the value of the close flag
|
||||
*/
|
||||
public boolean isClose()
|
||||
{
|
||||
return close;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the {@link Fields}
|
||||
*/
|
||||
public Fields getHeaders()
|
||||
{
|
||||
return headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the close flag as integer
|
||||
* @see #FLAG_CLOSE
|
||||
*/
|
||||
public byte getFlags()
|
||||
{
|
||||
return isClose() ? FLAG_CLOSE : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("SYN push close=%b headers=%s", close, headers);
|
||||
}
|
||||
}
|
|
@ -18,12 +18,14 @@
|
|||
|
||||
package org.eclipse.jetty.spdy.api;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
|
||||
/**
|
||||
* <p>A container for SYN_REPLY frames metadata and headers.</p>
|
||||
*/
|
||||
public class ReplyInfo
|
||||
public class ReplyInfo extends Info
|
||||
{
|
||||
/**
|
||||
* <p>Flag that indicates that this {@link ReplyInfo} is the last frame in the stream.</p>
|
||||
|
@ -50,10 +52,24 @@ public class ReplyInfo
|
|||
* <p>Creates a {@link ReplyInfo} instance with the given headers and the given close flag.</p>
|
||||
*
|
||||
* @param headers the {@link Fields}
|
||||
* @param close the value of the close flag
|
||||
* @param close the value of the close flag
|
||||
*/
|
||||
public ReplyInfo(Fields headers, boolean close)
|
||||
{
|
||||
this(0, TimeUnit.SECONDS, headers, close);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Creates a {@link ReplyInfo} instance with the given headers and the given close flag.</p>
|
||||
*
|
||||
* @param timeout the timeout
|
||||
* @param unit the time unit for the timeout
|
||||
* @param headers the {@link Fields}
|
||||
* @param close the value of the close flag
|
||||
*/
|
||||
public ReplyInfo(long timeout, TimeUnit unit, Fields headers, boolean close)
|
||||
{
|
||||
super(timeout, unit);
|
||||
this.headers = headers;
|
||||
this.close = close;
|
||||
}
|
||||
|
|
|
@ -18,10 +18,12 @@
|
|||
|
||||
package org.eclipse.jetty.spdy.api;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* <p>A container for RST_STREAM frames data: the stream id and the stream status.</p>
|
||||
*/
|
||||
public class RstInfo
|
||||
public class RstInfo extends Info
|
||||
{
|
||||
private final int streamId;
|
||||
private final StreamStatus streamStatus;
|
||||
|
@ -29,13 +31,27 @@ public class RstInfo
|
|||
/**
|
||||
* <p>Creates a new {@link RstInfo} with the given stream id and stream status</p>
|
||||
*
|
||||
* @param streamId the stream id
|
||||
* @param timeout the operation's timeout
|
||||
* @param unit the timeout's unit
|
||||
* @param streamId the stream id
|
||||
* @param streamStatus the stream status
|
||||
*/
|
||||
public RstInfo(long timeout, TimeUnit unit, int streamId, StreamStatus streamStatus)
|
||||
{
|
||||
super(timeout, unit);
|
||||
this.streamId = streamId;
|
||||
this.streamStatus = streamStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Creates a new {@link RstInfo} with the given stream id and stream status</p>
|
||||
*
|
||||
* @param streamId
|
||||
* @param streamStatus
|
||||
*/
|
||||
public RstInfo(int streamId, StreamStatus streamStatus)
|
||||
{
|
||||
this.streamId = streamId;
|
||||
this.streamStatus = streamStatus;
|
||||
this(0, TimeUnit.SECONDS, streamId, streamStatus);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -21,8 +21,8 @@ package org.eclipse.jetty.spdy.api;
|
|||
import java.net.InetSocketAddress;
|
||||
import java.util.EventListener;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
|
@ -33,7 +33,7 @@ import org.eclipse.jetty.util.Promise;
|
|||
* <pre>
|
||||
* Session session = ...;
|
||||
* SynInfo synInfo = new SynInfo(true);
|
||||
* session.syn(synInfo, new Stream.FrameListener.Adapter()
|
||||
* session.push(synInfo, new Stream.FrameListener.Adapter()
|
||||
* {
|
||||
* public void onReply(Stream stream, ReplyInfo replyInfo)
|
||||
* {
|
||||
|
@ -75,115 +75,118 @@ public interface Session
|
|||
* <p>Callers may use the returned future to wait for the stream to be created, and
|
||||
* use the stream, for example, to send data frames.</p>
|
||||
*
|
||||
*
|
||||
* @param synInfo the metadata to send on stream creation
|
||||
* @param listener the listener to invoke when events happen on the stream just created
|
||||
* @return a future for the stream that will be created
|
||||
* @see #syn(SynInfo, StreamFrameListener, long, TimeUnit, Promise)
|
||||
* @return the stream that will be created
|
||||
* @see #syn(SynInfo, StreamFrameListener, Promise
|
||||
*/
|
||||
public Future<Stream> syn(SynInfo synInfo, StreamFrameListener listener);
|
||||
public Stream syn(SynInfo synInfo, StreamFrameListener listener) throws ExecutionException, InterruptedException, TimeoutException;
|
||||
|
||||
/**
|
||||
* <p>Sends asynchronously a SYN_FRAME to create a new {@link Stream SPDY stream}.</p>
|
||||
* <p>Callers may pass a non-null completion callback to be notified of when the
|
||||
* stream has been created and use the stream, for example, to send data frames.</p>
|
||||
*
|
||||
*
|
||||
* @param synInfo the metadata to send on stream creation
|
||||
* @param listener the listener to invoke when events happen on the stream just created
|
||||
* @param timeout the operation's timeout
|
||||
* @param unit the timeout's unit
|
||||
* @param promise the completion callback that gets notified of stream creation
|
||||
* @see #syn(SynInfo, StreamFrameListener)
|
||||
*/
|
||||
public void syn(SynInfo synInfo, StreamFrameListener listener, long timeout, TimeUnit unit, Promise<Stream> promise);
|
||||
|
||||
public void syn(SynInfo synInfo, StreamFrameListener listener, Promise<Stream> promise);
|
||||
|
||||
/**
|
||||
* <p>Sends asynchronously a RST_STREAM to abort a stream.</p>
|
||||
* <p>Callers may use the returned future to wait for the reset to be sent.</p>
|
||||
*
|
||||
*
|
||||
* @param rstInfo the metadata to reset the stream
|
||||
* @return a future to wait for the reset to be sent
|
||||
* @see #rst(RstInfo, long, TimeUnit, Callback)
|
||||
* @return the RstInfo belonging to the reset to be sent
|
||||
* @see #rst(RstInfo, Callback)
|
||||
*/
|
||||
public Future<Void> rst(RstInfo rstInfo);
|
||||
public void rst(RstInfo rstInfo) throws InterruptedException, ExecutionException, TimeoutException;
|
||||
|
||||
/**
|
||||
* <p>Sends asynchronously a RST_STREAM to abort a stream.</p>
|
||||
* <p>Callers may pass a non-null completion callback to be notified of when the
|
||||
* reset has been actually sent.</p>
|
||||
*
|
||||
*
|
||||
* @param rstInfo the metadata to reset the stream
|
||||
* @param timeout the operation's timeout
|
||||
* @param unit the timeout's unit
|
||||
* @param callback the completion callback that gets notified of reset's send
|
||||
* @see #rst(RstInfo)
|
||||
*/
|
||||
public void rst(RstInfo rstInfo, long timeout, TimeUnit unit, Callback callback);
|
||||
public void rst(RstInfo rstInfo, Callback callback);
|
||||
|
||||
/**
|
||||
* <p>Sends asynchronously a SETTINGS to configure the SPDY connection.</p>
|
||||
* <p>Callers may use the returned future to wait for the settings to be sent.</p>
|
||||
*
|
||||
*
|
||||
* @param settingsInfo the metadata to send
|
||||
* @return a future to wait for the settings to be sent
|
||||
* @see #settings(SettingsInfo, long, TimeUnit, Callback)
|
||||
* @see #settings(SettingsInfo, Callback)
|
||||
*/
|
||||
public Future<Void> settings(SettingsInfo settingsInfo);
|
||||
public void settings(SettingsInfo settingsInfo) throws ExecutionException, InterruptedException, TimeoutException;
|
||||
|
||||
/**
|
||||
* <p>Sends asynchronously a SETTINGS to configure the SPDY connection.</p>
|
||||
* <p>Callers may pass a non-null completion callback to be notified of when the
|
||||
* settings has been actually sent.</p>
|
||||
*
|
||||
*
|
||||
* @param settingsInfo the metadata to send
|
||||
* @param timeout the operation's timeout
|
||||
* @param unit the timeout's unit
|
||||
* @param callback the completion callback that gets notified of settings' send
|
||||
* @see #settings(SettingsInfo)
|
||||
*/
|
||||
public void settings(SettingsInfo settingsInfo, long timeout, TimeUnit unit, Callback callback);
|
||||
public void settings(SettingsInfo settingsInfo, Callback callback);
|
||||
|
||||
/**
|
||||
* <p>Sends asynchronously a PING, normally to measure round-trip time.</p>
|
||||
* <p>Callers may use the returned future to wait for the ping to be sent.</p>
|
||||
*
|
||||
* @return a future for the metadata sent
|
||||
* @see #ping(long, TimeUnit, Promise)
|
||||
* @see #ping(PingInfo, Promise
|
||||
* @param pingInfo
|
||||
*/
|
||||
public Future<PingInfo> ping();
|
||||
public PingResultInfo ping(PingInfo pingInfo) throws ExecutionException, InterruptedException, TimeoutException;
|
||||
|
||||
/**
|
||||
* <p>Sends asynchronously a PING, normally to measure round-trip time.</p>
|
||||
* <p>Callers may pass a non-null completion callback to be notified of when the
|
||||
* ping has been actually sent.</p>
|
||||
*
|
||||
* @param timeout the operation's timeout
|
||||
* @param unit the timeout's unit
|
||||
*
|
||||
*
|
||||
* @param pingInfo
|
||||
* @param promise the completion callback that gets notified of ping's send
|
||||
* @see #ping()
|
||||
* @see #ping(PingInfo)
|
||||
*/
|
||||
public void ping(long timeout, TimeUnit unit, Promise<PingInfo> promise);
|
||||
public void ping(PingInfo pingInfo, Promise<PingResultInfo> promise);
|
||||
|
||||
/**
|
||||
* <p>Closes gracefully this session, sending a GO_AWAY frame and then closing the TCP connection.</p>
|
||||
* <p>Callers may use the returned future to wait for the go away to be sent.</p>
|
||||
*
|
||||
* @return a future to wait for the go away to be sent
|
||||
* @see #goAway(long, TimeUnit, Callback)
|
||||
* @see #goAway(GoAwayInfo, Callback)
|
||||
* @param goAwayInfo
|
||||
*/
|
||||
public Future<Void> goAway();
|
||||
public void goAway(GoAwayInfo goAwayInfo) throws ExecutionException, InterruptedException, TimeoutException;
|
||||
|
||||
/**
|
||||
* <p>Closes gracefully this session, sending a GO_AWAY frame and then closing the TCP connection.</p>
|
||||
* <p>Callers may pass a non-null completion callback to be notified of when the
|
||||
* go away has been actually sent.</p>
|
||||
*
|
||||
* @param timeout the operation's timeout
|
||||
* @param unit the timeout's unit
|
||||
*
|
||||
*
|
||||
* @param goAwayInfo
|
||||
* @param callback the completion callback that gets notified of go away's send
|
||||
* @see #goAway()
|
||||
* @see #goAway(GoAwayInfo)
|
||||
*/
|
||||
public void goAway(long timeout, TimeUnit unit, Callback callback);
|
||||
public void goAway(GoAwayInfo goAwayInfo, Callback callback);
|
||||
|
||||
/**
|
||||
* @return a snapshot of the streams currently active in this session
|
||||
|
|
|
@ -98,17 +98,17 @@ public interface SessionFrameListener extends EventListener
|
|||
* <p>Callback invoked when a ping request has completed its round-trip.</p>
|
||||
*
|
||||
* @param session the session
|
||||
* @param pingInfo the metadata received
|
||||
* @param pingResultInfo the metadata received
|
||||
*/
|
||||
public void onPing(Session session, PingInfo pingInfo);
|
||||
public void onPing(Session session, PingResultInfo pingResultInfo);
|
||||
|
||||
/**
|
||||
* <p>Callback invoked when the other peer signals that it is closing the connection.</p>
|
||||
*
|
||||
* @param session the session
|
||||
* @param goAwayInfo the metadata sent
|
||||
* @param goAwayReceivedInfo the metadata sent
|
||||
*/
|
||||
public void onGoAway(Session session, GoAwayInfo goAwayInfo);
|
||||
public void onGoAway(Session session, GoAwayReceivedInfo goAwayReceivedInfo);
|
||||
|
||||
/**
|
||||
* <p>Callback invoked when an exception is thrown during the processing of an event on a
|
||||
|
@ -143,12 +143,12 @@ public interface SessionFrameListener extends EventListener
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onPing(Session session, PingInfo pingInfo)
|
||||
public void onPing(Session session, PingResultInfo pingResultInfo)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGoAway(Session session, GoAwayInfo goAwayInfo)
|
||||
public void onGoAway(Session session, GoAwayReceivedInfo goAwayReceivedInfo)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,9 @@
|
|||
|
||||
package org.eclipse.jetty.spdy.api;
|
||||
|
||||
public class SettingsInfo
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class SettingsInfo extends Info
|
||||
{
|
||||
public static final byte CLEAR_PERSISTED = 1;
|
||||
|
||||
|
@ -27,13 +29,19 @@ public class SettingsInfo
|
|||
|
||||
public SettingsInfo(Settings settings)
|
||||
{
|
||||
this(settings, false);
|
||||
this(0, TimeUnit.SECONDS, settings, false);
|
||||
}
|
||||
|
||||
public SettingsInfo(long timeout, TimeUnit unit, Settings settings, boolean clearPersisted)
|
||||
{
|
||||
super(timeout, unit);
|
||||
this.settings = settings;
|
||||
this.clearPersisted = clearPersisted;
|
||||
}
|
||||
|
||||
public SettingsInfo(Settings settings, boolean clearPersisted)
|
||||
{
|
||||
this.settings = settings;
|
||||
this.clearPersisted = clearPersisted;
|
||||
this(0, TimeUnit.SECONDS, settings, clearPersisted);
|
||||
}
|
||||
|
||||
public boolean isClearPersisted()
|
||||
|
|
|
@ -20,8 +20,8 @@ package org.eclipse.jetty.spdy.api;
|
|||
|
||||
import java.nio.channels.WritePendingException;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
|
@ -50,7 +50,7 @@ import org.eclipse.jetty.util.Promise;
|
|||
* stream.data(StringDataInfo("chunk1", false), 5, TimeUnit.SECONDS, new Handler<Void>() { ... });
|
||||
* stream.data(StringDataInfo("chunk2", true), 1, TimeUnit.SECONDS, new Handler<Void>() { ... });
|
||||
* </pre>
|
||||
* <p>where the second call to {@link #data(DataInfo, long, TimeUnit, Callback)} has a timeout smaller
|
||||
* <p>where the second call to {@link #data(DataInfo, Callback)} has a timeout smaller
|
||||
* than the previous call.</p>
|
||||
* <p>The behavior of such style of invocations is unspecified (it may even throw an exception - similar
|
||||
* to {@link WritePendingException}).</p>
|
||||
|
@ -95,35 +95,37 @@ public interface Stream
|
|||
* <p>Initiate a unidirectional spdy pushstream associated to this stream asynchronously<p>
|
||||
* <p>Callers may use the returned future to get the pushstream once it got created</p>
|
||||
*
|
||||
* @param synInfo the metadata to send on stream creation
|
||||
*
|
||||
*
|
||||
* @param pushInfo the metadata to send on stream creation
|
||||
* @return a future containing the stream once it got established
|
||||
* @see #syn(SynInfo, long, TimeUnit, Promise)
|
||||
* @see #push(PushInfo, Promise
|
||||
*/
|
||||
public Future<Stream> syn(SynInfo synInfo);
|
||||
public Stream push(PushInfo pushInfo) throws InterruptedException, ExecutionException, TimeoutException;
|
||||
|
||||
/**
|
||||
* <p>Initiate a unidirectional spdy pushstream associated to this stream asynchronously<p>
|
||||
* <p>Callers may pass a non-null completion callback to be notified of when the
|
||||
* pushstream has been established.</p>
|
||||
*
|
||||
* @param synInfo the metadata to send on stream creation
|
||||
* @param timeout the operation's timeout
|
||||
* @param unit the timeout's unit
|
||||
*
|
||||
* @param pushInfo the metadata to send on stream creation
|
||||
* @param callback the completion callback that gets notified once the pushstream is established
|
||||
* @see #syn(SynInfo)
|
||||
* @see #push(PushInfo)
|
||||
*/
|
||||
public void syn(SynInfo synInfo, long timeout, TimeUnit unit, Promise<Stream> callback);
|
||||
public void push(PushInfo pushInfo, Promise<Stream> callback);
|
||||
|
||||
/**
|
||||
* <p>Sends asynchronously a SYN_REPLY frame in response to a SYN_STREAM frame.</p>
|
||||
* <p>Callers may use the returned future to wait for the reply to be actually sent.</p>
|
||||
*
|
||||
*
|
||||
* @param replyInfo the metadata to send
|
||||
* @return a future to wait for the reply to be sent
|
||||
* @see #reply(ReplyInfo, long, TimeUnit, Callback)
|
||||
* @see #reply(ReplyInfo, Callback)
|
||||
* @see SessionFrameListener#onSyn(Stream, SynInfo)
|
||||
*/
|
||||
public Future<Void> reply(ReplyInfo replyInfo);
|
||||
public void reply(ReplyInfo replyInfo) throws InterruptedException, ExecutionException, TimeoutException;
|
||||
|
||||
/**
|
||||
* <p>Sends asynchronously a SYN_REPLY frame in response to a SYN_STREAM frame.</p>
|
||||
|
@ -131,24 +133,23 @@ public interface Stream
|
|||
* reply has been actually sent.</p>
|
||||
*
|
||||
* @param replyInfo the metadata to send
|
||||
* @param timeout the operation's timeout
|
||||
* @param unit the timeout's unit
|
||||
* @param callback the completion callback that gets notified of reply sent
|
||||
* @see #reply(ReplyInfo)
|
||||
*/
|
||||
public void reply(ReplyInfo replyInfo, long timeout, TimeUnit unit, Callback callback);
|
||||
public void reply(ReplyInfo replyInfo, Callback callback);
|
||||
|
||||
/**
|
||||
* <p>Sends asynchronously a DATA frame on this stream.</p>
|
||||
* <p>DATA frames should always be sent after a SYN_REPLY frame.</p>
|
||||
* <p>Callers may use the returned future to wait for the data to be actually sent.</p>
|
||||
*
|
||||
*
|
||||
* @param dataInfo the metadata to send
|
||||
* @return a future to wait for the data to be sent
|
||||
* @see #data(DataInfo, long, TimeUnit, Callback)
|
||||
* @see #data(DataInfo, Callback)
|
||||
* @see #reply(ReplyInfo)
|
||||
*/
|
||||
public Future<Void> data(DataInfo dataInfo);
|
||||
public void data(DataInfo dataInfo) throws InterruptedException, ExecutionException, TimeoutException;
|
||||
|
||||
/**
|
||||
* <p>Sends asynchronously a DATA frame on this stream.</p>
|
||||
|
@ -157,24 +158,23 @@ public interface Stream
|
|||
* data has been actually sent.</p>
|
||||
*
|
||||
* @param dataInfo the metadata to send
|
||||
* @param timeout the operation's timeout
|
||||
* @param unit the timeout's unit
|
||||
* @param callback the completion callback that gets notified of data sent
|
||||
* @see #data(DataInfo)
|
||||
*/
|
||||
public void data(DataInfo dataInfo, long timeout, TimeUnit unit, Callback callback);
|
||||
public void data(DataInfo dataInfo, Callback callback);
|
||||
|
||||
/**
|
||||
* <p>Sends asynchronously a HEADER frame on this stream.</p>
|
||||
* <p>HEADERS frames should always be sent after a SYN_REPLY frame.</p>
|
||||
* <p>Callers may use the returned future to wait for the headers to be actually sent.</p>
|
||||
*
|
||||
*
|
||||
* @param headersInfo the metadata to send
|
||||
* @return a future to wait for the headers to be sent
|
||||
* @see #headers(HeadersInfo, long, TimeUnit, Callback
|
||||
* @see #headers(HeadersInfo, Callback
|
||||
* @see #reply(ReplyInfo)
|
||||
*/
|
||||
public Future<Void> headers(HeadersInfo headersInfo);
|
||||
public void headers(HeadersInfo headersInfo) throws InterruptedException, ExecutionException, TimeoutException;
|
||||
|
||||
/**
|
||||
* <p>Sends asynchronously a HEADER frame on this stream.</p>
|
||||
|
@ -183,12 +183,10 @@ public interface Stream
|
|||
* headers have been actually sent.</p>
|
||||
*
|
||||
* @param headersInfo the metadata to send
|
||||
* @param timeout the operation's timeout
|
||||
* @param unit the timeout's unit
|
||||
* @param callback the completion callback that gets notified of headers sent
|
||||
* @see #headers(HeadersInfo)
|
||||
*/
|
||||
public void headers(HeadersInfo headersInfo, long timeout, TimeUnit unit, Callback callback);
|
||||
public void headers(HeadersInfo headersInfo, Callback callback);
|
||||
|
||||
/**
|
||||
* @return whether this stream is unidirectional or not
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
package org.eclipse.jetty.spdy.api;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* <p>Specialized {@link DataInfo} for {@link String} content.</p>
|
||||
|
@ -29,4 +30,9 @@ public class StringDataInfo extends BytesDataInfo
|
|||
{
|
||||
super(string.getBytes(Charset.forName("UTF-8")), close);
|
||||
}
|
||||
|
||||
public StringDataInfo(long timeout, TimeUnit unit, String string, boolean close)
|
||||
{
|
||||
super(timeout, unit, string.getBytes(Charset.forName("UTF-8")), close);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,15 +18,17 @@
|
|||
|
||||
package org.eclipse.jetty.spdy.api;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
|
||||
/**
|
||||
* <p>A container for SYN_STREAM frames metadata and data.</p>
|
||||
*/
|
||||
public class SynInfo
|
||||
public class SynInfo extends Info
|
||||
{
|
||||
/**
|
||||
* <p>Flag that indicates that this {@link DataInfo} is the last frame in the stream.</p>
|
||||
* <p>Flag that indicates that this {@link SynInfo} is the last frame in the stream.</p>
|
||||
*
|
||||
* @see #isClose()
|
||||
* @see #getFlags()
|
||||
|
@ -38,18 +40,7 @@ public class SynInfo
|
|||
private final Fields headers;
|
||||
|
||||
/**
|
||||
* <p>Creates a new {@link SynInfo} instance with empty headers and the given close flag,
|
||||
* not unidirectional, without associated stream, and with default priority.</p>
|
||||
*
|
||||
* @param close the value of the close flag
|
||||
*/
|
||||
public SynInfo(boolean close)
|
||||
{
|
||||
this(new Fields(), close);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Creates a {@link ReplyInfo} instance with the given headers and the given close flag,
|
||||
* <p>Creates a {@link SynInfo} instance with the given headers and the given close flag,
|
||||
* not unidirectional, without associated stream, and with default priority.</p>
|
||||
*
|
||||
* @param headers the {@link Fields}
|
||||
|
@ -57,23 +48,40 @@ public class SynInfo
|
|||
*/
|
||||
public SynInfo(Fields headers, boolean close)
|
||||
{
|
||||
this(headers, close, (byte)0);
|
||||
this(0, TimeUnit.SECONDS, headers, close, (byte)0);
|
||||
// either builder or setters for timeout
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Creates a {@link ReplyInfo} instance with the given headers, the given close flag and with the given priority.
|
||||
* Creates a {@link SynInfo} instance with the given headers, the given close flag and with the given priority.
|
||||
* </p>
|
||||
*
|
||||
* @param headers
|
||||
* the {@link Fields}
|
||||
* @param close
|
||||
* the value of the close flag
|
||||
* @param priority
|
||||
* the priority
|
||||
*/
|
||||
public SynInfo(Fields headers, boolean close, byte priority)
|
||||
{
|
||||
this(0, TimeUnit.SECONDS, headers, close, priority);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Creates a {@link SynInfo} instance with the given headers, the given close flag and with the given priority.
|
||||
* </p>
|
||||
* @param timeout the timeout value
|
||||
* @param unit the TimeUnit of the timeout
|
||||
* @param headers
|
||||
* the {@link Fields}
|
||||
* @param close
|
||||
* the value of the close flag
|
||||
* @param priority
|
||||
*/
|
||||
public SynInfo(long timeout, TimeUnit unit, Fields headers, boolean close, byte priority)
|
||||
{
|
||||
super(timeout, unit);
|
||||
this.close = close;
|
||||
this.priority = priority;
|
||||
this.headers = headers;
|
||||
|
|
|
@ -55,14 +55,9 @@ public class DataFrame
|
|||
return (flags & DataInfo.FLAG_CLOSE) == DataInfo.FLAG_CLOSE;
|
||||
}
|
||||
|
||||
public boolean isCompress()
|
||||
{
|
||||
return (flags & DataInfo.FLAG_COMPRESS) == DataInfo.FLAG_COMPRESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("DATA frame stream=%d length=%d close=%b compress=%b", getStreamId(), getLength(), isClose(), isCompress());
|
||||
return String.format("DATA frame stream=%d length=%d close=%b", getStreamId(), getLength(), isClose());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ import org.eclipse.jetty.spdy.generator.Generator;
|
|||
import org.eclipse.jetty.toolchain.test.AdvancedRunner;
|
||||
import org.eclipse.jetty.toolchain.test.annotation.Slow;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
import org.eclipse.jetty.util.thread.Scheduler;
|
||||
import org.eclipse.jetty.util.thread.TimerScheduler;
|
||||
|
@ -77,7 +78,7 @@ public class AsyncTimeoutTest
|
|||
};
|
||||
|
||||
final CountDownLatch failedLatch = new CountDownLatch(1);
|
||||
session.syn(new SynInfo(true), null, timeout, unit, new Promise.Adapter<Stream>()
|
||||
session.syn(new SynInfo(timeout, unit, new Fields(), true, (byte)0), null, new Promise.Adapter<Stream>()
|
||||
{
|
||||
@Override
|
||||
public void failed(Throwable x)
|
||||
|
@ -121,9 +122,9 @@ public class AsyncTimeoutTest
|
|||
}
|
||||
};
|
||||
|
||||
Stream stream = session.syn(new SynInfo(false), null).get(5, TimeUnit.SECONDS);
|
||||
Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), false, (byte)0), null);
|
||||
final CountDownLatch failedLatch = new CountDownLatch(1);
|
||||
stream.data(new StringDataInfo("data", true), timeout, unit, new Callback.Adapter()
|
||||
stream.data(new StringDataInfo(timeout, unit, "data", true), new Callback.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void failed(Throwable x)
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.eclipse.jetty.io.MappedByteBufferPool;
|
|||
import org.eclipse.jetty.spdy.api.ByteBufferDataInfo;
|
||||
import org.eclipse.jetty.spdy.api.DataInfo;
|
||||
import org.eclipse.jetty.spdy.api.HeadersInfo;
|
||||
import org.eclipse.jetty.spdy.api.PushInfo;
|
||||
import org.eclipse.jetty.spdy.api.RstInfo;
|
||||
import org.eclipse.jetty.spdy.api.SPDY;
|
||||
import org.eclipse.jetty.spdy.api.Session;
|
||||
|
@ -48,6 +49,7 @@ import org.eclipse.jetty.spdy.frames.SynStreamFrame;
|
|||
import org.eclipse.jetty.spdy.generator.Generator;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
import org.eclipse.jetty.util.FuturePromise;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
@ -76,6 +78,7 @@ import static org.mockito.Mockito.verify;
|
|||
public class StandardSessionTest
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(StandardSessionTest.class);
|
||||
private static final short VERSION = SPDY.V2;
|
||||
|
||||
@Mock
|
||||
private Controller controller;
|
||||
|
@ -92,7 +95,7 @@ public class StandardSessionTest
|
|||
threadPool = Executors.newCachedThreadPool();
|
||||
scheduler = new TimerScheduler();
|
||||
scheduler.start();
|
||||
session = new StandardSession(SPDY.V2, bufferPool, threadPool, scheduler, controller, null, null, 1, null,
|
||||
session = new StandardSession(VERSION, bufferPool, threadPool, scheduler, controller, null, null, 1, null,
|
||||
generator, new FlowControlStrategy.None());
|
||||
headers = new Fields();
|
||||
}
|
||||
|
@ -144,7 +147,7 @@ public class StandardSessionTest
|
|||
IStream stream = createStream();
|
||||
assertThatStreamIsInSession(stream);
|
||||
stream.updateCloseState(true, true);
|
||||
session.onControlFrame(new SynReplyFrame(SPDY.V2, SynInfo.FLAG_CLOSE, stream.getId(), null));
|
||||
session.onControlFrame(new SynReplyFrame(VERSION, SynInfo.FLAG_CLOSE, stream.getId(), null));
|
||||
assertThatStreamIsClosed(stream);
|
||||
assertThatStreamIsNotInSession(stream);
|
||||
}
|
||||
|
@ -202,7 +205,7 @@ public class StandardSessionTest
|
|||
assertThatPushStreamIsHalfClosed(pushStream);
|
||||
assertThatPushStreamIsNotClosed(pushStream);
|
||||
|
||||
session.onControlFrame(new SynReplyFrame(SPDY.V2, SynInfo.FLAG_CLOSE, stream.getId(), null));
|
||||
session.onControlFrame(new SynReplyFrame(VERSION, SynInfo.FLAG_CLOSE, stream.getId(), null));
|
||||
assertThatStreamIsClosed(stream);
|
||||
assertThatPushStreamIsNotClosed(pushStream);
|
||||
}
|
||||
|
@ -223,8 +226,8 @@ public class StandardSessionTest
|
|||
private void createPushStreamAndMakeSureItFails(IStream stream) throws InterruptedException
|
||||
{
|
||||
final CountDownLatch failedLatch = new CountDownLatch(1);
|
||||
SynInfo synInfo = new SynInfo(headers, false, stream.getPriority());
|
||||
stream.syn(synInfo, 5, TimeUnit.SECONDS, new Promise.Adapter<Stream>()
|
||||
PushInfo pushInfo = new PushInfo(5, TimeUnit.SECONDS, headers, false);
|
||||
stream.push(pushInfo, new Promise.Adapter<Stream>()
|
||||
{
|
||||
@Override
|
||||
public void failed(Throwable x)
|
||||
|
@ -257,7 +260,7 @@ public class StandardSessionTest
|
|||
setControllerWriteExpectation(false);
|
||||
|
||||
IStream stream = createStream();
|
||||
IStream pushStream = (IStream)stream.syn(new SynInfo(false)).get();
|
||||
IStream pushStream = (IStream)stream.push(new PushInfo(new Fields(), false));
|
||||
assertThatPushStreamIsInSession(pushStream);
|
||||
session.rst(new RstInfo(pushStream.getId(), StreamStatus.INVALID_STREAM));
|
||||
assertThatPushStreamIsNotInSession(pushStream);
|
||||
|
@ -271,8 +274,8 @@ public class StandardSessionTest
|
|||
setControllerWriteExpectation(false);
|
||||
|
||||
IStream stream = createStream();
|
||||
SynInfo synInfo = new SynInfo(headers, true, stream.getPriority());
|
||||
IStream pushStream = (IStream)stream.syn(synInfo).get(5, TimeUnit.SECONDS);
|
||||
PushInfo pushInfo = new PushInfo(5, TimeUnit.SECONDS, headers, true);
|
||||
IStream pushStream = (IStream)stream.push(pushInfo);
|
||||
assertThatPushStreamIsHalfClosed(pushStream);
|
||||
assertThatPushStreamIsClosed(pushStream);
|
||||
assertThatStreamIsNotAssociatedWithPushStream(stream, pushStream);
|
||||
|
@ -286,8 +289,8 @@ public class StandardSessionTest
|
|||
setControllerWriteExpectation(false);
|
||||
|
||||
IStream stream = createStream();
|
||||
SynInfo synInfo = new SynInfo(headers, false, stream.getPriority());
|
||||
IStream pushStream = (IStream)stream.syn(synInfo).get(5, TimeUnit.SECONDS);
|
||||
PushInfo pushInfo = new PushInfo(5, TimeUnit.SECONDS, headers, false);
|
||||
IStream pushStream = (IStream)stream.push(pushInfo);
|
||||
assertThatStreamIsAssociatedWithPushStream(stream, pushStream);
|
||||
assertThatPushStreamIsInSession(pushStream);
|
||||
pushStream.headers(new HeadersInfo(headers, true));
|
||||
|
@ -306,6 +309,7 @@ public class StandardSessionTest
|
|||
final CountDownLatch closedListenerCalledLatch = new CountDownLatch(1);
|
||||
session.addListener(new TestStreamListener(createdListenerCalledLatch, closedListenerCalledLatch));
|
||||
IStream stream = createStream();
|
||||
session.onControlFrame(new SynReplyFrame(VERSION, (byte)0, stream.getId(), new Fields()));
|
||||
session.onDataFrame(new DataFrame(stream.getId(), SynInfo.FLAG_CLOSE, 128), ByteBuffer.allocate(128));
|
||||
stream.data(new StringDataInfo("close", true));
|
||||
assertThat("onStreamCreated listener has been called", createdListenerCalledLatch.await(5, TimeUnit.SECONDS), is(true));
|
||||
|
@ -383,11 +387,11 @@ public class StandardSessionTest
|
|||
|
||||
@Test
|
||||
@Ignore("In V3 we need to rst the stream if we receive data on a remotely half closed stream.")
|
||||
public void receiveDataOnRemotelyHalfClosedStreamResetsStreamInV3() throws InterruptedException, ExecutionException
|
||||
public void receiveDataOnRemotelyHalfClosedStreamResetsStreamInV3() throws InterruptedException, ExecutionException, TimeoutException
|
||||
{
|
||||
setControllerWriteExpectation(false);
|
||||
|
||||
IStream stream = (IStream)session.syn(new SynInfo(false), new StreamFrameListener.Adapter()).get();
|
||||
IStream stream = (IStream)session.syn(new SynInfo(new Fields(), false), new StreamFrameListener.Adapter());
|
||||
stream.updateCloseState(true, false);
|
||||
assertThat("stream is half closed from remote side", stream.isHalfClosed(), is(true));
|
||||
stream.process(new ByteBufferDataInfo(ByteBuffer.allocate(256), true));
|
||||
|
@ -399,16 +403,17 @@ public class StandardSessionTest
|
|||
setControllerWriteExpectation(false);
|
||||
|
||||
final CountDownLatch onDataCalledLatch = new CountDownLatch(1);
|
||||
Stream stream = session.syn(new SynInfo(false), new StreamFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onData(Stream stream, DataInfo dataInfo)
|
||||
{
|
||||
onDataCalledLatch.countDown();
|
||||
super.onData(stream, dataInfo);
|
||||
}
|
||||
}).get(5, TimeUnit.SECONDS);
|
||||
session.onControlFrame(new SynReplyFrame(SPDY.V2, SynInfo.FLAG_CLOSE, stream.getId(), headers));
|
||||
Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), false, (byte)0),
|
||||
new StreamFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onData(Stream stream, DataInfo dataInfo)
|
||||
{
|
||||
onDataCalledLatch.countDown();
|
||||
super.onData(stream, dataInfo);
|
||||
}
|
||||
});
|
||||
session.onControlFrame(new SynReplyFrame(VERSION, SynInfo.FLAG_CLOSE, stream.getId(), headers));
|
||||
session.onDataFrame(new DataFrame(stream.getId(), (byte)0, 0), ByteBuffer.allocate(128));
|
||||
assertThat("onData is never called", onDataCalledLatch.await(1, TimeUnit.SECONDS), not(true));
|
||||
}
|
||||
|
@ -420,7 +425,7 @@ public class StandardSessionTest
|
|||
setControllerWriteExpectation(true);
|
||||
|
||||
final CountDownLatch failedCalledLatch = new CountDownLatch(2);
|
||||
SynStreamFrame synStreamFrame = new SynStreamFrame(SPDY.V2, SynInfo.FLAG_CLOSE, 1, 0, (byte)0, (short)0, null);
|
||||
SynStreamFrame synStreamFrame = new SynStreamFrame(VERSION, SynInfo.FLAG_CLOSE, 1, 0, (byte)0, (short)0, null);
|
||||
IStream stream = new StandardStream(synStreamFrame.getStreamId(), synStreamFrame.getPriority(), session, null, null);
|
||||
stream.updateWindowSize(8192);
|
||||
Callback.Adapter callback = new Callback.Adapter()
|
||||
|
@ -433,9 +438,9 @@ public class StandardSessionTest
|
|||
};
|
||||
|
||||
// first data frame should fail on controller.write()
|
||||
stream.data(new StringDataInfo("data", false), 5, TimeUnit.SECONDS, callback);
|
||||
stream.data(new StringDataInfo(5, TimeUnit.SECONDS, "data", false), callback);
|
||||
// second data frame should fail without controller.write() as the connection is expected to be broken after first controller.write() call failed.
|
||||
stream.data(new StringDataInfo("data", false), 5, TimeUnit.SECONDS, callback);
|
||||
stream.data(new StringDataInfo(5, TimeUnit.SECONDS, "data", false), callback);
|
||||
|
||||
verify(controller, times(1)).write(any(ByteBuffer.class), any(Callback.class));
|
||||
assertThat("Callback.failed has been called twice", failedCalledLatch.await(5, TimeUnit.SECONDS), is(true));
|
||||
|
@ -449,7 +454,7 @@ public class StandardSessionTest
|
|||
// This is necessary to keep the compression context of Headers valid
|
||||
IStream stream = createStream();
|
||||
session.rst(new RstInfo(stream.getId(), StreamStatus.INVALID_STREAM));
|
||||
stream.headers(new HeadersInfo(headers,true));
|
||||
stream.headers(new HeadersInfo(headers, true));
|
||||
|
||||
verify(controller, times(3)).write(any(ByteBuffer.class), any(Callback.class));
|
||||
|
||||
|
@ -471,7 +476,7 @@ public class StandardSessionTest
|
|||
|
||||
private void testHeaderFramesAreSentInOrder(final byte priority0, final byte priority1, final byte priority2) throws InterruptedException, ExecutionException
|
||||
{
|
||||
final StandardSession testLocalSession = new StandardSession(SPDY.V2, bufferPool, threadPool, scheduler,
|
||||
final StandardSession testLocalSession = new StandardSession(VERSION, bufferPool, threadPool, scheduler,
|
||||
new ControllerMock(), null, null, 1, null, generator, new FlowControlStrategy.None());
|
||||
HashSet<Future> tasks = new HashSet<>();
|
||||
|
||||
|
@ -492,7 +497,7 @@ public class StandardSessionTest
|
|||
private void synStream(byte priority)
|
||||
{
|
||||
SynInfo synInfo = new SynInfo(headers, false, priority);
|
||||
testLocalSession.syn(synInfo, new StreamFrameListener.Adapter());
|
||||
testLocalSession.syn(synInfo, new StreamFrameListener.Adapter(), new FuturePromise<Stream>());
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
@ -533,14 +538,14 @@ public class StandardSessionTest
|
|||
|
||||
private IStream createStream() throws InterruptedException, ExecutionException, TimeoutException
|
||||
{
|
||||
SynInfo synInfo = new SynInfo(headers, false, (byte)0);
|
||||
return (IStream)session.syn(synInfo, new StreamFrameListener.Adapter()).get(5, TimeUnit.SECONDS);
|
||||
SynInfo synInfo = new SynInfo(5, TimeUnit.SECONDS, headers, false, (byte)0);
|
||||
return (IStream)session.syn(synInfo, new StreamFrameListener.Adapter());
|
||||
}
|
||||
|
||||
private IStream createPushStream(Stream stream) throws InterruptedException, ExecutionException, TimeoutException
|
||||
{
|
||||
SynInfo synInfo = new SynInfo(headers, false, stream.getPriority());
|
||||
return (IStream)stream.syn(synInfo).get(5, TimeUnit.SECONDS);
|
||||
PushInfo pushInfo = new PushInfo(5, TimeUnit.SECONDS, headers, false);
|
||||
return (IStream)stream.push(pushInfo);
|
||||
}
|
||||
|
||||
private void assertThatStreamIsClosed(IStream stream)
|
||||
|
|
|
@ -26,6 +26,7 @@ import java.util.concurrent.TimeUnit;
|
|||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.eclipse.jetty.spdy.api.DataInfo;
|
||||
import org.eclipse.jetty.spdy.api.PushInfo;
|
||||
import org.eclipse.jetty.spdy.api.SPDY;
|
||||
import org.eclipse.jetty.spdy.api.Stream;
|
||||
import org.eclipse.jetty.spdy.api.StreamFrameListener;
|
||||
|
@ -33,6 +34,7 @@ import org.eclipse.jetty.spdy.api.StringDataInfo;
|
|||
import org.eclipse.jetty.spdy.api.SynInfo;
|
||||
import org.eclipse.jetty.spdy.frames.SynStreamFrame;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
@ -45,7 +47,6 @@ import static org.hamcrest.Matchers.is;
|
|||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Matchers.anyLong;
|
||||
import static org.mockito.Matchers.argThat;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
@ -60,7 +61,7 @@ public class StandardStreamTest
|
|||
private SynStreamFrame synStreamFrame;
|
||||
|
||||
/**
|
||||
* Test method for {@link org.eclipse.jetty.spdy.StandardStream#syn(org.eclipse.jetty.spdy.api.SynInfo)}.
|
||||
* Test method for {@link Stream#push(org.eclipse.jetty.spdy.api.PushInfo)}.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
|
@ -70,30 +71,29 @@ public class StandardStreamTest
|
|||
Set<Stream> streams = new HashSet<>();
|
||||
streams.add(stream);
|
||||
when(synStreamFrame.isClose()).thenReturn(false);
|
||||
SynInfo synInfo = new SynInfo(false);
|
||||
PushInfo pushInfo = new PushInfo(new Fields(), false);
|
||||
when(session.getStreams()).thenReturn(streams);
|
||||
stream.syn(synInfo);
|
||||
verify(session).syn(argThat(new PushSynInfoMatcher(stream.getId(), synInfo)), any(StreamFrameListener.class), anyLong(), any(TimeUnit.class), any(Promise.class));
|
||||
stream.push(pushInfo, new Promise.Adapter<Stream>());
|
||||
verify(session).syn(argThat(new PushSynInfoMatcher(stream.getId(), pushInfo)),
|
||||
any(StreamFrameListener.class), any(Promise.class));
|
||||
}
|
||||
|
||||
private class PushSynInfoMatcher extends ArgumentMatcher<PushSynInfo>
|
||||
{
|
||||
int associatedStreamId;
|
||||
SynInfo synInfo;
|
||||
private int associatedStreamId;
|
||||
private PushInfo pushInfo;
|
||||
|
||||
public PushSynInfoMatcher(int associatedStreamId, SynInfo synInfo)
|
||||
public PushSynInfoMatcher(int associatedStreamId, PushInfo pushInfo)
|
||||
{
|
||||
this.associatedStreamId = associatedStreamId;
|
||||
this.synInfo = synInfo;
|
||||
this.pushInfo = pushInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Object argument)
|
||||
{
|
||||
PushSynInfo pushSynInfo = (PushSynInfo)argument;
|
||||
if (pushSynInfo.getAssociatedStreamId() != associatedStreamId)
|
||||
return false;
|
||||
return pushSynInfo.isClose() == synInfo.isClose();
|
||||
return pushSynInfo.getAssociatedStreamId() == associatedStreamId && pushSynInfo.isClose() == pushInfo.isClose();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,7 +105,7 @@ public class StandardStreamTest
|
|||
stream.updateCloseState(true, false);
|
||||
assertThat("stream expected to be closed", stream.isClosed(), is(true));
|
||||
final CountDownLatch failedLatch = new CountDownLatch(1);
|
||||
stream.syn(new SynInfo(false), 1, TimeUnit.SECONDS, new Promise.Adapter<Stream>()
|
||||
stream.push(new PushInfo(1, TimeUnit.SECONDS, new Fields(), false), new Promise.Adapter<Stream>()
|
||||
{
|
||||
@Override
|
||||
public void failed(Throwable x)
|
||||
|
|
|
@ -19,9 +19,12 @@
|
|||
package org.eclipse.jetty.spdy.api;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.eclipse.jetty.spdy.StandardSession;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
import org.junit.Ignore;
|
||||
|
@ -35,7 +38,7 @@ public class ClientUsageTest
|
|||
{
|
||||
Session session = new StandardSession(SPDY.V2, null, null, null, null, null, null, 1, null, null, null);
|
||||
|
||||
session.syn(new SynInfo(true), new StreamFrameListener.Adapter()
|
||||
session.syn(new SynInfo(new Fields(), true), new StreamFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onReply(Stream stream, ReplyInfo replyInfo)
|
||||
|
@ -44,7 +47,14 @@ public class ClientUsageTest
|
|||
replyInfo.getHeaders().get("host");
|
||||
|
||||
// Then issue another similar request
|
||||
stream.getSession().syn(new SynInfo(true), this);
|
||||
try
|
||||
{
|
||||
stream.getSession().syn(new SynInfo(new Fields(), true), this);
|
||||
}
|
||||
catch (ExecutionException | InterruptedException | TimeoutException e)
|
||||
{
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -54,18 +64,26 @@ public class ClientUsageTest
|
|||
{
|
||||
Session session = new StandardSession(SPDY.V2, null, null, null, null, null, null, 1, null, null, null);
|
||||
|
||||
Stream stream = session.syn(new SynInfo(false), new StreamFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), false, (byte)0),
|
||||
new StreamFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onReply(Stream stream, ReplyInfo replyInfo)
|
||||
{
|
||||
// Do something with the response
|
||||
replyInfo.getHeaders().get("host");
|
||||
|
||||
// Then issue another similar request
|
||||
stream.getSession().syn(new SynInfo(true), this);
|
||||
try
|
||||
{
|
||||
stream.getSession().syn(new SynInfo(new Fields(), true), this);
|
||||
}
|
||||
catch (ExecutionException | InterruptedException | TimeoutException e)
|
||||
{
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
}).get(5, TimeUnit.SECONDS);
|
||||
});
|
||||
// Send-and-forget the data
|
||||
stream.data(new StringDataInfo("data", true));
|
||||
}
|
||||
|
@ -76,8 +94,8 @@ public class ClientUsageTest
|
|||
Session session = new StandardSession(SPDY.V2, null, null, null, null, null, null, 1, null, null, null);
|
||||
|
||||
final String context = "context";
|
||||
session.syn(new SynInfo(false), new StreamFrameListener.Adapter()
|
||||
{
|
||||
session.syn(new SynInfo(new Fields(), false), new StreamFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onReply(Stream stream, ReplyInfo replyInfo)
|
||||
{
|
||||
|
@ -85,11 +103,18 @@ public class ClientUsageTest
|
|||
replyInfo.getHeaders().get("host");
|
||||
|
||||
// Then issue another similar request
|
||||
stream.getSession().syn(new SynInfo(true), this);
|
||||
try
|
||||
{
|
||||
stream.getSession().syn(new SynInfo(new Fields(), true), this);
|
||||
}
|
||||
catch (ExecutionException | InterruptedException | TimeoutException e)
|
||||
{
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
}, 0, TimeUnit.MILLISECONDS, new Promise.Adapter<Stream>()
|
||||
{
|
||||
@Override
|
||||
}, new Promise.Adapter<Stream>()
|
||||
{
|
||||
@Override
|
||||
public void succeeded(Stream stream)
|
||||
{
|
||||
// Differently from JDK 7 AIO, there is no need to
|
||||
|
@ -100,7 +125,7 @@ public class ClientUsageTest
|
|||
// The style below is fire-and-forget, since
|
||||
// we do not pass the handler nor we call get()
|
||||
// to wait for the data to be sent
|
||||
stream.data(new StringDataInfo(context, true));
|
||||
stream.data(new StringDataInfo(context, true), new Callback.Adapter());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -110,9 +135,9 @@ public class ClientUsageTest
|
|||
{
|
||||
Session session = new StandardSession(SPDY.V2, null, null, null, null, null, null, 1, null, null, null);
|
||||
|
||||
session.syn(new SynInfo(false), new StreamFrameListener.Adapter()
|
||||
{
|
||||
// The good of passing the listener to syn() is that applications can safely
|
||||
session.syn(new SynInfo(new Fields(), false), new StreamFrameListener.Adapter()
|
||||
{
|
||||
// The good of passing the listener to push() is that applications can safely
|
||||
// accumulate info from the reply headers to be used in the data callback,
|
||||
// e.g. content-type, charset, etc.
|
||||
|
||||
|
@ -127,7 +152,14 @@ public class ClientUsageTest
|
|||
stream.setAttribute("builder", new StringBuilder());
|
||||
|
||||
// May issue another similar request while waiting for data
|
||||
stream.getSession().syn(new SynInfo(true), this);
|
||||
try
|
||||
{
|
||||
stream.getSession().syn(new SynInfo(new Fields(), true), this);
|
||||
}
|
||||
catch (ExecutionException | InterruptedException | TimeoutException e)
|
||||
{
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -138,18 +170,18 @@ public class ClientUsageTest
|
|||
if (dataInfo.isClose())
|
||||
{
|
||||
int receivedLength = builder.toString().getBytes(Charset.forName("UTF-8")).length;
|
||||
assert receivedLength == (Integer)stream.getAttribute("content-length");
|
||||
assert receivedLength == stream.getAttribute("content-length");
|
||||
}
|
||||
|
||||
}
|
||||
}, 0, TimeUnit.MILLISECONDS, new Promise.Adapter<Stream>()
|
||||
{
|
||||
@Override
|
||||
}, new Promise.Adapter<Stream>()
|
||||
{
|
||||
@Override
|
||||
public void succeeded(Stream stream)
|
||||
{
|
||||
stream.data(new BytesDataInfo("wee".getBytes(Charset.forName("UTF-8")), false));
|
||||
stream.data(new StringDataInfo("foo", false));
|
||||
stream.data(new ByteBufferDataInfo(Charset.forName("UTF-8").encode("bar"), true));
|
||||
stream.data(new BytesDataInfo("wee".getBytes(Charset.forName("UTF-8")), false), new Callback.Adapter());
|
||||
stream.data(new StringDataInfo("foo", false), new Callback.Adapter());
|
||||
stream.data(new ByteBufferDataInfo(Charset.forName("UTF-8").encode("bar"), true), new Callback.Adapter());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
|
||||
package org.eclipse.jetty.spdy.api;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
|
||||
|
@ -48,11 +46,11 @@ public class ServerUsageTest
|
|||
Fields replyHeaders = new Fields();
|
||||
replyHeaders.put(synHeaders.get("host"));
|
||||
// Sends a reply
|
||||
stream.reply(new ReplyInfo(replyHeaders, false));
|
||||
stream.reply(new ReplyInfo(replyHeaders, false), new Callback.Adapter());
|
||||
|
||||
// Sends data
|
||||
StringDataInfo dataInfo = new StringDataInfo("foo", false);
|
||||
stream.data(dataInfo);
|
||||
stream.data(dataInfo, new Callback.Adapter());
|
||||
// Stream is now closed
|
||||
return null;
|
||||
}
|
||||
|
@ -77,7 +75,7 @@ public class ServerUsageTest
|
|||
//
|
||||
// However, the API may allow to initiate the stream
|
||||
|
||||
session.syn(new SynInfo(false), null, 0, TimeUnit.MILLISECONDS, new Promise.Adapter<Stream>()
|
||||
session.syn(new SynInfo(new Fields(), false), null, new Promise.Adapter<Stream>()
|
||||
{
|
||||
@Override
|
||||
public void succeeded(Stream stream)
|
||||
|
@ -87,7 +85,7 @@ public class ServerUsageTest
|
|||
// the client sends a rst frame.
|
||||
// We have to atomically set some flag on the stream to signal it's closed
|
||||
// and any operation on it will throw
|
||||
stream.headers(new HeadersInfo(new Fields(), true));
|
||||
stream.headers(new HeadersInfo(new Fields(), true), new Callback.Adapter());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -104,16 +102,16 @@ public class ServerUsageTest
|
|||
public StreamFrameListener onSyn(Stream stream, SynInfo streamInfo)
|
||||
{
|
||||
// Need to send the reply first
|
||||
stream.reply(new ReplyInfo(false));
|
||||
stream.reply(new ReplyInfo(false), new Callback.Adapter());
|
||||
|
||||
Session session = stream.getSession();
|
||||
// Since it's unidirectional, no need to pass the listener
|
||||
session.syn(new SynInfo(new Fields(), false, (byte)0), null, 0, TimeUnit.MILLISECONDS, new Promise.Adapter<Stream>()
|
||||
session.syn(new SynInfo(new Fields(), false, (byte)0), null, new Promise.Adapter<Stream>()
|
||||
{
|
||||
@Override
|
||||
public void succeeded(Stream pushStream)
|
||||
{
|
||||
pushStream.data(new StringDataInfo("foo", false));
|
||||
pushStream.data(new StringDataInfo("foo", false), new Callback.Adapter());
|
||||
}
|
||||
});
|
||||
return null;
|
||||
|
|
|
@ -134,7 +134,7 @@ public class HttpChannelOverSPDY extends HttpChannel<DataInfo>
|
|||
// will be consumed. When the copy is consumed, we consume also the
|
||||
// original, so the implementation can send a window update.
|
||||
ByteBuffer copyByteBuffer = dataInfo.asByteBuffer(false);
|
||||
ByteBufferDataInfo copyDataInfo = new ByteBufferDataInfo(copyByteBuffer, dataInfo.isClose(), dataInfo.isCompress())
|
||||
ByteBufferDataInfo copyDataInfo = new ByteBufferDataInfo(copyByteBuffer, dataInfo.isClose())
|
||||
{
|
||||
@Override
|
||||
public void consume(int delta)
|
||||
|
|
|
@ -37,11 +37,11 @@ import org.eclipse.jetty.server.HttpConfiguration;
|
|||
import org.eclipse.jetty.server.HttpTransport;
|
||||
import org.eclipse.jetty.spdy.StreamException;
|
||||
import org.eclipse.jetty.spdy.api.ByteBufferDataInfo;
|
||||
import org.eclipse.jetty.spdy.api.PushInfo;
|
||||
import org.eclipse.jetty.spdy.api.ReplyInfo;
|
||||
import org.eclipse.jetty.spdy.api.SPDY;
|
||||
import org.eclipse.jetty.spdy.api.Stream;
|
||||
import org.eclipse.jetty.spdy.api.StreamStatus;
|
||||
import org.eclipse.jetty.spdy.api.SynInfo;
|
||||
import org.eclipse.jetty.util.BlockingCallback;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
|
@ -68,7 +68,7 @@ public class HttpTransportOverSPDY implements HttpTransport
|
|||
this.connector = connector;
|
||||
this.configuration = configuration;
|
||||
this.endPoint = endPoint;
|
||||
this.pushStrategy = pushStrategy==null?new PushStrategy.None():pushStrategy;
|
||||
this.pushStrategy = pushStrategy == null ? new PushStrategy.None() : pushStrategy;
|
||||
this.stream = stream;
|
||||
this.requestHeaders = requestHeaders;
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ public class HttpTransportOverSPDY implements HttpTransport
|
|||
public void send(HttpGenerator.ResponseInfo info, ByteBuffer content, boolean lastContent, Callback callback)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("send {} {} {} {} last={}",this,stream,info,BufferUtil.toDetailString(content),lastContent);
|
||||
LOG.debug("send {} {} {} {} last={}", this, stream, info, BufferUtil.toDetailString(content), lastContent);
|
||||
|
||||
if (stream.isClosed() || stream.isReset())
|
||||
{
|
||||
|
@ -98,9 +98,10 @@ public class HttpTransportOverSPDY implements HttpTransport
|
|||
|
||||
boolean hasContent = BufferUtil.hasContent(content);
|
||||
|
||||
if (info!=null)
|
||||
if (info != null)
|
||||
{
|
||||
if(!committed.compareAndSet(false, true)){
|
||||
if (!committed.compareAndSet(false, true))
|
||||
{
|
||||
StreamException exception = new StreamException(stream.getId(), StreamStatus.PROTOCOL_ERROR,
|
||||
"Stream already committed!");
|
||||
callback.failed(exception);
|
||||
|
@ -138,7 +139,7 @@ public class HttpTransportOverSPDY implements HttpTransport
|
|||
}
|
||||
|
||||
boolean close = !hasContent && lastContent;
|
||||
ReplyInfo reply = new ReplyInfo(headers,close);
|
||||
ReplyInfo reply = new ReplyInfo(headers, close);
|
||||
reply(stream, reply);
|
||||
}
|
||||
|
||||
|
@ -146,23 +147,25 @@ public class HttpTransportOverSPDY implements HttpTransport
|
|||
if (hasContent)
|
||||
{
|
||||
// Is the stream still open?
|
||||
if (stream.isClosed()|| stream.isReset())
|
||||
if (stream.isClosed() || stream.isReset())
|
||||
// tell the callback about the EOF
|
||||
callback.failed(new EofException("stream closed"));
|
||||
else
|
||||
callback.failed(new EofException("stream closed"));
|
||||
else
|
||||
// send the data and let it call the callback
|
||||
stream.data(new ByteBufferDataInfo(content, lastContent),endPoint.getIdleTimeout(),TimeUnit.MILLISECONDS,callback);
|
||||
stream.data(new ByteBufferDataInfo(endPoint.getIdleTimeout(), TimeUnit.MILLISECONDS, content, lastContent
|
||||
), callback);
|
||||
}
|
||||
// else do we need to close
|
||||
else if (lastContent)
|
||||
{
|
||||
// Are we closed ?
|
||||
if (stream.isClosed()|| stream.isReset())
|
||||
if (stream.isClosed() || stream.isReset())
|
||||
// already closed by reply, so just tell callback we are complete
|
||||
callback.succeeded();
|
||||
callback.succeeded();
|
||||
else
|
||||
// send empty data to close and let the send call the callback
|
||||
stream.data(new ByteBufferDataInfo(BufferUtil.EMPTY_BUFFER, lastContent),endPoint.getIdleTimeout(),TimeUnit.MILLISECONDS,callback);
|
||||
stream.data(new ByteBufferDataInfo(endPoint.getIdleTimeout(), TimeUnit.MILLISECONDS,
|
||||
BufferUtil.EMPTY_BUFFER, lastContent), callback);
|
||||
}
|
||||
else
|
||||
// No data and no close so tell callback we are completed
|
||||
|
@ -173,7 +176,7 @@ public class HttpTransportOverSPDY implements HttpTransport
|
|||
@Override
|
||||
public void send(HttpGenerator.ResponseInfo info, ByteBuffer content, boolean lastContent) throws EofException
|
||||
{
|
||||
send(info,content,lastContent,streamBlocker);
|
||||
send(info, content, lastContent, streamBlocker);
|
||||
try
|
||||
{
|
||||
streamBlocker.block();
|
||||
|
@ -194,7 +197,7 @@ public class HttpTransportOverSPDY implements HttpTransport
|
|||
private void reply(Stream stream, ReplyInfo replyInfo)
|
||||
{
|
||||
if (!stream.isUnidirectional())
|
||||
stream.reply(replyInfo);
|
||||
stream.reply(replyInfo, new Callback.Adapter());
|
||||
|
||||
Fields responseHeaders = replyInfo.getHeaders();
|
||||
short version = stream.getSession().getVersion();
|
||||
|
@ -212,7 +215,7 @@ public class HttpTransportOverSPDY implements HttpTransport
|
|||
final Fields pushRequestHeaders = createRequestHeaders(scheme, host, uri, pushResource);
|
||||
|
||||
// TODO: handle the timeout better
|
||||
stream.syn(new SynInfo(pushHeaders, false), 0, TimeUnit.MILLISECONDS, new Promise.Adapter<Stream>()
|
||||
stream.push(new PushInfo(0, TimeUnit.MILLISECONDS, pushHeaders, false), new Promise.Adapter<Stream>()
|
||||
{
|
||||
@Override
|
||||
public void succeeded(Stream pushStream)
|
||||
|
|
|
@ -23,8 +23,8 @@ import java.util.HashMap;
|
|||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.eclipse.jetty.spdy.api.GoAwayInfo;
|
||||
import org.eclipse.jetty.spdy.api.PingInfo;
|
||||
import org.eclipse.jetty.spdy.api.GoAwayReceivedInfo;
|
||||
import org.eclipse.jetty.spdy.api.PingResultInfo;
|
||||
import org.eclipse.jetty.spdy.api.RstInfo;
|
||||
import org.eclipse.jetty.spdy.api.Session;
|
||||
import org.eclipse.jetty.spdy.api.Stream;
|
||||
|
@ -33,14 +33,15 @@ import org.eclipse.jetty.spdy.api.StreamStatus;
|
|||
import org.eclipse.jetty.spdy.api.SynInfo;
|
||||
import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
|
||||
import org.eclipse.jetty.spdy.server.http.HTTPSPDYHeader;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
/**
|
||||
* <p>{@link ProxyEngineSelector} is the main entry point for syn stream events of a jetty SPDY proxy. It receives the
|
||||
* syn stream frames from the clients, checks if there's an appropriate {@link ProxyServerInfo} for the given target
|
||||
* host and forwards the syn to a {@link ProxyEngine} for the protocol defined in {@link ProxyServerInfo}.</p>
|
||||
* <p>{@link ProxyEngineSelector} is the main entry point for push stream events of a jetty SPDY proxy. It receives the
|
||||
* push stream frames from the clients, checks if there's an appropriate {@link ProxyServerInfo} for the given target
|
||||
* host and forwards the push to a {@link ProxyEngine} for the protocol defined in {@link ProxyServerInfo}.</p>
|
||||
*
|
||||
* <p>If no {@link ProxyServerInfo} can be found for the given target host or no {@link ProxyEngine} can be found for
|
||||
* the given protocol, it resets the client stream.</p>
|
||||
|
@ -96,14 +97,14 @@ public class ProxyEngineSelector extends ServerSessionFrameListener.Adapter
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onPing(Session clientSession, PingInfo pingInfo)
|
||||
public void onPing(Session clientSession, PingResultInfo pingResultInfo)
|
||||
{
|
||||
// We do not know to which upstream server
|
||||
// to send the PING so we just ignore it
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGoAway(Session session, GoAwayInfo goAwayInfo)
|
||||
public void onGoAway(Session session, GoAwayReceivedInfo goAwayReceivedInfo)
|
||||
{
|
||||
// TODO:
|
||||
}
|
||||
|
@ -153,7 +154,7 @@ public class ProxyEngineSelector extends ServerSessionFrameListener.Adapter
|
|||
private void rst(Stream stream)
|
||||
{
|
||||
RstInfo rstInfo = new RstInfo(stream.getId(), StreamStatus.REFUSED_STREAM);
|
||||
stream.getSession().rst(rstInfo);
|
||||
stream.getSession().rst(rstInfo, new Callback.Adapter());
|
||||
}
|
||||
|
||||
public static class ProxyServerInfo
|
||||
|
|
|
@ -20,8 +20,6 @@ package org.eclipse.jetty.spdy.server.proxy;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
@ -44,7 +42,9 @@ import org.eclipse.jetty.spdy.StandardStream;
|
|||
import org.eclipse.jetty.spdy.api.ByteBufferDataInfo;
|
||||
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.HeadersInfo;
|
||||
import org.eclipse.jetty.spdy.api.PushInfo;
|
||||
import org.eclipse.jetty.spdy.api.ReplyInfo;
|
||||
import org.eclipse.jetty.spdy.api.RstInfo;
|
||||
import org.eclipse.jetty.spdy.api.SessionStatus;
|
||||
|
@ -135,7 +135,7 @@ public class ProxyHTTPSPDYConnection extends HttpConnection implements HttpParse
|
|||
{
|
||||
assert content == null;
|
||||
if (headers.isEmpty())
|
||||
proxyEngineSelector.onGoAway(session, new GoAwayInfo(0, SessionStatus.OK));
|
||||
proxyEngineSelector.onGoAway(session, new GoAwayReceivedInfo(0, SessionStatus.OK));
|
||||
else
|
||||
syn(true);
|
||||
}
|
||||
|
@ -184,14 +184,14 @@ public class ProxyHTTPSPDYConnection extends HttpConnection implements HttpParse
|
|||
}
|
||||
|
||||
@Override
|
||||
public void rst(RstInfo rstInfo, long timeout, TimeUnit unit, Callback handler)
|
||||
public void rst(RstInfo rstInfo, Callback handler)
|
||||
{
|
||||
// Not much we can do in HTTP land: just close the connection
|
||||
goAway(timeout, unit, handler);
|
||||
goAway(new GoAwayInfo(rstInfo.getTimeout(), rstInfo.getUnit()), handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void goAway(long timeout, TimeUnit unit, Callback handler)
|
||||
public void goAway(GoAwayInfo goAwayInfo, Callback handler)
|
||||
{
|
||||
getEndPoint().close();
|
||||
handler.succeeded();
|
||||
|
@ -211,21 +211,21 @@ public class ProxyHTTPSPDYConnection extends HttpConnection implements HttpParse
|
|||
}
|
||||
|
||||
@Override
|
||||
public void syn(SynInfo synInfo, long timeout, TimeUnit unit, Promise<Stream> handler)
|
||||
public void push(PushInfo pushInfo, Promise<Stream> handler)
|
||||
{
|
||||
// HTTP does not support pushed streams
|
||||
handler.succeeded(new HTTPPushStream(2, getPriority(), getSession(), this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void headers(HeadersInfo headersInfo, long timeout, TimeUnit unit, Callback handler)
|
||||
public void headers(HeadersInfo headersInfo, Callback handler)
|
||||
{
|
||||
// TODO
|
||||
throw new UnsupportedOperationException("Not Yet Implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reply(ReplyInfo replyInfo, long timeout, TimeUnit unit, Callback handler)
|
||||
public void reply(ReplyInfo replyInfo, Callback handler)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -284,7 +284,7 @@ public class ProxyHTTPSPDYConnection extends HttpConnection implements HttpParse
|
|||
}
|
||||
|
||||
@Override
|
||||
public void data(DataInfo dataInfo, long timeout, TimeUnit unit, Callback handler)
|
||||
public void data(DataInfo dataInfo, Callback handler)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -313,14 +313,14 @@ public class ProxyHTTPSPDYConnection extends HttpConnection implements HttpParse
|
|||
}
|
||||
|
||||
@Override
|
||||
public void headers(HeadersInfo headersInfo, long timeout, TimeUnit unit, Callback handler)
|
||||
public void headers(HeadersInfo headersInfo, Callback handler)
|
||||
{
|
||||
// Ignore pushed headers
|
||||
handler.succeeded();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void data(DataInfo dataInfo, long timeout, TimeUnit unit, Callback handler)
|
||||
public void data(DataInfo dataInfo, Callback handler)
|
||||
{
|
||||
// Ignore pushed data
|
||||
handler.succeeded();
|
||||
|
|
|
@ -29,7 +29,9 @@ import java.util.concurrent.TimeUnit;
|
|||
import org.eclipse.jetty.spdy.api.ByteBufferDataInfo;
|
||||
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.HeadersInfo;
|
||||
import org.eclipse.jetty.spdy.api.PushInfo;
|
||||
import org.eclipse.jetty.spdy.api.ReplyInfo;
|
||||
import org.eclipse.jetty.spdy.api.RstInfo;
|
||||
import org.eclipse.jetty.spdy.api.SPDY;
|
||||
|
@ -108,7 +110,7 @@ public class SPDYProxyEngine extends ProxyEngine implements StreamFrameListener
|
|||
StreamFrameListener listener = new ProxyStreamFrameListener(clientStream);
|
||||
StreamHandler handler = new StreamHandler(clientStream, serverSynInfo);
|
||||
clientStream.setAttribute(STREAM_HANDLER_ATTRIBUTE, handler);
|
||||
serverSession.syn(serverSynInfo, listener, timeout, TimeUnit.MILLISECONDS, handler);
|
||||
serverSession.syn(serverSynInfo, listener, handler);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -170,7 +172,7 @@ public class SPDYProxyEngine extends ProxyEngine implements StreamFrameListener
|
|||
Session existing = serverSessions.putIfAbsent(host, session);
|
||||
if (existing != null)
|
||||
{
|
||||
session.goAway(getTimeout(), TimeUnit.MILLISECONDS, new Callback.Adapter());
|
||||
session.goAway(new GoAwayInfo(), new Callback.Adapter());
|
||||
session = existing;
|
||||
}
|
||||
}
|
||||
|
@ -203,7 +205,7 @@ public class SPDYProxyEngine extends ProxyEngine implements StreamFrameListener
|
|||
private void rst(Stream stream)
|
||||
{
|
||||
RstInfo rstInfo = new RstInfo(stream.getId(), StreamStatus.REFUSED_STREAM);
|
||||
stream.getSession().rst(rstInfo, getTimeout(), TimeUnit.MILLISECONDS, new Callback.Adapter());
|
||||
stream.getSession().rst(rstInfo, new Callback.Adapter());
|
||||
}
|
||||
|
||||
private class ProxyStreamFrameListener extends StreamFrameListener.Adapter
|
||||
|
@ -259,7 +261,7 @@ public class SPDYProxyEngine extends ProxyEngine implements StreamFrameListener
|
|||
{
|
||||
final ReplyInfo replyInfo = this.replyInfo;
|
||||
this.replyInfo = null;
|
||||
clientStream.reply(replyInfo, getTimeout(), TimeUnit.MILLISECONDS, new Callback()
|
||||
clientStream.reply(replyInfo, new Callback()
|
||||
{
|
||||
@Override
|
||||
public void succeeded()
|
||||
|
@ -278,7 +280,7 @@ public class SPDYProxyEngine extends ProxyEngine implements StreamFrameListener
|
|||
|
||||
private void data(final Stream stream, final DataInfo dataInfo)
|
||||
{
|
||||
clientStream.data(dataInfo, getTimeout(), TimeUnit.MILLISECONDS, new Callback()
|
||||
clientStream.data(dataInfo, new Callback() //TODO: timeout???
|
||||
{
|
||||
@Override
|
||||
public void succeeded()
|
||||
|
@ -394,7 +396,7 @@ public class SPDYProxyEngine extends ProxyEngine implements StreamFrameListener
|
|||
private void flush(Stream serverStream, DataInfoHandler dataInfoHandler)
|
||||
{
|
||||
logger.debug("P -> S {} on {}", dataInfoHandler.dataInfo, serverStream);
|
||||
serverStream.data(dataInfoHandler.dataInfo, getTimeout(), TimeUnit.MILLISECONDS,dataInfoHandler);
|
||||
serverStream.data(dataInfoHandler.dataInfo, dataInfoHandler); //TODO: timeout???
|
||||
}
|
||||
|
||||
private class DataInfoHandler implements Callback
|
||||
|
@ -459,8 +461,8 @@ public class SPDYProxyEngine extends ProxyEngine implements StreamFrameListener
|
|||
|
||||
StreamHandler handler = new StreamHandler(clientStream, serverSynInfo);
|
||||
serverStream.setAttribute(STREAM_HANDLER_ATTRIBUTE, handler);
|
||||
clientStream.syn(new SynInfo(headers, serverSynInfo.isClose()), getTimeout(), TimeUnit.MILLISECONDS, handler);
|
||||
|
||||
clientStream.push(new PushInfo(getTimeout(), TimeUnit.MILLISECONDS, headers, serverSynInfo.isClose()),
|
||||
handler);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -475,13 +477,13 @@ public class SPDYProxyEngine extends ProxyEngine implements StreamFrameListener
|
|||
{
|
||||
Session clientSession = clientStream.getSession();
|
||||
RstInfo clientRstInfo = new RstInfo(clientStream.getId(), serverRstInfo.getStreamStatus());
|
||||
clientSession.rst(clientRstInfo, getTimeout(), TimeUnit.MILLISECONDS, new Callback.Adapter());
|
||||
clientSession.rst(clientRstInfo, new Callback.Adapter());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGoAway(Session serverSession, GoAwayInfo goAwayInfo)
|
||||
public void onGoAway(Session serverSession, GoAwayReceivedInfo goAwayReceivedInfo)
|
||||
{
|
||||
serverSessions.values().remove(serverSession);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ package org.eclipse.jetty.spdy.server.http;
|
|||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.http.HttpGenerator;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
|
@ -49,7 +48,6 @@ import org.mockito.runners.MockitoJUnitRunner;
|
|||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyLong;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
@ -97,7 +95,7 @@ public class HttpTransportOverSPDYTest
|
|||
|
||||
httpTransportOverSPDY.send(null, content, lastContent, callback);
|
||||
ArgumentCaptor<ByteBufferDataInfo> dataInfoCaptor = ArgumentCaptor.forClass(ByteBufferDataInfo.class);
|
||||
verify(stream, times(1)).data(dataInfoCaptor.capture(), anyLong(), any(TimeUnit.class), any(Callback.class));
|
||||
verify(stream, times(1)).data(dataInfoCaptor.capture(), any(Callback.class));
|
||||
assertThat("lastContent is true", dataInfoCaptor.getValue().isClose(), is(true));
|
||||
assertThat("ByteBuffer is empty", dataInfoCaptor.getValue().length(), is(0));
|
||||
}
|
||||
|
@ -108,11 +106,10 @@ public class HttpTransportOverSPDYTest
|
|||
ByteBuffer content = createRandomByteBuffer();
|
||||
|
||||
boolean lastContent = true;
|
||||
|
||||
|
||||
httpTransportOverSPDY.send(null, content, lastContent, callback);
|
||||
ArgumentCaptor<ByteBufferDataInfo> dataInfoCaptor = ArgumentCaptor.forClass(ByteBufferDataInfo.class);
|
||||
verify(stream, times(1)).data(dataInfoCaptor.capture(), anyLong(), any(TimeUnit.class), any(Callback.class));
|
||||
verify(stream, times(1)).data(dataInfoCaptor.capture(), any(Callback.class));
|
||||
assertThat("lastContent is true", dataInfoCaptor.getValue().isClose(), is(true));
|
||||
assertThat("ByteBuffer length is 4096", dataInfoCaptor.getValue().length(), is(4096));
|
||||
}
|
||||
|
@ -126,7 +123,7 @@ public class HttpTransportOverSPDYTest
|
|||
|
||||
httpTransportOverSPDY.send(null, content, lastContent, callback);
|
||||
ArgumentCaptor<ByteBufferDataInfo> dataInfoCaptor = ArgumentCaptor.forClass(ByteBufferDataInfo.class);
|
||||
verify(stream, times(1)).data(dataInfoCaptor.capture(), anyLong(), any(TimeUnit.class), any(Callback.class));
|
||||
verify(stream, times(1)).data(dataInfoCaptor.capture(), any(Callback.class));
|
||||
assertThat("lastContent is true", dataInfoCaptor.getValue().isClose(), is(true));
|
||||
assertThat("ByteBuffer is empty", dataInfoCaptor.getValue().length(), is(0));
|
||||
}
|
||||
|
@ -139,7 +136,7 @@ public class HttpTransportOverSPDYTest
|
|||
|
||||
|
||||
httpTransportOverSPDY.send(null, content, lastContent, callback);
|
||||
verify(stream, times(0)).data(any(ByteBufferDataInfo.class), anyLong(), any(TimeUnit.class), any(Callback.class));
|
||||
verify(stream, times(0)).data(any(ByteBufferDataInfo.class), any(Callback.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -151,7 +148,7 @@ public class HttpTransportOverSPDYTest
|
|||
|
||||
httpTransportOverSPDY.send(null, content, lastContent, callback);
|
||||
ArgumentCaptor<ByteBufferDataInfo> dataInfoCaptor = ArgumentCaptor.forClass(ByteBufferDataInfo.class);
|
||||
verify(stream, times(1)).data(dataInfoCaptor.capture(), anyLong(), any(TimeUnit.class), any(Callback.class));
|
||||
verify(stream, times(1)).data(dataInfoCaptor.capture(), any(Callback.class));
|
||||
assertThat("lastContent is false", dataInfoCaptor.getValue().isClose(), is(false));
|
||||
assertThat("ByteBuffer is empty", dataInfoCaptor.getValue().length(), is(4096));
|
||||
}
|
||||
|
@ -164,7 +161,7 @@ public class HttpTransportOverSPDYTest
|
|||
|
||||
|
||||
httpTransportOverSPDY.send(null, content, lastContent, callback);
|
||||
verify(stream, times(0)).data(any(ByteBufferDataInfo.class), anyLong(), any(TimeUnit.class), any(Callback.class));
|
||||
verify(stream, times(0)).data(any(ByteBufferDataInfo.class), any(Callback.class));
|
||||
verify(callback, times(1)).succeeded();
|
||||
}
|
||||
|
||||
|
@ -179,7 +176,7 @@ public class HttpTransportOverSPDYTest
|
|||
|
||||
httpTransportOverSPDY.send(responseInfo, content, lastContent, callback);
|
||||
ArgumentCaptor<ReplyInfo> replyInfoCaptor = ArgumentCaptor.forClass(ReplyInfo.class);
|
||||
verify(stream, times(1)).reply(replyInfoCaptor.capture());
|
||||
verify(stream, times(1)).reply(replyInfoCaptor.capture(), any(Callback.class));
|
||||
assertThat("ReplyInfo close is true", replyInfoCaptor.getValue().isClose(), is(true));
|
||||
|
||||
verify(callback, times(1)).succeeded();
|
||||
|
@ -196,11 +193,11 @@ public class HttpTransportOverSPDYTest
|
|||
httpTransportOverSPDY.send(responseInfo, content, lastContent, callback);
|
||||
|
||||
ArgumentCaptor<ReplyInfo> replyInfoCaptor = ArgumentCaptor.forClass(ReplyInfo.class);
|
||||
verify(stream, times(1)).reply(replyInfoCaptor.capture());
|
||||
verify(stream, times(1)).reply(replyInfoCaptor.capture(), any(Callback.class));
|
||||
assertThat("ReplyInfo close is false", replyInfoCaptor.getValue().isClose(), is(false));
|
||||
|
||||
ArgumentCaptor<ByteBufferDataInfo> dataInfoCaptor = ArgumentCaptor.forClass(ByteBufferDataInfo.class);
|
||||
verify(stream, times(1)).data(dataInfoCaptor.capture(), anyLong(), any(TimeUnit.class), any(Callback.class));
|
||||
verify(stream, times(1)).data(dataInfoCaptor.capture(), any(Callback.class));
|
||||
assertThat("lastContent is true", dataInfoCaptor.getValue().isClose(), is(true));
|
||||
assertThat("ByteBuffer length is 4096", dataInfoCaptor.getValue().length(), is(4096));
|
||||
}
|
||||
|
@ -214,10 +211,10 @@ public class HttpTransportOverSPDYTest
|
|||
|
||||
httpTransportOverSPDY.send(responseInfo, content, lastContent, callback);
|
||||
ArgumentCaptor<ReplyInfo> replyInfoCaptor = ArgumentCaptor.forClass(ReplyInfo.class);
|
||||
verify(stream, times(1)).reply(replyInfoCaptor.capture());
|
||||
verify(stream, times(1)).reply(replyInfoCaptor.capture(), any(Callback.class));
|
||||
assertThat("ReplyInfo close is true", replyInfoCaptor.getValue().isClose(), is(false));
|
||||
|
||||
verify(stream, times(0)).data(any(ByteBufferDataInfo.class), anyLong(), any(TimeUnit.class), any(Callback.class));
|
||||
verify(stream, times(0)).data(any(ByteBufferDataInfo.class), any(Callback.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -230,11 +227,11 @@ public class HttpTransportOverSPDYTest
|
|||
|
||||
httpTransportOverSPDY.send(responseInfo, content, lastContent, callback);
|
||||
ArgumentCaptor<ReplyInfo> replyInfoCaptor = ArgumentCaptor.forClass(ReplyInfo.class);
|
||||
verify(stream, times(1)).reply(replyInfoCaptor.capture());
|
||||
verify(stream, times(1)).reply(replyInfoCaptor.capture(), any(Callback.class));
|
||||
assertThat("ReplyInfo close is false", replyInfoCaptor.getValue().isClose(), is(false));
|
||||
|
||||
ArgumentCaptor<ByteBufferDataInfo> dataInfoCaptor = ArgumentCaptor.forClass(ByteBufferDataInfo.class);
|
||||
verify(stream, times(1)).data(dataInfoCaptor.capture(), anyLong(), any(TimeUnit.class), any(Callback.class));
|
||||
verify(stream, times(1)).data(dataInfoCaptor.capture(), any(Callback.class));
|
||||
assertThat("lastContent is false", dataInfoCaptor.getValue().isClose(), is(false));
|
||||
assertThat("ByteBuffer length is 4096", dataInfoCaptor.getValue().length(), is(4096));
|
||||
}
|
||||
|
@ -248,13 +245,12 @@ public class HttpTransportOverSPDYTest
|
|||
|
||||
httpTransportOverSPDY.send(responseInfo,content,lastContent, callback);
|
||||
ArgumentCaptor<ReplyInfo> replyInfoCaptor = ArgumentCaptor.forClass(ReplyInfo.class);
|
||||
verify(stream, times(1)).reply(replyInfoCaptor.capture());
|
||||
verify(stream, times(1)).reply(replyInfoCaptor.capture(), any(Callback.class));
|
||||
assertThat("ReplyInfo close is false", replyInfoCaptor.getValue().isClose(), is(false));
|
||||
|
||||
httpTransportOverSPDY.send(HttpGenerator.RESPONSE_500_INFO, null,true);
|
||||
|
||||
verify(stream, times(0)).data(any(DataInfo.class));
|
||||
verify(stream, times(1)).data(any(DataInfo.class), anyLong(), any(TimeUnit.class), any(Callback.class));
|
||||
verify(stream, times(1)).data(any(DataInfo.class), any(Callback.class));
|
||||
|
||||
((StdErrLog)Log.getLogger(HttpTransportOverSPDY.class)).setHideStacks(false);
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ import org.eclipse.jetty.server.HttpConnectionFactory;
|
|||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.handler.AbstractHandler;
|
||||
import org.eclipse.jetty.spdy.api.DataInfo;
|
||||
import org.eclipse.jetty.spdy.api.GoAwayInfo;
|
||||
import org.eclipse.jetty.spdy.api.SPDY;
|
||||
import org.eclipse.jetty.spdy.api.Session;
|
||||
import org.eclipse.jetty.spdy.api.SessionFrameListener;
|
||||
|
@ -97,7 +98,7 @@ public class PushStrategyBenchmarkTest extends AbstractHTTPSPDYTest
|
|||
connector.setDefaultProtocol(factory.getProtocol());
|
||||
Session session = startClient(version, address, new ClientSessionFrameListener());
|
||||
benchmarkSPDY(pushStrategy, session);
|
||||
session.goAway().get(5, TimeUnit.SECONDS);
|
||||
session.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
|
||||
|
||||
// Second push strategy
|
||||
pushStrategy = new ReferrerPushStrategy();
|
||||
|
@ -105,7 +106,7 @@ public class PushStrategyBenchmarkTest extends AbstractHTTPSPDYTest
|
|||
connector.setDefaultProtocol(factory.getProtocol());
|
||||
session = startClient(version, address, new ClientSessionFrameListener());
|
||||
benchmarkSPDY(pushStrategy, session);
|
||||
session.goAway().get(5, TimeUnit.SECONDS);
|
||||
session.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
private void benchmarkHTTP(HttpClient httpClient) throws Exception
|
||||
|
|
|
@ -43,7 +43,9 @@ import org.eclipse.jetty.spdy.api.StreamFrameListener;
|
|||
import org.eclipse.jetty.spdy.api.StreamStatus;
|
||||
import org.eclipse.jetty.spdy.api.SynInfo;
|
||||
import org.eclipse.jetty.spdy.server.NPNServerConnectionFactory;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
@ -117,7 +119,7 @@ public class ReferrerPushStrategyTest extends AbstractHTTPSPDYTest
|
|||
("" +
|
||||
".css"),
|
||||
is(true));
|
||||
stream.getSession().rst(new RstInfo(stream.getId(), StreamStatus.REFUSED_STREAM));
|
||||
stream.getSession().rst(new RstInfo(stream.getId(), StreamStatus.REFUSED_STREAM), new Callback.Adapter());
|
||||
return new StreamFrameListener.Adapter()
|
||||
{
|
||||
|
||||
|
@ -130,11 +132,11 @@ public class ReferrerPushStrategyTest extends AbstractHTTPSPDYTest
|
|||
};
|
||||
}
|
||||
});
|
||||
// Send main request. That should initiate the push syn's which get reset by the client
|
||||
// Send main request. That should initiate the push push's which get reset by the client
|
||||
sendRequest(session, mainRequestHeaders);
|
||||
|
||||
assertThat("No push data is received", pushDataLatch.await(1, TimeUnit.SECONDS), is(false));
|
||||
assertThat("Push syn headers valid", pushSynHeadersValid.await(5, TimeUnit.SECONDS), is(true));
|
||||
assertThat("Push push headers valid", pushSynHeadersValid.await(5, TimeUnit.SECONDS), is(true));
|
||||
|
||||
sendRequest(session, associatedCSSRequestHeaders);
|
||||
}
|
||||
|
@ -224,7 +226,7 @@ public class ReferrerPushStrategyTest extends AbstractHTTPSPDYTest
|
|||
if (dataInfo.isClose())
|
||||
dataReceivedLatch.countDown();
|
||||
}
|
||||
});
|
||||
}, new Promise.Adapter<Stream>());
|
||||
Assert.assertTrue(received200OKLatch.await(5, TimeUnit.SECONDS));
|
||||
Assert.assertTrue(dataReceivedLatch.await(5, TimeUnit.SECONDS));
|
||||
}
|
||||
|
@ -286,7 +288,7 @@ public class ReferrerPushStrategyTest extends AbstractHTTPSPDYTest
|
|||
else
|
||||
assertThat("No push data is received", pushDataLatch.await(1, TimeUnit.SECONDS), is(false));
|
||||
if (validateHeaders)
|
||||
assertThat("Push syn headers valid", pushSynHeadersValid.await(5, TimeUnit.SECONDS), is(true));
|
||||
assertThat("Push push headers valid", pushSynHeadersValid.await(5, TimeUnit.SECONDS), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -202,7 +202,8 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
|
|||
Fields headers = createHeaders("POST", path);
|
||||
headers.put("content-type", "application/x-www-form-urlencoded");
|
||||
final CountDownLatch replyLatch = new CountDownLatch(1);
|
||||
Stream stream = session.syn(new SynInfo(headers, false), new StreamFrameListener.Adapter()
|
||||
Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, headers, false, (byte)0),
|
||||
new StreamFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onReply(Stream stream, ReplyInfo replyInfo)
|
||||
|
@ -212,7 +213,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
|
|||
Assert.assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).value().contains("200"));
|
||||
replyLatch.countDown();
|
||||
}
|
||||
}).get(5, TimeUnit.SECONDS);
|
||||
});
|
||||
stream.data(new StringDataInfo(data, true));
|
||||
|
||||
Assert.assertTrue(handlerLatch.await(5, TimeUnit.SECONDS));
|
||||
|
@ -243,7 +244,8 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
|
|||
Fields headers = createHeaders("POST", path);
|
||||
headers.put("content-type", "application/x-www-form-urlencoded");
|
||||
final CountDownLatch replyLatch = new CountDownLatch(1);
|
||||
Stream stream = session.syn(new SynInfo(headers, false), new StreamFrameListener.Adapter()
|
||||
Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, headers, false, (byte)0),
|
||||
new StreamFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onReply(Stream stream, ReplyInfo replyInfo)
|
||||
|
@ -253,7 +255,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
|
|||
Assert.assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).value().contains("200"));
|
||||
replyLatch.countDown();
|
||||
}
|
||||
}).get(5, TimeUnit.SECONDS);
|
||||
});
|
||||
// Sleep between the data frames so that they will be read in 2 reads
|
||||
stream.data(new StringDataInfo(data1, false));
|
||||
Thread.sleep(1000);
|
||||
|
@ -287,7 +289,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
|
|||
Fields headers = createHeaders("POST", path);
|
||||
headers.put("content-type", "application/x-www-form-urlencoded");
|
||||
final CountDownLatch replyLatch = new CountDownLatch(1);
|
||||
Stream stream = session.syn(new SynInfo(headers, false), new StreamFrameListener.Adapter()
|
||||
Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, headers, false, (byte)0), new StreamFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onReply(Stream stream, ReplyInfo replyInfo)
|
||||
|
@ -297,7 +299,8 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
|
|||
Assert.assertTrue(replyHeaders.toString(), replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).value().contains("200"));
|
||||
replyLatch.countDown();
|
||||
}
|
||||
}).get(5, TimeUnit.SECONDS);
|
||||
});
|
||||
|
||||
// Send the data frames consecutively, so the server reads both frames in one read
|
||||
stream.data(new StringDataInfo(data1, false));
|
||||
stream.data(new StringDataInfo(data2, true));
|
||||
|
@ -1034,7 +1037,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
|
|||
|
||||
Fields headers = createHeaders("POST", "/foo");
|
||||
final CountDownLatch replyLatch = new CountDownLatch(1);
|
||||
Stream stream = session.syn(new SynInfo(headers, false), new StreamFrameListener.Adapter()
|
||||
Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, headers, false, (byte)0), new StreamFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onReply(Stream stream, ReplyInfo replyInfo)
|
||||
|
@ -1043,7 +1046,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
|
|||
Assert.assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).value().contains("200"));
|
||||
replyLatch.countDown();
|
||||
}
|
||||
}).get(5, TimeUnit.SECONDS);
|
||||
});
|
||||
stream.data(new BytesDataInfo(data, true));
|
||||
|
||||
Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
|
||||
|
@ -1077,7 +1080,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
|
|||
|
||||
Fields headers = createHeaders("POST", "/foo");
|
||||
final CountDownLatch replyLatch = new CountDownLatch(1);
|
||||
session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
|
||||
session.syn(new SynInfo(5, TimeUnit.SECONDS, headers, true, (byte)0), new StreamFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onReply(Stream stream, ReplyInfo replyInfo)
|
||||
|
@ -1086,7 +1089,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
|
|||
Assert.assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).value().contains("200"));
|
||||
replyLatch.countDown();
|
||||
}
|
||||
}).get(5, TimeUnit.SECONDS);
|
||||
});
|
||||
|
||||
Assert.assertTrue("Not dispatched again after expire", dispatchedAgainAfterExpire.await(5,
|
||||
TimeUnit.SECONDS));
|
||||
|
@ -1122,7 +1125,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
|
|||
|
||||
Fields headers = createHeaders("POST", "/foo");
|
||||
final CountDownLatch replyLatch = new CountDownLatch(1);
|
||||
Stream stream = session.syn(new SynInfo(headers, false), new StreamFrameListener.Adapter()
|
||||
Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, headers, false, (byte)0), new StreamFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onReply(Stream stream, ReplyInfo replyInfo)
|
||||
|
@ -1131,7 +1134,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
|
|||
Assert.assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).value().contains("200"));
|
||||
replyLatch.countDown();
|
||||
}
|
||||
}).get(5, TimeUnit.SECONDS);
|
||||
});
|
||||
stream.data(new BytesDataInfo(data, true));
|
||||
|
||||
Assert.assertTrue("Not dispatched again after expire", dispatchedAgainAfterExpire.await(5,
|
||||
|
@ -1190,7 +1193,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
|
|||
|
||||
Fields headers = createHeaders("POST", "/foo");
|
||||
final CountDownLatch replyLatch = new CountDownLatch(1);
|
||||
Stream stream = session.syn(new SynInfo(headers, false), new StreamFrameListener.Adapter()
|
||||
Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, headers, false, (byte)0), new StreamFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onReply(Stream stream, ReplyInfo replyInfo)
|
||||
|
@ -1199,7 +1202,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
|
|||
Assert.assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).value().contains("200"));
|
||||
replyLatch.countDown();
|
||||
}
|
||||
}).get(5, TimeUnit.SECONDS);
|
||||
});
|
||||
stream.data(new BytesDataInfo(data, false));
|
||||
stream.data(new BytesDataInfo(data, true));
|
||||
|
||||
|
@ -1258,7 +1261,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
|
|||
|
||||
Fields headers = createHeaders("POST", "/foo");
|
||||
final CountDownLatch responseLatch = new CountDownLatch(2);
|
||||
Stream stream = session.syn(new SynInfo(headers, false), new StreamFrameListener.Adapter()
|
||||
Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, headers, false, (byte)0), new StreamFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onReply(Stream stream, ReplyInfo replyInfo)
|
||||
|
@ -1274,7 +1277,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
|
|||
if (dataInfo.isClose())
|
||||
responseLatch.countDown();
|
||||
}
|
||||
}).get(5, TimeUnit.SECONDS);
|
||||
});
|
||||
stream.data(new BytesDataInfo(data, true));
|
||||
|
||||
Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
|
||||
|
@ -1299,7 +1302,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
|
|||
|
||||
Fields headers = createHeaders("POST", "/foo");
|
||||
final CountDownLatch responseLatch = new CountDownLatch(1);
|
||||
Stream stream = session.syn(new SynInfo(headers, false), new StreamFrameListener.Adapter()
|
||||
Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, headers, false, (byte)0), new StreamFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onReply(Stream stream, ReplyInfo replyInfo)
|
||||
|
@ -1308,9 +1311,9 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
|
|||
Assert.assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).value().contains("200"));
|
||||
responseLatch.countDown();
|
||||
}
|
||||
}).get(5, TimeUnit.SECONDS);
|
||||
});
|
||||
stream.data(new BytesDataInfo(data, false));
|
||||
stream.data(new BytesDataInfo(data, true)).get(5, TimeUnit.SECONDS);
|
||||
stream.data(new BytesDataInfo(5, TimeUnit.SECONDS, data, true));
|
||||
|
||||
Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
|
||||
Assert.assertTrue(responseLatch.await(5, TimeUnit.SECONDS));
|
||||
|
|
|
@ -35,7 +35,10 @@ import org.eclipse.jetty.server.ServerConnector;
|
|||
import org.eclipse.jetty.spdy.api.BytesDataInfo;
|
||||
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;
|
||||
import org.eclipse.jetty.spdy.api.PushInfo;
|
||||
import org.eclipse.jetty.spdy.api.ReplyInfo;
|
||||
import org.eclipse.jetty.spdy.api.RstInfo;
|
||||
import org.eclipse.jetty.spdy.api.SPDY;
|
||||
|
@ -103,7 +106,7 @@ public class ProxyHTTPSPDYTest
|
|||
{
|
||||
server = new Server();
|
||||
SPDYServerConnector serverConnector = new SPDYServerConnector(server, listener);
|
||||
serverConnector.addConnectionFactory(new SPDYServerConnectionFactory(version,listener));
|
||||
serverConnector.addConnectionFactory(new SPDYServerConnectionFactory(version, listener));
|
||||
serverConnector.setPort(0);
|
||||
server.addConnector(serverConnector);
|
||||
server.start();
|
||||
|
@ -159,12 +162,12 @@ public class ProxyHTTPSPDYTest
|
|||
Fields responseHeaders = new Fields();
|
||||
responseHeaders.put(HTTPSPDYHeader.VERSION.name(version), "HTTP/1.1");
|
||||
responseHeaders.put(HTTPSPDYHeader.STATUS.name(version), "200 OK");
|
||||
stream.reply(new ReplyInfo(responseHeaders, true));
|
||||
stream.reply(new ReplyInfo(responseHeaders, true), new Callback.Adapter());
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGoAway(Session session, GoAwayInfo goAwayInfo)
|
||||
public void onGoAway(Session session, GoAwayReceivedInfo goAwayInfo)
|
||||
{
|
||||
closeLatch.countDown();
|
||||
}
|
||||
|
@ -211,7 +214,7 @@ public class ProxyHTTPSPDYTest
|
|||
responseHeaders.put(HTTPSPDYHeader.VERSION.name(version), "HTTP/1.1");
|
||||
responseHeaders.put(HTTPSPDYHeader.STATUS.name(version), "200 OK");
|
||||
ReplyInfo replyInfo = new ReplyInfo(responseHeaders, true);
|
||||
stream.reply(replyInfo);
|
||||
stream.reply(replyInfo, new Callback.Adapter());
|
||||
return null;
|
||||
}
|
||||
}));
|
||||
|
@ -272,8 +275,8 @@ public class ProxyHTTPSPDYTest
|
|||
responseHeaders.put(HTTPSPDYHeader.VERSION.name(version), "HTTP/1.1");
|
||||
responseHeaders.put(HTTPSPDYHeader.STATUS.name(version), "200 OK");
|
||||
ReplyInfo replyInfo = new ReplyInfo(responseHeaders, false);
|
||||
stream.reply(replyInfo);
|
||||
stream.data(new BytesDataInfo(data, true));
|
||||
stream.reply(replyInfo, new Callback.Adapter());
|
||||
stream.data(new BytesDataInfo(data, true), new Callback.Adapter());
|
||||
|
||||
return null;
|
||||
}
|
||||
|
@ -335,7 +338,7 @@ public class ProxyHTTPSPDYTest
|
|||
Fields headers = new Fields();
|
||||
headers.put(HTTPSPDYHeader.VERSION.name(version), "HTTP/1.1");
|
||||
headers.put(HTTPSPDYHeader.STATUS.name(version), "303 See Other");
|
||||
stream.reply(new ReplyInfo(headers, true));
|
||||
stream.reply(new ReplyInfo(headers, true), new Callback.Adapter());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -399,8 +402,8 @@ public class ProxyHTTPSPDYTest
|
|||
responseHeaders.put(HTTPSPDYHeader.VERSION.name(version), "HTTP/1.1");
|
||||
responseHeaders.put(HTTPSPDYHeader.STATUS.name(version), "200 OK");
|
||||
ReplyInfo replyInfo = new ReplyInfo(responseHeaders, false);
|
||||
stream.reply(replyInfo);
|
||||
stream.data(new BytesDataInfo(data, true));
|
||||
stream.reply(replyInfo, new Callback.Adapter());
|
||||
stream.data(new BytesDataInfo(data, true), new Callback.Adapter());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -462,7 +465,7 @@ public class ProxyHTTPSPDYTest
|
|||
|
||||
Fields responseHeaders = new Fields();
|
||||
responseHeaders.put(header, "baz");
|
||||
stream.reply(new ReplyInfo(responseHeaders, true));
|
||||
stream.reply(new ReplyInfo(responseHeaders, true), new Callback.Adapter());
|
||||
return null;
|
||||
}
|
||||
}));
|
||||
|
@ -487,7 +490,7 @@ public class ProxyHTTPSPDYTest
|
|||
|
||||
Assert.assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
|
||||
|
||||
client.goAway().get(5, TimeUnit.SECONDS);
|
||||
client.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -506,8 +509,8 @@ public class ProxyHTTPSPDYTest
|
|||
|
||||
Fields responseHeaders = new Fields();
|
||||
responseHeaders.put(header, "baz");
|
||||
stream.reply(new ReplyInfo(responseHeaders, false));
|
||||
stream.data(new BytesDataInfo(data, true));
|
||||
stream.reply(new ReplyInfo(responseHeaders, false), new Callback.Adapter());
|
||||
stream.data(new BytesDataInfo(data, true), new Callback.Adapter());
|
||||
return null;
|
||||
}
|
||||
}));
|
||||
|
@ -547,7 +550,7 @@ public class ProxyHTTPSPDYTest
|
|||
Assert.assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
|
||||
Assert.assertTrue(dataLatch.await(5, TimeUnit.SECONDS));
|
||||
|
||||
client.goAway().get(5, TimeUnit.SECONDS);
|
||||
client.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -565,16 +568,16 @@ public class ProxyHTTPSPDYTest
|
|||
|
||||
Fields pushHeaders = new Fields();
|
||||
pushHeaders.put(HTTPSPDYHeader.URI.name(version), "/push");
|
||||
stream.syn(new SynInfo(pushHeaders, false), 5, TimeUnit.SECONDS, new Promise.Adapter<Stream>()
|
||||
stream.push(new PushInfo(5, TimeUnit.SECONDS, pushHeaders, false), new Promise.Adapter<Stream>()
|
||||
{
|
||||
@Override
|
||||
public void succeeded(Stream pushStream)
|
||||
{
|
||||
pushStream.data(new BytesDataInfo(data, true));
|
||||
pushStream.data(new BytesDataInfo(data, true), new Callback.Adapter());
|
||||
}
|
||||
});
|
||||
|
||||
stream.reply(new ReplyInfo(responseHeaders, true));
|
||||
stream.reply(new ReplyInfo(responseHeaders, true), new Callback.Adapter());
|
||||
return null;
|
||||
}
|
||||
}));
|
||||
|
@ -614,20 +617,20 @@ public class ProxyHTTPSPDYTest
|
|||
Fields responseHeaders = new Fields();
|
||||
responseHeaders.put(HTTPSPDYHeader.VERSION.name(version), "HTTP/1.1");
|
||||
responseHeaders.put(HTTPSPDYHeader.STATUS.name(version), "200 OK");
|
||||
stream.reply(new ReplyInfo(responseHeaders, false));
|
||||
stream.reply(new ReplyInfo(responseHeaders, false), new Callback.Adapter());
|
||||
|
||||
Fields pushHeaders = new Fields();
|
||||
pushHeaders.put(HTTPSPDYHeader.URI.name(version), "/push");
|
||||
stream.syn(new SynInfo(pushHeaders, false), 5, TimeUnit.SECONDS, new Promise.Adapter<Stream>()
|
||||
stream.push(new PushInfo(5, TimeUnit.SECONDS, pushHeaders, false), new Promise.Adapter<Stream>()
|
||||
{
|
||||
@Override
|
||||
public void succeeded(Stream pushStream)
|
||||
{
|
||||
pushStream.data(new BytesDataInfo(data, true));
|
||||
pushStream.data(new BytesDataInfo(data, true), new Callback.Adapter());
|
||||
}
|
||||
});
|
||||
|
||||
stream.data(new BytesDataInfo(data, true));
|
||||
stream.data(new BytesDataInfo(data, true), new Callback.Adapter());
|
||||
|
||||
return null;
|
||||
}
|
||||
|
@ -681,7 +684,7 @@ public class ProxyHTTPSPDYTest
|
|||
Assert.assertTrue(pushDataLatch.await(5, TimeUnit.SECONDS));
|
||||
Assert.assertTrue(dataLatch.await(5, TimeUnit.SECONDS));
|
||||
|
||||
client.goAway().get(5, TimeUnit.SECONDS);
|
||||
client.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -697,17 +700,17 @@ public class ProxyHTTPSPDYTest
|
|||
Session client = factory.newSPDYClient(version).connect(proxyAddress, new SessionFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onPing(Session session, PingInfo pingInfo)
|
||||
public void onPing(Session session, PingResultInfo pingInfo)
|
||||
{
|
||||
pingLatch.countDown();
|
||||
}
|
||||
}).get(5, TimeUnit.SECONDS);
|
||||
|
||||
client.ping().get(5, TimeUnit.SECONDS);
|
||||
client.ping(new PingInfo(5, TimeUnit.SECONDS));
|
||||
|
||||
Assert.assertTrue(pingLatch.await(5, TimeUnit.SECONDS));
|
||||
|
||||
client.goAway().get(5, TimeUnit.SECONDS);
|
||||
client.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -722,7 +725,7 @@ public class ProxyHTTPSPDYTest
|
|||
Fields requestHeaders = synInfo.getHeaders();
|
||||
Assert.assertNotNull(requestHeaders.get("via"));
|
||||
|
||||
stream.getSession().rst(new RstInfo(stream.getId(), StreamStatus.REFUSED_STREAM));
|
||||
stream.getSession().rst(new RstInfo(stream.getId(), StreamStatus.REFUSED_STREAM), new Callback.Adapter());
|
||||
|
||||
return null;
|
||||
}
|
||||
|
@ -758,7 +761,7 @@ public class ProxyHTTPSPDYTest
|
|||
Fields requestHeaders = synInfo.getHeaders();
|
||||
Assert.assertNotNull(requestHeaders.get("via"));
|
||||
|
||||
stream.getSession().rst(new RstInfo(stream.getId(), StreamStatus.REFUSED_STREAM));
|
||||
stream.getSession().rst(new RstInfo(stream.getId(), StreamStatus.REFUSED_STREAM), new Callback.Adapter());
|
||||
|
||||
return null;
|
||||
}
|
||||
|
@ -781,6 +784,6 @@ public class ProxyHTTPSPDYTest
|
|||
|
||||
Assert.assertTrue(resetLatch.await(5, TimeUnit.SECONDS));
|
||||
|
||||
client.goAway().get(5, TimeUnit.SECONDS);
|
||||
client.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,18 +32,24 @@ import org.eclipse.jetty.spdy.CompressionFactory;
|
|||
import org.eclipse.jetty.spdy.FlowControlStrategy;
|
||||
import org.eclipse.jetty.spdy.StandardCompressionFactory;
|
||||
import org.eclipse.jetty.spdy.StandardSession;
|
||||
import org.eclipse.jetty.spdy.api.GoAwayInfo;
|
||||
import org.eclipse.jetty.spdy.api.Session;
|
||||
import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
|
||||
import org.eclipse.jetty.spdy.client.FlowControlStrategyFactory;
|
||||
import org.eclipse.jetty.spdy.client.SPDYConnection;
|
||||
import org.eclipse.jetty.spdy.generator.Generator;
|
||||
import org.eclipse.jetty.spdy.parser.Parser;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
@ManagedObject("SPDY Server Connection Factory")
|
||||
public class SPDYServerConnectionFactory extends AbstractConnectionFactory
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(SPDYServerConnectionFactory.class);
|
||||
|
||||
// This method is placed here so as to provide a check for NPN before attempting to load any
|
||||
// NPN classes.
|
||||
public static void checkNPNAvailable()
|
||||
|
@ -51,15 +57,15 @@ public class SPDYServerConnectionFactory extends AbstractConnectionFactory
|
|||
try
|
||||
{
|
||||
Class<?> npn = ClassLoader.getSystemClassLoader().loadClass("org.eclipse.jetty.npn.NextProtoNego");
|
||||
if (npn.getClassLoader()!=null)
|
||||
if (npn.getClassLoader() != null)
|
||||
throw new IllegalStateException("NextProtoNego must be on JVM boot path");
|
||||
}
|
||||
catch (ClassNotFoundException e)
|
||||
{
|
||||
throw new IllegalStateException("No NextProtoNego on boot path",e);
|
||||
throw new IllegalStateException("No NextProtoNego on boot path", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private final short version;
|
||||
private final ServerSessionFrameListener listener;
|
||||
private int initialWindowSize;
|
||||
|
@ -70,9 +76,9 @@ public class SPDYServerConnectionFactory extends AbstractConnectionFactory
|
|||
this(version, null);
|
||||
}
|
||||
|
||||
public SPDYServerConnectionFactory(int version, ServerSessionFrameListener listener)
|
||||
public SPDYServerConnectionFactory(int version, ServerSessionFrameListener listener)
|
||||
{
|
||||
super("spdy/"+version);
|
||||
super("spdy/" + version);
|
||||
this.version = (short)version;
|
||||
this.listener = listener;
|
||||
setInitialWindowSize(65536);
|
||||
|
@ -96,8 +102,8 @@ public class SPDYServerConnectionFactory extends AbstractConnectionFactory
|
|||
Parser parser = new Parser(compressionFactory.newDecompressor());
|
||||
Generator generator = new Generator(connector.getByteBufferPool(), compressionFactory.newCompressor());
|
||||
|
||||
ServerSessionFrameListener listener = provideServerSessionFrameListener(connector,endPoint);
|
||||
SPDYConnection connection = new ServerSPDYConnection(connector,endPoint, parser, listener, getInputBufferSize());
|
||||
ServerSessionFrameListener listener = provideServerSessionFrameListener(connector, endPoint);
|
||||
SPDYConnection connection = new ServerSPDYConnection(connector, endPoint, parser, listener, getInputBufferSize());
|
||||
|
||||
FlowControlStrategy flowControlStrategy = newFlowControlStrategy(version);
|
||||
|
||||
|
@ -110,7 +116,7 @@ public class SPDYServerConnectionFactory extends AbstractConnectionFactory
|
|||
|
||||
sessionOpened(session);
|
||||
|
||||
return configure(connection,connector,endPoint);
|
||||
return configure(connection, connector, endPoint);
|
||||
}
|
||||
|
||||
protected FlowControlStrategy newFlowControlStrategy(short version)
|
||||
|
@ -150,7 +156,7 @@ public class SPDYServerConnectionFactory extends AbstractConnectionFactory
|
|||
void closeSessions()
|
||||
{
|
||||
for (Session session : sessions)
|
||||
session.goAway();
|
||||
session.goAway(new GoAwayInfo(), new Callback.Adapter());
|
||||
sessions.clear();
|
||||
}
|
||||
|
||||
|
@ -171,9 +177,9 @@ public class SPDYServerConnectionFactory extends AbstractConnectionFactory
|
|||
private final ServerSessionFrameListener listener;
|
||||
private final AtomicBoolean connected = new AtomicBoolean();
|
||||
|
||||
private ServerSPDYConnection(Connector connector,EndPoint endPoint, Parser parser, ServerSessionFrameListener listener, int bufferSize)
|
||||
private ServerSPDYConnection(Connector connector, EndPoint endPoint, Parser parser, ServerSessionFrameListener listener, int bufferSize)
|
||||
{
|
||||
super(endPoint, connector.getByteBufferPool(), parser, connector.getExecutor(),bufferSize);
|
||||
super(endPoint, connector.getByteBufferPool(), parser, connector.getExecutor(), bufferSize);
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.eclipse.jetty.spdy.StandardCompressionFactory;
|
|||
import org.eclipse.jetty.spdy.api.BytesDataInfo;
|
||||
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.ReplyInfo;
|
||||
import org.eclipse.jetty.spdy.api.SPDY;
|
||||
import org.eclipse.jetty.spdy.api.Session;
|
||||
|
@ -48,6 +49,7 @@ import org.eclipse.jetty.spdy.frames.SynStreamFrame;
|
|||
import org.eclipse.jetty.spdy.generator.Generator;
|
||||
import org.eclipse.jetty.spdy.parser.Parser;
|
||||
import org.eclipse.jetty.spdy.parser.Parser.Listener;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Ignore;
|
||||
|
@ -69,7 +71,7 @@ public class ClosedStreamTest extends AbstractTest
|
|||
|
||||
Session session = startClient(new InetSocketAddress("localhost", server.socket().getLocalPort()), null);
|
||||
final CountDownLatch dataLatch = new CountDownLatch(2);
|
||||
session.syn(new SynInfo(true), new StreamFrameListener.Adapter()
|
||||
session.syn(new SynInfo(new Fields(), true), new StreamFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onData(Stream stream, DataInfo dataInfo)
|
||||
|
@ -102,7 +104,7 @@ public class ClosedStreamTest extends AbstractTest
|
|||
|
||||
Assert.assertFalse(dataLatch.await(1, TimeUnit.SECONDS));
|
||||
|
||||
session.goAway().get(5, TimeUnit.SECONDS);
|
||||
session.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
|
||||
|
||||
server.close();
|
||||
}
|
||||
|
@ -119,7 +121,7 @@ public class ClosedStreamTest extends AbstractTest
|
|||
@Override
|
||||
public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
|
||||
{
|
||||
stream.reply(new ReplyInfo(true));
|
||||
stream.reply(new ReplyInfo(true), new Callback.Adapter());
|
||||
try
|
||||
{
|
||||
replyReceivedLatch.await(5,TimeUnit.SECONDS);
|
||||
|
@ -130,7 +132,7 @@ public class ClosedStreamTest extends AbstractTest
|
|||
}
|
||||
try
|
||||
{
|
||||
stream.data(new StringDataInfo("data send after half closed",false));
|
||||
stream.data(new StringDataInfo("data send after half closed",false), new Callback.Adapter());
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
{
|
||||
|
@ -142,7 +144,7 @@ public class ClosedStreamTest extends AbstractTest
|
|||
}
|
||||
}),null);
|
||||
|
||||
Stream stream = clientSession.syn(new SynInfo(false),new StreamFrameListener.Adapter()
|
||||
Stream stream = clientSession.syn(new SynInfo(new Fields(), false),new StreamFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onReply(Stream stream, ReplyInfo replyInfo)
|
||||
|
@ -155,7 +157,7 @@ public class ClosedStreamTest extends AbstractTest
|
|||
{
|
||||
clientReceivedDataLatch.countDown();
|
||||
}
|
||||
}).get();
|
||||
});
|
||||
assertThat("reply has been received by client",replyReceivedLatch.await(5,TimeUnit.SECONDS),is(true));
|
||||
assertThat("stream is half closed from server",stream.isHalfClosed(),is(true));
|
||||
assertThat("client has not received any data sent after stream was half closed by server",
|
||||
|
@ -189,7 +191,7 @@ public class ClosedStreamTest extends AbstractTest
|
|||
@Override
|
||||
public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
|
||||
{
|
||||
stream.reply(new ReplyInfo(false));
|
||||
stream.reply(new ReplyInfo(false), new Callback.Adapter());
|
||||
serverReplySentLatch.countDown();
|
||||
try
|
||||
{
|
||||
|
@ -209,7 +211,7 @@ public class ClosedStreamTest extends AbstractTest
|
|||
};
|
||||
}
|
||||
@Override
|
||||
public void onGoAway(Session session, GoAwayInfo goAwayInfo)
|
||||
public void onGoAway(Session session, GoAwayReceivedInfo goAwayInfo)
|
||||
{
|
||||
goAwayReceivedLatch.countDown();
|
||||
}
|
||||
|
@ -223,7 +225,7 @@ public class ClosedStreamTest extends AbstractTest
|
|||
socketChannel.write(synData);
|
||||
assertThat("synData is fully written", synData.hasRemaining(), is(false));
|
||||
|
||||
assertThat("server: syn reply is sent",serverReplySentLatch.await(5,TimeUnit.SECONDS),is(true));
|
||||
assertThat("server: push reply is sent",serverReplySentLatch.await(5,TimeUnit.SECONDS),is(true));
|
||||
|
||||
Parser parser = new Parser(new StandardCompressionFactory.StandardDecompressor());
|
||||
parser.addListener(new Listener.Adapter()
|
||||
|
|
|
@ -42,6 +42,9 @@ import org.eclipse.jetty.spdy.api.Stream;
|
|||
import org.eclipse.jetty.spdy.api.StreamFrameListener;
|
||||
import org.eclipse.jetty.spdy.api.SynInfo;
|
||||
import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
import org.eclipse.jetty.util.FutureCallback;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -66,7 +69,7 @@ public class FlowControlTest extends AbstractTest
|
|||
@Override
|
||||
public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
|
||||
{
|
||||
stream.reply(new ReplyInfo(true));
|
||||
stream.reply(new ReplyInfo(true), new Callback.Adapter());
|
||||
return new StreamFrameListener.Adapter()
|
||||
{
|
||||
private final AtomicInteger dataFrames = new AtomicInteger();
|
||||
|
@ -80,7 +83,7 @@ public class FlowControlTest extends AbstractTest
|
|||
dataInfoRef.set(dataInfo);
|
||||
Settings settings = new Settings();
|
||||
settings.put(new Settings.Setting(Settings.ID.INITIAL_WINDOW_SIZE, size));
|
||||
stream.getSession().settings(new SettingsInfo(settings));
|
||||
stream.getSession().settings(new SettingsInfo(settings), new FutureCallback());
|
||||
}
|
||||
else if (dataFrameCount > 1)
|
||||
{
|
||||
|
@ -99,12 +102,12 @@ public class FlowControlTest extends AbstractTest
|
|||
}
|
||||
});
|
||||
|
||||
Stream stream = session.syn(new SynInfo(false), null).get(5, TimeUnit.SECONDS);
|
||||
Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), false, (byte)0), null);
|
||||
stream.data(new BytesDataInfo(new byte[size * 2], false));
|
||||
settingsLatch.await(5, TimeUnit.SECONDS);
|
||||
|
||||
// Send the second chunk of data, must not arrive since we're flow control stalled now
|
||||
stream.data(new BytesDataInfo(new byte[size * 2], true));
|
||||
stream.data(new BytesDataInfo(new byte[size * 2], true), new Callback.Adapter());
|
||||
Assert.assertFalse(dataLatch.await(1, TimeUnit.SECONDS));
|
||||
|
||||
// Consume the data arrived to server, this will resume flow control
|
||||
|
@ -131,8 +134,8 @@ public class FlowControlTest extends AbstractTest
|
|||
@Override
|
||||
public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
|
||||
{
|
||||
stream.reply(new ReplyInfo(false));
|
||||
stream.data(new BytesDataInfo(new byte[length], true));
|
||||
stream.reply(new ReplyInfo(false), new Callback.Adapter());
|
||||
stream.data(new BytesDataInfo(new byte[length], true), new Callback.Adapter());
|
||||
return null;
|
||||
}
|
||||
}), null);
|
||||
|
@ -144,7 +147,7 @@ public class FlowControlTest extends AbstractTest
|
|||
Assert.assertTrue(settingsLatch.await(5, TimeUnit.SECONDS));
|
||||
|
||||
final Exchanger<DataInfo> exchanger = new Exchanger<>();
|
||||
session.syn(new SynInfo(true), new StreamFrameListener.Adapter()
|
||||
session.syn(new SynInfo(new Fields(), true), new StreamFrameListener.Adapter()
|
||||
{
|
||||
private AtomicInteger dataFrames = new AtomicInteger();
|
||||
|
||||
|
@ -230,13 +233,13 @@ public class FlowControlTest extends AbstractTest
|
|||
{
|
||||
Settings settings = new Settings();
|
||||
settings.put(new Settings.Setting(Settings.ID.INITIAL_WINDOW_SIZE, windowSize));
|
||||
session.settings(new SettingsInfo(settings));
|
||||
session.settings(new SettingsInfo(settings), new FutureCallback());
|
||||
}
|
||||
|
||||
@Override
|
||||
public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
|
||||
{
|
||||
stream.reply(new ReplyInfo(false));
|
||||
stream.reply(new ReplyInfo(false), new Callback.Adapter());
|
||||
return new StreamFrameListener.Adapter()
|
||||
{
|
||||
private AtomicInteger dataFrames = new AtomicInteger();
|
||||
|
@ -294,9 +297,9 @@ public class FlowControlTest extends AbstractTest
|
|||
|
||||
Assert.assertTrue(settingsLatch.await(5, TimeUnit.SECONDS));
|
||||
|
||||
Stream stream = session.syn(new SynInfo(false), null).get(5, TimeUnit.SECONDS);
|
||||
Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), false, (byte)0), null);
|
||||
final int length = 5 * windowSize;
|
||||
stream.data(new BytesDataInfo(new byte[length], true));
|
||||
stream.data(new BytesDataInfo(new byte[length], true), new Callback.Adapter());
|
||||
|
||||
DataInfo dataInfo = exchanger.exchange(null, 5, TimeUnit.SECONDS);
|
||||
checkThatWeAreFlowControlStalled(exchanger);
|
||||
|
@ -341,8 +344,8 @@ public class FlowControlTest extends AbstractTest
|
|||
@Override
|
||||
public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
|
||||
{
|
||||
stream.reply(new ReplyInfo(false));
|
||||
stream.data(new BytesDataInfo(new byte[windowSize * 2], true));
|
||||
stream.reply(new ReplyInfo(false), new Callback.Adapter());
|
||||
stream.data(new BytesDataInfo(new byte[windowSize * 2], true), new Callback.Adapter());
|
||||
return null;
|
||||
}
|
||||
}), null);
|
||||
|
@ -355,7 +358,7 @@ public class FlowControlTest extends AbstractTest
|
|||
final CountDownLatch latch = new CountDownLatch(3);
|
||||
final AtomicReference<DataInfo> dataInfoRef1 = new AtomicReference<>();
|
||||
final AtomicReference<DataInfo> dataInfoRef2 = new AtomicReference<>();
|
||||
session.syn(new SynInfo(true), new StreamFrameListener.Adapter()
|
||||
session.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), true, (byte)0), new StreamFrameListener.Adapter()
|
||||
{
|
||||
private final AtomicInteger dataFrames = new AtomicInteger();
|
||||
|
||||
|
@ -375,8 +378,8 @@ public class FlowControlTest extends AbstractTest
|
|||
latch.countDown();
|
||||
}
|
||||
}
|
||||
}).get(5, TimeUnit.SECONDS);
|
||||
session.syn(new SynInfo(true), new StreamFrameListener.Adapter()
|
||||
});
|
||||
session.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), true, (byte)0), new StreamFrameListener.Adapter()
|
||||
{
|
||||
private final AtomicInteger dataFrames = new AtomicInteger();
|
||||
|
||||
|
@ -396,8 +399,8 @@ public class FlowControlTest extends AbstractTest
|
|||
latch.countDown();
|
||||
}
|
||||
}
|
||||
}).get(5, TimeUnit.SECONDS);
|
||||
session.syn(new SynInfo(true), new StreamFrameListener.Adapter()
|
||||
});
|
||||
session.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), true, (byte)0), new StreamFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onData(Stream stream, DataInfo dataInfo)
|
||||
|
@ -412,7 +415,7 @@ public class FlowControlTest extends AbstractTest
|
|||
if (dataInfo.isClose())
|
||||
latch.countDown();
|
||||
}
|
||||
}).get(5, TimeUnit.SECONDS);
|
||||
});
|
||||
|
||||
Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
|
||||
}
|
||||
|
@ -440,13 +443,13 @@ public class FlowControlTest extends AbstractTest
|
|||
@Override
|
||||
public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
|
||||
{
|
||||
stream.reply(new ReplyInfo(false));
|
||||
stream.data(bigByteBufferDataInfo);
|
||||
stream.reply(new ReplyInfo(false), new Callback.Adapter());
|
||||
stream.data(bigByteBufferDataInfo, new Callback.Adapter());
|
||||
return null;
|
||||
}
|
||||
}),new SessionFrameListener.Adapter());
|
||||
|
||||
session.syn(new SynInfo(false),new StreamFrameListener.Adapter()
|
||||
session.syn(new SynInfo(new Fields(), false),new StreamFrameListener.Adapter()
|
||||
{
|
||||
private int dataBytesReceived;
|
||||
|
||||
|
|
|
@ -18,16 +18,17 @@
|
|||
|
||||
package org.eclipse.jetty.spdy.server;
|
||||
|
||||
import java.nio.channels.ClosedChannelException;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.eclipse.jetty.io.EofException;
|
||||
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.ReplyInfo;
|
||||
import org.eclipse.jetty.spdy.api.SPDYException;
|
||||
import org.eclipse.jetty.spdy.api.Session;
|
||||
import org.eclipse.jetty.spdy.api.SessionFrameListener;
|
||||
import org.eclipse.jetty.spdy.api.SessionStatus;
|
||||
|
@ -36,6 +37,10 @@ import org.eclipse.jetty.spdy.api.StreamFrameListener;
|
|||
import org.eclipse.jetty.spdy.api.StringDataInfo;
|
||||
import org.eclipse.jetty.spdy.api.SynInfo;
|
||||
import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
import org.eclipse.jetty.util.FutureCallback;
|
||||
import org.eclipse.jetty.util.FuturePromise;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
@ -51,12 +56,12 @@ public class GoAwayTest extends AbstractTest
|
|||
@Override
|
||||
public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
|
||||
{
|
||||
stream.reply(new ReplyInfo(true));
|
||||
stream.reply(new ReplyInfo(true), new Callback.Adapter());
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGoAway(Session session, GoAwayInfo goAwayInfo)
|
||||
public void onGoAway(Session session, GoAwayReceivedInfo goAwayInfo)
|
||||
{
|
||||
Assert.assertEquals(0, goAwayInfo.getLastStreamId());
|
||||
Assert.assertSame(SessionStatus.OK, goAwayInfo.getSessionStatus());
|
||||
|
@ -65,9 +70,9 @@ public class GoAwayTest extends AbstractTest
|
|||
};
|
||||
Session session = startClient(startServer(serverSessionFrameListener), null);
|
||||
|
||||
session.syn(new SynInfo(true), null);
|
||||
session.syn(new SynInfo(new Fields(), true), null);
|
||||
|
||||
session.goAway();
|
||||
session.goAway(new GoAwayInfo());
|
||||
|
||||
Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
|
||||
}
|
||||
|
@ -80,17 +85,17 @@ public class GoAwayTest extends AbstractTest
|
|||
@Override
|
||||
public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
|
||||
{
|
||||
stream.reply(new ReplyInfo(true));
|
||||
stream.getSession().goAway();
|
||||
stream.reply(new ReplyInfo(true), new Callback.Adapter());
|
||||
stream.getSession().goAway(new GoAwayInfo(), new FutureCallback());
|
||||
return null;
|
||||
}
|
||||
};
|
||||
final AtomicReference<GoAwayInfo> ref = new AtomicReference<>();
|
||||
final AtomicReference<GoAwayReceivedInfo> ref = new AtomicReference<>();
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
SessionFrameListener clientSessionFrameListener = new SessionFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onGoAway(Session session, GoAwayInfo goAwayInfo)
|
||||
public void onGoAway(Session session, GoAwayReceivedInfo goAwayInfo)
|
||||
{
|
||||
ref.set(goAwayInfo);
|
||||
latch.countDown();
|
||||
|
@ -98,13 +103,13 @@ public class GoAwayTest extends AbstractTest
|
|||
};
|
||||
Session session = startClient(startServer(serverSessionFrameListener), clientSessionFrameListener);
|
||||
|
||||
Stream stream1 = session.syn(new SynInfo(true), null).get(5, TimeUnit.SECONDS);
|
||||
Stream stream1 = session.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), true, (byte)0), null);
|
||||
|
||||
Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
|
||||
GoAwayInfo goAwayInfo = ref.get();
|
||||
Assert.assertNotNull(goAwayInfo);
|
||||
Assert.assertEquals(stream1.getId(), goAwayInfo.getLastStreamId());
|
||||
Assert.assertSame(SessionStatus.OK, goAwayInfo.getSessionStatus());
|
||||
GoAwayReceivedInfo goAwayReceivedInfo = ref.get();
|
||||
Assert.assertNotNull(goAwayReceivedInfo);
|
||||
Assert.assertEquals(stream1.getId(), goAwayReceivedInfo.getLastStreamId());
|
||||
Assert.assertSame(SessionStatus.OK, goAwayReceivedInfo.getSessionStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -121,8 +126,8 @@ public class GoAwayTest extends AbstractTest
|
|||
int synCount = syns.incrementAndGet();
|
||||
if (synCount == 1)
|
||||
{
|
||||
stream.reply(new ReplyInfo(true));
|
||||
stream.getSession().goAway();
|
||||
stream.reply(new ReplyInfo(true), new Callback.Adapter());
|
||||
stream.getSession().goAway(new GoAwayInfo(), new FutureCallback());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -134,14 +139,14 @@ public class GoAwayTest extends AbstractTest
|
|||
SessionFrameListener clientSessionFrameListener = new SessionFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onGoAway(Session session, GoAwayInfo goAwayInfo)
|
||||
public void onGoAway(Session session, GoAwayReceivedInfo goAwayInfo)
|
||||
{
|
||||
session.syn(new SynInfo(true), null);
|
||||
session.syn(new SynInfo(new Fields(), true), null, new FuturePromise<Stream>());
|
||||
}
|
||||
};
|
||||
Session session = startClient(startServer(serverSessionFrameListener), clientSessionFrameListener);
|
||||
|
||||
session.syn(new SynInfo(true), null);
|
||||
session.syn(new SynInfo(new Fields(), true), null);
|
||||
|
||||
Assert.assertFalse(latch.await(1, TimeUnit.SECONDS));
|
||||
}
|
||||
|
@ -158,7 +163,7 @@ public class GoAwayTest extends AbstractTest
|
|||
@Override
|
||||
public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
|
||||
{
|
||||
stream.reply(new ReplyInfo(true));
|
||||
stream.reply(new ReplyInfo(true), new Callback.Adapter());
|
||||
int synCount = syns.incrementAndGet();
|
||||
if (synCount == 1)
|
||||
{
|
||||
|
@ -166,7 +171,7 @@ public class GoAwayTest extends AbstractTest
|
|||
}
|
||||
else
|
||||
{
|
||||
stream.getSession().goAway();
|
||||
stream.getSession().goAway(new GoAwayInfo(), new FutureCallback());
|
||||
closeLatch.countDown();
|
||||
return new StreamFrameListener.Adapter()
|
||||
{
|
||||
|
@ -179,12 +184,12 @@ public class GoAwayTest extends AbstractTest
|
|||
}
|
||||
}
|
||||
};
|
||||
final AtomicReference<GoAwayInfo> goAwayRef = new AtomicReference<>();
|
||||
final AtomicReference<GoAwayReceivedInfo> goAwayRef = new AtomicReference<>();
|
||||
final CountDownLatch goAwayLatch = new CountDownLatch(1);
|
||||
SessionFrameListener clientSessionFrameListener = new SessionFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onGoAway(Session session, GoAwayInfo goAwayInfo)
|
||||
public void onGoAway(Session session, GoAwayReceivedInfo goAwayInfo)
|
||||
{
|
||||
goAwayRef.set(goAwayInfo);
|
||||
goAwayLatch.countDown();
|
||||
|
@ -194,18 +199,18 @@ public class GoAwayTest extends AbstractTest
|
|||
|
||||
// First stream is processed ok
|
||||
final CountDownLatch reply1Latch = new CountDownLatch(1);
|
||||
Stream stream1 = session.syn(new SynInfo(true), new StreamFrameListener.Adapter()
|
||||
session.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), true, (byte)0), new StreamFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onReply(Stream stream, ReplyInfo replyInfo)
|
||||
{
|
||||
reply1Latch.countDown();
|
||||
}
|
||||
}).get(5, TimeUnit.SECONDS);
|
||||
});
|
||||
Assert.assertTrue(reply1Latch.await(5, TimeUnit.SECONDS));
|
||||
|
||||
// Second stream is closed in the middle
|
||||
Stream stream2 = session.syn(new SynInfo(false), null).get(5, TimeUnit.SECONDS);
|
||||
Stream stream2 = session.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), false, (byte)0), null);
|
||||
Assert.assertTrue(closeLatch.await(5, TimeUnit.SECONDS));
|
||||
|
||||
// There is a race between the data we want to send, and the client
|
||||
|
@ -216,14 +221,14 @@ public class GoAwayTest extends AbstractTest
|
|||
stream2.data(new StringDataInfo("foo", true));
|
||||
Assert.assertFalse(dataLatch.await(1, TimeUnit.SECONDS));
|
||||
}
|
||||
catch (SPDYException x)
|
||||
catch (ExecutionException x)
|
||||
{
|
||||
Assert.assertThat(x.getCause(), CoreMatchers.instanceOf(ClosedChannelException.class));
|
||||
Assert.assertThat(x.getCause(), CoreMatchers.instanceOf(EofException.class));
|
||||
}
|
||||
|
||||
// The last good stream is the second, because it was received by the server
|
||||
Assert.assertTrue(goAwayLatch.await(5, TimeUnit.SECONDS));
|
||||
GoAwayInfo goAway = goAwayRef.get();
|
||||
GoAwayReceivedInfo goAway = goAwayRef.get();
|
||||
Assert.assertNotNull(goAway);
|
||||
Assert.assertEquals(stream2.getId(), goAway.getLastStreamId());
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ import org.eclipse.jetty.spdy.api.Stream;
|
|||
import org.eclipse.jetty.spdy.api.StreamFrameListener;
|
||||
import org.eclipse.jetty.spdy.api.SynInfo;
|
||||
import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
@ -43,14 +44,14 @@ public class HeadersTest extends AbstractTest
|
|||
@Override
|
||||
public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
|
||||
{
|
||||
stream.reply(new ReplyInfo(false));
|
||||
stream.reply(new ReplyInfo(false), new Callback.Adapter());
|
||||
return new StreamFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onHeaders(Stream stream, HeadersInfo headersInfo)
|
||||
{
|
||||
Assert.assertTrue(stream.isHalfClosed());
|
||||
stream.headers(new HeadersInfo(new Fields(), true));
|
||||
stream.headers(new HeadersInfo(new Fields(), true), new Callback.Adapter());
|
||||
Assert.assertTrue(stream.isClosed());
|
||||
}
|
||||
};
|
||||
|
@ -60,7 +61,7 @@ public class HeadersTest extends AbstractTest
|
|||
Session session = startClient(startServer(serverSessionFrameListener), null);
|
||||
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
session.syn(new SynInfo(false), new StreamFrameListener.Adapter()
|
||||
session.syn(new SynInfo(new Fields(), false), new StreamFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onReply(Stream stream, ReplyInfo replyInfo)
|
||||
|
@ -68,7 +69,7 @@ public class HeadersTest extends AbstractTest
|
|||
Fields headers = new Fields();
|
||||
headers.put("foo", "bar");
|
||||
headers.put("baz", "woo");
|
||||
stream.headers(new HeadersInfo(headers, true));
|
||||
stream.headers(new HeadersInfo(headers, true), new Callback.Adapter());
|
||||
Assert.assertTrue(stream.isHalfClosed());
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ import java.net.InetSocketAddress;
|
|||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.spdy.api.GoAwayInfo;
|
||||
import org.eclipse.jetty.spdy.api.GoAwayReceivedInfo;
|
||||
import org.eclipse.jetty.spdy.api.ReplyInfo;
|
||||
import org.eclipse.jetty.spdy.api.SPDY;
|
||||
import org.eclipse.jetty.spdy.api.Session;
|
||||
|
@ -33,6 +33,8 @@ import org.eclipse.jetty.spdy.api.StreamFrameListener;
|
|||
import org.eclipse.jetty.spdy.api.SynInfo;
|
||||
import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
|
||||
import org.eclipse.jetty.spdy.client.SPDYClient;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
@ -51,7 +53,7 @@ public class IdleTimeoutTest extends AbstractTest
|
|||
@Override
|
||||
public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
|
||||
{
|
||||
stream.reply(new ReplyInfo(true));
|
||||
stream.reply(new ReplyInfo(true), new Callback.Adapter());
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
@ -61,13 +63,13 @@ public class IdleTimeoutTest extends AbstractTest
|
|||
Session session = startClient(startServer(null), new SessionFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onGoAway(Session session, GoAwayInfo goAwayInfo)
|
||||
public void onGoAway(Session session, GoAwayReceivedInfo goAwayInfo)
|
||||
{
|
||||
latch.countDown();
|
||||
}
|
||||
});
|
||||
|
||||
session.syn(new SynInfo(true), null);
|
||||
session.syn(new SynInfo(new Fields(), true), null);
|
||||
|
||||
Assert.assertTrue(latch.await(2 * idleTimeout, TimeUnit.MILLISECONDS));
|
||||
}
|
||||
|
@ -83,14 +85,14 @@ public class IdleTimeoutTest extends AbstractTest
|
|||
Session session = startClient(startServer(null), new SessionFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onGoAway(Session session, GoAwayInfo goAwayInfo)
|
||||
public void onGoAway(Session session, GoAwayReceivedInfo goAwayInfo)
|
||||
{
|
||||
latch.countDown();
|
||||
}
|
||||
});
|
||||
|
||||
// The SYN is not replied, and the server should idle timeout
|
||||
session.syn(new SynInfo(true), null);
|
||||
session.syn(new SynInfo(new Fields(), true), null);
|
||||
|
||||
Assert.assertTrue(latch.await(2 * idleTimeout, TimeUnit.MILLISECONDS));
|
||||
}
|
||||
|
@ -107,7 +109,7 @@ public class IdleTimeoutTest extends AbstractTest
|
|||
try
|
||||
{
|
||||
Thread.sleep(2 * idleTimeout);
|
||||
stream.reply(new ReplyInfo(true));
|
||||
stream.reply(new ReplyInfo(true), new Callback.Adapter());
|
||||
return null;
|
||||
}
|
||||
catch (InterruptedException x)
|
||||
|
@ -123,14 +125,14 @@ public class IdleTimeoutTest extends AbstractTest
|
|||
Session session = startClient(startServer(null), new SessionFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onGoAway(Session session, GoAwayInfo goAwayInfo)
|
||||
public void onGoAway(Session session, GoAwayReceivedInfo goAwayInfo)
|
||||
{
|
||||
goAwayLatch.countDown();
|
||||
}
|
||||
});
|
||||
|
||||
final CountDownLatch replyLatch = new CountDownLatch(1);
|
||||
session.syn(new SynInfo(true), new StreamFrameListener.Adapter()
|
||||
session.syn(new SynInfo(new Fields(), true), new StreamFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onReply(Stream stream, ReplyInfo replyInfo)
|
||||
|
@ -154,12 +156,12 @@ public class IdleTimeoutTest extends AbstractTest
|
|||
@Override
|
||||
public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
|
||||
{
|
||||
stream.reply(new ReplyInfo(true));
|
||||
stream.reply(new ReplyInfo(true), new Callback.Adapter());
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGoAway(Session session, GoAwayInfo goAwayInfo)
|
||||
public void onGoAway(Session session, GoAwayReceivedInfo goAwayInfo)
|
||||
{
|
||||
latch.countDown();
|
||||
}
|
||||
|
@ -173,7 +175,7 @@ public class IdleTimeoutTest extends AbstractTest
|
|||
client.setIdleTimeout(idleTimeout);
|
||||
Session session = client.connect(address, null).get(5, TimeUnit.SECONDS);
|
||||
|
||||
session.syn(new SynInfo(true), null);
|
||||
session.syn(new SynInfo(new Fields(), true), null);
|
||||
|
||||
Assert.assertTrue(latch.await(2 * idleTimeout, TimeUnit.MILLISECONDS));
|
||||
}
|
||||
|
@ -185,7 +187,7 @@ public class IdleTimeoutTest extends AbstractTest
|
|||
InetSocketAddress address = startServer(new ServerSessionFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onGoAway(Session session, GoAwayInfo goAwayInfo)
|
||||
public void onGoAway(Session session, GoAwayReceivedInfo goAwayInfo)
|
||||
{
|
||||
latch.countDown();
|
||||
}
|
||||
|
@ -199,7 +201,7 @@ public class IdleTimeoutTest extends AbstractTest
|
|||
client.setIdleTimeout(idleTimeout);
|
||||
Session session = client.connect(address, null).get(5, TimeUnit.SECONDS);
|
||||
|
||||
session.syn(new SynInfo(true), null);
|
||||
session.syn(new SynInfo(new Fields(), true), null);
|
||||
|
||||
Assert.assertTrue(latch.await(2 * idleTimeout, TimeUnit.MILLISECONDS));
|
||||
}
|
||||
|
@ -213,12 +215,12 @@ public class IdleTimeoutTest extends AbstractTest
|
|||
@Override
|
||||
public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
|
||||
{
|
||||
stream.reply(new ReplyInfo(true));
|
||||
stream.reply(new ReplyInfo(true), new Callback.Adapter());
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGoAway(Session session, GoAwayInfo goAwayInfo)
|
||||
public void onGoAway(Session session, GoAwayReceivedInfo goAwayInfo)
|
||||
{
|
||||
latch.countDown();
|
||||
}
|
||||
|
@ -233,7 +235,7 @@ public class IdleTimeoutTest extends AbstractTest
|
|||
Session session = client.connect(address, null).get(5, TimeUnit.SECONDS);
|
||||
|
||||
final CountDownLatch replyLatch = new CountDownLatch(1);
|
||||
session.syn(new SynInfo(true), new StreamFrameListener.Adapter()
|
||||
session.syn(new SynInfo(new Fields(), true), new StreamFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onReply(Stream stream, ReplyInfo replyInfo)
|
||||
|
|
|
@ -24,10 +24,10 @@ import java.util.concurrent.TimeUnit;
|
|||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.eclipse.jetty.spdy.api.PingInfo;
|
||||
import org.eclipse.jetty.spdy.api.PingResultInfo;
|
||||
import org.eclipse.jetty.spdy.api.Session;
|
||||
import org.eclipse.jetty.spdy.api.SessionFrameListener;
|
||||
import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
@ -37,25 +37,25 @@ public class PingTest extends AbstractTest
|
|||
@Test
|
||||
public void testPingPong() throws Exception
|
||||
{
|
||||
final AtomicReference<PingInfo> ref = new AtomicReference<>();
|
||||
final AtomicReference<PingResultInfo> ref = new AtomicReference<>();
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
SessionFrameListener clientSessionFrameListener = new SessionFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onPing(Session session, PingInfo pingInfo)
|
||||
public void onPing(Session session, PingResultInfo pingInfo)
|
||||
{
|
||||
ref.set(pingInfo);
|
||||
latch.countDown();
|
||||
}
|
||||
};
|
||||
Session session = startClient(startServer(null), clientSessionFrameListener);
|
||||
PingInfo pingInfo = session.ping().get(5, TimeUnit.SECONDS);
|
||||
Assert.assertEquals(1, pingInfo.getPingId() % 2);
|
||||
PingResultInfo pingResultInfo = session.ping(new PingInfo(5, TimeUnit.SECONDS));
|
||||
Assert.assertEquals(1, pingResultInfo.getPingId() % 2);
|
||||
|
||||
Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
|
||||
PingInfo pongInfo = ref.get();
|
||||
PingResultInfo pongInfo = ref.get();
|
||||
Assert.assertNotNull(pongInfo);
|
||||
Assert.assertEquals(pingInfo.getPingId(), pongInfo.getPingId());
|
||||
Assert.assertEquals(pingResultInfo.getPingId(), pongInfo.getPingId());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -69,10 +69,10 @@ public class PingTest extends AbstractTest
|
|||
@Override
|
||||
public void onConnect(Session session)
|
||||
{
|
||||
session.ping(0, TimeUnit.MILLISECONDS, new Promise.Adapter<PingInfo>()
|
||||
session.ping(new PingInfo(), new Promise.Adapter<PingResultInfo>()
|
||||
{
|
||||
@Override
|
||||
public void succeeded(PingInfo pingInfo)
|
||||
public void succeeded(PingResultInfo pingInfo)
|
||||
{
|
||||
pingId = pingInfo.getPingId();
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ public class PingTest extends AbstractTest
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onPing(Session session, PingInfo pingInfo)
|
||||
public void onPing(Session session, PingResultInfo pingInfo)
|
||||
{
|
||||
Assert.assertEquals(0, pingInfo.getPingId() % 2);
|
||||
Assert.assertEquals(pingId, pingInfo.getPingId());
|
||||
|
|
|
@ -29,6 +29,7 @@ import org.eclipse.jetty.io.MappedByteBufferPool;
|
|||
import org.eclipse.jetty.spdy.StandardCompressionFactory;
|
||||
import org.eclipse.jetty.spdy.api.BytesDataInfo;
|
||||
import org.eclipse.jetty.spdy.api.DataInfo;
|
||||
import org.eclipse.jetty.spdy.api.GoAwayInfo;
|
||||
import org.eclipse.jetty.spdy.api.HeadersInfo;
|
||||
import org.eclipse.jetty.spdy.api.RstInfo;
|
||||
import org.eclipse.jetty.spdy.api.SPDY;
|
||||
|
@ -43,6 +44,7 @@ import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
|
|||
import org.eclipse.jetty.spdy.frames.ControlFrameType;
|
||||
import org.eclipse.jetty.spdy.frames.SynReplyFrame;
|
||||
import org.eclipse.jetty.spdy.generator.Generator;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
@ -64,7 +66,7 @@ public class ProtocolViolationsTest extends AbstractTest
|
|||
{
|
||||
try
|
||||
{
|
||||
stream.data(new StringDataInfo("failure", true));
|
||||
stream.data(new StringDataInfo("failure", true), new Callback.Adapter());
|
||||
return null;
|
||||
}
|
||||
catch (IllegalStateException x)
|
||||
|
@ -82,7 +84,7 @@ public class ProtocolViolationsTest extends AbstractTest
|
|||
resetLatch.countDown();
|
||||
}
|
||||
});
|
||||
session.syn(new SynInfo(true), null);
|
||||
session.syn(new SynInfo(new Fields(), true), null);
|
||||
Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
|
||||
Assert.assertTrue(resetLatch.await(5, TimeUnit.SECONDS));
|
||||
}
|
||||
|
@ -94,7 +96,7 @@ public class ProtocolViolationsTest extends AbstractTest
|
|||
server.bind(new InetSocketAddress("localhost", 0));
|
||||
|
||||
Session session = startClient(new InetSocketAddress("localhost", server.socket().getLocalPort()), null);
|
||||
session.syn(new SynInfo(true), null);
|
||||
session.syn(new SynInfo(new Fields(), true), null);
|
||||
|
||||
SocketChannel channel = server.accept();
|
||||
ByteBuffer readBuffer = ByteBuffer.allocate(1024);
|
||||
|
@ -114,7 +116,7 @@ public class ProtocolViolationsTest extends AbstractTest
|
|||
Assert.assertEquals(ControlFrameType.RST_STREAM.getCode(), readBuffer.getShort(2));
|
||||
Assert.assertEquals(streamId, readBuffer.getInt(8));
|
||||
|
||||
session.goAway().get(5,TimeUnit.SECONDS);
|
||||
session.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
|
||||
|
||||
server.close();
|
||||
}
|
||||
|
@ -123,7 +125,7 @@ public class ProtocolViolationsTest extends AbstractTest
|
|||
public void testSendDataAfterCloseIsIllegal() throws Exception
|
||||
{
|
||||
Session session = startClient(startServer(null), null);
|
||||
Stream stream = session.syn(new SynInfo(true), null).get(5, TimeUnit.SECONDS);
|
||||
Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), true, (byte)0), null);
|
||||
stream.data(new StringDataInfo("test", true));
|
||||
}
|
||||
|
||||
|
@ -131,7 +133,7 @@ public class ProtocolViolationsTest extends AbstractTest
|
|||
public void testSendHeadersAfterCloseIsIllegal() throws Exception
|
||||
{
|
||||
Session session = startClient(startServer(null), null);
|
||||
Stream stream = session.syn(new SynInfo(true), null).get(5, TimeUnit.SECONDS);
|
||||
Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), true, (byte)0), null);
|
||||
stream.headers(new HeadersInfo(new Fields(), true));
|
||||
}
|
||||
|
||||
|
@ -143,7 +145,7 @@ public class ProtocolViolationsTest extends AbstractTest
|
|||
|
||||
Session session = startClient(new InetSocketAddress("localhost", server.socket().getLocalPort()), null);
|
||||
final CountDownLatch dataLatch = new CountDownLatch(2);
|
||||
session.syn(new SynInfo(false), new StreamFrameListener.Adapter()
|
||||
session.syn(new SynInfo(new Fields(), false), new StreamFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onData(Stream stream, DataInfo dataInfo)
|
||||
|
@ -176,7 +178,7 @@ public class ProtocolViolationsTest extends AbstractTest
|
|||
|
||||
Assert.assertFalse(dataLatch.await(1, TimeUnit.SECONDS));
|
||||
|
||||
session.goAway().get(5,TimeUnit.SECONDS);
|
||||
session.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
|
||||
|
||||
server.close();
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ import java.util.concurrent.CyclicBarrier;
|
|||
import java.util.concurrent.Exchanger;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
|
@ -37,7 +38,8 @@ import org.eclipse.jetty.io.MappedByteBufferPool;
|
|||
import org.eclipse.jetty.spdy.StandardCompressionFactory;
|
||||
import org.eclipse.jetty.spdy.api.BytesDataInfo;
|
||||
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.PushInfo;
|
||||
import org.eclipse.jetty.spdy.api.ReplyInfo;
|
||||
import org.eclipse.jetty.spdy.api.RstInfo;
|
||||
import org.eclipse.jetty.spdy.api.SPDY;
|
||||
|
@ -62,6 +64,8 @@ import org.eclipse.jetty.spdy.parser.Parser.Listener;
|
|||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -73,6 +77,8 @@ import static org.junit.Assert.fail;
|
|||
|
||||
public class PushStreamTest extends AbstractTest
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(PushStreamTest.class);
|
||||
|
||||
@Test
|
||||
public void testSynPushStream() throws Exception
|
||||
{
|
||||
|
@ -84,8 +90,8 @@ public class PushStreamTest extends AbstractTest
|
|||
@Override
|
||||
public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
|
||||
{
|
||||
stream.reply(new ReplyInfo(false));
|
||||
stream.syn(new SynInfo(true));
|
||||
stream.reply(new ReplyInfo(false), new Callback.Adapter());
|
||||
stream.push(new PushInfo(new Fields(), true), new Promise.Adapter<Stream>());
|
||||
return null;
|
||||
}
|
||||
}), new SessionFrameListener.Adapter()
|
||||
|
@ -93,13 +99,13 @@ public class PushStreamTest extends AbstractTest
|
|||
@Override
|
||||
public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
|
||||
{
|
||||
assertThat("streamId is even",stream.getId() % 2,is(0));
|
||||
assertThat("stream is unidirectional",stream.isUnidirectional(),is(true));
|
||||
assertThat("stream is closed",stream.isClosed(),is(true));
|
||||
assertThat("stream has associated stream",stream.getAssociatedStream(),notNullValue());
|
||||
assertThat("streamId is even", stream.getId() % 2, is(0));
|
||||
assertThat("stream is unidirectional", stream.isUnidirectional(), is(true));
|
||||
assertThat("stream is closed", stream.isClosed(), is(true));
|
||||
assertThat("stream has associated stream", stream.getAssociatedStream(), notNullValue());
|
||||
try
|
||||
{
|
||||
stream.reply(new ReplyInfo(false));
|
||||
stream.reply(new ReplyInfo(false), new Callback.Adapter());
|
||||
fail("Cannot reply to push streams");
|
||||
}
|
||||
catch (IllegalStateException x)
|
||||
|
@ -112,10 +118,10 @@ public class PushStreamTest extends AbstractTest
|
|||
}
|
||||
});
|
||||
|
||||
Stream stream = clientSession.syn(new SynInfo(true),null).get();
|
||||
assertThat("onSyn has been called",pushStreamLatch.await(5,TimeUnit.SECONDS),is(true));
|
||||
Stream stream = clientSession.syn(new SynInfo(new Fields(), true), null);
|
||||
assertThat("onSyn has been called", pushStreamLatch.await(5, TimeUnit.SECONDS), is(true));
|
||||
Stream pushStream = pushStreamRef.get();
|
||||
assertThat("main stream and associated stream are the same",stream,sameInstance(pushStream.getAssociatedStream()));
|
||||
assertThat("main stream and associated stream are the same", stream, sameInstance(pushStream.getAssociatedStream()));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -134,10 +140,10 @@ public class PushStreamTest extends AbstractTest
|
|||
@Override
|
||||
public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
|
||||
{
|
||||
stream.reply(new ReplyInfo(false));
|
||||
stream.reply(new ReplyInfo(false), new Callback.Adapter());
|
||||
try
|
||||
{
|
||||
replyBarrier.await(5,TimeUnit.SECONDS);
|
||||
replyBarrier.await(5, TimeUnit.SECONDS);
|
||||
return new StreamFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
|
@ -147,14 +153,14 @@ public class PushStreamTest extends AbstractTest
|
|||
{
|
||||
if (dataInfo.isClose())
|
||||
{
|
||||
stream.data(new StringDataInfo("close stream",true));
|
||||
closeBarrier.await(5,TimeUnit.SECONDS);
|
||||
stream.data(new StringDataInfo("close stream", true));
|
||||
closeBarrier.await(5, TimeUnit.SECONDS);
|
||||
}
|
||||
streamDataSent.countDown();
|
||||
if (pushStreamDataReceived.getCount() == 2)
|
||||
{
|
||||
Stream pushStream = stream.syn(new SynInfo(false)).get();
|
||||
streamExchanger.exchange(pushStream,5,TimeUnit.SECONDS);
|
||||
Stream pushStream = stream.push(new PushInfo(new Fields(), false));
|
||||
streamExchanger.exchange(pushStream, 5, TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
|
@ -171,7 +177,7 @@ public class PushStreamTest extends AbstractTest
|
|||
}
|
||||
}
|
||||
|
||||
}),new SessionFrameListener.Adapter()
|
||||
}), new SessionFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
|
||||
|
@ -183,20 +189,20 @@ public class PushStreamTest extends AbstractTest
|
|||
public void onData(Stream stream, DataInfo dataInfo)
|
||||
{
|
||||
pushStreamDataReceived.countDown();
|
||||
super.onData(stream,dataInfo);
|
||||
super.onData(stream, dataInfo);
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
Stream stream = clientSession.syn(new SynInfo(false),new StreamFrameListener.Adapter()
|
||||
Stream stream = clientSession.syn(new SynInfo(new Fields(), false), new StreamFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onReply(Stream stream, ReplyInfo replyInfo)
|
||||
{
|
||||
try
|
||||
{
|
||||
replyBarrier.await(5,TimeUnit.SECONDS);
|
||||
replyBarrier.await(5, TimeUnit.SECONDS);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -209,29 +215,29 @@ public class PushStreamTest extends AbstractTest
|
|||
{
|
||||
try
|
||||
{
|
||||
closeBarrier.await(5,TimeUnit.SECONDS);
|
||||
closeBarrier.await(5, TimeUnit.SECONDS);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
exceptionCountDownLatch.countDown();
|
||||
}
|
||||
}
|
||||
}).get();
|
||||
});
|
||||
|
||||
replyBarrier.await(5,TimeUnit.SECONDS);
|
||||
stream.data(new StringDataInfo("client data",false));
|
||||
Stream pushStream = streamExchanger.exchange(null,5,TimeUnit.SECONDS);
|
||||
pushStream.data(new StringDataInfo("first push data frame",false));
|
||||
replyBarrier.await(5, TimeUnit.SECONDS);
|
||||
stream.data(new StringDataInfo("client data", false));
|
||||
Stream pushStream = streamExchanger.exchange(null, 5, TimeUnit.SECONDS);
|
||||
pushStream.data(new StringDataInfo("first push data frame", false));
|
||||
// nasty, but less complex than using another cyclicBarrier for example
|
||||
while (pushStreamDataReceived.getCount() != 1)
|
||||
Thread.sleep(1);
|
||||
stream.data(new StringDataInfo("client close",true));
|
||||
closeBarrier.await(5,TimeUnit.SECONDS);
|
||||
assertThat("stream is closed",stream.isClosed(),is(true));
|
||||
pushStream.data(new StringDataInfo("second push data frame while associated stream has been closed already",false));
|
||||
assertThat("2 pushStream data frames have been received.",pushStreamDataReceived.await(5,TimeUnit.SECONDS),is(true));
|
||||
assertThat("2 data frames have been sent",streamDataSent.await(5,TimeUnit.SECONDS),is(true));
|
||||
assertThatNoExceptionOccured(exceptionCountDownLatch);
|
||||
stream.data(new StringDataInfo("client close", true));
|
||||
closeBarrier.await(5, TimeUnit.SECONDS);
|
||||
assertThat("stream is closed", stream.isClosed(), is(true));
|
||||
pushStream.data(new StringDataInfo("second push data frame while associated stream has been closed already", false));
|
||||
assertThat("2 pushStream data frames have been received.", pushStreamDataReceived.await(5, TimeUnit.SECONDS), is(true));
|
||||
assertThat("2 data frames have been sent", streamDataSent.await(5, TimeUnit.SECONDS), is(true));
|
||||
assertThatNoExceptionOccurred(exceptionCountDownLatch);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -244,21 +250,22 @@ public class PushStreamTest extends AbstractTest
|
|||
@Override
|
||||
public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
|
||||
{
|
||||
stream.reply(new ReplyInfo(true));
|
||||
stream.syn(new SynInfo(false),1,TimeUnit.SECONDS,new Promise.Adapter<Stream>()
|
||||
{
|
||||
@Override
|
||||
public void failed(Throwable x)
|
||||
{
|
||||
pushStreamFailedLatch.countDown();
|
||||
}
|
||||
});
|
||||
return super.onSyn(stream,synInfo);
|
||||
stream.reply(new ReplyInfo(true), new Callback.Adapter());
|
||||
stream.push(new PushInfo(1, TimeUnit.SECONDS, new Fields(), false),
|
||||
new Promise.Adapter<Stream>()
|
||||
{
|
||||
@Override
|
||||
public void failed(Throwable x)
|
||||
{
|
||||
pushStreamFailedLatch.countDown();
|
||||
}
|
||||
});
|
||||
return super.onSyn(stream, synInfo);
|
||||
}
|
||||
}),new SessionFrameListener.Adapter());
|
||||
}), new SessionFrameListener.Adapter());
|
||||
|
||||
clientSession.syn(new SynInfo(true),null);
|
||||
assertThat("pushStream syn has failed",pushStreamFailedLatch.await(5,TimeUnit.SECONDS),is(true));
|
||||
clientSession.syn(new SynInfo(new Fields(), true), null);
|
||||
assertThat("pushStream push has failed", pushStreamFailedLatch.await(5, TimeUnit.SECONDS), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -278,11 +285,11 @@ public class PushStreamTest extends AbstractTest
|
|||
{
|
||||
try
|
||||
{
|
||||
Stream pushStream = stream.syn(new SynInfo(false)).get();
|
||||
Stream pushStream = stream.push(new PushInfo(new Fields(), false));
|
||||
stream.reply(new ReplyInfo(true));
|
||||
// wait until stream is closed
|
||||
streamClosedLatch.await(5,TimeUnit.SECONDS);
|
||||
pushStream.data(new BytesDataInfo(transferBytes,true));
|
||||
streamClosedLatch.await(5, TimeUnit.SECONDS);
|
||||
pushStream.data(new BytesDataInfo(transferBytes, true), new Callback.Adapter());
|
||||
return null;
|
||||
}
|
||||
catch (Exception e)
|
||||
|
@ -291,7 +298,7 @@ public class PushStreamTest extends AbstractTest
|
|||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
}),new SessionFrameListener.Adapter()
|
||||
}), new SessionFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
|
||||
|
@ -310,7 +317,7 @@ public class PushStreamTest extends AbstractTest
|
|||
try
|
||||
{
|
||||
receivedBytes.flip();
|
||||
exchanger.exchange(receivedBytes.slice(),5,TimeUnit.SECONDS);
|
||||
exchanger.exchange(receivedBytes.slice(), 5, TimeUnit.SECONDS);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -322,23 +329,23 @@ public class PushStreamTest extends AbstractTest
|
|||
}
|
||||
});
|
||||
|
||||
Stream stream = clientSession.syn(new SynInfo(true),new StreamFrameListener.Adapter()
|
||||
Stream stream = clientSession.syn(new SynInfo(new Fields(), true), new StreamFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onReply(Stream stream, ReplyInfo replyInfo)
|
||||
{
|
||||
streamClosedLatch.countDown();
|
||||
super.onReply(stream,replyInfo);
|
||||
super.onReply(stream, replyInfo);
|
||||
}
|
||||
}).get();
|
||||
});
|
||||
|
||||
ByteBuffer receivedBytes = exchanger.exchange(null,5,TimeUnit.SECONDS);
|
||||
ByteBuffer receivedBytes = exchanger.exchange(null, 5, TimeUnit.SECONDS);
|
||||
|
||||
assertThat("received byte array is the same as transferred byte array",Arrays.equals(transferBytes,receivedBytes.array()),is(true));
|
||||
assertThat("onReply has been called to close the stream",streamClosedLatch.await(5,TimeUnit.SECONDS),is(true));
|
||||
assertThat("stream is closed",stream.isClosed(),is(true));
|
||||
assertThat("all data has been received",allDataReceived.await(20,TimeUnit.SECONDS),is(true));
|
||||
assertThatNoExceptionOccured(exceptionCountDownLatch);
|
||||
assertThat("received byte array is the same as transferred byte array", Arrays.equals(transferBytes, receivedBytes.array()), is(true));
|
||||
assertThat("onReply has been called to close the stream", streamClosedLatch.await(5, TimeUnit.SECONDS), is(true));
|
||||
assertThat("stream is closed", stream.isClosed(), is(true));
|
||||
assertThat("all data has been received", allDataReceived.await(20, TimeUnit.SECONDS), is(true));
|
||||
assertThatNoExceptionOccurred(exceptionCountDownLatch);
|
||||
}
|
||||
|
||||
private byte[] createHugeByteArray(int sizeInBytes)
|
||||
|
@ -364,10 +371,11 @@ public class PushStreamTest extends AbstractTest
|
|||
}
|
||||
|
||||
private volatile boolean read = true;
|
||||
private void testNoMoreFramesAreSentOnPushStreamAfterClientResetsThePushStream(final boolean flowControl) throws Exception, IOException, InterruptedException
|
||||
|
||||
private void testNoMoreFramesAreSentOnPushStreamAfterClientResetsThePushStream(final boolean flowControl) throws Exception
|
||||
{
|
||||
final short version = SPDY.V3;
|
||||
final AtomicBoolean unexpectedExceptionOccured = new AtomicBoolean(false);
|
||||
final AtomicBoolean unexpectedExceptionOccurred = new AtomicBoolean(false);
|
||||
final CountDownLatch resetReceivedLatch = new CountDownLatch(1);
|
||||
final CountDownLatch allDataFramesReceivedLatch = new CountDownLatch(1);
|
||||
final CountDownLatch goAwayReceivedLatch = new CountDownLatch(1);
|
||||
|
@ -385,20 +393,28 @@ public class PushStreamTest extends AbstractTest
|
|||
@Override
|
||||
public void run()
|
||||
{
|
||||
Stream pushStream=null;
|
||||
Stream pushStream = null;
|
||||
try
|
||||
{
|
||||
stream.reply(new ReplyInfo(false));
|
||||
pushStream = stream.syn(new SynInfo(false)).get();
|
||||
resetReceivedLatch.await(5,TimeUnit.SECONDS);
|
||||
stream.reply(new ReplyInfo(false), new Callback.Adapter());
|
||||
pushStream = stream.push(new PushInfo(new Fields(), false));
|
||||
resetReceivedLatch.await(5, TimeUnit.SECONDS);
|
||||
}
|
||||
catch (InterruptedException | ExecutionException e)
|
||||
catch (InterruptedException | ExecutionException | TimeoutException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
unexpectedExceptionOccured.set(true);
|
||||
unexpectedExceptionOccurred.set(true);
|
||||
}
|
||||
assert pushStream != null;
|
||||
try
|
||||
{
|
||||
pushStream.data(new BytesDataInfo(transferBytes, true));
|
||||
stream.data(new StringDataInfo("close", true));
|
||||
}
|
||||
catch (InterruptedException | ExecutionException | TimeoutException e)
|
||||
{
|
||||
LOG.debug(e.getMessage());
|
||||
}
|
||||
pushStream.data(new BytesDataInfo(transferBytes,true));
|
||||
stream.data(new StringDataInfo("close",true));
|
||||
}
|
||||
}).start();
|
||||
return null;
|
||||
|
@ -411,7 +427,7 @@ public class PushStreamTest extends AbstractTest
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onGoAway(Session session, GoAwayInfo goAwayInfo)
|
||||
public void onGoAway(Session session, GoAwayReceivedInfo goAwayInfo)
|
||||
{
|
||||
goAwayReceivedLatch.countDown();
|
||||
}
|
||||
|
@ -420,9 +436,9 @@ public class PushStreamTest extends AbstractTest
|
|||
final SocketChannel channel = SocketChannel.open(serverAddress);
|
||||
final Generator generator = new Generator(new MappedByteBufferPool(), new StandardCompressionFactory.StandardCompressor());
|
||||
int streamId = 1;
|
||||
ByteBuffer writeBuffer = generator.control(new SynStreamFrame(version,(byte)0,streamId,0,(byte)0,(short)0,new Fields()));
|
||||
ByteBuffer writeBuffer = generator.control(new SynStreamFrame(version, (byte)0, streamId, 0, (byte)0, (short)0, new Fields()));
|
||||
channel.write(writeBuffer);
|
||||
assertThat("writeBuffer is fully written",writeBuffer.hasRemaining(), is(false));
|
||||
assertThat("writeBuffer is fully written", writeBuffer.hasRemaining(), is(false));
|
||||
|
||||
final Parser parser = new Parser(new StandardCompressionFactory.StandardDecompressor());
|
||||
parser.addListener(new Listener.Adapter()
|
||||
|
@ -432,9 +448,10 @@ public class PushStreamTest extends AbstractTest
|
|||
@Override
|
||||
public void onControlFrame(ControlFrame frame)
|
||||
{
|
||||
if(frame instanceof SynStreamFrame){
|
||||
if (frame instanceof SynStreamFrame)
|
||||
{
|
||||
int pushStreamId = ((SynStreamFrame)frame).getStreamId();
|
||||
ByteBuffer writeBuffer = generator.control(new RstStreamFrame(version,pushStreamId,StreamStatus.CANCEL_STREAM.getCode(version)));
|
||||
ByteBuffer writeBuffer = generator.control(new RstStreamFrame(version, pushStreamId, StreamStatus.CANCEL_STREAM.getCode(version)));
|
||||
try
|
||||
{
|
||||
channel.write(writeBuffer);
|
||||
|
@ -442,7 +459,7 @@ public class PushStreamTest extends AbstractTest
|
|||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
unexpectedExceptionOccured.set(true);
|
||||
unexpectedExceptionOccurred.set(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -450,15 +467,16 @@ public class PushStreamTest extends AbstractTest
|
|||
@Override
|
||||
public void onDataFrame(DataFrame frame, ByteBuffer data)
|
||||
{
|
||||
if(frame.getStreamId() == 2)
|
||||
if (frame.getStreamId() == 2)
|
||||
bytesRead = bytesRead + frame.getLength();
|
||||
if(bytesRead == dataSizeInBytes){
|
||||
if (bytesRead == dataSizeInBytes)
|
||||
{
|
||||
allDataFramesReceivedLatch.countDown();
|
||||
return;
|
||||
}
|
||||
if (flowControl)
|
||||
{
|
||||
ByteBuffer writeBuffer = generator.control(new WindowUpdateFrame(version,frame.getStreamId(),frame.getLength()));
|
||||
ByteBuffer writeBuffer = generator.control(new WindowUpdateFrame(version, frame.getStreamId(), frame.getLength()));
|
||||
try
|
||||
{
|
||||
channel.write(writeBuffer);
|
||||
|
@ -466,7 +484,7 @@ public class PushStreamTest extends AbstractTest
|
|||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
unexpectedExceptionOccured.set(true);
|
||||
unexpectedExceptionOccurred.set(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -477,7 +495,7 @@ public class PushStreamTest extends AbstractTest
|
|||
@Override
|
||||
public void run()
|
||||
{
|
||||
ByteBuffer readBuffer = ByteBuffer.allocate(dataSizeInBytes*2);
|
||||
ByteBuffer readBuffer = ByteBuffer.allocate(dataSizeInBytes * 2);
|
||||
while (read)
|
||||
{
|
||||
try
|
||||
|
@ -487,7 +505,7 @@ public class PushStreamTest extends AbstractTest
|
|||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
unexpectedExceptionOccured.set(true);
|
||||
unexpectedExceptionOccurred.set(true);
|
||||
}
|
||||
readBuffer.flip();
|
||||
parser.parse(readBuffer);
|
||||
|
@ -499,15 +517,15 @@ public class PushStreamTest extends AbstractTest
|
|||
reader.start();
|
||||
read = false;
|
||||
|
||||
assertThat("no unexpected exceptions occured", unexpectedExceptionOccured.get(), is(false));
|
||||
assertThat("not all dataframes have been received as the pushstream has been reset by the client.",allDataFramesReceivedLatch.await(streamId,TimeUnit.SECONDS),is(false));
|
||||
assertThat("no unexpected exceptions occurred", unexpectedExceptionOccurred.get(), is(false));
|
||||
assertThat("not all dataframes have been received as the pushstream has been reset by the client.", allDataFramesReceivedLatch.await(streamId, TimeUnit.SECONDS), is(false));
|
||||
|
||||
|
||||
ByteBuffer buffer = generator.control(new GoAwayFrame(version, streamId, SessionStatus.OK.getCode()));
|
||||
channel.write(buffer);
|
||||
Assert.assertThat(buffer.hasRemaining(), is(false));
|
||||
|
||||
assertThat("GoAway frame is received by server", goAwayReceivedLatch.await(5,TimeUnit.SECONDS), is(true));
|
||||
assertThat("GoAway frame is received by server", goAwayReceivedLatch.await(5, TimeUnit.SECONDS), is(true));
|
||||
channel.shutdownOutput();
|
||||
channel.close();
|
||||
}
|
||||
|
@ -522,42 +540,42 @@ public class PushStreamTest extends AbstractTest
|
|||
@Override
|
||||
public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
|
||||
{
|
||||
stream.syn(new SynInfo(false));
|
||||
stream.push(new PushInfo(new Fields(), false), new Promise.Adapter<Stream>());
|
||||
return null;
|
||||
}
|
||||
}),new SessionFrameListener.Adapter()
|
||||
}), new SessionFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
|
||||
{
|
||||
assertStreamIdIsEven(stream);
|
||||
pushStreamIdIsEvenLatch.countDown();
|
||||
return super.onSyn(stream,synInfo);
|
||||
return super.onSyn(stream, synInfo);
|
||||
}
|
||||
});
|
||||
|
||||
Stream stream = clientSession.syn(new SynInfo(false),null).get();
|
||||
Stream stream2 = clientSession.syn(new SynInfo(false),null).get();
|
||||
Stream stream3 = clientSession.syn(new SynInfo(false),null).get();
|
||||
Stream stream = clientSession.syn(new SynInfo(new Fields(), false), null);
|
||||
Stream stream2 = clientSession.syn(new SynInfo(new Fields(), false), null);
|
||||
Stream stream3 = clientSession.syn(new SynInfo(new Fields(), false), null);
|
||||
assertStreamIdIsOdd(stream);
|
||||
assertStreamIdIsOdd(stream2);
|
||||
assertStreamIdIsOdd(stream3);
|
||||
|
||||
assertThat("all pushStreams had even ids",pushStreamIdIsEvenLatch.await(5,TimeUnit.SECONDS),is(true));
|
||||
assertThat("all pushStreams had even ids", pushStreamIdIsEvenLatch.await(5, TimeUnit.SECONDS), is(true));
|
||||
}
|
||||
|
||||
private void assertStreamIdIsEven(Stream stream)
|
||||
{
|
||||
assertThat("streamId is odd",stream.getId() % 2,is(0));
|
||||
assertThat("streamId is odd", stream.getId() % 2, is(0));
|
||||
}
|
||||
|
||||
private void assertStreamIdIsOdd(Stream stream)
|
||||
{
|
||||
assertThat("streamId is odd",stream.getId() % 2,is(1));
|
||||
assertThat("streamId is odd", stream.getId() % 2, is(1));
|
||||
}
|
||||
|
||||
private void assertThatNoExceptionOccured(final CountDownLatch exceptionCountDownLatch) throws InterruptedException
|
||||
private void assertThatNoExceptionOccurred(final CountDownLatch exceptionCountDownLatch) throws InterruptedException
|
||||
{
|
||||
assertThat("No exception occured",exceptionCountDownLatch.await(1,TimeUnit.SECONDS),is(false));
|
||||
assertThat("No exception occurred", exceptionCountDownLatch.await(1, TimeUnit.SECONDS), is(false));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,8 @@ import org.eclipse.jetty.spdy.api.StringDataInfo;
|
|||
import org.eclipse.jetty.spdy.api.SynInfo;
|
||||
import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
import org.eclipse.jetty.util.FutureCallback;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
@ -46,12 +48,12 @@ public class ResetStreamTest extends AbstractTest
|
|||
@Test
|
||||
public void testResetStreamIsRemoved() throws Exception
|
||||
{
|
||||
Session session = startClient(startServer(new ServerSessionFrameListener.Adapter()/*TODO, true*/),null);
|
||||
Session session = startClient(startServer(new ServerSessionFrameListener.Adapter()/*TODO, true*/), null);
|
||||
|
||||
Stream stream = session.syn(new SynInfo(false),null).get(5,TimeUnit.SECONDS);
|
||||
session.rst(new RstInfo(stream.getId(),StreamStatus.CANCEL_STREAM)).get(5,TimeUnit.SECONDS);
|
||||
Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), false, (byte)0), null);
|
||||
session.rst(new RstInfo(5, TimeUnit.SECONDS, stream.getId(), StreamStatus.CANCEL_STREAM));
|
||||
|
||||
assertEquals("session expected to contain 0 streams",0,session.getStreams().size());
|
||||
assertEquals("session expected to contain 0 streams", 0, session.getStreams().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -67,11 +69,11 @@ public class ResetStreamTest extends AbstractTest
|
|||
{
|
||||
Session serverSession = stream.getSession();
|
||||
serverSessionRef.set(serverSession);
|
||||
serverSession.rst(new RstInfo(stream.getId(),StreamStatus.REFUSED_STREAM));
|
||||
serverSession.rst(new RstInfo(stream.getId(), StreamStatus.REFUSED_STREAM), new FutureCallback());
|
||||
synLatch.countDown();
|
||||
return null;
|
||||
}
|
||||
}),new SessionFrameListener.Adapter()
|
||||
}), new SessionFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onRst(Session session, RstInfo rstInfo)
|
||||
|
@ -80,17 +82,17 @@ public class ResetStreamTest extends AbstractTest
|
|||
}
|
||||
});
|
||||
|
||||
Stream stream = clientSession.syn(new SynInfo(false),null).get(5,TimeUnit.SECONDS);
|
||||
Stream stream = clientSession.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), false, (byte)0), null);
|
||||
|
||||
assertTrue("syncLatch didn't count down",synLatch.await(5,TimeUnit.SECONDS));
|
||||
assertTrue("syncLatch didn't count down", synLatch.await(5, TimeUnit.SECONDS));
|
||||
Session serverSession = serverSessionRef.get();
|
||||
assertEquals("serverSession expected to contain 0 streams",0,serverSession.getStreams().size());
|
||||
assertEquals("serverSession expected to contain 0 streams", 0, serverSession.getStreams().size());
|
||||
|
||||
assertTrue("rstLatch didn't count down",rstLatch.await(5,TimeUnit.SECONDS));
|
||||
assertTrue("rstLatch didn't count down", rstLatch.await(5, TimeUnit.SECONDS));
|
||||
// Need to sleep a while to give the chance to the implementation to remove the stream
|
||||
TimeUnit.SECONDS.sleep(1);
|
||||
assertTrue("stream is expected to be reset",stream.isReset());
|
||||
assertEquals("clientSession expected to contain 0 streams",0,clientSession.getStreams().size());
|
||||
assertTrue("stream is expected to be reset", stream.isReset());
|
||||
assertEquals("clientSession expected to contain 0 streams", 0, clientSession.getStreams().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -107,8 +109,8 @@ public class ResetStreamTest extends AbstractTest
|
|||
try
|
||||
{
|
||||
// Refuse the stream, we must ignore data frames
|
||||
assertTrue(synLatch.await(5,TimeUnit.SECONDS));
|
||||
stream.getSession().rst(new RstInfo(stream.getId(),StreamStatus.REFUSED_STREAM));
|
||||
assertTrue(synLatch.await(5, TimeUnit.SECONDS));
|
||||
stream.getSession().rst(new RstInfo(stream.getId(), StreamStatus.REFUSED_STREAM), new FutureCallback());
|
||||
return new StreamFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
|
@ -124,7 +126,7 @@ public class ResetStreamTest extends AbstractTest
|
|||
return null;
|
||||
}
|
||||
}
|
||||
}),new SessionFrameListener.Adapter()
|
||||
}), new SessionFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onRst(Session session, RstInfo rstInfo)
|
||||
|
@ -133,8 +135,8 @@ public class ResetStreamTest extends AbstractTest
|
|||
}
|
||||
});
|
||||
|
||||
Stream stream = session.syn(new SynInfo(false),null).get(5,TimeUnit.SECONDS);
|
||||
stream.data(new StringDataInfo("data",true),5,TimeUnit.SECONDS,new Callback.Adapter()
|
||||
Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), false, (byte)0), null);
|
||||
stream.data(new StringDataInfo(5, TimeUnit.SECONDS, "data", true), new Callback.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void succeeded()
|
||||
|
@ -143,9 +145,9 @@ public class ResetStreamTest extends AbstractTest
|
|||
}
|
||||
});
|
||||
|
||||
assertTrue("rstLatch didn't count down",rstLatch.await(5,TimeUnit.SECONDS));
|
||||
assertTrue("stream is expected to be reset",stream.isReset());
|
||||
assertFalse("dataLatch shouln't be count down",dataLatch.await(1,TimeUnit.SECONDS));
|
||||
assertTrue("rstLatch didn't count down", rstLatch.await(5, TimeUnit.SECONDS));
|
||||
assertTrue("stream is expected to be reset", stream.isReset());
|
||||
assertFalse("dataLatch shouldn't be count down", dataLatch.await(1, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -167,11 +169,11 @@ public class ResetStreamTest extends AbstractTest
|
|||
public void onData(Stream stream, DataInfo dataInfo)
|
||||
{
|
||||
dataLatch.countDown();
|
||||
stream.getSession().rst(new RstInfo(stream.getId(),StreamStatus.REFUSED_STREAM));
|
||||
stream.getSession().rst(new RstInfo(stream.getId(), StreamStatus.REFUSED_STREAM), new FutureCallback());
|
||||
}
|
||||
};
|
||||
}
|
||||
}),new SessionFrameListener.Adapter()
|
||||
}), new SessionFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onRst(Session session, RstInfo rstInfo)
|
||||
|
@ -180,11 +182,11 @@ public class ResetStreamTest extends AbstractTest
|
|||
}
|
||||
});
|
||||
|
||||
Stream stream = session.syn(new SynInfo(false),null).get(5,TimeUnit.SECONDS);
|
||||
assertThat("syn is received by server", synLatch.await(5,TimeUnit.SECONDS),is(true));
|
||||
stream.data(new StringDataInfo("data",false),5,TimeUnit.SECONDS,new Callback.Adapter());
|
||||
assertThat("stream is reset",rstLatch.await(5,TimeUnit.SECONDS),is(true));
|
||||
stream.data(new StringDataInfo("2nd dataframe",false),5L,TimeUnit.SECONDS,new Callback.Adapter()
|
||||
Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), false, (byte)0), null);
|
||||
assertThat("push is received by server", synLatch.await(5, TimeUnit.SECONDS), is(true));
|
||||
stream.data(new StringDataInfo(5, TimeUnit.SECONDS, "data", false), new Callback.Adapter());
|
||||
assertThat("stream is reset", rstLatch.await(5, TimeUnit.SECONDS), is(true));
|
||||
stream.data(new StringDataInfo(5, TimeUnit.SECONDS, "2nd dataframe", false), new Callback.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void failed(Throwable x)
|
||||
|
@ -193,8 +195,8 @@ public class ResetStreamTest extends AbstractTest
|
|||
}
|
||||
});
|
||||
|
||||
assertThat("2nd data call failed",failLatch.await(5,TimeUnit.SECONDS),is(true));
|
||||
assertThat("stream is reset",stream.isReset(),is(true));
|
||||
assertThat("2nd data call failed", failLatch.await(5, TimeUnit.SECONDS), is(true));
|
||||
assertThat("stream is reset", stream.isReset(), is(true));
|
||||
}
|
||||
|
||||
// TODO: If server already received 2nd dataframe after it rst, it should ignore it. Not easy to do.
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.util.concurrent.CountDownLatch;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.spdy.api.GoAwayInfo;
|
||||
import org.eclipse.jetty.spdy.api.GoAwayReceivedInfo;
|
||||
import org.eclipse.jetty.spdy.api.Session;
|
||||
import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
|
||||
import org.junit.Assert;
|
||||
|
@ -37,7 +38,7 @@ public class SPDYClientFactoryTest extends AbstractTest
|
|||
startClient(startServer(new ServerSessionFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onGoAway(Session session, GoAwayInfo goAwayInfo)
|
||||
public void onGoAway(Session session, GoAwayReceivedInfo goAwayReceivedInfo)
|
||||
{
|
||||
latch.countDown();
|
||||
}
|
||||
|
@ -58,7 +59,7 @@ public class SPDYClientFactoryTest extends AbstractTest
|
|||
{
|
||||
Session session = startClient(startServer(null), null);
|
||||
|
||||
session.goAway().get(5, TimeUnit.SECONDS);
|
||||
session.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
|
||||
|
||||
// Sleep a while to allow the factory to remove the session
|
||||
// since it is done asynchronously by the selector thread
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.util.concurrent.CountDownLatch;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.spdy.api.GoAwayInfo;
|
||||
import org.eclipse.jetty.spdy.api.GoAwayReceivedInfo;
|
||||
import org.eclipse.jetty.spdy.api.Session;
|
||||
import org.eclipse.jetty.spdy.api.SessionFrameListener;
|
||||
import org.junit.Assert;
|
||||
|
@ -37,7 +38,7 @@ public class SPDYServerConnectorTest extends AbstractTest
|
|||
startClient(startServer(null), new SessionFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onGoAway(Session session, GoAwayInfo goAwayInfo)
|
||||
public void onGoAway(Session session, GoAwayReceivedInfo goAwayReceivedInfo)
|
||||
{
|
||||
latch.countDown();
|
||||
}
|
||||
|
@ -58,7 +59,7 @@ public class SPDYServerConnectorTest extends AbstractTest
|
|||
{
|
||||
Session session = startClient(startServer(null), null);
|
||||
|
||||
session.goAway().get(5, TimeUnit.SECONDS);
|
||||
session.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
|
||||
|
||||
// Sleep a while to allow the connector to remove the session
|
||||
// since it is done asynchronously by the selector thread
|
||||
|
|
|
@ -25,6 +25,7 @@ import java.util.concurrent.TimeUnit;
|
|||
|
||||
import org.eclipse.jetty.npn.NextProtoNego;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.spdy.api.GoAwayInfo;
|
||||
import org.eclipse.jetty.spdy.api.Session;
|
||||
import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
|
||||
import org.eclipse.jetty.spdy.client.SPDYClient;
|
||||
|
@ -83,6 +84,6 @@ public class SSLEngineLeakTest extends AbstractTest
|
|||
private void avoidStackLocalVariables() throws Exception
|
||||
{
|
||||
Session session = startClient(startServer(null), null);
|
||||
session.goAway().get(5, TimeUnit.SECONDS);
|
||||
session.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.eclipse.jetty.spdy.api.SessionFrameListener;
|
|||
import org.eclipse.jetty.spdy.api.Settings;
|
||||
import org.eclipse.jetty.spdy.api.SettingsInfo;
|
||||
import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
|
||||
import org.eclipse.jetty.util.FutureCallback;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -106,7 +107,7 @@ public class SettingsTest extends AbstractTest
|
|||
@Override
|
||||
public void onConnect(Session session)
|
||||
{
|
||||
session.settings(serverSettingsInfo);
|
||||
session.settings(serverSettingsInfo, new FutureCallback());
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -57,14 +57,14 @@ public class SynDataReplyDataLoadTest extends AbstractTest
|
|||
@Override
|
||||
public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
|
||||
{
|
||||
stream.reply(new ReplyInfo(synInfo.getHeaders(), false));
|
||||
stream.reply(new ReplyInfo(synInfo.getHeaders(), false), new Callback.Adapter());
|
||||
return new StreamFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onData(Stream stream, DataInfo dataInfo)
|
||||
{
|
||||
ByteBuffer buffer = dataInfo.asByteBuffer(true);
|
||||
stream.data(new ByteBufferDataInfo(buffer, dataInfo.isClose()));
|
||||
stream.data(new ByteBufferDataInfo(buffer, dataInfo.isClose()), new Callback.Adapter());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -173,12 +173,13 @@ public class SynDataReplyDataLoadTest extends AbstractTest
|
|||
latch.countDown();
|
||||
}
|
||||
}
|
||||
}, 0, TimeUnit.SECONDS, new Promise.Adapter<Stream>()
|
||||
{
|
||||
}, new Promise.Adapter<Stream>()
|
||||
{
|
||||
@Override
|
||||
public void succeeded(Stream stream)
|
||||
{
|
||||
stream.data(new StringDataInfo("data_" + stream.getId(), true), 0, TimeUnit.SECONDS, new Callback.Adapter());
|
||||
stream.data(new StringDataInfo("data_" + stream.getId(), true),
|
||||
new Callback.Adapter());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -195,7 +196,8 @@ public class SynDataReplyDataLoadTest extends AbstractTest
|
|||
final AtomicInteger count = new AtomicInteger(2);
|
||||
final int index = i;
|
||||
counter.put(index, index);
|
||||
Stream stream = session.syn(new SynInfo(headers, false), new StreamFrameListener.Adapter()
|
||||
Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, headers, false, (byte)0),
|
||||
new StreamFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onReply(Stream stream, ReplyInfo replyInfo)
|
||||
|
@ -216,8 +218,8 @@ public class SynDataReplyDataLoadTest extends AbstractTest
|
|||
latch.countDown();
|
||||
}
|
||||
}
|
||||
}).get(5, TimeUnit.SECONDS);
|
||||
stream.data(new StringDataInfo("data_" + stream.getId(), true)).get(5, TimeUnit.SECONDS);
|
||||
});
|
||||
stream.data(new StringDataInfo(5, TimeUnit.SECONDS, "data_" + stream.getId(), true));
|
||||
}
|
||||
Assert.assertTrue(latch.await(iterations, TimeUnit.SECONDS));
|
||||
Assert.assertTrue(counter.toString(), counter.isEmpty());
|
||||
|
|
|
@ -64,7 +64,7 @@ public class SynReplyTest extends AbstractTest
|
|||
public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
|
||||
{
|
||||
Assert.assertTrue(stream.isHalfClosed());
|
||||
stream.reply(new ReplyInfo(new Fields(), true));
|
||||
stream.reply(new ReplyInfo(new Fields(), true), new Callback.Adapter());
|
||||
synLatch.countDown();
|
||||
return null;
|
||||
}
|
||||
|
@ -94,7 +94,8 @@ public class SynReplyTest extends AbstractTest
|
|||
});
|
||||
|
||||
final CountDownLatch replyLatch = new CountDownLatch(1);
|
||||
Stream stream = session.syn(new SynInfo(new Fields(), true), new StreamFrameListener.Adapter()
|
||||
Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), true, (byte)0),
|
||||
new StreamFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onReply(Stream stream, ReplyInfo replyInfo)
|
||||
|
@ -102,7 +103,7 @@ public class SynReplyTest extends AbstractTest
|
|||
Assert.assertTrue(stream.isClosed());
|
||||
replyLatch.countDown();
|
||||
}
|
||||
}).get(5, TimeUnit.SECONDS);
|
||||
});
|
||||
|
||||
Assert.assertTrue(synLatch.await(5, TimeUnit.SECONDS));
|
||||
|
||||
|
@ -147,7 +148,7 @@ public class SynReplyTest extends AbstractTest
|
|||
Assert.assertTrue(stream.isHalfClosed());
|
||||
Assert.assertFalse(stream.isClosed());
|
||||
|
||||
stream.reply(new ReplyInfo(true));
|
||||
stream.reply(new ReplyInfo(true), new Callback.Adapter());
|
||||
Assert.assertTrue(stream.isClosed());
|
||||
dataLatch.countDown();
|
||||
}
|
||||
|
@ -168,14 +169,15 @@ public class SynReplyTest extends AbstractTest
|
|||
});
|
||||
|
||||
final CountDownLatch replyLatch = new CountDownLatch(1);
|
||||
Stream stream = session.syn(new SynInfo(false), new StreamFrameListener.Adapter()
|
||||
Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), false, (byte)0),
|
||||
new StreamFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onReply(Stream stream, ReplyInfo replyInfo)
|
||||
{
|
||||
replyLatch.countDown();
|
||||
}
|
||||
}).get(5, TimeUnit.SECONDS);
|
||||
});
|
||||
stream.data(new BytesDataInfo(dataBytes, true));
|
||||
|
||||
Assert.assertTrue(synLatch.await(5, TimeUnit.SECONDS));
|
||||
|
@ -199,13 +201,13 @@ public class SynReplyTest extends AbstractTest
|
|||
{
|
||||
Assert.assertTrue(stream.isHalfClosed());
|
||||
|
||||
stream.reply(new ReplyInfo(false));
|
||||
stream.data(new StringDataInfo(data1, false), 5, TimeUnit.SECONDS, new Callback.Adapter()
|
||||
stream.reply(new ReplyInfo(false), new Callback.Adapter());
|
||||
stream.data(new StringDataInfo(5, TimeUnit.SECONDS, data1, false), new Callback.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void succeeded()
|
||||
{
|
||||
stream.data(new StringDataInfo(data2, true));
|
||||
stream.data(new StringDataInfo(data2, true), new Adapter());
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -216,7 +218,7 @@ public class SynReplyTest extends AbstractTest
|
|||
final CountDownLatch replyLatch = new CountDownLatch(1);
|
||||
final CountDownLatch dataLatch1 = new CountDownLatch(1);
|
||||
final CountDownLatch dataLatch2 = new CountDownLatch(1);
|
||||
session.syn(new SynInfo(true), new StreamFrameListener.Adapter()
|
||||
session.syn(new SynInfo(new Fields(), true), new StreamFrameListener.Adapter()
|
||||
{
|
||||
private AtomicInteger dataCount = new AtomicInteger();
|
||||
|
||||
|
@ -264,7 +266,7 @@ public class SynReplyTest extends AbstractTest
|
|||
@Override
|
||||
public void onConnect(Session session)
|
||||
{
|
||||
session.syn(new SynInfo(false), new StreamFrameListener.Adapter()
|
||||
session.syn(new SynInfo(new Fields(), false), new StreamFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onReply(Stream stream, ReplyInfo replyInfo)
|
||||
|
@ -279,12 +281,12 @@ public class SynReplyTest extends AbstractTest
|
|||
Assert.assertEquals(clientData, data);
|
||||
clientDataLatch.countDown();
|
||||
}
|
||||
}, 0, TimeUnit.MILLISECONDS, new Promise.Adapter<Stream>()
|
||||
}, new Promise.Adapter<Stream>()
|
||||
{
|
||||
@Override
|
||||
public void succeeded(Stream stream)
|
||||
{
|
||||
stream.data(new StringDataInfo(serverData, true));
|
||||
stream.data(new StringDataInfo(serverData, true), new Callback.Adapter());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -299,8 +301,8 @@ public class SynReplyTest extends AbstractTest
|
|||
{
|
||||
Assert.assertEquals(0, stream.getId() % 2);
|
||||
|
||||
stream.reply(new ReplyInfo(false));
|
||||
stream.data(new StringDataInfo(clientData, true));
|
||||
stream.reply(new ReplyInfo(false), new Callback.Adapter());
|
||||
stream.data(new StringDataInfo(clientData, true), new Callback.Adapter());
|
||||
synLatch.countDown();
|
||||
|
||||
return new StreamFrameListener.Adapter()
|
||||
|
@ -336,8 +338,8 @@ public class SynReplyTest extends AbstractTest
|
|||
{
|
||||
Assert.assertTrue(stream.isHalfClosed());
|
||||
|
||||
stream.reply(new ReplyInfo(false));
|
||||
stream.data(new StringDataInfo(data, true));
|
||||
stream.reply(new ReplyInfo(false), new Callback.Adapter());
|
||||
stream.data(new StringDataInfo(data, true), new Callback.Adapter());
|
||||
|
||||
return null;
|
||||
}
|
||||
|
@ -364,8 +366,8 @@ public class SynReplyTest extends AbstractTest
|
|||
dataLatch.countDown();
|
||||
}
|
||||
};
|
||||
session.syn(new SynInfo(true), clientStreamFrameListener);
|
||||
session.syn(new SynInfo(true), clientStreamFrameListener);
|
||||
session.syn(new SynInfo(new Fields(), true), clientStreamFrameListener);
|
||||
session.syn(new SynInfo(new Fields(), true), clientStreamFrameListener);
|
||||
|
||||
Assert.assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
|
||||
Assert.assertTrue(dataLatch.await(5, TimeUnit.SECONDS));
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -18,71 +18,68 @@
|
|||
|
||||
package org.eclipse.jetty.util;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.CyclicBarrier;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.eclipse.jetty.toolchain.test.AdvancedRunner;
|
||||
import org.eclipse.jetty.toolchain.test.annotation.Slow;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RunWith(AdvancedRunner.class)
|
||||
public class BlockingArrayQueueTest
|
||||
{
|
||||
|
||||
@Test
|
||||
public void testWrap() throws Exception
|
||||
{
|
||||
BlockingArrayQueue<String> queue = new BlockingArrayQueue<String>(3);
|
||||
BlockingArrayQueue<String> queue = new BlockingArrayQueue<>(3);
|
||||
|
||||
assertEquals(0,queue.size());
|
||||
Assert.assertEquals(0, queue.size());
|
||||
|
||||
for (int i=0;i<3;i++)
|
||||
for (int i=0;i<queue.getMaxCapacity();i++)
|
||||
{
|
||||
queue.offer("one");
|
||||
assertEquals(1,queue.size());
|
||||
Assert.assertEquals(1, queue.size());
|
||||
|
||||
queue.offer("two");
|
||||
assertEquals(2,queue.size());
|
||||
Assert.assertEquals(2, queue.size());
|
||||
|
||||
queue.offer("three");
|
||||
assertEquals(3,queue.size());
|
||||
Assert.assertEquals(3, queue.size());
|
||||
|
||||
assertEquals("one",queue.get(0));
|
||||
assertEquals("two",queue.get(1));
|
||||
assertEquals("three",queue.get(2));
|
||||
Assert.assertEquals("one", queue.get(0));
|
||||
Assert.assertEquals("two", queue.get(1));
|
||||
Assert.assertEquals("three", queue.get(2));
|
||||
|
||||
assertEquals("[one, two, three]",queue.toString());
|
||||
Assert.assertEquals("[one, two, three]", queue.toString());
|
||||
|
||||
assertEquals("one",queue.poll());
|
||||
assertEquals(2,queue.size());
|
||||
Assert.assertEquals("one", queue.poll());
|
||||
Assert.assertEquals(2, queue.size());
|
||||
|
||||
assertEquals("two",queue.poll());
|
||||
assertEquals(1,queue.size());
|
||||
Assert.assertEquals("two", queue.poll());
|
||||
Assert.assertEquals(1, queue.size());
|
||||
|
||||
assertEquals("three",queue.poll());
|
||||
assertEquals(0,queue.size());
|
||||
Assert.assertEquals("three", queue.poll());
|
||||
Assert.assertEquals(0, queue.size());
|
||||
|
||||
|
||||
queue.offer("xxx");
|
||||
assertEquals(1,queue.size());
|
||||
assertEquals("xxx",queue.poll());
|
||||
assertEquals(0,queue.size());
|
||||
|
||||
Assert.assertEquals(1, queue.size());
|
||||
Assert.assertEquals("xxx", queue.poll());
|
||||
Assert.assertEquals(0, queue.size());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemove() throws Exception
|
||||
{
|
||||
BlockingArrayQueue<String> queue = new BlockingArrayQueue<String>(3,3);
|
||||
BlockingArrayQueue<String> queue = new BlockingArrayQueue<>(3,3);
|
||||
|
||||
queue.add("0");
|
||||
queue.add("x");
|
||||
|
@ -96,23 +93,36 @@ public class BlockingArrayQueueTest
|
|||
}
|
||||
|
||||
for (int i=0;i<99;i++)
|
||||
assertEquals(i+"!",queue.get(i));
|
||||
Assert.assertEquals(i + "!", queue.get(i));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLimit() throws Exception
|
||||
{
|
||||
BlockingArrayQueue<String> queue = new BlockingArrayQueue<>(1,0,1);
|
||||
|
||||
String element = "0";
|
||||
Assert.assertTrue(queue.add(element));
|
||||
Assert.assertFalse(queue.offer("1"));
|
||||
|
||||
Assert.assertEquals(element, queue.poll());
|
||||
Assert.assertTrue(queue.add(element));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGrow() throws Exception
|
||||
{
|
||||
BlockingArrayQueue<String> queue = new BlockingArrayQueue<String>(3,2);
|
||||
assertEquals(3,queue.getCapacity());
|
||||
BlockingArrayQueue<String> queue = new BlockingArrayQueue<>(3,2);
|
||||
Assert.assertEquals(3, queue.getCapacity());
|
||||
|
||||
queue.add("a");
|
||||
queue.add("a");
|
||||
assertEquals(2,queue.size());
|
||||
assertEquals(3,queue.getCapacity());
|
||||
Assert.assertEquals(2, queue.size());
|
||||
Assert.assertEquals(3, queue.getCapacity());
|
||||
queue.add("a");
|
||||
queue.add("a");
|
||||
assertEquals(4,queue.size());
|
||||
assertEquals(5,queue.getCapacity());
|
||||
Assert.assertEquals(4, queue.size());
|
||||
Assert.assertEquals(5, queue.getCapacity());
|
||||
|
||||
int s=5;
|
||||
int c=5;
|
||||
|
@ -120,25 +130,25 @@ public class BlockingArrayQueueTest
|
|||
|
||||
for (int t=0;t<100;t++)
|
||||
{
|
||||
assertEquals(s,queue.size());
|
||||
assertEquals(c,queue.getCapacity());
|
||||
Assert.assertEquals(s, queue.size());
|
||||
Assert.assertEquals(c, queue.getCapacity());
|
||||
|
||||
for (int i=queue.size();i-->0;)
|
||||
queue.poll();
|
||||
assertEquals(0,queue.size());
|
||||
assertEquals(c,queue.getCapacity());
|
||||
Assert.assertEquals(0, queue.size());
|
||||
Assert.assertEquals(c, queue.getCapacity());
|
||||
|
||||
for (int i=queue.getCapacity();i-->0;)
|
||||
queue.add("a");
|
||||
queue.add("a");
|
||||
assertEquals(s+1,queue.size());
|
||||
assertEquals(c+2,queue.getCapacity());
|
||||
Assert.assertEquals(s + 1, queue.size());
|
||||
Assert.assertEquals(c + 2, queue.getCapacity());
|
||||
|
||||
queue.poll();
|
||||
queue.add("a");
|
||||
queue.add("a");
|
||||
assertEquals(s+2,queue.size());
|
||||
assertEquals(c+2,queue.getCapacity());
|
||||
Assert.assertEquals(s + 2, queue.size());
|
||||
Assert.assertEquals(c + 2, queue.getCapacity());
|
||||
|
||||
s+=2;
|
||||
c+=2;
|
||||
|
@ -151,7 +161,7 @@ public class BlockingArrayQueueTest
|
|||
{
|
||||
final String[] data=new String[4];
|
||||
|
||||
final BlockingArrayQueue<String> queue = new BlockingArrayQueue<String>();
|
||||
final BlockingArrayQueue<String> queue = new BlockingArrayQueue<>();
|
||||
|
||||
Thread thread = new Thread()
|
||||
{
|
||||
|
@ -168,8 +178,8 @@ public class BlockingArrayQueueTest
|
|||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
assertTrue(false);
|
||||
e.printStackTrace();
|
||||
Assert.fail();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -183,15 +193,12 @@ public class BlockingArrayQueueTest
|
|||
queue.offer("two");
|
||||
thread.join();
|
||||
|
||||
assertEquals("zero",data[0]);
|
||||
assertEquals("one",data[1]);
|
||||
assertEquals("two",data[2]);
|
||||
assertEquals(null,data[3]);
|
||||
|
||||
Assert.assertEquals("zero", data[0]);
|
||||
Assert.assertEquals("one", data[1]);
|
||||
Assert.assertEquals("two", data[2]);
|
||||
Assert.assertEquals(null, data[3]);
|
||||
}
|
||||
|
||||
volatile boolean _running;
|
||||
|
||||
@Test
|
||||
@Slow
|
||||
public void testConcurrentAccess() throws Exception
|
||||
|
@ -199,19 +206,17 @@ public class BlockingArrayQueueTest
|
|||
final int THREADS=50;
|
||||
final int LOOPS=1000;
|
||||
|
||||
final BlockingArrayQueue<Integer> queue = new BlockingArrayQueue<Integer>(1+THREADS*LOOPS);
|
||||
final BlockingArrayQueue<Integer> queue = new BlockingArrayQueue<>(1+THREADS*LOOPS);
|
||||
|
||||
final ConcurrentLinkedQueue<Integer> produced=new ConcurrentLinkedQueue<Integer>();
|
||||
final ConcurrentLinkedQueue<Integer> consumed=new ConcurrentLinkedQueue<Integer>();
|
||||
final ConcurrentLinkedQueue<Integer> produced=new ConcurrentLinkedQueue<>();
|
||||
final ConcurrentLinkedQueue<Integer> consumed=new ConcurrentLinkedQueue<>();
|
||||
|
||||
|
||||
_running=true;
|
||||
final AtomicBoolean running = new AtomicBoolean(true);
|
||||
|
||||
// start consumers
|
||||
final CyclicBarrier barrier0 = new CyclicBarrier(THREADS+1);
|
||||
for (int i=0;i<THREADS;i++)
|
||||
{
|
||||
final Integer id = new Integer(i);
|
||||
new Thread()
|
||||
{
|
||||
@Override
|
||||
|
@ -222,7 +227,7 @@ public class BlockingArrayQueueTest
|
|||
setPriority(getPriority()-1);
|
||||
try
|
||||
{
|
||||
while(_running)
|
||||
while(running.get())
|
||||
{
|
||||
int r=1+random.nextInt(10);
|
||||
if (r%2==0)
|
||||
|
@ -267,7 +272,7 @@ public class BlockingArrayQueueTest
|
|||
final CyclicBarrier barrier1 = new CyclicBarrier(THREADS+1);
|
||||
for (int i=0;i<THREADS;i++)
|
||||
{
|
||||
final Integer id = new Integer(i);
|
||||
final int id = i;
|
||||
new Thread()
|
||||
{
|
||||
@Override
|
||||
|
@ -278,7 +283,7 @@ public class BlockingArrayQueueTest
|
|||
{
|
||||
for (int j=0;j<LOOPS;j++)
|
||||
{
|
||||
Integer msg = new Integer(random.nextInt());
|
||||
Integer msg = random.nextInt();
|
||||
produced.add(msg);
|
||||
if (!queue.offer(msg))
|
||||
throw new Exception(id+" FULL! "+queue.size());
|
||||
|
@ -313,12 +318,178 @@ public class BlockingArrayQueueTest
|
|||
Thread.sleep(500);
|
||||
size=queue.size();
|
||||
}
|
||||
_running=false;
|
||||
running.set(false);
|
||||
barrier0.await();
|
||||
|
||||
HashSet<Integer> prodSet = new HashSet<Integer>(produced);
|
||||
HashSet<Integer> consSet = new HashSet<Integer>(consumed);
|
||||
HashSet<Integer> prodSet = new HashSet<>(produced);
|
||||
HashSet<Integer> consSet = new HashSet<>(consumed);
|
||||
|
||||
assertEquals(prodSet,consSet);
|
||||
Assert.assertEquals(prodSet, consSet);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveObjectFromEmptyQueue()
|
||||
{
|
||||
BlockingArrayQueue<String> queue = new BlockingArrayQueue<>(4,0,4);
|
||||
Assert.assertFalse(queue.remove("SOMETHING"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveObjectWithWrappedTail() throws Exception
|
||||
{
|
||||
BlockingArrayQueue<String> queue = new BlockingArrayQueue<>(6);
|
||||
// Wrap the tail
|
||||
for (int i = 0; i < queue.getMaxCapacity(); ++i)
|
||||
queue.offer("" + i);
|
||||
// Advance the head
|
||||
queue.poll();
|
||||
// Remove from the middle
|
||||
Assert.assertTrue(queue.remove("2"));
|
||||
|
||||
// Advance the tail
|
||||
Assert.assertTrue(queue.offer("A"));
|
||||
Assert.assertTrue(queue.offer("B"));
|
||||
queue.poll();
|
||||
// Remove from the middle
|
||||
Assert.assertTrue(queue.remove("3"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveObject() throws Exception
|
||||
{
|
||||
BlockingArrayQueue<String> queue = new BlockingArrayQueue<>(4,0,4);
|
||||
|
||||
String element1 = "A";
|
||||
Assert.assertTrue(queue.offer(element1));
|
||||
Assert.assertTrue(queue.remove(element1));
|
||||
|
||||
for (int i = 0; i < queue.getMaxCapacity() - 1; ++i)
|
||||
{
|
||||
queue.offer("" + i);
|
||||
queue.poll();
|
||||
}
|
||||
String element2 = "B";
|
||||
Assert.assertTrue(queue.offer(element2));
|
||||
Assert.assertTrue(queue.offer(element1));
|
||||
Assert.assertTrue(queue.remove(element1));
|
||||
|
||||
Assert.assertFalse(queue.remove("NOT_PRESENT"));
|
||||
|
||||
Assert.assertTrue(queue.remove(element2));
|
||||
Assert.assertFalse(queue.remove("NOT_PRESENT"));
|
||||
|
||||
queue.clear();
|
||||
|
||||
for (int i = 0; i < queue.getMaxCapacity(); ++i)
|
||||
queue.offer("" + i);
|
||||
|
||||
Assert.assertTrue(queue.remove("" + (queue.getMaxCapacity() - 1)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveWithMaxCapacityOne() throws Exception
|
||||
{
|
||||
BlockingArrayQueue<String> queue = new BlockingArrayQueue<>(1);
|
||||
|
||||
String element = "A";
|
||||
Assert.assertTrue(queue.offer(element));
|
||||
Assert.assertTrue(queue.remove(element));
|
||||
|
||||
Assert.assertTrue(queue.offer(element));
|
||||
Assert.assertEquals(element, queue.remove(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIteratorWithModification() throws Exception
|
||||
{
|
||||
BlockingArrayQueue<String> queue = new BlockingArrayQueue<>(4,0,4);
|
||||
int count = queue.getMaxCapacity() - 1;
|
||||
for (int i = 0; i < count; ++i)
|
||||
queue.offer("" + i);
|
||||
|
||||
int sum = 0;
|
||||
for (String element : queue)
|
||||
{
|
||||
++sum;
|
||||
// Concurrent modification, must not change the iterator
|
||||
queue.remove(element);
|
||||
}
|
||||
|
||||
Assert.assertEquals(count, sum);
|
||||
Assert.assertTrue(queue.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListIterator() throws Exception
|
||||
{
|
||||
BlockingArrayQueue<String> queue = new BlockingArrayQueue<>(4,0,4);
|
||||
String element1 = "A";
|
||||
String element2 = "B";
|
||||
queue.offer(element1);
|
||||
queue.offer(element2);
|
||||
|
||||
ListIterator<String> iterator = queue.listIterator();
|
||||
Assert.assertTrue(iterator.hasNext());
|
||||
Assert.assertFalse(iterator.hasPrevious());
|
||||
|
||||
String element = iterator.next();
|
||||
Assert.assertEquals(element1, element);
|
||||
Assert.assertTrue(iterator.hasNext());
|
||||
Assert.assertTrue(iterator.hasPrevious());
|
||||
|
||||
element = iterator.next();
|
||||
Assert.assertEquals(element2, element);
|
||||
Assert.assertFalse(iterator.hasNext());
|
||||
Assert.assertTrue(iterator.hasPrevious());
|
||||
|
||||
element = iterator.previous();
|
||||
Assert.assertEquals(element2, element);
|
||||
Assert.assertTrue(iterator.hasNext());
|
||||
Assert.assertTrue(iterator.hasPrevious());
|
||||
|
||||
element = iterator.previous();
|
||||
Assert.assertEquals(element1, element);
|
||||
Assert.assertTrue(iterator.hasNext());
|
||||
Assert.assertFalse(iterator.hasPrevious());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListIteratorWithWrappedHead() throws Exception
|
||||
{
|
||||
BlockingArrayQueue<String> queue = new BlockingArrayQueue<>(4,0,4);
|
||||
// This sequence of offers and polls wraps the head around the array
|
||||
queue.offer("0");
|
||||
queue.offer("1");
|
||||
queue.offer("2");
|
||||
queue.offer("3");
|
||||
queue.poll();
|
||||
queue.poll();
|
||||
|
||||
String element1 = queue.get(0);
|
||||
String element2 = queue.get(1);
|
||||
|
||||
ListIterator<String> iterator = queue.listIterator();
|
||||
Assert.assertTrue(iterator.hasNext());
|
||||
Assert.assertFalse(iterator.hasPrevious());
|
||||
|
||||
String element = iterator.next();
|
||||
Assert.assertEquals(element1, element);
|
||||
Assert.assertTrue(iterator.hasNext());
|
||||
Assert.assertTrue(iterator.hasPrevious());
|
||||
|
||||
element = iterator.next();
|
||||
Assert.assertEquals(element2, element);
|
||||
Assert.assertFalse(iterator.hasNext());
|
||||
Assert.assertTrue(iterator.hasPrevious());
|
||||
|
||||
element = iterator.previous();
|
||||
Assert.assertEquals(element2, element);
|
||||
Assert.assertTrue(iterator.hasNext());
|
||||
Assert.assertTrue(iterator.hasPrevious());
|
||||
|
||||
element = iterator.previous();
|
||||
Assert.assertEquals(element1, element);
|
||||
Assert.assertTrue(iterator.hasNext());
|
||||
Assert.assertFalse(iterator.hasPrevious());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ public class LocalWebSocketConnection implements WebSocketConnection, LogicalCon
|
|||
private WebSocketPolicy policy = WebSocketPolicy.newServerPolicy();
|
||||
private boolean open = false;
|
||||
private IncomingFrames incoming;
|
||||
private IOState ioState = new IOState();
|
||||
|
||||
public LocalWebSocketConnection()
|
||||
{
|
||||
|
@ -83,8 +84,7 @@ public class LocalWebSocketConnection implements WebSocketConnection, LogicalCon
|
|||
@Override
|
||||
public IOState getIOState()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
return ioState;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -25,13 +25,16 @@ import java.nio.ByteBuffer;
|
|||
import java.util.Arrays;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.toolchain.test.AdvancedRunner;
|
||||
import org.eclipse.jetty.util.Utf8Appendable.NotUtf8Exception;
|
||||
import org.eclipse.jetty.util.Utf8StringBuilder;
|
||||
import org.eclipse.jetty.util.log.StdErrLog;
|
||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||
import org.eclipse.jetty.websocket.common.CloseInfo;
|
||||
import org.eclipse.jetty.websocket.common.Generator;
|
||||
import org.eclipse.jetty.websocket.common.OpCode;
|
||||
import org.eclipse.jetty.websocket.common.Parser;
|
||||
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
||||
import org.eclipse.jetty.websocket.server.blockhead.BlockheadClient;
|
||||
import org.eclipse.jetty.websocket.server.helper.IncomingFramesCapture;
|
||||
|
@ -42,12 +45,14 @@ import org.junit.Assert;
|
|||
import org.junit.BeforeClass;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
/**
|
||||
* Test various <a href="http://tools.ietf.org/html/rfc6455">RFC 6455</a> specified requirements placed on {@link WebSocketServlet}
|
||||
* <p>
|
||||
* This test serves a different purpose than than the {@link WebSocketMessageRFC6455Test}, and {@link WebSocketParserRFC6455Test} tests.
|
||||
*/
|
||||
@RunWith(AdvancedRunner.class)
|
||||
public class WebSocketServletRFCTest
|
||||
{
|
||||
private static Generator generator = new UnitGenerator();
|
||||
|
@ -66,6 +71,12 @@ public class WebSocketServletRFCTest
|
|||
server.stop();
|
||||
}
|
||||
|
||||
private void enableStacks(Class<?> clazz, boolean enabled)
|
||||
{
|
||||
StdErrLog log = StdErrLog.getLogger(clazz);
|
||||
log.setHideStacks(!enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that aggregation of binary frames into a single message occurs
|
||||
*/
|
||||
|
@ -324,6 +335,9 @@ public class WebSocketServletRFCTest
|
|||
@Test
|
||||
public void testTextNotUTF8() throws Exception
|
||||
{
|
||||
// Disable Long Stacks from Parser (we know this test will throw an exception)
|
||||
enableStacks(Parser.class,false);
|
||||
|
||||
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
||||
client.setProtocols("other");
|
||||
try
|
||||
|
@ -347,8 +361,9 @@ public class WebSocketServletRFCTest
|
|||
}
|
||||
finally
|
||||
{
|
||||
// Reenable Long Stacks from Parser
|
||||
enableStacks(Parser.class,true);
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.nio.ByteBuffer;
|
|||
import org.eclipse.jetty.io.ByteBufferPool;
|
||||
import org.eclipse.jetty.io.MappedByteBufferPool;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.log.StdErrLog;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||
import org.eclipse.jetty.websocket.common.Generator;
|
||||
import org.eclipse.jetty.websocket.server.SimpleServletServer;
|
||||
|
@ -88,6 +89,12 @@ public abstract class AbstractABCase
|
|||
@Rule
|
||||
public TestName testname = new TestName();
|
||||
|
||||
protected void enableStacks(Class<?> clazz, boolean enabled)
|
||||
{
|
||||
StdErrLog log = StdErrLog.getLogger(clazz);
|
||||
log.setHideStacks(!enabled);
|
||||
}
|
||||
|
||||
public Generator getLaxGenerator()
|
||||
{
|
||||
return laxGenerator;
|
||||
|
|
|
@ -190,6 +190,7 @@ public class Fuzzer
|
|||
// we expect that the close handshake to have occurred and the server should have closed the connection
|
||||
try
|
||||
{
|
||||
@SuppressWarnings("unused")
|
||||
int val = client.read();
|
||||
|
||||
Assert.fail("Server has not closed socket");
|
||||
|
|
|
@ -22,13 +22,17 @@ import java.util.ArrayList;
|
|||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.toolchain.test.AdvancedRunner;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||
import org.eclipse.jetty.websocket.common.CloseInfo;
|
||||
import org.eclipse.jetty.websocket.common.OpCode;
|
||||
import org.eclipse.jetty.websocket.common.Parser;
|
||||
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RunWith(AdvancedRunner.class)
|
||||
public class TestABCase2 extends AbstractABCase
|
||||
{
|
||||
/**
|
||||
|
@ -232,6 +236,9 @@ public class TestABCase2 extends AbstractABCase
|
|||
@Test
|
||||
public void testCase2_5() throws Exception
|
||||
{
|
||||
// Disable Long Stacks from Parser (we know this test will throw an exception)
|
||||
enableStacks(Parser.class,false);
|
||||
|
||||
byte payload[] = new byte[126]; // intentionally too big
|
||||
Arrays.fill(payload,(byte)'5');
|
||||
|
||||
|
@ -253,6 +260,7 @@ public class TestABCase2 extends AbstractABCase
|
|||
}
|
||||
finally
|
||||
{
|
||||
enableStacks(Parser.class,true);
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,13 +22,34 @@ import java.util.ArrayList;
|
|||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.toolchain.test.AdvancedRunner;
|
||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||
import org.eclipse.jetty.websocket.common.CloseInfo;
|
||||
import org.eclipse.jetty.websocket.common.Parser;
|
||||
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
/**
|
||||
* Test various RSV violations
|
||||
*/
|
||||
@RunWith(AdvancedRunner.class)
|
||||
public class TestABCase3 extends AbstractABCase
|
||||
{
|
||||
@After
|
||||
public void enableParserStacks()
|
||||
{
|
||||
enableStacks(Parser.class,true);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void quietParserStacks()
|
||||
{
|
||||
enableStacks(Parser.class,false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send small text frame, with RSV1 == true, with no extensions defined.
|
||||
*/
|
||||
|
|
|
@ -21,12 +21,21 @@ package org.eclipse.jetty.websocket.server.ab;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.toolchain.test.AdvancedRunner;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||
import org.eclipse.jetty.websocket.common.CloseInfo;
|
||||
import org.eclipse.jetty.websocket.common.Parser;
|
||||
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
/**
|
||||
* Test various bad / forbidden opcodes (per spec)
|
||||
*/
|
||||
@RunWith(AdvancedRunner.class)
|
||||
public class TestABCase4 extends AbstractABCase
|
||||
{
|
||||
// Allow Fuzzer / Generator to create bad frames for testing frame validation
|
||||
|
@ -40,6 +49,18 @@ public class TestABCase4 extends AbstractABCase
|
|||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void enableParserStacks()
|
||||
{
|
||||
enableStacks(Parser.class,true);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void quietParserStacks()
|
||||
{
|
||||
enableStacks(Parser.class,false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send opcode 3 (reserved)
|
||||
*/
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.eclipse.jetty.toolchain.test.annotation.Slow;
|
|||
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||
import org.eclipse.jetty.websocket.common.CloseInfo;
|
||||
import org.eclipse.jetty.websocket.common.OpCode;
|
||||
import org.eclipse.jetty.websocket.common.Parser;
|
||||
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
@ -43,6 +44,9 @@ public class TestABCase5 extends AbstractABCase
|
|||
@Test
|
||||
public void testCase5_1() throws Exception
|
||||
{
|
||||
// Disable Long Stacks from Parser (we know this test will throw an exception)
|
||||
enableStacks(Parser.class,false);
|
||||
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(new WebSocketFrame(OpCode.PING).setPayload("hello, ").setFin(false));
|
||||
send.add(new WebSocketFrame(OpCode.CONTINUATION).setPayload("world"));
|
||||
|
@ -62,6 +66,7 @@ public class TestABCase5 extends AbstractABCase
|
|||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
enableStacks(Parser.class,true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,6 +76,9 @@ public class TestABCase5 extends AbstractABCase
|
|||
@Test
|
||||
public void testCase5_10() throws Exception
|
||||
{
|
||||
// Disable Long Stacks from Parser (we know this test will throw an exception)
|
||||
enableStacks(Parser.class,false);
|
||||
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(new WebSocketFrame(OpCode.CONTINUATION).setPayload("sorry").setFin(true));
|
||||
send.add(new WebSocketFrame(OpCode.TEXT).setPayload("hello, world"));
|
||||
|
@ -89,6 +97,7 @@ public class TestABCase5 extends AbstractABCase
|
|||
}
|
||||
finally
|
||||
{
|
||||
enableStacks(Parser.class,true);
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
@ -99,6 +108,9 @@ public class TestABCase5 extends AbstractABCase
|
|||
@Test
|
||||
public void testCase5_11() throws Exception
|
||||
{
|
||||
// Disable Long Stacks from Parser (we know this test will throw an exception)
|
||||
enableStacks(Parser.class,false);
|
||||
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(new WebSocketFrame(OpCode.CONTINUATION).setPayload("sorry").setFin(true));
|
||||
send.add(new WebSocketFrame(OpCode.TEXT).setPayload("hello, world"));
|
||||
|
@ -118,6 +130,7 @@ public class TestABCase5 extends AbstractABCase
|
|||
}
|
||||
finally
|
||||
{
|
||||
enableStacks(Parser.class,true);
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
@ -128,6 +141,9 @@ public class TestABCase5 extends AbstractABCase
|
|||
@Test
|
||||
public void testCase5_12() throws Exception
|
||||
{
|
||||
// Disable Long Stacks from Parser (we know this test will throw an exception)
|
||||
enableStacks(Parser.class,false);
|
||||
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(new WebSocketFrame(OpCode.CONTINUATION).setPayload("sorry").setFin(false));
|
||||
send.add(new WebSocketFrame(OpCode.TEXT).setPayload("hello, world"));
|
||||
|
@ -146,6 +162,7 @@ public class TestABCase5 extends AbstractABCase
|
|||
}
|
||||
finally
|
||||
{
|
||||
enableStacks(Parser.class,true);
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
@ -156,6 +173,8 @@ public class TestABCase5 extends AbstractABCase
|
|||
@Test
|
||||
public void testCase5_13() throws Exception
|
||||
{
|
||||
// Disable Long Stacks from Parser (we know this test will throw an exception)
|
||||
enableStacks(Parser.class,false);
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(new WebSocketFrame(OpCode.CONTINUATION).setPayload("sorry").setFin(false));
|
||||
send.add(new WebSocketFrame(OpCode.TEXT).setPayload("hello, world"));
|
||||
|
@ -174,6 +193,7 @@ public class TestABCase5 extends AbstractABCase
|
|||
}
|
||||
finally
|
||||
{
|
||||
enableStacks(Parser.class,true);
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
@ -184,6 +204,9 @@ public class TestABCase5 extends AbstractABCase
|
|||
@Test
|
||||
public void testCase5_14() throws Exception
|
||||
{
|
||||
// Disable Long Stacks from Parser (we know this test will throw an exception)
|
||||
enableStacks(Parser.class,false);
|
||||
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(new WebSocketFrame(OpCode.CONTINUATION).setPayload("sorry").setFin(false));
|
||||
send.add(new WebSocketFrame(OpCode.TEXT).setPayload("hello, world"));
|
||||
|
@ -203,6 +226,7 @@ public class TestABCase5 extends AbstractABCase
|
|||
}
|
||||
finally
|
||||
{
|
||||
enableStacks(Parser.class,false);
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
@ -213,6 +237,9 @@ public class TestABCase5 extends AbstractABCase
|
|||
@Test
|
||||
public void testCase5_15() throws Exception
|
||||
{
|
||||
// Disable Long Stacks from Parser (we know this test will throw an exception)
|
||||
enableStacks(Parser.class,false);
|
||||
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(new WebSocketFrame(OpCode.TEXT).setPayload("fragment1").setFin(false));
|
||||
send.add(new WebSocketFrame(OpCode.CONTINUATION).setPayload("fragment2").setFin(true));
|
||||
|
@ -234,6 +261,7 @@ public class TestABCase5 extends AbstractABCase
|
|||
}
|
||||
finally
|
||||
{
|
||||
enableStacks(Parser.class,true);
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
@ -244,6 +272,9 @@ public class TestABCase5 extends AbstractABCase
|
|||
@Test
|
||||
public void testCase5_16() throws Exception
|
||||
{
|
||||
// Disable Long Stacks from Parser (we know this test will throw an exception)
|
||||
enableStacks(Parser.class,false);
|
||||
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(new WebSocketFrame(OpCode.CONTINUATION).setPayload("fragment1").setFin(false)); // bad frame
|
||||
send.add(new WebSocketFrame(OpCode.TEXT).setPayload("fragment2").setFin(false));
|
||||
|
@ -266,6 +297,7 @@ public class TestABCase5 extends AbstractABCase
|
|||
}
|
||||
finally
|
||||
{
|
||||
enableStacks(Parser.class,true);
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
@ -276,6 +308,9 @@ public class TestABCase5 extends AbstractABCase
|
|||
@Test
|
||||
public void testCase5_17() throws Exception
|
||||
{
|
||||
// Disable Long Stacks from Parser (we know this test will throw an exception)
|
||||
enableStacks(Parser.class,false);
|
||||
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(new WebSocketFrame(OpCode.CONTINUATION).setPayload("fragment1").setFin(true)); // nothing to continue
|
||||
send.add(new WebSocketFrame(OpCode.TEXT).setPayload("fragment2").setFin(false));
|
||||
|
@ -298,6 +333,7 @@ public class TestABCase5 extends AbstractABCase
|
|||
}
|
||||
finally
|
||||
{
|
||||
enableStacks(Parser.class,true);
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
@ -308,6 +344,9 @@ public class TestABCase5 extends AbstractABCase
|
|||
@Test
|
||||
public void testCase5_18() throws Exception
|
||||
{
|
||||
// Disable Long Stacks from Parser (we know this test will throw an exception)
|
||||
enableStacks(Parser.class,false);
|
||||
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(new WebSocketFrame(OpCode.TEXT).setPayload("fragment1").setFin(false));
|
||||
send.add(new WebSocketFrame(OpCode.TEXT).setPayload("fragment2").setFin(true)); // bad frame, must be continuation
|
||||
|
@ -326,6 +365,7 @@ public class TestABCase5 extends AbstractABCase
|
|||
}
|
||||
finally
|
||||
{
|
||||
enableStacks(Parser.class,true);
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
@ -388,6 +428,9 @@ public class TestABCase5 extends AbstractABCase
|
|||
@Test
|
||||
public void testCase5_2() throws Exception
|
||||
{
|
||||
// Disable Long Stacks from Parser (we know this test will throw an exception)
|
||||
enableStacks(Parser.class,false);
|
||||
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(new WebSocketFrame(OpCode.PONG).setPayload("hello, ").setFin(false));
|
||||
send.add(new WebSocketFrame(OpCode.CONTINUATION).setPayload("world"));
|
||||
|
@ -406,6 +449,7 @@ public class TestABCase5 extends AbstractABCase
|
|||
}
|
||||
finally
|
||||
{
|
||||
enableStacks(Parser.class,true);
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
@ -691,6 +735,9 @@ public class TestABCase5 extends AbstractABCase
|
|||
@Test
|
||||
public void testCase5_9() throws Exception
|
||||
{
|
||||
// Disable Long Stacks from Parser (we know this test will throw an exception)
|
||||
enableStacks(Parser.class,false);
|
||||
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(new WebSocketFrame(OpCode.CONTINUATION).setPayload("sorry").setFin(true));
|
||||
send.add(new WebSocketFrame(OpCode.TEXT).setPayload("hello, world"));
|
||||
|
@ -709,6 +756,7 @@ public class TestABCase5 extends AbstractABCase
|
|||
}
|
||||
finally
|
||||
{
|
||||
enableStacks(Parser.class,true);
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.eclipse.jetty.util.TypeUtil;
|
|||
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||
import org.eclipse.jetty.websocket.common.CloseInfo;
|
||||
import org.eclipse.jetty.websocket.common.OpCode;
|
||||
import org.eclipse.jetty.websocket.common.Parser;
|
||||
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
||||
import org.eclipse.jetty.websocket.server.helper.Hex;
|
||||
import org.junit.Test;
|
||||
|
@ -356,6 +357,9 @@ public class TestABCase6 extends AbstractABCase
|
|||
@Slow
|
||||
public void testCase6_4_3() throws Exception
|
||||
{
|
||||
// Disable Long Stacks from Parser (we know this test will throw an exception)
|
||||
enableStacks(Parser.class,false);
|
||||
|
||||
ByteBuffer payload = ByteBuffer.allocate(64);
|
||||
BufferUtil.clearToFill(payload);
|
||||
payload.put(TypeUtil.fromHexString("cebae1bdb9cf83cebcceb5")); // good
|
||||
|
@ -400,6 +404,7 @@ public class TestABCase6 extends AbstractABCase
|
|||
}
|
||||
finally
|
||||
{
|
||||
enableStacks(Parser.class,true);
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
@ -411,6 +416,9 @@ public class TestABCase6 extends AbstractABCase
|
|||
@Slow
|
||||
public void testCase6_4_4() throws Exception
|
||||
{
|
||||
// Disable Long Stacks from Parser (we know this test will throw an exception)
|
||||
enableStacks(Parser.class,false);
|
||||
|
||||
byte invalid[] = Hex.asByteArray("CEBAE1BDB9CF83CEBCCEB5F49080808080656469746564");
|
||||
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
|
@ -437,6 +445,7 @@ public class TestABCase6 extends AbstractABCase
|
|||
}
|
||||
finally
|
||||
{
|
||||
enableStacks(Parser.class,true);
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@ import java.util.List;
|
|||
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.log.StdErrLog;
|
||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||
import org.eclipse.jetty.websocket.common.CloseInfo;
|
||||
import org.eclipse.jetty.websocket.common.OpCode;
|
||||
|
@ -177,10 +176,4 @@ public class TestABCase6_BadUTF extends AbstractABCase
|
|||
enableStacks(Parser.class,true);
|
||||
}
|
||||
}
|
||||
|
||||
private void enableStacks(Class<?> clazz, boolean enabled)
|
||||
{
|
||||
StdErrLog log = StdErrLog.getLogger(clazz);
|
||||
log.setHideStacks(!enabled);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@ import java.util.List;
|
|||
import org.eclipse.jetty.toolchain.test.TestTracker;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.log.StdErrLog;
|
||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||
import org.eclipse.jetty.websocket.common.CloseInfo;
|
||||
import org.eclipse.jetty.websocket.common.OpCode;
|
||||
|
@ -41,12 +40,6 @@ import org.junit.Test;
|
|||
*/
|
||||
public class TestABCase7 extends AbstractABCase
|
||||
{
|
||||
private static void enableStacks(Class<?> clazz, boolean enabled)
|
||||
{
|
||||
StdErrLog log = StdErrLog.getLogger(clazz);
|
||||
log.setHideStacks(!enabled);
|
||||
}
|
||||
|
||||
@Rule
|
||||
public TestTracker tt = new TestTracker();
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
|
||||
# org.eclipse.jetty.LEVEL=WARN
|
||||
org.eclipse.jetty.LEVEL=WARN
|
||||
|
||||
# org.eclipse.jetty.websocket.LEVEL=DEBUG
|
||||
org.eclipse.jetty.websocket.LEVEL=WARN
|
||||
# org.eclipse.jetty.websocket.LEVEL=WARN
|
||||
# org.eclipse.jetty.websocket.common.io.LEVEL=DEBUG
|
||||
# org.eclipse.jetty.websocket.server.ab.LEVEL=DEBUG
|
||||
# org.eclipse.jetty.websocket.common.io.LEVEL=DEBUG
|
||||
|
|
Loading…
Reference in New Issue