Skip to content
This repository was archived by the owner on Jul 9, 2023. It is now read-only.

Beta 3.0.866+ #538

Merged
merged 10 commits into from
Jan 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
## Titanium Web Proxy

A light weight HTTP(S) proxy server written in C#
A lightweight HTTP(S) proxy server written in C#.

<a href="https://ci.appveyor.com/project/justcoding121/titanium-web-proxy">![Build Status](https://ci.appveyor.com/api/projects/status/p5vvtbpx9yp250ol?svg=true)</a> [![Join the chat at https://gitter.im/Titanium-Web-Proxy/Lobby](https://badges.gitter.im/Titanium-Web-Proxy/Lobby.svg)](https://gitter.im/Titanium-Web-Proxy/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

Kindly report only issues/bugs here . For programming help or questions use [StackOverflow](http://stackoverflow.com/questions/tagged/titanium-web-proxy) with the tag Titanium-Web-Proxy.
Kindly report only issues/bugs here. For programming help or questions use [StackOverflow](http://stackoverflow.com/questions/tagged/titanium-web-proxy) with the tag Titanium-Web-Proxy.

* [API Documentation](https://justcoding121.github.io/Titanium-Web-Proxy/docs/api/Titanium.Web.Proxy.ProxyServer.html)
* [Uncyclo & Contribution guidelines](https://github.com/justcoding121/Titanium-Web-Proxy/wiki)

### Features

* Multithreaded & fully asynchronous proxy employing server connection pooling, certificate cache & buffer pooling
* View/modify/redirect/block requests & responses
* Multi-threaded fully asynchronous proxy employing server connection pooling, certificate cache, and buffer pooling
* View/modify/redirect/block requests and responses
* Supports mutual SSL authentication, proxy authentication & automatic upstream proxy detection
* Kerberos/NTLM authentication over HTTP protocols for windows domain

Expand Down Expand Up @@ -48,7 +48,7 @@ Supports

### Usage

Refer the HTTP Proxy Server library in your project, look up Test project to learn usage.
Refer the HTTP Proxy Server library in your project and look up the test project to learn usage.

Setup HTTP proxy:

Expand Down Expand Up @@ -228,7 +228,7 @@ public Task OnCertificateSelection(object sender, CertificateSelectionEventArgs
```
### Note to contributors

#### Roadmap
#### Road map

* Support HTTP 2.0

Expand Down
10 changes: 5 additions & 5 deletions docs/api/Titanium.Web.Proxy.Helpers.RunTime.html
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ <h3 id="properties">Properties
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_Helpers_RunTime_IsLinux.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.Helpers.RunTime.IsLinux%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span>
<span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/Helpers/RunTime.cs/#L50">View Source</a>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/Helpers/RunTime.cs/#L47">View Source</a>
</span>
<a id="Titanium_Web_Proxy_Helpers_RunTime_IsLinux_" data-uid="Titanium.Web.Proxy.Helpers.RunTime.IsLinux*"></a>
<h4 id="Titanium_Web_Proxy_Helpers_RunTime_IsLinux" data-uid="Titanium.Web.Proxy.Helpers.RunTime.IsLinux">IsLinux</h4>
Expand Down Expand Up @@ -158,7 +158,7 @@ <h5 class="propertyValue">Property Value</h5>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_Helpers_RunTime_IsMac.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.Helpers.RunTime.IsMac%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span>
<span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/Helpers/RunTime.cs/#L63">View Source</a>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/Helpers/RunTime.cs/#L60">View Source</a>
</span>
<a id="Titanium_Web_Proxy_Helpers_RunTime_IsMac_" data-uid="Titanium.Web.Proxy.Helpers.RunTime.IsMac*"></a>
<h4 id="Titanium_Web_Proxy_Helpers_RunTime_IsMac" data-uid="Titanium.Web.Proxy.Helpers.RunTime.IsMac">IsMac</h4>
Expand Down Expand Up @@ -188,7 +188,7 @@ <h5 class="propertyValue">Property Value</h5>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_Helpers_RunTime_IsUwpOnWindows.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.Helpers.RunTime.IsUwpOnWindows%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span>
<span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/Helpers/RunTime.cs/#L58">View Source</a>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/Helpers/RunTime.cs/#L55">View Source</a>
</span>
<a id="Titanium_Web_Proxy_Helpers_RunTime_IsUwpOnWindows_" data-uid="Titanium.Web.Proxy.Helpers.RunTime.IsUwpOnWindows*"></a>
<h4 id="Titanium_Web_Proxy_Helpers_RunTime_IsUwpOnWindows" data-uid="Titanium.Web.Proxy.Helpers.RunTime.IsUwpOnWindows">IsUwpOnWindows</h4>
Expand Down Expand Up @@ -218,7 +218,7 @@ <h5 class="propertyValue">Property Value</h5>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_Helpers_RunTime_IsWindows.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.Helpers.RunTime.IsWindows%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span>
<span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/Helpers/RunTime.cs/#L56">View Source</a>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/Helpers/RunTime.cs/#L53">View Source</a>
</span>
<a id="Titanium_Web_Proxy_Helpers_RunTime_IsWindows_" data-uid="Titanium.Web.Proxy.Helpers.RunTime.IsWindows*"></a>
<h4 id="Titanium_Web_Proxy_Helpers_RunTime_IsWindows" data-uid="Titanium.Web.Proxy.Helpers.RunTime.IsWindows">IsWindows</h4>
Expand Down Expand Up @@ -254,7 +254,7 @@ <h5 class="propertyValue">Property Value</h5>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_Helpers_RunTime.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.Helpers.RunTime%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A" class="contribution-link">Improve this Doc</a>
</li>
<li>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/Helpers/RunTime.cs/#L13" class="contribution-link">View Source</a>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/Helpers/RunTime.cs/#L10" class="contribution-link">View Source</a>
</li>
</ul>
</div>
Expand Down
62 changes: 32 additions & 30 deletions src/Titanium.Web.Proxy/Helpers/Network.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
using System.Linq;
using System;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;

namespace Titanium.Web.Proxy.Helpers
{
internal class NetworkHelper
{
private static readonly string localhostName = Dns.GetHostName();
private static readonly IPHostEntry localhostEntry = Dns.GetHostEntry(string.Empty);

/// <summary>
/// Adapated from below link
/// http://stackoverflow.com/questions/11834091/how-to-check-if-localhost
Expand All @@ -19,55 +24,52 @@ internal static bool IsLocalIpAddress(IPAddress address)
return true;
}

// get local IP addresses
var localIPs = Dns.GetHostAddresses(Dns.GetHostName());

// test if any host IP equals to any local IP or to localhost
return localIPs.Contains(address);
// test if host IP equals any local IP
return localhostEntry.AddressList.Contains(address);
}

internal static bool IsLocalIpAddress(string hostName)
{
hostName = hostName.ToLower();

if (hostName == "127.0.0.1"
|| hostName == "localhost")
if (IPAddress.TryParse(hostName, out var ipAddress)
&& IsLocalIpAddress(ipAddress))
{
return true;
}

var localhostDnsName = Dns.GetHostName().ToLower();

//if hostname matches current machine DNS name
if (hostName == localhostDnsName)
if (hostName.Equals("localhost", StringComparison.OrdinalIgnoreCase))
{
return true;
}

var isLocalhost = false;
IPHostEntry hostEntry = null;

//check if parsable to an IP Address
if (IPAddress.TryParse(hostName, out var ipAddress))
//if hostname matches local host name
if (hostName.Equals(localhostName, StringComparison.OrdinalIgnoreCase))
{
hostEntry = Dns.GetHostEntry(localhostDnsName);
isLocalhost = hostEntry.AddressList.Any(x => x.Equals(ipAddress));
return true;
}

if (!isLocalhost)
// if hostname matches fully qualified local DNS name
if (hostName.Equals(localhostEntry.HostName, StringComparison.OrdinalIgnoreCase))
{
try
{
hostEntry = Dns.GetHostEntry(hostName);
isLocalhost = hostEntry.AddressList.Any(x => hostEntry.AddressList.Any(x.Equals));
}
catch (SocketException)
return true;
}

try
{
// do reverse DNS lookup even if hostName is an IP address
var hostEntry = Dns.GetHostEntry(hostName);
// if DNS resolved hostname matches local DNS name,
// or if host IP address list contains any local IP address
if (hostEntry.HostName.Equals(localhostEntry.HostName, StringComparison.OrdinalIgnoreCase)
|| hostEntry.AddressList.Any(hostIP => localhostEntry.AddressList.Contains(hostIP)))
{
return true;
}
}
catch (SocketException)
{
}


return isLocalhost;
return false;
}
}
}
3 changes: 0 additions & 3 deletions src/Titanium.Web.Proxy/Helpers/RunTime.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
using System;
using System.Runtime.InteropServices;
using System.Text;
#if NETSTANDARD2_0
using System.Runtime.InteropServices;
#endif

namespace Titanium.Web.Proxy.Helpers
{
Expand Down
58 changes: 37 additions & 21 deletions src/Titanium.Web.Proxy/Network/DefaultCertificateDiskCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.IO;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using Titanium.Web.Proxy.Helpers;

namespace Titanium.Web.Proxy.Network
{
Expand All @@ -13,24 +14,24 @@ internal sealed class DefaultCertificateDiskCache : ICertificateCache
private string rootCertificatePath;
private string certificatePath;

public X509Certificate2 LoadRootCertificate(string name, string password, X509KeyStorageFlags storageFlags)
public X509Certificate2 LoadRootCertificate(string pathOrName, string password, X509KeyStorageFlags storageFlags)
{
string filePath = getRootCertificatePath(name);
return loadCertificate(filePath, password, storageFlags);
string path = getRootCertificatePath(pathOrName);
return loadCertificate(path, password, storageFlags);
}

public void SaveRootCertificate(string name, string password, X509Certificate2 certificate)
public void SaveRootCertificate(string pathOrName, string password, X509Certificate2 certificate)
{
string filePath = getRootCertificatePath(name);
string path = getRootCertificatePath(pathOrName);
byte[] exported = certificate.Export(X509ContentType.Pkcs12, password);
File.WriteAllBytes(filePath, exported);
File.WriteAllBytes(path, exported);
}

/// <inheritdoc />
public X509Certificate2 LoadCertificate(string subjectName, X509KeyStorageFlags storageFlags)
{
string filePath = Path.Combine(getCertificatePath(), subjectName + defaultCertificateFileExtension);
return loadCertificate(filePath, string.Empty, storageFlags);
string path = Path.Combine(getCertificatePath(), subjectName + defaultCertificateFileExtension);
return loadCertificate(path, string.Empty, storageFlags);
}

/// <inheritdoc />
Expand All @@ -55,12 +56,12 @@ public void Clear()
certificatePath = null;
}

private X509Certificate2 loadCertificate(string filePath, string password, X509KeyStorageFlags storageFlags)
private X509Certificate2 loadCertificate(string path, string password, X509KeyStorageFlags storageFlags)
{
byte[] exported;
try
{
exported = File.ReadAllBytes(filePath);
exported = File.ReadAllBytes(path);
}
catch (IOException)
{
Expand All @@ -71,15 +72,15 @@ private X509Certificate2 loadCertificate(string filePath, string password, X509K
return new X509Certificate2(exported, password, storageFlags);
}

private string getRootCertificatePath(string filePath)
private string getRootCertificatePath(string pathOrName)
{
if (Path.IsPathRooted(filePath))
if (Path.IsPathRooted(pathOrName))
{
return filePath;
return pathOrName;
}

return Path.Combine(getRootCertificateDirectory(),
string.IsNullOrEmpty(filePath) ? defaultRootCertificateFileName : filePath);
string.IsNullOrEmpty(pathOrName) ? defaultRootCertificateFileName : pathOrName);
}

private string getCertificatePath()
Expand All @@ -104,17 +105,32 @@ private string getRootCertificateDirectory()
{
if (rootCertificatePath == null)
{
string assemblyLocation = GetType().Assembly.Location;

// dynamically loaded assemblies returns string.Empty location
if (assemblyLocation == string.Empty)
if (RunTime.IsUwpOnWindows)
{
rootCertificatePath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
}
else if (RunTime.IsLinux)
{
assemblyLocation = Assembly.GetEntryAssembly().Location;
rootCertificatePath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
}
else if (RunTime.IsMac)
{
rootCertificatePath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
}
else
{
string assemblyLocation = GetType().Assembly.Location;

string path = Path.GetDirectoryName(assemblyLocation);
// dynamically loaded assemblies returns string.Empty location
if (assemblyLocation == string.Empty)
{
assemblyLocation = Assembly.GetEntryAssembly().Location;
}

rootCertificatePath = path ?? throw new NullReferenceException();
string path = Path.GetDirectoryName(assemblyLocation);

rootCertificatePath = path ?? throw new NullReferenceException();
}
}

return rootCertificatePath;
Expand Down
4 changes: 2 additions & 2 deletions src/Titanium.Web.Proxy/Network/ICertificateCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ public interface ICertificateCache
/// <summary>
/// Loads the root certificate from the storage.
/// </summary>
X509Certificate2 LoadRootCertificate(string name, string password, X509KeyStorageFlags storageFlags);
X509Certificate2 LoadRootCertificate(string pathOrName, string password, X509KeyStorageFlags storageFlags);

/// <summary>
/// Saves the root certificate to the storage.
/// </summary>
void SaveRootCertificate(string name, string password, X509Certificate2 certificate);
void SaveRootCertificate(string pathOrName, string password, X509Certificate2 certificate);

/// <summary>
/// Loads certificate from the storage. Returns true if certificate does not exist.
Expand Down
17 changes: 13 additions & 4 deletions src/Titanium.Web.Proxy/Titanium.Web.Proxy.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,22 @@
<copyright>Copyright &#x00A9; Titanium. All rights reserved.</copyright>
<tags></tags>
<dependencies>
<dependency id="StreamExtended" version="1.0.179" />
<dependency id="Portable.BouncyCastle" version="1.8.2" />
<dependency id="BrotliSharpLib" version="0.3.1" />
<group targetFramework="net45">
<dependency id="StreamExtended" version="1.0.179" />
<dependency id="Portable.BouncyCastle" version="1.8.2" />
<dependency id="BrotliSharpLib" version="0.3.1" />
</group>
<group targetFramework="netstandard2.0">
<dependency id="StreamExtended" version="1.0.179" />
<dependency id="Portable.BouncyCastle" version="1.8.2" />
<dependency id="BrotliSharpLib" version="0.3.1" />
<dependency id="Microsoft.Win32.Registry" version="4.4.0" />
<dependency id="System.Security.Principal.Windows" version="4.4.1" />
</group>
</dependencies>
</metadata>
<files>
<file src="bin\$configuration$\net45\Titanium.Web.Proxy.dll" target="lib\net45" />
<file src="bin\$configuration$\netstandard2.0\Titanium.Web.Proxy.*" target="lib\netstandard2.0" />
<file src="bin\$configuration$\netstandard2.0\Titanium.Web.Proxy.dll" target="lib\netstandard2.0" />
</files>
</package>