Merge pull request #1921 from jpinner/kill_spdy_2
SPDY: remove SPDY/2 support
This commit is contained in:
commit
ef139306af
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012 The Netty Project
|
* Copyright 2013 The Netty Project
|
||||||
*
|
*
|
||||||
* The Netty Project licenses this file to you under the Apache License,
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
* version 2.0 (the "License"); you may not use this file except in compliance
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
@ -186,23 +186,10 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder {
|
|||||||
|
|
||||||
int readableEntries = Math.min(buffer.readableBytes() >> 3, length >> 3);
|
int readableEntries = Math.min(buffer.readableBytes() >> 3, length >> 3);
|
||||||
for (int i = 0; i < readableEntries; i ++) {
|
for (int i = 0; i < readableEntries; i ++) {
|
||||||
int ID;
|
byte ID_flags = buffer.getByte(buffer.readerIndex());
|
||||||
byte ID_flags;
|
int ID = getUnsignedMedium(buffer, buffer.readerIndex() + 1);
|
||||||
if (version < 3) {
|
int value = getSignedInt(buffer, buffer.readerIndex() + 4);
|
||||||
// Chromium Issue 79156
|
buffer.skipBytes(8);
|
||||||
// SPDY setting ids are not written in network byte order
|
|
||||||
// Read id assuming the architecture is little endian
|
|
||||||
ID = buffer.readByte() & 0xFF |
|
|
||||||
(buffer.readByte() & 0xFF) << 8 |
|
|
||||||
(buffer.readByte() & 0xFF) << 16;
|
|
||||||
ID_flags = buffer.readByte();
|
|
||||||
} else {
|
|
||||||
ID_flags = buffer.readByte();
|
|
||||||
ID = getUnsignedMedium(buffer, buffer.readerIndex());
|
|
||||||
buffer.skipBytes(3);
|
|
||||||
}
|
|
||||||
int value = getSignedInt(buffer, buffer.readerIndex());
|
|
||||||
buffer.skipBytes(4);
|
|
||||||
|
|
||||||
// Check for invalid ID -- avoid IllegalArgumentException in setValue
|
// Check for invalid ID -- avoid IllegalArgumentException in setValue
|
||||||
if (ID == 0) {
|
if (ID == 0) {
|
||||||
@ -427,20 +414,13 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder {
|
|||||||
return new DefaultSpdyPingFrame(ID);
|
return new DefaultSpdyPingFrame(ID);
|
||||||
|
|
||||||
case SPDY_GOAWAY_FRAME:
|
case SPDY_GOAWAY_FRAME:
|
||||||
int minLength = version < 3 ? 4 : 8;
|
if (buffer.readableBytes() < 8) {
|
||||||
if (buffer.readableBytes() < minLength) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lastGoodStreamId = getUnsignedInt(buffer, buffer.readerIndex());
|
int lastGoodStreamId = getUnsignedInt(buffer, buffer.readerIndex());
|
||||||
buffer.skipBytes(4);
|
statusCode = getSignedInt(buffer, buffer.readerIndex() + 4);
|
||||||
|
buffer.skipBytes(8);
|
||||||
if (version < 3) {
|
|
||||||
return new DefaultSpdyGoAwayFrame(lastGoodStreamId);
|
|
||||||
}
|
|
||||||
|
|
||||||
statusCode = getSignedInt(buffer, buffer.readerIndex());
|
|
||||||
buffer.skipBytes(4);
|
|
||||||
|
|
||||||
return new DefaultSpdyGoAwayFrame(lastGoodStreamId, statusCode);
|
return new DefaultSpdyGoAwayFrame(lastGoodStreamId, statusCode);
|
||||||
|
|
||||||
@ -461,12 +441,10 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private SpdyHeadersFrame readHeaderBlockFrame(ByteBuf buffer) {
|
private SpdyHeadersFrame readHeaderBlockFrame(ByteBuf buffer) {
|
||||||
int minLength;
|
|
||||||
int streamId;
|
int streamId;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SPDY_SYN_STREAM_FRAME:
|
case SPDY_SYN_STREAM_FRAME:
|
||||||
minLength = version < 3 ? 12 : 10;
|
if (buffer.readableBytes() < 10) {
|
||||||
if (buffer.readableBytes() < minLength) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -474,18 +452,9 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder {
|
|||||||
streamId = getUnsignedInt(buffer, offset);
|
streamId = getUnsignedInt(buffer, offset);
|
||||||
int associatedToStreamId = getUnsignedInt(buffer, offset + 4);
|
int associatedToStreamId = getUnsignedInt(buffer, offset + 4);
|
||||||
byte priority = (byte) (buffer.getByte(offset + 8) >> 5 & 0x07);
|
byte priority = (byte) (buffer.getByte(offset + 8) >> 5 & 0x07);
|
||||||
if (version < 3) {
|
|
||||||
priority >>= 1;
|
|
||||||
}
|
|
||||||
buffer.skipBytes(10);
|
buffer.skipBytes(10);
|
||||||
length -= 10;
|
length -= 10;
|
||||||
|
|
||||||
// SPDY/2 requires 16-bits of padding for empty header blocks
|
|
||||||
if (version < 3 && length == 2 && buffer.getShort(buffer.readerIndex()) == 0) {
|
|
||||||
buffer.skipBytes(2);
|
|
||||||
length = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
SpdySynStreamFrame spdySynStreamFrame =
|
SpdySynStreamFrame spdySynStreamFrame =
|
||||||
new DefaultSpdySynStreamFrame(streamId, associatedToStreamId, priority);
|
new DefaultSpdySynStreamFrame(streamId, associatedToStreamId, priority);
|
||||||
spdySynStreamFrame.setLast((flags & SPDY_FLAG_FIN) != 0);
|
spdySynStreamFrame.setLast((flags & SPDY_FLAG_FIN) != 0);
|
||||||
@ -494,8 +463,7 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder {
|
|||||||
return spdySynStreamFrame;
|
return spdySynStreamFrame;
|
||||||
|
|
||||||
case SPDY_SYN_REPLY_FRAME:
|
case SPDY_SYN_REPLY_FRAME:
|
||||||
minLength = version < 3 ? 8 : 4;
|
if (buffer.readableBytes() < 4) {
|
||||||
if (buffer.readableBytes() < minLength) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -503,18 +471,6 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder {
|
|||||||
buffer.skipBytes(4);
|
buffer.skipBytes(4);
|
||||||
length -= 4;
|
length -= 4;
|
||||||
|
|
||||||
// SPDY/2 has 16-bits of unused space
|
|
||||||
if (version < 3) {
|
|
||||||
buffer.skipBytes(2);
|
|
||||||
length -= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SPDY/2 requires 16-bits of padding for empty header blocks
|
|
||||||
if (version < 3 && length == 2 && buffer.getShort(buffer.readerIndex()) == 0) {
|
|
||||||
buffer.skipBytes(2);
|
|
||||||
length = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
SpdySynReplyFrame spdySynReplyFrame = new DefaultSpdySynReplyFrame(streamId);
|
SpdySynReplyFrame spdySynReplyFrame = new DefaultSpdySynReplyFrame(streamId);
|
||||||
spdySynReplyFrame.setLast((flags & SPDY_FLAG_FIN) != 0);
|
spdySynReplyFrame.setLast((flags & SPDY_FLAG_FIN) != 0);
|
||||||
|
|
||||||
@ -525,27 +481,10 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SPDY/2 allows length 4 frame when there are no name/value pairs
|
|
||||||
if (version < 3 && length > 4 && buffer.readableBytes() < 8) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
streamId = getUnsignedInt(buffer, buffer.readerIndex());
|
streamId = getUnsignedInt(buffer, buffer.readerIndex());
|
||||||
buffer.skipBytes(4);
|
buffer.skipBytes(4);
|
||||||
length -= 4;
|
length -= 4;
|
||||||
|
|
||||||
// SPDY/2 has 16-bits of unused space
|
|
||||||
if (version < 3 && length != 0) {
|
|
||||||
buffer.skipBytes(2);
|
|
||||||
length -= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SPDY/2 requires 16-bits of padding for empty header blocks
|
|
||||||
if (version < 3 && length == 2 && buffer.getShort(buffer.readerIndex()) == 0) {
|
|
||||||
buffer.skipBytes(2);
|
|
||||||
length = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
SpdyHeadersFrame spdyHeadersFrame = new DefaultSpdyHeadersFrame(streamId);
|
SpdyHeadersFrame spdyHeadersFrame = new DefaultSpdyHeadersFrame(streamId);
|
||||||
spdyHeadersFrame.setLast((flags & SPDY_FLAG_FIN) != 0);
|
spdyHeadersFrame.setLast((flags & SPDY_FLAG_FIN) != 0);
|
||||||
|
|
||||||
@ -562,10 +501,10 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder {
|
|||||||
return streamId != 0;
|
return streamId != 0;
|
||||||
|
|
||||||
case SPDY_SYN_STREAM_FRAME:
|
case SPDY_SYN_STREAM_FRAME:
|
||||||
return version < 3 ? length >= 12 : length >= 10;
|
return length >= 10;
|
||||||
|
|
||||||
case SPDY_SYN_REPLY_FRAME:
|
case SPDY_SYN_REPLY_FRAME:
|
||||||
return version < 3 ? length >= 8 : length >= 4;
|
return length >= 4;
|
||||||
|
|
||||||
case SPDY_RST_STREAM_FRAME:
|
case SPDY_RST_STREAM_FRAME:
|
||||||
return flags == 0 && length == 8;
|
return flags == 0 && length == 8;
|
||||||
@ -577,14 +516,10 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder {
|
|||||||
return length == 4;
|
return length == 4;
|
||||||
|
|
||||||
case SPDY_GOAWAY_FRAME:
|
case SPDY_GOAWAY_FRAME:
|
||||||
return version < 3 ? length == 4 : length == 8;
|
return length == 8;
|
||||||
|
|
||||||
case SPDY_HEADERS_FRAME:
|
case SPDY_HEADERS_FRAME:
|
||||||
if (version < 3) {
|
return length >= 4;
|
||||||
return length == 4 || length >= 8;
|
|
||||||
} else {
|
|
||||||
return length >= 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SPDY_WINDOW_UPDATE_FRAME:
|
case SPDY_WINDOW_UPDATE_FRAME:
|
||||||
return length == 8;
|
return length == 8;
|
||||||
|
@ -92,12 +92,7 @@ public class SpdyFrameEncoder extends MessageToByteEncoder<SpdyFrame> {
|
|||||||
flags |= SPDY_FLAG_UNIDIRECTIONAL;
|
flags |= SPDY_FLAG_UNIDIRECTIONAL;
|
||||||
}
|
}
|
||||||
int headerBlockLength = data.readableBytes();
|
int headerBlockLength = data.readableBytes();
|
||||||
int length;
|
int length = 10 + headerBlockLength;
|
||||||
if (version < 3) {
|
|
||||||
length = headerBlockLength == 0 ? 12 : 10 + headerBlockLength;
|
|
||||||
} else {
|
|
||||||
length = 10 + headerBlockLength;
|
|
||||||
}
|
|
||||||
out.ensureWritable(SPDY_HEADER_SIZE + length);
|
out.ensureWritable(SPDY_HEADER_SIZE + length);
|
||||||
out.writeShort(version | 0x8000);
|
out.writeShort(version | 0x8000);
|
||||||
out.writeShort(SPDY_SYN_STREAM_FRAME);
|
out.writeShort(SPDY_SYN_STREAM_FRAME);
|
||||||
@ -105,19 +100,7 @@ public class SpdyFrameEncoder extends MessageToByteEncoder<SpdyFrame> {
|
|||||||
out.writeMedium(length);
|
out.writeMedium(length);
|
||||||
out.writeInt(spdySynStreamFrame.getStreamId());
|
out.writeInt(spdySynStreamFrame.getStreamId());
|
||||||
out.writeInt(spdySynStreamFrame.getAssociatedToStreamId());
|
out.writeInt(spdySynStreamFrame.getAssociatedToStreamId());
|
||||||
if (version < 3) {
|
out.writeShort((spdySynStreamFrame.getPriority() & 0xFF) << 13);
|
||||||
// Restrict priorities for SPDY/2 to between 0 and 3
|
|
||||||
byte priority = spdySynStreamFrame.getPriority();
|
|
||||||
if (priority > 3) {
|
|
||||||
priority = 3;
|
|
||||||
}
|
|
||||||
out.writeShort((priority & 0xFF) << 14);
|
|
||||||
} else {
|
|
||||||
out.writeShort((spdySynStreamFrame.getPriority() & 0xFF) << 13);
|
|
||||||
}
|
|
||||||
if (version < 3 && data.readableBytes() == 0) {
|
|
||||||
out.writeShort(0);
|
|
||||||
}
|
|
||||||
out.writeBytes(data, data.readerIndex(), headerBlockLength);
|
out.writeBytes(data, data.readerIndex(), headerBlockLength);
|
||||||
} finally {
|
} finally {
|
||||||
data.release();
|
data.release();
|
||||||
@ -130,25 +113,13 @@ public class SpdyFrameEncoder extends MessageToByteEncoder<SpdyFrame> {
|
|||||||
try {
|
try {
|
||||||
byte flags = spdySynReplyFrame.isLast() ? SPDY_FLAG_FIN : 0;
|
byte flags = spdySynReplyFrame.isLast() ? SPDY_FLAG_FIN : 0;
|
||||||
int headerBlockLength = data.readableBytes();
|
int headerBlockLength = data.readableBytes();
|
||||||
int length;
|
int length = 4 + headerBlockLength;
|
||||||
if (version < 3) {
|
|
||||||
length = headerBlockLength == 0 ? 8 : 6 + headerBlockLength;
|
|
||||||
} else {
|
|
||||||
length = 4 + headerBlockLength;
|
|
||||||
}
|
|
||||||
out.ensureWritable(SPDY_HEADER_SIZE + length);
|
out.ensureWritable(SPDY_HEADER_SIZE + length);
|
||||||
out.writeShort(version | 0x8000);
|
out.writeShort(version | 0x8000);
|
||||||
out.writeShort(SPDY_SYN_REPLY_FRAME);
|
out.writeShort(SPDY_SYN_REPLY_FRAME);
|
||||||
out.writeByte(flags);
|
out.writeByte(flags);
|
||||||
out.writeMedium(length);
|
out.writeMedium(length);
|
||||||
out.writeInt(spdySynReplyFrame.getStreamId());
|
out.writeInt(spdySynReplyFrame.getStreamId());
|
||||||
if (version < 3) {
|
|
||||||
if (headerBlockLength == 0) {
|
|
||||||
out.writeInt(0);
|
|
||||||
} else {
|
|
||||||
out.writeShort(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
out.writeBytes(data, data.readerIndex(), headerBlockLength);
|
out.writeBytes(data, data.readerIndex(), headerBlockLength);
|
||||||
} finally {
|
} finally {
|
||||||
data.release();
|
data.release();
|
||||||
@ -178,8 +149,7 @@ public class SpdyFrameEncoder extends MessageToByteEncoder<SpdyFrame> {
|
|||||||
out.writeByte(flags);
|
out.writeByte(flags);
|
||||||
out.writeMedium(length);
|
out.writeMedium(length);
|
||||||
out.writeInt(numEntries);
|
out.writeInt(numEntries);
|
||||||
for (Integer ID: IDs) {
|
for (Integer id: IDs) {
|
||||||
int id = ID.intValue();
|
|
||||||
byte ID_flags = 0;
|
byte ID_flags = 0;
|
||||||
if (spdySettingsFrame.isPersistValue(id)) {
|
if (spdySettingsFrame.isPersistValue(id)) {
|
||||||
ID_flags |= SPDY_SETTINGS_PERSIST_VALUE;
|
ID_flags |= SPDY_SETTINGS_PERSIST_VALUE;
|
||||||
@ -187,18 +157,8 @@ public class SpdyFrameEncoder extends MessageToByteEncoder<SpdyFrame> {
|
|||||||
if (spdySettingsFrame.isPersisted(id)) {
|
if (spdySettingsFrame.isPersisted(id)) {
|
||||||
ID_flags |= SPDY_SETTINGS_PERSISTED;
|
ID_flags |= SPDY_SETTINGS_PERSISTED;
|
||||||
}
|
}
|
||||||
if (version < 3) {
|
out.writeByte(ID_flags);
|
||||||
// Chromium Issue 79156
|
out.writeMedium(id);
|
||||||
// SPDY setting ids are not written in network byte order
|
|
||||||
// Write id assuming the architecture is little endian
|
|
||||||
out.writeByte(id & 0xFF);
|
|
||||||
out.writeByte(id >> 8 & 0xFF);
|
|
||||||
out.writeByte(id >> 16 & 0xFF);
|
|
||||||
out.writeByte(ID_flags);
|
|
||||||
} else {
|
|
||||||
out.writeByte(ID_flags);
|
|
||||||
out.writeMedium(id);
|
|
||||||
}
|
|
||||||
out.writeInt(spdySettingsFrame.getValue(id));
|
out.writeInt(spdySettingsFrame.getValue(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,15 +174,12 @@ public class SpdyFrameEncoder extends MessageToByteEncoder<SpdyFrame> {
|
|||||||
} else if (msg instanceof SpdyGoAwayFrame) {
|
} else if (msg instanceof SpdyGoAwayFrame) {
|
||||||
|
|
||||||
SpdyGoAwayFrame spdyGoAwayFrame = (SpdyGoAwayFrame) msg;
|
SpdyGoAwayFrame spdyGoAwayFrame = (SpdyGoAwayFrame) msg;
|
||||||
int length = version < 3 ? 4 : 8;
|
out.ensureWritable(SPDY_HEADER_SIZE + 8);
|
||||||
out.ensureWritable(SPDY_HEADER_SIZE + length);
|
|
||||||
out.writeShort(version | 0x8000);
|
out.writeShort(version | 0x8000);
|
||||||
out.writeShort(SPDY_GOAWAY_FRAME);
|
out.writeShort(SPDY_GOAWAY_FRAME);
|
||||||
out.writeInt(length);
|
out.writeInt(8);
|
||||||
out.writeInt(spdyGoAwayFrame.getLastGoodStreamId());
|
out.writeInt(spdyGoAwayFrame.getLastGoodStreamId());
|
||||||
if (version >= 3) {
|
out.writeInt(spdyGoAwayFrame.getStatus().getCode());
|
||||||
out.writeInt(spdyGoAwayFrame.getStatus().getCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (msg instanceof SpdyHeadersFrame) {
|
} else if (msg instanceof SpdyHeadersFrame) {
|
||||||
|
|
||||||
@ -231,21 +188,13 @@ public class SpdyFrameEncoder extends MessageToByteEncoder<SpdyFrame> {
|
|||||||
try {
|
try {
|
||||||
byte flags = spdyHeadersFrame.isLast() ? SPDY_FLAG_FIN : 0;
|
byte flags = spdyHeadersFrame.isLast() ? SPDY_FLAG_FIN : 0;
|
||||||
int headerBlockLength = data.readableBytes();
|
int headerBlockLength = data.readableBytes();
|
||||||
int length;
|
int length = 4 + headerBlockLength;
|
||||||
if (version < 3) {
|
|
||||||
length = headerBlockLength == 0 ? 4 : 6 + headerBlockLength;
|
|
||||||
} else {
|
|
||||||
length = 4 + headerBlockLength;
|
|
||||||
}
|
|
||||||
out.ensureWritable(SPDY_HEADER_SIZE + length);
|
out.ensureWritable(SPDY_HEADER_SIZE + length);
|
||||||
out.writeShort(version | 0x8000);
|
out.writeShort(version | 0x8000);
|
||||||
out.writeShort(SPDY_HEADERS_FRAME);
|
out.writeShort(SPDY_HEADERS_FRAME);
|
||||||
out.writeByte(flags);
|
out.writeByte(flags);
|
||||||
out.writeMedium(length);
|
out.writeMedium(length);
|
||||||
out.writeInt(spdyHeadersFrame.getStreamId());
|
out.writeInt(spdyHeadersFrame.getStreamId());
|
||||||
if (version < 3 && headerBlockLength != 0) {
|
|
||||||
out.writeShort(0);
|
|
||||||
}
|
|
||||||
out.writeBytes(data, data.readerIndex(), headerBlockLength);
|
out.writeBytes(data, data.readerIndex(), headerBlockLength);
|
||||||
} finally {
|
} finally {
|
||||||
data.release();
|
data.release();
|
||||||
|
@ -39,7 +39,6 @@ public abstract class SpdyOrHttpChooser extends ByteToMessageDecoder {
|
|||||||
// TODO: Replace with generic NPN handler
|
// TODO: Replace with generic NPN handler
|
||||||
|
|
||||||
public enum SelectedProtocol {
|
public enum SelectedProtocol {
|
||||||
SPDY_2,
|
|
||||||
SPDY_3,
|
SPDY_3,
|
||||||
SPDY_3_1,
|
SPDY_3_1,
|
||||||
HTTP_1_1,
|
HTTP_1_1,
|
||||||
@ -84,9 +83,6 @@ public abstract class SpdyOrHttpChooser extends ByteToMessageDecoder {
|
|||||||
case UNKNOWN:
|
case UNKNOWN:
|
||||||
// Not done with choosing the protocol, so just return here for now,
|
// Not done with choosing the protocol, so just return here for now,
|
||||||
return false;
|
return false;
|
||||||
case SPDY_2:
|
|
||||||
addSpdyHandlers(ctx, SpdyVersion.SPDY_2);
|
|
||||||
break;
|
|
||||||
case SPDY_3:
|
case SPDY_3:
|
||||||
addSpdyHandlers(ctx, SpdyVersion.SPDY_3);
|
addSpdyHandlers(ctx, SpdyVersion.SPDY_3);
|
||||||
break;
|
break;
|
||||||
@ -137,8 +133,8 @@ public abstract class SpdyOrHttpChooser extends ByteToMessageDecoder {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Create the {@link ChannelInboundHandler} that is responsible for handling the http responses
|
* Create the {@link ChannelInboundHandler} that is responsible for handling the http responses
|
||||||
* when the {@link SelectedProtocol} was {@link SelectedProtocol#SPDY_2} or
|
* when the {@link SelectedProtocol} was {@link SelectedProtocol#SPDY_3} or
|
||||||
* {@link SelectedProtocol#SPDY_3}.
|
* {@link SelectedProtocol#SPDY_3_1}.
|
||||||
*
|
*
|
||||||
* By default this getMethod will just delecate to {@link #createHttpRequestHandlerForHttp()}, but
|
* By default this getMethod will just delecate to {@link #createHttpRequestHandlerForHttp()}, but
|
||||||
* sub-classes may override this to change the behaviour.
|
* sub-classes may override this to change the behaviour.
|
||||||
|
@ -61,7 +61,6 @@ public class SpdySessionHandler
|
|||||||
private ChannelFutureListener closeSessionFutureListener;
|
private ChannelFutureListener closeSessionFutureListener;
|
||||||
|
|
||||||
private final boolean server;
|
private final boolean server;
|
||||||
private final boolean flowControl;
|
|
||||||
private final boolean sessionFlowControl;
|
private final boolean sessionFlowControl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -78,7 +77,6 @@ public class SpdySessionHandler
|
|||||||
throw new NullPointerException("version");
|
throw new NullPointerException("version");
|
||||||
}
|
}
|
||||||
this.server = server;
|
this.server = server;
|
||||||
flowControl = version.useFlowControl();
|
|
||||||
sessionFlowControl = version.useSessionFlowControl();
|
sessionFlowControl = version.useSessionFlowControl();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,40 +163,38 @@ public class SpdySessionHandler
|
|||||||
* Recipient should not send a WINDOW_UPDATE frame as it consumes the last data frame.
|
* Recipient should not send a WINDOW_UPDATE frame as it consumes the last data frame.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (flowControl) {
|
// Update receive window size
|
||||||
// Update receive window size
|
int deltaWindowSize = -1 * spdyDataFrame.content().readableBytes();
|
||||||
int deltaWindowSize = -1 * spdyDataFrame.content().readableBytes();
|
int newWindowSize = spdySession.updateReceiveWindowSize(streamId, deltaWindowSize);
|
||||||
int newWindowSize = spdySession.updateReceiveWindowSize(streamId, deltaWindowSize);
|
|
||||||
|
|
||||||
// Window size can become negative if we sent a SETTINGS frame that reduces the
|
// Window size can become negative if we sent a SETTINGS frame that reduces the
|
||||||
// size of the transfer window after the peer has written data frames.
|
// size of the transfer window after the peer has written data frames.
|
||||||
// The value is bounded by the length that SETTINGS frame decrease the window.
|
// The value is bounded by the length that SETTINGS frame decrease the window.
|
||||||
// This difference is stored for the session when writing the SETTINGS frame
|
// This difference is stored for the session when writing the SETTINGS frame
|
||||||
// and is cleared once we send a WINDOW_UPDATE frame.
|
// and is cleared once we send a WINDOW_UPDATE frame.
|
||||||
if (newWindowSize < spdySession.getReceiveWindowSizeLowerBound(streamId)) {
|
if (newWindowSize < spdySession.getReceiveWindowSizeLowerBound(streamId)) {
|
||||||
spdyDataFrame.release();
|
spdyDataFrame.release();
|
||||||
issueStreamError(ctx, streamId, SpdyStreamStatus.FLOW_CONTROL_ERROR);
|
issueStreamError(ctx, streamId, SpdyStreamStatus.FLOW_CONTROL_ERROR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Window size became negative due to sender writing frame before receiving SETTINGS
|
// Window size became negative due to sender writing frame before receiving SETTINGS
|
||||||
// Send data frames upstream in initialReceiveWindowSize chunks
|
// Send data frames upstream in initialReceiveWindowSize chunks
|
||||||
if (newWindowSize < 0) {
|
if (newWindowSize < 0) {
|
||||||
while (spdyDataFrame.content().readableBytes() > initialReceiveWindowSize) {
|
while (spdyDataFrame.content().readableBytes() > initialReceiveWindowSize) {
|
||||||
SpdyDataFrame partialDataFrame = new DefaultSpdyDataFrame(streamId,
|
SpdyDataFrame partialDataFrame = new DefaultSpdyDataFrame(streamId,
|
||||||
spdyDataFrame.content().readSlice(initialReceiveWindowSize).retain());
|
spdyDataFrame.content().readSlice(initialReceiveWindowSize).retain());
|
||||||
ctx.writeAndFlush(partialDataFrame);
|
ctx.writeAndFlush(partialDataFrame);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Send a WINDOW_UPDATE frame if less than half the stream window size remains
|
// Send a WINDOW_UPDATE frame if less than half the stream window size remains
|
||||||
if (newWindowSize <= initialReceiveWindowSize / 2 && !spdyDataFrame.isLast()) {
|
if (newWindowSize <= initialReceiveWindowSize / 2 && !spdyDataFrame.isLast()) {
|
||||||
deltaWindowSize = initialReceiveWindowSize - newWindowSize;
|
deltaWindowSize = initialReceiveWindowSize - newWindowSize;
|
||||||
spdySession.updateReceiveWindowSize(streamId, deltaWindowSize);
|
spdySession.updateReceiveWindowSize(streamId, deltaWindowSize);
|
||||||
SpdyWindowUpdateFrame spdyWindowUpdateFrame =
|
SpdyWindowUpdateFrame spdyWindowUpdateFrame =
|
||||||
new DefaultSpdyWindowUpdateFrame(streamId, deltaWindowSize);
|
new DefaultSpdyWindowUpdateFrame(streamId, deltaWindowSize);
|
||||||
ctx.writeAndFlush(spdyWindowUpdateFrame);
|
ctx.writeAndFlush(spdyWindowUpdateFrame);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close the remote side of the stream if this is the last frame
|
// Close the remote side of the stream if this is the last frame
|
||||||
@ -313,12 +309,10 @@ public class SpdySessionHandler
|
|||||||
}
|
}
|
||||||
spdySettingsFrame.setPersistValue(SpdySettingsFrame.SETTINGS_INITIAL_WINDOW_SIZE, false);
|
spdySettingsFrame.setPersistValue(SpdySettingsFrame.SETTINGS_INITIAL_WINDOW_SIZE, false);
|
||||||
|
|
||||||
if (flowControl) {
|
int newInitialWindowSize =
|
||||||
int newInitialWindowSize =
|
spdySettingsFrame.getValue(SpdySettingsFrame.SETTINGS_INITIAL_WINDOW_SIZE);
|
||||||
spdySettingsFrame.getValue(SpdySettingsFrame.SETTINGS_INITIAL_WINDOW_SIZE);
|
if (newInitialWindowSize >= 0) {
|
||||||
if (newInitialWindowSize >= 0) {
|
updateInitialSendWindowSize(newInitialWindowSize);
|
||||||
updateInitialSendWindowSize(newInitialWindowSize);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (msg instanceof SpdyPingFrame) {
|
} else if (msg instanceof SpdyPingFrame) {
|
||||||
@ -382,28 +376,26 @@ public class SpdySessionHandler
|
|||||||
* after sending the last frame for the stream.
|
* after sending the last frame for the stream.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (flowControl) {
|
SpdyWindowUpdateFrame spdyWindowUpdateFrame = (SpdyWindowUpdateFrame) msg;
|
||||||
SpdyWindowUpdateFrame spdyWindowUpdateFrame = (SpdyWindowUpdateFrame) msg;
|
int streamId = spdyWindowUpdateFrame.getStreamId();
|
||||||
int streamId = spdyWindowUpdateFrame.getStreamId();
|
int deltaWindowSize = spdyWindowUpdateFrame.getDeltaWindowSize();
|
||||||
int deltaWindowSize = spdyWindowUpdateFrame.getDeltaWindowSize();
|
|
||||||
|
|
||||||
// Ignore frames for half-closed streams
|
// Ignore frames for half-closed streams
|
||||||
if (streamId != SPDY_SESSION_STREAM_ID && spdySession.isLocalSideClosed(streamId)) {
|
if (streamId != SPDY_SESSION_STREAM_ID && spdySession.isLocalSideClosed(streamId)) {
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
// Check for numerical overflow
|
|
||||||
if (spdySession.getSendWindowSize(streamId) > Integer.MAX_VALUE - deltaWindowSize) {
|
|
||||||
if (streamId == SPDY_SESSION_STREAM_ID) {
|
|
||||||
issueSessionError(ctx, SpdySessionStatus.PROTOCOL_ERROR);
|
|
||||||
} else {
|
|
||||||
issueStreamError(ctx, streamId, SpdyStreamStatus.FLOW_CONTROL_ERROR);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
updateSendWindowSize(ctx, streamId, deltaWindowSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for numerical overflow
|
||||||
|
if (spdySession.getSendWindowSize(streamId) > Integer.MAX_VALUE - deltaWindowSize) {
|
||||||
|
if (streamId == SPDY_SESSION_STREAM_ID) {
|
||||||
|
issueSessionError(ctx, SpdySessionStatus.PROTOCOL_ERROR);
|
||||||
|
} else {
|
||||||
|
issueStreamError(ctx, streamId, SpdyStreamStatus.FLOW_CONTROL_ERROR);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateSendWindowSize(ctx, streamId, deltaWindowSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.fireChannelRead(msg);
|
ctx.fireChannelRead(msg);
|
||||||
@ -475,65 +467,63 @@ public class SpdySessionHandler
|
|||||||
* sender must pause transmitting data frames.
|
* sender must pause transmitting data frames.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (flowControl) {
|
synchronized (flowControlLock) {
|
||||||
synchronized (flowControlLock) {
|
int dataLength = spdyDataFrame.content().readableBytes();
|
||||||
int dataLength = spdyDataFrame.content().readableBytes();
|
int sendWindowSize = spdySession.getSendWindowSize(streamId);
|
||||||
int sendWindowSize = spdySession.getSendWindowSize(streamId);
|
|
||||||
|
|
||||||
|
if (sessionFlowControl) {
|
||||||
|
int sessionSendWindowSize = spdySession.getSendWindowSize(SPDY_SESSION_STREAM_ID);
|
||||||
|
sendWindowSize = Math.min(sendWindowSize, sessionSendWindowSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sendWindowSize <= 0) {
|
||||||
|
// Stream is stalled -- enqueue Data frame and return
|
||||||
|
spdySession.putPendingWrite(streamId, new SpdySession.PendingWrite(spdyDataFrame, promise));
|
||||||
|
return;
|
||||||
|
} else if (sendWindowSize < dataLength) {
|
||||||
|
// Stream is not stalled but we cannot send the entire frame
|
||||||
|
spdySession.updateSendWindowSize(streamId, -1 * sendWindowSize);
|
||||||
if (sessionFlowControl) {
|
if (sessionFlowControl) {
|
||||||
int sessionSendWindowSize = spdySession.getSendWindowSize(SPDY_SESSION_STREAM_ID);
|
spdySession.updateSendWindowSize(SPDY_SESSION_STREAM_ID, -1 * sendWindowSize);
|
||||||
sendWindowSize = Math.min(sendWindowSize, sessionSendWindowSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sendWindowSize <= 0) {
|
// Create a partial data frame whose length is the current window size
|
||||||
// Stream is stalled -- enqueue Data frame and return
|
SpdyDataFrame partialDataFrame = new DefaultSpdyDataFrame(streamId,
|
||||||
spdySession.putPendingWrite(streamId, new SpdySession.PendingWrite(spdyDataFrame, promise));
|
spdyDataFrame.content().readSlice(sendWindowSize).retain());
|
||||||
return;
|
|
||||||
} else if (sendWindowSize < dataLength) {
|
|
||||||
// Stream is not stalled but we cannot send the entire frame
|
|
||||||
spdySession.updateSendWindowSize(streamId, -1 * sendWindowSize);
|
|
||||||
if (sessionFlowControl) {
|
|
||||||
spdySession.updateSendWindowSize(SPDY_SESSION_STREAM_ID, -1 * sendWindowSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a partial data frame whose length is the current window size
|
// Enqueue the remaining data (will be the first frame queued)
|
||||||
SpdyDataFrame partialDataFrame = new DefaultSpdyDataFrame(streamId,
|
spdySession.putPendingWrite(streamId, new SpdySession.PendingWrite(spdyDataFrame, promise));
|
||||||
spdyDataFrame.content().readSlice(sendWindowSize).retain());
|
|
||||||
|
|
||||||
// Enqueue the remaining data (will be the first frame queued)
|
// The transfer window size is pre-decremented when sending a data frame downstream.
|
||||||
spdySession.putPendingWrite(streamId, new SpdySession.PendingWrite(spdyDataFrame, promise));
|
// Close the session on write failures that leave the transfer window in a corrupt state.
|
||||||
|
final ChannelHandlerContext context = ctx;
|
||||||
// The transfer window size is pre-decremented when sending a data frame downstream.
|
ctx.write(partialDataFrame).addListener(new ChannelFutureListener() {
|
||||||
// Close the session on write failures that leave the transfer window in a corrupt state.
|
@Override
|
||||||
final ChannelHandlerContext context = ctx;
|
public void operationComplete(ChannelFuture future) throws Exception {
|
||||||
ctx.write(partialDataFrame).addListener(new ChannelFutureListener() {
|
if (!future.isSuccess()) {
|
||||||
@Override
|
issueSessionError(context, SpdySessionStatus.INTERNAL_ERROR);
|
||||||
public void operationComplete(ChannelFuture future) throws Exception {
|
|
||||||
if (!future.isSuccess()) {
|
|
||||||
issueSessionError(context, SpdySessionStatus.INTERNAL_ERROR);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
// Window size is large enough to send entire data frame
|
|
||||||
spdySession.updateSendWindowSize(streamId, -1 * dataLength);
|
|
||||||
if (sessionFlowControl) {
|
|
||||||
spdySession.updateSendWindowSize(SPDY_SESSION_STREAM_ID, -1 * dataLength);
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
// The transfer window size is pre-decremented when sending a data frame downstream.
|
return;
|
||||||
// Close the session on write failures that leave the transfer window in a corrupt state.
|
} else {
|
||||||
final ChannelHandlerContext context = ctx;
|
// Window size is large enough to send entire data frame
|
||||||
promise.addListener(new ChannelFutureListener() {
|
spdySession.updateSendWindowSize(streamId, -1 * dataLength);
|
||||||
@Override
|
if (sessionFlowControl) {
|
||||||
public void operationComplete(ChannelFuture future) throws Exception {
|
spdySession.updateSendWindowSize(SPDY_SESSION_STREAM_ID, -1 * dataLength);
|
||||||
if (!future.isSuccess()) {
|
|
||||||
issueSessionError(context, SpdySessionStatus.INTERNAL_ERROR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The transfer window size is pre-decremented when sending a data frame downstream.
|
||||||
|
// Close the session on write failures that leave the transfer window in a corrupt state.
|
||||||
|
final ChannelHandlerContext context = ctx;
|
||||||
|
promise.addListener(new ChannelFutureListener() {
|
||||||
|
@Override
|
||||||
|
public void operationComplete(ChannelFuture future) throws Exception {
|
||||||
|
if (!future.isSuccess()) {
|
||||||
|
issueSessionError(context, SpdySessionStatus.INTERNAL_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -599,12 +589,10 @@ public class SpdySessionHandler
|
|||||||
}
|
}
|
||||||
spdySettingsFrame.setPersistValue(SpdySettingsFrame.SETTINGS_INITIAL_WINDOW_SIZE, false);
|
spdySettingsFrame.setPersistValue(SpdySettingsFrame.SETTINGS_INITIAL_WINDOW_SIZE, false);
|
||||||
|
|
||||||
if (flowControl) {
|
int newInitialWindowSize =
|
||||||
int newInitialWindowSize =
|
spdySettingsFrame.getValue(SpdySettingsFrame.SETTINGS_INITIAL_WINDOW_SIZE);
|
||||||
spdySettingsFrame.getValue(SpdySettingsFrame.SETTINGS_INITIAL_WINDOW_SIZE);
|
if (newInitialWindowSize >= 0) {
|
||||||
if (newInitialWindowSize >= 0) {
|
updateInitialReceiveWindowSize(newInitialWindowSize);
|
||||||
updateInitialReceiveWindowSize(newInitialWindowSize);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (msg instanceof SpdyPingFrame) {
|
} else if (msg instanceof SpdyPingFrame) {
|
||||||
|
@ -16,28 +16,14 @@
|
|||||||
package io.netty.handler.codec.spdy;
|
package io.netty.handler.codec.spdy;
|
||||||
|
|
||||||
public enum SpdyVersion {
|
public enum SpdyVersion {
|
||||||
SPDY_2 (2, false, false),
|
SPDY_3 (3, false),
|
||||||
SPDY_3 (3, true, false),
|
SPDY_3_1 (3, true);
|
||||||
SPDY_3_1 (3, true, true);
|
|
||||||
|
|
||||||
static SpdyVersion valueOf(int version) {
|
|
||||||
if (version == 2) {
|
|
||||||
return SPDY_2;
|
|
||||||
}
|
|
||||||
if (version == 3) {
|
|
||||||
return SPDY_3;
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"unsupported version: " + version);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final int version;
|
private final int version;
|
||||||
private final boolean flowControl;
|
|
||||||
private final boolean sessionFlowControl;
|
private final boolean sessionFlowControl;
|
||||||
|
|
||||||
private SpdyVersion(int version, boolean flowControl, boolean sessionFlowControl) {
|
private SpdyVersion(int version, boolean sessionFlowControl) {
|
||||||
this.version = version;
|
this.version = version;
|
||||||
this.flowControl = flowControl;
|
|
||||||
this.sessionFlowControl = sessionFlowControl;
|
this.sessionFlowControl = sessionFlowControl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,10 +31,6 @@ public enum SpdyVersion {
|
|||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean useFlowControl() {
|
|
||||||
return flowControl;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean useSessionFlowControl() {
|
boolean useSessionFlowControl() {
|
||||||
return sessionFlowControl;
|
return sessionFlowControl;
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,6 @@ public class SpdyFrameDecoderTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTooLargeHeaderNameOnSynStreamRequest() throws Exception {
|
public void testTooLargeHeaderNameOnSynStreamRequest() throws Exception {
|
||||||
testTooLargeHeaderNameOnSynStreamRequest(SpdyVersion.SPDY_2);
|
|
||||||
testTooLargeHeaderNameOnSynStreamRequest(SpdyVersion.SPDY_3);
|
testTooLargeHeaderNameOnSynStreamRequest(SpdyVersion.SPDY_3);
|
||||||
testTooLargeHeaderNameOnSynStreamRequest(SpdyVersion.SPDY_3_1);
|
testTooLargeHeaderNameOnSynStreamRequest(SpdyVersion.SPDY_3_1);
|
||||||
}
|
}
|
||||||
|
@ -282,8 +282,6 @@ public class SpdySessionHandlerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSpdyClientSessionHandler() {
|
public void testSpdyClientSessionHandler() {
|
||||||
logger.info("Running: testSpdyClientSessionHandler v2");
|
|
||||||
testSpdySessionHandler(SpdyVersion.SPDY_2, false);
|
|
||||||
logger.info("Running: testSpdyClientSessionHandler v3");
|
logger.info("Running: testSpdyClientSessionHandler v3");
|
||||||
testSpdySessionHandler(SpdyVersion.SPDY_3, false);
|
testSpdySessionHandler(SpdyVersion.SPDY_3, false);
|
||||||
logger.info("Running: testSpdyClientSessionHandler v3.1");
|
logger.info("Running: testSpdyClientSessionHandler v3.1");
|
||||||
@ -292,8 +290,6 @@ public class SpdySessionHandlerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSpdyClientSessionHandlerPing() {
|
public void testSpdyClientSessionHandlerPing() {
|
||||||
logger.info("Running: testSpdyClientSessionHandlerPing v2");
|
|
||||||
testSpdySessionHandlerPing(SpdyVersion.SPDY_2, false);
|
|
||||||
logger.info("Running: testSpdyClientSessionHandlerPing v3");
|
logger.info("Running: testSpdyClientSessionHandlerPing v3");
|
||||||
testSpdySessionHandlerPing(SpdyVersion.SPDY_3, false);
|
testSpdySessionHandlerPing(SpdyVersion.SPDY_3, false);
|
||||||
logger.info("Running: testSpdyClientSessionHandlerPing v3.1");
|
logger.info("Running: testSpdyClientSessionHandlerPing v3.1");
|
||||||
@ -302,8 +298,6 @@ public class SpdySessionHandlerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSpdyClientSessionHandlerGoAway() {
|
public void testSpdyClientSessionHandlerGoAway() {
|
||||||
logger.info("Running: testSpdyClientSessionHandlerGoAway v2");
|
|
||||||
testSpdySessionHandlerGoAway(SpdyVersion.SPDY_2, false);
|
|
||||||
logger.info("Running: testSpdyClientSessionHandlerGoAway v3");
|
logger.info("Running: testSpdyClientSessionHandlerGoAway v3");
|
||||||
testSpdySessionHandlerGoAway(SpdyVersion.SPDY_3, false);
|
testSpdySessionHandlerGoAway(SpdyVersion.SPDY_3, false);
|
||||||
logger.info("Running: testSpdyClientSessionHandlerGoAway v3.1");
|
logger.info("Running: testSpdyClientSessionHandlerGoAway v3.1");
|
||||||
@ -312,8 +306,6 @@ public class SpdySessionHandlerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSpdyServerSessionHandler() {
|
public void testSpdyServerSessionHandler() {
|
||||||
logger.info("Running: testSpdyServerSessionHandler v2");
|
|
||||||
testSpdySessionHandler(SpdyVersion.SPDY_2, true);
|
|
||||||
logger.info("Running: testSpdyServerSessionHandler v3");
|
logger.info("Running: testSpdyServerSessionHandler v3");
|
||||||
testSpdySessionHandler(SpdyVersion.SPDY_3, true);
|
testSpdySessionHandler(SpdyVersion.SPDY_3, true);
|
||||||
logger.info("Running: testSpdyServerSessionHandler v3.1");
|
logger.info("Running: testSpdyServerSessionHandler v3.1");
|
||||||
@ -322,8 +314,6 @@ public class SpdySessionHandlerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSpdyServerSessionHandlerPing() {
|
public void testSpdyServerSessionHandlerPing() {
|
||||||
logger.info("Running: testSpdyServerSessionHandlerPing v2");
|
|
||||||
testSpdySessionHandlerPing(SpdyVersion.SPDY_2, true);
|
|
||||||
logger.info("Running: testSpdyServerSessionHandlerPing v3");
|
logger.info("Running: testSpdyServerSessionHandlerPing v3");
|
||||||
testSpdySessionHandlerPing(SpdyVersion.SPDY_3, true);
|
testSpdySessionHandlerPing(SpdyVersion.SPDY_3, true);
|
||||||
logger.info("Running: testSpdyServerSessionHandlerPing v3.1");
|
logger.info("Running: testSpdyServerSessionHandlerPing v3.1");
|
||||||
@ -332,8 +322,6 @@ public class SpdySessionHandlerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSpdyServerSessionHandlerGoAway() {
|
public void testSpdyServerSessionHandlerGoAway() {
|
||||||
logger.info("Running: testSpdyServerSessionHandlerGoAway v2");
|
|
||||||
testSpdySessionHandlerGoAway(SpdyVersion.SPDY_2, true);
|
|
||||||
logger.info("Running: testSpdyServerSessionHandlerGoAway v3");
|
logger.info("Running: testSpdyServerSessionHandlerGoAway v3");
|
||||||
testSpdySessionHandlerGoAway(SpdyVersion.SPDY_3, true);
|
testSpdySessionHandlerGoAway(SpdyVersion.SPDY_3, true);
|
||||||
logger.info("Running: testSpdyServerSessionHandlerGoAway v3.1");
|
logger.info("Running: testSpdyServerSessionHandlerGoAway v3.1");
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012 The Netty Project
|
* Copyright 2013 The Netty Project
|
||||||
*
|
*
|
||||||
* The Netty Project licenses this file to you under the Apache License,
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
* version 2.0 (the "License"); you may not use this file except in compliance
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
@ -44,8 +44,7 @@ public class SocketSpdyEchoTest extends AbstractSocketTest {
|
|||||||
static final int ignoredBytes = 20;
|
static final int ignoredBytes = 20;
|
||||||
|
|
||||||
private static ByteBuf createFrames(int version) {
|
private static ByteBuf createFrames(int version) {
|
||||||
int length = version < 3 ? 1176 : 1174;
|
ByteBuf frames = Unpooled.buffer(1174);
|
||||||
ByteBuf frames = Unpooled.buffer(length);
|
|
||||||
|
|
||||||
// SPDY UNKNOWN Frame
|
// SPDY UNKNOWN Frame
|
||||||
frames.writeByte(0x80);
|
frames.writeByte(0x80);
|
||||||
@ -74,11 +73,7 @@ public class SocketSpdyEchoTest extends AbstractSocketTest {
|
|||||||
frames.writeByte(version);
|
frames.writeByte(version);
|
||||||
frames.writeShort(1);
|
frames.writeShort(1);
|
||||||
frames.writeByte(0x03);
|
frames.writeByte(0x03);
|
||||||
if (version < 3) {
|
frames.writeMedium(10);
|
||||||
frames.writeMedium(12);
|
|
||||||
} else {
|
|
||||||
frames.writeMedium(10);
|
|
||||||
}
|
|
||||||
frames.writeInt(random.nextInt() & 0x7FFFFFFF | 0x01);
|
frames.writeInt(random.nextInt() & 0x7FFFFFFF | 0x01);
|
||||||
frames.writeInt(random.nextInt() & 0x7FFFFFFF);
|
frames.writeInt(random.nextInt() & 0x7FFFFFFF);
|
||||||
frames.writeShort(0x8000);
|
frames.writeShort(0x8000);
|
||||||
@ -91,11 +86,7 @@ public class SocketSpdyEchoTest extends AbstractSocketTest {
|
|||||||
frames.writeByte(version);
|
frames.writeByte(version);
|
||||||
frames.writeShort(2);
|
frames.writeShort(2);
|
||||||
frames.writeByte(0x01);
|
frames.writeByte(0x01);
|
||||||
if (version < 3) {
|
frames.writeMedium(4);
|
||||||
frames.writeMedium(8);
|
|
||||||
} else {
|
|
||||||
frames.writeMedium(4);
|
|
||||||
}
|
|
||||||
frames.writeInt(random.nextInt() & 0x7FFFFFFF | 0x01);
|
frames.writeInt(random.nextInt() & 0x7FFFFFFF | 0x01);
|
||||||
if (version < 3) {
|
if (version < 3) {
|
||||||
frames.writeInt(0);
|
frames.writeInt(0);
|
||||||
@ -116,13 +107,8 @@ public class SocketSpdyEchoTest extends AbstractSocketTest {
|
|||||||
frames.writeByte(0x01);
|
frames.writeByte(0x01);
|
||||||
frames.writeMedium(12);
|
frames.writeMedium(12);
|
||||||
frames.writeInt(1);
|
frames.writeInt(1);
|
||||||
if (version < 3) {
|
frames.writeByte(0x03);
|
||||||
frames.writeMedium(random.nextInt());
|
frames.writeMedium(random.nextInt());
|
||||||
frames.writeByte(0x03);
|
|
||||||
} else {
|
|
||||||
frames.writeByte(0x03);
|
|
||||||
frames.writeMedium(random.nextInt());
|
|
||||||
}
|
|
||||||
frames.writeInt(random.nextInt());
|
frames.writeInt(random.nextInt());
|
||||||
|
|
||||||
// SPDY PING Frame
|
// SPDY PING Frame
|
||||||
@ -136,15 +122,9 @@ public class SocketSpdyEchoTest extends AbstractSocketTest {
|
|||||||
frames.writeByte(0x80);
|
frames.writeByte(0x80);
|
||||||
frames.writeByte(version);
|
frames.writeByte(version);
|
||||||
frames.writeShort(7);
|
frames.writeShort(7);
|
||||||
if (version < 3) {
|
frames.writeInt(8);
|
||||||
frames.writeInt(4);
|
|
||||||
} else {
|
|
||||||
frames.writeInt(8);
|
|
||||||
}
|
|
||||||
frames.writeInt(random.nextInt() & 0x7FFFFFFF);
|
frames.writeInt(random.nextInt() & 0x7FFFFFFF);
|
||||||
if (version >= 3) {
|
frames.writeInt(random.nextInt() | 0x01);
|
||||||
frames.writeInt(random.nextInt() | 0x01);
|
|
||||||
}
|
|
||||||
|
|
||||||
// SPDY HEADERS Frame
|
// SPDY HEADERS Frame
|
||||||
frames.writeByte(0x80);
|
frames.writeByte(0x80);
|
||||||
@ -169,10 +149,6 @@ public class SocketSpdyEchoTest extends AbstractSocketTest {
|
|||||||
|
|
||||||
@Test(timeout = 15000)
|
@Test(timeout = 15000)
|
||||||
public void testSpdyEcho() throws Throwable {
|
public void testSpdyEcho() throws Throwable {
|
||||||
version = SpdyVersion.SPDY_2;
|
|
||||||
logger.info("Testing against SPDY v2");
|
|
||||||
run();
|
|
||||||
|
|
||||||
version = SpdyVersion.SPDY_3;
|
version = SpdyVersion.SPDY_3;
|
||||||
logger.info("Testing against SPDY v3");
|
logger.info("Testing against SPDY v3");
|
||||||
run();
|
run();
|
||||||
@ -186,9 +162,6 @@ public class SocketSpdyEchoTest extends AbstractSocketTest {
|
|||||||
|
|
||||||
ByteBuf frames;
|
ByteBuf frames;
|
||||||
switch (version) {
|
switch (version) {
|
||||||
case SPDY_2:
|
|
||||||
frames = createFrames(2);
|
|
||||||
break;
|
|
||||||
case SPDY_3:
|
case SPDY_3:
|
||||||
case SPDY_3_1:
|
case SPDY_3_1:
|
||||||
frames = createFrames(3);
|
frames = createFrames(3);
|
||||||
|
Loading…
Reference in New Issue
Block a user