public static async Task <HttpApplicationResponseSection> ReadNextHttpApplicationResponseSectionAsync( this MultipartReader reader, CancellationToken cancellationToken = default) { var section = await reader.ReadNextSectionAsync(cancellationToken).ConfigureAwait(false); if (section == null) { return(null); // if null we're done } var contentTypeHeader = MediaTypeHeaderValue.Parse(section.ContentType); if (!contentTypeHeader.MediaType.HasValue || !contentTypeHeader.MediaType.Equals("application/http", StringComparison.OrdinalIgnoreCase)) { throw new InvalidDataException("Invalid Content-Type."); } var param = contentTypeHeader.Parameters.SingleOrDefault(a => a.Name.HasValue && a.Value.HasValue && a.Name.Value.Equals("msgtype", StringComparison.OrdinalIgnoreCase) && a.Value.Equals("response", StringComparison.OrdinalIgnoreCase)); if (param == null) { throw new InvalidDataException("Invalid Content-Type."); } var bufferedStream = new BufferedReadStream(section.Body, SectionHelper.DefaultBufferSize); var responseLine = await ReadResponseLineAsync(bufferedStream, cancellationToken).ConfigureAwait(false); if (responseLine.Length != 3) { throw new InvalidDataException("Invalid request line."); } var headers = await SectionHelper.ReadHeadersAsync(bufferedStream, cancellationToken).ConfigureAwait(false); return(new HttpApplicationResponseSection { ResponseFeature = new ResponseFeature { Body = bufferedStream, Protocol = responseLine[0], StatusCode = int.Parse(responseLine[1]), ReasonPhrase = responseLine[2], Headers = new HeaderDictionary(headers) } }); }
public static async Task <HttpApplicationRequestSection> ReadNextHttpApplicationRequestSectionAsync( this MultipartReader reader, PathString pathBase = default, bool isHttps = false, CancellationToken cancellationToken = default) { var section = await reader.ReadNextSectionAsync(cancellationToken).ConfigureAwait(false); if (section == null) { return(null); // if null we're done } var contentTypeHeader = MediaTypeHeaderValue.Parse(section.ContentType); if (!contentTypeHeader.MediaType.HasValue || !contentTypeHeader.MediaType.Equals("application/http", StringComparison.OrdinalIgnoreCase)) { throw new InvalidDataException("Invalid Content-Type."); } var param = contentTypeHeader.Parameters.SingleOrDefault(a => a.Name.HasValue && a.Value.HasValue && a.Name.Equals("msgtype", StringComparison.OrdinalIgnoreCase) && a.Value.Equals("request", StringComparison.OrdinalIgnoreCase)); if (param == null) { throw new InvalidDataException("Invalid Content-Type."); } var bufferedStream = new BufferedReadStream(section.Body, SectionHelper.DefaultBufferSize); var requestLineParts = await ReadRequestLineAsync(bufferedStream, cancellationToken).ConfigureAwait(false); if (requestLineParts.Length != 3) { throw new InvalidDataException("Invalid request line."); } // Validation of the request line parts necessary? var headers = await SectionHelper.ReadHeadersAsync(bufferedStream, cancellationToken).ConfigureAwait(false); if (!headers.TryGetValue(HeaderNames.Host, out var hostHeader)) { throw new InvalidDataException("No Host Header"); } var uri = BuildUri(isHttps, hostHeader, requestLineParts[1]); var fullPath = PathString.FromUriComponent(uri); var feature = new HttpRequestFeature { Body = bufferedStream, Headers = new HeaderDictionary(headers), Method = requestLineParts[0], Protocol = requestLineParts[2], Scheme = uri.Scheme, QueryString = uri.Query }; if (fullPath.StartsWithSegments(pathBase, out var remainder)) { feature.PathBase = pathBase.Value; feature.Path = remainder.Value; } else { feature.PathBase = string.Empty; feature.Path = fullPath.Value; } return(new HttpApplicationRequestSection { RequestFeature = feature }); }