internal static async Task <Match> MatchLineAsync(this IAsyncEnumerator <byte> enumerator, Regex regex)
        {
            // Validate parameters.
            if (enumerator == null)
            {
                throw new ArgumentNullException(nameof(enumerator));
            }
            if (regex == null)
            {
                throw new ArgumentNullException(nameof(regex));
            }

            // The line.
            string line = await enumerator.ReadLineAsync().ConfigureAwait(false);

            // Match.
            Match match = regex.Match(line);

            // If not successful, throw an exception.
            if (!match.Success)
            {
                throw new InvalidOperationException($"The regular expression did not match the line. (regex: { regex }, line: { line }");
            }

            // Return the match.
            return(match);
        }
Ejemplo n.º 2
0
        internal static async Task SetHeaderFieldsAsync(this HttpResponseMessage response,
                                                        IAsyncEnumerator <byte> enumerator,
                                                        CancellationToken cancellationToken)
        {
            // Validate parameters.
            if (response == null)
            {
                throw new ArgumentNullException(nameof(response));
            }
            if (enumerator == null)
            {
                throw new ArgumentNullException(nameof(enumerator));
            }

            // The line.
            string line;

            // The field and value.
            string field = null;
            string value = null;

            // While the line is not null or empty.
            while (!string.IsNullOrEmpty(line = await enumerator.ReadLineAsync(cancellationToken).ConfigureAwait(false)))
            {
                // The match.
                Match match;

                // Does this match a folded value?  If so, add to the previous value.
                if ((match = FoldedHeaderFieldRegex.Match(line)).Success)
                {
                    // Add to the previous value.
                    value += " " + match.GetGroupValue("value");
                }
                else if ((match = HeaderFieldRegex.Match(line)).Success)
                {
                    // If the field and value are set, then set them now.
                    if (field != null && value != null)
                    {
                        response.Headers.TryAddWithoutValidation(field, value);
                    }

                    // Set the field and the value.
                    field = match.GetGroupValue("fieldName");
                    value = match.GetGroupValue("fieldValue");
                }
            }

            // If the field and value are set, then set them now.
            if (field != null && value != null)
            {
                response.Headers.TryAddWithoutValidation(field, value);
            }
        }
Ejemplo n.º 3
0
        internal static async Task <HttpContent> ReadHttpContentFromChunkedTransferEncoding(this IAsyncEnumerator <byte> enumerator,
                                                                                            HttpResponseMessage response, CancellationToken cancellationToken)
        {
            // Validate parameters.
            if (enumerator == null)
            {
                throw new ArgumentNullException(nameof(enumerator));
            }
            if (response == null)
            {
                throw new ArgumentNullException(nameof(response));
            }

            // The memory stream.
            var ms = new MemoryStream();

            // Continue forever.
            while (true)
            {
                // Read the array buffer as a string.
                string chunkSize = await enumerator.ReadLineAsync(cancellationToken).ConfigureAwait(false);

                // Match.
                Match match = ChunkSizeRegex.Match(chunkSize);

                // Convert to a length.
                int length = int.Parse(match.GetGroupValue("chunkSize"), NumberStyles.HexNumber);

                // If 0, get out.
                if (length == 0 && !match.Groups["chunkExtension"].Success)
                {
                    // Get out.
                    break;
                }

                // While there are bytes to read.
                while (length-- > 0 && await enumerator.MoveNext(cancellationToken).ConfigureAwait(false))
                {
                    ms.WriteByte(enumerator.Current);
                }

                // Read the bytes.
                var line = await enumerator.ReadLineBytesAsync(cancellationToken).ConfigureAwait(false);

                // If not empty, throw.
                if (line.Count > 0)
                {
                    throw new InvalidOperationException("An unexpected byte sequence was encountered after processing chunked encoding data.");
                }
            }

            // Set the header fields again.  This is for extra headers that
            // may be passed down.
            await response.SetHeaderFieldsAsync(enumerator, cancellationToken).ConfigureAwait(false);

            // Reset the memory stream.
            ms.Seek(0, SeekOrigin.Begin);

            // Return the content.
            return(new StreamContent(ms));
        }