Skip to content

Commit

Permalink
Merge pull request netty#1921 from jpinner/kill_spdy_2
Browse files Browse the repository at this point in the history
SPDY: remove SPDY/2 support
  • Loading branch information
Bill Gallagher committed Oct 15, 2013
2 parents 1f1a627 + 949a696 commit ef13930
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 328 deletions.
Original file line number Diff line number Diff line change
@@ -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,
* version 2.0 (the "License"); you may not use this file except in compliance
Expand Down Expand Up @@ -186,23 +186,10 @@ protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> ou

int readableEntries = Math.min(buffer.readableBytes() >> 3, length >> 3);
for (int i = 0; i < readableEntries; i ++) {
int ID;
byte ID_flags;
if (version < 3) {
// Chromium Issue 79156
// 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);
byte ID_flags = buffer.getByte(buffer.readerIndex());
int ID = getUnsignedMedium(buffer, buffer.readerIndex() + 1);
int value = getSignedInt(buffer, buffer.readerIndex() + 4);
buffer.skipBytes(8);

// Check for invalid ID -- avoid IllegalArgumentException in setValue
if (ID == 0) {
Expand Down Expand Up @@ -427,20 +414,13 @@ private Object readControlFrame(ByteBuf buffer) {
return new DefaultSpdyPingFrame(ID);

case SPDY_GOAWAY_FRAME:
int minLength = version < 3 ? 4 : 8;
if (buffer.readableBytes() < minLength) {
if (buffer.readableBytes() < 8) {
return null;
}

int lastGoodStreamId = getUnsignedInt(buffer, buffer.readerIndex());
buffer.skipBytes(4);

if (version < 3) {
return new DefaultSpdyGoAwayFrame(lastGoodStreamId);
}

statusCode = getSignedInt(buffer, buffer.readerIndex());
buffer.skipBytes(4);
statusCode = getSignedInt(buffer, buffer.readerIndex() + 4);
buffer.skipBytes(8);

return new DefaultSpdyGoAwayFrame(lastGoodStreamId, statusCode);

Expand All @@ -461,31 +441,20 @@ private Object readControlFrame(ByteBuf buffer) {
}

private SpdyHeadersFrame readHeaderBlockFrame(ByteBuf buffer) {
int minLength;
int streamId;
switch (type) {
case SPDY_SYN_STREAM_FRAME:
minLength = version < 3 ? 12 : 10;
if (buffer.readableBytes() < minLength) {
if (buffer.readableBytes() < 10) {
return null;
}

int offset = buffer.readerIndex();
streamId = getUnsignedInt(buffer, offset);
int associatedToStreamId = getUnsignedInt(buffer, offset + 4);
byte priority = (byte) (buffer.getByte(offset + 8) >> 5 & 0x07);
if (version < 3) {
priority >>= 1;
}
buffer.skipBytes(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 =
new DefaultSpdySynStreamFrame(streamId, associatedToStreamId, priority);
spdySynStreamFrame.setLast((flags & SPDY_FLAG_FIN) != 0);
Expand All @@ -494,27 +463,14 @@ private SpdyHeadersFrame readHeaderBlockFrame(ByteBuf buffer) {
return spdySynStreamFrame;

case SPDY_SYN_REPLY_FRAME:
minLength = version < 3 ? 8 : 4;
if (buffer.readableBytes() < minLength) {
if (buffer.readableBytes() < 4) {
return null;
}

streamId = getUnsignedInt(buffer, buffer.readerIndex());
buffer.skipBytes(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.setLast((flags & SPDY_FLAG_FIN) != 0);

Expand All @@ -525,27 +481,10 @@ private SpdyHeadersFrame readHeaderBlockFrame(ByteBuf buffer) {
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());
buffer.skipBytes(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.setLast((flags & SPDY_FLAG_FIN) != 0);

Expand All @@ -562,10 +501,10 @@ private boolean isValidFrameHeader() {
return streamId != 0;

case SPDY_SYN_STREAM_FRAME:
return version < 3 ? length >= 12 : length >= 10;
return length >= 10;

case SPDY_SYN_REPLY_FRAME:
return version < 3 ? length >= 8 : length >= 4;
return length >= 4;

case SPDY_RST_STREAM_FRAME:
return flags == 0 && length == 8;
Expand All @@ -577,14 +516,10 @@ private boolean isValidFrameHeader() {
return length == 4;

case SPDY_GOAWAY_FRAME:
return version < 3 ? length == 4 : length == 8;
return length == 8;

case SPDY_HEADERS_FRAME:
if (version < 3) {
return length == 4 || length >= 8;
} else {
return length >= 4;
}
return length >= 4;

case SPDY_WINDOW_UPDATE_FRAME:
return length == 8;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,32 +92,15 @@ protected void encode(ChannelHandlerContext ctx, SpdyFrame msg, ByteBuf out) thr
flags |= SPDY_FLAG_UNIDIRECTIONAL;
}
int headerBlockLength = data.readableBytes();
int length;
if (version < 3) {
length = headerBlockLength == 0 ? 12 : 10 + headerBlockLength;
} else {
length = 10 + headerBlockLength;
}
int length = 10 + headerBlockLength;
out.ensureWritable(SPDY_HEADER_SIZE + length);
out.writeShort(version | 0x8000);
out.writeShort(SPDY_SYN_STREAM_FRAME);
out.writeByte(flags);
out.writeMedium(length);
out.writeInt(spdySynStreamFrame.getStreamId());
out.writeInt(spdySynStreamFrame.getAssociatedToStreamId());
if (version < 3) {
// 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.writeShort((spdySynStreamFrame.getPriority() & 0xFF) << 13);
out.writeBytes(data, data.readerIndex(), headerBlockLength);
} finally {
data.release();
Expand All @@ -130,25 +113,13 @@ protected void encode(ChannelHandlerContext ctx, SpdyFrame msg, ByteBuf out) thr
try {
byte flags = spdySynReplyFrame.isLast() ? SPDY_FLAG_FIN : 0;
int headerBlockLength = data.readableBytes();
int length;
if (version < 3) {
length = headerBlockLength == 0 ? 8 : 6 + headerBlockLength;
} else {
length = 4 + headerBlockLength;
}
int length = 4 + headerBlockLength;
out.ensureWritable(SPDY_HEADER_SIZE + length);
out.writeShort(version | 0x8000);
out.writeShort(SPDY_SYN_REPLY_FRAME);
out.writeByte(flags);
out.writeMedium(length);
out.writeInt(spdySynReplyFrame.getStreamId());
if (version < 3) {
if (headerBlockLength == 0) {
out.writeInt(0);
} else {
out.writeShort(0);
}
}
out.writeBytes(data, data.readerIndex(), headerBlockLength);
} finally {
data.release();
Expand Down Expand Up @@ -178,27 +149,16 @@ protected void encode(ChannelHandlerContext ctx, SpdyFrame msg, ByteBuf out) thr
out.writeByte(flags);
out.writeMedium(length);
out.writeInt(numEntries);
for (Integer ID: IDs) {
int id = ID.intValue();
for (Integer id: IDs) {
byte ID_flags = 0;
if (spdySettingsFrame.isPersistValue(id)) {
ID_flags |= SPDY_SETTINGS_PERSIST_VALUE;
}
if (spdySettingsFrame.isPersisted(id)) {
ID_flags |= SPDY_SETTINGS_PERSISTED;
}
if (version < 3) {
// Chromium Issue 79156
// 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.writeByte(ID_flags);
out.writeMedium(id);
out.writeInt(spdySettingsFrame.getValue(id));
}

Expand All @@ -214,15 +174,12 @@ protected void encode(ChannelHandlerContext ctx, SpdyFrame msg, ByteBuf out) thr
} else if (msg instanceof SpdyGoAwayFrame) {

SpdyGoAwayFrame spdyGoAwayFrame = (SpdyGoAwayFrame) msg;
int length = version < 3 ? 4 : 8;
out.ensureWritable(SPDY_HEADER_SIZE + length);
out.ensureWritable(SPDY_HEADER_SIZE + 8);
out.writeShort(version | 0x8000);
out.writeShort(SPDY_GOAWAY_FRAME);
out.writeInt(length);
out.writeInt(8);
out.writeInt(spdyGoAwayFrame.getLastGoodStreamId());
if (version >= 3) {
out.writeInt(spdyGoAwayFrame.getStatus().getCode());
}
out.writeInt(spdyGoAwayFrame.getStatus().getCode());

} else if (msg instanceof SpdyHeadersFrame) {

Expand All @@ -231,21 +188,13 @@ protected void encode(ChannelHandlerContext ctx, SpdyFrame msg, ByteBuf out) thr
try {
byte flags = spdyHeadersFrame.isLast() ? SPDY_FLAG_FIN : 0;
int headerBlockLength = data.readableBytes();
int length;
if (version < 3) {
length = headerBlockLength == 0 ? 4 : 6 + headerBlockLength;
} else {
length = 4 + headerBlockLength;
}
int length = 4 + headerBlockLength;
out.ensureWritable(SPDY_HEADER_SIZE + length);
out.writeShort(version | 0x8000);
out.writeShort(SPDY_HEADERS_FRAME);
out.writeByte(flags);
out.writeMedium(length);
out.writeInt(spdyHeadersFrame.getStreamId());
if (version < 3 && headerBlockLength != 0) {
out.writeShort(0);
}
out.writeBytes(data, data.readerIndex(), headerBlockLength);
} finally {
data.release();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ public abstract class SpdyOrHttpChooser extends ByteToMessageDecoder {
// TODO: Replace with generic NPN handler

public enum SelectedProtocol {
SPDY_2,
SPDY_3,
SPDY_3_1,
HTTP_1_1,
Expand Down Expand Up @@ -84,9 +83,6 @@ private boolean initPipeline(ChannelHandlerContext ctx) {
case UNKNOWN:
// Not done with choosing the protocol, so just return here for now,
return false;
case SPDY_2:
addSpdyHandlers(ctx, SpdyVersion.SPDY_2);
break;
case SPDY_3:
addSpdyHandlers(ctx, SpdyVersion.SPDY_3);
break;
Expand Down Expand Up @@ -137,8 +133,8 @@ protected void addHttpHandlers(ChannelHandlerContext ctx) {

/**
* Create the {@link ChannelInboundHandler} that is responsible for handling the http responses
* when the {@link SelectedProtocol} was {@link SelectedProtocol#SPDY_2} or
* {@link SelectedProtocol#SPDY_3}.
* when the {@link SelectedProtocol} was {@link SelectedProtocol#SPDY_3} or
* {@link SelectedProtocol#SPDY_3_1}.
*
* By default this getMethod will just delecate to {@link #createHttpRequestHandlerForHttp()}, but
* sub-classes may override this to change the behaviour.
Expand Down
Loading

0 comments on commit ef13930

Please sign in to comment.