Search in sources :

Example 36 with ByteBuf

use of io.netty.buffer.ByteBuf in project netty by netty.

the class DefaultHttp2FrameReader method processPayloadState.

private void processPayloadState(ChannelHandlerContext ctx, ByteBuf in, Http2FrameListener listener) throws Http2Exception {
    if (in.readableBytes() < payloadLength) {
        // Wait until the entire payload has been read.
        return;
    }
    // Get a view of the buffer for the size of the payload.
    ByteBuf payload = in.readSlice(payloadLength);
    // We have consumed the data, next time we read we will be expecting to read a frame header.
    readingHeaders = true;
    // Read the payload and fire the frame event to the listener.
    switch(frameType) {
        case DATA:
            readDataFrame(ctx, payload, listener);
            break;
        case HEADERS:
            readHeadersFrame(ctx, payload, listener);
            break;
        case PRIORITY:
            readPriorityFrame(ctx, payload, listener);
            break;
        case RST_STREAM:
            readRstStreamFrame(ctx, payload, listener);
            break;
        case SETTINGS:
            readSettingsFrame(ctx, payload, listener);
            break;
        case PUSH_PROMISE:
            readPushPromiseFrame(ctx, payload, listener);
            break;
        case PING:
            readPingFrame(ctx, payload, listener);
            break;
        case GO_AWAY:
            readGoAwayFrame(ctx, payload, listener);
            break;
        case WINDOW_UPDATE:
            readWindowUpdateFrame(ctx, payload, listener);
            break;
        case CONTINUATION:
            readContinuationFrame(payload, listener);
            break;
        default:
            readUnknownFrame(ctx, payload, listener);
            break;
    }
}
Also used : ByteBuf(io.netty.buffer.ByteBuf)

Example 37 with ByteBuf

use of io.netty.buffer.ByteBuf in project netty by netty.

the class DefaultHttp2FrameWriter method writePushPromise.

@Override
public ChannelFuture writePushPromise(ChannelHandlerContext ctx, int streamId, int promisedStreamId, Http2Headers headers, int padding, ChannelPromise promise) {
    ByteBuf headerBlock = null;
    SimpleChannelPromiseAggregator promiseAggregator = new SimpleChannelPromiseAggregator(promise, ctx.channel(), ctx.executor());
    try {
        verifyStreamId(streamId, STREAM_ID);
        verifyStreamId(promisedStreamId, "Promised Stream ID");
        verifyPadding(padding);
        // Encode the entire header block into an intermediate buffer.
        headerBlock = ctx.alloc().buffer();
        headersEncoder.encodeHeaders(streamId, headers, headerBlock);
        // Read the first fragment (possibly everything).
        Http2Flags flags = new Http2Flags().paddingPresent(padding > 0);
        // INT_FIELD_LENGTH is for the length of the promisedStreamId
        int nonFragmentLength = INT_FIELD_LENGTH + padding;
        int maxFragmentLength = maxFrameSize - nonFragmentLength;
        ByteBuf fragment = headerBlock.readRetainedSlice(min(headerBlock.readableBytes(), maxFragmentLength));
        flags.endOfHeaders(!headerBlock.isReadable());
        int payloadLength = fragment.readableBytes() + nonFragmentLength;
        ByteBuf buf = ctx.alloc().buffer(PUSH_PROMISE_FRAME_HEADER_LENGTH);
        writeFrameHeaderInternal(buf, payloadLength, PUSH_PROMISE, flags, streamId);
        writePaddingLength(buf, padding);
        // Write out the promised stream ID.
        buf.writeInt(promisedStreamId);
        ctx.write(buf, promiseAggregator.newPromise());
        // Write the first fragment.
        ctx.write(fragment, promiseAggregator.newPromise());
        // Write out the padding, if any.
        if (paddingBytes(padding) > 0) {
            ctx.write(ZERO_BUFFER.slice(0, paddingBytes(padding)), promiseAggregator.newPromise());
        }
        if (!flags.endOfHeaders()) {
            writeContinuationFrames(ctx, streamId, headerBlock, padding, promiseAggregator);
        }
    } catch (Http2Exception e) {
        promiseAggregator.setFailure(e);
    } catch (Throwable t) {
        promiseAggregator.setFailure(t);
        promiseAggregator.doneAllocatingPromises();
        PlatformDependent.throwException(t);
    } finally {
        if (headerBlock != null) {
            headerBlock.release();
        }
    }
    return promiseAggregator.doneAllocatingPromises();
}
Also used : SimpleChannelPromiseAggregator(io.netty.handler.codec.http2.Http2CodecUtil.SimpleChannelPromiseAggregator) ByteBuf(io.netty.buffer.ByteBuf)

Example 38 with ByteBuf

use of io.netty.buffer.ByteBuf in project netty by netty.

the class DefaultHttp2FrameWriter method writeData.

@Override
public ChannelFuture writeData(ChannelHandlerContext ctx, int streamId, ByteBuf data, int padding, boolean endStream, ChannelPromise promise) {
    final SimpleChannelPromiseAggregator promiseAggregator = new SimpleChannelPromiseAggregator(promise, ctx.channel(), ctx.executor());
    final DataFrameHeader header = new DataFrameHeader(ctx, streamId);
    boolean needToReleaseHeaders = true;
    boolean needToReleaseData = true;
    try {
        verifyStreamId(streamId, STREAM_ID);
        verifyPadding(padding);
        boolean lastFrame;
        int remainingData = data.readableBytes();
        do {
            // Determine how much data and padding to write in this frame. Put all padding at the end.
            int frameDataBytes = min(remainingData, maxFrameSize);
            int framePaddingBytes = min(padding, max(0, (maxFrameSize - 1) - frameDataBytes));
            // Decrement the remaining counters.
            padding -= framePaddingBytes;
            remainingData -= frameDataBytes;
            // Determine whether or not this is the last frame to be sent.
            lastFrame = remainingData == 0 && padding == 0;
            // Only the last frame is not retained. Until then, the outer finally must release.
            ByteBuf frameHeader = header.slice(frameDataBytes, framePaddingBytes, lastFrame && endStream);
            needToReleaseHeaders = !lastFrame;
            ctx.write(lastFrame ? frameHeader : frameHeader.retain(), promiseAggregator.newPromise());
            // Write the frame data.
            ByteBuf frameData = data.readSlice(frameDataBytes);
            // Only the last frame is not retained. Until then, the outer finally must release.
            needToReleaseData = !lastFrame;
            ctx.write(lastFrame ? frameData : frameData.retain(), promiseAggregator.newPromise());
            // Write the frame padding.
            if (paddingBytes(framePaddingBytes) > 0) {
                ctx.write(ZERO_BUFFER.slice(0, paddingBytes(framePaddingBytes)), promiseAggregator.newPromise());
            }
        } while (!lastFrame);
    } catch (Throwable t) {
        if (needToReleaseHeaders) {
            header.release();
        }
        if (needToReleaseData) {
            data.release();
        }
        promiseAggregator.setFailure(t);
    }
    return promiseAggregator.doneAllocatingPromises();
}
Also used : SimpleChannelPromiseAggregator(io.netty.handler.codec.http2.Http2CodecUtil.SimpleChannelPromiseAggregator) ByteBuf(io.netty.buffer.ByteBuf)

Example 39 with ByteBuf

use of io.netty.buffer.ByteBuf in project netty by netty.

the class DefaultHttp2FrameWriter method writeHeadersInternal.

private ChannelFuture writeHeadersInternal(ChannelHandlerContext ctx, int streamId, Http2Headers headers, int padding, boolean endStream, boolean hasPriority, int streamDependency, short weight, boolean exclusive, ChannelPromise promise) {
    ByteBuf headerBlock = null;
    SimpleChannelPromiseAggregator promiseAggregator = new SimpleChannelPromiseAggregator(promise, ctx.channel(), ctx.executor());
    try {
        verifyStreamId(streamId, STREAM_ID);
        if (hasPriority) {
            verifyStreamOrConnectionId(streamDependency, STREAM_DEPENDENCY);
            verifyPadding(padding);
            verifyWeight(weight);
        }
        // Encode the entire header block.
        headerBlock = ctx.alloc().buffer();
        headersEncoder.encodeHeaders(streamId, headers, headerBlock);
        Http2Flags flags = new Http2Flags().endOfStream(endStream).priorityPresent(hasPriority).paddingPresent(padding > 0);
        // Read the first fragment (possibly everything).
        int nonFragmentBytes = padding + flags.getNumPriorityBytes();
        int maxFragmentLength = maxFrameSize - nonFragmentBytes;
        ByteBuf fragment = headerBlock.readRetainedSlice(min(headerBlock.readableBytes(), maxFragmentLength));
        // Set the end of headers flag for the first frame.
        flags.endOfHeaders(!headerBlock.isReadable());
        int payloadLength = fragment.readableBytes() + nonFragmentBytes;
        ByteBuf buf = ctx.alloc().buffer(HEADERS_FRAME_HEADER_LENGTH);
        writeFrameHeaderInternal(buf, payloadLength, HEADERS, flags, streamId);
        writePaddingLength(buf, padding);
        if (hasPriority) {
            long word1 = exclusive ? 0x80000000L | streamDependency : streamDependency;
            writeUnsignedInt(word1, buf);
            // Adjust the weight so that it fits into a single byte on the wire.
            buf.writeByte(weight - 1);
        }
        ctx.write(buf, promiseAggregator.newPromise());
        // Write the first fragment.
        ctx.write(fragment, promiseAggregator.newPromise());
        // Write out the padding, if any.
        if (paddingBytes(padding) > 0) {
            ctx.write(ZERO_BUFFER.slice(0, paddingBytes(padding)), promiseAggregator.newPromise());
        }
        if (!flags.endOfHeaders()) {
            writeContinuationFrames(ctx, streamId, headerBlock, padding, promiseAggregator);
        }
    } catch (Http2Exception e) {
        promiseAggregator.setFailure(e);
    } catch (Throwable t) {
        promiseAggregator.setFailure(t);
        promiseAggregator.doneAllocatingPromises();
        PlatformDependent.throwException(t);
    } finally {
        if (headerBlock != null) {
            headerBlock.release();
        }
    }
    return promiseAggregator.doneAllocatingPromises();
}
Also used : SimpleChannelPromiseAggregator(io.netty.handler.codec.http2.Http2CodecUtil.SimpleChannelPromiseAggregator) ByteBuf(io.netty.buffer.ByteBuf)

Example 40 with ByteBuf

use of io.netty.buffer.ByteBuf in project netty by netty.

the class DefaultHttp2ConnectionEncoderTest method dataWriteShouldCreateHalfClosedStream.

@Test
public void dataWriteShouldCreateHalfClosedStream() throws Exception {
    writeAllFlowControlledFrames();
    Http2Stream stream = createStream(STREAM_ID, false);
    ByteBuf data = dummyData();
    ChannelPromise promise = newPromise();
    encoder.writeData(ctx, STREAM_ID, data.retain(), 0, true, promise);
    assertTrue(promise.isSuccess());
    verify(remoteFlow).addFlowControlled(eq(stream), any(FlowControlled.class));
    verify(lifecycleManager).closeStreamLocal(stream, promise);
    assertEquals(data.toString(UTF_8), writtenData.get(0));
    data.release();
}
Also used : ChannelPromise(io.netty.channel.ChannelPromise) DefaultChannelPromise(io.netty.channel.DefaultChannelPromise) ByteBuf(io.netty.buffer.ByteBuf) FlowControlled(io.netty.handler.codec.http2.Http2RemoteFlowController.FlowControlled) Test(org.junit.Test)

Aggregations

ByteBuf (io.netty.buffer.ByteBuf)1557 Test (org.junit.Test)668 EmbeddedChannel (io.netty.channel.embedded.EmbeddedChannel)162 IOException (java.io.IOException)99 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)89 CompositeByteBuf (io.netty.buffer.CompositeByteBuf)81 Test (org.testng.annotations.Test)68 InetSocketAddress (java.net.InetSocketAddress)60 Channel (io.netty.channel.Channel)57 ChannelFuture (io.netty.channel.ChannelFuture)56 ArrayList (java.util.ArrayList)55 Map (java.util.Map)45 ChannelPromise (io.netty.channel.ChannelPromise)41 AtomicReference (java.util.concurrent.atomic.AtomicReference)36 DefaultFullHttpResponse (io.netty.handler.codec.http.DefaultFullHttpResponse)35 NioEventLoopGroup (io.netty.channel.nio.NioEventLoopGroup)34 HashMap (java.util.HashMap)34 CountDownLatch (java.util.concurrent.CountDownLatch)34 RecyclableDuplicateByteBuf (io.netty.buffer.RecyclableDuplicateByteBuf)32 EventLoopGroup (io.netty.channel.EventLoopGroup)32