private HttpMethod(string method, int?http3StaticTableIndex) : this(method) { _http3EncodedBytes = http3StaticTableIndex != null? QPackEncoder.EncodeStaticIndexedHeaderFieldToArray(http3StaticTableIndex.GetValueOrDefault()) : QPackEncoder.EncodeLiteralHeaderFieldWithStaticNameReferenceToArray(H3StaticTable.MethodGet, method); }
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); } }
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); }
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); }
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); } }
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)); }