Commit 47be26d5 authored by Honfika's avatar Honfika
parents 8b41f880 ded334fc
...@@ -151,7 +151,7 @@ namespace Titanium.Web.Proxy.Examples.Basic ...@@ -151,7 +151,7 @@ namespace Titanium.Web.Proxy.Examples.Basic
return Task.FromResult(false); return Task.FromResult(false);
} }
// intecept & cancel redirect or update requests // intercept & cancel redirect or update requests
private async Task onRequest(object sender, SessionEventArgs e) private async Task onRequest(object sender, SessionEventArgs e)
{ {
await writeToConsole("Active Client Connections:" + ((ProxyServer)sender).ClientConnectionCount); await writeToConsole("Active Client Connections:" + ((ProxyServer)sender).ClientConnectionCount);
......
using System; using System;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Titanium.Web.Proxy.Exceptions; using Titanium.Web.Proxy.Exceptions;
using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.StreamExtended.BufferPool; using Titanium.Web.Proxy.StreamExtended.BufferPool;
using Titanium.Web.Proxy.StreamExtended.Network; using Titanium.Web.Proxy.StreamExtended.Network;
...@@ -51,11 +51,22 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -51,11 +51,22 @@ namespace Titanium.Web.Proxy.EventArguments
{ {
// read the chunk trail of the previous chunk // read the chunk trail of the previous chunk
string? s = baseReader.ReadLineAsync().Result; string? s = baseReader.ReadLineAsync().Result;
if (s == null)
{
bytesRemaining = -1;
return;
}
} }
readChunkTrail = true; readChunkTrail = true;
string? chunkHead = baseReader.ReadLineAsync().Result!; string? chunkHead = baseReader.ReadLineAsync().Result;
if (chunkHead == null)
{
bytesRemaining = -1;
return;
}
int idx = chunkHead.IndexOf(";", StringComparison.Ordinal); int idx = chunkHead.IndexOf(";", StringComparison.Ordinal);
if (idx >= 0) if (idx >= 0)
{ {
...@@ -80,6 +91,50 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -80,6 +91,50 @@ namespace Titanium.Web.Proxy.EventArguments
} }
} }
private async Task getNextChunkAsync()
{
if (readChunkTrail)
{
// read the chunk trail of the previous chunk
string? s = await baseReader.ReadLineAsync();
if (s == null)
{
bytesRemaining = -1;
return;
}
}
readChunkTrail = true;
string? chunkHead = await baseReader.ReadLineAsync();
if (chunkHead == null)
{
bytesRemaining = -1;
return;
}
int idx = chunkHead.IndexOf(";", StringComparison.Ordinal);
if (idx >= 0)
{
chunkHead = chunkHead.Substring(0, idx);
}
if (!int.TryParse(chunkHead, NumberStyles.HexNumber, null, out int chunkSize))
{
throw new ProxyHttpException($"Invalid chunk length: '{chunkHead}'", null, null);
}
bytesRemaining = chunkSize;
if (chunkSize == 0)
{
bytesRemaining = -1;
// chunk trail
await baseReader.ReadLineAsync();
}
}
public override void Flush() public override void Flush()
{ {
throw new NotSupportedException(); throw new NotSupportedException();
...@@ -131,6 +186,42 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -131,6 +186,42 @@ namespace Titanium.Web.Proxy.EventArguments
return res; return res;
} }
public override async Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
if (bytesRemaining == -1)
{
return 0;
}
if (bytesRemaining == 0)
{
if (isChunked)
{
await getNextChunkAsync();
}
else
{
bytesRemaining = -1;
}
}
if (bytesRemaining == -1)
{
return 0;
}
int toRead = (int)Math.Min(count, bytesRemaining);
int res = await baseReader.ReadAsync(buffer, offset, toRead, cancellationToken);
bytesRemaining -= res;
if (res == 0)
{
bytesRemaining = -1;
}
return res;
}
public async Task Finish() public async Task Finish()
{ {
if (bytesRemaining != -1) if (bytesRemaining != -1)
......
...@@ -650,7 +650,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -650,7 +650,7 @@ namespace Titanium.Web.Proxy.Helpers
if (bufferDataLength == buffer.Length) if (bufferDataLength == buffer.Length)
{ {
ResizeBuffer(ref buffer, bufferDataLength * 2); resizeBuffer(ref buffer, bufferDataLength * 2);
} }
} }
} }
...@@ -683,7 +683,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -683,7 +683,7 @@ namespace Titanium.Web.Proxy.Helpers
/// </summary> /// </summary>
/// <param name="buffer"></param> /// <param name="buffer"></param>
/// <param name="size"></param> /// <param name="size"></param>
private static void ResizeBuffer(ref byte[] buffer, long size) private static void resizeBuffer(ref byte[] buffer, long size)
{ {
var newBuffer = new byte[size]; var newBuffer = new byte[size];
Buffer.BlockCopy(buffer, 0, newBuffer, 0, buffer.Length); Buffer.BlockCopy(buffer, 0, newBuffer, 0, buffer.Length);
...@@ -889,7 +889,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -889,7 +889,7 @@ namespace Titanium.Web.Proxy.Helpers
string? contentEncoding = useOriginalHeaderValues ? requestResponse.OriginalContentEncoding : requestResponse.ContentEncoding; string? contentEncoding = useOriginalHeaderValues ? requestResponse.OriginalContentEncoding : requestResponse.ContentEncoding;
Stream s = limitedStream = new LimitedStream(this, bufferPool, isChunked, contentLength); Stream s = limitedStream = new LimitedStream(this, bufferPool, isChunked, contentLength);
if (transformation == TransformationMode.Uncompress && contentEncoding != null) if (transformation == TransformationMode.Uncompress && contentEncoding != null)
{ {
s = decompressStream = DecompressionFactory.Create(CompressionUtil.CompressionNameToEnum(contentEncoding), s); s = decompressStream = DecompressionFactory.Create(CompressionUtil.CompressionNameToEnum(contentEncoding), s);
......
...@@ -100,12 +100,10 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -100,12 +100,10 @@ namespace Titanium.Web.Proxy.Helpers
/// <param name="onDataSend"></param> /// <param name="onDataSend"></param>
/// <param name="onDataReceive"></param> /// <param name="onDataReceive"></param>
/// <param name="cancellationTokenSource"></param> /// <param name="cancellationTokenSource"></param>
/// <param name="exceptionFunc"></param>
/// <returns></returns> /// <returns></returns>
private static async Task sendRawTap(Stream clientStream, Stream serverStream, IBufferPool bufferPool, private static async Task sendRawTap(Stream clientStream, Stream serverStream, IBufferPool bufferPool,
Action<byte[], int, int>? onDataSend, Action<byte[], int, int>? onDataReceive, Action<byte[], int, int>? onDataSend, Action<byte[], int, int>? onDataReceive,
CancellationTokenSource cancellationTokenSource, CancellationTokenSource cancellationTokenSource)
ExceptionHandler exceptionFunc)
{ {
// Now async relay all server=>client & client=>server data // Now async relay all server=>client & client=>server data
var sendRelay = var sendRelay =
...@@ -139,8 +137,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -139,8 +137,7 @@ namespace Titanium.Web.Proxy.Helpers
{ {
// todo: fix APM mode // todo: fix APM mode
return sendRawTap(clientStream, serverStream, bufferPool, onDataSend, onDataReceive, return sendRawTap(clientStream, serverStream, bufferPool, onDataSend, onDataReceive,
cancellationTokenSource, cancellationTokenSource);
exceptionFunc);
} }
} }
} }
...@@ -24,17 +24,5 @@ namespace Titanium.Web.Proxy.Http ...@@ -24,17 +24,5 @@ namespace Titanium.Web.Proxy.Http
headerCollection.AddHeader(headerName, headerValue); headerCollection.AddHeader(headerName, headerValue);
} }
} }
/// <summary>
/// Increase size of buffer and copy existing content to new buffer
/// </summary>
/// <param name="buffer"></param>
/// <param name="size"></param>
private static void resizeBuffer(ref byte[] buffer, long size)
{
var newBuffer = new byte[size];
Buffer.BlockCopy(buffer, 0, newBuffer, 0, buffer.Length);
buffer = newBuffer;
}
} }
} }
using System; using System;
using System.IO; using System.IO;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
using System.Threading;
using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Pkcs; using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Asn1.X509;
...@@ -219,11 +218,9 @@ namespace Titanium.Web.Proxy.Network.Certificate ...@@ -219,11 +218,9 @@ namespace Titanium.Web.Proxy.Network.Certificate
/// <param name="subject">The s subject cn.</param> /// <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="switchToMtaIfNeeded">if set to <c>true</c> [switch to MTA if needed].</param>
/// <param name="signingCert">The signing cert.</param> /// <param name="signingCert">The signing cert.</param>
/// <param name="cancellationToken">Task cancellation token</param>
/// <returns>X509Certificate2.</returns> /// <returns>X509Certificate2.</returns>
private X509Certificate2 makeCertificateInternal(string subject, private X509Certificate2 makeCertificateInternal(string subject,
bool switchToMtaIfNeeded, X509Certificate2? signingCert = null, bool switchToMtaIfNeeded, X509Certificate2? signingCert = null)
CancellationToken cancellationToken = default)
{ {
return makeCertificateInternal(subject, $"CN={subject}", return makeCertificateInternal(subject, $"CN={subject}",
DateTime.UtcNow.AddDays(-certificateGraceDays), DateTime.UtcNow.AddDays(certificateValidDays), DateTime.UtcNow.AddDays(-certificateGraceDays), DateTime.UtcNow.AddDays(certificateValidDays),
......
...@@ -291,13 +291,13 @@ namespace Titanium.Web.Proxy ...@@ -291,13 +291,13 @@ namespace Titanium.Web.Proxy
} }
// construct the web request that we are going to issue on behalf of the client. // construct the web request that we are going to issue on behalf of the client.
await handleHttpSessionRequest(connection, args); await handleHttpSessionRequest(args);
return true; return true;
}, generator, serverConnection); }, generator, serverConnection);
} }
private async Task handleHttpSessionRequest(TcpServerConnection connection, SessionEventArgs args) private async Task handleHttpSessionRequest(SessionEventArgs args)
{ {
var cancellationToken = args.CancellationTokenSource.Token; var cancellationToken = args.CancellationTokenSource.Token;
var request = args.HttpClient.Request; var request = args.HttpClient.Request;
......
...@@ -154,7 +154,7 @@ namespace Titanium.Web.Proxy.StreamExtended ...@@ -154,7 +154,7 @@ namespace Titanium.Web.Proxy.StreamExtended
if(extensionsStartPosition < recordLength + 5) 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) var clientHelloInfo = new ClientHelloInfo(3, majorVersion, minorVersion, random, sessionId, ciphers, peekStream.Position)
...@@ -292,7 +292,7 @@ namespace Titanium.Web.Proxy.StreamExtended ...@@ -292,7 +292,7 @@ namespace Titanium.Web.Proxy.StreamExtended
if (extensionsStartPosition < recordLength + 5) 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) var serverHelloInfo = new ServerHelloInfo(3, majorVersion, minorVersion, random, sessionId, cipherSuite, peekStream.Position)
...@@ -308,7 +308,7 @@ namespace Titanium.Web.Proxy.StreamExtended ...@@ -308,7 +308,7 @@ namespace Titanium.Web.Proxy.StreamExtended
return null; 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; Dictionary<string, SslExtension>? extensions = null;
if (majorVersion > 3 || majorVersion == 3 && minorVersion >= 1) if (majorVersion > 3 || majorVersion == 3 && minorVersion >= 1)
......
...@@ -75,14 +75,15 @@ namespace Titanium.Web.Proxy ...@@ -75,14 +75,15 @@ namespace Titanium.Web.Proxy
// HTTPS server created - we can now decrypt the client's traffic // HTTPS server created - we can now decrypt the client's traffic
clientStream = new HttpClientStream(sslStream, BufferPool); clientStream = new HttpClientStream(sslStream, BufferPool);
sslStream = null; // clientStream was created, no need to keep SSL stream reference
} }
catch (Exception e) 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, var session = new SessionEventArgs(this, endPoint, clientConnection, clientStream, null,
cancellationTokenSource); cancellationTokenSource);
throw new ProxyConnectException( throw new ProxyConnectException(
$"Couldn't authenticate host '{httpsHostName}' with certificate '{certname}'.", e, session); $"Couldn't authenticate host '{httpsHostName}' with certificate '{certName}'.", e, session);
} }
} }
......
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