Exemple #1
0
            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));
                }
            }
Exemple #2
0
        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));
            }
        }
Exemple #3
0
        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);
        }