Skip to content

Commit ffc3d8c

Browse files
Allow to adjust the handler and client used by the reverse proxy (#621)
1 parent 4e46821 commit ffc3d8c

File tree

4 files changed

+80
-16
lines changed

4 files changed

+80
-16
lines changed

Modules/ReverseProxy/Provider/ReverseProxyBuilder.cs

+55-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
using GenHTTP.Api.Content;
1+
using System.Net;
2+
3+
using GenHTTP.Api.Content;
24
using GenHTTP.Api.Infrastructure;
35

46
namespace GenHTTP.Modules.ReverseProxy.Provider;
@@ -12,8 +14,15 @@ public sealed class ReverseProxyBuilder : IHandlerBuilder<ReverseProxyBuilder>
1214

1315
private string? _Upstream;
1416

17+
private Action<SocketsHttpHandler>? _HandlerAdjustments;
18+
private Action<HttpClient>? _ClientAdjustments;
19+
1520
#region Functionality
1621

22+
/// <summary>
23+
/// Sets the server to pass the incoming requests to.
24+
/// </summary>
25+
/// <param name="upstream">The URL of the server to pass requests to</param>
1726
public ReverseProxyBuilder Upstream(string upstream)
1827
{
1928
_Upstream = upstream;
@@ -26,18 +35,46 @@ public ReverseProxyBuilder Upstream(string upstream)
2635
return this;
2736
}
2837

38+
/// <summary>
39+
/// The time allowed to try connecting to the upstream server (defaults to 10 seconds).
40+
/// </summary>
41+
/// <param name="connectTimeout">The connection timeout to be set</param>
2942
public ReverseProxyBuilder ConnectTimeout(TimeSpan connectTimeout)
3043
{
3144
_ConnectTimeout = connectTimeout;
3245
return this;
3346
}
3447

48+
/// <summary>
49+
/// The time allowed for the upstream server to generate a response (defaults to 60 seconds).
50+
/// </summary>
51+
/// <param name="readTimeout">The read timeout to be set</param>
3552
public ReverseProxyBuilder ReadTimeout(TimeSpan readTimeout)
3653
{
3754
_ReadTimeout = readTimeout;
3855
return this;
3956
}
4057

58+
/// <summary>
59+
/// A callback to be invoked to configure the socket HTTP handler used by the handler.
60+
/// </summary>
61+
/// <param name="adjustment">The callback to be invoked</param>
62+
public ReverseProxyBuilder AdjustHandler(Action<SocketsHttpHandler> adjustment)
63+
{
64+
_HandlerAdjustments = adjustment;
65+
return this;
66+
}
67+
68+
/// <summary>
69+
/// A callback to be invoked to configure the HTTP client used by the handler.
70+
/// </summary>
71+
/// <param name="adjustment">The callback to be invoked</param>
72+
public ReverseProxyBuilder AdjustClient(Action<HttpClient> adjustment)
73+
{
74+
_ClientAdjustments = adjustment;
75+
return this;
76+
}
77+
4178
public ReverseProxyBuilder Add(IConcernBuilder concern)
4279
{
4380
_Concerns.Add(concern);
@@ -51,7 +88,23 @@ public IHandler Build()
5188
throw new BuilderMissingPropertyException("Upstream");
5289
}
5390

54-
return Concerns.Chain(_Concerns, new ReverseProxyProvider( _Upstream, _ConnectTimeout, _ReadTimeout));
91+
var handler = new SocketsHttpHandler
92+
{
93+
AllowAutoRedirect = false,
94+
AutomaticDecompression = DecompressionMethods.None,
95+
ConnectTimeout = _ConnectTimeout
96+
};
97+
98+
_HandlerAdjustments?.Invoke(handler);
99+
100+
var client = new HttpClient(handler)
101+
{
102+
Timeout = _ReadTimeout
103+
};
104+
105+
_ClientAdjustments?.Invoke(client);
106+
107+
return Concerns.Chain(_Concerns, new ReverseProxyProvider(_Upstream, client));
55108
}
56109

57110
#endregion

Modules/ReverseProxy/Provider/ReverseProxyProvider.cs

+4-14
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
using System.Globalization;
2-
using System.Net;
32
using System.Net.Http.Headers;
43
using System.Web;
4+
55
using GenHTTP.Api.Content;
66
using GenHTTP.Api.Protocol;
7+
78
using GenHTTP.Modules.Basics;
89

910
namespace GenHTTP.Modules.ReverseProxy.Provider;
@@ -40,21 +41,10 @@ public sealed class ReverseProxyProvider : IHandler
4041

4142
#region Initialization
4243

43-
public ReverseProxyProvider(string upstream, TimeSpan connectTimeout, TimeSpan readTimeout)
44+
public ReverseProxyProvider(string upstream, HttpClient client)
4445
{
4546
Upstream = upstream;
46-
47-
var handler = new SocketsHttpHandler
48-
{
49-
AllowAutoRedirect = false,
50-
AutomaticDecompression = DecompressionMethods.None,
51-
ConnectTimeout = connectTimeout
52-
};
53-
54-
Client = new HttpClient(handler)
55-
{
56-
Timeout = readTimeout
57-
};
47+
Client = client;
5848
}
5949

6050
#endregion

Modules/ReverseProxy/Proxy.cs

+6
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,11 @@ namespace GenHTTP.Modules.ReverseProxy;
55
public static class Proxy
66
{
77

8+
/// <summary>
9+
/// Creates a handler that will route incoming requests to
10+
/// the specified upstream server.
11+
/// </summary>
12+
/// <returns>The newly created handler</returns>
813
public static ReverseProxyBuilder Create() => new();
14+
915
}

Testing/Acceptance/Modules/ReverseProxy/ReverseProxyTests.cs

+15
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,21 @@ public async Task TestCompression(TestEngine engine)
287287
Assert.AreEqual("br", response.GetContentHeader("Content-Encoding"));
288288
}
289289

290+
[TestMethod]
291+
public void TestAdjustments()
292+
{
293+
var i = 0;
294+
295+
var proxy = Proxy.Create()
296+
.Upstream("https://google.com")
297+
.AdjustHandler(h => i++)
298+
.AdjustClient(c => i++);
299+
300+
proxy.Build();
301+
302+
Assert.AreEqual(2, i);
303+
}
304+
290305
#region Supporting data structures
291306

292307
private class TestSetup : IAsyncDisposable

0 commit comments

Comments
 (0)