private byte[] HeaderPayload(int streamId, IHttp2Headers headers) { var byteBuf = Unpooled.Buffer(); try { _http2HeadersEncoder.EncodeHeaders(streamId, headers, byteBuf); byte[] bytes = new byte[byteBuf.ReadableBytes]; byteBuf.ReadBytes(bytes); return(bytes); } finally { byteBuf.Release(); } }
public virtual Task WritePushPromiseAsync(IChannelHandlerContext ctx, int streamId, int promisedStreamId, IHttp2Headers headers, int padding, IPromise promise) { IByteBuffer headerBlock = null; SimplePromiseAggregator promiseAggregator = new SimplePromiseAggregator(promise); try { if ((uint)(streamId - 1) > SharedConstants.TooBigOrNegative) { ThrowHelper.ThrowArgumentException_Positive(ExceptionArgument.StreamID); } if (promisedStreamId <= 0) { ThrowHelper.ThrowArgumentException_Positive(ExceptionArgument.PromisedStreamId); } Http2CodecUtil.VerifyPadding(padding); // Encode the entire header block into an intermediate buffer. headerBlock = ctx.Allocator.Buffer(); _headersEncoder.EncodeHeaders(streamId, headers, headerBlock); // Read the first fragment (possibly everything). Http2Flags flags = new Http2Flags().PaddingPresent(padding > 0); // IntFieldLength is for the length of the promisedStreamId int nonFragmentLength = Http2CodecUtil.IntFieldLength + padding; int maxFragmentLength = _maxFrameSize - nonFragmentLength; IByteBuffer fragment = headerBlock.ReadRetainedSlice(Math.Min(headerBlock.ReadableBytes, maxFragmentLength)); _ = flags.EndOfHeaders(!headerBlock.IsReadable()); int payloadLength = fragment.ReadableBytes + nonFragmentLength; IByteBuffer buf = ctx.Allocator.Buffer(Http2CodecUtil.PushPromiseFrameHeaderLength); Http2CodecUtil.WriteFrameHeaderInternal(buf, payloadLength, Http2FrameTypes.PushPromise, flags, streamId); WritePaddingLength(buf, padding); // Write out the promised stream ID. _ = buf.WriteInt(promisedStreamId); _ = ctx.WriteAsync(buf, promiseAggregator.NewPromise()); // Write the first fragment. _ = ctx.WriteAsync(fragment, promiseAggregator.NewPromise()); // Write out the padding, if any. if (PaddingBytes(padding) > 0) { _ = ctx.WriteAsync(ZeroBuffer.Slice(0, PaddingBytes(padding)), promiseAggregator.NewPromise()); } if (!flags.EndOfHeaders()) { _ = WriteContinuationFramesAsync(ctx, streamId, headerBlock, promiseAggregator); } } catch (Http2Exception e) { promiseAggregator.SetException(e); } catch (Exception t) { promiseAggregator.SetException(t); _ = promiseAggregator.DoneAllocatingPromises(); throw; } finally { if (headerBlock is object) { _ = headerBlock.Release(); } } _ = promiseAggregator.DoneAllocatingPromises(); return(promiseAggregator.Task); }