Skip to content

Commit

Permalink
add xml docs to Request.cs file
Browse files Browse the repository at this point in the history
  • Loading branch information
bezzad committed Sep 18, 2024
1 parent c991bf1 commit 98fb472
Showing 1 changed file with 82 additions and 3 deletions.
85 changes: 82 additions & 3 deletions src/Downloader/Request.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@

namespace Downloader;

/// <summary>
/// Represents a class for making HTTP requests and handling response headers.
/// </summary>
public class Request
{
private const string GetRequestMethod = "GET";
Expand All @@ -19,11 +22,24 @@ public class Request
private readonly RequestConfiguration _configuration;
private readonly Dictionary<string, string> _responseHeaders;
private readonly Regex _contentRangePattern;

/// <summary>
/// Gets the URI address of the request.
/// </summary>
public Uri Address { get; private set; }

/// <summary>
/// Initializes a new instance of the <see cref="Request"/> class with the specified address.
/// </summary>
/// <param name="address">The URL address to create the request for.</param>
public Request(string address) : this(address, new RequestConfiguration())
{ }

/// <summary>
/// Initializes a new instance of the <see cref="Request"/> class with the specified address and configuration.
/// </summary>
/// <param name="address">The URL address to create the request for.</param>
/// <param name="config">The configuration for the request.</param>
public Request(string address, RequestConfiguration config)
{
if (Uri.TryCreate(address, UriKind.Absolute, out Uri uri) == false)
Expand All @@ -37,6 +53,11 @@ public Request(string address, RequestConfiguration config)
_contentRangePattern = new Regex(@"bytes\s*((?<from>\d*)\s*-\s*(?<to>\d*)|\*)\s*\/\s*(?<size>\d+|\*)", RegexOptions.Compiled);
}

/// <summary>
/// Creates an HTTP request with the specified method.
/// </summary>
/// <param name="method">The HTTP method to use for the request.</param>
/// <returns>An instance of <see cref="HttpWebRequest"/> representing the HTTP request.</returns>
private HttpWebRequest GetRequest(string method)
{
HttpWebRequest request = WebRequest.CreateHttp(Address);

Check warning on line 63 in src/Downloader/Request.cs

View workflow job for this annotation

GitHub Actions / build

'WebRequest.CreateHttp(Uri)' is obsolete: 'WebRequest, HttpWebRequest, ServicePoint, and WebClient are obsolete. Use HttpClient instead.' (https://aka.ms/dotnet-warnings/SYSLIB0014)

Check warning on line 63 in src/Downloader/Request.cs

View workflow job for this annotation

GitHub Actions / build

'WebRequest.CreateHttp(Uri)' is obsolete: 'WebRequest, HttpWebRequest, ServicePoint, and WebClient are obsolete. Use HttpClient instead.' (https://aka.ms/dotnet-warnings/SYSLIB0014)
Expand Down Expand Up @@ -78,11 +99,21 @@ private HttpWebRequest GetRequest(string method)

return request;
}

/// <summary>
/// Creates an HTTP GET request.
/// </summary>
/// <returns>An instance of <see cref="HttpWebRequest"/> representing the HTTP GET request.</returns>
public HttpWebRequest GetRequest()
{
return GetRequest(GetRequestMethod);
}

/// <summary>
/// Fetches the response headers asynchronously.
/// </summary>
/// <param name="addRange">Indicates whether to add a range header to the request.</param>
/// <returns>A task that represents the asynchronous operation.</returns>
private async Task FetchResponseHeaders(bool addRange = true)
{
try
Expand All @@ -99,7 +130,7 @@ private async Task FetchResponseHeaders(bool addRange = true)

using WebResponse response = await request.GetResponseAsync().ConfigureAwait(false);
EnsureResponseAddressIsSameWithOrigin(response);
if (response?.SupportsHeaders == true)
if (response.SupportsHeaders)
{
foreach (string headerKey in response.Headers.AllKeys)
{
Expand Down Expand Up @@ -128,6 +159,11 @@ exp.Response is HttpWebResponse response &&
}
}

/// <summary>
/// Ensures that the response address is the same as the original address.
/// </summary>
/// <param name="response">The web response to check.</param>
/// <returns>True if the response address is the same as the original address; otherwise, false.</returns>
private bool EnsureResponseAddressIsSameWithOrigin(WebResponse response)
{
var redirectUri = GetRedirectUrl(response);
Expand All @@ -140,6 +176,11 @@ private bool EnsureResponseAddressIsSameWithOrigin(WebResponse response)
return true;
}

/// <summary>
/// Gets the redirect URL from the web response.
/// </summary>
/// <param name="response">The web response to get the redirect URL from.</param>
/// <returns>The redirect URL.</returns>
public Uri GetRedirectUrl(WebResponse response)
{
// https://github.com/dotnet/runtime/issues/23264
Expand All @@ -156,6 +197,10 @@ public Uri GetRedirectUrl(WebResponse response)
return Address;
}

/// <summary>
/// Gets the file size asynchronously.
/// </summary>
/// <returns>A task that represents the asynchronous operation. The task result contains the file size.</returns>
public async Task<long> GetFileSize()
{
if (await IsSupportDownloadInRange().ConfigureAwait(false))
Expand All @@ -166,6 +211,10 @@ public async Task<long> GetFileSize()
return GetTotalSizeFromContentLength(_responseHeaders);
}

/// <summary>
/// Throws an exception if the download in range is not supported.
/// </summary>
/// <returns>A task that represents the asynchronous operation.</returns>
public async Task ThrowIfIsNotSupportDownloadInRange()
{
var isSupport = await IsSupportDownloadInRange().ConfigureAwait(false);
Expand All @@ -175,6 +224,10 @@ public async Task ThrowIfIsNotSupportDownloadInRange()
}
}

/// <summary>
/// Checks if the download in range is supported.
/// </summary>
/// <returns>A task that represents the asynchronous operation. The task result contains a boolean indicating whether the download in range is supported.</returns>
public async Task<bool> IsSupportDownloadInRange()
{
await FetchResponseHeaders().ConfigureAwait(false);
Expand All @@ -198,6 +251,11 @@ public async Task<bool> IsSupportDownloadInRange()
return false;
}

/// <summary>
/// Gets the total size from the content range headers.
/// </summary>
/// <param name="headers">The headers to get the total size from.</param>
/// <returns>The total size of the content.</returns>
public long GetTotalSizeFromContentRange(Dictionary<string, string> headers)
{
if (headers.TryGetValue(HeaderContentRangeKey, out string contentRange) &&
Expand All @@ -215,6 +273,11 @@ public long GetTotalSizeFromContentRange(Dictionary<string, string> headers)
return -1L;
}

/// <summary>
/// Gets the total size from the content length headers.
/// </summary>
/// <param name="headers">The headers to get the total size from.</param>
/// <returns>The total size of the content.</returns>
public long GetTotalSizeFromContentLength(Dictionary<string, string> headers)
{
if (headers.TryGetValue(HeaderContentLengthKey, out string contentLengthText) &&
Expand All @@ -226,6 +289,10 @@ public long GetTotalSizeFromContentLength(Dictionary<string, string> headers)
return -1L;
}

/// <summary>
/// Gets the file name asynchronously.
/// </summary>
/// <returns>A task that represents the asynchronous operation. The task result contains the file name.</returns>
public async Task<string> GetFileName()
{
var filename = await GetUrlDispositionFilenameAsync().ConfigureAwait(false);
Expand All @@ -241,6 +308,10 @@ public async Task<string> GetFileName()
return filename;
}

/// <summary>
/// Gets the file name from the URL.
/// </summary>
/// <returns>The file name extracted from the URL.</returns>
public string GetFileNameFromUrl()
{
string filename = Path.GetFileName(Address.LocalPath);
Expand All @@ -253,6 +324,10 @@ public string GetFileNameFromUrl()
return filename;
}

/// <summary>
/// Gets the file name from the URL disposition header asynchronously.
/// </summary>
/// <returns>A task that represents the asynchronous operation. The task result contains the file name.</returns>
public async Task<string> GetUrlDispositionFilenameAsync()
{
try
Expand Down Expand Up @@ -289,10 +364,14 @@ public async Task<string> GetUrlDispositionFilenameAsync()
return null;
}

/// <summary>
/// Converts the specified text from 'latin-1' encoding to 'utf-8' encoding.
/// </summary>
/// <param name="otherEncodedText">The text to convert.</param>
/// <returns>The converted text in 'utf-8' encoding.</returns>
public string ToUnicode(string otherEncodedText)
{
// decode 'latin-1' to 'utf-8'
string unicode = Encoding.UTF8.GetString(Encoding.GetEncoding("iso-8859-1").GetBytes(otherEncodedText));
return unicode;
return Encoding.UTF8.GetString(Encoding.GetEncoding("iso-8859-1").GetBytes(otherEncodedText));
}
}

0 comments on commit 98fb472

Please sign in to comment.