From 949a6968ee6d6b68965d6c510cec9c788469ea40 Mon Sep 17 00:00:00 2001 From: Jeff Pinner Date: Mon, 14 Oct 2013 07:27:50 -0700 Subject: [PATCH] SPDY: remove SPDY/2 support --- .../handler/codec/spdy/SpdyFrameDecoder.java | 93 ++------ .../handler/codec/spdy/SpdyFrameEncoder.java | 71 +----- .../handler/codec/spdy/SpdyOrHttpChooser.java | 8 +- .../codec/spdy/SpdySessionHandler.java | 216 +++++++++--------- .../netty/handler/codec/spdy/SpdyVersion.java | 24 +- .../codec/spdy/SpdyFrameDecoderTest.java | 1 - .../codec/spdy/SpdySessionHandlerTest.java | 12 - .../transport/socket/SocketSpdyEchoTest.java | 43 +--- 8 files changed, 139 insertions(+), 329 deletions(-) diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyFrameDecoder.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyFrameDecoder.java index afb90aafea..5c1ca54150 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyFrameDecoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyFrameDecoder.java @@ -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 @@ -186,23 +186,10 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder { 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) { @@ -427,20 +414,13 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder { 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); @@ -461,12 +441,10 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder { } 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; } @@ -474,18 +452,9 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder { 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); @@ -494,8 +463,7 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder { return spdySynStreamFrame; case SPDY_SYN_REPLY_FRAME: - minLength = version < 3 ? 8 : 4; - if (buffer.readableBytes() < minLength) { + if (buffer.readableBytes() < 4) { return null; } @@ -503,18 +471,6 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder { 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); @@ -525,27 +481,10 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder { 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); @@ -562,10 +501,10 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder { 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; @@ -577,14 +516,10 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder { 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; diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyFrameEncoder.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyFrameEncoder.java index f397f81c54..e4d239d78d 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyFrameEncoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyFrameEncoder.java @@ -92,12 +92,7 @@ public class SpdyFrameEncoder extends MessageToByteEncoder { 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); @@ -105,19 +100,7 @@ public class SpdyFrameEncoder extends MessageToByteEncoder { 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(); @@ -130,25 +113,13 @@ public class SpdyFrameEncoder extends MessageToByteEncoder { 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(); @@ -178,8 +149,7 @@ public class SpdyFrameEncoder extends MessageToByteEncoder { 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; @@ -187,18 +157,8 @@ public class SpdyFrameEncoder extends MessageToByteEncoder { 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)); } @@ -214,15 +174,12 @@ public class SpdyFrameEncoder extends MessageToByteEncoder { } 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) { @@ -231,21 +188,13 @@ public class SpdyFrameEncoder extends MessageToByteEncoder { 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(); diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyOrHttpChooser.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyOrHttpChooser.java index d80ce89c1b..717182b5e9 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyOrHttpChooser.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyOrHttpChooser.java @@ -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, @@ -84,9 +83,6 @@ public abstract class SpdyOrHttpChooser extends ByteToMessageDecoder { 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; @@ -137,8 +133,8 @@ public abstract class SpdyOrHttpChooser extends ByteToMessageDecoder { /** * 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. diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdySessionHandler.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdySessionHandler.java index 53c248a852..6a62ab7fb5 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdySessionHandler.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdySessionHandler.java @@ -61,7 +61,6 @@ public class SpdySessionHandler private ChannelFutureListener closeSessionFutureListener; private final boolean server; - private final boolean flowControl; private final boolean sessionFlowControl; /** @@ -78,7 +77,6 @@ public class SpdySessionHandler throw new NullPointerException("version"); } this.server = server; - flowControl = version.useFlowControl(); 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. */ - if (flowControl) { - // Update receive window size - int deltaWindowSize = -1 * spdyDataFrame.content().readableBytes(); - int newWindowSize = spdySession.updateReceiveWindowSize(streamId, deltaWindowSize); + // Update receive window size + int deltaWindowSize = -1 * spdyDataFrame.content().readableBytes(); + int newWindowSize = spdySession.updateReceiveWindowSize(streamId, deltaWindowSize); - // 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. - // 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 - // and is cleared once we send a WINDOW_UPDATE frame. - if (newWindowSize < spdySession.getReceiveWindowSizeLowerBound(streamId)) { - spdyDataFrame.release(); - issueStreamError(ctx, streamId, SpdyStreamStatus.FLOW_CONTROL_ERROR); - return; - } + // 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. + // 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 + // and is cleared once we send a WINDOW_UPDATE frame. + if (newWindowSize < spdySession.getReceiveWindowSizeLowerBound(streamId)) { + spdyDataFrame.release(); + issueStreamError(ctx, streamId, SpdyStreamStatus.FLOW_CONTROL_ERROR); + return; + } - // Window size became negative due to sender writing frame before receiving SETTINGS - // Send data frames upstream in initialReceiveWindowSize chunks - if (newWindowSize < 0) { - while (spdyDataFrame.content().readableBytes() > initialReceiveWindowSize) { - SpdyDataFrame partialDataFrame = new DefaultSpdyDataFrame(streamId, - spdyDataFrame.content().readSlice(initialReceiveWindowSize).retain()); - ctx.writeAndFlush(partialDataFrame); - } + // Window size became negative due to sender writing frame before receiving SETTINGS + // Send data frames upstream in initialReceiveWindowSize chunks + if (newWindowSize < 0) { + while (spdyDataFrame.content().readableBytes() > initialReceiveWindowSize) { + SpdyDataFrame partialDataFrame = new DefaultSpdyDataFrame(streamId, + spdyDataFrame.content().readSlice(initialReceiveWindowSize).retain()); + ctx.writeAndFlush(partialDataFrame); } + } - // Send a WINDOW_UPDATE frame if less than half the stream window size remains - if (newWindowSize <= initialReceiveWindowSize / 2 && !spdyDataFrame.isLast()) { - deltaWindowSize = initialReceiveWindowSize - newWindowSize; - spdySession.updateReceiveWindowSize(streamId, deltaWindowSize); - SpdyWindowUpdateFrame spdyWindowUpdateFrame = - new DefaultSpdyWindowUpdateFrame(streamId, deltaWindowSize); - ctx.writeAndFlush(spdyWindowUpdateFrame); - } + // Send a WINDOW_UPDATE frame if less than half the stream window size remains + if (newWindowSize <= initialReceiveWindowSize / 2 && !spdyDataFrame.isLast()) { + deltaWindowSize = initialReceiveWindowSize - newWindowSize; + spdySession.updateReceiveWindowSize(streamId, deltaWindowSize); + SpdyWindowUpdateFrame spdyWindowUpdateFrame = + new DefaultSpdyWindowUpdateFrame(streamId, deltaWindowSize); + ctx.writeAndFlush(spdyWindowUpdateFrame); } // 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); - if (flowControl) { - int newInitialWindowSize = - spdySettingsFrame.getValue(SpdySettingsFrame.SETTINGS_INITIAL_WINDOW_SIZE); - if (newInitialWindowSize >= 0) { - updateInitialSendWindowSize(newInitialWindowSize); - } + int newInitialWindowSize = + spdySettingsFrame.getValue(SpdySettingsFrame.SETTINGS_INITIAL_WINDOW_SIZE); + if (newInitialWindowSize >= 0) { + updateInitialSendWindowSize(newInitialWindowSize); } } else if (msg instanceof SpdyPingFrame) { @@ -382,28 +376,26 @@ public class SpdySessionHandler * after sending the last frame for the stream. */ - if (flowControl) { - SpdyWindowUpdateFrame spdyWindowUpdateFrame = (SpdyWindowUpdateFrame) msg; - int streamId = spdyWindowUpdateFrame.getStreamId(); - int deltaWindowSize = spdyWindowUpdateFrame.getDeltaWindowSize(); + SpdyWindowUpdateFrame spdyWindowUpdateFrame = (SpdyWindowUpdateFrame) msg; + int streamId = spdyWindowUpdateFrame.getStreamId(); + int deltaWindowSize = spdyWindowUpdateFrame.getDeltaWindowSize(); - // Ignore frames for half-closed streams - if (streamId != SPDY_SESSION_STREAM_ID && spdySession.isLocalSideClosed(streamId)) { - 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); + // Ignore frames for half-closed streams + if (streamId != SPDY_SESSION_STREAM_ID && spdySession.isLocalSideClosed(streamId)) { + 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); } ctx.fireChannelRead(msg); @@ -475,65 +467,63 @@ public class SpdySessionHandler * sender must pause transmitting data frames. */ - if (flowControl) { - synchronized (flowControlLock) { - int dataLength = spdyDataFrame.content().readableBytes(); - int sendWindowSize = spdySession.getSendWindowSize(streamId); + synchronized (flowControlLock) { + int dataLength = spdyDataFrame.content().readableBytes(); + 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) { - int sessionSendWindowSize = spdySession.getSendWindowSize(SPDY_SESSION_STREAM_ID); - sendWindowSize = Math.min(sendWindowSize, sessionSendWindowSize); + spdySession.updateSendWindowSize(SPDY_SESSION_STREAM_ID, -1 * sendWindowSize); } - 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) { - spdySession.updateSendWindowSize(SPDY_SESSION_STREAM_ID, -1 * sendWindowSize); - } + // Create a partial data frame whose length is the current window size + SpdyDataFrame partialDataFrame = new DefaultSpdyDataFrame(streamId, + spdyDataFrame.content().readSlice(sendWindowSize).retain()); - // Create a partial data frame whose length is the current window size - SpdyDataFrame partialDataFrame = new DefaultSpdyDataFrame(streamId, - spdyDataFrame.content().readSlice(sendWindowSize).retain()); + // Enqueue the remaining data (will be the first frame queued) + spdySession.putPendingWrite(streamId, new SpdySession.PendingWrite(spdyDataFrame, promise)); - // Enqueue the remaining data (will be the first frame queued) - spdySession.putPendingWrite(streamId, new SpdySession.PendingWrite(spdyDataFrame, promise)); - - // 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; - ctx.write(partialDataFrame).addListener(new ChannelFutureListener() { - @Override - public void operationComplete(ChannelFuture future) throws Exception { - 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; + ctx.write(partialDataFrame).addListener(new ChannelFutureListener() { + @Override + 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. - // 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); - } - } - }); + }); + 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. + // 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); - if (flowControl) { - int newInitialWindowSize = - spdySettingsFrame.getValue(SpdySettingsFrame.SETTINGS_INITIAL_WINDOW_SIZE); - if (newInitialWindowSize >= 0) { - updateInitialReceiveWindowSize(newInitialWindowSize); - } + int newInitialWindowSize = + spdySettingsFrame.getValue(SpdySettingsFrame.SETTINGS_INITIAL_WINDOW_SIZE); + if (newInitialWindowSize >= 0) { + updateInitialReceiveWindowSize(newInitialWindowSize); } } else if (msg instanceof SpdyPingFrame) { diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyVersion.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyVersion.java index 84d66028ca..0e4c4fbe28 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyVersion.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyVersion.java @@ -16,28 +16,14 @@ package io.netty.handler.codec.spdy; public enum SpdyVersion { - SPDY_2 (2, false, false), - SPDY_3 (3, true, false), - 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); - } + SPDY_3 (3, false), + SPDY_3_1 (3, true); private final int version; - private final boolean flowControl; private final boolean sessionFlowControl; - private SpdyVersion(int version, boolean flowControl, boolean sessionFlowControl) { + private SpdyVersion(int version, boolean sessionFlowControl) { this.version = version; - this.flowControl = flowControl; this.sessionFlowControl = sessionFlowControl; } @@ -45,10 +31,6 @@ public enum SpdyVersion { return version; } - boolean useFlowControl() { - return flowControl; - } - boolean useSessionFlowControl() { return sessionFlowControl; } diff --git a/codec-http/src/test/java/io/netty/handler/codec/spdy/SpdyFrameDecoderTest.java b/codec-http/src/test/java/io/netty/handler/codec/spdy/SpdyFrameDecoderTest.java index 1e3cc3fdc1..7c25570260 100644 --- a/codec-http/src/test/java/io/netty/handler/codec/spdy/SpdyFrameDecoderTest.java +++ b/codec-http/src/test/java/io/netty/handler/codec/spdy/SpdyFrameDecoderTest.java @@ -47,7 +47,6 @@ public class SpdyFrameDecoderTest { @Test public void testTooLargeHeaderNameOnSynStreamRequest() throws Exception { - testTooLargeHeaderNameOnSynStreamRequest(SpdyVersion.SPDY_2); testTooLargeHeaderNameOnSynStreamRequest(SpdyVersion.SPDY_3); testTooLargeHeaderNameOnSynStreamRequest(SpdyVersion.SPDY_3_1); } diff --git a/codec-http/src/test/java/io/netty/handler/codec/spdy/SpdySessionHandlerTest.java b/codec-http/src/test/java/io/netty/handler/codec/spdy/SpdySessionHandlerTest.java index 4039b1bfa9..55346cbc32 100644 --- a/codec-http/src/test/java/io/netty/handler/codec/spdy/SpdySessionHandlerTest.java +++ b/codec-http/src/test/java/io/netty/handler/codec/spdy/SpdySessionHandlerTest.java @@ -282,8 +282,6 @@ public class SpdySessionHandlerTest { @Test public void testSpdyClientSessionHandler() { - logger.info("Running: testSpdyClientSessionHandler v2"); - testSpdySessionHandler(SpdyVersion.SPDY_2, false); logger.info("Running: testSpdyClientSessionHandler v3"); testSpdySessionHandler(SpdyVersion.SPDY_3, false); logger.info("Running: testSpdyClientSessionHandler v3.1"); @@ -292,8 +290,6 @@ public class SpdySessionHandlerTest { @Test public void testSpdyClientSessionHandlerPing() { - logger.info("Running: testSpdyClientSessionHandlerPing v2"); - testSpdySessionHandlerPing(SpdyVersion.SPDY_2, false); logger.info("Running: testSpdyClientSessionHandlerPing v3"); testSpdySessionHandlerPing(SpdyVersion.SPDY_3, false); logger.info("Running: testSpdyClientSessionHandlerPing v3.1"); @@ -302,8 +298,6 @@ public class SpdySessionHandlerTest { @Test public void testSpdyClientSessionHandlerGoAway() { - logger.info("Running: testSpdyClientSessionHandlerGoAway v2"); - testSpdySessionHandlerGoAway(SpdyVersion.SPDY_2, false); logger.info("Running: testSpdyClientSessionHandlerGoAway v3"); testSpdySessionHandlerGoAway(SpdyVersion.SPDY_3, false); logger.info("Running: testSpdyClientSessionHandlerGoAway v3.1"); @@ -312,8 +306,6 @@ public class SpdySessionHandlerTest { @Test public void testSpdyServerSessionHandler() { - logger.info("Running: testSpdyServerSessionHandler v2"); - testSpdySessionHandler(SpdyVersion.SPDY_2, true); logger.info("Running: testSpdyServerSessionHandler v3"); testSpdySessionHandler(SpdyVersion.SPDY_3, true); logger.info("Running: testSpdyServerSessionHandler v3.1"); @@ -322,8 +314,6 @@ public class SpdySessionHandlerTest { @Test public void testSpdyServerSessionHandlerPing() { - logger.info("Running: testSpdyServerSessionHandlerPing v2"); - testSpdySessionHandlerPing(SpdyVersion.SPDY_2, true); logger.info("Running: testSpdyServerSessionHandlerPing v3"); testSpdySessionHandlerPing(SpdyVersion.SPDY_3, true); logger.info("Running: testSpdyServerSessionHandlerPing v3.1"); @@ -332,8 +322,6 @@ public class SpdySessionHandlerTest { @Test public void testSpdyServerSessionHandlerGoAway() { - logger.info("Running: testSpdyServerSessionHandlerGoAway v2"); - testSpdySessionHandlerGoAway(SpdyVersion.SPDY_2, true); logger.info("Running: testSpdyServerSessionHandlerGoAway v3"); testSpdySessionHandlerGoAway(SpdyVersion.SPDY_3, true); logger.info("Running: testSpdyServerSessionHandlerGoAway v3.1"); diff --git a/testsuite/src/test/java/io/netty/testsuite/transport/socket/SocketSpdyEchoTest.java b/testsuite/src/test/java/io/netty/testsuite/transport/socket/SocketSpdyEchoTest.java index a80d297514..1780ad66e0 100644 --- a/testsuite/src/test/java/io/netty/testsuite/transport/socket/SocketSpdyEchoTest.java +++ b/testsuite/src/test/java/io/netty/testsuite/transport/socket/SocketSpdyEchoTest.java @@ -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 @@ -44,8 +44,7 @@ public class SocketSpdyEchoTest extends AbstractSocketTest { static final int ignoredBytes = 20; private static ByteBuf createFrames(int version) { - int length = version < 3 ? 1176 : 1174; - ByteBuf frames = Unpooled.buffer(length); + ByteBuf frames = Unpooled.buffer(1174); // SPDY UNKNOWN Frame frames.writeByte(0x80); @@ -74,11 +73,7 @@ public class SocketSpdyEchoTest extends AbstractSocketTest { frames.writeByte(version); frames.writeShort(1); frames.writeByte(0x03); - if (version < 3) { - frames.writeMedium(12); - } else { - frames.writeMedium(10); - } + frames.writeMedium(10); frames.writeInt(random.nextInt() & 0x7FFFFFFF | 0x01); frames.writeInt(random.nextInt() & 0x7FFFFFFF); frames.writeShort(0x8000); @@ -91,11 +86,7 @@ public class SocketSpdyEchoTest extends AbstractSocketTest { frames.writeByte(version); frames.writeShort(2); frames.writeByte(0x01); - if (version < 3) { - frames.writeMedium(8); - } else { - frames.writeMedium(4); - } + frames.writeMedium(4); frames.writeInt(random.nextInt() & 0x7FFFFFFF | 0x01); if (version < 3) { frames.writeInt(0); @@ -116,13 +107,8 @@ public class SocketSpdyEchoTest extends AbstractSocketTest { frames.writeByte(0x01); frames.writeMedium(12); frames.writeInt(1); - if (version < 3) { - frames.writeMedium(random.nextInt()); - frames.writeByte(0x03); - } else { - frames.writeByte(0x03); - frames.writeMedium(random.nextInt()); - } + frames.writeByte(0x03); + frames.writeMedium(random.nextInt()); frames.writeInt(random.nextInt()); // SPDY PING Frame @@ -136,15 +122,9 @@ public class SocketSpdyEchoTest extends AbstractSocketTest { frames.writeByte(0x80); frames.writeByte(version); frames.writeShort(7); - if (version < 3) { - frames.writeInt(4); - } else { - frames.writeInt(8); - } + frames.writeInt(8); frames.writeInt(random.nextInt() & 0x7FFFFFFF); - if (version >= 3) { - frames.writeInt(random.nextInt() | 0x01); - } + frames.writeInt(random.nextInt() | 0x01); // SPDY HEADERS Frame frames.writeByte(0x80); @@ -169,10 +149,6 @@ public class SocketSpdyEchoTest extends AbstractSocketTest { @Test(timeout = 15000) public void testSpdyEcho() throws Throwable { - version = SpdyVersion.SPDY_2; - logger.info("Testing against SPDY v2"); - run(); - version = SpdyVersion.SPDY_3; logger.info("Testing against SPDY v3"); run(); @@ -186,9 +162,6 @@ public class SocketSpdyEchoTest extends AbstractSocketTest { ByteBuf frames; switch (version) { - case SPDY_2: - frames = createFrames(2); - break; case SPDY_3: case SPDY_3_1: frames = createFrames(3);