/// <summary> /// Checks 9 bytes from <paramref name="begin"/> correspond to a known HTTP version. /// </summary> /// <remarks> /// A "known HTTP version" Is is either HTTP/1.0 or HTTP/1.1. /// Since those fit in 8 bytes, they can be optimally looked up by reading those bytes as a long. Once /// in that format, it can be checked against the known versions. /// The Known versions will be checked with the required '\r'. /// To optimize performance the HTTP/1.1 will be checked first. /// </remarks> /// <param name="begin">The iterator from which to start the known string lookup.</param> /// <param name="scan">If we found a valid method, then scan will be updated to new position</param> /// <param name="knownVersion">A reference to a pre-allocated known string, if the input matches any.</param> /// <returns><c>true</c> if the input matches a known string, <c>false</c> otherwise.</returns> public static bool GetKnownVersion(this MemoryPoolIterator begin, ref MemoryPoolIterator scan, out string knownVersion) { knownVersion = null; var value = begin.PeekLong(); if (value == _http11VersionLong) { knownVersion = Http11Version; scan.Skip(8); if (scan.Take() == '\r') { return(true); } } else if (value == _http10VersionLong) { knownVersion = Http10Version; scan.Skip(8); if (scan.Take() == '\r') { return(true); } } knownVersion = null; return(false); }
/// <summary> /// Checks that up to 8 bytes from <paramref name="begin"/> correspond to a known HTTP method. /// </summary> /// <remarks> /// A "known HTTP method" can be an HTTP method name defined in the HTTP/1.1 RFC. /// Since all of those fit in at most 8 bytes, they can be optimally looked up by reading those bytes as a long. Once /// in that format, it can be checked against the known method. /// The Known Methods (CONNECT, DELETE, GET, HEAD, PATCH, POST, PUT, OPTIONS, TRACE) are all less than 8 bytes /// and will be compared with the required space. A mask is used if the Known method is less than 8 bytes. /// To optimize performance the GET method will be checked first. /// </remarks> /// <param name="begin">The iterator from which to start the known string lookup.</param> /// <param name="scan">If we found a valid method, then scan will be updated to new position</param> /// <param name="knownMethod">A reference to a pre-allocated known string, if the input matches any.</param> /// <returns><c>true</c> if the input matches a known string, <c>false</c> otherwise.</returns> public static bool GetKnownMethod(this MemoryPoolIterator begin, ref MemoryPoolIterator scan, out string knownMethod) { knownMethod = null; var value = begin.PeekLong(); if ((value & _mask4Chars) == _httpGetMethodLong) { knownMethod = HttpGetMethod; scan.Skip(4); return(true); } foreach (var x in _knownMethods) { if ((value & x.Item1) == x.Item2) { knownMethod = x.Item3; scan.Skip(knownMethod.Length + 1); return(true); } } return(false); }