Reviewed use of StreamException and SessionException.
This commit is contained in:
parent
3f1c7aa102
commit
b1ef0e87c9
|
@ -26,7 +26,7 @@ import org.eclipse.jetty.spdy.frames.ControlFrame;
|
|||
|
||||
public interface ISession extends Session
|
||||
{
|
||||
public <C> void control(IStream stream, ControlFrame frame, long timeout, TimeUnit unit, Handler<C> handler, C context) throws StreamException;
|
||||
public <C> void control(IStream stream, ControlFrame frame, long timeout, TimeUnit unit, Handler<C> handler, C context);
|
||||
|
||||
public <C> void data(IStream stream, DataInfo dataInfo, long timeout, TimeUnit unit, Handler<C> handler, C context);
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ package org.eclipse.jetty.spdy;
|
|||
|
||||
import org.eclipse.jetty.spdy.api.SessionStatus;
|
||||
|
||||
public class SessionException extends Exception
|
||||
public class SessionException extends RuntimeException
|
||||
{
|
||||
private final SessionStatus sessionStatus;
|
||||
|
||||
|
|
|
@ -367,15 +367,15 @@ public class StandardSession implements ISession, Parser.Listener, Handler<Stand
|
|||
@Override
|
||||
public void onStreamException(StreamException x)
|
||||
{
|
||||
// TODO: must send a RST_STREAM on the proper stream... too little information in StreamException
|
||||
throw new SPDYException(x);
|
||||
logger.info("Caught stream exception", x);
|
||||
rst(new RstInfo(x.getStreamId(), x.getStreamStatus()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSessionException(SessionException x)
|
||||
{
|
||||
// TODO: must send a GOAWAY with the x.sessionStatus, then close
|
||||
close();
|
||||
logger.info("Caught session exception", x);
|
||||
goAway();
|
||||
}
|
||||
|
||||
private void onSyn(final SynStreamFrame frame)
|
||||
|
@ -714,25 +714,32 @@ public class StandardSession implements ISession, Parser.Listener, Handler<Stand
|
|||
}
|
||||
|
||||
@Override
|
||||
public <C> void control(IStream stream, ControlFrame frame, long timeout, TimeUnit unit, Handler<C> handler, C context) throws StreamException
|
||||
public <C> void control(IStream stream, ControlFrame frame, long timeout, TimeUnit unit, Handler<C> handler, C context)
|
||||
{
|
||||
if (stream != null)
|
||||
updateLastStreamId(stream); // TODO: not sure this is right
|
||||
|
||||
// Synchronization is necessary, since we may have concurrent replies
|
||||
// and those needs to be generated and enqueued atomically in order
|
||||
// to maintain a correct compression context
|
||||
synchronized (this)
|
||||
try
|
||||
{
|
||||
ByteBuffer buffer = generator.control(frame);
|
||||
logger.debug("Queuing {} on {}", frame, stream);
|
||||
ControlFrameBytes<C> frameBytes = new ControlFrameBytes<>(frame, buffer, handler, context);
|
||||
if (timeout > 0)
|
||||
frameBytes.task = scheduler.schedule(frameBytes, timeout, unit);
|
||||
enqueueLast(frameBytes);
|
||||
}
|
||||
if (stream != null)
|
||||
updateLastStreamId(stream); // TODO: not sure this is right
|
||||
|
||||
flush();
|
||||
// Synchronization is necessary, since we may have concurrent replies
|
||||
// and those needs to be generated and enqueued atomically in order
|
||||
// to maintain a correct compression context
|
||||
synchronized (this)
|
||||
{
|
||||
ByteBuffer buffer = generator.control(frame);
|
||||
logger.debug("Queuing {} on {}", frame, stream);
|
||||
ControlFrameBytes<C> frameBytes = new ControlFrameBytes<>(frame, buffer, handler, context);
|
||||
if (timeout > 0)
|
||||
frameBytes.task = scheduler.schedule(frameBytes, timeout, unit);
|
||||
enqueueLast(frameBytes);
|
||||
}
|
||||
|
||||
flush();
|
||||
}
|
||||
catch (Throwable x)
|
||||
{
|
||||
handler.failed(x);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateLastStreamId(IStream stream)
|
||||
|
@ -925,14 +932,22 @@ public class StandardSession implements ISession, Parser.Listener, Handler<Stand
|
|||
@Override
|
||||
public ByteBuffer getByteBuffer()
|
||||
{
|
||||
int windowSize = stream.getWindowSize();
|
||||
if (windowSize <= 0)
|
||||
try
|
||||
{
|
||||
int windowSize = stream.getWindowSize();
|
||||
if (windowSize <= 0)
|
||||
return null;
|
||||
|
||||
ByteBuffer buffer = generator.data(stream.getId(), windowSize, data);
|
||||
dataLength = buffer.remaining() - DataFrame.HEADER_LENGTH;
|
||||
|
||||
return buffer;
|
||||
}
|
||||
catch (Throwable x)
|
||||
{
|
||||
handler.failed(x);
|
||||
return null;
|
||||
|
||||
ByteBuffer buffer = generator.data(stream.getId(), windowSize, data);
|
||||
dataLength = buffer.remaining() - DataFrame.HEADER_LENGTH;
|
||||
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -18,27 +18,36 @@ package org.eclipse.jetty.spdy;
|
|||
|
||||
import org.eclipse.jetty.spdy.api.StreamStatus;
|
||||
|
||||
public class StreamException extends Exception
|
||||
public class StreamException extends RuntimeException
|
||||
{
|
||||
private final int streamId;
|
||||
private final StreamStatus streamStatus;
|
||||
|
||||
public StreamException(StreamStatus streamStatus)
|
||||
public StreamException(int streamId, StreamStatus streamStatus)
|
||||
{
|
||||
this.streamId = streamId;
|
||||
this.streamStatus = streamStatus;
|
||||
}
|
||||
|
||||
public StreamException(StreamStatus streamStatus, String message)
|
||||
public StreamException(int streamId, StreamStatus streamStatus, String message)
|
||||
{
|
||||
super(message);
|
||||
this.streamId = streamId;
|
||||
this.streamStatus = streamStatus;
|
||||
}
|
||||
|
||||
public StreamException(StreamStatus streamStatus, Throwable x)
|
||||
public StreamException(int streamId, StreamStatus streamStatus, Throwable x)
|
||||
{
|
||||
super(x);
|
||||
this.streamId = streamId;
|
||||
this.streamStatus = streamStatus;
|
||||
}
|
||||
|
||||
public int getStreamId()
|
||||
{
|
||||
return streamId;
|
||||
}
|
||||
|
||||
public StreamStatus getStreamStatus()
|
||||
{
|
||||
return streamStatus;
|
||||
|
|
|
@ -18,12 +18,11 @@ package org.eclipse.jetty.spdy.generator;
|
|||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.eclipse.jetty.spdy.StreamException;
|
||||
import org.eclipse.jetty.spdy.frames.ControlFrame;
|
||||
|
||||
public abstract class ControlFrameGenerator
|
||||
{
|
||||
public abstract ByteBuffer generate(ControlFrame frame) throws StreamException;
|
||||
public abstract ByteBuffer generate(ControlFrame frame);
|
||||
|
||||
protected void generateControlFrameHeader(ControlFrame frame, int frameLength, ByteBuffer buffer)
|
||||
{
|
||||
|
|
|
@ -20,7 +20,6 @@ import java.nio.ByteBuffer;
|
|||
import java.util.EnumMap;
|
||||
|
||||
import org.eclipse.jetty.spdy.CompressionFactory;
|
||||
import org.eclipse.jetty.spdy.StreamException;
|
||||
import org.eclipse.jetty.spdy.api.DataInfo;
|
||||
import org.eclipse.jetty.spdy.frames.ControlFrame;
|
||||
import org.eclipse.jetty.spdy.frames.ControlFrameType;
|
||||
|
@ -46,7 +45,7 @@ public class Generator
|
|||
dataFrameGenerator = new DataFrameGenerator();
|
||||
}
|
||||
|
||||
public ByteBuffer control(ControlFrame frame) throws StreamException
|
||||
public ByteBuffer control(ControlFrame frame)
|
||||
{
|
||||
ControlFrameGenerator generator = generators.get(frame.getType());
|
||||
return generator.generate(frame);
|
||||
|
|
|
@ -18,7 +18,6 @@ package org.eclipse.jetty.spdy.generator;
|
|||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.eclipse.jetty.spdy.StreamException;
|
||||
import org.eclipse.jetty.spdy.api.SPDY;
|
||||
import org.eclipse.jetty.spdy.frames.ControlFrame;
|
||||
import org.eclipse.jetty.spdy.frames.GoAwayFrame;
|
||||
|
@ -26,7 +25,7 @@ import org.eclipse.jetty.spdy.frames.GoAwayFrame;
|
|||
public class GoAwayGenerator extends ControlFrameGenerator
|
||||
{
|
||||
@Override
|
||||
public ByteBuffer generate(ControlFrame frame) throws StreamException
|
||||
public ByteBuffer generate(ControlFrame frame)
|
||||
{
|
||||
GoAwayFrame goAway = (GoAwayFrame)frame;
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@ import java.nio.charset.Charset;
|
|||
|
||||
import org.eclipse.jetty.spdy.CompressionDictionary;
|
||||
import org.eclipse.jetty.spdy.CompressionFactory;
|
||||
import org.eclipse.jetty.spdy.StreamException;
|
||||
import org.eclipse.jetty.spdy.api.Headers;
|
||||
import org.eclipse.jetty.spdy.api.SPDY;
|
||||
|
||||
|
@ -36,7 +35,7 @@ public class HeadersBlockGenerator
|
|||
this.compressor = compressor;
|
||||
}
|
||||
|
||||
public ByteBuffer generate(short version, Headers headers) throws StreamException
|
||||
public ByteBuffer generate(short version, Headers headers)
|
||||
{
|
||||
// TODO: ByteArrayOutputStream is quite inefficient, but grows on demand; optimize using ByteBuffer ?
|
||||
Charset iso1 = Charset.forName("ISO-8859-1");
|
||||
|
@ -107,7 +106,7 @@ public class HeadersBlockGenerator
|
|||
return ByteBuffer.wrap(buffer.toByteArray());
|
||||
}
|
||||
|
||||
private void writeCount(short version, ByteArrayOutputStream buffer, int value) throws StreamException
|
||||
private void writeCount(short version, ByteArrayOutputStream buffer, int value)
|
||||
{
|
||||
switch (version)
|
||||
{
|
||||
|
@ -134,12 +133,12 @@ public class HeadersBlockGenerator
|
|||
}
|
||||
}
|
||||
|
||||
private void writeNameLength(short version, ByteArrayOutputStream buffer, int length) throws StreamException
|
||||
private void writeNameLength(short version, ByteArrayOutputStream buffer, int length)
|
||||
{
|
||||
writeCount(version, buffer, length);
|
||||
}
|
||||
|
||||
private void writeValueLength(short version, ByteArrayOutputStream buffer, int length) throws StreamException
|
||||
private void writeValueLength(short version, ByteArrayOutputStream buffer, int length)
|
||||
{
|
||||
writeCount(version, buffer, length);
|
||||
}
|
||||
|
|
|
@ -18,8 +18,8 @@ package org.eclipse.jetty.spdy.generator;
|
|||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.eclipse.jetty.spdy.StreamException;
|
||||
import org.eclipse.jetty.spdy.api.StreamStatus;
|
||||
import org.eclipse.jetty.spdy.SessionException;
|
||||
import org.eclipse.jetty.spdy.api.SessionStatus;
|
||||
import org.eclipse.jetty.spdy.frames.ControlFrame;
|
||||
import org.eclipse.jetty.spdy.frames.HeadersFrame;
|
||||
|
||||
|
@ -33,7 +33,7 @@ public class HeadersGenerator extends ControlFrameGenerator
|
|||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer generate(ControlFrame frame) throws StreamException
|
||||
public ByteBuffer generate(ControlFrame frame)
|
||||
{
|
||||
HeadersFrame headers = (HeadersFrame)frame;
|
||||
short version = headers.getVersion();
|
||||
|
@ -44,7 +44,11 @@ public class HeadersGenerator extends ControlFrameGenerator
|
|||
|
||||
int frameLength = frameBodyLength + headersBuffer.remaining();
|
||||
if (frameLength > 0xFF_FF_FF)
|
||||
throw new StreamException(StreamStatus.PROTOCOL_ERROR, "Too many headers");
|
||||
{
|
||||
// Too many headers, but unfortunately we have already modified the compression
|
||||
// context, so we have no other choice than tear down the connection.
|
||||
throw new SessionException(SessionStatus.PROTOCOL_ERROR, "Too many headers");
|
||||
}
|
||||
|
||||
int totalLength = ControlFrame.HEADER_LENGTH + frameLength;
|
||||
|
||||
|
|
|
@ -18,14 +18,13 @@ package org.eclipse.jetty.spdy.generator;
|
|||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.eclipse.jetty.spdy.StreamException;
|
||||
import org.eclipse.jetty.spdy.frames.ControlFrame;
|
||||
import org.eclipse.jetty.spdy.frames.NoOpFrame;
|
||||
|
||||
public class NoOpGenerator extends ControlFrameGenerator
|
||||
{
|
||||
@Override
|
||||
public ByteBuffer generate(ControlFrame frame) throws StreamException
|
||||
public ByteBuffer generate(ControlFrame frame)
|
||||
{
|
||||
NoOpFrame noOp = (NoOpFrame)frame;
|
||||
|
||||
|
|
|
@ -18,14 +18,13 @@ package org.eclipse.jetty.spdy.generator;
|
|||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.eclipse.jetty.spdy.StreamException;
|
||||
import org.eclipse.jetty.spdy.frames.ControlFrame;
|
||||
import org.eclipse.jetty.spdy.frames.PingFrame;
|
||||
|
||||
public class PingGenerator extends ControlFrameGenerator
|
||||
{
|
||||
@Override
|
||||
public ByteBuffer generate(ControlFrame frame) throws StreamException
|
||||
public ByteBuffer generate(ControlFrame frame)
|
||||
{
|
||||
PingFrame ping = (PingFrame)frame;
|
||||
|
||||
|
|
|
@ -18,14 +18,13 @@ package org.eclipse.jetty.spdy.generator;
|
|||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.eclipse.jetty.spdy.StreamException;
|
||||
import org.eclipse.jetty.spdy.frames.ControlFrame;
|
||||
import org.eclipse.jetty.spdy.frames.RstStreamFrame;
|
||||
|
||||
public class RstStreamGenerator extends ControlFrameGenerator
|
||||
{
|
||||
@Override
|
||||
public ByteBuffer generate(ControlFrame frame) throws StreamException
|
||||
public ByteBuffer generate(ControlFrame frame)
|
||||
{
|
||||
RstStreamFrame rstStream = (RstStreamFrame)frame;
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@ package org.eclipse.jetty.spdy.generator;
|
|||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.eclipse.jetty.spdy.StreamException;
|
||||
import org.eclipse.jetty.spdy.api.SPDY;
|
||||
import org.eclipse.jetty.spdy.api.Settings;
|
||||
import org.eclipse.jetty.spdy.frames.ControlFrame;
|
||||
|
@ -27,7 +26,7 @@ import org.eclipse.jetty.spdy.frames.SettingsFrame;
|
|||
public class SettingsGenerator extends ControlFrameGenerator
|
||||
{
|
||||
@Override
|
||||
public ByteBuffer generate(ControlFrame frame) throws StreamException
|
||||
public ByteBuffer generate(ControlFrame frame)
|
||||
{
|
||||
SettingsFrame settingsFrame = (SettingsFrame)frame;
|
||||
|
||||
|
|
|
@ -18,9 +18,9 @@ package org.eclipse.jetty.spdy.generator;
|
|||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.eclipse.jetty.spdy.StreamException;
|
||||
import org.eclipse.jetty.spdy.SessionException;
|
||||
import org.eclipse.jetty.spdy.api.SPDY;
|
||||
import org.eclipse.jetty.spdy.api.StreamStatus;
|
||||
import org.eclipse.jetty.spdy.api.SessionStatus;
|
||||
import org.eclipse.jetty.spdy.frames.ControlFrame;
|
||||
import org.eclipse.jetty.spdy.frames.SynReplyFrame;
|
||||
|
||||
|
@ -34,7 +34,7 @@ public class SynReplyGenerator extends ControlFrameGenerator
|
|||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer generate(ControlFrame frame) throws StreamException
|
||||
public ByteBuffer generate(ControlFrame frame)
|
||||
{
|
||||
SynReplyFrame synReply = (SynReplyFrame)frame;
|
||||
short version = synReply.getVersion();
|
||||
|
@ -45,7 +45,11 @@ public class SynReplyGenerator extends ControlFrameGenerator
|
|||
|
||||
int frameLength = frameBodyLength + headersBuffer.remaining();
|
||||
if (frameLength > 0xFF_FF_FF)
|
||||
throw new StreamException(StreamStatus.PROTOCOL_ERROR, "Too many headers");
|
||||
{
|
||||
// Too many headers, but unfortunately we have already modified the compression
|
||||
// context, so we have no other choice than tear down the connection.
|
||||
throw new SessionException(SessionStatus.PROTOCOL_ERROR, "Too many headers");
|
||||
}
|
||||
|
||||
int totalLength = ControlFrame.HEADER_LENGTH + frameLength;
|
||||
|
||||
|
@ -61,7 +65,7 @@ public class SynReplyGenerator extends ControlFrameGenerator
|
|||
return buffer;
|
||||
}
|
||||
|
||||
private int getFrameDataLength(short version) throws StreamException
|
||||
private int getFrameDataLength(short version)
|
||||
{
|
||||
switch (version)
|
||||
{
|
||||
|
@ -76,7 +80,7 @@ public class SynReplyGenerator extends ControlFrameGenerator
|
|||
}
|
||||
}
|
||||
|
||||
private void writeAdditional(short version, ByteBuffer buffer) throws StreamException
|
||||
private void writeAdditional(short version, ByteBuffer buffer)
|
||||
{
|
||||
switch (version)
|
||||
{
|
||||
|
|
|
@ -18,8 +18,10 @@ package org.eclipse.jetty.spdy.generator;
|
|||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.eclipse.jetty.spdy.SessionException;
|
||||
import org.eclipse.jetty.spdy.StreamException;
|
||||
import org.eclipse.jetty.spdy.api.SPDY;
|
||||
import org.eclipse.jetty.spdy.api.SessionStatus;
|
||||
import org.eclipse.jetty.spdy.api.StreamStatus;
|
||||
import org.eclipse.jetty.spdy.frames.ControlFrame;
|
||||
import org.eclipse.jetty.spdy.frames.SynStreamFrame;
|
||||
|
@ -34,7 +36,7 @@ public class SynStreamGenerator extends ControlFrameGenerator
|
|||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer generate(ControlFrame frame) throws StreamException
|
||||
public ByteBuffer generate(ControlFrame frame)
|
||||
{
|
||||
SynStreamFrame synStream = (SynStreamFrame)frame;
|
||||
short version = synStream.getVersion();
|
||||
|
@ -45,16 +47,21 @@ public class SynStreamGenerator extends ControlFrameGenerator
|
|||
|
||||
int frameLength = frameBodyLength + headersBuffer.remaining();
|
||||
if (frameLength > 0xFF_FF_FF)
|
||||
throw new StreamException(StreamStatus.PROTOCOL_ERROR, "Too many headers");
|
||||
{
|
||||
// Too many headers, but unfortunately we have already modified the compression
|
||||
// context, so we have no other choice than tear down the connection.
|
||||
throw new SessionException(SessionStatus.PROTOCOL_ERROR, "Too many headers");
|
||||
}
|
||||
|
||||
int totalLength = ControlFrame.HEADER_LENGTH + frameLength;
|
||||
|
||||
ByteBuffer buffer = ByteBuffer.allocate(totalLength);
|
||||
generateControlFrameHeader(synStream, frameLength, buffer);
|
||||
|
||||
buffer.putInt(synStream.getStreamId() & 0x7F_FF_FF_FF);
|
||||
int streamId = synStream.getStreamId();
|
||||
buffer.putInt(streamId & 0x7F_FF_FF_FF);
|
||||
buffer.putInt(synStream.getAssociatedStreamId() & 0x7F_FF_FF_FF);
|
||||
writePriority(version, synStream.getPriority(), buffer);
|
||||
writePriority(streamId, version, synStream.getPriority(), buffer);
|
||||
|
||||
buffer.put(headersBuffer);
|
||||
|
||||
|
@ -62,7 +69,7 @@ public class SynStreamGenerator extends ControlFrameGenerator
|
|||
return buffer;
|
||||
}
|
||||
|
||||
private void writePriority(short version, byte priority, ByteBuffer buffer) throws StreamException
|
||||
private void writePriority(int streamId, short version, byte priority, ByteBuffer buffer)
|
||||
{
|
||||
switch (version)
|
||||
{
|
||||
|
@ -73,7 +80,7 @@ public class SynStreamGenerator extends ControlFrameGenerator
|
|||
priority <<= 5;
|
||||
break;
|
||||
default:
|
||||
throw new StreamException(StreamStatus.UNSUPPORTED_VERSION);
|
||||
throw new StreamException(streamId, StreamStatus.UNSUPPORTED_VERSION);
|
||||
}
|
||||
buffer.put(priority);
|
||||
buffer.put((byte)0);
|
||||
|
|
|
@ -18,14 +18,13 @@ package org.eclipse.jetty.spdy.generator;
|
|||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.eclipse.jetty.spdy.StreamException;
|
||||
import org.eclipse.jetty.spdy.frames.ControlFrame;
|
||||
import org.eclipse.jetty.spdy.frames.WindowUpdateFrame;
|
||||
|
||||
public class WindowUpdateGenerator extends ControlFrameGenerator
|
||||
{
|
||||
@Override
|
||||
public ByteBuffer generate(ControlFrame frame) throws StreamException
|
||||
public ByteBuffer generate(ControlFrame frame)
|
||||
{
|
||||
WindowUpdateFrame windowUpdate = (WindowUpdateFrame)frame;
|
||||
|
||||
|
|
|
@ -18,9 +18,7 @@ package org.eclipse.jetty.spdy.parser;
|
|||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.eclipse.jetty.spdy.StreamException;
|
||||
|
||||
public abstract class ControlFrameBodyParser
|
||||
{
|
||||
public abstract boolean parse(ByteBuffer buffer) throws StreamException;
|
||||
public abstract boolean parse(ByteBuffer buffer);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ import java.util.EnumMap;
|
|||
|
||||
import org.eclipse.jetty.spdy.CompressionFactory;
|
||||
import org.eclipse.jetty.spdy.SessionException;
|
||||
import org.eclipse.jetty.spdy.StreamException;
|
||||
import org.eclipse.jetty.spdy.api.SPDY;
|
||||
import org.eclipse.jetty.spdy.api.SessionStatus;
|
||||
import org.eclipse.jetty.spdy.frames.ControlFrame;
|
||||
|
@ -67,7 +66,7 @@ public abstract class ControlFrameParser
|
|||
return length;
|
||||
}
|
||||
|
||||
public boolean parse(ByteBuffer buffer) throws SessionException, StreamException
|
||||
public boolean parse(ByteBuffer buffer)
|
||||
{
|
||||
while (buffer.hasRemaining())
|
||||
{
|
||||
|
@ -172,7 +171,7 @@ public abstract class ControlFrameParser
|
|||
return false;
|
||||
}
|
||||
|
||||
private void checkVersion(short version) throws SessionException
|
||||
private void checkVersion(short version)
|
||||
{
|
||||
if (version != SPDY.V2 && version != SPDY.V3)
|
||||
throw new SessionException(SessionStatus.PROTOCOL_ERROR, "Unrecognized version " + version);
|
||||
|
|
|
@ -18,7 +18,6 @@ package org.eclipse.jetty.spdy.parser;
|
|||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.eclipse.jetty.spdy.StreamException;
|
||||
import org.eclipse.jetty.spdy.api.SPDY;
|
||||
import org.eclipse.jetty.spdy.frames.GoAwayFrame;
|
||||
|
||||
|
@ -36,7 +35,7 @@ public class GoAwayBodyParser extends ControlFrameBodyParser
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean parse(ByteBuffer buffer) throws StreamException
|
||||
public boolean parse(ByteBuffer buffer)
|
||||
{
|
||||
while (buffer.hasRemaining())
|
||||
{
|
||||
|
|
|
@ -22,8 +22,10 @@ import java.util.zip.ZipException;
|
|||
|
||||
import org.eclipse.jetty.spdy.CompressionDictionary;
|
||||
import org.eclipse.jetty.spdy.CompressionFactory;
|
||||
import org.eclipse.jetty.spdy.SessionException;
|
||||
import org.eclipse.jetty.spdy.StreamException;
|
||||
import org.eclipse.jetty.spdy.api.SPDY;
|
||||
import org.eclipse.jetty.spdy.api.SessionStatus;
|
||||
import org.eclipse.jetty.spdy.api.StreamStatus;
|
||||
|
||||
public abstract class HeadersBlockParser
|
||||
|
@ -37,7 +39,7 @@ public abstract class HeadersBlockParser
|
|||
this.decompressor = decompressor;
|
||||
}
|
||||
|
||||
public boolean parse(short version, int length, ByteBuffer buffer) throws StreamException
|
||||
public boolean parse(int streamId, short version, int length, ByteBuffer buffer)
|
||||
{
|
||||
// Need to be sure that all the compressed data has arrived
|
||||
// Because SPDY uses SYNC_FLUSH mode, and the Java API
|
||||
|
@ -62,14 +64,14 @@ public abstract class HeadersBlockParser
|
|||
{
|
||||
int nameLength = readNameLength(version, decompressedHeaders);
|
||||
if (nameLength == 0)
|
||||
throw new StreamException(StreamStatus.PROTOCOL_ERROR, "Invalid header name length");
|
||||
throw new StreamException(streamId, StreamStatus.PROTOCOL_ERROR, "Invalid header name length");
|
||||
byte[] nameBytes = new byte[nameLength];
|
||||
decompressedHeaders.get(nameBytes);
|
||||
String name = new String(nameBytes, iso1);
|
||||
|
||||
int valueLength = readValueLength(version, decompressedHeaders);
|
||||
if (valueLength == 0)
|
||||
throw new StreamException(StreamStatus.PROTOCOL_ERROR, "Invalid header value length");
|
||||
throw new StreamException(streamId, StreamStatus.PROTOCOL_ERROR, "Invalid header value length");
|
||||
byte[] valueBytes = new byte[valueLength];
|
||||
decompressedHeaders.get(valueBytes);
|
||||
String value = new String(valueBytes, iso1);
|
||||
|
@ -78,7 +80,7 @@ public abstract class HeadersBlockParser
|
|||
// Check if there are multiple NULs (section 2.6.9)
|
||||
for (String v : values)
|
||||
if (v.length() == 0)
|
||||
throw new StreamException(StreamStatus.PROTOCOL_ERROR, "Invalid multi valued header");
|
||||
throw new StreamException(streamId, StreamStatus.PROTOCOL_ERROR, "Invalid multi valued header");
|
||||
|
||||
onHeader(name, values);
|
||||
}
|
||||
|
@ -127,7 +129,7 @@ public abstract class HeadersBlockParser
|
|||
}
|
||||
}
|
||||
|
||||
private int readCount(int version, ByteBuffer buffer) throws StreamException
|
||||
private int readCount(int version, ByteBuffer buffer)
|
||||
{
|
||||
switch (version)
|
||||
{
|
||||
|
@ -140,19 +142,19 @@ public abstract class HeadersBlockParser
|
|||
}
|
||||
}
|
||||
|
||||
private int readNameLength(int version, ByteBuffer buffer) throws StreamException
|
||||
private int readNameLength(int version, ByteBuffer buffer)
|
||||
{
|
||||
return readCount(version, buffer);
|
||||
}
|
||||
|
||||
private int readValueLength(int version, ByteBuffer buffer) throws StreamException
|
||||
private int readValueLength(int version, ByteBuffer buffer)
|
||||
{
|
||||
return readCount(version, buffer);
|
||||
}
|
||||
|
||||
protected abstract void onHeader(String name, String[] values);
|
||||
|
||||
private ByteBuffer decompress(short version, byte[] compressed) throws StreamException
|
||||
private ByteBuffer decompress(short version, byte[] compressed)
|
||||
{
|
||||
// Differently from compression, decompression always happens
|
||||
// non-concurrently because we read and parse with a single
|
||||
|
@ -221,7 +223,9 @@ public abstract class HeadersBlockParser
|
|||
}
|
||||
catch (ZipException x)
|
||||
{
|
||||
throw new StreamException(StreamStatus.PROTOCOL_ERROR, x);
|
||||
// We had a compression problem, and since the compression context
|
||||
// is per-connection, we need to tear down the connection
|
||||
throw new SessionException(SessionStatus.PROTOCOL_ERROR, x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@ package org.eclipse.jetty.spdy.parser;
|
|||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.eclipse.jetty.spdy.CompressionFactory;
|
||||
import org.eclipse.jetty.spdy.StreamException;
|
||||
import org.eclipse.jetty.spdy.api.Headers;
|
||||
import org.eclipse.jetty.spdy.api.HeadersInfo;
|
||||
import org.eclipse.jetty.spdy.frames.ControlFrameType;
|
||||
|
@ -41,7 +40,7 @@ public class HeadersBodyParser extends ControlFrameBodyParser
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean parse(ByteBuffer buffer) throws StreamException
|
||||
public boolean parse(ByteBuffer buffer)
|
||||
{
|
||||
while (buffer.hasRemaining())
|
||||
{
|
||||
|
@ -77,7 +76,7 @@ public class HeadersBodyParser extends ControlFrameBodyParser
|
|||
{
|
||||
short version = controlFrameParser.getVersion();
|
||||
int length = controlFrameParser.getLength() - 4;
|
||||
if (headersBlockParser.parse(version, length, buffer))
|
||||
if (headersBlockParser.parse(streamId, version, length, buffer))
|
||||
{
|
||||
byte flags = controlFrameParser.getFlags();
|
||||
if (flags != 0 && flags != HeadersInfo.FLAG_CLOSE && flags != HeadersInfo.FLAG_RESET_COMPRESSION)
|
||||
|
|
|
@ -18,7 +18,6 @@ package org.eclipse.jetty.spdy.parser;
|
|||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.eclipse.jetty.spdy.StreamException;
|
||||
import org.eclipse.jetty.spdy.frames.NoOpFrame;
|
||||
|
||||
public class NoOpBodyParser extends ControlFrameBodyParser
|
||||
|
@ -31,7 +30,7 @@ public class NoOpBodyParser extends ControlFrameBodyParser
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean parse(ByteBuffer buffer) throws StreamException
|
||||
public boolean parse(ByteBuffer buffer)
|
||||
{
|
||||
NoOpFrame frame = new NoOpFrame();
|
||||
controlFrameParser.onControlFrame(frame);
|
||||
|
|
|
@ -110,7 +110,7 @@ public class Parser
|
|||
}
|
||||
}
|
||||
|
||||
protected void notifySPDYSessionException(SessionException x)
|
||||
protected void notifySessionException(SessionException x)
|
||||
{
|
||||
logger.debug("SPDY session exception", x);
|
||||
for (Listener listener : listeners)
|
||||
|
@ -165,7 +165,7 @@ public class Parser
|
|||
}
|
||||
catch (SessionException x)
|
||||
{
|
||||
notifySPDYSessionException(x);
|
||||
notifySessionException(x);
|
||||
}
|
||||
catch (StreamException x)
|
||||
{
|
||||
|
@ -173,7 +173,7 @@ public class Parser
|
|||
}
|
||||
catch (Throwable x)
|
||||
{
|
||||
notifySPDYSessionException(new SessionException(SessionStatus.PROTOCOL_ERROR, x));
|
||||
notifySessionException(new SessionException(SessionStatus.PROTOCOL_ERROR, x));
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
|
|
@ -18,7 +18,6 @@ package org.eclipse.jetty.spdy.parser;
|
|||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.eclipse.jetty.spdy.StreamException;
|
||||
import org.eclipse.jetty.spdy.frames.PingFrame;
|
||||
|
||||
public class PingBodyParser extends ControlFrameBodyParser
|
||||
|
@ -34,7 +33,7 @@ public class PingBodyParser extends ControlFrameBodyParser
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean parse(ByteBuffer buffer) throws StreamException
|
||||
public boolean parse(ByteBuffer buffer)
|
||||
{
|
||||
while (buffer.hasRemaining())
|
||||
{
|
||||
|
|
|
@ -18,7 +18,6 @@ package org.eclipse.jetty.spdy.parser;
|
|||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.eclipse.jetty.spdy.StreamException;
|
||||
import org.eclipse.jetty.spdy.frames.RstStreamFrame;
|
||||
|
||||
public class RstStreamBodyParser extends ControlFrameBodyParser
|
||||
|
@ -35,7 +34,7 @@ public class RstStreamBodyParser extends ControlFrameBodyParser
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean parse(ByteBuffer buffer) throws StreamException
|
||||
public boolean parse(ByteBuffer buffer)
|
||||
{
|
||||
while (buffer.hasRemaining())
|
||||
{
|
||||
|
|
|
@ -18,7 +18,6 @@ package org.eclipse.jetty.spdy.parser;
|
|||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.eclipse.jetty.spdy.StreamException;
|
||||
import org.eclipse.jetty.spdy.api.SPDY;
|
||||
import org.eclipse.jetty.spdy.api.Settings;
|
||||
import org.eclipse.jetty.spdy.frames.SettingsFrame;
|
||||
|
@ -39,7 +38,7 @@ public class SettingsBodyParser extends ControlFrameBodyParser
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean parse(ByteBuffer buffer) throws StreamException
|
||||
public boolean parse(ByteBuffer buffer)
|
||||
{
|
||||
while (buffer.hasRemaining())
|
||||
{
|
||||
|
|
|
@ -19,7 +19,6 @@ package org.eclipse.jetty.spdy.parser;
|
|||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.eclipse.jetty.spdy.CompressionFactory;
|
||||
import org.eclipse.jetty.spdy.StreamException;
|
||||
import org.eclipse.jetty.spdy.api.Headers;
|
||||
import org.eclipse.jetty.spdy.api.ReplyInfo;
|
||||
import org.eclipse.jetty.spdy.api.SPDY;
|
||||
|
@ -42,7 +41,7 @@ public class SynReplyBodyParser extends ControlFrameBodyParser
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean parse(ByteBuffer buffer) throws StreamException
|
||||
public boolean parse(ByteBuffer buffer)
|
||||
{
|
||||
while (buffer.hasRemaining())
|
||||
{
|
||||
|
@ -117,7 +116,7 @@ public class SynReplyBodyParser extends ControlFrameBodyParser
|
|||
{
|
||||
short version = controlFrameParser.getVersion();
|
||||
int length = controlFrameParser.getLength() - getSynReplyDataLength(version);
|
||||
if (headersBlockParser.parse(version, length, buffer))
|
||||
if (headersBlockParser.parse(streamId, version, length, buffer))
|
||||
{
|
||||
byte flags = controlFrameParser.getFlags();
|
||||
if (flags != 0 && flags != ReplyInfo.FLAG_CLOSE)
|
||||
|
@ -140,7 +139,7 @@ public class SynReplyBodyParser extends ControlFrameBodyParser
|
|||
return false;
|
||||
}
|
||||
|
||||
private int getSynReplyDataLength(short version) throws StreamException
|
||||
private int getSynReplyDataLength(short version)
|
||||
{
|
||||
switch (version)
|
||||
{
|
||||
|
|
|
@ -19,7 +19,6 @@ package org.eclipse.jetty.spdy.parser;
|
|||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.eclipse.jetty.spdy.CompressionFactory;
|
||||
import org.eclipse.jetty.spdy.StreamException;
|
||||
import org.eclipse.jetty.spdy.api.Headers;
|
||||
import org.eclipse.jetty.spdy.api.SPDY;
|
||||
import org.eclipse.jetty.spdy.api.SynInfo;
|
||||
|
@ -44,7 +43,7 @@ public class SynStreamBodyParser extends ControlFrameBodyParser
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean parse(ByteBuffer buffer) throws StreamException
|
||||
public boolean parse(ByteBuffer buffer)
|
||||
{
|
||||
while (buffer.hasRemaining())
|
||||
{
|
||||
|
@ -122,7 +121,7 @@ public class SynStreamBodyParser extends ControlFrameBodyParser
|
|||
{
|
||||
short version = controlFrameParser.getVersion();
|
||||
int length = controlFrameParser.getLength() - 10;
|
||||
if (headersBlockParser.parse(version, length, buffer))
|
||||
if (headersBlockParser.parse(streamId, version, length, buffer))
|
||||
{
|
||||
byte flags = controlFrameParser.getFlags();
|
||||
// TODO: can it be both FIN and UNIDIRECTIONAL ?
|
||||
|
@ -146,7 +145,7 @@ public class SynStreamBodyParser extends ControlFrameBodyParser
|
|||
return false;
|
||||
}
|
||||
|
||||
private byte readPriority(short version, byte currByte) throws StreamException
|
||||
private byte readPriority(short version, byte currByte)
|
||||
{
|
||||
// Right shift retains the sign bit when operated on a byte,
|
||||
// so we use an int to perform the shifts
|
||||
|
|
|
@ -18,8 +18,6 @@ package org.eclipse.jetty.spdy.parser;
|
|||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.eclipse.jetty.spdy.StreamException;
|
||||
|
||||
public class UnknownControlFrameBodyParser extends ControlFrameBodyParser
|
||||
{
|
||||
private int remaining;
|
||||
|
@ -30,7 +28,7 @@ public class UnknownControlFrameBodyParser extends ControlFrameBodyParser
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean parse(ByteBuffer buffer) throws StreamException
|
||||
public boolean parse(ByteBuffer buffer)
|
||||
{
|
||||
int consumed = Math.min(remaining, buffer.remaining());
|
||||
buffer.position(buffer.position() + consumed);
|
||||
|
|
|
@ -18,7 +18,6 @@ package org.eclipse.jetty.spdy.parser;
|
|||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.eclipse.jetty.spdy.StreamException;
|
||||
import org.eclipse.jetty.spdy.frames.WindowUpdateFrame;
|
||||
|
||||
public class WindowUpdateBodyParser extends ControlFrameBodyParser
|
||||
|
@ -35,7 +34,7 @@ public class WindowUpdateBodyParser extends ControlFrameBodyParser
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean parse(ByteBuffer buffer) throws StreamException
|
||||
public boolean parse(ByteBuffer buffer)
|
||||
{
|
||||
while (buffer.hasRemaining())
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue