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

beta #683

Merged
merged 3 commits into from
Nov 26, 2019
Merged

beta #683

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
2 changes: 0 additions & 2 deletions src/Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using Titanium.Web.Proxy.Compression;
using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Http;
using Titanium.Web.Proxy.Http.Responses;
using Titanium.Web.Proxy.Models;
using Titanium.Web.Proxy.Network;
using Titanium.Web.Proxy.Network.Tcp;
using Titanium.Web.Proxy.StreamExtended.Network;

Expand Down
18 changes: 9 additions & 9 deletions src/Titanium.Web.Proxy/ExplicitClientHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,18 +52,16 @@ private async Task handleClient(ExplicitProxyEndPoint endPoint, TcpClientConnect
if (await HttpHelper.IsConnectMethod(clientStream, BufferPool, cancellationToken) == 1)
{
// read the first line HTTP command
string? httpCmd = await clientStream.ReadLineAsync(cancellationToken);
if (string.IsNullOrEmpty(httpCmd))
var requestLine = await clientStream.ReadRequestLine(cancellationToken);
if (requestLine.IsEmpty())
{
return;
}

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

var connectRequest = new ConnectRequest(httpUrl.GetString())
var connectRequest = new ConnectRequest(requestLine.RequestUri.GetString())
{
RequestUriString8 = httpUrl,
HttpVersion = version
RequestUriString8 = requestLine.RequestUri,
HttpVersion = requestLine.Version
};

await HeaderParser.ReadHeaders(clientStream, connectRequest.Headers, cancellationToken);
Expand Down Expand Up @@ -105,7 +103,7 @@ private async Task handleClient(ExplicitProxyEndPoint endPoint, TcpClientConnect
}

// write back successful CONNECT response
var response = ConnectResponse.CreateSuccessfulConnectResponse(version);
var response = ConnectResponse.CreateSuccessfulConnectResponse(requestLine.Version);

// Set ContentLength explicitly to properly handle HTTP 1.0
response.ContentLength = 0;
Expand Down Expand Up @@ -175,7 +173,7 @@ private async Task handleClient(ExplicitProxyEndPoint endPoint, TcpClientConnect
}
}

string connectHostname = httpUrl.GetString();
string connectHostname = requestLine.RequestUri.GetString();
int idx = connectHostname.IndexOf(":");
if (idx >= 0)
{
Expand Down Expand Up @@ -214,6 +212,8 @@ private async Task handleClient(ExplicitProxyEndPoint endPoint, TcpClientConnect

// HTTPS server created - we can now decrypt the client's traffic
clientStream = new HttpClientStream(sslStream, BufferPool);
sslStream = null; // clientStream was created, no need to keep SSL stream reference

clientStream.DataRead += (o, args) => connectArgs.OnDecryptedDataSent(args.Buffer, args.Offset, args.Count);
clientStream.DataWrite += (o, args) => connectArgs.OnDecryptedDataReceived(args.Buffer, args.Offset, args.Count);
}
Expand Down
14 changes: 14 additions & 0 deletions src/Titanium.Web.Proxy/Helpers/HttpClientStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,19 @@ internal async ValueTask WriteResponseAsync(Response response, CancellationToken

await WriteAsync(response, headerBuilder, cancellationToken);
}

internal async ValueTask<RequestStatusInfo> ReadRequestLine(CancellationToken cancellationToken = default)
{
// read the first line HTTP command
string? httpCmd = await ReadLineAsync(cancellationToken);
if (string.IsNullOrEmpty(httpCmd))
{
return default;
}

Request.ParseRequestLine(httpCmd!, out string method, out var requestUri, out var version);

return new RequestStatusInfo { Method = method, RequestUri = requestUri, Version = version };
}
}
}
19 changes: 19 additions & 0 deletions src/Titanium.Web.Proxy/Helpers/RequestStatusInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;
using Titanium.Web.Proxy.Models;

