using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Threading;
using System.Threading.Tasks;
namespace Sandbox;
public static partial class Http
{
///
/// Send a HTTP request to the specified URI and return the response body as a string in an asynchronous operation.
///
/// The URI to request.
/// The HTTP verb for the request (eg. GET, POST, etc.).
/// The content to include within the request, or null if none should be sent.
/// Headers to add to the request, or null if none should be added.
/// An optional cancellation token for canceling this request.
/// An asynchronous task which resolves to the response body as a string.
/// The request responded with a non-2xx HTTP status code.
/// The request was not allowed, either an unallowed URI or header.
public static async Task RequestStringAsync( string requestUri, string method = "GET", HttpContent content = null, Dictionary headers = null, CancellationToken cancellationToken = default )
{
using var response = await RequestAsync( requestUri, method, content, headers: headers, cancellationToken: cancellationToken );
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync( cancellationToken );
}
///
/// Send a HTTP request to the specified URI and return the response body as a byte array in an asynchronous operation.
///
/// The URI to request.
/// The HTTP verb for the request (eg. GET, POST, etc.).
/// The content to include within the request, or null if none should be sent.
/// Headers to add to the request, or null if none should be added.
/// An optional cancellation token for canceling this request.
/// An asynchronous task which resolves to the response body as a byte array.
/// The request responded with a non-2xx HTTP status code.
/// The request was not allowed, either an unallowed URI or header.
public static async Task RequestBytesAsync( string requestUri, string method = "GET", HttpContent content = null, Dictionary headers = null, CancellationToken cancellationToken = default )
{
using var response = await RequestAsync( requestUri, method, content, headers: headers, cancellationToken: cancellationToken );
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsByteArrayAsync( cancellationToken );
}
///
/// Send a HTTP request to the specified URI and return the response body as a stream in an asynchronous operation.
///
/// The URI to request.
/// The HTTP verb for the request (eg. GET, POST, etc.).
/// The content to include within the request, or null if none should be sent.
/// Headers to add to the request, or null if none should be added.
/// An optional cancellation token for canceling this request.
/// An asynchronous task which resolves to the response body as a .
/// The request responded with a non-2xx HTTP status code.
/// The request was not allowed, either an unallowed URI or header.
public static async Task RequestStreamAsync( string requestUri, string method = "GET", HttpContent content = null, Dictionary headers = null, CancellationToken cancellationToken = default )
{
using var response = await RequestAsync( requestUri, method, content, headers: headers, cancellationToken: cancellationToken );
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStreamAsync( cancellationToken );
}
///
/// Sends a HTTP request to the specified URI and return the response body as a JSON deserialized object in an asynchronous operation.
///
/// The URI to request.
/// The HTTP verb for the request (eg. GET, POST, etc.).
/// The content to include within the request, or null if none should be sent.
/// Headers to add to the request, or null if none should be added.
/// An optional cancellation token for canceling this request.
/// An asynchronous task which resolves to the response body deserialized from JSON.
/// The request responded with a non-2xx HTTP status code.
/// The request was not allowed, either an unallowed URI or header.
public static async Task RequestJsonAsync( string requestUri, string method = "GET", HttpContent content = null, Dictionary headers = null, CancellationToken cancellationToken = default )
{
using var response = await RequestAsync( requestUri, method, content, headers: headers, cancellationToken: cancellationToken );
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync( cancellationToken: cancellationToken );
}
///
/// Sends a HTTP request to the specified URI and returns the response in an asynchronous operation.
///
/// The URI to request.
/// The HTTP verb for the request (eg. GET, POST, etc.).
/// The content to include within the request, or null if none should be sent.
/// Headers to add to the request, or null if none should be added.
/// An optional cancellation token for canceling this request.
/// An asynchronous task which resolves to a containing the response for the request.
/// The request responded with a non-2xx HTTP status code.
/// The request was not allowed, either an unallowed URI or header.
public static async Task RequestAsync( string requestUri, string method = "GET", HttpContent content = null, Dictionary headers = null, CancellationToken cancellationToken = default )
{
if ( string.IsNullOrWhiteSpace( method ) )
{
throw new ArgumentNullException( nameof( method ) );
}
using var request = CreateRequest( new HttpMethod( method ), requestUri, headers );
request.Content = content;
return await Client.SendAsync( request, cancellationToken );
}
///
/// Creates a new instance containing the specified object serialized to JSON.
///
public static HttpContent CreateJsonContent( T target )
{
return JsonContent.Create( target, new MediaTypeHeaderValue( "application/json" ) );
}
internal static HttpRequestMessage CreateRequest( HttpMethod method, string requestUri, Dictionary headers )
{
var uri = new Uri( requestUri, UriKind.Absolute );
if ( !IsAllowed( uri ) )
{
throw new InvalidOperationException( $"Access to '{uri}' is not allowed." );
}
var request = new HttpRequestMessage( method, uri );
if ( headers != null )
{
foreach ( var (key, value) in headers )
{
if ( !IsHeaderAllowed( key ) )
{
throw new InvalidOperationException( $"Not allowed to set header '{key}'." );
}
request.Headers.TryAddWithoutValidation( key, value );
}
}
return request;
}
}