private void WriteHeader(ref HeaderEncodingState state, string name, string value) { // TODO: ISSUE 31307: Use static table for known headers int bytesWritten; while (!HPackEncoder.EncodeHeader(name, value, _requestBuffer.AvailableSpan, out bytesWritten)) { GrowWriteBuffer(); } _requestBuffer.Commit(bytesWritten); while (_requestBuffer.ActiveSpan.Slice(state.CurrentFrameOffset).Length > FrameHeader.Size + FrameHeader.MaxLength) { // We've exceeded the frame size limit. // Fill in the current frame header. WriteCurrentFrameHeader(ref state, FrameHeader.MaxLength, false); state.IsFirstFrame = false; state.CurrentFrameOffset += FrameHeader.Size + FrameHeader.MaxLength; // Reserve space for new frame header _requestBuffer.Commit(FrameHeader.Size); Span <byte> currentFrameSpan = _requestBuffer.ActiveSpan.Slice(state.CurrentFrameOffset); // Shift the remainder down to make room for the new frame header. // We'll fill this in when the frame is complete. currentFrameSpan.Slice(0, currentFrameSpan.Length - FrameHeader.Size).CopyTo(currentFrameSpan.Slice(FrameHeader.Size)); } }
private static bool EncodeStatusHeader(int statusCode, HPackEncoder hpackEncoder, Span <byte> buffer, out int length) { switch (statusCode) { case 200: case 204: case 206: case 304: case 400: case 404: case 500: // Status codes which exist in the HTTP/2 StaticTable. return(HPackEncoder.EncodeIndexedHeaderField(H2StaticTable.GetStatusIndex(statusCode), buffer, out length)); default: const string name = ":status"; var value = StatusCodes.ToStatusString(statusCode); return(hpackEncoder.EncodeHeader(buffer, H2StaticTable.Status200, HeaderEncodingHint.Index, name, value, out length)); } }
private static bool EncodeHeadersCore(HPackEncoder hpackEncoder, Http2HeadersEnumerator headersEnumerator, Span <byte> buffer, bool throwIfNoneEncoded, out int length) { var currentLength = 0; do { var staticTableId = headersEnumerator.HPackStaticTableId; var name = headersEnumerator.Current.Key; var value = headersEnumerator.Current.Value; var hint = ResolveHeaderEncodingHint(staticTableId, name); if (!hpackEncoder.EncodeHeader( buffer.Slice(currentLength), staticTableId, hint, name, value, out var headerLength)) { // If the header wasn't written, and no headers have been written, then the header is too large. // Throw an error to avoid an infinite loop of attempting to write large header. if (currentLength == 0 && throwIfNoneEncoded) { throw new HPackEncodingException(SR.net_http_hpack_encode_failure); } length = currentLength; return(false); } currentLength += headerLength; }while (headersEnumerator.MoveNext()); length = currentLength; return(true); }