namespace Titanium.Web.Proxy.Helpers
{
struct RequestStatusInfo
{
public string Method { get; set; }

public ByteString RequestUri { get; set; }

public Version Version { get; set; }

public bool IsEmpty()
{
return Method == null && RequestUri.Length == 0 && Version == null;
}
}
}
7 changes: 2 additions & 5 deletions src/Titanium.Web.Proxy/Helpers/TcpHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,10 @@ private static uint toNetworkByteOrder(uint port)
/// <param name="onDataSend"></param>
/// <param name="onDataReceive"></param>
/// <param name="cancellationTokenSource"></param>
/// <param name="exceptionFunc"></param>
/// <returns></returns>
private static async Task sendRawTap(Stream clientStream, Stream serverStream, IBufferPool bufferPool,
Action<byte[], int, int>? onDataSend, Action<byte[], int, int>? onDataReceive,
CancellationTokenSource cancellationTokenSource,
ExceptionHandler exceptionFunc)
CancellationTokenSource cancellationTokenSource)
{
// Now async relay all server=>client & client=>server data
var sendRelay =
Expand Down Expand Up @@ -139,8 +137,7 @@ internal static Task SendRaw(Stream clientStream, Stream serverStream, IBufferPo
{
// todo: fix APM mode
return sendRawTap(clientStream, serverStream, bufferPool, onDataSend, onDataReceive,
cancellationTokenSource,
exceptionFunc);
cancellationTokenSource);
}
}
}
12 changes: 6 additions & 6 deletions src/Titanium.Web.Proxy/Http/Request.cs
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ internal override void EnsureBodyAvailable(bool throwWhenNotReadYet = true)
}
}

internal static void ParseRequestLine(string httpCmd, out string httpMethod, out ByteString httpUrl,
internal static void ParseRequestLine(string httpCmd, out string method, out ByteString requestUri,
out Version version)
{
int firstSpace = httpCmd.IndexOf(' ');
Expand All @@ -269,21 +269,21 @@ internal static void ParseRequestLine(string httpCmd, out string httpMethod, out
// break up the line into three components (method, remote URL & Http Version)

// Find the request Verb
httpMethod = httpCmd.Substring(0, firstSpace);
if (!isAllUpper(httpMethod))
method = httpCmd.Substring(0, firstSpace);
if (!isAllUpper(method))
{
httpMethod = httpMethod.ToUpper();
method = method.ToUpper();
}

version = HttpHeader.Version11;

if (firstSpace == lastSpace)
{
httpUrl = (ByteString)httpCmd.AsSpan(firstSpace + 1).ToString();
requestUri = (ByteString)httpCmd.AsSpan(firstSpace + 1).ToString();
}
else
{
httpUrl = (ByteString)httpCmd.AsSpan(firstSpace + 1, lastSpace - firstSpace - 1).ToString();
requestUri = (ByteString)httpCmd.AsSpan(firstSpace + 1, lastSpace - firstSpace - 1).ToString();

// parse the HTTP version
var httpVersion = httpCmd.AsSpan(lastSpace + 1);
Expand Down
2 changes: 1 addition & 1 deletion src/Titanium.Web.Proxy/Http/RequestResponseBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ internal set
/// Use the encoding specified to decode the byte[] data to string
/// </summary>
[Browsable(false)]
public string BodyString => bodyString ?? (bodyString = Encoding.GetString(Body));
public string BodyString => bodyString ??= Encoding.GetString(Body);

/// <summary>
/// Was the body read by user?
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.X509;
Expand Down Expand Up @@ -219,11 +218,9 @@ private X509Certificate2 makeCertificateInternal(string hostName, string subject
/// <param name="subject">The s subject cn.</param>
/// <param name="switchToMtaIfNeeded">if set to <c>true</c> [switch to MTA if needed].</param>
/// <param name="signingCert">The signing cert.</param>
/// <param name="cancellationToken">Task cancellation token</param>
/// <returns>X509Certificate2.</returns>
private X509Certificate2 makeCertificateInternal(string subject,
bool switchToMtaIfNeeded, X509Certificate2? signingCert = null,
CancellationToken cancellationToken = default)
bool switchToMtaIfNeeded, X509Certificate2? signingCert = null)
{
return makeCertificateInternal(subject, $"CN={subject}",
DateTime.UtcNow.AddDays(-certificateGraceDays), DateTime.UtcNow.AddDays(certificateValidDays),
Expand Down
16 changes: 7 additions & 9 deletions src/Titanium.Web.Proxy/RequestHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ private async Task handleHttpSessionRequest(ProxyEndPoint endPoint, TcpClientCon
}

// read the request line
string? httpCmd = await clientStream.ReadLineAsync(cancellationToken);
if (string.IsNullOrEmpty(httpCmd))
var requestLine = await clientStream.ReadRequestLine(cancellationToken);
if (requestLine.IsEmpty())
{
return;
}
Expand All @@ -73,8 +73,6 @@ private async Task handleHttpSessionRequest(ProxyEndPoint endPoint, TcpClientCon
{
try
{
Request.ParseRequestLine(httpCmd!, out string httpMethod, out ByteString httpUrl, out var version);

// Read the request headers in to unique and non-unique header collections
await HeaderParser.ReadHeaders(clientStream, args.HttpClient.Request.Headers,
cancellationToken);
Expand All @@ -86,10 +84,10 @@ await HeaderParser.ReadHeaders(clientStream, args.HttpClient.Request.Headers,
request.Authority = connectRequest.Authority;
}

request.RequestUriString8 = httpUrl;
request.RequestUriString8 = requestLine.RequestUri;

request.Method = httpMethod;
request.HttpVersion = version;
request.Method = requestLine.Method;
request.HttpVersion = requestLine.Version;

if (!args.IsTransparent)
{
Expand Down Expand Up @@ -293,13 +291,13 @@ private async Task<RetryResult> handleHttpSessionRequest(SessionEventArgs args,
}

// construct the web request that we are going to issue on behalf of the client.
await handleHttpSessionRequest(connection, args);
await handleHttpSessionRequest(args);
return true;

}, generator, serverConnection);
}

private async Task handleHttpSessionRequest(TcpServerConnection connection, SessionEventArgs args)
private async Task handleHttpSessionRequest(SessionEventArgs args)
{
var cancellationToken = args.CancellationTokenSource.Token;
var request = args.HttpClient.Request;
Expand Down
6 changes: 3 additions & 3 deletions src/Titanium.Web.Proxy/StreamExtended/SslTools.cs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ internal class SslTools

if(extensionsStartPosition < recordLength + 5)
{
extensions = await ReadExtensions(majorVersion, minorVersion, peekStream, bufferPool, cancellationToken);
extensions = await ReadExtensions(majorVersion, minorVersion, peekStream, cancellationToken);
}

var clientHelloInfo = new ClientHelloInfo(3, majorVersion, minorVersion, random, sessionId, ciphers, peekStream.Position)
Expand Down Expand Up @@ -292,7 +292,7 @@ public static async Task<bool> IsServerHello(IPeekStream stream, IBufferPool buf

if (extensionsStartPosition < recordLength + 5)
{
extensions = await ReadExtensions(majorVersion, minorVersion, peekStream, bufferPool, cancellationToken);
extensions = await ReadExtensions(majorVersion, minorVersion, peekStream, cancellationToken);
}

var serverHelloInfo = new ServerHelloInfo(3, majorVersion, minorVersion, random, sessionId, cipherSuite, peekStream.Position)
Expand All @@ -308,7 +308,7 @@ public static async Task<bool> IsServerHello(IPeekStream stream, IBufferPool buf
return null;
}

private static async Task<Dictionary<string, SslExtension>?> ReadExtensions(int majorVersion, int minorVersion, PeekStreamReader peekStreamReader, IBufferPool bufferPool, CancellationToken cancellationToken)
private static async Task<Dictionary<string, SslExtension>?> ReadExtensions(int majorVersion, int minorVersion, PeekStreamReader peekStreamReader, CancellationToken cancellationToken)
{
Dictionary<string, SslExtension>? extensions = null;
if (majorVersion > 3 || majorVersion == 3 && minorVersion >= 1)
Expand Down
5 changes: 3 additions & 2 deletions src/Titanium.Web.Proxy/TransparentClientHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,15 @@ private async Task handleClient(TransparentProxyEndPoint endPoint, TcpClientConn

// HTTPS server created - we can now decrypt the client's traffic
clientStream = new HttpClientStream(sslStream, BufferPool);
sslStream = null; // clientStream was created, no need to keep SSL stream reference
}
catch (Exception e)
{
var certname = certificate?.GetNameInfo(X509NameType.SimpleName, false);
var certName = certificate?.GetNameInfo(X509NameType.SimpleName, false);
var session = new SessionEventArgs(this, endPoint, clientConnection, clientStream, null,
cancellationTokenSource);
throw new ProxyConnectException(
$"Couldn't authenticate host '{httpsHostName}' with certificate '{certname}'.", e, session);
$"Couldn't authenticate host '{httpsHostName}' with certificate '{certName}'.", e, session);
}

}
Expand Down