
io.netty.handler.codec.spdy.SpdyFrameCodec Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2014 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:
*
* https://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.buffer.ByteBuf;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelOutboundHandler;
import io.netty.channel.ChannelPromise;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.UnsupportedMessageTypeException;
import java.net.SocketAddress;
import java.util.List;
/**
* A {@link ChannelHandler} that encodes and decodes SPDY Frames.
*/
public class SpdyFrameCodec extends ByteToMessageDecoder
implements SpdyFrameDecoderDelegate, ChannelOutboundHandler {
protected static final SpdyProtocolException INVALID_FRAME =
new SpdyProtocolException("Received invalid frame");
protected final SpdyFrameDecoder spdyFrameDecoder;
protected final SpdyFrameEncoder spdyFrameEncoder;
private final SpdyHeaderBlockDecoder spdyHeaderBlockDecoder;
private final SpdyHeaderBlockEncoder spdyHeaderBlockEncoder;
private SpdyHeadersFrame spdyHeadersFrame;
private SpdySettingsFrame spdySettingsFrame;
private ChannelHandlerContext ctx;
private boolean read;
private final boolean validateHeaders;
private final boolean supportsUnknownFrames;
/**
* Creates a new instance with the specified {@code version},
* {@code validateHeaders (true)}, and
* the default decoder and encoder options
* ({@code maxChunkSize (8192)}, {@code maxHeaderSize (16384)},
* {@code compressionLevel (6)}, {@code windowBits (15)},
* and {@code memLevel (8)}).
*/
public SpdyFrameCodec(SpdyVersion version) {
this(version, true);
}
/**
* Creates a new instance with the specified {@code version},
* {@code validateHeaders}, and
* the default decoder and encoder options
* ({@code maxChunkSize (8192)}, {@code maxHeaderSize (16384)},
* {@code compressionLevel (6)}, {@code windowBits (15)},
* and {@code memLevel (8)}).
*/
public SpdyFrameCodec(SpdyVersion version, boolean validateHeaders) {
this(version, 8192, 16384, 6, 15, 8, validateHeaders);
}
/**
* Creates a new instance with the specified {@code version}, {@code validateHeaders (true)},
* decoder and encoder options.
*/
public SpdyFrameCodec(
SpdyVersion version, int maxChunkSize, int maxHeaderSize,
int compressionLevel, int windowBits, int memLevel) {
this(version, maxChunkSize, maxHeaderSize, compressionLevel, windowBits, memLevel, true);
}
/**
* Creates a new instance with the specified {@code version}, {@code validateHeaders},
* decoder and encoder options.
*/
public SpdyFrameCodec(
SpdyVersion version, int maxChunkSize, int maxHeaderSize,
int compressionLevel, int windowBits, int memLevel, boolean validateHeaders) {
this(version, maxChunkSize,
SpdyHeaderBlockDecoder.newInstance(version, maxHeaderSize),
SpdyHeaderBlockEncoder.newInstance(version, compressionLevel, windowBits, memLevel),
validateHeaders, false);
}
/**
* Creates a new instance with the specified {@code version}, {@code validateHeaders},
* decoder and encoder options.
*/
public SpdyFrameCodec(
SpdyVersion version, int maxChunkSize, int maxHeaderSize,
int compressionLevel, int windowBits, int memLevel, boolean validateHeaders,
boolean supportsUnknownFrames) {
this(version, maxChunkSize,
SpdyHeaderBlockDecoder.newInstance(version, maxHeaderSize),
SpdyHeaderBlockEncoder.newInstance(version, compressionLevel, windowBits, memLevel),
validateHeaders, supportsUnknownFrames);
}
protected SpdyFrameCodec(SpdyVersion version, int maxChunkSize,
SpdyHeaderBlockDecoder spdyHeaderBlockDecoder,
SpdyHeaderBlockEncoder spdyHeaderBlockEncoder,
boolean validateHeaders) {
this(version, maxChunkSize, spdyHeaderBlockDecoder, spdyHeaderBlockEncoder, validateHeaders, false);
}
protected SpdyFrameCodec(SpdyVersion version, int maxChunkSize,
SpdyHeaderBlockDecoder spdyHeaderBlockDecoder, SpdyHeaderBlockEncoder spdyHeaderBlockEncoder,
boolean validateHeaders, boolean supportsUnknownFrames) {
this.supportsUnknownFrames = supportsUnknownFrames;
spdyFrameDecoder = createDecoder(version, supportsUnknownFrames ? new SpdyFrameDecoderExtendedDelegate() {
@Override
public void readUnknownFrame(int frameType, byte flags, ByteBuf payload) {
SpdyFrameCodec.this.readUnknownFrame(frameType, flags, payload);
}
@Override
public void readDataFrame(int streamId, boolean last, ByteBuf data) {
SpdyFrameCodec.this.readDataFrame(streamId, last, data);
}
@Override
public void readSynStreamFrame(int streamId, int associatedToStreamId, byte priority,
boolean last, boolean unidirectional) {
SpdyFrameCodec.this.readSynStreamFrame(streamId, associatedToStreamId, priority, last, unidirectional);
}
@Override
public void readSynReplyFrame(int streamId, boolean last) {
SpdyFrameCodec.this.readSynReplyFrame(streamId, last);
}
@Override
public void readRstStreamFrame(int streamId, int statusCode) {
SpdyFrameCodec.this.readRstStreamFrame(streamId, statusCode);
}
@Override
public void readSettingsFrame(boolean clearPersisted) {
SpdyFrameCodec.this.readSettingsFrame(clearPersisted);
}
@Override
public void readSetting(int id, int value, boolean persistValue, boolean persisted) {
SpdyFrameCodec.this.readSetting(id, value, persistValue, persisted);
}
@Override
public void readSettingsEnd() {
SpdyFrameCodec.this.readSettingsEnd();
}
@Override
public void readPingFrame(int id) {
SpdyFrameCodec.this.readPingFrame(id);
}
@Override
public void readGoAwayFrame(int lastGoodStreamId, int statusCode) {
SpdyFrameCodec.this.readGoAwayFrame(lastGoodStreamId, statusCode);
}
@Override
public void readHeadersFrame(int streamId, boolean last) {
SpdyFrameCodec.this.readHeadersFrame(streamId, last);
}
@Override
public void readWindowUpdateFrame(int streamId, int deltaWindowSize) {
SpdyFrameCodec.this.readWindowUpdateFrame(streamId, deltaWindowSize);
}
@Override
public void readHeaderBlock(ByteBuf headerBlock) {
SpdyFrameCodec.this.readHeaderBlock(headerBlock);
}
@Override
public void readHeaderBlockEnd() {
SpdyFrameCodec.this.readHeaderBlockEnd();
}
@Override
public void readFrameError(String message) {
SpdyFrameCodec.this.readFrameError(message);
}
} : this, maxChunkSize);
spdyFrameEncoder = createEncoder(version);
this.spdyHeaderBlockDecoder = spdyHeaderBlockDecoder;
this.spdyHeaderBlockEncoder = spdyHeaderBlockEncoder;
this.validateHeaders = validateHeaders;
}
protected SpdyFrameDecoder createDecoder(SpdyVersion version, SpdyFrameDecoderDelegate delegate, int maxChunkSize) {
return new SpdyFrameDecoder(version, delegate, maxChunkSize) {
@Override
protected boolean isValidUnknownFrameHeader(int streamId, int type, byte flags, int length) {
if (supportsUnknownFrames) {
return SpdyFrameCodec.this.isValidUnknownFrameHeader(streamId, type, flags, length);
}
return super.isValidUnknownFrameHeader(streamId, type, flags, length);
}
};
}
protected SpdyFrameEncoder createEncoder(SpdyVersion version) {
return new SpdyFrameEncoder(version);
}
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
super.handlerAdded(ctx);
this.ctx = ctx;
ctx.channel().closeFuture().addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
spdyHeaderBlockDecoder.end();
spdyHeaderBlockEncoder.end();
}
});
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy