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

Commit

Permalink
Merge pull request #657 from justcoding121/master
Browse files Browse the repository at this point in the history
fixes
  • Loading branch information
honfika authored Nov 16, 2019
2 parents e24f3cc + 3d6e72a commit 94e3df9
Show file tree
Hide file tree
Showing 12 changed files with 93 additions and 60 deletions.
6 changes: 3 additions & 3 deletions src/Titanium.Web.Proxy/Compression/CompressionUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ internal static class CompressionUtil
{
public static HttpCompression CompressionNameToEnum(string name)
{
if (KnownHeaders.ContentEncodingGzip.Equals(name.AsSpan()))
if (KnownHeaders.ContentEncodingGzip.Equals(name))
return HttpCompression.Gzip;

if (KnownHeaders.ContentEncodingDeflate.Equals(name.AsSpan()))
if (KnownHeaders.ContentEncodingDeflate.Equals(name))
return HttpCompression.Deflate;

if (KnownHeaders.ContentEncodingBrotli.Equals(name.AsSpan()))
if (KnownHeaders.ContentEncodingBrotli.Equals(name))
return HttpCompression.Brotli;

return HttpCompression.Unsupported;
Expand Down
19 changes: 9 additions & 10 deletions src/Titanium.Web.Proxy/ExplicitClientHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ private async Task handleClient(ExplicitProxyEndPoint endPoint, TcpClientConnect

try
{
string? connectHostname = null;
TunnelConnectSessionEventArgs? connectArgs = null;

// Client wants to create a secure tcp tunnel (probably its a HTTPS or Websocket request)
Expand All @@ -62,14 +61,7 @@ private async Task handleClient(ExplicitProxyEndPoint endPoint, TcpClientConnect

Request.ParseRequestLine(httpCmd!, out string _, out string httpUrl, out var version);

connectHostname = httpUrl;
int idx = connectHostname.IndexOf(":");
if (idx >= 0)
{
connectHostname = connectHostname.Substring(0, idx);
}

var connectRequest = new ConnectRequest(connectHostname)
var connectRequest = new ConnectRequest(httpUrl)
{
OriginalUrlData = HttpHeader.Encoding.GetBytes(httpUrl),
HttpVersion = version
Expand Down Expand Up @@ -130,7 +122,7 @@ await clientStreamWriter.WriteResponseAsync(connectArgs.HttpClient.Response,
bool isClientHello = clientHelloInfo != null;
if (clientHelloInfo != null)
{
connectRequest.Scheme = ProxyServer.UriSchemeHttps;
connectRequest.IsHttps = true;
connectRequest.TunnelType = TunnelType.Https;
connectRequest.ClientHelloInfo = clientHelloInfo;
}
Expand Down Expand Up @@ -186,6 +178,13 @@ await clientStreamWriter.WriteResponseAsync(connectArgs.HttpClient.Response,
}
}

string connectHostname = httpUrl;
int idx = connectHostname.IndexOf(":");
if (idx >= 0)
{
connectHostname = connectHostname.Substring(0, idx);
}

X509Certificate2? certificate = null;
try
{
Expand Down
4 changes: 2 additions & 2 deletions src/Titanium.Web.Proxy/Http/ConnectRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ namespace Titanium.Web.Proxy.Http
/// </summary>
public class ConnectRequest : Request
{
public ConnectRequest(string hostname)
public ConnectRequest(string authority)
{
Method = "CONNECT";
Hostname = hostname;
Authority = authority;
}

public TunnelType TunnelType { get; internal set; }
Expand Down
4 changes: 4 additions & 0 deletions src/Titanium.Web.Proxy/Http/HttpWebClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ internal async Task SendRequest(bool enable100ContinueBehaviour, bool isTranspar
else
{
url = Request.RequestUri.GetOriginalPathAndQuery();
if (url == string.Empty)
{
url = "/";
}
}

var headerBuilder = new HeaderBuilder();
Expand Down
69 changes: 45 additions & 24 deletions src/Titanium.Web.Proxy/Http/Request.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ public class Request : RequestResponseBase
/// <summary>
/// Is Https?
/// </summary>
public bool IsHttps => RequestUri.Scheme == ProxyServer.UriSchemeHttps;
public bool IsHttps { get; internal set; }

private ByteString originalUrlData;
private protected ByteString UrlData;
private ByteString urlData;

internal ByteString OriginalUrlData
{
Expand All @@ -37,9 +37,21 @@ internal ByteString OriginalUrlData
}
}

internal string Scheme { get; set; } = ProxyServer.UriSchemeHttp;
private protected ByteString UrlData
{
get => urlData;
set
{
urlData = value;
var scheme = getUriScheme(UrlData);
if (scheme.Length > 0)
{
IsHttps = scheme.Equals(ProxyServer.UriSchemeHttps8);
}
}
}

internal string? Hostname { get; set; }
internal string? Authority { get; set; }

/// <summary>
/// The original request Url.
Expand All @@ -53,21 +65,21 @@ public Uri RequestUri
{
get
{
string url;
if (startsWithUriScheme(UrlData))
{
url = UrlData.GetString();
}
else
string url = UrlData.GetString();
if (getUriScheme(UrlData).Length == 0)
{
string? host = Host ?? Hostname;
string? hostAndPath = host;
if (UrlData.Length > 0 && UrlData[0] == '/')
string? hostAndPath = Host ?? Authority;

if (url.StartsWith("/"))
{
hostAndPath += url;
}
else
{
hostAndPath += UrlData.GetString();
//throw new Exception($"Invalid URL: '{url}'");
}

url = string.Concat(Scheme == ProxyServer.UriSchemeHttps ? "https://" : "http://", hostAndPath);
url = string.Concat(IsHttps ? "https://" : "http://", hostAndPath);
}

try
Expand All @@ -87,7 +99,16 @@ public Uri RequestUri
public string Url
{
get => UrlData.GetString();
set => UrlData = value.GetByteString();
set
{
UrlData = value.GetByteString();

if (Host != null)
{
var uri = new Uri(value);
Host = uri.Authority;
}
}
}

[Obsolete("This property is obsolete. Use Url property instead")]
Expand Down Expand Up @@ -147,7 +168,7 @@ public bool ExpectContinue
get
{
string? headerValue = Headers.GetHeaderValueOrNull(KnownHeaders.Expect);
return headerValue != null && headerValue.Equals(KnownHeaders.Expect100Continue);
return KnownHeaders.Expect100Continue.Equals(headerValue);
}
}

Expand Down Expand Up @@ -290,11 +311,11 @@ private static bool isAllUpper(string input)
return true;
}

private bool startsWithUriScheme(ByteString str)
private ByteString getUriScheme(ByteString str)
{
if (str.Length < 3)
{
return false;
return ByteString.Empty;
}

// regex: "^[a-z]*://"
Expand All @@ -310,26 +331,26 @@ private bool startsWithUriScheme(ByteString str)

if (ch < 'A' || ch > 'z' || (ch > 'Z' && ch < 'a')) // ASCII letter
{
return false;
return ByteString.Empty;
}
}

if (str[i++] != ':')
{
return false;
return ByteString.Empty;
}

if (str[i++] != '/')
{
return false;
return ByteString.Empty;
}

if (str[i] != '/')
{
return false;
return ByteString.Empty;
}

return true;
return new ByteString(str.Data.Slice(0, i - 2));
}
}
}
17 changes: 7 additions & 10 deletions src/Titanium.Web.Proxy/Http2/Http2Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -263,9 +263,9 @@ private static async Task copyHttp2FrameAsync(Stream input, Stream output,

request.HttpVersion = HttpVersion.Version20;
request.Method = method.GetString();
request.IsHttps = headerListener.Scheme == ProxyServer.UriSchemeHttps;
request.Authority = headerListener.Authority.GetString();
request.OriginalUrlData = path;
request.Scheme = headerListener.Scheme;
request.Hostname = headerListener.Authority.GetString();

//request.RequestUri = headerListener.GetUri();
}
Expand Down Expand Up @@ -468,9 +468,10 @@ private static async Task sendHeader(Http2Settings settings, Http2FrameHeader fr

if (rr is Request request)
{
var uri = request.RequestUri;
encoder.EncodeHeader(writer, StaticTable.KnownHeaderMethod, request.Method.GetByteString());
encoder.EncodeHeader(writer, StaticTable.KnownHeaderAuhtority, request.RequestUri.Host.GetByteString());
encoder.EncodeHeader(writer, StaticTable.KnownHeaderScheme, request.RequestUri.Scheme.GetByteString());
encoder.EncodeHeader(writer, StaticTable.KnownHeaderAuhtority, uri.Authority.GetByteString());
encoder.EncodeHeader(writer, StaticTable.KnownHeaderScheme, uri.Scheme.GetByteString());
encoder.EncodeHeader(writer, StaticTable.KnownHeaderPath, request.Url.GetByteString(), false,
HpackUtil.IndexType.None, false);
}
Expand Down Expand Up @@ -572,10 +573,6 @@ class Http2Settings

class MyHeaderListener : IHeaderListener
{
private static ByteString SchemeHttp = (ByteString)ProxyServer.UriSchemeHttp;

private static ByteString SchemeHttps = (ByteString)ProxyServer.UriSchemeHttps;

private readonly Action<ByteString, ByteString> addHeaderFunc;

public ByteString Method { get; private set; }
Expand All @@ -592,12 +589,12 @@ public string Scheme
{
get
{
if (scheme.Equals(SchemeHttp))
if (scheme.Equals(ProxyServer.UriSchemeHttp8))
{
return ProxyServer.UriSchemeHttp;
}

if (scheme.Equals(SchemeHttps))
if (scheme.Equals(ProxyServer.UriSchemeHttps8))
{
return ProxyServer.UriSchemeHttps;
}
Expand Down
4 changes: 3 additions & 1 deletion src/Titanium.Web.Proxy/Models/ExplicitProxyEndPoint.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Net;
using System.Diagnostics;
using System.Net;
using System.Threading.Tasks;
using Titanium.Web.Proxy.EventArguments;
using Titanium.Web.Proxy.Extensions;
Expand All @@ -9,6 +10,7 @@ namespace Titanium.Web.Proxy.Models
/// A proxy endpoint that the client is aware of.
/// So client application know that it is communicating with a proxy server.
/// </summary>
[DebuggerDisplay("Explicit: {IpAddress}:{Port}")]
public class ExplicitProxyEndPoint : ProxyEndPoint
{
/// <summary>
Expand Down
4 changes: 3 additions & 1 deletion src/Titanium.Web.Proxy/Models/TransparentProxyEndPoint.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Net;
using System.Diagnostics;
using System.Net;
using System.Threading.Tasks;
using Titanium.Web.Proxy.EventArguments;
using Titanium.Web.Proxy.Extensions;
Expand All @@ -9,6 +10,7 @@ namespace Titanium.Web.Proxy.Models
/// A proxy end point client is not aware of.
/// Useful when requests are redirected to this proxy end point through port forwarding via router.
/// </summary>
[DebuggerDisplay("Explicit: {IpAddress}:{Port}")]
public class TransparentProxyEndPoint : ProxyEndPoint
{
/// <summary>
Expand Down
16 changes: 10 additions & 6 deletions src/Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,10 @@ internal async Task<string> GetConnectionCacheKey(ProxyServer server, SessionEve

session.CustomUpStreamProxyUsed = customUpStreamProxy;

var uri = session.HttpClient.Request.RequestUri;
return GetConnectionCacheKey(
session.HttpClient.Request.RequestUri.Host,
session.HttpClient.Request.RequestUri.Port,
uri.Host,
uri.Port,
isHttps, applicationProtocols,
session.HttpClient.UpStreamEndPoint ?? server.UpStreamEndPoint,
customUpStreamProxy ?? (isHttps ? server.UpStreamHttpsProxy : server.UpStreamHttpProxy));
Expand Down Expand Up @@ -179,9 +180,10 @@ internal async Task<TcpServerConnection> GetServerConnection(ProxyServer server,

session.CustomUpStreamProxyUsed = customUpStreamProxy;

var uri = session.HttpClient.Request.RequestUri;
return await GetServerConnection(
session.HttpClient.Request.RequestUri.Host,
session.HttpClient.Request.RequestUri.Port,
uri.Host,
uri.Port,
session.HttpClient.Request.HttpVersion,
isHttps, applicationProtocols, isConnect,
server, session, session.HttpClient.UpStreamEndPoint ?? server.UpStreamEndPoint,
Expand Down Expand Up @@ -372,9 +374,11 @@ private async Task<TcpServerConnection> createServerConnection(string remoteHost
if (useUpstreamProxy && (isConnect || isHttps))
{
var writer = new HttpRequestWriter(stream, proxyServer.BufferPool);
var connectRequest = new ConnectRequest(remoteHostName)
string authority = $"{remoteHostName}:{remotePort}";
var connectRequest = new ConnectRequest(authority)
{
OriginalUrlData = HttpHeader.Encoding.GetBytes($"{remoteHostName}:{remotePort}"),
IsHttps = isHttps,
OriginalUrlData = HttpHeader.Encoding.GetBytes(authority),
HttpVersion = httpVersion
};

Expand Down
4 changes: 4 additions & 0 deletions src/Titanium.Web.Proxy/ProxyServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ public partial class ProxyServer : IDisposable
internal static readonly string UriSchemeHttp = Uri.UriSchemeHttp;
internal static readonly string UriSchemeHttps = Uri.UriSchemeHttps;

internal static ByteString UriSchemeHttp8 = (ByteString)UriSchemeHttp;
internal static ByteString UriSchemeHttps8 = (ByteString)UriSchemeHttps;


/// <summary>
/// A default exception log func.
/// </summary>
Expand Down
4 changes: 2 additions & 2 deletions src/Titanium.Web.Proxy/RequestHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ await HeaderParser.ReadHeaders(clientStream, args.HttpClient.Request.Headers,
var request = args.HttpClient.Request;
if (connectRequest != null)
{
request.Scheme = connectRequest.Scheme;
request.Hostname = connectRequest.Hostname;
request.IsHttps = connectRequest.IsHttps;
request.Authority = connectRequest.Authority;
}

request.OriginalUrlData = HttpHeader.Encoding.GetBytes(httpUrl);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public async Task<Response> Post(string server, int port, string content)

var buffer = new byte[1024];
var responseMsg = string.Empty;
Response response = null;
Response response;

while ((response = HttpMessageParsing.ParseResponse(responseMsg)) == null)
{
Expand Down

0 comments on commit 94e3df9

Please sign in to comment.