SPDY: update object hierarchy
This commit is contained in:
parent
7f7bf304b0
commit
c8ca329932
@ -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) {
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
@ -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);
|
||||
|
@ -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
|
||||
}
|
@ -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
|
||||
|
@ -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 ++;
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
||||
}
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
|
@ -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
|
||||
}
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
// }
|
||||
// }
|
||||
//});
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user