SPDY: update object hierarchy

This commit is contained in:
Jeff Pinner 2013-06-04 14:32:11 -07:00 committed by Norman Maurer
parent 7f7bf304b0
commit c8ca329932
36 changed files with 531 additions and 682 deletions

View File

@ -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) {

View File

@ -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();
}
}

View File

@ -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<String, String> e: headers().entries()) {
buf.append(" ");
buf.append(e.getKey());
buf.append(": ");
buf.append(e.getValue());
buf.append(StringUtil.NEWLINE);
}
}
}

View File

@ -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<String, String> e: headers().entries()) {
buf.append(" ");
buf.append(e.getKey());
buf.append(": ");
buf.append(e.getValue());
buf.append(StringUtil.NEWLINE);
}
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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);

View File

@ -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();
}
}

View File

@ -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
}

View File

@ -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);

View File

@ -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
}

View File

@ -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<SpdyFrameDecoder, SpdyFrameEncoder> {
/**
* Creates a new instance with the specified {@code version} and
* the default decoder and encoder options

View File

@ -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 ++;

View File

@ -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<SpdyDataOrControlFrame> {
public class SpdyFrameEncoder extends MessageToByteEncoder<SpdyFrame> {
private final int version;
private volatile boolean finished;
@ -76,7 +76,7 @@ public class SpdyFrameEncoder extends MessageToByteEncoder<SpdyDataOrControlFram
}
@Override
protected void encode(ChannelHandlerContext ctx, SpdyDataOrControlFrame msg, ByteBuf out) throws Exception {
protected void encode(ChannelHandlerContext ctx, SpdyFrame msg, ByteBuf out) throws Exception {
if (msg instanceof SpdyDataFrame) {
SpdyDataFrame spdyDataFrame = (SpdyDataFrame) msg;
@ -202,13 +202,6 @@ public class SpdyFrameEncoder extends MessageToByteEncoder<SpdyDataOrControlFram
out.writeInt(spdySettingsFrame.getValue(id));
}
} else if (msg instanceof SpdyNoOpFrame) {
out.ensureWritable(SPDY_HEADER_SIZE);
out.writeShort(version | 0x8000);
out.writeShort(SPDY_NOOP_FRAME);
out.writeInt(0);
} else if (msg instanceof SpdyPingFrame) {
SpdyPingFrame spdyPingFrame = (SpdyPingFrame) msg;
@ -285,7 +278,7 @@ public class SpdyFrameEncoder extends MessageToByteEncoder<SpdyDataOrControlFram
}
}
private static ByteBuf encodeHeaderBlock(int version, SpdyHeaderBlock headerFrame)
private static ByteBuf encodeHeaderBlock(int version, SpdyHeadersFrame headerFrame)
throws Exception {
Set<String> names = headerFrame.headers().names();
int numHeaders = names.size();

View File

@ -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);
}

View File

@ -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();
}

View File

@ -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<Map.Entry<String, String>> {
@ -166,8 +166,8 @@ public abstract class SpdyHeaders implements Iterable<Map.Entry<String, String>>
*
* @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<Map.Entry<String, String>>
* @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<Map.Entry<String, String>>
* 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<Map.Entry<String, String>>
/**
* 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<Map.Entry<String, String>>
/**
* 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<Map.Entry<String, String>>
/**
* 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<Map.Entry<String, String>>
public abstract List<String> 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<Map.Entry<String, String>>
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<String> names();
@ -490,7 +490,7 @@ public abstract class SpdyHeaders implements Iterable<Map.Entry<String, String>>
public abstract SpdyHeaders remove(String name);
/**
* Removes all headers from this block.
* Removes all headers from this frame.
*/
public abstract SpdyHeaders clear();

View File

@ -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();
}

View File

@ -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<SpdyHttpDecoder, SpdyHttpEncoder> {
/**
* Creates a new instance with the specified decoder options.
*/

View File

@ -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<SpdyDataOrControlFrame> {
public class SpdyHttpDecoder extends MessageToMessageDecoder<SpdyFrame> {
private final int spdyVersion;
private final int maxContentLength;
@ -91,7 +91,7 @@ public class SpdyHttpDecoder extends MessageToMessageDecoder<SpdyDataOrControlFr
}
@Override
protected void decode(ChannelHandlerContext ctx, SpdyDataOrControlFrame msg, MessageList<Object> out)
protected void decode(ChannelHandlerContext ctx, SpdyFrame msg, MessageList<Object> out)
throws Exception {
if (msg instanceof SpdySynStreamFrame) {
@ -252,7 +252,7 @@ public class SpdyHttpDecoder extends MessageToMessageDecoder<SpdyDataOrControlFr
}
}
private static FullHttpRequest createHttpRequest(int spdyVersion, SpdyHeaderBlock requestFrame)
private static FullHttpRequest createHttpRequest(int spdyVersion, SpdyHeadersFrame requestFrame)
throws Exception {
// Create the first line of the request from the name/value pairs
HttpMethod method = SpdyHeaders.getMethod(spdyVersion, requestFrame);
@ -287,7 +287,7 @@ public class SpdyHttpDecoder extends MessageToMessageDecoder<SpdyDataOrControlFr
return req;
}
private static FullHttpResponse createHttpResponse(int spdyVersion, SpdyHeaderBlock responseFrame)
private static FullHttpResponse createHttpResponse(int spdyVersion, SpdyHeadersFrame responseFrame)
throws Exception {
// Create the first line of the response from the name/value pairs
HttpResponseStatus status = SpdyHeaders.getStatus(spdyVersion, responseFrame);

View File

@ -266,7 +266,7 @@ public class SpdyHttpEncoder extends MessageToMessageEncoder<HttpObject> {
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");

View File

@ -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
}

View File

@ -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.

View File

@ -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);
}

View File

@ -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<Object> in) {
ChannelHandlerContext ctx, int streamId, SpdyStreamStatus status, MessageList<Object> 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<Object> out) {
private void updateSendWindowSize(final int streamId, int deltaWindowSize, MessageList<Object> 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);
// }
// }
//});

View File

@ -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<SpdySessionStatus> {
@ -40,7 +40,7 @@ public class SpdySessionStatus implements Comparable<SpdySessionStatus> {
/**
* 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<SpdySessionStatus> {
}
/**
* 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;

View File

@ -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;

View File

@ -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.

View File

@ -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<SpdyStreamStatus> {
@ -88,13 +88,13 @@ public class SpdyStreamStatus implements Comparable<SpdyStreamStatus> {
/**
* 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<SpdyStreamStatus> {
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<SpdyStreamStatus> {
}
/**
* 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;

View File

@ -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);

View File

@ -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.

View File

@ -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);

View File

@ -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<String> expectedValues = expected.headers().getAll(name);
List<String> 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<String> expectedValues = headers.getAll(name);
List<String> 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<Object> {
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<Object> 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<String, String> 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<String, String> 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();
}
}
}