public void TranslateHeaders(IEnumerable <HeaderEntry <ICharSequence, ICharSequence> > inputHeaders) { // lazily created as needed StringBuilder cookies = null; foreach (var entry in inputHeaders) { var name = entry.Key; var value = entry.Value; if (_translations.TryGet(name, out var translatedName)) { _ = _output.Add(translatedName, AsciiString.Of(value)); } else if (!PseudoHeaderName.IsPseudoHeader(name)) { // https://tools.ietf.org/html/rfc7540#section-8.1.2.3 // All headers that start with ':' are only valid in HTTP/2 context if (0u >= (uint)name.Count || name[0] == ':') { StringBuilderManager.Free(cookies); ThrowHelper.ThrowStreamError_InvalidHttp2HeaderEncounteredInTranslationToHttp1(_streamId, name); } var cookie = HttpHeaderNames.Cookie; if (cookie.Equals(name)) { // combine the cookie values into 1 header entry. // https://tools.ietf.org/html/rfc7540#section-8.1.2.5 if (cookies is null) { cookies = StringBuilderManager.Allocate(); } else if ((uint)cookies.Length > 0u) { _ = cookies.Append("; "); } _ = cookies.Append(value.ToString()); } else { _ = _output.Add(AsciiString.Of(name), value); } } } if (cookies is object) { _ = _output.Add(HttpHeaderNames.Cookie, StringBuilderManager.ReturnAndFree(cookies)); } }
/// <summary> /// Returns the <see cref="PseudoHeaderName"/> corresponding to the specified header name. /// return corresponding <see cref="PseudoHeaderName"/> if any, <c>null</c> otherwise. /// </summary> /// <param name="header"></param> public static PseudoHeaderName GetPseudoHeader(ICharSequence header) { return(PseudoHeaders.TryGet(header, out var name) ? name : null); }
/// <summary> /// Returns the lowest index value for the given header field name in the static table. Returns /// -1 if the header field name is not in the static table. /// </summary> /// <param name="name"></param> internal static int GetIndex(ICharSequence name) { return(StaticIndexByName.TryGet(name, out var index) ? index : -1); }