From c8ca3299324a1e2b9ce501c95715cf10ea70c238 Mon Sep 17 00:00:00 2001 From: Jeff Pinner Date: Tue, 4 Jun 2013 14:32:11 -0700 Subject: [PATCH] SPDY: update object hierarchy --- .../codec/spdy/DefaultSpdyDataFrame.java | 67 +++--- .../codec/spdy/DefaultSpdyGoAwayFrame.java | 12 +- .../codec/spdy/DefaultSpdyHeaderBlock.java | 61 ------ .../codec/spdy/DefaultSpdyHeadersFrame.java | 52 ++--- .../codec/spdy/DefaultSpdyNoOpFrame.java | 27 --- .../codec/spdy/DefaultSpdyPingFrame.java | 6 +- .../codec/spdy/DefaultSpdyRstStreamFrame.java | 31 ++- .../codec/spdy/DefaultSpdyStreamFrame.java | 56 +++++ .../codec/spdy/DefaultSpdySynReplyFrame.java | 29 +-- .../codec/spdy/DefaultSpdySynStreamFrame.java | 50 ++--- .../spdy/DefaultSpdyWindowUpdateFrame.java | 10 +- .../handler/codec/spdy/SpdyControlFrame.java | 23 -- .../handler/codec/spdy/SpdyDataFrame.java | 6 +- ...DataOrControlFrame.java => SpdyFrame.java} | 6 +- .../handler/codec/spdy/SpdyFrameCodec.java | 3 +- .../handler/codec/spdy/SpdyFrameDecoder.java | 48 ++--- .../handler/codec/spdy/SpdyFrameEncoder.java | 17 +- .../handler/codec/spdy/SpdyGoAwayFrame.java | 10 +- .../handler/codec/spdy/SpdyHeaderBlock.java | 42 ---- .../netty/handler/codec/spdy/SpdyHeaders.java | 132 ++++++------ .../handler/codec/spdy/SpdyHeadersFrame.java | 26 ++- .../handler/codec/spdy/SpdyHttpCodec.java | 3 +- .../handler/codec/spdy/SpdyHttpDecoder.java | 10 +- .../handler/codec/spdy/SpdyHttpEncoder.java | 2 +- .../handler/codec/spdy/SpdyNoOpFrame.java | 23 -- .../handler/codec/spdy/SpdyPingFrame.java | 6 +- .../codec/spdy/SpdyRstStreamFrame.java | 28 ++- .../codec/spdy/SpdySessionHandler.java | 177 ++++++++-------- .../handler/codec/spdy/SpdySessionStatus.java | 10 +- .../handler/codec/spdy/SpdySettingsFrame.java | 6 +- .../handler/codec/spdy/SpdyStreamFrame.java | 4 +- .../handler/codec/spdy/SpdyStreamStatus.java | 14 +- .../handler/codec/spdy/SpdySynReplyFrame.java | 6 +- .../codec/spdy/SpdySynStreamFrame.java | 6 +- .../codec/spdy/SpdyWindowUpdateFrame.java | 8 +- .../codec/spdy/SpdySessionHandlerTest.java | 196 +++++++++--------- 36 files changed, 531 insertions(+), 682 deletions(-) delete mode 100644 codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdyHeaderBlock.java delete mode 100644 codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdyNoOpFrame.java create mode 100644 codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdyStreamFrame.java delete mode 100644 codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyControlFrame.java rename codec-http/src/main/java/io/netty/handler/codec/spdy/{SpdyDataOrControlFrame.java => SpdyFrame.java} (91%) delete mode 100644 codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHeaderBlock.java delete mode 100644 codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyNoOpFrame.java diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdyDataFrame.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdyDataFrame.java index 3897560f12..cded6488b1 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdyDataFrame.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdyDataFrame.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 @@ -16,17 +16,16 @@ package io.netty.handler.codec.spdy; import io.netty.buffer.ByteBuf; -import io.netty.buffer.DefaultByteBufHolder; +import io.netty.buffer.IllegalBufferAccessException; import io.netty.buffer.Unpooled; import io.netty.util.internal.StringUtil; /** * The default {@link SpdyDataFrame} implementation. */ -public class DefaultSpdyDataFrame extends DefaultByteBufHolder implements SpdyDataFrame { +public class DefaultSpdyDataFrame extends DefaultSpdyStreamFrame implements SpdyDataFrame { - private int streamId; - private boolean last; + private final ByteBuf data; /** * Creates a new instance. @@ -44,8 +43,11 @@ public class DefaultSpdyDataFrame extends DefaultByteBufHolder implements SpdyDa * @param data the payload of the frame. Can not exceed {@link SpdyCodecUtil#SPDY_MAX_LENGTH} */ public DefaultSpdyDataFrame(int streamId, ByteBuf data) { - super(validate(data)); - setStreamId(streamId); + super(streamId); + if (data == null) { + throw new NullPointerException("data"); + } + this.data = validate(data); } private static ByteBuf validate(ByteBuf data) { @@ -56,51 +58,60 @@ public class DefaultSpdyDataFrame extends DefaultByteBufHolder implements SpdyDa return data; } - @Override - public int getStreamId() { - return streamId; - } - @Override public SpdyDataFrame setStreamId(int streamId) { - if (streamId <= 0) { - throw new IllegalArgumentException( - "Stream-ID must be positive: " + streamId); - } - this.streamId = streamId; + super.setStreamId(streamId); return this; } - @Override - public boolean isLast() { - return last; - } - @Override public SpdyDataFrame setLast(boolean last) { - this.last = last; + super.setLast(last); return this; } @Override - public DefaultSpdyDataFrame copy() { - DefaultSpdyDataFrame frame = new DefaultSpdyDataFrame(getStreamId(), content().copy()); + public ByteBuf content() { + if (data.refCnt() <= 0) { + throw new IllegalBufferAccessException(); + } + return data; + } + + @Override + public SpdyDataFrame copy() { + SpdyDataFrame frame = new DefaultSpdyDataFrame(getStreamId(), content().copy()); frame.setLast(isLast()); return frame; } + @Override + public int refCnt() { + return data.refCnt(); + } + @Override public SpdyDataFrame retain() { - super.retain(); + data.retain(); return this; } @Override public SpdyDataFrame retain(int increment) { - super.retain(increment); + data.retain(increment); return this; } + @Override + public boolean release() { + return data.release(); + } + + @Override + public boolean release(int decrement) { + return data.release(decrement); + } + @Override public String toString() { StringBuilder buf = new StringBuilder(); @@ -110,7 +121,7 @@ public class DefaultSpdyDataFrame extends DefaultByteBufHolder implements SpdyDa buf.append(')'); buf.append(StringUtil.NEWLINE); buf.append("--> Stream-ID = "); - buf.append(streamId); + buf.append(getStreamId()); buf.append(StringUtil.NEWLINE); buf.append("--> Size = "); if (refCnt() == 0) { diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdyGoAwayFrame.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdyGoAwayFrame.java index 26c26c261d..6d0d379581 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdyGoAwayFrame.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdyGoAwayFrame.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 @@ -48,19 +48,17 @@ public class DefaultSpdyGoAwayFrame implements SpdyGoAwayFrame { * Creates a new instance. * * @param lastGoodStreamId the Last-good-stream-ID of this frame - * @param status the getStatus of this frame + * @param status the status of this frame */ public DefaultSpdyGoAwayFrame(int lastGoodStreamId, SpdySessionStatus status) { setLastGoodStreamId(lastGoodStreamId); setStatus(status); } - @Override public int getLastGoodStreamId() { return lastGoodStreamId; } - @Override public SpdyGoAwayFrame setLastGoodStreamId(int lastGoodStreamId) { if (lastGoodStreamId < 0) { throw new IllegalArgumentException("Last-good-stream-ID" @@ -70,12 +68,10 @@ public class DefaultSpdyGoAwayFrame implements SpdyGoAwayFrame { return this; } - @Override public SpdySessionStatus getStatus() { return status; } - @Override public SpdyGoAwayFrame setStatus(SpdySessionStatus status) { this.status = status; return this; @@ -87,10 +83,10 @@ public class DefaultSpdyGoAwayFrame implements SpdyGoAwayFrame { buf.append(getClass().getSimpleName()); buf.append(StringUtil.NEWLINE); buf.append("--> Last-good-stream-ID = "); - buf.append(lastGoodStreamId); + buf.append(getLastGoodStreamId()); buf.append(StringUtil.NEWLINE); buf.append("--> Status: "); - buf.append(status.toString()); + buf.append(getStatus().toString()); return buf.toString(); } } diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdyHeaderBlock.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdyHeaderBlock.java deleted file mode 100644 index 2521bc44be..0000000000 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdyHeaderBlock.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2012 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 - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ -package io.netty.handler.codec.spdy; - -import io.netty.util.internal.StringUtil; - -import java.util.Map; - -/** - * The default {@link SpdyHeaderBlock} implementation. - */ -public class DefaultSpdyHeaderBlock implements SpdyHeaderBlock { - - private boolean invalid; - private final SpdyHeaders headers = new DefaultSpdyHeaders(); - - /** - * Creates a new instance. - */ - protected DefaultSpdyHeaderBlock() { - } - - @Override - public boolean isInvalid() { - return invalid; - } - - @Override - public SpdyHeaderBlock setInvalid() { - invalid = true; - return this; - } - - @Override - public SpdyHeaders headers() { - return headers; - } - - protected void appendHeaders(StringBuilder buf) { - for (Map.Entry e: headers().entries()) { - buf.append(" "); - buf.append(e.getKey()); - buf.append(": "); - buf.append(e.getValue()); - buf.append(StringUtil.NEWLINE); - } - } -} diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdyHeadersFrame.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdyHeadersFrame.java index 1687bf0c73..6abb43fd73 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdyHeadersFrame.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdyHeadersFrame.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 @@ -15,17 +15,18 @@ */ package io.netty.handler.codec.spdy; +import java.util.Map; import io.netty.util.internal.StringUtil; /** * The default {@link SpdyHeadersFrame} implementation. */ -public class DefaultSpdyHeadersFrame extends DefaultSpdyHeaderBlock +public class DefaultSpdyHeadersFrame extends DefaultSpdyStreamFrame implements SpdyHeadersFrame { - private int streamId; - private boolean last; + private boolean invalid; + private final SpdyHeaders headers = new DefaultSpdyHeaders(); /** * Creates a new instance. @@ -33,41 +34,34 @@ public class DefaultSpdyHeadersFrame extends DefaultSpdyHeaderBlock * @param streamId the Stream-ID of this frame */ public DefaultSpdyHeadersFrame(int streamId) { - setStreamId(streamId); - } - - @Override - public int getStreamId() { - return streamId; + super(streamId); } @Override public SpdyHeadersFrame setStreamId(int streamId) { - if (streamId <= 0) { - throw new IllegalArgumentException( - "Stream-ID must be positive: " + streamId); - } - this.streamId = streamId; + super.setStreamId(streamId); return this; } - @Override - public boolean isLast() { - return last; - } - @Override public SpdyHeadersFrame setLast(boolean last) { - this.last = last; + super.setLast(last); return this; } - @Override + public boolean isInvalid() { + return invalid; + } + public SpdyHeadersFrame setInvalid() { - super.setInvalid(); + invalid = true; return this; } + public SpdyHeaders headers() { + return headers; + } + @Override public String toString() { StringBuilder buf = new StringBuilder(); @@ -77,7 +71,7 @@ public class DefaultSpdyHeadersFrame extends DefaultSpdyHeaderBlock buf.append(')'); buf.append(StringUtil.NEWLINE); buf.append("--> Stream-ID = "); - buf.append(streamId); + buf.append(getStreamId()); buf.append(StringUtil.NEWLINE); buf.append("--> Headers:"); buf.append(StringUtil.NEWLINE); @@ -87,4 +81,14 @@ public class DefaultSpdyHeadersFrame extends DefaultSpdyHeaderBlock buf.setLength(buf.length() - StringUtil.NEWLINE.length()); return buf.toString(); } + + protected void appendHeaders(StringBuilder buf) { + for (Map.Entry e: headers().entries()) { + buf.append(" "); + buf.append(e.getKey()); + buf.append(": "); + buf.append(e.getValue()); + buf.append(StringUtil.NEWLINE); + } + } } diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdyNoOpFrame.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdyNoOpFrame.java deleted file mode 100644 index 4f75c0382a..0000000000 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdyNoOpFrame.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2012 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 - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ -package io.netty.handler.codec.spdy; - -/** - * The default {@link SpdyNoOpFrame} implementation. - */ -public class DefaultSpdyNoOpFrame implements SpdyNoOpFrame { - - @Override - public String toString() { - return getClass().getSimpleName(); - } -} diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdyPingFrame.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdyPingFrame.java index 7e2ad7ac7f..d2d6b5c092 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdyPingFrame.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdyPingFrame.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 @@ -33,12 +33,10 @@ public class DefaultSpdyPingFrame implements SpdyPingFrame { setId(id); } - @Override public int getId() { return id; } - @Override public SpdyPingFrame setId(int id) { this.id = id; return this; @@ -50,7 +48,7 @@ public class DefaultSpdyPingFrame implements SpdyPingFrame { buf.append(getClass().getSimpleName()); buf.append(StringUtil.NEWLINE); buf.append("--> ID = "); - buf.append(id); + buf.append(getId()); return buf.toString(); } } diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdyRstStreamFrame.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdyRstStreamFrame.java index e27c55a009..894b3cc6ba 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdyRstStreamFrame.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdyRstStreamFrame.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 @@ -20,9 +20,9 @@ import io.netty.util.internal.StringUtil; /** * The default {@link SpdyRstStreamFrame} implementation. */ -public class DefaultSpdyRstStreamFrame implements SpdyRstStreamFrame { +public class DefaultSpdyRstStreamFrame extends DefaultSpdyStreamFrame + implements SpdyRstStreamFrame { - private int streamId; private SpdyStreamStatus status; /** @@ -39,34 +39,29 @@ public class DefaultSpdyRstStreamFrame implements SpdyRstStreamFrame { * Creates a new instance. * * @param streamId the Stream-ID of this frame - * @param status the getStatus of this frame + * @param status the status of this frame */ public DefaultSpdyRstStreamFrame(int streamId, SpdyStreamStatus status) { - setStreamId(streamId); + super(streamId); setStatus(status); } - @Override - public int getStreamId() { - return streamId; - } - @Override public SpdyRstStreamFrame setStreamId(int streamId) { - if (streamId <= 0) { - throw new IllegalArgumentException( - "Stream-ID must be positive: " + streamId); - } - this.streamId = streamId; + super.setStreamId(streamId); return this; } @Override + public SpdyRstStreamFrame setLast(boolean last) { + super.setLast(last); + return this; + } + public SpdyStreamStatus getStatus() { return status; } - @Override public SpdyRstStreamFrame setStatus(SpdyStreamStatus status) { this.status = status; return this; @@ -78,10 +73,10 @@ public class DefaultSpdyRstStreamFrame implements SpdyRstStreamFrame { buf.append(getClass().getSimpleName()); buf.append(StringUtil.NEWLINE); buf.append("--> Stream-ID = "); - buf.append(streamId); + buf.append(getStreamId()); buf.append(StringUtil.NEWLINE); buf.append("--> Status: "); - buf.append(status.toString()); + buf.append(getStatus().toString()); return buf.toString(); } } diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdyStreamFrame.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdyStreamFrame.java new file mode 100644 index 0000000000..5353699cc7 --- /dev/null +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdyStreamFrame.java @@ -0,0 +1,56 @@ +/* + * 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 + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package io.netty.handler.codec.spdy; + +/** + * The default {@link SpdyStreamFrame} implementation. + */ +public abstract class DefaultSpdyStreamFrame implements SpdyStreamFrame { + + private int streamId; + private boolean last; + + /** + * Creates a new instance. + * + * @param streamId the Stream-ID of this frame + */ + protected DefaultSpdyStreamFrame(int streamId) { + setStreamId(streamId); + } + + public int getStreamId() { + return streamId; + } + + public SpdyStreamFrame setStreamId(int streamId) { + if (streamId <= 0) { + throw new IllegalArgumentException( + "Stream-ID must be positive: " + streamId); + } + this.streamId = streamId; + return this; + } + + public boolean isLast() { + return last; + } + + public SpdyStreamFrame setLast(boolean last) { + this.last = last; + return this; + } +} diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdySynReplyFrame.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdySynReplyFrame.java index e9858c674c..ef5b61033c 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdySynReplyFrame.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdySynReplyFrame.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 @@ -20,44 +20,27 @@ import io.netty.util.internal.StringUtil; /** * The default {@link SpdySynReplyFrame} implementation. */ -public class DefaultSpdySynReplyFrame extends DefaultSpdyHeaderBlock +public class DefaultSpdySynReplyFrame extends DefaultSpdyHeadersFrame implements SpdySynReplyFrame { - private int streamId; - private boolean last; - /** * Creates a new instance. * * @param streamId the Stream-ID of this frame */ public DefaultSpdySynReplyFrame(int streamId) { - setStreamId(streamId); - } - - @Override - public int getStreamId() { - return streamId; + super(streamId); } @Override public SpdySynReplyFrame setStreamId(int streamId) { - if (streamId <= 0) { - throw new IllegalArgumentException( - "Stream-ID must be positive: " + streamId); - } - this.streamId = streamId; + super.setStreamId(streamId); return this; } - @Override - public boolean isLast() { - return last; - } - @Override public SpdySynReplyFrame setLast(boolean last) { - this.last = last; + super.setLast(last); return this; } @@ -76,7 +59,7 @@ public class DefaultSpdySynReplyFrame extends DefaultSpdyHeaderBlock buf.append(')'); buf.append(StringUtil.NEWLINE); buf.append("--> Stream-ID = "); - buf.append(streamId); + buf.append(getStreamId()); buf.append(StringUtil.NEWLINE); buf.append("--> Headers:"); buf.append(StringUtil.NEWLINE); diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdySynStreamFrame.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdySynStreamFrame.java index 3b0d1290ad..c2bba9deb1 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdySynStreamFrame.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdySynStreamFrame.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 @@ -20,13 +20,11 @@ import io.netty.util.internal.StringUtil; /** * The default {@link SpdySynStreamFrame} implementation. */ -public class DefaultSpdySynStreamFrame extends DefaultSpdyHeaderBlock +public class DefaultSpdySynStreamFrame extends DefaultSpdyHeadersFrame implements SpdySynStreamFrame { - private int streamId; private int associatedToStreamId; private byte priority; - private boolean last; private boolean unidirectional; /** @@ -38,23 +36,26 @@ public class DefaultSpdySynStreamFrame extends DefaultSpdyHeaderBlock */ public DefaultSpdySynStreamFrame( int streamId, int associatedToStreamId, byte priority) { - setStreamId(streamId); + super(streamId); setAssociatedToStreamId(associatedToStreamId); setPriority(priority); } @Override - public int getStreamId() { - return streamId; + public SpdySynStreamFrame setStreamId(int streamId) { + super.setStreamId(streamId); + return this; } @Override - public SpdySynStreamFrame setStreamId(int streamId) { - if (streamId <= 0) { - throw new IllegalArgumentException( - "Stream-ID must be positive: " + streamId); - } - this.streamId = streamId; + public SpdySynStreamFrame setLast(boolean last) { + super.setLast(last); + return this; + } + + @Override + public SpdySynStreamFrame setInvalid() { + super.setInvalid(); return this; } @@ -89,17 +90,6 @@ public class DefaultSpdySynStreamFrame extends DefaultSpdyHeaderBlock return this; } - @Override - public boolean isLast() { - return last; - } - - @Override - public SpdySynStreamFrame setLast(boolean last) { - this.last = last; - return this; - } - @Override public boolean isUnidirectional() { return unidirectional; @@ -111,12 +101,6 @@ public class DefaultSpdySynStreamFrame extends DefaultSpdyHeaderBlock return this; } - @Override - public SpdySynStreamFrame setInvalid() { - super.setInvalid(); - return this; - } - @Override public String toString() { StringBuilder buf = new StringBuilder(); @@ -128,15 +112,15 @@ public class DefaultSpdySynStreamFrame extends DefaultSpdyHeaderBlock buf.append(')'); buf.append(StringUtil.NEWLINE); buf.append("--> Stream-ID = "); - buf.append(streamId); + buf.append(getStreamId()); buf.append(StringUtil.NEWLINE); if (associatedToStreamId != 0) { buf.append("--> Associated-To-Stream-ID = "); - buf.append(associatedToStreamId); + buf.append(getAssociatedToStreamId()); buf.append(StringUtil.NEWLINE); } buf.append("--> Priority = "); - buf.append(priority); + buf.append(getPriority()); buf.append(StringUtil.NEWLINE); buf.append("--> Headers:"); buf.append(StringUtil.NEWLINE); diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdyWindowUpdateFrame.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdyWindowUpdateFrame.java index 88d18f3c0e..b1905ba75d 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdyWindowUpdateFrame.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/DefaultSpdyWindowUpdateFrame.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 @@ -43,9 +43,9 @@ public class DefaultSpdyWindowUpdateFrame implements SpdyWindowUpdateFrame { @Override public SpdyWindowUpdateFrame setStreamId(int streamId) { - if (streamId <= 0) { + if (streamId < 0) { throw new IllegalArgumentException( - "Stream-ID must be positive: " + streamId); + "Stream-ID cannot be negative: " + streamId); } this.streamId = streamId; return this; @@ -73,10 +73,10 @@ public class DefaultSpdyWindowUpdateFrame implements SpdyWindowUpdateFrame { buf.append(getClass().getSimpleName()); buf.append(StringUtil.NEWLINE); buf.append("--> Stream-ID = "); - buf.append(streamId); + buf.append(getStreamId()); buf.append(StringUtil.NEWLINE); buf.append("--> Delta-Window-Size = "); - buf.append(deltaWindowSize); + buf.append(getDeltaWindowSize()); return buf.toString(); } } diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyControlFrame.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyControlFrame.java deleted file mode 100644 index 7680ef54df..0000000000 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyControlFrame.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2012 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 - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ -package io.netty.handler.codec.spdy; - -/** - * A SPDY Protocol Control Frame - */ -public interface SpdyControlFrame extends SpdyDataOrControlFrame { - // Tag interface -} diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyDataFrame.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyDataFrame.java index 42909fe300..ea6d5e6b19 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyDataFrame.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyDataFrame.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 @@ -20,9 +20,9 @@ import io.netty.buffer.ByteBufHolder; import io.netty.buffer.Unpooled; /** - * A SPDY Protocol Data Frame + * A SPDY Protocol DATA Frame */ -public interface SpdyDataFrame extends ByteBufHolder, SpdyStreamFrame, SpdyDataOrControlFrame { +public interface SpdyDataFrame extends ByteBufHolder, SpdyStreamFrame { @Override SpdyDataFrame setStreamId(int streamID); diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyDataOrControlFrame.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyFrame.java similarity index 91% rename from codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyDataOrControlFrame.java rename to codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyFrame.java index 2d25961c00..df0b72f7eb 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyDataOrControlFrame.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyFrame.java @@ -13,9 +13,11 @@ * License for the specific language governing permissions and limitations * under the License. */ - package io.netty.handler.codec.spdy; -public interface SpdyDataOrControlFrame { +/** + * A SPDY Protocol Frame + */ +public interface SpdyFrame { // Tag interface } diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyFrameCodec.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyFrameCodec.java index d18952f6fb..7e594b27d4 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyFrameCodec.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyFrameCodec.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 @@ -21,7 +21,6 @@ import io.netty.channel.CombinedChannelDuplexHandler; * A combination of {@link SpdyFrameDecoder} and {@link SpdyFrameEncoder}. */ public final class SpdyFrameCodec extends CombinedChannelDuplexHandler { - /** * Creates a new instance with the specified {@code version} and * the default decoder and encoder options 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 4147f5ac5d..12df32ad96 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 @@ -25,7 +25,7 @@ import io.netty.handler.codec.TooLongFrameException; import static io.netty.handler.codec.spdy.SpdyCodecUtil.*; /** - * Decodes {@link ByteBuf}s into SPDY Data and Control Frames. + * Decodes {@link ByteBuf}s into SPDY Frames. */ public class SpdyFrameDecoder extends ByteToMessageDecoder { @@ -37,7 +37,7 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder { private State state; private SpdySettingsFrame spdySettingsFrame; - private SpdyHeaderBlock spdyHeaderBlock; + private SpdyHeadersFrame spdyHeadersFrame; // SPDY common header fields private byte flags; @@ -221,12 +221,12 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder { case READ_HEADER_BLOCK_FRAME: try { - spdyHeaderBlock = readHeaderBlockFrame(buffer); - if (spdyHeaderBlock != null) { + spdyHeadersFrame = readHeaderBlockFrame(buffer); + if (spdyHeadersFrame != null) { if (length == 0) { state = State.READ_COMMON_HEADER; - Object frame = spdyHeaderBlock; - spdyHeaderBlock = null; + Object frame = spdyHeadersFrame; + spdyHeadersFrame = null; out.add(frame); return; } @@ -247,15 +247,15 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder { decodeHeaderBlock(buffer.readSlice(compressedBytes)); } catch (Exception e) { state = State.FRAME_ERROR; - spdyHeaderBlock = null; + spdyHeadersFrame = null; decompressed = null; ctx.fireExceptionCaught(e); return; } - if (spdyHeaderBlock != null && spdyHeaderBlock.isInvalid()) { - Object frame = spdyHeaderBlock; - spdyHeaderBlock = null; + if (spdyHeadersFrame != null && spdyHeadersFrame.isInvalid()) { + Object frame = spdyHeadersFrame; + spdyHeadersFrame = null; decompressed = null; if (length == 0) { state = State.READ_COMMON_HEADER; @@ -265,8 +265,8 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder { } if (length == 0) { - Object frame = spdyHeaderBlock; - spdyHeaderBlock = null; + Object frame = spdyHeadersFrame; + spdyHeadersFrame = null; state = State.READ_COMMON_HEADER; out.add(frame); return; @@ -436,7 +436,7 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder { } } - private SpdyHeaderBlock readHeaderBlockFrame(ByteBuf buffer) { + private SpdyHeadersFrame readHeaderBlockFrame(ByteBuf buffer) { int minLength; int streamID; switch (type) { @@ -567,7 +567,7 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder { headerBlockDecompressor.setInput(buffer); headerBlockDecompressor.decode(decompressed); - if (spdyHeaderBlock == null) { + if (spdyHeadersFrame == null) { // Only decompressing data to keep decompression context in sync decompressed = null; return; @@ -582,7 +582,7 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder { } numHeaders = readLengthField(); if (numHeaders < 0) { - spdyHeaderBlock.setInvalid(); + spdyHeadersFrame.setInvalid(); return; } } @@ -601,7 +601,7 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder { // Recipients of a zero-length name must issue a stream error if (nameLength <= 0) { - spdyHeaderBlock.setInvalid(); + spdyHeadersFrame.setInvalid(); return; } headerSize += nameLength; @@ -621,8 +621,8 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder { String name = new String(nameBytes, "UTF-8"); // Check for identically named headers - if (spdyHeaderBlock.headers().contains(name)) { - spdyHeaderBlock.setInvalid(); + if (spdyHeadersFrame.headers().contains(name)) { + spdyHeadersFrame.setInvalid(); return; } @@ -636,17 +636,17 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder { // Recipients of illegal value fields must issue a stream error if (valueLength < 0) { - spdyHeaderBlock.setInvalid(); + spdyHeadersFrame.setInvalid(); return; } // SPDY/3 allows zero-length (empty) header values if (valueLength == 0) { if (version < 3) { - spdyHeaderBlock.setInvalid(); + spdyHeadersFrame.setInvalid(); return; } else { - spdyHeaderBlock.headers().add(name, ""); + spdyHeadersFrame.headers().add(name, ""); numHeaders --; this.headerSize = headerSize; continue; @@ -678,16 +678,16 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder { if (index < valueBytes.length && valueBytes[index + 1] == (byte) 0) { // Received multiple, in-sequence NULL characters // Recipients of illegal value fields must issue a stream error - spdyHeaderBlock.setInvalid(); + spdyHeadersFrame.setInvalid(); return; } String value = new String(valueBytes, offset, index - offset, "UTF-8"); try { - spdyHeaderBlock.headers().add(name, value); + spdyHeadersFrame.headers().add(name, value); } catch (IllegalArgumentException e) { // Name contains NULL or non-ascii characters - spdyHeaderBlock.setInvalid(); + spdyHeadersFrame.setInvalid(); return; } index ++; 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 6a866505df..e16b6c68a7 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 @@ -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 @@ -29,9 +29,9 @@ import java.util.Set; import static io.netty.handler.codec.spdy.SpdyCodecUtil.*; /** - * Encodes a SPDY Data or Control Frame into a {@link ByteBuf}. + * Encodes a SPDY Frame into a {@link ByteBuf}. */ -public class SpdyFrameEncoder extends MessageToByteEncoder { +public class SpdyFrameEncoder extends MessageToByteEncoder { private final int version; private volatile boolean finished; @@ -76,7 +76,7 @@ public class SpdyFrameEncoder extends MessageToByteEncoder names = headerFrame.headers().names(); int numHeaders = names.size(); diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyGoAwayFrame.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyGoAwayFrame.java index 2963316760..318c6bfe92 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyGoAwayFrame.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyGoAwayFrame.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 @@ -16,9 +16,9 @@ package io.netty.handler.codec.spdy; /** - * A SPDY Protocol GOAWAY Control Frame + * A SPDY Protocol GOAWAY Frame */ -public interface SpdyGoAwayFrame extends SpdyControlFrame { +public interface SpdyGoAwayFrame extends SpdyFrame { /** * Returns the Last-good-stream-ID of this frame. @@ -32,12 +32,12 @@ public interface SpdyGoAwayFrame extends SpdyControlFrame { SpdyGoAwayFrame setLastGoodStreamId(int lastGoodStreamId); /** - * Returns the getStatus of this frame. + * Returns the status of this frame. */ SpdySessionStatus getStatus(); /** - * Sets the getStatus of this frame. + * Sets the status of this frame. */ SpdyGoAwayFrame setStatus(SpdySessionStatus status); } diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHeaderBlock.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHeaderBlock.java deleted file mode 100644 index 902cce7c4e..0000000000 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHeaderBlock.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2012 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 - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ -package io.netty.handler.codec.spdy; - - -/** - * A SPDY Name/Value Header Block which provides common properties for - * {@link SpdySynStreamFrame}, {@link SpdySynReplyFrame}, and - * {@link SpdyHeadersFrame}. - * @see SpdyHeaders - */ -public interface SpdyHeaderBlock { - - /** - * Returns {@code true} if this header block is invalid. - * A RST_STREAM frame with code PROTOCOL_ERROR should be sent. - */ - boolean isInvalid(); - - /** - * Marks this header block as invalid. - */ - SpdyHeaderBlock setInvalid(); - - /** - * Returns the {@link SpdyHeaders}. - */ - SpdyHeaders headers(); -} diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHeaders.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHeaders.java index 6ab424cf22..3e073370d2 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHeaders.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHeaders.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 @@ -27,7 +27,7 @@ import java.util.Set; /** * Provides the constants for the standard SPDY HTTP header names and commonly - * used utility methods that access a {@link SpdyHeaderBlock}. + * used utility methods that access a {@link SpdyHeadersFrame}. */ public abstract class SpdyHeaders implements Iterable> { @@ -166,8 +166,8 @@ public abstract class SpdyHeaders implements Iterable> * * @return the header value or {@code null} if there is no such header */ - public static String getHeader(SpdyHeaderBlock block, String name) { - return block.headers().get(name); + public static String getHeader(SpdyHeadersFrame frame, String name) { + return frame.headers().get(name); } /** @@ -178,8 +178,8 @@ public abstract class SpdyHeaders implements Iterable> * @return the header value or the {@code defaultValue} if there is no such * header */ - public static String getHeader(SpdyHeaderBlock block, String name, String defaultValue) { - String value = block.headers().get(name); + public static String getHeader(SpdyHeadersFrame frame, String name, String defaultValue) { + String value = frame.headers().get(name); if (value == null) { return defaultValue; } @@ -190,66 +190,66 @@ public abstract class SpdyHeaders implements Iterable> * Sets a new header with the specified name and value. If there is an * existing header with the same name, the existing header is removed. */ - public static void setHeader(SpdyHeaderBlock block, String name, Object value) { - block.headers().set(name, value); + public static void setHeader(SpdyHeadersFrame frame, String name, Object value) { + frame.headers().set(name, value); } /** * Sets a new header with the specified name and values. If there is an * existing header with the same name, the existing header is removed. */ - public static void setHeader(SpdyHeaderBlock block, String name, Iterable values) { - block.headers().set(name, values); + public static void setHeader(SpdyHeadersFrame frame, String name, Iterable values) { + frame.headers().set(name, values); } /** * Adds a new header with the specified name and value. */ - public static void addHeader(SpdyHeaderBlock block, String name, Object value) { - block.headers().add(name, value); + public static void addHeader(SpdyHeadersFrame frame, String name, Object value) { + frame.headers().add(name, value); } /** * Removes the SPDY host header. */ - public static void removeHost(SpdyHeaderBlock block) { - block.headers().remove(HttpNames.HOST); + public static void removeHost(SpdyHeadersFrame frame) { + frame.headers().remove(HttpNames.HOST); } /** * Returns the SPDY host header. */ - public static String getHost(SpdyHeaderBlock block) { - return block.headers().get(HttpNames.HOST); + public static String getHost(SpdyHeadersFrame frame) { + return frame.headers().get(HttpNames.HOST); } /** * Set the SPDY host header. */ - public static void setHost(SpdyHeaderBlock block, String host) { - block.headers().set(HttpNames.HOST, host); + public static void setHost(SpdyHeadersFrame frame, String host) { + frame.headers().set(HttpNames.HOST, host); } /** * Removes the HTTP method header. */ - public static void removeMethod(int spdyVersion, SpdyHeaderBlock block) { + public static void removeMethod(int spdyVersion, SpdyHeadersFrame frame) { if (spdyVersion < 3) { - block.headers().remove(Spdy2HttpNames.METHOD); + frame.headers().remove(Spdy2HttpNames.METHOD); } else { - block.headers().remove(HttpNames.METHOD); + frame.headers().remove(HttpNames.METHOD); } } /** * Returns the {@link HttpMethod} represented by the HTTP method header. */ - public static HttpMethod getMethod(int spdyVersion, SpdyHeaderBlock block) { + public static HttpMethod getMethod(int spdyVersion, SpdyHeadersFrame frame) { try { if (spdyVersion < 3) { - return HttpMethod.valueOf(block.headers().get(Spdy2HttpNames.METHOD)); + return HttpMethod.valueOf(frame.headers().get(Spdy2HttpNames.METHOD)); } else { - return HttpMethod.valueOf(block.headers().get(HttpNames.METHOD)); + return HttpMethod.valueOf(frame.headers().get(HttpNames.METHOD)); } } catch (Exception e) { return null; @@ -259,68 +259,68 @@ public abstract class SpdyHeaders implements Iterable> /** * Sets the HTTP method header. */ - public static void setMethod(int spdyVersion, SpdyHeaderBlock block, HttpMethod method) { + public static void setMethod(int spdyVersion, SpdyHeadersFrame frame, HttpMethod method) { if (spdyVersion < 3) { - block.headers().set(Spdy2HttpNames.METHOD, method.name()); + frame.headers().set(Spdy2HttpNames.METHOD, method.name()); } else { - block.headers().set(HttpNames.METHOD, method.name()); + frame.headers().set(HttpNames.METHOD, method.name()); } } /** * Removes the URL scheme header. */ - public static void removeScheme(int spdyVersion, SpdyHeaderBlock block) { + public static void removeScheme(int spdyVersion, SpdyHeadersFrame frame) { if (spdyVersion < 2) { - block.headers().remove(Spdy2HttpNames.SCHEME); + frame.headers().remove(Spdy2HttpNames.SCHEME); } else { - block.headers().remove(HttpNames.SCHEME); + frame.headers().remove(HttpNames.SCHEME); } } /** * Returns the value of the URL scheme header. */ - public static String getScheme(int spdyVersion, SpdyHeaderBlock block) { + public static String getScheme(int spdyVersion, SpdyHeadersFrame frame) { if (spdyVersion < 3) { - return block.headers().get(Spdy2HttpNames.SCHEME); + return frame.headers().get(Spdy2HttpNames.SCHEME); } else { - return block.headers().get(HttpNames.SCHEME); + return frame.headers().get(HttpNames.SCHEME); } } /** * Sets the URL scheme header. */ - public static void setScheme(int spdyVersion, SpdyHeaderBlock block, String scheme) { + public static void setScheme(int spdyVersion, SpdyHeadersFrame frame, String scheme) { if (spdyVersion < 3) { - block.headers().set(Spdy2HttpNames.SCHEME, scheme); + frame.headers().set(Spdy2HttpNames.SCHEME, scheme); } else { - block.headers().set(HttpNames.SCHEME, scheme); + frame.headers().set(HttpNames.SCHEME, scheme); } } /** * Removes the HTTP response status header. */ - public static void removeStatus(int spdyVersion, SpdyHeaderBlock block) { + public static void removeStatus(int spdyVersion, SpdyHeadersFrame frame) { if (spdyVersion < 3) { - block.headers().remove(Spdy2HttpNames.STATUS); + frame.headers().remove(Spdy2HttpNames.STATUS); } else { - block.headers().remove(HttpNames.STATUS); + frame.headers().remove(HttpNames.STATUS); } } /** * Returns the {@link HttpResponseStatus} represented by the HTTP response status header. */ - public static HttpResponseStatus getStatus(int spdyVersion, SpdyHeaderBlock block) { + public static HttpResponseStatus getStatus(int spdyVersion, SpdyHeadersFrame frame) { try { String status; if (spdyVersion < 3) { - status = block.headers().get(Spdy2HttpNames.STATUS); + status = frame.headers().get(Spdy2HttpNames.STATUS); } else { - status = block.headers().get(HttpNames.STATUS); + status = frame.headers().get(HttpNames.STATUS); } int space = status.indexOf(' '); if (space == -1) { @@ -343,67 +343,67 @@ public abstract class SpdyHeaders implements Iterable> /** * Sets the HTTP response status header. */ - public static void setStatus(int spdyVersion, SpdyHeaderBlock block, HttpResponseStatus status) { + public static void setStatus(int spdyVersion, SpdyHeadersFrame frame, HttpResponseStatus status) { if (spdyVersion < 3) { - block.headers().set(Spdy2HttpNames.STATUS, status.toString()); + frame.headers().set(Spdy2HttpNames.STATUS, status.toString()); } else { - block.headers().set(HttpNames.STATUS, status.toString()); + frame.headers().set(HttpNames.STATUS, status.toString()); } } /** * Removes the URL path header. */ - public static void removeUrl(int spdyVersion, SpdyHeaderBlock block) { + public static void removeUrl(int spdyVersion, SpdyHeadersFrame frame) { if (spdyVersion < 3) { - block.headers().remove(Spdy2HttpNames.URL); + frame.headers().remove(Spdy2HttpNames.URL); } else { - block.headers().remove(HttpNames.PATH); + frame.headers().remove(HttpNames.PATH); } } /** * Returns the value of the URL path header. */ - public static String getUrl(int spdyVersion, SpdyHeaderBlock block) { + public static String getUrl(int spdyVersion, SpdyHeadersFrame frame) { if (spdyVersion < 3) { - return block.headers().get(Spdy2HttpNames.URL); + return frame.headers().get(Spdy2HttpNames.URL); } else { - return block.headers().get(HttpNames.PATH); + return frame.headers().get(HttpNames.PATH); } } /** * Sets the URL path header. */ - public static void setUrl(int spdyVersion, SpdyHeaderBlock block, String path) { + public static void setUrl(int spdyVersion, SpdyHeadersFrame frame, String path) { if (spdyVersion < 3) { - block.headers().set(Spdy2HttpNames.URL, path); + frame.headers().set(Spdy2HttpNames.URL, path); } else { - block.headers().set(HttpNames.PATH, path); + frame.headers().set(HttpNames.PATH, path); } } /** * Removes the HTTP version header. */ - public static void removeVersion(int spdyVersion, SpdyHeaderBlock block) { + public static void removeVersion(int spdyVersion, SpdyHeadersFrame frame) { if (spdyVersion < 3) { - block.headers().remove(Spdy2HttpNames.VERSION); + frame.headers().remove(Spdy2HttpNames.VERSION); } else { - block.headers().remove(HttpNames.VERSION); + frame.headers().remove(HttpNames.VERSION); } } /** * Returns the {@link HttpVersion} represented by the HTTP version header. */ - public static HttpVersion getVersion(int spdyVersion, SpdyHeaderBlock block) { + public static HttpVersion getVersion(int spdyVersion, SpdyHeadersFrame frame) { try { if (spdyVersion < 3) { - return HttpVersion.valueOf(block.headers().get(Spdy2HttpNames.VERSION)); + return HttpVersion.valueOf(frame.headers().get(Spdy2HttpNames.VERSION)); } else { - return HttpVersion.valueOf(block.headers().get(HttpNames.VERSION)); + return HttpVersion.valueOf(frame.headers().get(HttpNames.VERSION)); } } catch (Exception e) { return null; @@ -413,11 +413,11 @@ public abstract class SpdyHeaders implements Iterable> /** * Sets the HTTP version header. */ - public static void setVersion(int spdyVersion, SpdyHeaderBlock block, HttpVersion httpVersion) { + public static void setVersion(int spdyVersion, SpdyHeadersFrame frame, HttpVersion httpVersion) { if (spdyVersion < 3) { - block.headers().set(Spdy2HttpNames.VERSION, httpVersion.text()); + frame.headers().set(Spdy2HttpNames.VERSION, httpVersion.text()); } else { - block.headers().set(HttpNames.VERSION, httpVersion.text()); + frame.headers().set(HttpNames.VERSION, httpVersion.text()); } } @Override @@ -443,7 +443,7 @@ public abstract class SpdyHeaders implements Iterable> public abstract List getAll(String name); /** - * Returns all header names and values that this block contains. + * Returns all header names and values that this frame contains. * * @return the {@link List} of the header name-value pairs. An empty list * if there is no header in this message. @@ -457,7 +457,7 @@ public abstract class SpdyHeaders implements Iterable> public abstract boolean contains(String name); /** - * Returns the {@link Set} of all header names that this block contains. + * Returns the {@link Set} of all header names that this frame contains. */ public abstract Set names(); @@ -490,7 +490,7 @@ public abstract class SpdyHeaders implements Iterable> public abstract SpdyHeaders remove(String name); /** - * Removes all headers from this block. + * Removes all headers from this frame. */ public abstract SpdyHeaders clear(); diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHeadersFrame.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHeadersFrame.java index 28a7956abb..7c587f969b 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHeadersFrame.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHeadersFrame.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 @@ -16,17 +16,29 @@ package io.netty.handler.codec.spdy; /** - * A SPDY Protocol HEADERS Control Frame + * A SPDY Protocol HEADERS Frame */ -public interface SpdyHeadersFrame extends SpdyHeaderBlock, SpdyControlFrame, SpdyStreamFrame { +public interface SpdyHeadersFrame extends SpdyStreamFrame { + + /** + * Returns {@code true} if this header block is invalid. + * A RST_STREAM frame with code PROTOCOL_ERROR should be sent. + */ + boolean isInvalid(); + + /** + * Marks this header block as invalid. + */ + SpdyHeadersFrame setInvalid(); + + /** + * Returns the {@link SpdyHeaders}. + */ + SpdyHeaders headers(); @Override SpdyHeadersFrame setStreamId(int streamID); @Override SpdyHeadersFrame setLast(boolean last); - - @Override - SpdyHeadersFrame setInvalid(); - } diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHttpCodec.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHttpCodec.java index 562aef5b1c..86bfea22e7 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHttpCodec.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHttpCodec.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 @@ -22,7 +22,6 @@ import io.netty.channel.CombinedChannelDuplexHandler; */ public final class SpdyHttpCodec extends CombinedChannelDuplexHandler { - /** * Creates a new instance with the specified decoder options. */ diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHttpDecoder.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHttpDecoder.java index e10fc2809c..0e256efcb6 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHttpDecoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHttpDecoder.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 @@ -37,7 +37,7 @@ import java.util.Map; * Decodes {@link SpdySynStreamFrame}s, {@link SpdySynReplyFrame}s, * and {@link SpdyDataFrame}s into {@link FullHttpRequest}s and {@link FullHttpResponse}s. */ -public class SpdyHttpDecoder extends MessageToMessageDecoder { +public class SpdyHttpDecoder extends MessageToMessageDecoder { private final int spdyVersion; private final int maxContentLength; @@ -91,7 +91,7 @@ public class SpdyHttpDecoder extends MessageToMessageDecoder out) + protected void decode(ChannelHandlerContext ctx, SpdyFrame msg, MessageList out) throws Exception { if (msg instanceof SpdySynStreamFrame) { @@ -252,7 +252,7 @@ public class SpdyHttpDecoder extends MessageToMessageDecoder { int streamID = SpdyHttpHeaders.getStreamId(httpResponse); SpdyHttpHeaders.removeStreamId(httpResponse); - // The Connection, Keep-Alive, Proxy-Connection, and Transfer-ENcoding + // The Connection, Keep-Alive, Proxy-Connection, and Transfer-Encoding // headers are not valid and MUST not be sent. httpResponse.headers().remove(HttpHeaders.Names.CONNECTION); httpResponse.headers().remove("Keep-Alive"); diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyNoOpFrame.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyNoOpFrame.java deleted file mode 100644 index 31b6e11a0b..0000000000 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyNoOpFrame.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2012 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 - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ -package io.netty.handler.codec.spdy; - -/** - * A SPDY Protocol NOOP Control Frame - */ -public interface SpdyNoOpFrame extends SpdyControlFrame { - // Tag interface -} diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyPingFrame.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyPingFrame.java index 63c582e8da..d2e98e67b9 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyPingFrame.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyPingFrame.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 @@ -16,9 +16,9 @@ package io.netty.handler.codec.spdy; /** - * A SPDY Protocol PING Control Frame + * A SPDY Protocol PING Frame */ -public interface SpdyPingFrame extends SpdyControlFrame { +public interface SpdyPingFrame extends SpdyFrame { /** * Returns the ID of this frame. diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyRstStreamFrame.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyRstStreamFrame.java index 06af326aea..fbab068e8d 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyRstStreamFrame.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyRstStreamFrame.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 @@ -16,27 +16,23 @@ package io.netty.handler.codec.spdy; /** - * A SPDY Protocol RST_STREAM Control Frame + * A SPDY Protocol RST_STREAM Frame */ -public interface SpdyRstStreamFrame extends SpdyControlFrame { +public interface SpdyRstStreamFrame extends SpdyStreamFrame { /** - * Returns the Stream-ID of this frame. - */ - int getStreamId(); - - /** - * Sets the Stream-ID of this frame. The Stream-ID must be positive. - */ - SpdyControlFrame setStreamId(int streamID); - - /** - * Returns the getStatus of this frame. + * Returns the status of this frame. */ SpdyStreamStatus getStatus(); /** - * Sets the getStatus of this frame. + * Sets the status of this frame. */ - SpdyControlFrame setStatus(SpdyStreamStatus status); + SpdyRstStreamFrame setStatus(SpdyStreamStatus status); + + @Override + SpdyRstStreamFrame setStreamId(int streamId); + + @Override + SpdyRstStreamFrame setLast(boolean last); } 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 4a4272548c..2c4ec524e2 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 @@ -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 @@ -135,27 +135,29 @@ public class SpdySessionHandler */ SpdyDataFrame spdyDataFrame = (SpdyDataFrame) msg; - int streamID = spdyDataFrame.getStreamId(); + int streamId = spdyDataFrame.getStreamId(); // Check if we received a data frame for a Stream-ID which is not open - if (!spdySession.isActiveStream(streamID)) { - if (streamID <= lastGoodStreamId) { - issueStreamError(ctx, streamID, SpdyStreamStatus.PROTOCOL_ERROR, out); + + if (!spdySession.isActiveStream(streamId)) { + if (streamId <= lastGoodStreamId) { + issueStreamError(ctx, streamId, SpdyStreamStatus.PROTOCOL_ERROR, out); } else if (!sentGoAwayFrame) { - issueStreamError(ctx, streamID, SpdyStreamStatus.INVALID_STREAM, out); + issueStreamError(ctx, streamId, SpdyStreamStatus.INVALID_STREAM, out); } return; } // Check if we received a data frame for a stream which is half-closed - if (spdySession.isRemoteSideClosed(streamID)) { - issueStreamError(ctx, streamID, SpdyStreamStatus.STREAM_ALREADY_CLOSED, out); + + if (spdySession.isRemoteSideClosed(streamId)) { + issueStreamError(ctx, streamId, SpdyStreamStatus.STREAM_ALREADY_CLOSED, out); return; } // Check if we received a data frame before receiving a SYN_REPLY - if (!isRemoteInitiatedID(streamID) && !spdySession.hasReceivedReply(streamID)) { - issueStreamError(ctx, streamID, SpdyStreamStatus.PROTOCOL_ERROR, out); + if (!isRemoteInitiatedID(streamId) && !spdySession.hasReceivedReply(streamId)) { + issueStreamError(ctx, streamId, SpdyStreamStatus.PROTOCOL_ERROR, out); return; } @@ -168,15 +170,15 @@ public class SpdySessionHandler if (flowControl) { // Update receive window size 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 // 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)) { - issueStreamError(ctx, streamID, SpdyStreamStatus.FLOW_CONTROL_ERROR, out); + if (newWindowSize < spdySession.getReceiveWindowSizeLowerBound(streamId)) { + issueStreamError(ctx, streamId, SpdyStreamStatus.FLOW_CONTROL_ERROR, out); return; } @@ -184,7 +186,7 @@ public class SpdySessionHandler // Send data frames upstream in initialReceiveWindowSize chunks if (newWindowSize < 0) { while (spdyDataFrame.content().readableBytes() > initialReceiveWindowSize) { - SpdyDataFrame partialDataFrame = new DefaultSpdyDataFrame(streamID, + SpdyDataFrame partialDataFrame = new DefaultSpdyDataFrame(streamId, spdyDataFrame.content().readSlice(initialReceiveWindowSize).retain()); ctx.write(partialDataFrame); } @@ -193,16 +195,16 @@ public class SpdySessionHandler // Send a WINDOW_UPDATE frame if less than half the window size remains if (newWindowSize <= initialReceiveWindowSize / 2 && !spdyDataFrame.isLast()) { deltaWindowSize = initialReceiveWindowSize - newWindowSize; - spdySession.updateReceiveWindowSize(streamID, deltaWindowSize); + spdySession.updateReceiveWindowSize(streamId, deltaWindowSize); SpdyWindowUpdateFrame spdyWindowUpdateFrame = - new DefaultSpdyWindowUpdateFrame(streamID, deltaWindowSize); + new DefaultSpdyWindowUpdateFrame(streamId, deltaWindowSize); ctx.write(spdyWindowUpdateFrame); } } // Close the remote side of the stream if this is the last frame if (spdyDataFrame.isLast()) { - halfCloseStream(streamID, true); + halfCloseStream(streamId, true); } } else if (msg instanceof SpdySynStreamFrame) { @@ -222,18 +224,18 @@ public class SpdySessionHandler */ SpdySynStreamFrame spdySynStreamFrame = (SpdySynStreamFrame) msg; - int streamID = spdySynStreamFrame.getStreamId(); + int streamId = spdySynStreamFrame.getStreamId(); // Check if we received a valid SYN_STREAM frame if (spdySynStreamFrame.isInvalid() || - !isRemoteInitiatedID(streamID) || - spdySession.isActiveStream(streamID)) { - issueStreamError(ctx, streamID, SpdyStreamStatus.PROTOCOL_ERROR, out); + !isRemoteInitiatedID(streamId) || + spdySession.isActiveStream(streamId)) { + issueStreamError(ctx, streamId, SpdyStreamStatus.PROTOCOL_ERROR, out); return; } // Stream-IDs must be monotonically increasing - if (streamID <= lastGoodStreamId) { + if (streamId <= lastGoodStreamId) { issueSessionError(ctx, SpdySessionStatus.PROTOCOL_ERROR); return; } @@ -242,8 +244,8 @@ public class SpdySessionHandler byte priority = spdySynStreamFrame.getPriority(); boolean remoteSideClosed = spdySynStreamFrame.isLast(); boolean localSideClosed = spdySynStreamFrame.isUnidirectional(); - if (!acceptStream(streamID, priority, remoteSideClosed, localSideClosed)) { - issueStreamError(ctx, streamID, SpdyStreamStatus.REFUSED_STREAM, out); + if (!acceptStream(streamId, priority, remoteSideClosed, localSideClosed)) { + issueStreamError(ctx, streamId, SpdyStreamStatus.REFUSED_STREAM, out); return; } @@ -257,27 +259,27 @@ public class SpdySessionHandler */ SpdySynReplyFrame spdySynReplyFrame = (SpdySynReplyFrame) msg; - int streamID = spdySynReplyFrame.getStreamId(); + int streamId = spdySynReplyFrame.getStreamId(); // Check if we received a valid SYN_REPLY frame if (spdySynReplyFrame.isInvalid() || - isRemoteInitiatedID(streamID) || - spdySession.isRemoteSideClosed(streamID)) { - issueStreamError(ctx, streamID, SpdyStreamStatus.INVALID_STREAM, out); + isRemoteInitiatedID(streamId) || + spdySession.isRemoteSideClosed(streamId)) { + issueStreamError(ctx, streamId, SpdyStreamStatus.INVALID_STREAM, out); return; } // Check if we have received multiple frames for the same Stream-ID - if (spdySession.hasReceivedReply(streamID)) { - issueStreamError(ctx, streamID, SpdyStreamStatus.STREAM_IN_USE, out); + if (spdySession.hasReceivedReply(streamId)) { + issueStreamError(ctx, streamId, SpdyStreamStatus.STREAM_IN_USE, out); return; } - spdySession.receivedReply(streamID); + spdySession.receivedReply(streamId); // Close the remote side of the stream if this is the last frame if (spdySynReplyFrame.isLast()) { - halfCloseStream(streamID, true); + halfCloseStream(streamId, true); } } else if (msg instanceof SpdyRstStreamFrame) { @@ -351,22 +353,22 @@ public class SpdySessionHandler } else if (msg instanceof SpdyHeadersFrame) { SpdyHeadersFrame spdyHeadersFrame = (SpdyHeadersFrame) msg; - int streamID = spdyHeadersFrame.getStreamId(); + int streamId = spdyHeadersFrame.getStreamId(); // Check if we received a valid HEADERS frame if (spdyHeadersFrame.isInvalid()) { - issueStreamError(ctx, streamID, SpdyStreamStatus.PROTOCOL_ERROR, out); + issueStreamError(ctx, streamId, SpdyStreamStatus.PROTOCOL_ERROR, out); return; } - if (spdySession.isRemoteSideClosed(streamID)) { - issueStreamError(ctx, streamID, SpdyStreamStatus.INVALID_STREAM, out); + if (spdySession.isRemoteSideClosed(streamId)) { + issueStreamError(ctx, streamId, SpdyStreamStatus.INVALID_STREAM, out); return; } // Close the remote side of the stream if this is the last frame if (spdyHeadersFrame.isLast()) { - halfCloseStream(streamID, true); + halfCloseStream(streamId, true); } } else if (msg instanceof SpdyWindowUpdateFrame) { @@ -383,21 +385,21 @@ public class SpdySessionHandler if (flowControl) { SpdyWindowUpdateFrame spdyWindowUpdateFrame = (SpdyWindowUpdateFrame) msg; - int streamID = spdyWindowUpdateFrame.getStreamId(); + int streamId = spdyWindowUpdateFrame.getStreamId(); int deltaWindowSize = spdyWindowUpdateFrame.getDeltaWindowSize(); // Ignore frames for half-closed streams - if (spdySession.isLocalSideClosed(streamID)) { + if (spdySession.isLocalSideClosed(streamId)) { return; } // Check for numerical overflow - if (spdySession.getSendWindowSize(streamID) > Integer.MAX_VALUE - deltaWindowSize) { - issueStreamError(ctx, streamID, SpdyStreamStatus.FLOW_CONTROL_ERROR, out); + if (spdySession.getSendWindowSize(streamId) > Integer.MAX_VALUE - deltaWindowSize) { + issueStreamError(ctx, streamId, SpdyStreamStatus.FLOW_CONTROL_ERROR, out); return; } - updateSendWindowSize(streamID, deltaWindowSize, out); + updateSendWindowSize(streamId, deltaWindowSize, out); } } @@ -459,10 +461,10 @@ public class SpdySessionHandler if (msg instanceof SpdyDataFrame) { SpdyDataFrame spdyDataFrame = (SpdyDataFrame) msg; - final int streamID = spdyDataFrame.getStreamId(); + final int streamId = spdyDataFrame.getStreamId(); // Frames must not be sent on half-closed streams - if (spdySession.isLocalSideClosed(streamID)) { + if (spdySession.isLocalSideClosed(streamId)) { throw PROTOCOL_EXCEPTION; } @@ -482,22 +484,22 @@ public class SpdySessionHandler if (flowControl) { synchronized (flowControlLock) { int dataLength = spdyDataFrame.content().readableBytes(); - int sendWindowSize = spdySession.getSendWindowSize(streamID); + int sendWindowSize = spdySession.getSendWindowSize(streamId); if (sendWindowSize <= 0) { // Stream is stalled -- enqueue Data frame and return - spdySession.putPendingWrite(streamID, spdyDataFrame); + spdySession.putPendingWrite(streamId, spdyDataFrame); return; } else if (sendWindowSize < dataLength) { // Stream is not stalled but we cannot send the entire frame - spdySession.updateSendWindowSize(streamID, -1 * sendWindowSize); + spdySession.updateSendWindowSize(streamId, -1 * sendWindowSize); // Create a partial data frame whose length is the current window size - SpdyDataFrame partialDataFrame = new DefaultSpdyDataFrame(streamID, + SpdyDataFrame partialDataFrame = new DefaultSpdyDataFrame(streamId, spdyDataFrame.content().readSlice(sendWindowSize).retain()); // Enqueue the remaining data (will be the first frame queued) - spdySession.putPendingWrite(streamID, spdyDataFrame); + spdySession.putPendingWrite(streamId, spdyDataFrame); // The transfer window size is pre-decremented when sending a data frame downstream. // Close the stream on write failures that leaves the transfer window in a corrupt state. @@ -511,7 +513,7 @@ public class SpdySessionHandler // @Override // public void operationComplete(ChannelFuture future) throws Exception { // if (!future.isSuccess()) { - // issueStreamError(context, streamID, SpdyStreamStatus.INTERNAL_ERROR); + // issueStreamError(context, streamId, SpdyStreamStatus.INTERNAL_ERROR); // } // } //}); @@ -520,7 +522,7 @@ public class SpdySessionHandler return; } else { // Window size is large enough to send entire data frame - spdySession.updateSendWindowSize(streamID, -1 * dataLength); + spdySession.updateSendWindowSize(streamId, -1 * dataLength); // The transfer window size is pre-decremented when sending a data frame downstream. // Close the stream on write failures that leaves the transfer window in a corrupt state. @@ -533,7 +535,7 @@ public class SpdySessionHandler // @Override // public void operationComplete(ChannelFuture future) throws Exception { // if (!future.isSuccess()) { - // issueStreamError(context, streamID, SpdyStreamStatus.INTERNAL_ERROR); + // issueStreamError(context, streamId, SpdyStreamStatus.INTERNAL_ERROR); // } // } //}); @@ -543,38 +545,38 @@ public class SpdySessionHandler // Close the local side of the stream if this is the last frame if (spdyDataFrame.isLast()) { - halfCloseStream(streamID, false); + halfCloseStream(streamId, false); } } else if (msg instanceof SpdySynStreamFrame) { SpdySynStreamFrame spdySynStreamFrame = (SpdySynStreamFrame) msg; - int streamID = spdySynStreamFrame.getStreamId(); + int streamId = spdySynStreamFrame.getStreamId(); - if (isRemoteInitiatedID(streamID)) { + if (isRemoteInitiatedID(streamId)) { throw PROTOCOL_EXCEPTION; } byte priority = spdySynStreamFrame.getPriority(); boolean remoteSideClosed = spdySynStreamFrame.isUnidirectional(); boolean localSideClosed = spdySynStreamFrame.isLast(); - if (!acceptStream(streamID, priority, remoteSideClosed, localSideClosed)) { + if (!acceptStream(streamId, priority, remoteSideClosed, localSideClosed)) { throw PROTOCOL_EXCEPTION; } } else if (msg instanceof SpdySynReplyFrame) { SpdySynReplyFrame spdySynReplyFrame = (SpdySynReplyFrame) msg; - int streamID = spdySynReplyFrame.getStreamId(); + int streamId = spdySynReplyFrame.getStreamId(); // Frames must not be sent on half-closed streams - if (!isRemoteInitiatedID(streamID) || spdySession.isLocalSideClosed(streamID)) { + if (!isRemoteInitiatedID(streamId) || spdySession.isLocalSideClosed(streamId)) { throw PROTOCOL_EXCEPTION; } // Close the local side of the stream if this is the last frame if (spdySynReplyFrame.isLast()) { - halfCloseStream(streamID, false); + halfCloseStream(streamId, false); } } else if (msg instanceof SpdyRstStreamFrame) { @@ -627,16 +629,16 @@ public class SpdySessionHandler } else if (msg instanceof SpdyHeadersFrame) { SpdyHeadersFrame spdyHeadersFrame = (SpdyHeadersFrame) msg; - int streamID = spdyHeadersFrame.getStreamId(); + int streamId = spdyHeadersFrame.getStreamId(); // Frames must not be sent on half-closed streams - if (spdySession.isLocalSideClosed(streamID)) { + if (spdySession.isLocalSideClosed(streamId)) { throw PROTOCOL_EXCEPTION; } // Close the local side of the stream if this is the last frame if (spdyHeadersFrame.isLast()) { - halfCloseStream(streamID, false); + halfCloseStream(streamId, false); } } else if (msg instanceof SpdyWindowUpdateFrame) { @@ -675,12 +677,11 @@ public class SpdySessionHandler * Note: this is only called by the worker thread */ private void issueStreamError( - ChannelHandlerContext ctx, int streamID, SpdyStreamStatus status, MessageList in) { + ChannelHandlerContext ctx, int streamId, SpdyStreamStatus status, MessageList in) { + boolean fireMessageReceived = !spdySession.isRemoteSideClosed(streamId); + removeStream(ctx, streamId); - boolean fireMessageReceived = !spdySession.isRemoteSideClosed(streamID); - removeStream(ctx, streamID); - - SpdyRstStreamFrame spdyRstStreamFrame = new DefaultSpdyRstStreamFrame(streamID, status); + SpdyRstStreamFrame spdyRstStreamFrame = new DefaultSpdyRstStreamFrame(streamId, status); ctx.write(spdyRstStreamFrame); if (fireMessageReceived) { in.add(spdyRstStreamFrame); @@ -694,8 +695,8 @@ public class SpdySessionHandler */ private boolean isRemoteInitiatedID(int id) { - boolean serverID = SpdyCodecUtil.isServerId(id); - return server && !serverID || !server && serverID; + boolean serverId = SpdyCodecUtil.isServerId(id); + return server && !serverId || !server && serverId; } private void updateConcurrentStreams(int newConcurrentStreams, boolean remote) { @@ -741,7 +742,7 @@ public class SpdySessionHandler // need to synchronize accesses to sentGoAwayFrame, lastGoodStreamId, and initial window sizes private synchronized boolean acceptStream( - int streamID, byte priority, boolean remoteSideClosed, boolean localSideClosed) { + int streamId, byte priority, boolean remoteSideClosed, boolean localSideClosed) { // Cannot initiate any new streams after receiving or sending GOAWAY if (receivedGoAwayFrame || sentGoAwayFrame) { return false; @@ -753,27 +754,27 @@ public class SpdySessionHandler return false; } spdySession.acceptStream( - streamID, priority, remoteSideClosed, localSideClosed, + streamId, priority, remoteSideClosed, localSideClosed, initialSendWindowSize, initialReceiveWindowSize); - if (isRemoteInitiatedID(streamID)) { - lastGoodStreamId = streamID; + if (isRemoteInitiatedID(streamId)) { + lastGoodStreamId = streamId; } return true; } - private void halfCloseStream(int streamID, boolean remote) { + private void halfCloseStream(int streamId, boolean remote) { if (remote) { - spdySession.closeRemoteSide(streamID); + spdySession.closeRemoteSide(streamId); } else { - spdySession.closeLocalSide(streamID); + spdySession.closeLocalSide(streamId); } if (closeSessionFuture != null && spdySession.noActiveStreams()) { closeSessionFuture.trySuccess(); } } - private void removeStream(ChannelHandlerContext ctx, int streamID) { - if (spdySession.removeStream(streamID)) { + private void removeStream(ChannelHandlerContext ctx, int streamId) { + if (spdySession.removeStream(streamId)) { ctx.fireExceptionCaught(STREAM_CLOSED); } @@ -782,13 +783,13 @@ public class SpdySessionHandler } } - private void updateSendWindowSize(final int streamID, int deltaWindowSize, MessageList out) { + private void updateSendWindowSize(final int streamId, int deltaWindowSize, MessageList out) { synchronized (flowControlLock) { - int newWindowSize = spdySession.updateSendWindowSize(streamID, deltaWindowSize); + int newWindowSize = spdySession.updateSendWindowSize(streamId, deltaWindowSize); while (newWindowSize > 0) { // Check if we have unblocked a stalled stream - SpdyDataFrame spdyDataFrame = (SpdyDataFrame) spdySession.getPendingWrite(streamID); + SpdyDataFrame spdyDataFrame = (SpdyDataFrame) spdySession.getPendingWrite(streamId); if (spdyDataFrame == null) { break; } @@ -797,8 +798,8 @@ public class SpdySessionHandler if (newWindowSize >= dataFrameSize) { // Window size is large enough to send entire data frame - spdySession.removePendingWrite(streamID); - newWindowSize = spdySession.updateSendWindowSize(streamID, -1 * dataFrameSize); + spdySession.removePendingWrite(streamId); + newWindowSize = spdySession.updateSendWindowSize(streamId, -1 * dataFrameSize); // The transfer window size is pre-decremented when sending a data frame downstream. // Close the stream on write failures that leaves the transfer window in a corrupt state. @@ -811,23 +812,23 @@ public class SpdySessionHandler // @Override // public void operationComplete(ChannelFuture future) throws Exception { // if (!future.isSuccess()) { - // issueStreamError(context, streamID, SpdyStreamStatus.INTERNAL_ERROR); + // issueStreamError(context, streamId, SpdyStreamStatus.INTERNAL_ERROR); // } // } //}); // Close the local side of the stream if this is the last frame if (spdyDataFrame.isLast()) { - halfCloseStream(streamID, false); + halfCloseStream(streamId, false); } out.add(spdyDataFrame); } else { // We can send a partial frame - spdySession.updateSendWindowSize(streamID, -1 * newWindowSize); + spdySession.updateSendWindowSize(streamId, -1 * newWindowSize); // Create a partial data frame whose length is the current window size - SpdyDataFrame partialDataFrame = new DefaultSpdyDataFrame(streamID, + SpdyDataFrame partialDataFrame = new DefaultSpdyDataFrame(streamId, spdyDataFrame.content().readSlice(newWindowSize).retain()); // The transfer window size is pre-decremented when sending a data frame downstream. @@ -842,7 +843,7 @@ public class SpdySessionHandler // @Override // public void operationComplete(ChannelFuture future) throws Exception { // if (!future.isSuccess()) { - // issueStreamError(context, streamID, SpdyStreamStatus.INTERNAL_ERROR); + // issueStreamError(context, streamId, SpdyStreamStatus.INTERNAL_ERROR); // } // } //}); diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdySessionStatus.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdySessionStatus.java index 120b509eeb..577f99f390 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdySessionStatus.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdySessionStatus.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 @@ -16,7 +16,7 @@ package io.netty.handler.codec.spdy; /** - * The SPDY session getStatus code and its description. + * The SPDY session status code and its description. */ public class SpdySessionStatus implements Comparable { @@ -40,7 +40,7 @@ public class SpdySessionStatus implements Comparable { /** * Returns the {@link SpdySessionStatus} represented by the specified code. - * If the specified code is a defined SPDY getStatus code, a cached instance + * If the specified code is a defined SPDY status code, a cached instance * will be returned. Otherwise, a new instance will be returned. */ public static SpdySessionStatus valueOf(int code) { @@ -74,14 +74,14 @@ public class SpdySessionStatus implements Comparable { } /** - * Returns the code of this getStatus. + * Returns the code of this status. */ public int getCode() { return code; } /** - * Returns the getStatus phrase of this getStatus. + * Returns the status phrase of this status. */ public String getStatusPhrase() { return statusPhrase; diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdySettingsFrame.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdySettingsFrame.java index d60154698a..6cdbb8afa4 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdySettingsFrame.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdySettingsFrame.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 @@ -18,9 +18,9 @@ package io.netty.handler.codec.spdy; import java.util.Set; /** - * A SPDY Protocol SETTINGS Control Frame + * A SPDY Protocol SETTINGS Frame */ -public interface SpdySettingsFrame extends SpdyControlFrame { +public interface SpdySettingsFrame extends SpdyFrame { int SETTINGS_UPLOAD_BANDWIDTH = 1; int SETTINGS_DOWNLOAD_BANDWIDTH = 2; diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyStreamFrame.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyStreamFrame.java index 9482efd811..e5299f9ae9 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyStreamFrame.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyStreamFrame.java @@ -16,9 +16,9 @@ package io.netty.handler.codec.spdy; /** - * A frame which is part of a stream + * A SPDY Protocol Frame that is associated with an individual SPDY Stream */ -public interface SpdyStreamFrame { +public interface SpdyStreamFrame extends SpdyFrame { /** * Returns the Stream-ID of this frame. diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyStreamStatus.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyStreamStatus.java index 4487fa8c52..ccb0d814d2 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyStreamStatus.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyStreamStatus.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 @@ -16,7 +16,7 @@ package io.netty.handler.codec.spdy; /** - * The SPDY stream getStatus code and its description. + * The SPDY stream status code and its description. */ public class SpdyStreamStatus implements Comparable { @@ -88,13 +88,13 @@ public class SpdyStreamStatus implements Comparable { /** * Returns the {@link SpdyStreamStatus} represented by the specified code. - * If the specified code is a defined SPDY getStatus code, a cached instance + * If the specified code is a defined SPDY status code, a cached instance * will be returned. Otherwise, a new instance will be returned. */ public static SpdyStreamStatus valueOf(int code) { if (code == 0) { throw new IllegalArgumentException( - "0 is not a valid getStatus code for a RST_STREAM"); + "0 is not a valid status code for a RST_STREAM"); } switch (code) { @@ -136,7 +136,7 @@ public class SpdyStreamStatus implements Comparable { public SpdyStreamStatus(int code, String statusPhrase) { if (code == 0) { throw new IllegalArgumentException( - "0 is not a valid getStatus code for a RST_STREAM"); + "0 is not a valid status code for a RST_STREAM"); } if (statusPhrase == null) { @@ -148,14 +148,14 @@ public class SpdyStreamStatus implements Comparable { } /** - * Returns the code of this getStatus. + * Returns the code of this status. */ public int getCode() { return code; } /** - * Returns the getStatus phrase of this getStatus. + * Returns the status phrase of this status. */ public String getStatusPhrase() { return statusPhrase; diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdySynReplyFrame.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdySynReplyFrame.java index ff399b6f44..4bce003620 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdySynReplyFrame.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdySynReplyFrame.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 @@ -16,9 +16,9 @@ package io.netty.handler.codec.spdy; /** - * A SPDY Protocol SYN_REPLY Control Frame + * A SPDY Protocol SYN_REPLY Frame */ -public interface SpdySynReplyFrame extends SpdyHeaderBlock, SpdyControlFrame, SpdyStreamFrame { +public interface SpdySynReplyFrame extends SpdyHeadersFrame { @Override SpdySynReplyFrame setStreamId(int streamID); diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdySynStreamFrame.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdySynStreamFrame.java index dba39b01c4..b4e6331f02 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdySynStreamFrame.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdySynStreamFrame.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 @@ -16,9 +16,9 @@ package io.netty.handler.codec.spdy; /** - * A SPDY Protocol SYN_STREAM Control Frame + * A SPDY Protocol SYN_STREAM Frame */ -public interface SpdySynStreamFrame extends SpdyHeaderBlock, SpdyControlFrame , SpdyStreamFrame { +public interface SpdySynStreamFrame extends SpdyHeadersFrame { /** * Returns the Associated-To-Stream-ID of this frame. diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyWindowUpdateFrame.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyWindowUpdateFrame.java index 86fe94faa6..587b1f66d2 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyWindowUpdateFrame.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyWindowUpdateFrame.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 @@ -16,9 +16,9 @@ package io.netty.handler.codec.spdy; /** - * A SPDY Protocol WINDOW_UPDATE Control Frame + * A SPDY Protocol WINDOW_UPDATE Frame */ -public interface SpdyWindowUpdateFrame extends SpdyControlFrame { +public interface SpdyWindowUpdateFrame extends SpdyFrame { /** * Returns the Stream-ID of this frame. @@ -26,7 +26,7 @@ public interface SpdyWindowUpdateFrame extends SpdyControlFrame { int getStreamId(); /** - * Sets the Stream-ID of this frame. The Stream-ID must be positive. + * Sets the Stream-ID of this frame. The Stream-ID cannot be negative. */ SpdyWindowUpdateFrame setStreamId(int streamID); 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 7515ceb888..701d62eb53 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 @@ -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 @@ -18,6 +18,7 @@ package io.netty.handler.codec.spdy; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.MessageList; +import io.netty.channel.SimpleChannelInboundHandler; import io.netty.channel.embedded.EmbeddedChannel; import io.netty.util.internal.logging.InternalLogger; import io.netty.util.internal.logging.InternalLoggerFactory; @@ -40,40 +41,25 @@ public class SpdySessionHandlerTest { closeMessage.setValue(closeSignal, 0); } - private static void assertHeaderBlock(SpdyHeaderBlock received, SpdyHeaderBlock expected) { - for (String name: expected.headers().names()) { - List expectedValues = expected.headers().getAll(name); - List receivedValues = received.headers().getAll(name); - assertTrue(receivedValues.containsAll(expectedValues)); - receivedValues.removeAll(expectedValues); - assertTrue(receivedValues.isEmpty()); - received.headers().remove(name); - } - assertTrue(received.headers().entries().isEmpty()); - } - - private static void assertDataFrame(Object msg, int streamID, boolean last) { + private static void assertDataFrame(Object msg, int streamId, boolean last) { assertNotNull(msg); assertTrue(msg instanceof SpdyDataFrame); SpdyDataFrame spdyDataFrame = (SpdyDataFrame) msg; - assertEquals(spdyDataFrame.getStreamId(), streamID); + assertEquals(spdyDataFrame.getStreamId(), streamId); assertEquals(spdyDataFrame.isLast(), last); } - private static void assertSynReply(Object msg, int streamID, boolean last, SpdyHeaderBlock headers) { + private static void assertSynReply(Object msg, int streamId, boolean last, SpdyHeaders headers) { assertNotNull(msg); assertTrue(msg instanceof SpdySynReplyFrame); - SpdySynReplyFrame spdySynReplyFrame = (SpdySynReplyFrame) msg; - assertEquals(spdySynReplyFrame.getStreamId(), streamID); - assertEquals(spdySynReplyFrame.isLast(), last); - assertHeaderBlock(spdySynReplyFrame, headers); + assertHeaders(msg, streamId, last, headers); } - private static void assertRstStream(Object msg, int streamID, SpdyStreamStatus status) { + private static void assertRstStream(Object msg, int streamId, SpdyStreamStatus status) { assertNotNull(msg); assertTrue(msg instanceof SpdyRstStreamFrame); SpdyRstStreamFrame spdyRstStreamFrame = (SpdyRstStreamFrame) msg; - assertEquals(spdyRstStreamFrame.getStreamId(), streamID); + assertEquals(spdyRstStreamFrame.getStreamId(), streamId); assertEquals(spdyRstStreamFrame.getStatus(), status); } @@ -84,19 +70,28 @@ public class SpdySessionHandlerTest { assertEquals(spdyPingFrame.getId(), id); } - private static void assertGoAway(Object msg, int lastGoodStreamID) { + private static void assertGoAway(Object msg, int lastGoodStreamId) { assertNotNull(msg); assertTrue(msg instanceof SpdyGoAwayFrame); SpdyGoAwayFrame spdyGoAwayFrame = (SpdyGoAwayFrame) msg; - assertEquals(spdyGoAwayFrame.getLastGoodStreamId(), lastGoodStreamID); + assertEquals(spdyGoAwayFrame.getLastGoodStreamId(), lastGoodStreamId); } - private static void assertHeaders(Object msg, int streamID, SpdyHeaderBlock headers) { + private static void assertHeaders(Object msg, int streamId, boolean last, SpdyHeaders headers) { assertNotNull(msg); assertTrue(msg instanceof SpdyHeadersFrame); SpdyHeadersFrame spdyHeadersFrame = (SpdyHeadersFrame) msg; - assertEquals(spdyHeadersFrame.getStreamId(), streamID); - assertHeaderBlock(spdyHeadersFrame, headers); + assertEquals(spdyHeadersFrame.getStreamId(), streamId); + assertEquals(spdyHeadersFrame.isLast(), last); + for (String name: headers.names()) { + List expectedValues = headers.getAll(name); + List receivedValues = spdyHeadersFrame.headers().getAll(name); + assertTrue(receivedValues.containsAll(expectedValues)); + receivedValues.removeAll(expectedValues); + assertTrue(receivedValues.isEmpty()); + spdyHeadersFrame.headers().remove(name); + } + assertTrue(spdyHeadersFrame.headers().entries().isEmpty()); } private static void testSpdySessionHandler(int version, boolean server) { @@ -107,71 +102,71 @@ public class SpdySessionHandlerTest { continue; } - int localStreamID = server ? 1 : 2; - int remoteStreamID = server ? 2 : 1; + int localStreamId = server ? 1 : 2; + int remoteStreamId = server ? 2 : 1; - SpdyPingFrame localPingFrame = new DefaultSpdyPingFrame(localStreamID); - SpdyPingFrame remotePingFrame = new DefaultSpdyPingFrame(remoteStreamID); + SpdyPingFrame localPingFrame = new DefaultSpdyPingFrame(localStreamId); + SpdyPingFrame remotePingFrame = new DefaultSpdyPingFrame(remoteStreamId); SpdySynStreamFrame spdySynStreamFrame = - new DefaultSpdySynStreamFrame(localStreamID, 0, (byte) 0); + new DefaultSpdySynStreamFrame(localStreamId, 0, (byte) 0); spdySynStreamFrame.headers().set("Compression", "test"); - SpdyDataFrame spdyDataFrame = new DefaultSpdyDataFrame(localStreamID); + SpdyDataFrame spdyDataFrame = new DefaultSpdyDataFrame(localStreamId); spdyDataFrame.setLast(true); // Check if session handler returns INVALID_STREAM if it receives // a data frame for a Stream-ID that is not open - sessionHandler.writeInbound(new DefaultSpdyDataFrame(localStreamID)); - assertRstStream(sessionHandler.readOutbound(), localStreamID, SpdyStreamStatus.INVALID_STREAM); + sessionHandler.writeInbound(new DefaultSpdyDataFrame(localStreamId)); + assertRstStream(sessionHandler.readOutbound(), localStreamId, SpdyStreamStatus.INVALID_STREAM); assertNull(sessionHandler.readOutbound()); // Check if session handler returns PROTOCOL_ERROR if it receives // a data frame for a Stream-ID before receiving a SYN_REPLY frame - sessionHandler.writeInbound(new DefaultSpdyDataFrame(remoteStreamID)); - assertRstStream(sessionHandler.readOutbound(), remoteStreamID, SpdyStreamStatus.PROTOCOL_ERROR); + sessionHandler.writeInbound(new DefaultSpdyDataFrame(remoteStreamId)); + assertRstStream(sessionHandler.readOutbound(), remoteStreamId, SpdyStreamStatus.PROTOCOL_ERROR); assertNull(sessionHandler.readOutbound()); - remoteStreamID += 2; + remoteStreamId += 2; // Check if session handler returns PROTOCOL_ERROR if it receives // multiple SYN_REPLY frames for the same active Stream-ID - sessionHandler.writeInbound(new DefaultSpdySynReplyFrame(remoteStreamID)); + sessionHandler.writeInbound(new DefaultSpdySynReplyFrame(remoteStreamId)); assertNull(sessionHandler.readOutbound()); - sessionHandler.writeInbound(new DefaultSpdySynReplyFrame(remoteStreamID)); - assertRstStream(sessionHandler.readOutbound(), remoteStreamID, SpdyStreamStatus.STREAM_IN_USE); + sessionHandler.writeInbound(new DefaultSpdySynReplyFrame(remoteStreamId)); + assertRstStream(sessionHandler.readOutbound(), remoteStreamId, SpdyStreamStatus.STREAM_IN_USE); assertNull(sessionHandler.readOutbound()); - remoteStreamID += 2; + remoteStreamId += 2; // Check if frame codec correctly compresses/uncompresses headers sessionHandler.writeInbound(spdySynStreamFrame); - assertSynReply(sessionHandler.readOutbound(), localStreamID, false, spdySynStreamFrame); + assertSynReply(sessionHandler.readOutbound(), localStreamId, false, spdySynStreamFrame.headers()); assertNull(sessionHandler.readOutbound()); - SpdyHeadersFrame spdyHeadersFrame = new DefaultSpdyHeadersFrame(localStreamID); + SpdyHeadersFrame spdyHeadersFrame = new DefaultSpdyHeadersFrame(localStreamId); spdyHeadersFrame.headers().add("HEADER", "test1"); spdyHeadersFrame.headers().add("HEADER", "test2"); sessionHandler.writeInbound(spdyHeadersFrame); - assertHeaders(sessionHandler.readOutbound(), localStreamID, spdyHeadersFrame); + assertHeaders(sessionHandler.readOutbound(), localStreamId, false, spdyHeadersFrame.headers()); assertNull(sessionHandler.readOutbound()); - localStreamID += 2; + localStreamId += 2; // Check if session handler closed the streams using the number // of concurrent streams and that it returns REFUSED_STREAM // if it receives a SYN_STREAM frame it does not wish to accept - spdySynStreamFrame.setStreamId(localStreamID); + spdySynStreamFrame.setStreamId(localStreamId); spdySynStreamFrame.setLast(true); spdySynStreamFrame.setUnidirectional(true); sessionHandler.writeInbound(spdySynStreamFrame); - assertRstStream(sessionHandler.readOutbound(), localStreamID, SpdyStreamStatus.REFUSED_STREAM); + assertRstStream(sessionHandler.readOutbound(), localStreamId, SpdyStreamStatus.REFUSED_STREAM); assertNull(sessionHandler.readOutbound()); // Check if session handler drops active streams if it receives // a RST_STREAM frame for that Stream-ID - sessionHandler.writeInbound(new DefaultSpdyRstStreamFrame(remoteStreamID, 3)); + sessionHandler.writeInbound(new DefaultSpdyRstStreamFrame(remoteStreamId, 3)); assertNull(sessionHandler.readOutbound()); - remoteStreamID += 2; + remoteStreamId += 2; // Check if session handler honors UNIDIRECTIONAL streams spdySynStreamFrame.setLast(false); @@ -182,17 +177,17 @@ public class SpdySessionHandlerTest { // Check if session handler returns PROTOCOL_ERROR if it receives // multiple SYN_STREAM frames for the same active Stream-ID sessionHandler.writeInbound(spdySynStreamFrame); - assertRstStream(sessionHandler.readOutbound(), localStreamID, SpdyStreamStatus.PROTOCOL_ERROR); + assertRstStream(sessionHandler.readOutbound(), localStreamId, SpdyStreamStatus.PROTOCOL_ERROR); assertNull(sessionHandler.readOutbound()); - localStreamID += 2; + localStreamId += 2; // Check if session handler returns PROTOCOL_ERROR if it receives // a SYN_STREAM frame with an invalid Stream-ID - spdySynStreamFrame.setStreamId(localStreamID - 1); + spdySynStreamFrame.setStreamId(localStreamId - 1); sessionHandler.writeInbound(spdySynStreamFrame); - assertRstStream(sessionHandler.readOutbound(), localStreamID - 1, SpdyStreamStatus.PROTOCOL_ERROR); + assertRstStream(sessionHandler.readOutbound(), localStreamId - 1, SpdyStreamStatus.PROTOCOL_ERROR); assertNull(sessionHandler.readOutbound()); - spdySynStreamFrame.setStreamId(localStreamID); + spdySynStreamFrame.setStreamId(localStreamId); // Check if session handler correctly limits the number of // concurrent streams in the SETTINGS frame @@ -201,33 +196,33 @@ public class SpdySessionHandlerTest { sessionHandler.writeInbound(spdySettingsFrame); assertNull(sessionHandler.readOutbound()); sessionHandler.writeInbound(spdySynStreamFrame); - assertRstStream(sessionHandler.readOutbound(), localStreamID, SpdyStreamStatus.REFUSED_STREAM); + assertRstStream(sessionHandler.readOutbound(), localStreamId, SpdyStreamStatus.REFUSED_STREAM); assertNull(sessionHandler.readOutbound()); spdySettingsFrame.setValue(SpdySettingsFrame.SETTINGS_MAX_CONCURRENT_STREAMS, 4); sessionHandler.writeInbound(spdySettingsFrame); assertNull(sessionHandler.readOutbound()); sessionHandler.writeInbound(spdySynStreamFrame); - assertSynReply(sessionHandler.readOutbound(), localStreamID, false, spdySynStreamFrame); + assertSynReply(sessionHandler.readOutbound(), localStreamId, false, spdySynStreamFrame.headers()); assertNull(sessionHandler.readOutbound()); // Check if session handler rejects HEADERS for closed streams - int testStreamID = spdyDataFrame.getStreamId(); + int testStreamId = spdyDataFrame.getStreamId(); sessionHandler.writeInbound(spdyDataFrame); - assertDataFrame(sessionHandler.readOutbound(), testStreamID, spdyDataFrame.isLast()); + assertDataFrame(sessionHandler.readOutbound(), testStreamId, spdyDataFrame.isLast()); assertNull(sessionHandler.readOutbound()); - spdyHeadersFrame.setStreamId(testStreamID); + spdyHeadersFrame.setStreamId(testStreamId); sessionHandler.writeInbound(spdyHeadersFrame); - assertRstStream(sessionHandler.readOutbound(), testStreamID, SpdyStreamStatus.INVALID_STREAM); + assertRstStream(sessionHandler.readOutbound(), testStreamId, SpdyStreamStatus.INVALID_STREAM); assertNull(sessionHandler.readOutbound()); // Check if session handler returns PROTOCOL_ERROR if it receives // an invalid HEADERS frame - spdyHeadersFrame.setStreamId(localStreamID); + spdyHeadersFrame.setStreamId(localStreamId); spdyHeadersFrame.setInvalid(); sessionHandler.writeInbound(spdyHeadersFrame); - assertRstStream(sessionHandler.readOutbound(), localStreamID, SpdyStreamStatus.PROTOCOL_ERROR); + assertRstStream(sessionHandler.readOutbound(), localStreamId, SpdyStreamStatus.PROTOCOL_ERROR); assertNull(sessionHandler.readOutbound()); // Check if session handler returns identical local PINGs @@ -241,20 +236,20 @@ public class SpdySessionHandlerTest { // Check if session handler sends a GOAWAY frame when closing sessionHandler.writeInbound(closeMessage); - assertGoAway(sessionHandler.readOutbound(), localStreamID); + assertGoAway(sessionHandler.readOutbound(), localStreamId); assertNull(sessionHandler.readOutbound()); - localStreamID += 2; + localStreamId += 2; // Check if session handler returns REFUSED_STREAM if it receives // SYN_STREAM frames after sending a GOAWAY frame - spdySynStreamFrame.setStreamId(localStreamID); + spdySynStreamFrame.setStreamId(localStreamId); sessionHandler.writeInbound(spdySynStreamFrame); - assertRstStream(sessionHandler.readOutbound(), localStreamID, SpdyStreamStatus.REFUSED_STREAM); + assertRstStream(sessionHandler.readOutbound(), localStreamId, SpdyStreamStatus.REFUSED_STREAM); assertNull(sessionHandler.readOutbound()); // Check if session handler ignores Data frames after sending // a GOAWAY frame - spdyDataFrame.setStreamId(localStreamID); + spdyDataFrame.setStreamId(localStreamId); sessionHandler.writeInbound(spdyDataFrame); assertNull(sessionHandler.readOutbound()); @@ -279,7 +274,7 @@ public class SpdySessionHandlerTest { // Echo Handler opens 4 half-closed streams on session connection // and then sets the number of concurrent streams to 3 - private static class EchoHandler extends ChannelInboundHandlerAdapter { + private static class EchoHandler extends SimpleChannelInboundHandler { private final int closeSignal; private final boolean server; @@ -291,9 +286,9 @@ public class SpdySessionHandlerTest { @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { // Initiate 4 new streams - int streamID = server ? 2 : 1; + int streamId = server ? 2 : 1; SpdySynStreamFrame spdySynStreamFrame = - new DefaultSpdySynStreamFrame(streamID, 0, (byte) 0); + new DefaultSpdySynStreamFrame(streamId, 0, (byte) 0); spdySynStreamFrame.setLast(true); ctx.write(spdySynStreamFrame); spdySynStreamFrame.setStreamId(spdySynStreamFrame.getStreamId() + 2); @@ -310,38 +305,39 @@ public class SpdySessionHandlerTest { } @Override - public void messageReceived(ChannelHandlerContext ctx, MessageList messages) throws Exception { - for (int i = 0; i < messages.size(); i++) { - Object msg = messages.get(i); - if (msg instanceof SpdyDataFrame || - msg instanceof SpdyPingFrame || - msg instanceof SpdyHeadersFrame) { + public void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception { + if (msg instanceof SpdySynStreamFrame) { - ctx.write(msg); - return; - } - - if (msg instanceof SpdySynStreamFrame) { - - SpdySynStreamFrame spdySynStreamFrame = (SpdySynStreamFrame) msg; - if (!spdySynStreamFrame.isUnidirectional()) { - int streamID = spdySynStreamFrame.getStreamId(); - SpdySynReplyFrame spdySynReplyFrame = new DefaultSpdySynReplyFrame(streamID); - spdySynReplyFrame.setLast(spdySynStreamFrame.isLast()); - for (Map.Entry entry: spdySynStreamFrame.headers()) { - spdySynReplyFrame.headers().add(entry.getKey(), entry.getValue()); - } - - ctx.write(spdySynReplyFrame); + SpdySynStreamFrame spdySynStreamFrame = (SpdySynStreamFrame) msg; + if (!spdySynStreamFrame.isUnidirectional()) { + int streamId = spdySynStreamFrame.getStreamId(); + SpdySynReplyFrame spdySynReplyFrame = new DefaultSpdySynReplyFrame(streamId); + spdySynReplyFrame.setLast(spdySynStreamFrame.isLast()); + for (Map.Entry entry: spdySynStreamFrame.headers()) { + spdySynReplyFrame.headers().add(entry.getKey(), entry.getValue()); } - return; - } - if (msg instanceof SpdySettingsFrame) { - SpdySettingsFrame spdySettingsFrame = (SpdySettingsFrame) msg; - if (spdySettingsFrame.isSet(closeSignal)) { - ctx.close(); - } + ctx.write(spdySynReplyFrame); + } + return; + } + + if (msg instanceof SpdySynReplyFrame) { + return; + } + + if (msg instanceof SpdyDataFrame || + msg instanceof SpdyPingFrame || + msg instanceof SpdyHeadersFrame) { + + ctx.write(msg); + return; + } + + if (msg instanceof SpdySettingsFrame) { + SpdySettingsFrame spdySettingsFrame = (SpdySettingsFrame) msg; + if (spdySettingsFrame.isSet(closeSignal)) { + ctx.close(); } } }