private static async Task sendHeader(Http2Settings settings, Http2FrameHeader frameHeader, byte[] frameHeaderBuffer, RequestResponseBase rr, bool endStream, Stream output, bool pushPromise) { var encoder = new Encoder(settings.HeaderTableSize); var ms = new MemoryStream(); var writer = new BinaryWriter(ms); if (rr.Priority.HasValue) { long p = rr.Priority.Value; writer.Write((byte)((p >> 32) & 0xff)); writer.Write((byte)((p >> 24) & 0xff)); writer.Write((byte)((p >> 16) & 0xff)); writer.Write((byte)((p >> 8) & 0xff)); writer.Write((byte)(p & 0xff)); } if (rr is Request request) { var uri = request.RequestUri; encoder.EncodeHeader(writer, StaticTable.KnownHeaderMethod, request.Method.GetByteString()); encoder.EncodeHeader(writer, StaticTable.KnownHeaderAuhtority, uri.Authority.GetByteString()); encoder.EncodeHeader(writer, StaticTable.KnownHeaderScheme, uri.Scheme.GetByteString()); encoder.EncodeHeader(writer, StaticTable.KnownHeaderPath, request.Url.GetByteString(), false, HpackUtil.IndexType.None, false); } else { var response = (Response)rr; encoder.EncodeHeader(writer, StaticTable.KnownHeaderStatus, response.StatusCode.ToString().GetByteString()); } foreach (var header in rr.Headers) { encoder.EncodeHeader(writer, header.NameData, header.ValueData); } var data = ms.ToArray(); int newLength = data.Length; frameHeader.Length = newLength; frameHeader.Type = pushPromise ? Http2FrameType.PushPromise : Http2FrameType.Headers; var flags = Http2FrameFlag.EndHeaders; if (endStream) { flags |= Http2FrameFlag.EndStream; } if (rr.Priority.HasValue) { flags |= Http2FrameFlag.Priority; } frameHeader.Flags = flags; // clear the padding flag //headerBuffer[4] = (byte)(flags & ~((int)Http2FrameFlag.Padded)); // send the header frameHeader.CopyToBuffer(frameHeaderBuffer); await output.WriteAsync(frameHeaderBuffer, 0, frameHeaderBuffer.Length /*, cancellationToken*/); await output.WriteAsync(data, 0, data.Length /*, cancellationToken*/); }