Commit d05aa8c4 authored by Jehonathan Thomas's avatar Jehonathan Thomas Committed by GitHub

Merge pull request #291 from honfika/develop

Fix for #289
parents e651e429 1e8cf7e2
......@@ -76,7 +76,16 @@ namespace Titanium.Web.Proxy.Examples.Wpf
{
//IncludedHttpsHostNameRegex = new string[0],
};
proxyServer.AddEndPoint(explicitEndPoint);
//proxyServer.UpStreamHttpProxy = new ExternalProxy
//{
// HostName = "158.69.115.45",
// Port = 3128,
// UserName = "Titanium",
// Password = "Titanium",
//};
proxyServer.BeforeRequest += ProxyServer_BeforeRequest;
proxyServer.BeforeResponse += ProxyServer_BeforeResponse;
proxyServer.TunnelConnectRequest += ProxyServer_TunnelConnectRequest;
......
......@@ -69,7 +69,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// <summary>
/// Does this session uses SSL
/// </summary>
public bool IsHttps => WebSession.Request.RequestUri.Scheme == ProxyServer.UriSchemeHttps;
public bool IsHttps => WebSession.Request.IsHttps;
/// <summary>
/// Client End Point.
......
......@@ -49,8 +49,7 @@ namespace Titanium.Web.Proxy.Http
/// <summary>
/// Is Https?
/// </summary>
public bool IsHttps => Request.RequestUri.Scheme == ProxyServer.UriSchemeHttps;
public bool IsHttps => Request.IsHttps;
internal HttpWebClient()
{
......@@ -81,7 +80,7 @@ namespace Titanium.Web.Proxy.Http
var requestLines = new StringBuilder();
//prepare the request & headers
requestLines.AppendLine($"{Request.Method} {Request.RequestUri.PathAndQuery} HTTP/{Request.HttpVersion.Major}.{Request.HttpVersion.Minor}");
requestLines.AppendLine($"{Request.Method} {Request.OriginalRequestUrl} HTTP/{Request.HttpVersion.Major}.{Request.HttpVersion.Minor}");
//Send Authentication to Upstream proxy if needed
......
......@@ -23,6 +23,16 @@ namespace Titanium.Web.Proxy.Http
/// </summary>
public Uri RequestUri { get; set; }
/// <summary>
/// Is Https?
/// </summary>
public bool IsHttps => RequestUri.Scheme == ProxyServer.UriSchemeHttps;
/// <summary>
/// The original request Url.
/// </summary>
public string OriginalRequestUrl { get; set; }
/// <summary>
/// Request Http Version
/// </summary>
......@@ -219,7 +229,7 @@ namespace Titanium.Web.Proxy.Http
get
{
var sb = new StringBuilder();
sb.AppendLine($"{Method} {RequestUri.PathAndQuery} HTTP/{HttpVersion.Major}.{HttpVersion.Minor}");
sb.AppendLine($"{Method} {OriginalRequestUrl} HTTP/{HttpVersion.Major}.{HttpVersion.Minor}");
foreach (var header in RequestHeaders)
{
sb.AppendLine(header.ToString());
......
......@@ -16,7 +16,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
internal ExternalProxy UpStreamHttpsProxy { get; set; }
internal ExternalProxy UpStreamProxy => UseProxy ? IsHttps ? UpStreamHttpsProxy : UpStreamHttpProxy : null;
internal ExternalProxy UpStreamProxy => UseUpstreamProxy ? IsHttps ? UpStreamHttpsProxy : UpStreamHttpProxy : null;
internal string HostName { get; set; }
......@@ -24,7 +24,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
internal bool IsHttps { get; set; }
internal bool UseProxy { get; set; }
internal bool UseUpstreamProxy { get; set; }
/// <summary>
/// Http version
......
......@@ -32,18 +32,18 @@ namespace Titanium.Web.Proxy.Network.Tcp
internal async Task<TcpConnection> CreateClient(ProxyServer server, string remoteHostName, int remotePort, Version httpVersion, bool isHttps,
ExternalProxy externalHttpProxy, ExternalProxy externalHttpsProxy)
{
bool useProxy = false;
bool useUpstreamProxy = false;
var externalProxy = isHttps ? externalHttpsProxy : externalHttpProxy;
//check if external proxy is set for HTTP/HTTPS
if (externalProxy != null && !(externalProxy.HostName == remoteHostName && externalProxy.Port == remotePort))
{
useProxy = true;
useUpstreamProxy = true;
//check if we need to ByPass
if (externalProxy.BypassLocalhost && NetworkHelper.IsLocalIpAddress(remoteHostName))
{
useProxy = false;
useUpstreamProxy = false;
}
}
......@@ -53,7 +53,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
try
{
//If this proxy uses another external proxy then create a tunnel request for HTTP/HTTPS connections
if (useProxy)
if (useUpstreamProxy)
{
#if NET45
client = new TcpClient(server.UpStreamEndPoint);
......@@ -63,36 +63,39 @@ namespace Titanium.Web.Proxy.Network.Tcp
await client.ConnectAsync(externalProxy.HostName, externalProxy.Port);
stream = new CustomBufferedStream(client.GetStream(), server.BufferSize);
using (var writer = new StreamWriter(stream, Encoding.ASCII, server.BufferSize, true)
if (isHttps)
{
NewLine = ProxyConstants.NewLine
})
{
await writer.WriteLineAsync($"CONNECT {remoteHostName}:{remotePort} HTTP/{httpVersion}");
await writer.WriteLineAsync($"Host: {remoteHostName}:{remotePort}");
await writer.WriteLineAsync("Connection: Keep-Alive");
if (!string.IsNullOrEmpty(externalProxy.UserName) && externalProxy.Password != null)
using (var writer = new StreamWriter(stream, Encoding.ASCII, server.BufferSize, true)
{
await writer.WriteLineAsync("Proxy-Connection: keep-alive");
await writer.WriteLineAsync("Proxy-Authorization" + ": Basic " +
Convert.ToBase64String(Encoding.UTF8.GetBytes(
externalProxy.UserName + ":" + externalProxy.Password)));
}
await writer.WriteLineAsync();
await writer.FlushAsync();
}
NewLine = ProxyConstants.NewLine
})
{
await writer.WriteLineAsync($"CONNECT {remoteHostName}:{remotePort} HTTP/{httpVersion}");
await writer.WriteLineAsync($"Host: {remoteHostName}:{remotePort}");
await writer.WriteLineAsync("Connection: Keep-Alive");
using (var reader = new CustomBinaryReader(stream, server.BufferSize))
{
string result = await reader.ReadLineAsync();
if (!string.IsNullOrEmpty(externalProxy.UserName) && externalProxy.Password != null)
{
await writer.WriteLineAsync("Proxy-Connection: keep-alive");
await writer.WriteLineAsync("Proxy-Authorization" + ": Basic " +
Convert.ToBase64String(Encoding.UTF8.GetBytes(
externalProxy.UserName + ":" + externalProxy.Password)));
}
await writer.WriteLineAsync();
await writer.FlushAsync();
}
if (!new[] { "200 OK", "connection established" }.Any(s => result.ContainsIgnoreCase(s)))
using (var reader = new CustomBinaryReader(stream, server.BufferSize))
{
throw new Exception("Upstream proxy failed to create a secure tunnel");
}
string result = await reader.ReadLineAsync();
await reader.ReadAndIgnoreAllLinesAsync();
if (!new[] { "200 OK", "connection established" }.Any(s => result.ContainsIgnoreCase(s)))
{
throw new Exception("Upstream proxy failed to create a secure tunnel");
}
await reader.ReadAndIgnoreAllLinesAsync();
}
}
}
else
......@@ -133,7 +136,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
HostName = remoteHostName,
Port = remotePort,
IsHttps = isHttps,
UseProxy = useProxy,
UseUpstreamProxy = useUpstreamProxy,
TcpClient = client,
StreamReader = new CustomBinaryReader(stream, server.BufferSize),
Stream = stream,
......
......@@ -85,6 +85,7 @@ namespace Titanium.Web.Proxy
connectRequest = new ConnectRequest
{
RequestUri = httpRemoteUri,
OriginalRequestUrl = httpUrl,
HttpVersion = version,
Method = httpMethod,
};
......@@ -303,6 +304,7 @@ namespace Titanium.Web.Proxy
: string.Concat("https://", args.WebSession.Request.Host ?? httpsConnectHostname, httpUrl));
args.WebSession.Request.RequestUri = httpRemoteUri;
args.WebSession.Request.OriginalRequestUrl = httpUrl;
args.WebSession.Request.Method = httpMethod;
args.WebSession.Request.HttpVersion = version;
......@@ -318,7 +320,6 @@ namespace Titanium.Web.Proxy
}
PrepareRequestHeaders(args.WebSession.Request.RequestHeaders);
args.WebSession.Request.Host = args.WebSession.Request.RequestUri.Authority;
#if NET45
//if win auth is enabled
......@@ -572,18 +573,18 @@ namespace Titanium.Web.Proxy
ExternalProxy customUpStreamHttpProxy = null;
ExternalProxy customUpStreamHttpsProxy = null;
if (args.WebSession.Request.RequestUri.Scheme == UriSchemeHttp)
if (args.WebSession.Request.IsHttps)
{
if (GetCustomUpStreamHttpProxyFunc != null)
if (GetCustomUpStreamHttpsProxyFunc != null)
{
customUpStreamHttpProxy = await GetCustomUpStreamHttpProxyFunc(args);
customUpStreamHttpsProxy = await GetCustomUpStreamHttpsProxyFunc(args);
}
}
else
{
if (GetCustomUpStreamHttpsProxyFunc != null)
if (GetCustomUpStreamHttpProxyFunc != null)
{
customUpStreamHttpsProxy = await GetCustomUpStreamHttpsProxyFunc(args);
customUpStreamHttpProxy = await GetCustomUpStreamHttpProxyFunc(args);
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment