Search in sources :

Example 46 with Http2Exception

use of io.netty.handler.codec.http2.Http2Exception in project netty by netty.

the class Http2ConnectionHandlerTest method clientShouldNeverSend431WhenHeadersAreTooLarge.

@Test
public void clientShouldNeverSend431WhenHeadersAreTooLarge() throws Exception {
    int padding = 0;
    handler = newHandler();
    Http2Exception e = new Http2Exception.HeaderListSizeException(STREAM_ID, PROTOCOL_ERROR, "Header size exceeded max allowed size 8196", true);
    when(stream.id()).thenReturn(STREAM_ID);
    when(connection.isServer()).thenReturn(false);
    when(stream.isHeadersSent()).thenReturn(false);
    when(remote.lastStreamCreated()).thenReturn(STREAM_ID);
    when(frameWriter.writeRstStream(eq(ctx), eq(STREAM_ID), eq(PROTOCOL_ERROR.code()), eq(promise))).thenReturn(future);
    handler.exceptionCaught(ctx, e);
    verify(encoder, never()).writeHeaders(eq(ctx), eq(STREAM_ID), any(Http2Headers.class), eq(padding), eq(true), eq(promise));
    verify(frameWriter).writeRstStream(ctx, STREAM_ID, PROTOCOL_ERROR.code(), promise);
}
Also used : ShutdownHint(io.netty.handler.codec.http2.Http2Exception.ShutdownHint) Test(org.junit.jupiter.api.Test)

Example 47 with Http2Exception

use of io.netty.handler.codec.http2.Http2Exception in project netty by netty.

the class Http2ConnectionRoundtripTest method noMoreStreamIdsShouldSendGoAway.

@Test
public void noMoreStreamIdsShouldSendGoAway() throws Exception {
    bootstrapEnv(1, 1, 3, 1, 1);
    // Don't wait for the server to close streams
    setClientGracefulShutdownTime(0);
    // Create a single stream by sending a HEADERS frame to the server.
    final Http2Headers headers = dummyHeaders();
    runInChannel(clientChannel, new Http2Runnable() {

        @Override
        public void run() throws Http2Exception {
            http2Client.encoder().writeHeaders(ctx(), 3, headers, 0, (short) 16, false, 0, true, newPromise());
            http2Client.flush(ctx());
        }
    });
    assertTrue(serverSettingsAckLatch.await(DEFAULT_AWAIT_TIMEOUT_SECONDS, SECONDS));
    runInChannel(clientChannel, new Http2Runnable() {

        @Override
        public void run() throws Http2Exception {
            http2Client.encoder().writeHeaders(ctx(), MAX_VALUE + 1, headers, 0, (short) 16, false, 0, true, newPromise());
            http2Client.flush(ctx());
        }
    });
    assertTrue(goAwayLatch.await(DEFAULT_AWAIT_TIMEOUT_SECONDS, SECONDS));
    verify(serverListener).onGoAwayRead(any(ChannelHandlerContext.class), eq(0), eq(PROTOCOL_ERROR.code()), any(ByteBuf.class));
}
Also used : Http2Runnable(io.netty.handler.codec.http2.Http2TestUtil.Http2Runnable) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) ByteBuf(io.netty.buffer.ByteBuf) Test(org.junit.jupiter.api.Test)

Example 48 with Http2Exception

use of io.netty.handler.codec.http2.Http2Exception in project netty by netty.

the class Http2ConnectionRoundtripTest method priorityUsingHigherValuedStreamIdDoesNotPreventUsingLowerStreamId.

@Test
public void priorityUsingHigherValuedStreamIdDoesNotPreventUsingLowerStreamId() throws Exception {
    bootstrapEnv(1, 1, 2, 0);
    final Http2Headers headers = dummyHeaders();
    runInChannel(clientChannel, new Http2Runnable() {

        @Override
        public void run() throws Http2Exception {
            http2Client.encoder().writePriority(ctx(), 5, 3, (short) 14, false, newPromise());
            http2Client.encoder().writeHeaders(ctx(), 3, headers, 0, (short) 16, false, 0, false, newPromise());
            http2Client.flush(ctx());
        }
    });
    assertTrue(serverSettingsAckLatch.await(DEFAULT_AWAIT_TIMEOUT_SECONDS, SECONDS));
    assertTrue(requestLatch.await(DEFAULT_AWAIT_TIMEOUT_SECONDS, SECONDS));
    verify(serverListener).onPriorityRead(any(ChannelHandlerContext.class), eq(5), eq(3), eq((short) 14), eq(false));
    verify(serverListener).onHeadersRead(any(ChannelHandlerContext.class), eq(3), eq(headers), eq(0), eq((short) 16), eq(false), eq(0), eq(false));
    // Verify that no errors have been received.
    verify(serverListener, never()).onGoAwayRead(any(ChannelHandlerContext.class), anyInt(), anyLong(), any(ByteBuf.class));
    verify(serverListener, never()).onRstStreamRead(any(ChannelHandlerContext.class), anyInt(), anyLong());
    verify(clientListener, never()).onGoAwayRead(any(ChannelHandlerContext.class), anyInt(), anyLong(), any(ByteBuf.class));
    verify(clientListener, never()).onRstStreamRead(any(ChannelHandlerContext.class), anyInt(), anyLong());
}
Also used : Http2Runnable(io.netty.handler.codec.http2.Http2TestUtil.Http2Runnable) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) ByteBuf(io.netty.buffer.ByteBuf) Test(org.junit.jupiter.api.Test)

Example 49 with Http2Exception

use of io.netty.handler.codec.http2.Http2Exception in project netty by netty.

the class StreamBufferingEncoderTest method receivingGoAwayFailsBufferedStreams.

@Test
public void receivingGoAwayFailsBufferedStreams() throws Http2Exception {
    encoder.writeSettingsAck(ctx, newPromise());
    setMaxConcurrentStreams(5);
    int streamId = 3;
    List<ChannelFuture> futures = new ArrayList<ChannelFuture>();
    for (int i = 0; i < 9; i++) {
        futures.add(encoderWriteHeaders(streamId, newPromise()));
        streamId += 2;
    }
    assertEquals(5, connection.numActiveStreams());
    assertEquals(4, encoder.numBufferedStreams());
    connection.goAwayReceived(11, 8, EMPTY_BUFFER);
    assertEquals(5, connection.numActiveStreams());
    assertEquals(0, encoder.numBufferedStreams());
    int failCount = 0;
    for (ChannelFuture f : futures) {
        if (f.cause() != null) {
            assertTrue(f.cause() instanceof Http2GoAwayException);
            failCount++;
        }
    }
    assertEquals(4, failCount);
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) Http2GoAwayException(io.netty.handler.codec.http2.StreamBufferingEncoder.Http2GoAwayException) ArrayList(java.util.ArrayList) Test(org.junit.jupiter.api.Test)

Example 50 with Http2Exception

use of io.netty.handler.codec.http2.Http2Exception in project netty by netty.

the class HpackDecoder method decode.

private void decode(ByteBuf in, Sink sink) throws Http2Exception {
    int index = 0;
    int nameLength = 0;
    int valueLength = 0;
    byte state = READ_HEADER_REPRESENTATION;
    boolean huffmanEncoded = false;
    CharSequence name = null;
    IndexType indexType = IndexType.NONE;
    while (in.isReadable()) {
        switch(state) {
            case READ_HEADER_REPRESENTATION:
                byte b = in.readByte();
                if (maxDynamicTableSizeChangeRequired && (b & 0xE0) != 0x20) {
                    // HpackEncoder MUST signal maximum dynamic table size change
                    throw MAX_DYNAMIC_TABLE_SIZE_CHANGE_REQUIRED;
                }
                if (b < 0) {
                    // Indexed Header Field
                    index = b & 0x7F;
                    switch(index) {
                        case 0:
                            throw DECODE_ILLEGAL_INDEX_VALUE;
                        case 0x7F:
                            state = READ_INDEXED_HEADER;
                            break;
                        default:
                            HpackHeaderField indexedHeader = getIndexedHeader(index);
                            sink.appendToHeaderList(indexedHeader.name, indexedHeader.value);
                    }
                } else if ((b & 0x40) == 0x40) {
                    // Literal Header Field with Incremental Indexing
                    indexType = IndexType.INCREMENTAL;
                    index = b & 0x3F;
                    switch(index) {
                        case 0:
                            state = READ_LITERAL_HEADER_NAME_LENGTH_PREFIX;
                            break;
                        case 0x3F:
                            state = READ_INDEXED_HEADER_NAME;
                            break;
                        default:
                            // Index was stored as the prefix
                            name = readName(index);
                            nameLength = name.length();
                            state = READ_LITERAL_HEADER_VALUE_LENGTH_PREFIX;
                    }
                } else if ((b & 0x20) == 0x20) {
                    // Dynamic Table Size Update
                    index = b & 0x1F;
                    if (index == 0x1F) {
                        state = READ_MAX_DYNAMIC_TABLE_SIZE;
                    } else {
                        setDynamicTableSize(index);
                        state = READ_HEADER_REPRESENTATION;
                    }
                } else {
                    // Literal Header Field without Indexing / never Indexed
                    indexType = (b & 0x10) == 0x10 ? IndexType.NEVER : IndexType.NONE;
                    index = b & 0x0F;
                    switch(index) {
                        case 0:
                            state = READ_LITERAL_HEADER_NAME_LENGTH_PREFIX;
                            break;
                        case 0x0F:
                            state = READ_INDEXED_HEADER_NAME;
                            break;
                        default:
                            // Index was stored as the prefix
                            name = readName(index);
                            nameLength = name.length();
                            state = READ_LITERAL_HEADER_VALUE_LENGTH_PREFIX;
                    }
                }
                break;
            case READ_MAX_DYNAMIC_TABLE_SIZE:
                setDynamicTableSize(decodeULE128(in, (long) index));
                state = READ_HEADER_REPRESENTATION;
                break;
            case READ_INDEXED_HEADER:
                HpackHeaderField indexedHeader = getIndexedHeader(decodeULE128(in, index));
                sink.appendToHeaderList(indexedHeader.name, indexedHeader.value);
                state = READ_HEADER_REPRESENTATION;
                break;
            case READ_INDEXED_HEADER_NAME:
                // Header Name matches an entry in the Header Table
                name = readName(decodeULE128(in, index));
                nameLength = name.length();
                state = READ_LITERAL_HEADER_VALUE_LENGTH_PREFIX;
                break;
            case READ_LITERAL_HEADER_NAME_LENGTH_PREFIX:
                b = in.readByte();
                huffmanEncoded = (b & 0x80) == 0x80;
                index = b & 0x7F;
                if (index == 0x7f) {
                    state = READ_LITERAL_HEADER_NAME_LENGTH;
                } else {
                    nameLength = index;
                    state = READ_LITERAL_HEADER_NAME;
                }
                break;
            case READ_LITERAL_HEADER_NAME_LENGTH:
                // Header Name is a Literal String
                nameLength = decodeULE128(in, index);
                state = READ_LITERAL_HEADER_NAME;
                break;
            case READ_LITERAL_HEADER_NAME:
                // Wait until entire name is readable
                if (in.readableBytes() < nameLength) {
                    throw notEnoughDataException(in);
                }
                name = readStringLiteral(in, nameLength, huffmanEncoded);
                state = READ_LITERAL_HEADER_VALUE_LENGTH_PREFIX;
                break;
            case READ_LITERAL_HEADER_VALUE_LENGTH_PREFIX:
                b = in.readByte();
                huffmanEncoded = (b & 0x80) == 0x80;
                index = b & 0x7F;
                switch(index) {
                    case 0x7f:
                        state = READ_LITERAL_HEADER_VALUE_LENGTH;
                        break;
                    case 0:
                        insertHeader(sink, name, EMPTY_STRING, indexType);
                        state = READ_HEADER_REPRESENTATION;
                        break;
                    default:
                        valueLength = index;
                        state = READ_LITERAL_HEADER_VALUE;
                }
                break;
            case READ_LITERAL_HEADER_VALUE_LENGTH:
                // Header Value is a Literal String
                valueLength = decodeULE128(in, index);
                state = READ_LITERAL_HEADER_VALUE;
                break;
            case READ_LITERAL_HEADER_VALUE:
                // Wait until entire value is readable
                if (in.readableBytes() < valueLength) {
                    throw notEnoughDataException(in);
                }
                CharSequence value = readStringLiteral(in, valueLength, huffmanEncoded);
                insertHeader(sink, name, value, indexType);
                state = READ_HEADER_REPRESENTATION;
                break;
            default:
                throw new Error("should not reach here state: " + state);
        }
    }
    if (state != READ_HEADER_REPRESENTATION) {
        throw connectionError(COMPRESSION_ERROR, "Incomplete header block fragment.");
    }
}
Also used : Http2Exception.connectionError(io.netty.handler.codec.http2.Http2Exception.connectionError) Http2Exception.streamError(io.netty.handler.codec.http2.Http2Exception.streamError) IndexType(io.netty.handler.codec.http2.HpackUtil.IndexType)

Aggregations

ByteBuf (io.netty.buffer.ByteBuf)109 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)100 ChannelFuture (io.netty.channel.ChannelFuture)92 Test (org.junit.Test)89 Http2Exception (io.netty.handler.codec.http2.Http2Exception)85 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)81 AtomicReference (java.util.concurrent.atomic.AtomicReference)78 ByteArrayOutputStream (java.io.ByteArrayOutputStream)76 Channel (io.netty.channel.Channel)75 ChannelPipeline (io.netty.channel.ChannelPipeline)75 ArrayList (java.util.ArrayList)75 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)75 ChannelInitializer (io.netty.channel.ChannelInitializer)74 NioEventLoopGroup (io.netty.channel.nio.NioEventLoopGroup)74 HttpHeaderNames (io.netty.handler.codec.http.HttpHeaderNames)74 DefaultHttp2Headers (io.netty.handler.codec.http2.DefaultHttp2Headers)74 Http2Headers (io.netty.handler.codec.http2.Http2Headers)74 ApplicationProtocolNames (io.netty.handler.ssl.ApplicationProtocolNames)74 ApplicationProtocolNegotiationHandler (io.netty.handler.ssl.ApplicationProtocolNegotiationHandler)74 SslHandler (io.netty.handler.ssl.SslHandler)74