diff --git a/Octokit/Clients/ReleasesClient.cs b/Octokit/Clients/ReleasesClient.cs index 1a82f7fdc8..a8fb1958f1 100644 --- a/Octokit/Clients/ReleasesClient.cs +++ b/Octokit/Clients/ReleasesClient.cs @@ -1,6 +1,8 @@ using System.Threading.Tasks; using System.Collections.Generic; using System.Threading; +using System.IO; +using System; namespace Octokit { @@ -501,6 +503,37 @@ public Task GetAsset(long repositoryId, int assetId) return ApiConnection.Get(endpoint); } + /// + /// Gets a raw read-only stream containing the file data for the specified asset + /// + /// + /// See the API documentation for more information. + /// + /// The Id of the repository + /// The id of the + [ManualRoute("GET", "/repositories/{id}/releases/assets/{asset_id}")] + public Task DownloadAsset(long repositoryId, int assetId) + { + var endpoint = ApiUrls.Asset(repositoryId, assetId); + return ApiConnection.GetRawStream(endpoint, null, "application/octet-stream"); + } + + /// + /// Gets a raw read-only stream containing the file data for the specified asset + /// + /// + /// See the API documentation for more information. + /// + /// The repository's owner + /// The repository's name + /// The id of the + [ManualRoute("GET", "/repositories/{id}/releases/assets/{asset_id}")] + public Task DownloadAsset(string owner, string name, int assetId) + { + var endpoint = ApiUrls.Asset(owner, name, assetId); + return ApiConnection.GetRawStream(endpoint, null, "application/octet-stream"); + } + /// /// Edits the for the specified release of the specified repository. /// diff --git a/Octokit/Http/ApiConnection.cs b/Octokit/Http/ApiConnection.cs index 929de72a65..2de304ce42 100644 --- a/Octokit/Http/ApiConnection.cs +++ b/Octokit/Http/ApiConnection.cs @@ -125,6 +125,31 @@ public async Task GetHtml(Uri uri, IDictionary parameter return response.Body; } + /// + /// Gets the raw content of the API resource at the specified URI. + /// + /// URI of the API resource to get + /// Accept header to use for the API request + /// Parameters to add to the API request + /// The API resource's raw content or null if the points to a directory. + /// Thrown when an API error occurs. + public async Task GetRaw(Uri uri, IDictionary parameters, string accepts) + { + Ensure.ArgumentNotNull(uri, nameof(uri)); + + var response = await Connection.GetRaw(uri, parameters, accepts).ConfigureAwait(false); + return response.Body; + } + + /// + public async Task GetRawStream(Uri uri, IDictionary parameters, string accepts) + { + Ensure.ArgumentNotNull(uri, nameof(uri)); + + var response = await Connection.GetRawStream(uri, parameters, accepts).ConfigureAwait(false); + return response.Body; + } + /// /// Gets the raw content of the API resource at the specified URI. /// diff --git a/Octokit/Http/Connection.cs b/Octokit/Http/Connection.cs index 091af09ca9..f5394f990d 100644 --- a/Octokit/Http/Connection.cs +++ b/Octokit/Http/Connection.cs @@ -224,6 +224,62 @@ public Task> GetHtml(Uri uri, IDictionary p }); } + /// + /// Performs an asynchronous HTTP GET request that expects a containing raw data. + /// + /// URI endpoint to send request to + /// Querystring parameters for the request + /// Accept header to use for the API request + /// representing the received HTTP response + /// The property will be null if the points to a directory instead of a file + public Task> GetRaw(Uri uri, IDictionary parameters, string accepts) + { + Ensure.ArgumentNotNull(uri, nameof(uri)); + + var req = new Request + { + Method = HttpMethod.Get, + BaseAddress = BaseAddress, + Endpoint = uri.ApplyParameters(parameters), + }; + req.Headers.Add("Accept", accepts); + + return GetRaw(req); + } + + /// + public Task> GetRaw(Uri uri, IDictionary parameters, TimeSpan timeout, string accepts) + { + Ensure.ArgumentNotNull(uri, nameof(uri)); + + var req = new Request + { + Method = HttpMethod.Get, + BaseAddress = BaseAddress, + Endpoint = uri.ApplyParameters(parameters), + Timeout = timeout + }; + req.Headers.Add("Accept", accepts); + + return GetRaw(req); + } + + /// + public Task> GetRawStream(Uri uri, IDictionary parameters, string accepts) + { + Ensure.ArgumentNotNull(uri, nameof(uri)); + + var req = new Request + { + Method = HttpMethod.Get, + BaseAddress = BaseAddress, + Endpoint = uri.ApplyParameters(parameters) + }; + req.Headers.Add("Accept", accepts); + + return GetRawStream(req); + } + /// /// Performs an asynchronous HTTP GET request that expects a containing raw data. /// @@ -737,14 +793,16 @@ public IResponseCache ResponseCache async Task> GetHtml(IRequest request) { - request.Headers.Add("Accept", AcceptHeaders.StableVersionHtml); + if (request.Headers.ContainsKey("Accept") is false) + request.Headers.Add("Accept", AcceptHeaders.StableVersionHtml); var response = await RunRequest(request, CancellationToken.None).ConfigureAwait(false); return new ApiResponse(response, response.Body as string); } async Task> GetRaw(IRequest request) { - request.Headers.Add("Accept", AcceptHeaders.RawContentMediaType); + if (request.Headers.ContainsKey("Accept") is false) + request.Headers.Add("Accept", AcceptHeaders.RawContentMediaType); var response = await RunRequest(request, CancellationToken.None).ConfigureAwait(false); if (response.Body is Stream stream) @@ -757,7 +815,8 @@ async Task> GetRaw(IRequest request) async Task> GetRawStream(IRequest request) { - request.Headers.Add("Accept", AcceptHeaders.RawContentMediaType); + if (request.Headers.ContainsKey("Accept") is false) + request.Headers.Add("Accept", AcceptHeaders.RawContentMediaType); var response = await RunRequest(request, CancellationToken.None).ConfigureAwait(false); return new ApiResponse(response, response.Body as Stream); diff --git a/Octokit/Http/IApiConnection.cs b/Octokit/Http/IApiConnection.cs index 3888f5883a..92180da7c7 100644 --- a/Octokit/Http/IApiConnection.cs +++ b/Octokit/Http/IApiConnection.cs @@ -63,6 +63,26 @@ public interface IApiConnection /// Thrown when an API error occurs. Task GetHtml(Uri uri, IDictionary parameters); + /// + /// Gets the raw content of the API resource at the specified URI. + /// + /// URI of the API resource to get + /// Accept header to use for the API request + /// Parameters to add to the API request + /// The API resource's raw content or null if the points to a directory. + /// Thrown when an API error occurs. + Task GetRaw(Uri uri, IDictionary parameters, string accepts); + + /// + /// Gets the raw stream of the API resource at the specified URI. + /// + /// URI of the API resource to get + /// Parameters to add to the API request + /// Accept header to use for the API request + /// The API resource's raw stream or null if the points to a directory. + /// Thrown when an API error occurs. + Task GetRawStream(Uri uri, IDictionary parameters, string accepts); + /// /// Gets the raw content of the API resource at the specified URI. /// diff --git a/Octokit/Http/IConnection.cs b/Octokit/Http/IConnection.cs index 4e75a10975..1041549602 100644 --- a/Octokit/Http/IConnection.cs +++ b/Octokit/Http/IConnection.cs @@ -22,6 +22,37 @@ public interface IConnection : IApiInfoProvider /// representing the received HTTP response Task> GetHtml(Uri uri, IDictionary parameters); + /// + /// Performs an asynchronous HTTP GET request that expects a containing raw data. + /// + /// URI endpoint to send request to + /// Querystring parameters for the request + /// Accept header to use for the API request + /// representing the received HTTP response + /// The property will be null if the points to a directory instead of a file + Task> GetRaw(Uri uri, IDictionary parameters, string accepts); + + /// + /// Performs an asynchronous HTTP GET request that expects a containing raw data. + /// + /// URI endpoint to send request to + /// Querystring parameters for the request + /// Accept header to use for the API request + /// The Timeout value + /// representing the received HTTP response + /// The property will be null if the points to a directory instead of a file + Task> GetRaw(Uri uri, IDictionary parameters, TimeSpan timeout, string accepts); + + /// + /// Performs an asynchronous HTTP GET request that expects a containing raw data. + /// + /// URI endpoint to send request to + /// Querystring parameters for the request + /// Accept header to use for the API request + /// representing the received HTTP response + /// The property will be null if the points to a directory instead of a file + Task> GetRawStream(Uri uri, IDictionary parameters, string accepts); + /// /// Performs an asynchronous HTTP GET request that expects a containing raw data. ///