Skip to content

Commit

Permalink
Merge pull request #156 from icarus-consulting/i155-support-content-e…
Browse files Browse the repository at this point in the history
…ncoding

Support automatic response content decompression
  • Loading branch information
DFU398 authored Mar 6, 2024
2 parents 944e1c5 + 8ea950b commit 9dc0367
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 9 deletions.
35 changes: 27 additions & 8 deletions src/Yaapii.Http/Wires/AspNetCore/AspNetCoreClients.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//MIT License

//Copyright(c) 2020 ICARUS Consulting GmbH
//Copyright(c) 2023 ICARUS Consulting GmbH

//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -36,7 +36,7 @@ namespace Yaapii.Http.Wires.AspNetCore
/// </summary>
public sealed class AspNetCoreClients : IAspHttpClients
{
private readonly IDictionary<long, HttpClient> clients = new Dictionary<long, HttpClient>();
private readonly IDictionary<long, HttpClient> clients;
private readonly Func<TimeSpan, HttpClient> addClient;
private readonly IAction setup;

Expand All @@ -55,8 +55,26 @@ public AspNetCoreClients() : this(
/// This will return an existing client, if the same timeout has been used before.
/// Otherwise, this will create a new client with the given timeout, because the timeout can only be set before the first request is sent.
/// </summary>
public AspNetCoreClients(SecurityProtocolType security) : this(timeout =>
new HttpClient()
public AspNetCoreClients(SecurityProtocolType security) : this(
security,
new HttpClientHandler()
{
#if NET6_0
AutomaticDecompression = DecompressionMethods.All
#else
AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip
#endif
}
)
{ }

/// <summary>
/// Only add one of these to your application to make sure clients will be reused whenever possible.
/// This will return an existing client, if the same timeout has been used before.
/// Otherwise, this will create a new client with the given timeout, because the timeout can only be set before the first request is sent.
/// </summary>
public AspNetCoreClients(SecurityProtocolType security, HttpClientHandler httpClientHandler) : this(timeout =>
new HttpClient(httpClientHandler)
{
Timeout = timeout
},
Expand All @@ -74,24 +92,25 @@ public AspNetCoreClients(SecurityProtocolType security) : this(timeout =>
/// </summary>
private AspNetCoreClients(Func<TimeSpan, HttpClient> addClient, IAction setup)
{
this.clients = new Dictionary<long, HttpClient>();
this.addClient = addClient;
this.setup = setup;
}

public HttpClient Client(TimeSpan timeout)
{
lock (clients)
lock (this.clients)
{
this.setup.Invoke();
if (!clients.Keys.Contains(timeout.Ticks))
if (!this.clients.Keys.Contains(timeout.Ticks))
{
clients.Add(
this.clients.Add(
timeout.Ticks,
this.addClient(timeout)
);
}
}
return clients[timeout.Ticks];
return this.clients[timeout.Ticks];
}
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,42 @@
using System;
//MIT License

//Copyright(c) 2023 ICARUS Consulting GmbH

//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:

//The above copyright notice and this permission notice shall be included in all
//copies or substantial portions of the Software.

//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//SOFTWARE.

using System;
using System.IO.Compression;
using System.Net;
using Xunit;
using Yaapii.Atoms.IO;
using Yaapii.Atoms.Map;
using Yaapii.Atoms.Text;
using Yaapii.Http.Fake;
using Yaapii.Http.Mock;
using Yaapii.Http.Parts.Bodies;
using Yaapii.Http.Parts.Uri;
using Yaapii.Http.Requests;
using Yaapii.Http.Test;

namespace Yaapii.Http.Wires.AspNetCore.Test
{
[Collection("actual http tests")]
public sealed class AspNetCoreClientsTests
{
[Fact]
Expand Down Expand Up @@ -54,5 +87,46 @@ public void SetsDefaultSecurityTypes()
SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12
);
}

[Fact]
public void SetsDefaultDecompressionMethods()
{
var port = new AwaitedPort(new TestPort()).Value();

var compressedStream = new System.IO.MemoryStream();
var zipStream = new GZipStream(compressedStream, CompressionMode.Compress);
new InputOf("very important content").Stream().CopyTo(zipStream);
zipStream.Close();

using (var server =
new HttpMock(port,
new FkWire(
new MapOf("Content-Encoding", "gzip"),
new Body(
new InputOf(compressedStream.ToArray())
)
)
).Value()
)
{
Assert.Equal(
"very important content",
new TextOf(
new Body.Of(
new AspNetCoreWire(
new AspNetCoreClients(),
new TimeSpan(0, 1, 0)
).Response(
new Get(
new Scheme("http"),
new Host("localhost"),
new Port(port)
)
)
)
).AsString()
);
}
}
}
}

0 comments on commit 9dc0367

Please sign in to comment.