Пример #1
0
 private HttpMethod(string method, int?http3StaticTableIndex)
     : this(method)
 {
     _http3EncodedBytes = http3StaticTableIndex != null?
                          QPackEncoder.EncodeStaticIndexedHeaderFieldToArray(http3StaticTableIndex.GetValueOrDefault()) :
                              QPackEncoder.EncodeLiteralHeaderFieldWithStaticNameReferenceToArray(H3StaticTable.MethodGet, method);
 }
Пример #2
0
        private static int EncodeStatusCode(int statusCode, Span <byte> buffer)
        {
            switch (statusCode)
            {
            case 200:
            case 204:
            case 206:
            case 304:
            case 400:
            case 404:
            case 500:
                QPackEncoder.EncodeStaticIndexedHeaderField(H3StaticTable.StatusIndex[statusCode], buffer, out var bytesWritten);
                return(bytesWritten);

            default:
                // https://tools.ietf.org/html/draft-ietf-quic-qpack-21#section-4.5.4
                // Index is 63 - :status
                buffer[0] = 0b01011111;
                buffer[1] = 0b00110000;

                ReadOnlySpan <byte> statusBytes = System.Net.Http.HPack.StatusCodes.ToStatusBytes(statusCode);
                buffer[2] = (byte)statusBytes.Length;
                statusBytes.CopyTo(buffer.Slice(3));

                return(3 + statusBytes.Length);
            }
        }
Пример #3
0
        private static bool Encode(Http3HeadersEnumerator enumerator, Span <byte> buffer, bool throwIfNoneEncoded, ref int totalHeaderSize, out int length)
        {
            length = 0;

            do
            {
                var current       = enumerator.Current;
                var valueEncoding = ReferenceEquals(enumerator.EncodingSelector, KestrelServerOptions.DefaultHeaderEncodingSelector)
                    ? null : enumerator.EncodingSelector(current.Key);

                if (!QPackEncoder.EncodeLiteralHeaderFieldWithoutNameReference(current.Key, current.Value, valueEncoding, buffer.Slice(length), out int headerLength))
                {
                    if (length == 0 && throwIfNoneEncoded)
                    {
                        throw new QPackEncodingException("TODO sync with corefx" /* CoreStrings.HPackErrorNotEnoughBuffer */);
                    }
                    return(false);
                }

                // https://quicwg.org/base-drafts/draft-ietf-quic-http.html#section-4.1.1.3
                totalHeaderSize += HeaderField.GetLength(current.Key.Length, current.Value.Length);
                length          += headerLength;
            } while (enumerator.MoveNext());

            return(true);
        }
Пример #4
0
    private static bool Encode(Http3HeadersEnumerator headersEnumerator, Span <byte> buffer, bool throwIfNoneEncoded, ref int totalHeaderSize, out int length)
    {
        length = 0;

        do
        {
            // Match the current header to the QPACK static table. Possible outcomes:
            // 1. Known header and value. Write index.
            // 2. Known header with custom value. Write name index and full value.
            // 3. Unknown header. Write full name and value.
            var(staticTableId, matchedValue) = headersEnumerator.GetQPackStaticTableId();
            var name  = headersEnumerator.Current.Key;
            var value = headersEnumerator.Current.Value;

            int headerLength;
            if (matchedValue)
            {
                if (!QPackEncoder.EncodeStaticIndexedHeaderField(staticTableId, buffer.Slice(length), out headerLength))
                {
                    if (length == 0 && throwIfNoneEncoded)
                    {
                        throw new QPackEncodingException("TODO sync with corefx" /* CoreStrings.HPackErrorNotEnoughBuffer */);
                    }
                    return(false);
                }
            }
            else
            {
                var valueEncoding = ReferenceEquals(headersEnumerator.EncodingSelector, KestrelServerOptions.DefaultHeaderEncodingSelector)
                    ? null : headersEnumerator.EncodingSelector(name);

                if (!EncodeHeader(buffer.Slice(length), staticTableId, name, value, valueEncoding, out headerLength))
                {
                    if (length == 0 && throwIfNoneEncoded)
                    {
                        throw new QPackEncodingException("TODO sync with corefx" /* CoreStrings.HPackErrorNotEnoughBuffer */);
                    }
                    return(false);
                }
            }

            // https://quicwg.org/base-drafts/draft-ietf-quic-http.html#section-4.1.1.3
            totalHeaderSize += HeaderField.GetLength(name.Length, value.Length);
            length          += headerLength;
        } while (headersEnumerator.MoveNext());

        return(true);
    }
Пример #5
0
    private static int EncodeStatusCode(int statusCode, Span <byte> buffer)
    {
        if (H3StaticTable.TryGetStatusIndex(statusCode, out var index))
        {
            QPackEncoder.EncodeStaticIndexedHeaderField(index, buffer, out var bytesWritten);
            return(bytesWritten);
        }
        else
        {
            // https://tools.ietf.org/html/draft-ietf-quic-qpack-21#section-4.5.4
            // Index is 63 - :status
            buffer[0] = 0b01011111;
            buffer[1] = 0b00110000;

            ReadOnlySpan <byte> statusBytes = System.Net.Http.HPack.StatusCodes.ToStatusBytes(statusCode);
            buffer[2] = (byte)statusBytes.Length;
            statusBytes.CopyTo(buffer.Slice(3));

            return(3 + statusBytes.Length);
        }
    }
Пример #6
0
 private static bool EncodeHeader(Span <byte> buffer, int staticTableId, string name, string value, Encoding?valueEncoding, out int headerLength)
 {
     return(staticTableId == -1
         ? QPackEncoder.EncodeLiteralHeaderFieldWithoutNameReference(name, value, valueEncoding, buffer, out headerLength)
         : QPackEncoder.EncodeLiteralHeaderFieldWithStaticNameReference(staticTableId, value, valueEncoding, buffer, out headerLength));
 }