예제 #1
0
        private static bool EncodeHeaders(Http2HeadersEnumerator headersEnumerator, Span <byte> buffer, bool throwIfNoneEncoded, out int length)
        {
            var currentLength = 0;

            do
            {
                if (!EncodeHeader(headersEnumerator.KnownHeaderType, headersEnumerator.Current.Key, headersEnumerator.Current.Value, buffer.Slice(currentLength), out int headerLength))
                {
                    // The 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);
        }
예제 #2
0
        /// <summary>
        /// Begin encoding headers in the first HEADERS frame.
        /// </summary>
        public static bool BeginEncodeHeaders(Http2HeadersEnumerator headersEnumerator, Span <byte> buffer, out int length)
        {
            if (!headersEnumerator.MoveNext())
            {
                length = 0;
                return(true);
            }

            return(EncodeHeaders(headersEnumerator, buffer, throwIfNoneEncoded: true, out length));
        }
예제 #3
0
        /// <summary>
        /// Begin encoding headers in the first HEADERS frame.
        /// </summary>
        public static bool BeginEncodeHeaders(HPackEncoder hpackEncoder, Http2HeadersEnumerator headersEnumerator, Span <byte> buffer, out int length)
        {
            length = 0;

            if (!hpackEncoder.EnsureDynamicTableSizeUpdate(buffer, out var sizeUpdateLength))
            {
                throw new HPackEncodingException(SR.net_http_hpack_encode_failure);
            }
            length += sizeUpdateLength;

            if (!headersEnumerator.MoveNext())
            {
                return(true);
            }

            var done = EncodeHeadersCore(hpackEncoder, headersEnumerator, buffer.Slice(length), throwIfNoneEncoded: true, out var headersLength);

            length += headersLength;
            return(done);
        }
예제 #4
0
        private static bool EncodeHeadersCore(DynamicHPackEncoder 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 valueEncoding =
                    ReferenceEquals(headersEnumerator.EncodingSelector, KestrelServerOptions.DefaultHeaderEncodingSelector)
                    ? null : headersEnumerator.EncodingSelector(name);

                var hint = ResolveHeaderEncodingHint(staticTableId, name);

                if (!hpackEncoder.EncodeHeader(
                        buffer.Slice(currentLength),
                        staticTableId,
                        hint,
                        name,
                        value,
                        valueEncoding,
                        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);
        }
예제 #5
0
        /// <summary>
        /// Begin encoding headers in the first HEADERS frame.
        /// </summary>
        public static bool BeginEncodeHeaders(int statusCode, Http2HeadersEnumerator headersEnumerator, Span <byte> buffer, out int length)
        {
            if (!HPackEncoder.EncodeStatusHeader(statusCode, buffer, out var statusCodeLength))
            {
                throw new HPackEncodingException(SR.net_http_hpack_encode_failure);
            }

            if (!headersEnumerator.MoveNext())
            {
                length = statusCodeLength;
                return(true);
            }

            // We're ok with not throwing if no headers were encoded because we've already encoded the status.
            // There is a small chance that the header will encode if there is no other content in the next HEADERS frame.
            var done = EncodeHeaders(headersEnumerator, buffer.Slice(statusCodeLength), throwIfNoneEncoded: false, out var headersLength);

            length = statusCodeLength + headersLength;

            return(done);
        }
예제 #6
0
 /// <summary>
 /// Continue encoding headers in the next HEADERS frame. The enumerator should already have a current value.
 /// </summary>
 public static bool ContinueEncodeHeaders(HPackEncoder hpackEncoder, Http2HeadersEnumerator headersEnumerator, Span <byte> buffer, out int length)
 {
     return(EncodeHeadersCore(hpackEncoder, headersEnumerator, buffer, throwIfNoneEncoded: true, out length));
 }