Unobtanium.Web.Proxy.Events
0.9.1-beta-2
dotnet add package Unobtanium.Web.Proxy.Events --version 0.9.1-beta-2
NuGet\Install-Package Unobtanium.Web.Proxy.Events -Version 0.9.1-beta-2
<PackageReference Include="Unobtanium.Web.Proxy.Events" Version="0.9.1-beta-2" />
<PackageVersion Include="Unobtanium.Web.Proxy.Events" Version="0.9.1-beta-2" />
<PackageReference Include="Unobtanium.Web.Proxy.Events" />
paket add Unobtanium.Web.Proxy.Events --version 0.9.1-beta-2
#r "nuget: Unobtanium.Web.Proxy.Events, 0.9.1-beta-2"
#:package Unobtanium.Web.Proxy.Events@0.9.1-beta-2
#addin nuget:?package=Unobtanium.Web.Proxy.Events&version=0.9.1-beta-2&prerelease
#tool nuget:?package=Unobtanium.Web.Proxy.Events&version=0.9.1-beta-2&prerelease
Unobtanium Web Proxy
A lightweight HTTP(S) proxy server written in C# NET8.0
.
Report bugs or raise issues here.
Project reboot
This project is a rewrite of the original Titanium-Web-Proxy project. The original project was last updated two years ago, has been archived by the author on July 9th 2023 and has been inactive since then. This project aims to continue the development of the original project and provide a stable and reliable proxy server library for .NET developers.
Announcement Reboot discussion Issues
Reboot focus
net8.0
only (no support for older versions of .NET!)- Support for
ILogger
See #4 - Support for diagnostic events using
ActivitySource
andActivity
See #3 - Using the latest .NET features like
Span<T>
andMemory<T>
to improve performance - Update dependencies to the latest versions
TLS 1.2
andTLS 1.3
only support- Modern Event System: Event-handlers with
HttpRequestMessage
andHttpResponseMessage
, to greatly improve the portability of the library See #6 HttpClient
as the default client, and using the IHttpClientFactory to handle pooling of the clients- Testing, testing, testing!
Modern Event System
This proxy server uses a modern, clean event system based on standard HttpRequestMessage
and HttpResponseMessage
objects, making it easier to integrate with existing .NET HTTP libraries and patterns.
Request Interception
var events = new ProxyServerEvents();
events.OnRequest += async (sender, e, cancellationToken) =>
{
Console.WriteLine($"Request: {e.Request.Method} {e.Request.RequestUri}");
// Block specific domains
if (e.Request.RequestUri?.Host.Contains("blocked.com") == true)
{
var blockedResponse = new HttpResponseMessage(HttpStatusCode.Forbidden)
{
Content = new StringContent("Access Denied")
};
return RequestEventResponse.EarlyResponse(blockedResponse);
}
// Modify request headers
e.Request.Headers.Add("X-Proxy-Agent", "Unobtanium");
// Redirect requests
if (e.Request.RequestUri?.Host.Contains("example.com") == true)
{
var redirectedRequest = new HttpRequestMessage(e.Request.Method, "https://microsoft.com")
{
Content = e.Request.Content,
Version = e.Request.Version
};
// Copy headers
foreach (var header in e.Request.Headers)
{
redirectedRequest.Headers.TryAddWithoutValidation(header.Key, header.Value);
}
return RequestEventResponse.ModifyRequest(redirectedRequest);
}
return RequestEventResponse.ContinueResponse();
};
Response Interception
events.OnResponse += async (sender, e, cancellationToken) =>
{
Console.WriteLine($"Response: {e.Response.StatusCode} from {e.Request.RequestUri}");
// Modify responses
if (e.Response.Content != null)
{
var content = await e.Response.Content.ReadAsStringAsync(cancellationToken);
if (content.Contains("error"))
{
var modifiedResponse = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(content.Replace("error", "success")),
Version = e.Response.Version
};
// Copy headers
foreach (var header in e.Response.Headers)
{
modifiedResponse.Headers.TryAddWithoutValidation(header.Key, header.Value);
}
return ResponseEventResponse.ModifyResponse(modifiedResponse);
}
}
return ResponseEventResponse.ContinueResponse();
};
Features
API DocumentationWiki & Contribution guidelines- Multithreaded and asynchronous proxy employing server connection pooling, certificate cache, and buffer pooling
- View, modify, redirect and block requests or responses
- Modern event system based on
HttpRequestMessage
andHttpResponseMessage
Installation
Package on NuGet, Unobtanium.Web.Proxy
will be a partial drop-in replacement for Titanium.Web.Proxy
, if you're on NET8.0 or higher
.
dotnet add package Unobtanium.Web.Proxy
Supports
.NET 8.0
and above
As stated above, this project is a reboot of the original project. Expect things to change, everything marked as obsolete
in the original project will be removed in this project. And until this is v1.0.0
, expect breaking changes.
Usage
using Unobtanium.Web.Proxy;
using Unobtanium.Web.Proxy.Events;
var events = new ProxyServerEvents();
events.ShouldDecryptNewConnection = async (host, cts) =>
{
// Log the new connection details
return host.Equals("graph.microsoft.com");
};
events.OnRequest += async (s, e, cancellationToken) =>
{
Console.WriteLine($"Request to: {e.Request.RequestUri}");
if (e.Request.RequestUri.ToString().StartsWith("https://graph.microsoft.com/v1.0/"))
{
var content = @"What ever you want";
var response = new HttpResponseMessage {
StatusCode = System.Net.HttpStatusCode.Unauthorized,
Content = new StringContent(content, System.Text.Encoding.UTF8, "application/json")
};
return Unobtanium.Web.Proxy.Events.RequestEventResponse.EarlyResponse(response);
}
return Unobtanium.Web.Proxy.Events.RequestEventResponse.ContinueResponse();
};
events.OnResponse += async (s, e, cancellationToken) =>
{
Console.WriteLine($"Response from: {e.Request.RequestUri}");
//if (e.Response.Content is not null)
//{
// var body = await e.Response.Content!.ReadAsStringAsync(cancellationToken);
// Console.WriteLine(body);
//}
return ResponseEventResponse.ContinueResponse();
};
builder.Services.AddProxyEvents(events);
builder.Services.AddProxyServices();
Complete Example
Check out the worker template for a complete example of how to use the proxy server in a .NET worker service.
Creator
Since this ended up to be a full rewrite I'll put myself as owner:
You contributions are more then welcome! Let's make this project great again!
Previous Collaborators
The previous owner of this project, justcoding121, is considered to be inactive from this project due to his busy work schedule. See project reboot for more information.
Previous contributors:
- justcoding121 owner
- honfika
Development environment
Since this is a dotnet
project I would suggest to use Visual Studio 2022
or Visual Studio Code
as your development environment. The project is set up to use the dotnet
CLI, so you can also use that to build and run the project.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.1)
-
net9.0
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.1)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Unobtanium.Web.Proxy.Events:
Package | Downloads |
---|---|
Unobtanium.Web.Proxy
A web inspecting proxy library you can intgrate in your own application. Build in NET8.0 for maximum speed. |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last Updated |
---|---|---|
0.9.1-beta-2 | 132 | 8/18/2025 |
0.9.1-beta.2 | 121 | 8/18/2025 |
0.9.1-beta.1 | 121 | 8/14/2025 |
0.9.0-beta.1 | 196 | 8/7/2025 |