Proxy
HTTP-proxy gemaakt met C# om kennis te vergaren over het HTTP-protocol en het programmeren van C# zonder tools. De proxy bevat functionaliteiten zoals caching, authenticatie en een content filter.
Idee
Tijdens de cursus ".NET op de server" werd besloten dat het een goede oefening was om onder de motorkap te kijken en te zien hoe de zaken worden geïmplementeerd. De docenten besloten dat de leerlingen een proxy moesten bouwen op basis van de TcpClient
, vanwege de COVID-19 crisis werd besloten dat HttpListener
ook was toegestaan.
Vereisten
The proxy needed to make us of multi threading, be HTTP 1.0 compliant and be usable for binary and text data. Besides the proxy itself, we needed to build a UI implemented with MVVM and WPF that did not stop responding while the proxy was under load.
De proxy moest gebruik maken van multi-threading, HTTP 1.0-compatibel zijn en bruikbaar zijn voor binaire en text data. Naast de proxy zelf moest er een interface zijn om de proxy grafisch te bedienen. Deze interface werd geïmplementeerd met MVVM en WPF. Deze interface moest blijven werken ook onder zware load van de proxy.
Challenges
Het gebruik van middleware was niet toegestaand, daarom was een ontwerp handing om de juiste volgorde van de functionaliteiten te krijgen die overzichtelijk was. Daarom had ik een flowchart gemaakt om de algehele flow door het project te laten zien.
Om ervoor te zorgen dat alles onderhoudbaar een uitbreidbaar is heb ik gebruik gemaakt van het Strategy Pattern. Dit was cruciaal bij het bouwen van de Cache Validator
// ICachingStrategy.cs
public interface ICachingStrategy
{
bool IsValid();
}
// CacheValidator.cs
public bool IsValid(IResponse response, ProxyConfig config)
{
var headers = response.Headers;
if (config.IsForcedTimeout)
{
return new ForcedStrategy(response, config.ForcedTimeout).IsValid();
}
if (!string.IsNullOrEmpty(headers["Cache-Control"]))
{
return CacheControlStrategy(response).IsValid();
}
if (!string.IsNullOrEmpty(headers["Expires"]))
{
return new ExpiresStrategy(response).IsValid();
}
if (string.IsNullOrEmpty(headers["Last-Modified"]))
throw new ArgumentException("no caching strategies found", nameof(headers));
return new RevalidateStrategy(response).IsValid();
}