396193 spdy remove timeout parameters from api and move them to the Info* classes
This commit is contained in:
parent
3216a284b3
commit
26c5eb428f
|
@ -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)
|
||||
|
|
|
@ -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,8 +22,8 @@ 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;
|
||||
|
@ -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 syn(SynInfo synInfo) throws InterruptedException, ExecutionException, TimeoutException
|
||||
{
|
||||
FuturePromise<Stream> result = new FuturePromise<>();
|
||||
syn(synInfo,0,TimeUnit.MILLISECONDS,result);
|
||||
return result;
|
||||
syn(synInfo, result);
|
||||
if (synInfo.getTimeout() > 0)
|
||||
return result.get(synInfo.getTimeout(), synInfo.getUnit());
|
||||
else
|
||||
return result.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void syn(SynInfo synInfo, long timeout, TimeUnit unit, Promise<Stream> promise)
|
||||
public void syn(SynInfo synInfo, Promise<Stream> promise)
|
||||
{
|
||||
if (isClosed() || isReset())
|
||||
{
|
||||
|
@ -352,80 +355,89 @@ public class StandardStream implements IStream
|
|||
return;
|
||||
}
|
||||
PushSynInfo pushSynInfo = new PushSynInfo(getId(), synInfo);
|
||||
session.syn(pushSynInfo, null, timeout, unit, promise);
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
@ -75,115 +75,119 @@ 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,11 +95,12 @@ 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
|
||||
* @return a future containing the stream once it got established
|
||||
* @see #syn(SynInfo, long, TimeUnit, Promise)
|
||||
* @see #syn(SynInfo, Promise)
|
||||
*/
|
||||
public Future<Stream> syn(SynInfo synInfo);
|
||||
public Stream syn(SynInfo synInfo) throws InterruptedException, ExecutionException, TimeoutException;
|
||||
|
||||
/**
|
||||
* <p>Initiate a unidirectional spdy pushstream associated to this stream asynchronously<p>
|
||||
|
@ -107,23 +108,22 @@ public interface Stream
|
|||
* 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 callback the completion callback that gets notified once the pushstream is established
|
||||
* @see #syn(SynInfo)
|
||||
*/
|
||||
public void syn(SynInfo synInfo, long timeout, TimeUnit unit, Promise<Stream> callback);
|
||||
public void syn(SynInfo synInfo, 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 +131,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 +156,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 +181,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,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_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>
|
||||
|
@ -37,17 +39,6 @@ public class SynInfo
|
|||
private final byte priority;
|
||||
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,
|
||||
* not unidirectional, without associated stream, and with default priority.</p>
|
||||
|
@ -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.
|
||||
* </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 ReplyInfo} 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)
|
||||
|
|
|
@ -48,6 +48,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 +77,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 +94,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 +146,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 +204,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 +225,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>()
|
||||
SynInfo synInfo = new SynInfo(5, TimeUnit.SECONDS, headers, false, stream.getPriority());
|
||||
stream.syn(synInfo, new Promise.Adapter<Stream>()
|
||||
{
|
||||
@Override
|
||||
public void failed(Throwable x)
|
||||
|
@ -257,7 +259,7 @@ public class StandardSessionTest
|
|||
setControllerWriteExpectation(false);
|
||||
|
||||
IStream stream = createStream();
|
||||
IStream pushStream = (IStream)stream.syn(new SynInfo(false)).get();
|
||||
IStream pushStream = (IStream)stream.syn(new SynInfo(new Fields(), false));
|
||||
assertThatPushStreamIsInSession(pushStream);
|
||||
session.rst(new RstInfo(pushStream.getId(), StreamStatus.INVALID_STREAM));
|
||||
assertThatPushStreamIsNotInSession(pushStream);
|
||||
|
@ -271,8 +273,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);
|
||||
SynInfo synInfo = new SynInfo(5, TimeUnit.SECONDS, headers, true, stream.getPriority());
|
||||
IStream pushStream = (IStream)stream.syn(synInfo);
|
||||
assertThatPushStreamIsHalfClosed(pushStream);
|
||||
assertThatPushStreamIsClosed(pushStream);
|
||||
assertThatStreamIsNotAssociatedWithPushStream(stream, pushStream);
|
||||
|
@ -286,8 +288,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);
|
||||
SynInfo synInfo = new SynInfo(5, TimeUnit.SECONDS, headers, false, stream.getPriority());
|
||||
IStream pushStream = (IStream)stream.syn(synInfo);
|
||||
assertThatStreamIsAssociatedWithPushStream(stream, pushStream);
|
||||
assertThatPushStreamIsInSession(pushStream);
|
||||
pushStream.headers(new HeadersInfo(headers, true));
|
||||
|
@ -306,6 +308,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 +386,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 +402,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 +424,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 +437,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 +453,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 +475,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 +496,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 +537,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);
|
||||
SynInfo synInfo = new SynInfo(5, TimeUnit.SECONDS, headers, false, stream.getPriority());
|
||||
return (IStream)stream.syn(synInfo);
|
||||
}
|
||||
|
||||
private void assertThatStreamIsClosed(IStream stream)
|
||||
|
|
|
@ -33,6 +33,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 +46,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;
|
||||
|
@ -70,10 +70,10 @@ public class StandardStreamTest
|
|||
Set<Stream> streams = new HashSet<>();
|
||||
streams.add(stream);
|
||||
when(synStreamFrame.isClose()).thenReturn(false);
|
||||
SynInfo synInfo = new SynInfo(false);
|
||||
SynInfo synInfo = new SynInfo(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.syn(synInfo, new Promise.Adapter<Stream>());
|
||||
verify(session).syn(argThat(new PushSynInfoMatcher(stream.getId(), synInfo)), any(StreamFrameListener.class), any(Promise.class));
|
||||
}
|
||||
|
||||
private class PushSynInfoMatcher extends ArgumentMatcher<PushSynInfo>
|
||||
|
@ -91,9 +91,7 @@ public class StandardStreamTest
|
|||
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() == synInfo.isClose();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,7 +103,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.syn(new SynInfo(1, TimeUnit.SECONDS, new Fields(), false, (byte)0), 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,8 +135,8 @@ 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()
|
||||
{
|
||||
session.syn(new SynInfo(new Fields(), false), new StreamFrameListener.Adapter()
|
||||
{
|
||||
// The good of passing the listener to syn() 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)
|
||||
|
|
|
@ -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,8 @@ 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.syn(new SynInfo(0, TimeUnit.MILLISECONDS, pushHeaders, false, (byte)0),
|
||||
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,6 +33,7 @@ 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;
|
||||
|
@ -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,6 +42,7 @@ 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.ReplyInfo;
|
||||
import org.eclipse.jetty.spdy.api.RstInfo;
|
||||
|
@ -135,7 +134,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 +183,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 +210,21 @@ public class ProxyHTTPSPDYConnection extends HttpConnection implements HttpParse
|
|||
}
|
||||
|
||||
@Override
|
||||
public void syn(SynInfo synInfo, long timeout, TimeUnit unit, Promise<Stream> handler)
|
||||
public void syn(SynInfo synInfo, 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 +283,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 +312,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,6 +29,7 @@ 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.ReplyInfo;
|
||||
import org.eclipse.jetty.spdy.api.RstInfo;
|
||||
|
@ -108,7 +109,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 +171,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 +204,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 +260,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 +279,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 +395,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 +460,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.syn(new SynInfo(getTimeout(), TimeUnit.MILLISECONDS, headers, serverSynInfo.isClose(),
|
||||
(byte)0), handler);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -475,13 +476,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()
|
||||
{
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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,9 @@ 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.ReplyInfo;
|
||||
import org.eclipse.jetty.spdy.api.RstInfo;
|
||||
import org.eclipse.jetty.spdy.api.SPDY;
|
||||
|
@ -159,12 +161,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 +213,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 +274,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 +337,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 +401,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 +464,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 +489,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 +508,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 +549,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 +567,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.syn(new SynInfo(5, TimeUnit.SECONDS, pushHeaders, false, (byte)0), 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 +616,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.syn(new SynInfo(5, TimeUnit.SECONDS, pushHeaders, false, (byte)0), 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 +683,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 +699,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 +724,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 +760,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 +783,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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
|||
|
||||
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;
|
||||
|
@ -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
|
||||
|
@ -223,7 +228,7 @@ public class GoAwayTest extends AbstractTest
|
|||
|
||||
// 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,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.GoAwayReceivedInfo;
|
||||
import org.eclipse.jetty.spdy.api.ReplyInfo;
|
||||
import org.eclipse.jetty.spdy.api.RstInfo;
|
||||
import org.eclipse.jetty.spdy.api.SPDY;
|
||||
|
@ -84,8 +85,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.syn(new SynInfo(new Fields(), true), new Promise.Adapter<Stream>());
|
||||
return null;
|
||||
}
|
||||
}), new SessionFrameListener.Adapter()
|
||||
|
@ -93,13 +94,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 +113,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 +135,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 +148,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.syn(new SynInfo(new Fields(), false));
|
||||
streamExchanger.exchange(pushStream, 5, TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
|
@ -171,7 +172,7 @@ public class PushStreamTest extends AbstractTest
|
|||
}
|
||||
}
|
||||
|
||||
}),new SessionFrameListener.Adapter()
|
||||
}), new SessionFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
|
||||
|
@ -183,20 +184,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 +210,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,8 +245,8 @@ 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>()
|
||||
stream.reply(new ReplyInfo(true), new Callback.Adapter());
|
||||
stream.syn(new SynInfo(1, TimeUnit.SECONDS, new Fields(), false, (byte)0), new Promise.Adapter<Stream>()
|
||||
{
|
||||
@Override
|
||||
public void failed(Throwable x)
|
||||
|
@ -253,12 +254,12 @@ public class PushStreamTest extends AbstractTest
|
|||
pushStreamFailedLatch.countDown();
|
||||
}
|
||||
});
|
||||
return super.onSyn(stream,synInfo);
|
||||
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 syn has failed", pushStreamFailedLatch.await(5, TimeUnit.SECONDS), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -278,11 +279,11 @@ public class PushStreamTest extends AbstractTest
|
|||
{
|
||||
try
|
||||
{
|
||||
Stream pushStream = stream.syn(new SynInfo(false)).get();
|
||||
Stream pushStream = stream.syn(new SynInfo(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 +292,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 +311,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 +323,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 +365,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 +387,21 @@ 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.syn(new SynInfo(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);
|
||||
}
|
||||
pushStream.data(new BytesDataInfo(transferBytes,true));
|
||||
stream.data(new StringDataInfo("close",true));
|
||||
assert pushStream != null;
|
||||
pushStream.data(new BytesDataInfo(transferBytes, true), new Callback.Adapter());
|
||||
stream.data(new StringDataInfo("close", true), new Callback.Adapter());
|
||||
}
|
||||
}).start();
|
||||
return null;
|
||||
|
@ -411,7 +414,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 +423,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 +435,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 +446,7 @@ public class PushStreamTest extends AbstractTest
|
|||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
unexpectedExceptionOccured.set(true);
|
||||
unexpectedExceptionOccurred.set(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -450,15 +454,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 +471,7 @@ public class PushStreamTest extends AbstractTest
|
|||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
unexpectedExceptionOccured.set(true);
|
||||
unexpectedExceptionOccurred.set(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -477,7 +482,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 +492,7 @@ public class PushStreamTest extends AbstractTest
|
|||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
unexpectedExceptionOccured.set(true);
|
||||
unexpectedExceptionOccurred.set(true);
|
||||
}
|
||||
readBuffer.flip();
|
||||
parser.parse(readBuffer);
|
||||
|
@ -499,15 +504,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 +527,42 @@ public class PushStreamTest extends AbstractTest
|
|||
@Override
|
||||
public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
|
||||
{
|
||||
stream.syn(new SynInfo(false));
|
||||
stream.syn(new SynInfo(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("syn 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));
|
||||
|
|
Loading…
Reference in New Issue