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,
|
* 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
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
@ -16,17 +16,16 @@
|
||||||
package io.netty.handler.codec.spdy;
|
package io.netty.handler.codec.spdy;
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.DefaultByteBufHolder;
|
import io.netty.buffer.IllegalBufferAccessException;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import io.netty.util.internal.StringUtil;
|
import io.netty.util.internal.StringUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default {@link SpdyDataFrame} implementation.
|
* The default {@link SpdyDataFrame} implementation.
|
||||||
*/
|
*/
|
||||||
public class DefaultSpdyDataFrame extends DefaultByteBufHolder implements SpdyDataFrame {
|
public class DefaultSpdyDataFrame extends DefaultSpdyStreamFrame implements SpdyDataFrame {
|
||||||
|
|
||||||
private int streamId;
|
private final ByteBuf data;
|
||||||
private boolean last;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance.
|
* 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}
|
* @param data the payload of the frame. Can not exceed {@link SpdyCodecUtil#SPDY_MAX_LENGTH}
|
||||||
*/
|
*/
|
||||||
public DefaultSpdyDataFrame(int streamId, ByteBuf data) {
|
public DefaultSpdyDataFrame(int streamId, ByteBuf data) {
|
||||||
super(validate(data));
|
super(streamId);
|
||||||
setStreamId(streamId);
|
if (data == null) {
|
||||||
|
throw new NullPointerException("data");
|
||||||
|
}
|
||||||
|
this.data = validate(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ByteBuf validate(ByteBuf data) {
|
private static ByteBuf validate(ByteBuf data) {
|
||||||
|
@ -56,51 +58,60 @@ public class DefaultSpdyDataFrame extends DefaultByteBufHolder implements SpdyDa
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getStreamId() {
|
|
||||||
return streamId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SpdyDataFrame setStreamId(int streamId) {
|
public SpdyDataFrame setStreamId(int streamId) {
|
||||||
if (streamId <= 0) {
|
super.setStreamId(streamId);
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Stream-ID must be positive: " + streamId);
|
|
||||||
}
|
|
||||||
this.streamId = streamId;
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isLast() {
|
|
||||||
return last;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SpdyDataFrame setLast(boolean last) {
|
public SpdyDataFrame setLast(boolean last) {
|
||||||
this.last = last;
|
super.setLast(last);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DefaultSpdyDataFrame copy() {
|
public ByteBuf content() {
|
||||||
DefaultSpdyDataFrame frame = new DefaultSpdyDataFrame(getStreamId(), content().copy());
|
if (data.refCnt() <= 0) {
|
||||||
|
throw new IllegalBufferAccessException();
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SpdyDataFrame copy() {
|
||||||
|
SpdyDataFrame frame = new DefaultSpdyDataFrame(getStreamId(), content().copy());
|
||||||
frame.setLast(isLast());
|
frame.setLast(isLast());
|
||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int refCnt() {
|
||||||
|
return data.refCnt();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SpdyDataFrame retain() {
|
public SpdyDataFrame retain() {
|
||||||
super.retain();
|
data.retain();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SpdyDataFrame retain(int increment) {
|
public SpdyDataFrame retain(int increment) {
|
||||||
super.retain(increment);
|
data.retain(increment);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean release() {
|
||||||
|
return data.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean release(int decrement) {
|
||||||
|
return data.release(decrement);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder buf = new StringBuilder();
|
StringBuilder buf = new StringBuilder();
|
||||||
|
@ -110,7 +121,7 @@ public class DefaultSpdyDataFrame extends DefaultByteBufHolder implements SpdyDa
|
||||||
buf.append(')');
|
buf.append(')');
|
||||||
buf.append(StringUtil.NEWLINE);
|
buf.append(StringUtil.NEWLINE);
|
||||||
buf.append("--> Stream-ID = ");
|
buf.append("--> Stream-ID = ");
|
||||||
buf.append(streamId);
|
buf.append(getStreamId());
|
||||||
buf.append(StringUtil.NEWLINE);
|
buf.append(StringUtil.NEWLINE);
|
||||||
buf.append("--> Size = ");
|
buf.append("--> Size = ");
|
||||||
if (refCnt() == 0) {
|
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,
|
* 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
|
* 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.
|
* Creates a new instance.
|
||||||
*
|
*
|
||||||
* @param lastGoodStreamId the Last-good-stream-ID of this frame
|
* @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) {
|
public DefaultSpdyGoAwayFrame(int lastGoodStreamId, SpdySessionStatus status) {
|
||||||
setLastGoodStreamId(lastGoodStreamId);
|
setLastGoodStreamId(lastGoodStreamId);
|
||||||
setStatus(status);
|
setStatus(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getLastGoodStreamId() {
|
public int getLastGoodStreamId() {
|
||||||
return lastGoodStreamId;
|
return lastGoodStreamId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public SpdyGoAwayFrame setLastGoodStreamId(int lastGoodStreamId) {
|
public SpdyGoAwayFrame setLastGoodStreamId(int lastGoodStreamId) {
|
||||||
if (lastGoodStreamId < 0) {
|
if (lastGoodStreamId < 0) {
|
||||||
throw new IllegalArgumentException("Last-good-stream-ID"
|
throw new IllegalArgumentException("Last-good-stream-ID"
|
||||||
|
@ -70,12 +68,10 @@ public class DefaultSpdyGoAwayFrame implements SpdyGoAwayFrame {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public SpdySessionStatus getStatus() {
|
public SpdySessionStatus getStatus() {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public SpdyGoAwayFrame setStatus(SpdySessionStatus status) {
|
public SpdyGoAwayFrame setStatus(SpdySessionStatus status) {
|
||||||
this.status = status;
|
this.status = status;
|
||||||
return this;
|
return this;
|
||||||
|
@ -87,10 +83,10 @@ public class DefaultSpdyGoAwayFrame implements SpdyGoAwayFrame {
|
||||||
buf.append(getClass().getSimpleName());
|
buf.append(getClass().getSimpleName());
|
||||||
buf.append(StringUtil.NEWLINE);
|
buf.append(StringUtil.NEWLINE);
|
||||||
buf.append("--> Last-good-stream-ID = ");
|
buf.append("--> Last-good-stream-ID = ");
|
||||||
buf.append(lastGoodStreamId);
|
buf.append(getLastGoodStreamId());
|
||||||
buf.append(StringUtil.NEWLINE);
|
buf.append(StringUtil.NEWLINE);
|
||||||
buf.append("--> Status: ");
|
buf.append("--> Status: ");
|
||||||
buf.append(status.toString());
|
buf.append(getStatus().toString());
|
||||||
return buf.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,
|
* 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
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
@ -15,17 +15,18 @@
|
||||||
*/
|
*/
|
||||||
package io.netty.handler.codec.spdy;
|
package io.netty.handler.codec.spdy;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import io.netty.util.internal.StringUtil;
|
import io.netty.util.internal.StringUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default {@link SpdyHeadersFrame} implementation.
|
* The default {@link SpdyHeadersFrame} implementation.
|
||||||
*/
|
*/
|
||||||
public class DefaultSpdyHeadersFrame extends DefaultSpdyHeaderBlock
|
public class DefaultSpdyHeadersFrame extends DefaultSpdyStreamFrame
|
||||||
implements SpdyHeadersFrame {
|
implements SpdyHeadersFrame {
|
||||||
|
|
||||||
private int streamId;
|
private boolean invalid;
|
||||||
private boolean last;
|
private final SpdyHeaders headers = new DefaultSpdyHeaders();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance.
|
* Creates a new instance.
|
||||||
|
@ -33,41 +34,34 @@ public class DefaultSpdyHeadersFrame extends DefaultSpdyHeaderBlock
|
||||||
* @param streamId the Stream-ID of this frame
|
* @param streamId the Stream-ID of this frame
|
||||||
*/
|
*/
|
||||||
public DefaultSpdyHeadersFrame(int streamId) {
|
public DefaultSpdyHeadersFrame(int streamId) {
|
||||||
setStreamId(streamId);
|
super(streamId);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getStreamId() {
|
|
||||||
return streamId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SpdyHeadersFrame setStreamId(int streamId) {
|
public SpdyHeadersFrame setStreamId(int streamId) {
|
||||||
if (streamId <= 0) {
|
super.setStreamId(streamId);
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Stream-ID must be positive: " + streamId);
|
|
||||||
}
|
|
||||||
this.streamId = streamId;
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isLast() {
|
|
||||||
return last;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SpdyHeadersFrame setLast(boolean last) {
|
public SpdyHeadersFrame setLast(boolean last) {
|
||||||
this.last = last;
|
super.setLast(last);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public boolean isInvalid() {
|
||||||
|
return invalid;
|
||||||
|
}
|
||||||
|
|
||||||
public SpdyHeadersFrame setInvalid() {
|
public SpdyHeadersFrame setInvalid() {
|
||||||
super.setInvalid();
|
invalid = true;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SpdyHeaders headers() {
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder buf = new StringBuilder();
|
StringBuilder buf = new StringBuilder();
|
||||||
|
@ -77,7 +71,7 @@ public class DefaultSpdyHeadersFrame extends DefaultSpdyHeaderBlock
|
||||||
buf.append(')');
|
buf.append(')');
|
||||||
buf.append(StringUtil.NEWLINE);
|
buf.append(StringUtil.NEWLINE);
|
||||||
buf.append("--> Stream-ID = ");
|
buf.append("--> Stream-ID = ");
|
||||||
buf.append(streamId);
|
buf.append(getStreamId());
|
||||||
buf.append(StringUtil.NEWLINE);
|
buf.append(StringUtil.NEWLINE);
|
||||||
buf.append("--> Headers:");
|
buf.append("--> Headers:");
|
||||||
buf.append(StringUtil.NEWLINE);
|
buf.append(StringUtil.NEWLINE);
|
||||||
|
@ -87,4 +81,14 @@ public class DefaultSpdyHeadersFrame extends DefaultSpdyHeaderBlock
|
||||||
buf.setLength(buf.length() - StringUtil.NEWLINE.length());
|
buf.setLength(buf.length() - StringUtil.NEWLINE.length());
|
||||||
return buf.toString();
|
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,
|
* 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
|
* 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);
|
setId(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getId() {
|
public int getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public SpdyPingFrame setId(int id) {
|
public SpdyPingFrame setId(int id) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
return this;
|
return this;
|
||||||
|
@ -50,7 +48,7 @@ public class DefaultSpdyPingFrame implements SpdyPingFrame {
|
||||||
buf.append(getClass().getSimpleName());
|
buf.append(getClass().getSimpleName());
|
||||||
buf.append(StringUtil.NEWLINE);
|
buf.append(StringUtil.NEWLINE);
|
||||||
buf.append("--> ID = ");
|
buf.append("--> ID = ");
|
||||||
buf.append(id);
|
buf.append(getId());
|
||||||
return buf.toString();
|
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,
|
* 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
|
* 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.
|
* The default {@link SpdyRstStreamFrame} implementation.
|
||||||
*/
|
*/
|
||||||
public class DefaultSpdyRstStreamFrame implements SpdyRstStreamFrame {
|
public class DefaultSpdyRstStreamFrame extends DefaultSpdyStreamFrame
|
||||||
|
implements SpdyRstStreamFrame {
|
||||||
|
|
||||||
private int streamId;
|
|
||||||
private SpdyStreamStatus status;
|
private SpdyStreamStatus status;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,34 +39,29 @@ public class DefaultSpdyRstStreamFrame implements SpdyRstStreamFrame {
|
||||||
* Creates a new instance.
|
* Creates a new instance.
|
||||||
*
|
*
|
||||||
* @param streamId the Stream-ID of this frame
|
* @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) {
|
public DefaultSpdyRstStreamFrame(int streamId, SpdyStreamStatus status) {
|
||||||
setStreamId(streamId);
|
super(streamId);
|
||||||
setStatus(status);
|
setStatus(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getStreamId() {
|
|
||||||
return streamId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SpdyRstStreamFrame setStreamId(int streamId) {
|
public SpdyRstStreamFrame setStreamId(int streamId) {
|
||||||
if (streamId <= 0) {
|
super.setStreamId(streamId);
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Stream-ID must be positive: " + streamId);
|
|
||||||
}
|
|
||||||
this.streamId = streamId;
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
public SpdyRstStreamFrame setLast(boolean last) {
|
||||||
|
super.setLast(last);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public SpdyStreamStatus getStatus() {
|
public SpdyStreamStatus getStatus() {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public SpdyRstStreamFrame setStatus(SpdyStreamStatus status) {
|
public SpdyRstStreamFrame setStatus(SpdyStreamStatus status) {
|
||||||
this.status = status;
|
this.status = status;
|
||||||
return this;
|
return this;
|
||||||
|
@ -78,10 +73,10 @@ public class DefaultSpdyRstStreamFrame implements SpdyRstStreamFrame {
|
||||||
buf.append(getClass().getSimpleName());
|
buf.append(getClass().getSimpleName());
|
||||||
buf.append(StringUtil.NEWLINE);
|
buf.append(StringUtil.NEWLINE);
|
||||||
buf.append("--> Stream-ID = ");
|
buf.append("--> Stream-ID = ");
|
||||||
buf.append(streamId);
|
buf.append(getStreamId());
|
||||||
buf.append(StringUtil.NEWLINE);
|
buf.append(StringUtil.NEWLINE);
|
||||||
buf.append("--> Status: ");
|
buf.append("--> Status: ");
|
||||||
buf.append(status.toString());
|
buf.append(getStatus().toString());
|
||||||
return buf.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,
|
* 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
|
* 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.
|
* The default {@link SpdySynReplyFrame} implementation.
|
||||||
*/
|
*/
|
||||||
public class DefaultSpdySynReplyFrame extends DefaultSpdyHeaderBlock
|
public class DefaultSpdySynReplyFrame extends DefaultSpdyHeadersFrame
|
||||||
implements SpdySynReplyFrame {
|
implements SpdySynReplyFrame {
|
||||||
|
|
||||||
private int streamId;
|
|
||||||
private boolean last;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance.
|
* Creates a new instance.
|
||||||
*
|
*
|
||||||
* @param streamId the Stream-ID of this frame
|
* @param streamId the Stream-ID of this frame
|
||||||
*/
|
*/
|
||||||
public DefaultSpdySynReplyFrame(int streamId) {
|
public DefaultSpdySynReplyFrame(int streamId) {
|
||||||
setStreamId(streamId);
|
super(streamId);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getStreamId() {
|
|
||||||
return streamId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SpdySynReplyFrame setStreamId(int streamId) {
|
public SpdySynReplyFrame setStreamId(int streamId) {
|
||||||
if (streamId <= 0) {
|
super.setStreamId(streamId);
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Stream-ID must be positive: " + streamId);
|
|
||||||
}
|
|
||||||
this.streamId = streamId;
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isLast() {
|
|
||||||
return last;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SpdySynReplyFrame setLast(boolean last) {
|
public SpdySynReplyFrame setLast(boolean last) {
|
||||||
this.last = last;
|
super.setLast(last);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +59,7 @@ public class DefaultSpdySynReplyFrame extends DefaultSpdyHeaderBlock
|
||||||
buf.append(')');
|
buf.append(')');
|
||||||
buf.append(StringUtil.NEWLINE);
|
buf.append(StringUtil.NEWLINE);
|
||||||
buf.append("--> Stream-ID = ");
|
buf.append("--> Stream-ID = ");
|
||||||
buf.append(streamId);
|
buf.append(getStreamId());
|
||||||
buf.append(StringUtil.NEWLINE);
|
buf.append(StringUtil.NEWLINE);
|
||||||
buf.append("--> Headers:");
|
buf.append("--> Headers:");
|
||||||
buf.append(StringUtil.NEWLINE);
|
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,
|
* 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
|
* 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.
|
* The default {@link SpdySynStreamFrame} implementation.
|
||||||
*/
|
*/
|
||||||
public class DefaultSpdySynStreamFrame extends DefaultSpdyHeaderBlock
|
public class DefaultSpdySynStreamFrame extends DefaultSpdyHeadersFrame
|
||||||
implements SpdySynStreamFrame {
|
implements SpdySynStreamFrame {
|
||||||
|
|
||||||
private int streamId;
|
|
||||||
private int associatedToStreamId;
|
private int associatedToStreamId;
|
||||||
private byte priority;
|
private byte priority;
|
||||||
private boolean last;
|
|
||||||
private boolean unidirectional;
|
private boolean unidirectional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,23 +36,26 @@ public class DefaultSpdySynStreamFrame extends DefaultSpdyHeaderBlock
|
||||||
*/
|
*/
|
||||||
public DefaultSpdySynStreamFrame(
|
public DefaultSpdySynStreamFrame(
|
||||||
int streamId, int associatedToStreamId, byte priority) {
|
int streamId, int associatedToStreamId, byte priority) {
|
||||||
setStreamId(streamId);
|
super(streamId);
|
||||||
setAssociatedToStreamId(associatedToStreamId);
|
setAssociatedToStreamId(associatedToStreamId);
|
||||||
setPriority(priority);
|
setPriority(priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getStreamId() {
|
public SpdySynStreamFrame setStreamId(int streamId) {
|
||||||
return streamId;
|
super.setStreamId(streamId);
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SpdySynStreamFrame setStreamId(int streamId) {
|
public SpdySynStreamFrame setLast(boolean last) {
|
||||||
if (streamId <= 0) {
|
super.setLast(last);
|
||||||
throw new IllegalArgumentException(
|
return this;
|
||||||
"Stream-ID must be positive: " + streamId);
|
}
|
||||||
}
|
|
||||||
this.streamId = streamId;
|
@Override
|
||||||
|
public SpdySynStreamFrame setInvalid() {
|
||||||
|
super.setInvalid();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,17 +90,6 @@ public class DefaultSpdySynStreamFrame extends DefaultSpdyHeaderBlock
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isLast() {
|
|
||||||
return last;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SpdySynStreamFrame setLast(boolean last) {
|
|
||||||
this.last = last;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isUnidirectional() {
|
public boolean isUnidirectional() {
|
||||||
return unidirectional;
|
return unidirectional;
|
||||||
|
@ -111,12 +101,6 @@ public class DefaultSpdySynStreamFrame extends DefaultSpdyHeaderBlock
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public SpdySynStreamFrame setInvalid() {
|
|
||||||
super.setInvalid();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder buf = new StringBuilder();
|
StringBuilder buf = new StringBuilder();
|
||||||
|
@ -128,15 +112,15 @@ public class DefaultSpdySynStreamFrame extends DefaultSpdyHeaderBlock
|
||||||
buf.append(')');
|
buf.append(')');
|
||||||
buf.append(StringUtil.NEWLINE);
|
buf.append(StringUtil.NEWLINE);
|
||||||
buf.append("--> Stream-ID = ");
|
buf.append("--> Stream-ID = ");
|
||||||
buf.append(streamId);
|
buf.append(getStreamId());
|
||||||
buf.append(StringUtil.NEWLINE);
|
buf.append(StringUtil.NEWLINE);
|
||||||
if (associatedToStreamId != 0) {
|
if (associatedToStreamId != 0) {
|
||||||
buf.append("--> Associated-To-Stream-ID = ");
|
buf.append("--> Associated-To-Stream-ID = ");
|
||||||
buf.append(associatedToStreamId);
|
buf.append(getAssociatedToStreamId());
|
||||||
buf.append(StringUtil.NEWLINE);
|
buf.append(StringUtil.NEWLINE);
|
||||||
}
|
}
|
||||||
buf.append("--> Priority = ");
|
buf.append("--> Priority = ");
|
||||||
buf.append(priority);
|
buf.append(getPriority());
|
||||||
buf.append(StringUtil.NEWLINE);
|
buf.append(StringUtil.NEWLINE);
|
||||||
buf.append("--> Headers:");
|
buf.append("--> Headers:");
|
||||||
buf.append(StringUtil.NEWLINE);
|
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,
|
* 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
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
@ -43,9 +43,9 @@ public class DefaultSpdyWindowUpdateFrame implements SpdyWindowUpdateFrame {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SpdyWindowUpdateFrame setStreamId(int streamId) {
|
public SpdyWindowUpdateFrame setStreamId(int streamId) {
|
||||||
if (streamId <= 0) {
|
if (streamId < 0) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Stream-ID must be positive: " + streamId);
|
"Stream-ID cannot be negative: " + streamId);
|
||||||
}
|
}
|
||||||
this.streamId = streamId;
|
this.streamId = streamId;
|
||||||
return this;
|
return this;
|
||||||
|
@ -73,10 +73,10 @@ public class DefaultSpdyWindowUpdateFrame implements SpdyWindowUpdateFrame {
|
||||||
buf.append(getClass().getSimpleName());
|
buf.append(getClass().getSimpleName());
|
||||||
buf.append(StringUtil.NEWLINE);
|
buf.append(StringUtil.NEWLINE);
|
||||||
buf.append("--> Stream-ID = ");
|
buf.append("--> Stream-ID = ");
|
||||||
buf.append(streamId);
|
buf.append(getStreamId());
|
||||||
buf.append(StringUtil.NEWLINE);
|
buf.append(StringUtil.NEWLINE);
|
||||||
buf.append("--> Delta-Window-Size = ");
|
buf.append("--> Delta-Window-Size = ");
|
||||||
buf.append(deltaWindowSize);
|
buf.append(getDeltaWindowSize());
|
||||||
return buf.toString();
|
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,
|
* 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
|
* 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;
|
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
|
@Override
|
||||||
SpdyDataFrame setStreamId(int streamID);
|
SpdyDataFrame setStreamId(int streamID);
|
||||||
|
|
|
@ -13,9 +13,11 @@
|
||||||
* License for the specific language governing permissions and limitations
|
* License for the specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.netty.handler.codec.spdy;
|
package io.netty.handler.codec.spdy;
|
||||||
|
|
||||||
public interface SpdyDataOrControlFrame {
|
/**
|
||||||
|
* A SPDY Protocol Frame
|
||||||
|
*/
|
||||||
|
public interface SpdyFrame {
|
||||||
// Tag interface
|
// 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,
|
* 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
|
* 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}.
|
* A combination of {@link SpdyFrameDecoder} and {@link SpdyFrameEncoder}.
|
||||||
*/
|
*/
|
||||||
public final class SpdyFrameCodec extends CombinedChannelDuplexHandler<SpdyFrameDecoder, SpdyFrameEncoder> {
|
public final class SpdyFrameCodec extends CombinedChannelDuplexHandler<SpdyFrameDecoder, SpdyFrameEncoder> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance with the specified {@code version} and
|
* Creates a new instance with the specified {@code version} and
|
||||||
* the default decoder and encoder options
|
* the default decoder and encoder options
|
||||||
|
|
|
@ -25,7 +25,7 @@ import io.netty.handler.codec.TooLongFrameException;
|
||||||
import static io.netty.handler.codec.spdy.SpdyCodecUtil.*;
|
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 {
|
public class SpdyFrameDecoder extends ByteToMessageDecoder {
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder {
|
||||||
|
|
||||||
private State state;
|
private State state;
|
||||||
private SpdySettingsFrame spdySettingsFrame;
|
private SpdySettingsFrame spdySettingsFrame;
|
||||||
private SpdyHeaderBlock spdyHeaderBlock;
|
private SpdyHeadersFrame spdyHeadersFrame;
|
||||||
|
|
||||||
// SPDY common header fields
|
// SPDY common header fields
|
||||||
private byte flags;
|
private byte flags;
|
||||||
|
@ -221,12 +221,12 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder {
|
||||||
|
|
||||||
case READ_HEADER_BLOCK_FRAME:
|
case READ_HEADER_BLOCK_FRAME:
|
||||||
try {
|
try {
|
||||||
spdyHeaderBlock = readHeaderBlockFrame(buffer);
|
spdyHeadersFrame = readHeaderBlockFrame(buffer);
|
||||||
if (spdyHeaderBlock != null) {
|
if (spdyHeadersFrame != null) {
|
||||||
if (length == 0) {
|
if (length == 0) {
|
||||||
state = State.READ_COMMON_HEADER;
|
state = State.READ_COMMON_HEADER;
|
||||||
Object frame = spdyHeaderBlock;
|
Object frame = spdyHeadersFrame;
|
||||||
spdyHeaderBlock = null;
|
spdyHeadersFrame = null;
|
||||||
out.add(frame);
|
out.add(frame);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -247,15 +247,15 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder {
|
||||||
decodeHeaderBlock(buffer.readSlice(compressedBytes));
|
decodeHeaderBlock(buffer.readSlice(compressedBytes));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
state = State.FRAME_ERROR;
|
state = State.FRAME_ERROR;
|
||||||
spdyHeaderBlock = null;
|
spdyHeadersFrame = null;
|
||||||
decompressed = null;
|
decompressed = null;
|
||||||
ctx.fireExceptionCaught(e);
|
ctx.fireExceptionCaught(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spdyHeaderBlock != null && spdyHeaderBlock.isInvalid()) {
|
if (spdyHeadersFrame != null && spdyHeadersFrame.isInvalid()) {
|
||||||
Object frame = spdyHeaderBlock;
|
Object frame = spdyHeadersFrame;
|
||||||
spdyHeaderBlock = null;
|
spdyHeadersFrame = null;
|
||||||
decompressed = null;
|
decompressed = null;
|
||||||
if (length == 0) {
|
if (length == 0) {
|
||||||
state = State.READ_COMMON_HEADER;
|
state = State.READ_COMMON_HEADER;
|
||||||
|
@ -265,8 +265,8 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (length == 0) {
|
if (length == 0) {
|
||||||
Object frame = spdyHeaderBlock;
|
Object frame = spdyHeadersFrame;
|
||||||
spdyHeaderBlock = null;
|
spdyHeadersFrame = null;
|
||||||
state = State.READ_COMMON_HEADER;
|
state = State.READ_COMMON_HEADER;
|
||||||
out.add(frame);
|
out.add(frame);
|
||||||
return;
|
return;
|
||||||
|
@ -436,7 +436,7 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private SpdyHeaderBlock readHeaderBlockFrame(ByteBuf buffer) {
|
private SpdyHeadersFrame readHeaderBlockFrame(ByteBuf buffer) {
|
||||||
int minLength;
|
int minLength;
|
||||||
int streamID;
|
int streamID;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
@ -567,7 +567,7 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder {
|
||||||
headerBlockDecompressor.setInput(buffer);
|
headerBlockDecompressor.setInput(buffer);
|
||||||
headerBlockDecompressor.decode(decompressed);
|
headerBlockDecompressor.decode(decompressed);
|
||||||
|
|
||||||
if (spdyHeaderBlock == null) {
|
if (spdyHeadersFrame == null) {
|
||||||
// Only decompressing data to keep decompression context in sync
|
// Only decompressing data to keep decompression context in sync
|
||||||
decompressed = null;
|
decompressed = null;
|
||||||
return;
|
return;
|
||||||
|
@ -582,7 +582,7 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder {
|
||||||
}
|
}
|
||||||
numHeaders = readLengthField();
|
numHeaders = readLengthField();
|
||||||
if (numHeaders < 0) {
|
if (numHeaders < 0) {
|
||||||
spdyHeaderBlock.setInvalid();
|
spdyHeadersFrame.setInvalid();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -601,7 +601,7 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder {
|
||||||
|
|
||||||
// Recipients of a zero-length name must issue a stream error
|
// Recipients of a zero-length name must issue a stream error
|
||||||
if (nameLength <= 0) {
|
if (nameLength <= 0) {
|
||||||
spdyHeaderBlock.setInvalid();
|
spdyHeadersFrame.setInvalid();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
headerSize += nameLength;
|
headerSize += nameLength;
|
||||||
|
@ -621,8 +621,8 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder {
|
||||||
String name = new String(nameBytes, "UTF-8");
|
String name = new String(nameBytes, "UTF-8");
|
||||||
|
|
||||||
// Check for identically named headers
|
// Check for identically named headers
|
||||||
if (spdyHeaderBlock.headers().contains(name)) {
|
if (spdyHeadersFrame.headers().contains(name)) {
|
||||||
spdyHeaderBlock.setInvalid();
|
spdyHeadersFrame.setInvalid();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -636,17 +636,17 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder {
|
||||||
|
|
||||||
// Recipients of illegal value fields must issue a stream error
|
// Recipients of illegal value fields must issue a stream error
|
||||||
if (valueLength < 0) {
|
if (valueLength < 0) {
|
||||||
spdyHeaderBlock.setInvalid();
|
spdyHeadersFrame.setInvalid();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SPDY/3 allows zero-length (empty) header values
|
// SPDY/3 allows zero-length (empty) header values
|
||||||
if (valueLength == 0) {
|
if (valueLength == 0) {
|
||||||
if (version < 3) {
|
if (version < 3) {
|
||||||
spdyHeaderBlock.setInvalid();
|
spdyHeadersFrame.setInvalid();
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
spdyHeaderBlock.headers().add(name, "");
|
spdyHeadersFrame.headers().add(name, "");
|
||||||
numHeaders --;
|
numHeaders --;
|
||||||
this.headerSize = headerSize;
|
this.headerSize = headerSize;
|
||||||
continue;
|
continue;
|
||||||
|
@ -678,16 +678,16 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder {
|
||||||
if (index < valueBytes.length && valueBytes[index + 1] == (byte) 0) {
|
if (index < valueBytes.length && valueBytes[index + 1] == (byte) 0) {
|
||||||
// Received multiple, in-sequence NULL characters
|
// Received multiple, in-sequence NULL characters
|
||||||
// Recipients of illegal value fields must issue a stream error
|
// Recipients of illegal value fields must issue a stream error
|
||||||
spdyHeaderBlock.setInvalid();
|
spdyHeadersFrame.setInvalid();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String value = new String(valueBytes, offset, index - offset, "UTF-8");
|
String value = new String(valueBytes, offset, index - offset, "UTF-8");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
spdyHeaderBlock.headers().add(name, value);
|
spdyHeadersFrame.headers().add(name, value);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
// Name contains NULL or non-ascii characters
|
// Name contains NULL or non-ascii characters
|
||||||
spdyHeaderBlock.setInvalid();
|
spdyHeadersFrame.setInvalid();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
index ++;
|
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,
|
* 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
|
* 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.*;
|
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 final int version;
|
||||||
private volatile boolean finished;
|
private volatile boolean finished;
|
||||||
|
@ -76,7 +76,7 @@ public class SpdyFrameEncoder extends MessageToByteEncoder<SpdyDataOrControlFram
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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) {
|
if (msg instanceof SpdyDataFrame) {
|
||||||
|
|
||||||
SpdyDataFrame spdyDataFrame = (SpdyDataFrame) msg;
|
SpdyDataFrame spdyDataFrame = (SpdyDataFrame) msg;
|
||||||
|
@ -202,13 +202,6 @@ public class SpdyFrameEncoder extends MessageToByteEncoder<SpdyDataOrControlFram
|
||||||
out.writeInt(spdySettingsFrame.getValue(id));
|
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) {
|
} else if (msg instanceof SpdyPingFrame) {
|
||||||
|
|
||||||
SpdyPingFrame spdyPingFrame = (SpdyPingFrame) msg;
|
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 {
|
throws Exception {
|
||||||
Set<String> names = headerFrame.headers().names();
|
Set<String> names = headerFrame.headers().names();
|
||||||
int numHeaders = names.size();
|
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,
|
* 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
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
@ -16,9 +16,9 @@
|
||||||
package io.netty.handler.codec.spdy;
|
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.
|
* Returns the Last-good-stream-ID of this frame.
|
||||||
|
@ -32,12 +32,12 @@ public interface SpdyGoAwayFrame extends SpdyControlFrame {
|
||||||
SpdyGoAwayFrame setLastGoodStreamId(int lastGoodStreamId);
|
SpdyGoAwayFrame setLastGoodStreamId(int lastGoodStreamId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the getStatus of this frame.
|
* Returns the status of this frame.
|
||||||
*/
|
*/
|
||||||
SpdySessionStatus getStatus();
|
SpdySessionStatus getStatus();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the getStatus of this frame.
|
* Sets the status of this frame.
|
||||||
*/
|
*/
|
||||||
SpdyGoAwayFrame setStatus(SpdySessionStatus status);
|
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,
|
* 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
|
* 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
|
* 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>> {
|
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
|
* @return the header value or {@code null} if there is no such header
|
||||||
*/
|
*/
|
||||||
public static String getHeader(SpdyHeaderBlock block, String name) {
|
public static String getHeader(SpdyHeadersFrame frame, String name) {
|
||||||
return block.headers().get(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
|
* @return the header value or the {@code defaultValue} if there is no such
|
||||||
* header
|
* header
|
||||||
*/
|
*/
|
||||||
public static String getHeader(SpdyHeaderBlock block, String name, String defaultValue) {
|
public static String getHeader(SpdyHeadersFrame frame, String name, String defaultValue) {
|
||||||
String value = block.headers().get(name);
|
String value = frame.headers().get(name);
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
return defaultValue;
|
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
|
* 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.
|
* existing header with the same name, the existing header is removed.
|
||||||
*/
|
*/
|
||||||
public static void setHeader(SpdyHeaderBlock block, String name, Object value) {
|
public static void setHeader(SpdyHeadersFrame frame, String name, Object value) {
|
||||||
block.headers().set(name, value);
|
frame.headers().set(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a new header with the specified name and values. If there is an
|
* 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.
|
* existing header with the same name, the existing header is removed.
|
||||||
*/
|
*/
|
||||||
public static void setHeader(SpdyHeaderBlock block, String name, Iterable<?> values) {
|
public static void setHeader(SpdyHeadersFrame frame, String name, Iterable<?> values) {
|
||||||
block.headers().set(name, values);
|
frame.headers().set(name, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a new header with the specified name and value.
|
* Adds a new header with the specified name and value.
|
||||||
*/
|
*/
|
||||||
public static void addHeader(SpdyHeaderBlock block, String name, Object value) {
|
public static void addHeader(SpdyHeadersFrame frame, String name, Object value) {
|
||||||
block.headers().add(name, value);
|
frame.headers().add(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the SPDY host header.
|
* Removes the SPDY host header.
|
||||||
*/
|
*/
|
||||||
public static void removeHost(SpdyHeaderBlock block) {
|
public static void removeHost(SpdyHeadersFrame frame) {
|
||||||
block.headers().remove(HttpNames.HOST);
|
frame.headers().remove(HttpNames.HOST);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the SPDY host header.
|
* Returns the SPDY host header.
|
||||||
*/
|
*/
|
||||||
public static String getHost(SpdyHeaderBlock block) {
|
public static String getHost(SpdyHeadersFrame frame) {
|
||||||
return block.headers().get(HttpNames.HOST);
|
return frame.headers().get(HttpNames.HOST);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the SPDY host header.
|
* Set the SPDY host header.
|
||||||
*/
|
*/
|
||||||
public static void setHost(SpdyHeaderBlock block, String host) {
|
public static void setHost(SpdyHeadersFrame frame, String host) {
|
||||||
block.headers().set(HttpNames.HOST, host);
|
frame.headers().set(HttpNames.HOST, host);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the HTTP method header.
|
* Removes the HTTP method header.
|
||||||
*/
|
*/
|
||||||
public static void removeMethod(int spdyVersion, SpdyHeaderBlock block) {
|
public static void removeMethod(int spdyVersion, SpdyHeadersFrame frame) {
|
||||||
if (spdyVersion < 3) {
|
if (spdyVersion < 3) {
|
||||||
block.headers().remove(Spdy2HttpNames.METHOD);
|
frame.headers().remove(Spdy2HttpNames.METHOD);
|
||||||
} else {
|
} else {
|
||||||
block.headers().remove(HttpNames.METHOD);
|
frame.headers().remove(HttpNames.METHOD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@link HttpMethod} represented by the HTTP method header.
|
* 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 {
|
try {
|
||||||
if (spdyVersion < 3) {
|
if (spdyVersion < 3) {
|
||||||
return HttpMethod.valueOf(block.headers().get(Spdy2HttpNames.METHOD));
|
return HttpMethod.valueOf(frame.headers().get(Spdy2HttpNames.METHOD));
|
||||||
} else {
|
} else {
|
||||||
return HttpMethod.valueOf(block.headers().get(HttpNames.METHOD));
|
return HttpMethod.valueOf(frame.headers().get(HttpNames.METHOD));
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -259,68 +259,68 @@ public abstract class SpdyHeaders implements Iterable<Map.Entry<String, String>>
|
||||||
/**
|
/**
|
||||||
* Sets the HTTP method header.
|
* 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) {
|
if (spdyVersion < 3) {
|
||||||
block.headers().set(Spdy2HttpNames.METHOD, method.name());
|
frame.headers().set(Spdy2HttpNames.METHOD, method.name());
|
||||||
} else {
|
} else {
|
||||||
block.headers().set(HttpNames.METHOD, method.name());
|
frame.headers().set(HttpNames.METHOD, method.name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the URL scheme header.
|
* Removes the URL scheme header.
|
||||||
*/
|
*/
|
||||||
public static void removeScheme(int spdyVersion, SpdyHeaderBlock block) {
|
public static void removeScheme(int spdyVersion, SpdyHeadersFrame frame) {
|
||||||
if (spdyVersion < 2) {
|
if (spdyVersion < 2) {
|
||||||
block.headers().remove(Spdy2HttpNames.SCHEME);
|
frame.headers().remove(Spdy2HttpNames.SCHEME);
|
||||||
} else {
|
} else {
|
||||||
block.headers().remove(HttpNames.SCHEME);
|
frame.headers().remove(HttpNames.SCHEME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the value of the URL scheme header.
|
* 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) {
|
if (spdyVersion < 3) {
|
||||||
return block.headers().get(Spdy2HttpNames.SCHEME);
|
return frame.headers().get(Spdy2HttpNames.SCHEME);
|
||||||
} else {
|
} else {
|
||||||
return block.headers().get(HttpNames.SCHEME);
|
return frame.headers().get(HttpNames.SCHEME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the URL scheme header.
|
* 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) {
|
if (spdyVersion < 3) {
|
||||||
block.headers().set(Spdy2HttpNames.SCHEME, scheme);
|
frame.headers().set(Spdy2HttpNames.SCHEME, scheme);
|
||||||
} else {
|
} else {
|
||||||
block.headers().set(HttpNames.SCHEME, scheme);
|
frame.headers().set(HttpNames.SCHEME, scheme);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the HTTP response status header.
|
* 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) {
|
if (spdyVersion < 3) {
|
||||||
block.headers().remove(Spdy2HttpNames.STATUS);
|
frame.headers().remove(Spdy2HttpNames.STATUS);
|
||||||
} else {
|
} else {
|
||||||
block.headers().remove(HttpNames.STATUS);
|
frame.headers().remove(HttpNames.STATUS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@link HttpResponseStatus} represented by the HTTP response status header.
|
* 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 {
|
try {
|
||||||
String status;
|
String status;
|
||||||
if (spdyVersion < 3) {
|
if (spdyVersion < 3) {
|
||||||
status = block.headers().get(Spdy2HttpNames.STATUS);
|
status = frame.headers().get(Spdy2HttpNames.STATUS);
|
||||||
} else {
|
} else {
|
||||||
status = block.headers().get(HttpNames.STATUS);
|
status = frame.headers().get(HttpNames.STATUS);
|
||||||
}
|
}
|
||||||
int space = status.indexOf(' ');
|
int space = status.indexOf(' ');
|
||||||
if (space == -1) {
|
if (space == -1) {
|
||||||
|
@ -343,67 +343,67 @@ public abstract class SpdyHeaders implements Iterable<Map.Entry<String, String>>
|
||||||
/**
|
/**
|
||||||
* Sets the HTTP response status header.
|
* 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) {
|
if (spdyVersion < 3) {
|
||||||
block.headers().set(Spdy2HttpNames.STATUS, status.toString());
|
frame.headers().set(Spdy2HttpNames.STATUS, status.toString());
|
||||||
} else {
|
} else {
|
||||||
block.headers().set(HttpNames.STATUS, status.toString());
|
frame.headers().set(HttpNames.STATUS, status.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the URL path header.
|
* Removes the URL path header.
|
||||||
*/
|
*/
|
||||||
public static void removeUrl(int spdyVersion, SpdyHeaderBlock block) {
|
public static void removeUrl(int spdyVersion, SpdyHeadersFrame frame) {
|
||||||
if (spdyVersion < 3) {
|
if (spdyVersion < 3) {
|
||||||
block.headers().remove(Spdy2HttpNames.URL);
|
frame.headers().remove(Spdy2HttpNames.URL);
|
||||||
} else {
|
} else {
|
||||||
block.headers().remove(HttpNames.PATH);
|
frame.headers().remove(HttpNames.PATH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the value of the URL path header.
|
* 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) {
|
if (spdyVersion < 3) {
|
||||||
return block.headers().get(Spdy2HttpNames.URL);
|
return frame.headers().get(Spdy2HttpNames.URL);
|
||||||
} else {
|
} else {
|
||||||
return block.headers().get(HttpNames.PATH);
|
return frame.headers().get(HttpNames.PATH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the URL path header.
|
* 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) {
|
if (spdyVersion < 3) {
|
||||||
block.headers().set(Spdy2HttpNames.URL, path);
|
frame.headers().set(Spdy2HttpNames.URL, path);
|
||||||
} else {
|
} else {
|
||||||
block.headers().set(HttpNames.PATH, path);
|
frame.headers().set(HttpNames.PATH, path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the HTTP version header.
|
* Removes the HTTP version header.
|
||||||
*/
|
*/
|
||||||
public static void removeVersion(int spdyVersion, SpdyHeaderBlock block) {
|
public static void removeVersion(int spdyVersion, SpdyHeadersFrame frame) {
|
||||||
if (spdyVersion < 3) {
|
if (spdyVersion < 3) {
|
||||||
block.headers().remove(Spdy2HttpNames.VERSION);
|
frame.headers().remove(Spdy2HttpNames.VERSION);
|
||||||
} else {
|
} else {
|
||||||
block.headers().remove(HttpNames.VERSION);
|
frame.headers().remove(HttpNames.VERSION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@link HttpVersion} represented by the HTTP version header.
|
* 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 {
|
try {
|
||||||
if (spdyVersion < 3) {
|
if (spdyVersion < 3) {
|
||||||
return HttpVersion.valueOf(block.headers().get(Spdy2HttpNames.VERSION));
|
return HttpVersion.valueOf(frame.headers().get(Spdy2HttpNames.VERSION));
|
||||||
} else {
|
} else {
|
||||||
return HttpVersion.valueOf(block.headers().get(HttpNames.VERSION));
|
return HttpVersion.valueOf(frame.headers().get(HttpNames.VERSION));
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -413,11 +413,11 @@ public abstract class SpdyHeaders implements Iterable<Map.Entry<String, String>>
|
||||||
/**
|
/**
|
||||||
* Sets the HTTP version header.
|
* 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) {
|
if (spdyVersion < 3) {
|
||||||
block.headers().set(Spdy2HttpNames.VERSION, httpVersion.text());
|
frame.headers().set(Spdy2HttpNames.VERSION, httpVersion.text());
|
||||||
} else {
|
} else {
|
||||||
block.headers().set(HttpNames.VERSION, httpVersion.text());
|
frame.headers().set(HttpNames.VERSION, httpVersion.text());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
|
@ -443,7 +443,7 @@ public abstract class SpdyHeaders implements Iterable<Map.Entry<String, String>>
|
||||||
public abstract List<String> getAll(String name);
|
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
|
* @return the {@link List} of the header name-value pairs. An empty list
|
||||||
* if there is no header in this message.
|
* 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);
|
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();
|
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);
|
public abstract SpdyHeaders remove(String name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes all headers from this block.
|
* Removes all headers from this frame.
|
||||||
*/
|
*/
|
||||||
public abstract SpdyHeaders clear();
|
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,
|
* 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
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
@ -16,17 +16,29 @@
|
||||||
package io.netty.handler.codec.spdy;
|
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
|
@Override
|
||||||
SpdyHeadersFrame setStreamId(int streamID);
|
SpdyHeadersFrame setStreamId(int streamID);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
SpdyHeadersFrame setLast(boolean last);
|
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,
|
* 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
|
* 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
|
public final class SpdyHttpCodec
|
||||||
extends CombinedChannelDuplexHandler<SpdyHttpDecoder, SpdyHttpEncoder> {
|
extends CombinedChannelDuplexHandler<SpdyHttpDecoder, SpdyHttpEncoder> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance with the specified decoder options.
|
* 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,
|
* 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
|
* 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,
|
* Decodes {@link SpdySynStreamFrame}s, {@link SpdySynReplyFrame}s,
|
||||||
* and {@link SpdyDataFrame}s into {@link FullHttpRequest}s and {@link FullHttpResponse}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 spdyVersion;
|
||||||
private final int maxContentLength;
|
private final int maxContentLength;
|
||||||
|
@ -91,7 +91,7 @@ public class SpdyHttpDecoder extends MessageToMessageDecoder<SpdyDataOrControlFr
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void decode(ChannelHandlerContext ctx, SpdyDataOrControlFrame msg, MessageList<Object> out)
|
protected void decode(ChannelHandlerContext ctx, SpdyFrame msg, MessageList<Object> out)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
if (msg instanceof SpdySynStreamFrame) {
|
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 {
|
throws Exception {
|
||||||
// Create the first line of the request from the name/value pairs
|
// Create the first line of the request from the name/value pairs
|
||||||
HttpMethod method = SpdyHeaders.getMethod(spdyVersion, requestFrame);
|
HttpMethod method = SpdyHeaders.getMethod(spdyVersion, requestFrame);
|
||||||
|
@ -287,7 +287,7 @@ public class SpdyHttpDecoder extends MessageToMessageDecoder<SpdyDataOrControlFr
|
||||||
return req;
|
return req;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static FullHttpResponse createHttpResponse(int spdyVersion, SpdyHeaderBlock responseFrame)
|
private static FullHttpResponse createHttpResponse(int spdyVersion, SpdyHeadersFrame responseFrame)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
// Create the first line of the response from the name/value pairs
|
// Create the first line of the response from the name/value pairs
|
||||||
HttpResponseStatus status = SpdyHeaders.getStatus(spdyVersion, responseFrame);
|
HttpResponseStatus status = SpdyHeaders.getStatus(spdyVersion, responseFrame);
|
||||||
|
|
|
@ -266,7 +266,7 @@ public class SpdyHttpEncoder extends MessageToMessageEncoder<HttpObject> {
|
||||||
int streamID = SpdyHttpHeaders.getStreamId(httpResponse);
|
int streamID = SpdyHttpHeaders.getStreamId(httpResponse);
|
||||||
SpdyHttpHeaders.removeStreamId(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.
|
// headers are not valid and MUST not be sent.
|
||||||
httpResponse.headers().remove(HttpHeaders.Names.CONNECTION);
|
httpResponse.headers().remove(HttpHeaders.Names.CONNECTION);
|
||||||
httpResponse.headers().remove("Keep-Alive");
|
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,
|
* 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
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
@ -16,9 +16,9 @@
|
||||||
package io.netty.handler.codec.spdy;
|
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.
|
* 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,
|
* 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
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
@ -16,27 +16,23 @@
|
||||||
package io.netty.handler.codec.spdy;
|
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.
|
* Returns the status 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.
|
|
||||||
*/
|
*/
|
||||||
SpdyStreamStatus getStatus();
|
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,
|
* 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
|
* 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;
|
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
|
// Check if we received a data frame for a Stream-ID which is not open
|
||||||
if (!spdySession.isActiveStream(streamID)) {
|
|
||||||
if (streamID <= lastGoodStreamId) {
|
if (!spdySession.isActiveStream(streamId)) {
|
||||||
issueStreamError(ctx, streamID, SpdyStreamStatus.PROTOCOL_ERROR, out);
|
if (streamId <= lastGoodStreamId) {
|
||||||
|
issueStreamError(ctx, streamId, SpdyStreamStatus.PROTOCOL_ERROR, out);
|
||||||
} else if (!sentGoAwayFrame) {
|
} else if (!sentGoAwayFrame) {
|
||||||
issueStreamError(ctx, streamID, SpdyStreamStatus.INVALID_STREAM, out);
|
issueStreamError(ctx, streamId, SpdyStreamStatus.INVALID_STREAM, out);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we received a data frame for a stream which is half-closed
|
// 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we received a data frame before receiving a SYN_REPLY
|
// Check if we received a data frame before receiving a SYN_REPLY
|
||||||
if (!isRemoteInitiatedID(streamID) && !spdySession.hasReceivedReply(streamID)) {
|
if (!isRemoteInitiatedID(streamId) && !spdySession.hasReceivedReply(streamId)) {
|
||||||
issueStreamError(ctx, streamID, SpdyStreamStatus.PROTOCOL_ERROR, out);
|
issueStreamError(ctx, streamId, SpdyStreamStatus.PROTOCOL_ERROR, out);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,15 +170,15 @@ public class SpdySessionHandler
|
||||||
if (flowControl) {
|
if (flowControl) {
|
||||||
// Update receive window size
|
// Update receive window size
|
||||||
int deltaWindowSize = -1 * spdyDataFrame.content().readableBytes();
|
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
|
// 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.
|
// 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.
|
// 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
|
// This difference is stored for the session when writing the SETTINGS frame
|
||||||
// and is cleared once we send a WINDOW_UPDATE frame.
|
// and is cleared once we send a WINDOW_UPDATE frame.
|
||||||
if (newWindowSize < spdySession.getReceiveWindowSizeLowerBound(streamID)) {
|
if (newWindowSize < spdySession.getReceiveWindowSizeLowerBound(streamId)) {
|
||||||
issueStreamError(ctx, streamID, SpdyStreamStatus.FLOW_CONTROL_ERROR, out);
|
issueStreamError(ctx, streamId, SpdyStreamStatus.FLOW_CONTROL_ERROR, out);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,7 +186,7 @@ public class SpdySessionHandler
|
||||||
// Send data frames upstream in initialReceiveWindowSize chunks
|
// Send data frames upstream in initialReceiveWindowSize chunks
|
||||||
if (newWindowSize < 0) {
|
if (newWindowSize < 0) {
|
||||||
while (spdyDataFrame.content().readableBytes() > initialReceiveWindowSize) {
|
while (spdyDataFrame.content().readableBytes() > initialReceiveWindowSize) {
|
||||||
SpdyDataFrame partialDataFrame = new DefaultSpdyDataFrame(streamID,
|
SpdyDataFrame partialDataFrame = new DefaultSpdyDataFrame(streamId,
|
||||||
spdyDataFrame.content().readSlice(initialReceiveWindowSize).retain());
|
spdyDataFrame.content().readSlice(initialReceiveWindowSize).retain());
|
||||||
ctx.write(partialDataFrame);
|
ctx.write(partialDataFrame);
|
||||||
}
|
}
|
||||||
|
@ -193,16 +195,16 @@ public class SpdySessionHandler
|
||||||
// Send a WINDOW_UPDATE frame if less than half the window size remains
|
// Send a WINDOW_UPDATE frame if less than half the window size remains
|
||||||
if (newWindowSize <= initialReceiveWindowSize / 2 && !spdyDataFrame.isLast()) {
|
if (newWindowSize <= initialReceiveWindowSize / 2 && !spdyDataFrame.isLast()) {
|
||||||
deltaWindowSize = initialReceiveWindowSize - newWindowSize;
|
deltaWindowSize = initialReceiveWindowSize - newWindowSize;
|
||||||
spdySession.updateReceiveWindowSize(streamID, deltaWindowSize);
|
spdySession.updateReceiveWindowSize(streamId, deltaWindowSize);
|
||||||
SpdyWindowUpdateFrame spdyWindowUpdateFrame =
|
SpdyWindowUpdateFrame spdyWindowUpdateFrame =
|
||||||
new DefaultSpdyWindowUpdateFrame(streamID, deltaWindowSize);
|
new DefaultSpdyWindowUpdateFrame(streamId, deltaWindowSize);
|
||||||
ctx.write(spdyWindowUpdateFrame);
|
ctx.write(spdyWindowUpdateFrame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close the remote side of the stream if this is the last frame
|
// Close the remote side of the stream if this is the last frame
|
||||||
if (spdyDataFrame.isLast()) {
|
if (spdyDataFrame.isLast()) {
|
||||||
halfCloseStream(streamID, true);
|
halfCloseStream(streamId, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (msg instanceof SpdySynStreamFrame) {
|
} else if (msg instanceof SpdySynStreamFrame) {
|
||||||
|
@ -222,18 +224,18 @@ public class SpdySessionHandler
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SpdySynStreamFrame spdySynStreamFrame = (SpdySynStreamFrame) msg;
|
SpdySynStreamFrame spdySynStreamFrame = (SpdySynStreamFrame) msg;
|
||||||
int streamID = spdySynStreamFrame.getStreamId();
|
int streamId = spdySynStreamFrame.getStreamId();
|
||||||
|
|
||||||
// Check if we received a valid SYN_STREAM frame
|
// Check if we received a valid SYN_STREAM frame
|
||||||
if (spdySynStreamFrame.isInvalid() ||
|
if (spdySynStreamFrame.isInvalid() ||
|
||||||
!isRemoteInitiatedID(streamID) ||
|
!isRemoteInitiatedID(streamId) ||
|
||||||
spdySession.isActiveStream(streamID)) {
|
spdySession.isActiveStream(streamId)) {
|
||||||
issueStreamError(ctx, streamID, SpdyStreamStatus.PROTOCOL_ERROR, out);
|
issueStreamError(ctx, streamId, SpdyStreamStatus.PROTOCOL_ERROR, out);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stream-IDs must be monotonically increasing
|
// Stream-IDs must be monotonically increasing
|
||||||
if (streamID <= lastGoodStreamId) {
|
if (streamId <= lastGoodStreamId) {
|
||||||
issueSessionError(ctx, SpdySessionStatus.PROTOCOL_ERROR);
|
issueSessionError(ctx, SpdySessionStatus.PROTOCOL_ERROR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -242,8 +244,8 @@ public class SpdySessionHandler
|
||||||
byte priority = spdySynStreamFrame.getPriority();
|
byte priority = spdySynStreamFrame.getPriority();
|
||||||
boolean remoteSideClosed = spdySynStreamFrame.isLast();
|
boolean remoteSideClosed = spdySynStreamFrame.isLast();
|
||||||
boolean localSideClosed = spdySynStreamFrame.isUnidirectional();
|
boolean localSideClosed = spdySynStreamFrame.isUnidirectional();
|
||||||
if (!acceptStream(streamID, priority, remoteSideClosed, localSideClosed)) {
|
if (!acceptStream(streamId, priority, remoteSideClosed, localSideClosed)) {
|
||||||
issueStreamError(ctx, streamID, SpdyStreamStatus.REFUSED_STREAM, out);
|
issueStreamError(ctx, streamId, SpdyStreamStatus.REFUSED_STREAM, out);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,27 +259,27 @@ public class SpdySessionHandler
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SpdySynReplyFrame spdySynReplyFrame = (SpdySynReplyFrame) msg;
|
SpdySynReplyFrame spdySynReplyFrame = (SpdySynReplyFrame) msg;
|
||||||
int streamID = spdySynReplyFrame.getStreamId();
|
int streamId = spdySynReplyFrame.getStreamId();
|
||||||
|
|
||||||
// Check if we received a valid SYN_REPLY frame
|
// Check if we received a valid SYN_REPLY frame
|
||||||
if (spdySynReplyFrame.isInvalid() ||
|
if (spdySynReplyFrame.isInvalid() ||
|
||||||
isRemoteInitiatedID(streamID) ||
|
isRemoteInitiatedID(streamId) ||
|
||||||
spdySession.isRemoteSideClosed(streamID)) {
|
spdySession.isRemoteSideClosed(streamId)) {
|
||||||
issueStreamError(ctx, streamID, SpdyStreamStatus.INVALID_STREAM, out);
|
issueStreamError(ctx, streamId, SpdyStreamStatus.INVALID_STREAM, out);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we have received multiple frames for the same Stream-ID
|
// Check if we have received multiple frames for the same Stream-ID
|
||||||
if (spdySession.hasReceivedReply(streamID)) {
|
if (spdySession.hasReceivedReply(streamId)) {
|
||||||
issueStreamError(ctx, streamID, SpdyStreamStatus.STREAM_IN_USE, out);
|
issueStreamError(ctx, streamId, SpdyStreamStatus.STREAM_IN_USE, out);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
spdySession.receivedReply(streamID);
|
spdySession.receivedReply(streamId);
|
||||||
|
|
||||||
// Close the remote side of the stream if this is the last frame
|
// Close the remote side of the stream if this is the last frame
|
||||||
if (spdySynReplyFrame.isLast()) {
|
if (spdySynReplyFrame.isLast()) {
|
||||||
halfCloseStream(streamID, true);
|
halfCloseStream(streamId, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (msg instanceof SpdyRstStreamFrame) {
|
} else if (msg instanceof SpdyRstStreamFrame) {
|
||||||
|
@ -351,22 +353,22 @@ public class SpdySessionHandler
|
||||||
} else if (msg instanceof SpdyHeadersFrame) {
|
} else if (msg instanceof SpdyHeadersFrame) {
|
||||||
|
|
||||||
SpdyHeadersFrame spdyHeadersFrame = (SpdyHeadersFrame) msg;
|
SpdyHeadersFrame spdyHeadersFrame = (SpdyHeadersFrame) msg;
|
||||||
int streamID = spdyHeadersFrame.getStreamId();
|
int streamId = spdyHeadersFrame.getStreamId();
|
||||||
|
|
||||||
// Check if we received a valid HEADERS frame
|
// Check if we received a valid HEADERS frame
|
||||||
if (spdyHeadersFrame.isInvalid()) {
|
if (spdyHeadersFrame.isInvalid()) {
|
||||||
issueStreamError(ctx, streamID, SpdyStreamStatus.PROTOCOL_ERROR, out);
|
issueStreamError(ctx, streamId, SpdyStreamStatus.PROTOCOL_ERROR, out);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spdySession.isRemoteSideClosed(streamID)) {
|
if (spdySession.isRemoteSideClosed(streamId)) {
|
||||||
issueStreamError(ctx, streamID, SpdyStreamStatus.INVALID_STREAM, out);
|
issueStreamError(ctx, streamId, SpdyStreamStatus.INVALID_STREAM, out);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close the remote side of the stream if this is the last frame
|
// Close the remote side of the stream if this is the last frame
|
||||||
if (spdyHeadersFrame.isLast()) {
|
if (spdyHeadersFrame.isLast()) {
|
||||||
halfCloseStream(streamID, true);
|
halfCloseStream(streamId, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (msg instanceof SpdyWindowUpdateFrame) {
|
} else if (msg instanceof SpdyWindowUpdateFrame) {
|
||||||
|
@ -383,21 +385,21 @@ public class SpdySessionHandler
|
||||||
|
|
||||||
if (flowControl) {
|
if (flowControl) {
|
||||||
SpdyWindowUpdateFrame spdyWindowUpdateFrame = (SpdyWindowUpdateFrame) msg;
|
SpdyWindowUpdateFrame spdyWindowUpdateFrame = (SpdyWindowUpdateFrame) msg;
|
||||||
int streamID = spdyWindowUpdateFrame.getStreamId();
|
int streamId = spdyWindowUpdateFrame.getStreamId();
|
||||||
int deltaWindowSize = spdyWindowUpdateFrame.getDeltaWindowSize();
|
int deltaWindowSize = spdyWindowUpdateFrame.getDeltaWindowSize();
|
||||||
|
|
||||||
// Ignore frames for half-closed streams
|
// Ignore frames for half-closed streams
|
||||||
if (spdySession.isLocalSideClosed(streamID)) {
|
if (spdySession.isLocalSideClosed(streamId)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for numerical overflow
|
// Check for numerical overflow
|
||||||
if (spdySession.getSendWindowSize(streamID) > Integer.MAX_VALUE - deltaWindowSize) {
|
if (spdySession.getSendWindowSize(streamId) > Integer.MAX_VALUE - deltaWindowSize) {
|
||||||
issueStreamError(ctx, streamID, SpdyStreamStatus.FLOW_CONTROL_ERROR, out);
|
issueStreamError(ctx, streamId, SpdyStreamStatus.FLOW_CONTROL_ERROR, out);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSendWindowSize(streamID, deltaWindowSize, out);
|
updateSendWindowSize(streamId, deltaWindowSize, out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -459,10 +461,10 @@ public class SpdySessionHandler
|
||||||
if (msg instanceof SpdyDataFrame) {
|
if (msg instanceof SpdyDataFrame) {
|
||||||
|
|
||||||
SpdyDataFrame spdyDataFrame = (SpdyDataFrame) msg;
|
SpdyDataFrame spdyDataFrame = (SpdyDataFrame) msg;
|
||||||
final int streamID = spdyDataFrame.getStreamId();
|
final int streamId = spdyDataFrame.getStreamId();
|
||||||
|
|
||||||
// Frames must not be sent on half-closed streams
|
// Frames must not be sent on half-closed streams
|
||||||
if (spdySession.isLocalSideClosed(streamID)) {
|
if (spdySession.isLocalSideClosed(streamId)) {
|
||||||
throw PROTOCOL_EXCEPTION;
|
throw PROTOCOL_EXCEPTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -482,22 +484,22 @@ public class SpdySessionHandler
|
||||||
if (flowControl) {
|
if (flowControl) {
|
||||||
synchronized (flowControlLock) {
|
synchronized (flowControlLock) {
|
||||||
int dataLength = spdyDataFrame.content().readableBytes();
|
int dataLength = spdyDataFrame.content().readableBytes();
|
||||||
int sendWindowSize = spdySession.getSendWindowSize(streamID);
|
int sendWindowSize = spdySession.getSendWindowSize(streamId);
|
||||||
|
|
||||||
if (sendWindowSize <= 0) {
|
if (sendWindowSize <= 0) {
|
||||||
// Stream is stalled -- enqueue Data frame and return
|
// Stream is stalled -- enqueue Data frame and return
|
||||||
spdySession.putPendingWrite(streamID, spdyDataFrame);
|
spdySession.putPendingWrite(streamId, spdyDataFrame);
|
||||||
return;
|
return;
|
||||||
} else if (sendWindowSize < dataLength) {
|
} else if (sendWindowSize < dataLength) {
|
||||||
// Stream is not stalled but we cannot send the entire frame
|
// 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
|
// 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());
|
spdyDataFrame.content().readSlice(sendWindowSize).retain());
|
||||||
|
|
||||||
// Enqueue the remaining data (will be the first frame queued)
|
// 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.
|
// 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.
|
// Close the stream on write failures that leaves the transfer window in a corrupt state.
|
||||||
|
@ -511,7 +513,7 @@ public class SpdySessionHandler
|
||||||
// @Override
|
// @Override
|
||||||
// public void operationComplete(ChannelFuture future) throws Exception {
|
// public void operationComplete(ChannelFuture future) throws Exception {
|
||||||
// if (!future.isSuccess()) {
|
// if (!future.isSuccess()) {
|
||||||
// issueStreamError(context, streamID, SpdyStreamStatus.INTERNAL_ERROR);
|
// issueStreamError(context, streamId, SpdyStreamStatus.INTERNAL_ERROR);
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
//});
|
//});
|
||||||
|
@ -520,7 +522,7 @@ public class SpdySessionHandler
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
// Window size is large enough to send entire data frame
|
// 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.
|
// 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.
|
// Close the stream on write failures that leaves the transfer window in a corrupt state.
|
||||||
|
@ -533,7 +535,7 @@ public class SpdySessionHandler
|
||||||
// @Override
|
// @Override
|
||||||
// public void operationComplete(ChannelFuture future) throws Exception {
|
// public void operationComplete(ChannelFuture future) throws Exception {
|
||||||
// if (!future.isSuccess()) {
|
// 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
|
// Close the local side of the stream if this is the last frame
|
||||||
if (spdyDataFrame.isLast()) {
|
if (spdyDataFrame.isLast()) {
|
||||||
halfCloseStream(streamID, false);
|
halfCloseStream(streamId, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (msg instanceof SpdySynStreamFrame) {
|
} else if (msg instanceof SpdySynStreamFrame) {
|
||||||
|
|
||||||
SpdySynStreamFrame spdySynStreamFrame = (SpdySynStreamFrame) msg;
|
SpdySynStreamFrame spdySynStreamFrame = (SpdySynStreamFrame) msg;
|
||||||
int streamID = spdySynStreamFrame.getStreamId();
|
int streamId = spdySynStreamFrame.getStreamId();
|
||||||
|
|
||||||
if (isRemoteInitiatedID(streamID)) {
|
if (isRemoteInitiatedID(streamId)) {
|
||||||
throw PROTOCOL_EXCEPTION;
|
throw PROTOCOL_EXCEPTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte priority = spdySynStreamFrame.getPriority();
|
byte priority = spdySynStreamFrame.getPriority();
|
||||||
boolean remoteSideClosed = spdySynStreamFrame.isUnidirectional();
|
boolean remoteSideClosed = spdySynStreamFrame.isUnidirectional();
|
||||||
boolean localSideClosed = spdySynStreamFrame.isLast();
|
boolean localSideClosed = spdySynStreamFrame.isLast();
|
||||||
if (!acceptStream(streamID, priority, remoteSideClosed, localSideClosed)) {
|
if (!acceptStream(streamId, priority, remoteSideClosed, localSideClosed)) {
|
||||||
throw PROTOCOL_EXCEPTION;
|
throw PROTOCOL_EXCEPTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (msg instanceof SpdySynReplyFrame) {
|
} else if (msg instanceof SpdySynReplyFrame) {
|
||||||
|
|
||||||
SpdySynReplyFrame spdySynReplyFrame = (SpdySynReplyFrame) msg;
|
SpdySynReplyFrame spdySynReplyFrame = (SpdySynReplyFrame) msg;
|
||||||
int streamID = spdySynReplyFrame.getStreamId();
|
int streamId = spdySynReplyFrame.getStreamId();
|
||||||
|
|
||||||
// Frames must not be sent on half-closed streams
|
// Frames must not be sent on half-closed streams
|
||||||
if (!isRemoteInitiatedID(streamID) || spdySession.isLocalSideClosed(streamID)) {
|
if (!isRemoteInitiatedID(streamId) || spdySession.isLocalSideClosed(streamId)) {
|
||||||
throw PROTOCOL_EXCEPTION;
|
throw PROTOCOL_EXCEPTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close the local side of the stream if this is the last frame
|
// Close the local side of the stream if this is the last frame
|
||||||
if (spdySynReplyFrame.isLast()) {
|
if (spdySynReplyFrame.isLast()) {
|
||||||
halfCloseStream(streamID, false);
|
halfCloseStream(streamId, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (msg instanceof SpdyRstStreamFrame) {
|
} else if (msg instanceof SpdyRstStreamFrame) {
|
||||||
|
@ -627,16 +629,16 @@ public class SpdySessionHandler
|
||||||
} else if (msg instanceof SpdyHeadersFrame) {
|
} else if (msg instanceof SpdyHeadersFrame) {
|
||||||
|
|
||||||
SpdyHeadersFrame spdyHeadersFrame = (SpdyHeadersFrame) msg;
|
SpdyHeadersFrame spdyHeadersFrame = (SpdyHeadersFrame) msg;
|
||||||
int streamID = spdyHeadersFrame.getStreamId();
|
int streamId = spdyHeadersFrame.getStreamId();
|
||||||
|
|
||||||
// Frames must not be sent on half-closed streams
|
// Frames must not be sent on half-closed streams
|
||||||
if (spdySession.isLocalSideClosed(streamID)) {
|
if (spdySession.isLocalSideClosed(streamId)) {
|
||||||
throw PROTOCOL_EXCEPTION;
|
throw PROTOCOL_EXCEPTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close the local side of the stream if this is the last frame
|
// Close the local side of the stream if this is the last frame
|
||||||
if (spdyHeadersFrame.isLast()) {
|
if (spdyHeadersFrame.isLast()) {
|
||||||
halfCloseStream(streamID, false);
|
halfCloseStream(streamId, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (msg instanceof SpdyWindowUpdateFrame) {
|
} else if (msg instanceof SpdyWindowUpdateFrame) {
|
||||||
|
@ -675,12 +677,11 @@ public class SpdySessionHandler
|
||||||
* Note: this is only called by the worker thread
|
* Note: this is only called by the worker thread
|
||||||
*/
|
*/
|
||||||
private void issueStreamError(
|
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);
|
SpdyRstStreamFrame spdyRstStreamFrame = new DefaultSpdyRstStreamFrame(streamId, status);
|
||||||
removeStream(ctx, streamID);
|
|
||||||
|
|
||||||
SpdyRstStreamFrame spdyRstStreamFrame = new DefaultSpdyRstStreamFrame(streamID, status);
|
|
||||||
ctx.write(spdyRstStreamFrame);
|
ctx.write(spdyRstStreamFrame);
|
||||||
if (fireMessageReceived) {
|
if (fireMessageReceived) {
|
||||||
in.add(spdyRstStreamFrame);
|
in.add(spdyRstStreamFrame);
|
||||||
|
@ -694,8 +695,8 @@ public class SpdySessionHandler
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private boolean isRemoteInitiatedID(int id) {
|
private boolean isRemoteInitiatedID(int id) {
|
||||||
boolean serverID = SpdyCodecUtil.isServerId(id);
|
boolean serverId = SpdyCodecUtil.isServerId(id);
|
||||||
return server && !serverID || !server && serverID;
|
return server && !serverId || !server && serverId;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateConcurrentStreams(int newConcurrentStreams, boolean remote) {
|
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
|
// need to synchronize accesses to sentGoAwayFrame, lastGoodStreamId, and initial window sizes
|
||||||
private synchronized boolean acceptStream(
|
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
|
// Cannot initiate any new streams after receiving or sending GOAWAY
|
||||||
if (receivedGoAwayFrame || sentGoAwayFrame) {
|
if (receivedGoAwayFrame || sentGoAwayFrame) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -753,27 +754,27 @@ public class SpdySessionHandler
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
spdySession.acceptStream(
|
spdySession.acceptStream(
|
||||||
streamID, priority, remoteSideClosed, localSideClosed,
|
streamId, priority, remoteSideClosed, localSideClosed,
|
||||||
initialSendWindowSize, initialReceiveWindowSize);
|
initialSendWindowSize, initialReceiveWindowSize);
|
||||||
if (isRemoteInitiatedID(streamID)) {
|
if (isRemoteInitiatedID(streamId)) {
|
||||||
lastGoodStreamId = streamID;
|
lastGoodStreamId = streamId;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void halfCloseStream(int streamID, boolean remote) {
|
private void halfCloseStream(int streamId, boolean remote) {
|
||||||
if (remote) {
|
if (remote) {
|
||||||
spdySession.closeRemoteSide(streamID);
|
spdySession.closeRemoteSide(streamId);
|
||||||
} else {
|
} else {
|
||||||
spdySession.closeLocalSide(streamID);
|
spdySession.closeLocalSide(streamId);
|
||||||
}
|
}
|
||||||
if (closeSessionFuture != null && spdySession.noActiveStreams()) {
|
if (closeSessionFuture != null && spdySession.noActiveStreams()) {
|
||||||
closeSessionFuture.trySuccess();
|
closeSessionFuture.trySuccess();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeStream(ChannelHandlerContext ctx, int streamID) {
|
private void removeStream(ChannelHandlerContext ctx, int streamId) {
|
||||||
if (spdySession.removeStream(streamID)) {
|
if (spdySession.removeStream(streamId)) {
|
||||||
ctx.fireExceptionCaught(STREAM_CLOSED);
|
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) {
|
synchronized (flowControlLock) {
|
||||||
int newWindowSize = spdySession.updateSendWindowSize(streamID, deltaWindowSize);
|
int newWindowSize = spdySession.updateSendWindowSize(streamId, deltaWindowSize);
|
||||||
|
|
||||||
while (newWindowSize > 0) {
|
while (newWindowSize > 0) {
|
||||||
// Check if we have unblocked a stalled stream
|
// Check if we have unblocked a stalled stream
|
||||||
SpdyDataFrame spdyDataFrame = (SpdyDataFrame) spdySession.getPendingWrite(streamID);
|
SpdyDataFrame spdyDataFrame = (SpdyDataFrame) spdySession.getPendingWrite(streamId);
|
||||||
if (spdyDataFrame == null) {
|
if (spdyDataFrame == null) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -797,8 +798,8 @@ public class SpdySessionHandler
|
||||||
|
|
||||||
if (newWindowSize >= dataFrameSize) {
|
if (newWindowSize >= dataFrameSize) {
|
||||||
// Window size is large enough to send entire data frame
|
// Window size is large enough to send entire data frame
|
||||||
spdySession.removePendingWrite(streamID);
|
spdySession.removePendingWrite(streamId);
|
||||||
newWindowSize = spdySession.updateSendWindowSize(streamID, -1 * dataFrameSize);
|
newWindowSize = spdySession.updateSendWindowSize(streamId, -1 * dataFrameSize);
|
||||||
|
|
||||||
// The transfer window size is pre-decremented when sending a data frame downstream.
|
// 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.
|
// Close the stream on write failures that leaves the transfer window in a corrupt state.
|
||||||
|
@ -811,23 +812,23 @@ public class SpdySessionHandler
|
||||||
// @Override
|
// @Override
|
||||||
// public void operationComplete(ChannelFuture future) throws Exception {
|
// public void operationComplete(ChannelFuture future) throws Exception {
|
||||||
// if (!future.isSuccess()) {
|
// 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
|
// Close the local side of the stream if this is the last frame
|
||||||
if (spdyDataFrame.isLast()) {
|
if (spdyDataFrame.isLast()) {
|
||||||
halfCloseStream(streamID, false);
|
halfCloseStream(streamId, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
out.add(spdyDataFrame);
|
out.add(spdyDataFrame);
|
||||||
} else {
|
} else {
|
||||||
// We can send a partial frame
|
// 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
|
// 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());
|
spdyDataFrame.content().readSlice(newWindowSize).retain());
|
||||||
|
|
||||||
// The transfer window size is pre-decremented when sending a data frame downstream.
|
// The transfer window size is pre-decremented when sending a data frame downstream.
|
||||||
|
@ -842,7 +843,7 @@ public class SpdySessionHandler
|
||||||
// @Override
|
// @Override
|
||||||
// public void operationComplete(ChannelFuture future) throws Exception {
|
// public void operationComplete(ChannelFuture future) throws Exception {
|
||||||
// if (!future.isSuccess()) {
|
// 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,
|
* 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
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
package io.netty.handler.codec.spdy;
|
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> {
|
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.
|
* 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.
|
* will be returned. Otherwise, a new instance will be returned.
|
||||||
*/
|
*/
|
||||||
public static SpdySessionStatus valueOf(int code) {
|
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() {
|
public int getCode() {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the getStatus phrase of this getStatus.
|
* Returns the status phrase of this status.
|
||||||
*/
|
*/
|
||||||
public String getStatusPhrase() {
|
public String getStatusPhrase() {
|
||||||
return statusPhrase;
|
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,
|
* 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
|
* 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;
|
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_UPLOAD_BANDWIDTH = 1;
|
||||||
int SETTINGS_DOWNLOAD_BANDWIDTH = 2;
|
int SETTINGS_DOWNLOAD_BANDWIDTH = 2;
|
||||||
|
|
|
@ -16,9 +16,9 @@
|
||||||
package io.netty.handler.codec.spdy;
|
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.
|
* 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,
|
* 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
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
package io.netty.handler.codec.spdy;
|
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> {
|
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.
|
* 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.
|
* will be returned. Otherwise, a new instance will be returned.
|
||||||
*/
|
*/
|
||||||
public static SpdyStreamStatus valueOf(int code) {
|
public static SpdyStreamStatus valueOf(int code) {
|
||||||
if (code == 0) {
|
if (code == 0) {
|
||||||
throw new IllegalArgumentException(
|
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) {
|
switch (code) {
|
||||||
|
@ -136,7 +136,7 @@ public class SpdyStreamStatus implements Comparable<SpdyStreamStatus> {
|
||||||
public SpdyStreamStatus(int code, String statusPhrase) {
|
public SpdyStreamStatus(int code, String statusPhrase) {
|
||||||
if (code == 0) {
|
if (code == 0) {
|
||||||
throw new IllegalArgumentException(
|
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) {
|
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() {
|
public int getCode() {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the getStatus phrase of this getStatus.
|
* Returns the status phrase of this status.
|
||||||
*/
|
*/
|
||||||
public String getStatusPhrase() {
|
public String getStatusPhrase() {
|
||||||
return statusPhrase;
|
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,
|
* 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
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
@ -16,9 +16,9 @@
|
||||||
package io.netty.handler.codec.spdy;
|
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
|
@Override
|
||||||
SpdySynReplyFrame setStreamId(int streamID);
|
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,
|
* 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
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
@ -16,9 +16,9 @@
|
||||||
package io.netty.handler.codec.spdy;
|
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.
|
* 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,
|
* 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
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
@ -16,9 +16,9 @@
|
||||||
package io.netty.handler.codec.spdy;
|
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.
|
* Returns the Stream-ID of this frame.
|
||||||
|
@ -26,7 +26,7 @@ public interface SpdyWindowUpdateFrame extends SpdyControlFrame {
|
||||||
int getStreamId();
|
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);
|
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,
|
* 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
|
* 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.ChannelHandlerContext;
|
||||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||||
import io.netty.channel.MessageList;
|
import io.netty.channel.MessageList;
|
||||||
|
import io.netty.channel.SimpleChannelInboundHandler;
|
||||||
import io.netty.channel.embedded.EmbeddedChannel;
|
import io.netty.channel.embedded.EmbeddedChannel;
|
||||||
import io.netty.util.internal.logging.InternalLogger;
|
import io.netty.util.internal.logging.InternalLogger;
|
||||||
import io.netty.util.internal.logging.InternalLoggerFactory;
|
import io.netty.util.internal.logging.InternalLoggerFactory;
|
||||||
|
@ -40,40 +41,25 @@ public class SpdySessionHandlerTest {
|
||||||
closeMessage.setValue(closeSignal, 0);
|
closeMessage.setValue(closeSignal, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void assertHeaderBlock(SpdyHeaderBlock received, SpdyHeaderBlock expected) {
|
private static void assertDataFrame(Object msg, int streamId, boolean last) {
|
||||||
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) {
|
|
||||||
assertNotNull(msg);
|
assertNotNull(msg);
|
||||||
assertTrue(msg instanceof SpdyDataFrame);
|
assertTrue(msg instanceof SpdyDataFrame);
|
||||||
SpdyDataFrame spdyDataFrame = (SpdyDataFrame) msg;
|
SpdyDataFrame spdyDataFrame = (SpdyDataFrame) msg;
|
||||||
assertEquals(spdyDataFrame.getStreamId(), streamID);
|
assertEquals(spdyDataFrame.getStreamId(), streamId);
|
||||||
assertEquals(spdyDataFrame.isLast(), last);
|
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);
|
assertNotNull(msg);
|
||||||
assertTrue(msg instanceof SpdySynReplyFrame);
|
assertTrue(msg instanceof SpdySynReplyFrame);
|
||||||
SpdySynReplyFrame spdySynReplyFrame = (SpdySynReplyFrame) msg;
|
assertHeaders(msg, streamId, last, headers);
|
||||||
assertEquals(spdySynReplyFrame.getStreamId(), streamID);
|
|
||||||
assertEquals(spdySynReplyFrame.isLast(), last);
|
|
||||||
assertHeaderBlock(spdySynReplyFrame, headers);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void assertRstStream(Object msg, int streamID, SpdyStreamStatus status) {
|
private static void assertRstStream(Object msg, int streamId, SpdyStreamStatus status) {
|
||||||
assertNotNull(msg);
|
assertNotNull(msg);
|
||||||
assertTrue(msg instanceof SpdyRstStreamFrame);
|
assertTrue(msg instanceof SpdyRstStreamFrame);
|
||||||
SpdyRstStreamFrame spdyRstStreamFrame = (SpdyRstStreamFrame) msg;
|
SpdyRstStreamFrame spdyRstStreamFrame = (SpdyRstStreamFrame) msg;
|
||||||
assertEquals(spdyRstStreamFrame.getStreamId(), streamID);
|
assertEquals(spdyRstStreamFrame.getStreamId(), streamId);
|
||||||
assertEquals(spdyRstStreamFrame.getStatus(), status);
|
assertEquals(spdyRstStreamFrame.getStatus(), status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,19 +70,28 @@ public class SpdySessionHandlerTest {
|
||||||
assertEquals(spdyPingFrame.getId(), id);
|
assertEquals(spdyPingFrame.getId(), id);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void assertGoAway(Object msg, int lastGoodStreamID) {
|
private static void assertGoAway(Object msg, int lastGoodStreamId) {
|
||||||
assertNotNull(msg);
|
assertNotNull(msg);
|
||||||
assertTrue(msg instanceof SpdyGoAwayFrame);
|
assertTrue(msg instanceof SpdyGoAwayFrame);
|
||||||
SpdyGoAwayFrame spdyGoAwayFrame = (SpdyGoAwayFrame) msg;
|
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);
|
assertNotNull(msg);
|
||||||
assertTrue(msg instanceof SpdyHeadersFrame);
|
assertTrue(msg instanceof SpdyHeadersFrame);
|
||||||
SpdyHeadersFrame spdyHeadersFrame = (SpdyHeadersFrame) msg;
|
SpdyHeadersFrame spdyHeadersFrame = (SpdyHeadersFrame) msg;
|
||||||
assertEquals(spdyHeadersFrame.getStreamId(), streamID);
|
assertEquals(spdyHeadersFrame.getStreamId(), streamId);
|
||||||
assertHeaderBlock(spdyHeadersFrame, headers);
|
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) {
|
private static void testSpdySessionHandler(int version, boolean server) {
|
||||||
|
@ -107,71 +102,71 @@ public class SpdySessionHandlerTest {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int localStreamID = server ? 1 : 2;
|
int localStreamId = server ? 1 : 2;
|
||||||
int remoteStreamID = server ? 2 : 1;
|
int remoteStreamId = server ? 2 : 1;
|
||||||
|
|
||||||
SpdyPingFrame localPingFrame = new DefaultSpdyPingFrame(localStreamID);
|
SpdyPingFrame localPingFrame = new DefaultSpdyPingFrame(localStreamId);
|
||||||
SpdyPingFrame remotePingFrame = new DefaultSpdyPingFrame(remoteStreamID);
|
SpdyPingFrame remotePingFrame = new DefaultSpdyPingFrame(remoteStreamId);
|
||||||
|
|
||||||
SpdySynStreamFrame spdySynStreamFrame =
|
SpdySynStreamFrame spdySynStreamFrame =
|
||||||
new DefaultSpdySynStreamFrame(localStreamID, 0, (byte) 0);
|
new DefaultSpdySynStreamFrame(localStreamId, 0, (byte) 0);
|
||||||
spdySynStreamFrame.headers().set("Compression", "test");
|
spdySynStreamFrame.headers().set("Compression", "test");
|
||||||
|
|
||||||
SpdyDataFrame spdyDataFrame = new DefaultSpdyDataFrame(localStreamID);
|
SpdyDataFrame spdyDataFrame = new DefaultSpdyDataFrame(localStreamId);
|
||||||
spdyDataFrame.setLast(true);
|
spdyDataFrame.setLast(true);
|
||||||
|
|
||||||
// Check if session handler returns INVALID_STREAM if it receives
|
// Check if session handler returns INVALID_STREAM if it receives
|
||||||
// a data frame for a Stream-ID that is not open
|
// a data frame for a Stream-ID that is not open
|
||||||
sessionHandler.writeInbound(new DefaultSpdyDataFrame(localStreamID));
|
sessionHandler.writeInbound(new DefaultSpdyDataFrame(localStreamId));
|
||||||
assertRstStream(sessionHandler.readOutbound(), localStreamID, SpdyStreamStatus.INVALID_STREAM);
|
assertRstStream(sessionHandler.readOutbound(), localStreamId, SpdyStreamStatus.INVALID_STREAM);
|
||||||
assertNull(sessionHandler.readOutbound());
|
assertNull(sessionHandler.readOutbound());
|
||||||
|
|
||||||
// Check if session handler returns PROTOCOL_ERROR if it receives
|
// Check if session handler returns PROTOCOL_ERROR if it receives
|
||||||
// a data frame for a Stream-ID before receiving a SYN_REPLY frame
|
// a data frame for a Stream-ID before receiving a SYN_REPLY frame
|
||||||
sessionHandler.writeInbound(new DefaultSpdyDataFrame(remoteStreamID));
|
sessionHandler.writeInbound(new DefaultSpdyDataFrame(remoteStreamId));
|
||||||
assertRstStream(sessionHandler.readOutbound(), remoteStreamID, SpdyStreamStatus.PROTOCOL_ERROR);
|
assertRstStream(sessionHandler.readOutbound(), remoteStreamId, SpdyStreamStatus.PROTOCOL_ERROR);
|
||||||
assertNull(sessionHandler.readOutbound());
|
assertNull(sessionHandler.readOutbound());
|
||||||
remoteStreamID += 2;
|
remoteStreamId += 2;
|
||||||
|
|
||||||
// Check if session handler returns PROTOCOL_ERROR if it receives
|
// Check if session handler returns PROTOCOL_ERROR if it receives
|
||||||
// multiple SYN_REPLY frames for the same active Stream-ID
|
// multiple SYN_REPLY frames for the same active Stream-ID
|
||||||
sessionHandler.writeInbound(new DefaultSpdySynReplyFrame(remoteStreamID));
|
sessionHandler.writeInbound(new DefaultSpdySynReplyFrame(remoteStreamId));
|
||||||
assertNull(sessionHandler.readOutbound());
|
assertNull(sessionHandler.readOutbound());
|
||||||
sessionHandler.writeInbound(new DefaultSpdySynReplyFrame(remoteStreamID));
|
sessionHandler.writeInbound(new DefaultSpdySynReplyFrame(remoteStreamId));
|
||||||
assertRstStream(sessionHandler.readOutbound(), remoteStreamID, SpdyStreamStatus.STREAM_IN_USE);
|
assertRstStream(sessionHandler.readOutbound(), remoteStreamId, SpdyStreamStatus.STREAM_IN_USE);
|
||||||
assertNull(sessionHandler.readOutbound());
|
assertNull(sessionHandler.readOutbound());
|
||||||
remoteStreamID += 2;
|
remoteStreamId += 2;
|
||||||
|
|
||||||
// Check if frame codec correctly compresses/uncompresses headers
|
// Check if frame codec correctly compresses/uncompresses headers
|
||||||
sessionHandler.writeInbound(spdySynStreamFrame);
|
sessionHandler.writeInbound(spdySynStreamFrame);
|
||||||
assertSynReply(sessionHandler.readOutbound(), localStreamID, false, spdySynStreamFrame);
|
assertSynReply(sessionHandler.readOutbound(), localStreamId, false, spdySynStreamFrame.headers());
|
||||||
assertNull(sessionHandler.readOutbound());
|
assertNull(sessionHandler.readOutbound());
|
||||||
SpdyHeadersFrame spdyHeadersFrame = new DefaultSpdyHeadersFrame(localStreamID);
|
SpdyHeadersFrame spdyHeadersFrame = new DefaultSpdyHeadersFrame(localStreamId);
|
||||||
|
|
||||||
spdyHeadersFrame.headers().add("HEADER", "test1");
|
spdyHeadersFrame.headers().add("HEADER", "test1");
|
||||||
spdyHeadersFrame.headers().add("HEADER", "test2");
|
spdyHeadersFrame.headers().add("HEADER", "test2");
|
||||||
|
|
||||||
sessionHandler.writeInbound(spdyHeadersFrame);
|
sessionHandler.writeInbound(spdyHeadersFrame);
|
||||||
assertHeaders(sessionHandler.readOutbound(), localStreamID, spdyHeadersFrame);
|
assertHeaders(sessionHandler.readOutbound(), localStreamId, false, spdyHeadersFrame.headers());
|
||||||
assertNull(sessionHandler.readOutbound());
|
assertNull(sessionHandler.readOutbound());
|
||||||
localStreamID += 2;
|
localStreamId += 2;
|
||||||
|
|
||||||
// Check if session handler closed the streams using the number
|
// Check if session handler closed the streams using the number
|
||||||
// of concurrent streams and that it returns REFUSED_STREAM
|
// of concurrent streams and that it returns REFUSED_STREAM
|
||||||
// if it receives a SYN_STREAM frame it does not wish to accept
|
// if it receives a SYN_STREAM frame it does not wish to accept
|
||||||
spdySynStreamFrame.setStreamId(localStreamID);
|
spdySynStreamFrame.setStreamId(localStreamId);
|
||||||
spdySynStreamFrame.setLast(true);
|
spdySynStreamFrame.setLast(true);
|
||||||
spdySynStreamFrame.setUnidirectional(true);
|
spdySynStreamFrame.setUnidirectional(true);
|
||||||
|
|
||||||
sessionHandler.writeInbound(spdySynStreamFrame);
|
sessionHandler.writeInbound(spdySynStreamFrame);
|
||||||
assertRstStream(sessionHandler.readOutbound(), localStreamID, SpdyStreamStatus.REFUSED_STREAM);
|
assertRstStream(sessionHandler.readOutbound(), localStreamId, SpdyStreamStatus.REFUSED_STREAM);
|
||||||
assertNull(sessionHandler.readOutbound());
|
assertNull(sessionHandler.readOutbound());
|
||||||
|
|
||||||
// Check if session handler drops active streams if it receives
|
// Check if session handler drops active streams if it receives
|
||||||
// a RST_STREAM frame for that Stream-ID
|
// a RST_STREAM frame for that Stream-ID
|
||||||
sessionHandler.writeInbound(new DefaultSpdyRstStreamFrame(remoteStreamID, 3));
|
sessionHandler.writeInbound(new DefaultSpdyRstStreamFrame(remoteStreamId, 3));
|
||||||
assertNull(sessionHandler.readOutbound());
|
assertNull(sessionHandler.readOutbound());
|
||||||
remoteStreamID += 2;
|
remoteStreamId += 2;
|
||||||
|
|
||||||
// Check if session handler honors UNIDIRECTIONAL streams
|
// Check if session handler honors UNIDIRECTIONAL streams
|
||||||
spdySynStreamFrame.setLast(false);
|
spdySynStreamFrame.setLast(false);
|
||||||
|
@ -182,17 +177,17 @@ public class SpdySessionHandlerTest {
|
||||||
// Check if session handler returns PROTOCOL_ERROR if it receives
|
// Check if session handler returns PROTOCOL_ERROR if it receives
|
||||||
// multiple SYN_STREAM frames for the same active Stream-ID
|
// multiple SYN_STREAM frames for the same active Stream-ID
|
||||||
sessionHandler.writeInbound(spdySynStreamFrame);
|
sessionHandler.writeInbound(spdySynStreamFrame);
|
||||||
assertRstStream(sessionHandler.readOutbound(), localStreamID, SpdyStreamStatus.PROTOCOL_ERROR);
|
assertRstStream(sessionHandler.readOutbound(), localStreamId, SpdyStreamStatus.PROTOCOL_ERROR);
|
||||||
assertNull(sessionHandler.readOutbound());
|
assertNull(sessionHandler.readOutbound());
|
||||||
localStreamID += 2;
|
localStreamId += 2;
|
||||||
|
|
||||||
// Check if session handler returns PROTOCOL_ERROR if it receives
|
// Check if session handler returns PROTOCOL_ERROR if it receives
|
||||||
// a SYN_STREAM frame with an invalid Stream-ID
|
// a SYN_STREAM frame with an invalid Stream-ID
|
||||||
spdySynStreamFrame.setStreamId(localStreamID - 1);
|
spdySynStreamFrame.setStreamId(localStreamId - 1);
|
||||||
sessionHandler.writeInbound(spdySynStreamFrame);
|
sessionHandler.writeInbound(spdySynStreamFrame);
|
||||||
assertRstStream(sessionHandler.readOutbound(), localStreamID - 1, SpdyStreamStatus.PROTOCOL_ERROR);
|
assertRstStream(sessionHandler.readOutbound(), localStreamId - 1, SpdyStreamStatus.PROTOCOL_ERROR);
|
||||||
assertNull(sessionHandler.readOutbound());
|
assertNull(sessionHandler.readOutbound());
|
||||||
spdySynStreamFrame.setStreamId(localStreamID);
|
spdySynStreamFrame.setStreamId(localStreamId);
|
||||||
|
|
||||||
// Check if session handler correctly limits the number of
|
// Check if session handler correctly limits the number of
|
||||||
// concurrent streams in the SETTINGS frame
|
// concurrent streams in the SETTINGS frame
|
||||||
|
@ -201,33 +196,33 @@ public class SpdySessionHandlerTest {
|
||||||
sessionHandler.writeInbound(spdySettingsFrame);
|
sessionHandler.writeInbound(spdySettingsFrame);
|
||||||
assertNull(sessionHandler.readOutbound());
|
assertNull(sessionHandler.readOutbound());
|
||||||
sessionHandler.writeInbound(spdySynStreamFrame);
|
sessionHandler.writeInbound(spdySynStreamFrame);
|
||||||
assertRstStream(sessionHandler.readOutbound(), localStreamID, SpdyStreamStatus.REFUSED_STREAM);
|
assertRstStream(sessionHandler.readOutbound(), localStreamId, SpdyStreamStatus.REFUSED_STREAM);
|
||||||
assertNull(sessionHandler.readOutbound());
|
assertNull(sessionHandler.readOutbound());
|
||||||
spdySettingsFrame.setValue(SpdySettingsFrame.SETTINGS_MAX_CONCURRENT_STREAMS, 4);
|
spdySettingsFrame.setValue(SpdySettingsFrame.SETTINGS_MAX_CONCURRENT_STREAMS, 4);
|
||||||
sessionHandler.writeInbound(spdySettingsFrame);
|
sessionHandler.writeInbound(spdySettingsFrame);
|
||||||
assertNull(sessionHandler.readOutbound());
|
assertNull(sessionHandler.readOutbound());
|
||||||
sessionHandler.writeInbound(spdySynStreamFrame);
|
sessionHandler.writeInbound(spdySynStreamFrame);
|
||||||
assertSynReply(sessionHandler.readOutbound(), localStreamID, false, spdySynStreamFrame);
|
assertSynReply(sessionHandler.readOutbound(), localStreamId, false, spdySynStreamFrame.headers());
|
||||||
assertNull(sessionHandler.readOutbound());
|
assertNull(sessionHandler.readOutbound());
|
||||||
|
|
||||||
// Check if session handler rejects HEADERS for closed streams
|
// Check if session handler rejects HEADERS for closed streams
|
||||||
int testStreamID = spdyDataFrame.getStreamId();
|
int testStreamId = spdyDataFrame.getStreamId();
|
||||||
sessionHandler.writeInbound(spdyDataFrame);
|
sessionHandler.writeInbound(spdyDataFrame);
|
||||||
assertDataFrame(sessionHandler.readOutbound(), testStreamID, spdyDataFrame.isLast());
|
assertDataFrame(sessionHandler.readOutbound(), testStreamId, spdyDataFrame.isLast());
|
||||||
assertNull(sessionHandler.readOutbound());
|
assertNull(sessionHandler.readOutbound());
|
||||||
spdyHeadersFrame.setStreamId(testStreamID);
|
spdyHeadersFrame.setStreamId(testStreamId);
|
||||||
|
|
||||||
sessionHandler.writeInbound(spdyHeadersFrame);
|
sessionHandler.writeInbound(spdyHeadersFrame);
|
||||||
assertRstStream(sessionHandler.readOutbound(), testStreamID, SpdyStreamStatus.INVALID_STREAM);
|
assertRstStream(sessionHandler.readOutbound(), testStreamId, SpdyStreamStatus.INVALID_STREAM);
|
||||||
assertNull(sessionHandler.readOutbound());
|
assertNull(sessionHandler.readOutbound());
|
||||||
|
|
||||||
// Check if session handler returns PROTOCOL_ERROR if it receives
|
// Check if session handler returns PROTOCOL_ERROR if it receives
|
||||||
// an invalid HEADERS frame
|
// an invalid HEADERS frame
|
||||||
spdyHeadersFrame.setStreamId(localStreamID);
|
spdyHeadersFrame.setStreamId(localStreamId);
|
||||||
|
|
||||||
spdyHeadersFrame.setInvalid();
|
spdyHeadersFrame.setInvalid();
|
||||||
sessionHandler.writeInbound(spdyHeadersFrame);
|
sessionHandler.writeInbound(spdyHeadersFrame);
|
||||||
assertRstStream(sessionHandler.readOutbound(), localStreamID, SpdyStreamStatus.PROTOCOL_ERROR);
|
assertRstStream(sessionHandler.readOutbound(), localStreamId, SpdyStreamStatus.PROTOCOL_ERROR);
|
||||||
assertNull(sessionHandler.readOutbound());
|
assertNull(sessionHandler.readOutbound());
|
||||||
|
|
||||||
// Check if session handler returns identical local PINGs
|
// 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
|
// Check if session handler sends a GOAWAY frame when closing
|
||||||
sessionHandler.writeInbound(closeMessage);
|
sessionHandler.writeInbound(closeMessage);
|
||||||
assertGoAway(sessionHandler.readOutbound(), localStreamID);
|
assertGoAway(sessionHandler.readOutbound(), localStreamId);
|
||||||
assertNull(sessionHandler.readOutbound());
|
assertNull(sessionHandler.readOutbound());
|
||||||
localStreamID += 2;
|
localStreamId += 2;
|
||||||
|
|
||||||
// Check if session handler returns REFUSED_STREAM if it receives
|
// Check if session handler returns REFUSED_STREAM if it receives
|
||||||
// SYN_STREAM frames after sending a GOAWAY frame
|
// SYN_STREAM frames after sending a GOAWAY frame
|
||||||
spdySynStreamFrame.setStreamId(localStreamID);
|
spdySynStreamFrame.setStreamId(localStreamId);
|
||||||
sessionHandler.writeInbound(spdySynStreamFrame);
|
sessionHandler.writeInbound(spdySynStreamFrame);
|
||||||
assertRstStream(sessionHandler.readOutbound(), localStreamID, SpdyStreamStatus.REFUSED_STREAM);
|
assertRstStream(sessionHandler.readOutbound(), localStreamId, SpdyStreamStatus.REFUSED_STREAM);
|
||||||
assertNull(sessionHandler.readOutbound());
|
assertNull(sessionHandler.readOutbound());
|
||||||
|
|
||||||
// Check if session handler ignores Data frames after sending
|
// Check if session handler ignores Data frames after sending
|
||||||
// a GOAWAY frame
|
// a GOAWAY frame
|
||||||
spdyDataFrame.setStreamId(localStreamID);
|
spdyDataFrame.setStreamId(localStreamId);
|
||||||
sessionHandler.writeInbound(spdyDataFrame);
|
sessionHandler.writeInbound(spdyDataFrame);
|
||||||
assertNull(sessionHandler.readOutbound());
|
assertNull(sessionHandler.readOutbound());
|
||||||
|
|
||||||
|
@ -279,7 +274,7 @@ public class SpdySessionHandlerTest {
|
||||||
|
|
||||||
// Echo Handler opens 4 half-closed streams on session connection
|
// Echo Handler opens 4 half-closed streams on session connection
|
||||||
// and then sets the number of concurrent streams to 3
|
// 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 int closeSignal;
|
||||||
private final boolean server;
|
private final boolean server;
|
||||||
|
|
||||||
|
@ -291,9 +286,9 @@ public class SpdySessionHandlerTest {
|
||||||
@Override
|
@Override
|
||||||
public void channelActive(ChannelHandlerContext ctx) throws Exception {
|
public void channelActive(ChannelHandlerContext ctx) throws Exception {
|
||||||
// Initiate 4 new streams
|
// Initiate 4 new streams
|
||||||
int streamID = server ? 2 : 1;
|
int streamId = server ? 2 : 1;
|
||||||
SpdySynStreamFrame spdySynStreamFrame =
|
SpdySynStreamFrame spdySynStreamFrame =
|
||||||
new DefaultSpdySynStreamFrame(streamID, 0, (byte) 0);
|
new DefaultSpdySynStreamFrame(streamId, 0, (byte) 0);
|
||||||
spdySynStreamFrame.setLast(true);
|
spdySynStreamFrame.setLast(true);
|
||||||
ctx.write(spdySynStreamFrame);
|
ctx.write(spdySynStreamFrame);
|
||||||
spdySynStreamFrame.setStreamId(spdySynStreamFrame.getStreamId() + 2);
|
spdySynStreamFrame.setStreamId(spdySynStreamFrame.getStreamId() + 2);
|
||||||
|
@ -310,38 +305,39 @@ public class SpdySessionHandlerTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void messageReceived(ChannelHandlerContext ctx, MessageList<Object> messages) throws Exception {
|
public void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||||
for (int i = 0; i < messages.size(); i++) {
|
if (msg instanceof SpdySynStreamFrame) {
|
||||||
Object msg = messages.get(i);
|
|
||||||
if (msg instanceof SpdyDataFrame ||
|
|
||||||
msg instanceof SpdyPingFrame ||
|
|
||||||
msg instanceof SpdyHeadersFrame) {
|
|
||||||
|
|
||||||
ctx.write(msg);
|
SpdySynStreamFrame spdySynStreamFrame = (SpdySynStreamFrame) msg;
|
||||||
return;
|
if (!spdySynStreamFrame.isUnidirectional()) {
|
||||||
}
|
int streamId = spdySynStreamFrame.getStreamId();
|
||||||
|
SpdySynReplyFrame spdySynReplyFrame = new DefaultSpdySynReplyFrame(streamId);
|
||||||
if (msg instanceof SpdySynStreamFrame) {
|
spdySynReplyFrame.setLast(spdySynStreamFrame.isLast());
|
||||||
|
for (Map.Entry<String, String> entry: spdySynStreamFrame.headers()) {
|
||||||
SpdySynStreamFrame spdySynStreamFrame = (SpdySynStreamFrame) msg;
|
spdySynReplyFrame.headers().add(entry.getKey(), entry.getValue());
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (msg instanceof SpdySettingsFrame) {
|
ctx.write(spdySynReplyFrame);
|
||||||
SpdySettingsFrame spdySettingsFrame = (SpdySettingsFrame) msg;
|
}
|
||||||
if (spdySettingsFrame.isSet(closeSignal)) {
|
return;
|
||||||
ctx.close();
|
}
|
||||||
}
|
|
||||||
|
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