Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
aspriddell committed Nov 27, 2021
2 parents d2503da + 37675e0 commit 24a537c
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 4 deletions.
22 changes: 22 additions & 0 deletions DragonFruit.Common.Data.Tests/Requests/StreamTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// DragonFruit.Common Copyright 2021 DragonFruit Network
// Licensed under the MIT License. Please refer to the LICENSE file at the root of this project for details

using System.IO;
using System.Threading.Tasks;
using NUnit.Framework;

namespace DragonFruit.Common.Data.Tests.Requests
{
[TestFixture]
public class StreamTests : ApiTest
{
[Test]
public async Task TestStreamRequests()
{
var networkStream = await Client.PerformAsync<MemoryStream>("https://google.com");
var fileStream = await Client.PerformAsync<FileStream>("https://google.com");

Assert.AreEqual(networkStream.Length, fileStream.Length);
}
}
}
29 changes: 25 additions & 4 deletions DragonFruit.Common.Data/ApiClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading;
Expand Down Expand Up @@ -34,7 +35,7 @@ public ApiClient(CultureInfo culture = null)
}

/// <summary>
/// Initialises a new <see cref="ApiClient"/> using a user-set <see cref="ISerializer"/>
/// Initialises a new <see cref="ApiClient"/> using a user-set <see cref="ApiSerializer"/>
/// </summary>
public ApiClient(ApiSerializer serializer)
{
Expand Down Expand Up @@ -95,7 +96,7 @@ public Func<HttpMessageHandler> Handler
}

/// <summary>
/// The container for <see cref="ISerializer"/>s. The default serializer can be set at <see cref="SerializerResolver.Default"/>
/// The container for <see cref="ApiSerializer"/>s. The default serializer can be set at <see cref="SerializerResolver.Default"/>
/// </summary>
/// <remarks>
/// Defaults to <see cref="ApiJsonSerializer"/>
Expand Down Expand Up @@ -202,6 +203,7 @@ protected virtual void SetupRequest(HttpRequestMessage request)
/// <param name="request">The request to perform</param>
/// <param name="processResult"><see cref="Func{T,TResult}"/> to process the <see cref="HttpResponseMessage"/></param>
/// <param name="disposeResponse">Whether to dispose of the <see cref="HttpResponseMessage"/> produced after <see cref="processResult"/> has been invoked.</param>
/// <param name="token">(optional) <see cref="CancellationToken"/></param>
protected Task<T> InternalPerform<T>(HttpRequestMessage request, Func<HttpResponseMessage, Task<T>> processResult, bool disposeResponse, CancellationToken token = default)
{
var (client, clientLock) = GetClient();
Expand Down Expand Up @@ -261,6 +263,25 @@ protected virtual async Task<T> ValidateAndProcess<T>(HttpResponseMessage respon
response.EnsureSuccessStatusCode();

using var stream = await response.Content.ReadAsStreamAsync();

if (typeof(Stream).IsAssignableFrom(typeof(T)))
{
Stream result;

if (typeof(T) == typeof(Stream) && response.Content.Headers.ContentLength < 80000 || typeof(T) == typeof(MemoryStream))
{
result = new MemoryStream();
}
else
{
result = File.Create(Path.GetTempFileName(), 4096, FileOptions.Asynchronous | FileOptions.SequentialScan | FileOptions.DeleteOnClose);
}

await stream.CopyToAsync(result).ConfigureAwait(false);
result.Seek(0, SeekOrigin.Begin);
return result as T;
}

return Serializer.Resolve<T>(DataDirection.In).Deserialize<T>(stream);
}

Expand All @@ -272,6 +293,8 @@ protected virtual async Task<T> ValidateAndProcess<T>(HttpResponseMessage respon
/// <exception cref="ClientValidationException">The client can't be used because there is no auth url.</exception>
protected virtual void ValidateRequest(ApiRequest request)
{
request.OnRequestExecuting(this);

// note request path is validated on build
if (request.RequireAuth && string.IsNullOrEmpty(Authorization))
{
Expand All @@ -281,8 +304,6 @@ protected virtual void ValidateRequest(ApiRequest request)
throw new ClientValidationException("Authorization header was expected, but not found (in request or client)");
}
}

request.OnRequestExecuting(this);
}

/// <summary>
Expand Down

0 comments on commit 24a537c

Please sign in to comment.