forked from RPCS3/discord-bot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCompressionMessageHandler.cs
62 lines (57 loc) · 3.02 KB
/
CompressionMessageHandler.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
namespace CompatApiClient.Compression;
public class CompressionMessageHandler : DelegatingHandler
{
public ICollection<ICompressor> Compressors { get; }
public static readonly string PostCompressionFlag = "X-Set-Content-Encoding";
public static readonly string[] DefaultContentEncodings = ["gzip", "deflate"];
public static readonly string DefaultAcceptEncodings = "gzip, deflate";
private readonly bool isServer;
private readonly bool isClient;
public CompressionMessageHandler(bool isServer = false)
{
this.isServer = isServer;
isClient = !isServer;
Compressors = [new GZipCompressor(), new DeflateCompressor()];
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
if (isServer
&& request.Content?.Headers.ContentEncoding.FirstOrDefault() is string serverEncoding
&& Compressors.FirstOrDefault(c => c.EncodingType.Equals(serverEncoding, StringComparison.OrdinalIgnoreCase)) is ICompressor serverDecompressor)
{
request.Content = new DecompressedContent(request.Content, serverDecompressor);
}
else if (isClient
&& (request.Method == HttpMethod.Post || request.Method == HttpMethod.Put)
&& request.Content != null
&& request.Headers.TryGetValues(PostCompressionFlag, out var compressionFlagValues)
&& compressionFlagValues.FirstOrDefault() is string compressionFlag
&& Compressors.FirstOrDefault(c => c.EncodingType.Equals(compressionFlag, StringComparison.OrdinalIgnoreCase)) is ICompressor clientCompressor)
{
request.Content = new CompressedContent(request.Content, clientCompressor);
}
request.Headers.Remove(PostCompressionFlag);
//ApiConfig.Log.Trace($"{request.Method} {request.RequestUri}");
var response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
//ApiConfig.Log.Trace($"Response: {response.StatusCode} {request.RequestUri}");
if (isClient
&& response.Content.Headers.ContentEncoding.FirstOrDefault() is string clientEncoding
&& Compressors.FirstOrDefault(c => c.EncodingType.Equals(clientEncoding, StringComparison.OrdinalIgnoreCase)) is ICompressor clientDecompressor)
{
response.Content = new DecompressedContent(response.Content, clientDecompressor);
}
else if (isServer
&& request.Headers.AcceptEncoding.FirstOrDefault() is {} acceptEncoding
&& Compressors.FirstOrDefault(c => c.EncodingType.Equals(acceptEncoding.Value, StringComparison.OrdinalIgnoreCase)) is ICompressor serverCompressor)
{
response.Content = new CompressedContent(response.Content, serverCompressor);
}
return response;
}
}