}
public void handleDownstream(ChannelHandlerContext ctx, ChannelEvent evt)
throws Exception {
if (evt instanceof ChannelStateEvent) {
ChannelStateEvent e = (ChannelStateEvent) evt;
switch (e.getState()) {
case OPEN:
case CONNECTED:
case BOUND:
if (Boolean.FALSE.equals(e.getValue()) || e.getValue() == null) {
sendGoAwayFrame(ctx, e);
return;
}
}
}
if (!(evt instanceof MessageEvent)) {
ctx.sendDownstream(evt);
return;
}
MessageEvent e = (MessageEvent) evt;
Object msg = e.getMessage();
if (msg instanceof SpdyDataFrame) {
SpdyDataFrame spdyDataFrame = (SpdyDataFrame) msg;
int streamID = spdyDataFrame.getStreamID();
if (spdySession.isLocalSideClosed(streamID)) {
e.getFuture().setFailure(PROTOCOL_EXCEPTION);
return;
}
if (spdyDataFrame.isLast()) {
halfCloseStream(streamID, false);
}
} else if (msg instanceof SpdySynStreamFrame) {
SpdySynStreamFrame spdySynStreamFrame = (SpdySynStreamFrame) msg;
boolean remoteSideClosed = spdySynStreamFrame.isUnidirectional();
boolean localSideClosed = spdySynStreamFrame.isLast();
if (!acceptStream(spdySynStreamFrame.getStreamID(), remoteSideClosed, localSideClosed)) {
e.getFuture().setFailure(PROTOCOL_EXCEPTION);
return;
}
} else if (msg instanceof SpdySynReplyFrame) {
SpdySynReplyFrame spdySynReplyFrame = (SpdySynReplyFrame) msg;
int streamID = spdySynReplyFrame.getStreamID();
if (!isRemoteInitiatedID(streamID) || spdySession.isLocalSideClosed(streamID)) {
e.getFuture().setFailure(PROTOCOL_EXCEPTION);
return;
}
if (spdySynReplyFrame.isLast()) {
halfCloseStream(streamID, false);
}
} else if (msg instanceof SpdyRstStreamFrame) {
SpdyRstStreamFrame spdyRstStreamFrame = (SpdyRstStreamFrame) msg;
removeStream(spdyRstStreamFrame.getStreamID());
} else if (msg instanceof SpdySettingsFrame) {
SpdySettingsFrame spdySettingsFrame = (SpdySettingsFrame) msg;
updateConcurrentStreams(spdySettingsFrame, false);
} else if (msg instanceof SpdyPingFrame) {
SpdyPingFrame spdyPingFrame = (SpdyPingFrame) msg;
if (isRemoteInitiatedID(spdyPingFrame.getID())) {
e.getFuture().setFailure(new IllegalArgumentException(
"invalid PING ID: " + spdyPingFrame.getID()));
return;
}
pings.getAndIncrement();
} else if (msg instanceof SpdyGoAwayFrame) {
// Should send a CLOSE ChannelStateEvent
e.getFuture().setFailure(PROTOCOL_EXCEPTION);
return;
} else if (msg instanceof SpdyHeadersFrame) {
SpdyHeadersFrame spdyHeadersFrame = (SpdyHeadersFrame) msg;
int streamID = spdyHeadersFrame.getStreamID();
if (spdySession.isLocalSideClosed(streamID)) {
e.getFuture().setFailure(PROTOCOL_EXCEPTION);
return;
}
}
ctx.sendDownstream(evt);