/// <summary> /// Asynchronously parses a request body in <c>application/x-www-form-urlencoded</c> format. /// </summary> /// <param name="this">The <see cref="IHttpContext"/> on which this method is called.</param> /// <returns>A <see cref="Task{TResult}">Task</see>, representing the ongoing operation, /// whose result will be a read-only <see cref="NameValueCollection"/>of form field names and values.</returns> /// <exception cref="NullReferenceException"><paramref name="this"/> is <see langword="null"/>.</exception> /// <remarks> /// <para>This method may safely be called more than once for the same <see cref="IHttpContext"/>: /// it will return the same collection instead of trying to parse the request body again.</para> /// </remarks> public static async Task <NameValueCollection> GetRequestFormDataAsync(this IHttpContext @this) { if ([email protected](FormDataKey, out var previousResult)) { NameValueCollection result; try { using var reader = @this.OpenRequestText(); result = UrlEncodedDataParser.Parse(await reader.ReadToEndAsync().ConfigureAwait(false), false); } catch (Exception e) { @this.Items[FormDataKey] = e; throw; } @this.Items[FormDataKey] = result; return(result); } switch (previousResult) { case NameValueCollection collection: return(collection); case Exception exception: throw exception.RethrowPreservingStackTrace(); case null: throw SelfCheck.Failure($"Previous result of {nameof(HttpContextExtensions)}.{nameof(GetRequestFormDataAsync)} is null."); default: throw SelfCheck.Failure($"Previous result of {nameof(HttpContextExtensions)}.{nameof(GetRequestFormDataAsync)} is of unexpected type {previousResult.GetType().FullName}"); } }
/// <summary> /// Parses a request URL query. Note that this is different from getting the <see cref="IHttpRequest.QueryString"/> property, /// in that fields without an equal sign are treated as if they have an empty value, instead of their keys being grouped /// as values of the <c>null</c> key. /// </summary> /// <param name="this">The <see cref="IHttpContext"/> on which this method is called.</param> /// <returns>A read-only <see cref="NameValueCollection"/>.</returns> /// <exception cref="NullReferenceException"><paramref name="this"/> is <see langword="null"/>.</exception> /// <remarks> /// <para>This method may safely be called more than once for the same <see cref="IHttpContext"/>: /// it will return the same collection instead of trying to parse the request body again.</para> /// </remarks> public static NameValueCollection GetRequestQueryData(this IHttpContext @this) { if ([email protected](QueryDataKey, out var previousResult)) { NameValueCollection result; try { result = UrlEncodedDataParser.Parse(@this.Request.Url.Query, false); } catch (Exception e) { @this.Items[FormDataKey] = e; throw; } @this.Items[FormDataKey] = result; return(result); } switch (previousResult) { case NameValueCollection collection: return(collection); case Exception exception: throw exception.RethrowPreservingStackTrace(); case null: throw SelfCheck.Failure($"Previous result of {nameof(HttpContextExtensions)}.{nameof(GetRequestQueryData)} is null."); default: throw SelfCheck.Failure($"Previous result of {nameof(HttpContextExtensions)}.{nameof(GetRequestQueryData)} is of unexpected type {previousResult.GetType().FullName}"); } }
public TestRequest(HttpRequestMessage clientRequest) { _content = Validate.NotNull(nameof(clientRequest), clientRequest).Content; var headers = new NameValueCollection(); foreach (var pair in clientRequest.Headers) { var values = pair.Value.ToArray(); switch (values.Length) { case 0: headers.Add(pair.Key, string.Empty); break; case 1: headers.Add(pair.Key, values[0]); break; default: foreach (var value in values) { headers.Add(pair.Key, value); } break; } switch (pair.Key) { case HttpHeaderNames.Cookie: Cookies = CookieList.Parse(string.Join(",", values)); break; } } Headers = headers; if (Cookies == null) { Cookies = new CookieList(); } ProtocolVersion = clientRequest.Version; KeepAlive = !(clientRequest.Headers.ConnectionClose ?? true); RawUrl = clientRequest.RequestUri.PathAndQuery; QueryString = UrlEncodedDataParser.Parse(clientRequest.RequestUri.Query, true, true); HttpMethod = clientRequest.Method.ToString(); HttpVerb = HttpMethodToVerb(clientRequest.Method); Url = clientRequest.RequestUri; HasEntityBody = _content != null; ContentEncoding = Encoding.GetEncoding(_content?.Headers.ContentType?.CharSet ?? Encoding.UTF8.WebName); RemoteEndPoint = new IPEndPoint(IPAddress.Loopback, 9999); UserAgent = clientRequest.Headers.UserAgent?.ToString(); LocalEndPoint = new IPEndPoint(IPAddress.Loopback, 8080); ContentType = _content?.Headers.ContentType?.MediaType; }