Commit 01e06028 authored by Honfika's avatar Honfika

Removed duplicate "copy chunked" method. Estension method added for ssl server name

parent e4435101
......@@ -62,7 +62,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf
public MainWindow()
{
proxyServer = new ProxyServer();
//proxyServer.CertificateEngine = CertificateEngine.BouncyCastle;
//proxyServer.CertificateEngine = CertificateEngine.DefaultWindows;
proxyServer.TrustRootCertificate = true;
proxyServer.CertificateManager.TrustRootCertificateAsAdministrator();
proxyServer.ForwardToUpstreamGateway = true;
......
......@@ -5,7 +5,6 @@ using System.Net;
using System.Threading.Tasks;
using StreamExtended.Network;
using Titanium.Web.Proxy.Decompression;
using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Http;
using Titanium.Web.Proxy.Http.Responses;
......@@ -216,23 +215,8 @@ namespace Titanium.Web.Proxy.EventArguments
//If chunked then its easy just read the whole body with the content length mentioned in the header
using (var bodyStream = new MemoryStream())
{
//For chunked request we need to read data as they arrive, until we reach a chunk end symbol
if (isChunked)
{
await streamReader.CopyBytesToStreamChunked(bodyStream);
}
else
{
//http 1.0
if (contentLength == -1)
{
contentLength = long.MaxValue;
}
//If not chunked then its easy just read the amount of bytes mentioned in content length header
await streamReader.CopyBytesToStream(bodyStream, contentLength);
}
var writer = new HttpWriter(bodyStream, bufferSize);
await writer.CopyBodyAsync(streamReader, isChunked, contentLength, true);
return await GetDecompressedBody(contentEncoding, bodyStream.ToArray());
}
}
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using StreamExtended;
namespace Titanium.Web.Proxy.Extensions
{
static class SslExtensions
{
public static string GetServerName(this ClientHelloInfo clientHelloInfo)
{
if (clientHelloInfo.Extensions != null && clientHelloInfo.Extensions.TryGetValue("server_name", out var serverNameExtension))
{
return serverNameExtension.Data;
}
return null;
}
}
}
......@@ -36,65 +36,5 @@ namespace Titanium.Web.Proxy.Extensions
}
}
}
/// <summary>
/// copies the specified bytes to the stream from the input stream
/// </summary>
/// <param name="streamReader"></param>
/// <param name="stream"></param>
/// <param name="totalBytesToRead"></param>
/// <returns></returns>
internal static async Task CopyBytesToStream(this CustomBinaryReader streamReader, Stream stream, long totalBytesToRead)
{
var buffer = streamReader.Buffer;
long remainingBytes = totalBytesToRead;
while (remainingBytes > 0)
{
int bytesToRead = buffer.Length;
if (remainingBytes < bytesToRead)
{
bytesToRead = (int)remainingBytes;
}
int bytesRead = await streamReader.ReadBytesAsync(buffer, bytesToRead);
if (bytesRead == 0)
{
break;
}
remainingBytes -= bytesRead;
await stream.WriteAsync(buffer, 0, bytesRead);
}
}
/// <summary>
/// Copies the stream chunked
/// </summary>
/// <param name="reader"></param>
/// <param name="stream"></param>
/// <returns></returns>
internal static async Task CopyBytesToStreamChunked(this CustomBinaryReader reader, Stream stream)
{
while (true)
{
string chunkHead = await reader.ReadLineAsync();
int chunkSize = int.Parse(chunkHead, NumberStyles.HexNumber);
if (chunkSize != 0)
{
await CopyBytesToStream(reader, stream, chunkSize);
}
//chunk trail
await reader.ReadLineAsync();
if (chunkSize == 0)
{
break;
}
}
}
}
}
......@@ -5,13 +5,12 @@ using System.Text;
using System.Threading.Tasks;
using StreamExtended.Helpers;
using StreamExtended.Network;
using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Http;
using Titanium.Web.Proxy.Shared;
namespace Titanium.Web.Proxy.Helpers
{
abstract class HttpWriter
internal class HttpWriter
{
public int BufferSize { get; }
......@@ -23,7 +22,7 @@ namespace Titanium.Web.Proxy.Helpers
private static readonly Encoder encoder = Encoding.ASCII.GetEncoder();
protected HttpWriter(Stream stream, int bufferSize)
internal HttpWriter(Stream stream, int bufferSize)
{
BufferSize = bufferSize;
......@@ -136,14 +135,16 @@ namespace Titanium.Web.Proxy.Helpers
/// <param name="streamReader"></param>
/// <param name="isChunked"></param>
/// <param name="contentLength"></param>
/// <param name="removeChunkedEncoding"></param>
/// <returns></returns>
internal Task CopyBodyAsync(CustomBinaryReader streamReader, bool isChunked, long contentLength)
internal Task CopyBodyAsync(CustomBinaryReader streamReader, bool isChunked, long contentLength, bool removeChunkedEncoding)
{
//For chunked request we need to read data as they arrive, until we reach a chunk end symbol
if (isChunked)
{
//Need to revist, find any potential bugs
//send the body bytes to server in chunks
return CopyBodyChunkedAsync(streamReader);
return CopyBodyChunkedAsync(streamReader, removeChunkedEncoding);
}
//http 1.0
......@@ -152,6 +153,7 @@ namespace Titanium.Web.Proxy.Helpers
contentLength = long.MaxValue;
}
//If not chunked then its easy just read the amount of bytes mentioned in content length header
return CopyBytesFromStream(streamReader, contentLength);
}
......@@ -177,23 +179,29 @@ namespace Titanium.Web.Proxy.Helpers
/// Copies the streams chunked
/// </summary>
/// <param name="reader"></param>
/// <param name="removeChunkedEncoding"></param>
/// <returns></returns>
private async Task CopyBodyChunkedAsync(CustomBinaryReader reader)
private async Task CopyBodyChunkedAsync(CustomBinaryReader reader, bool removeChunkedEncoding)
{
while (true)
{
string chunkHead = await reader.ReadLineAsync();
int chunkSize = int.Parse(chunkHead, NumberStyles.HexNumber);
await WriteLineAsync(chunkHead);
if (!removeChunkedEncoding)
{
await WriteLineAsync(chunkHead);
}
if (chunkSize != 0)
{
await CopyBytesFromStream(reader, chunkSize);
}
await WriteLineAsync();
if (!removeChunkedEncoding)
{
await WriteLineAsync();
}
//chunk trail
await reader.ReadLineAsync();
......@@ -205,9 +213,35 @@ namespace Titanium.Web.Proxy.Helpers
}
}
private Task CopyBytesFromStream(CustomBinaryReader reader, long count)
/// <summary>
/// Copies the specified bytes to the stream from the input stream
/// </summary>
/// <param name="reader"></param>
/// <param name="count"></param>
/// <returns></returns>
private async Task CopyBytesFromStream(CustomBinaryReader reader, long count)
{
return reader.CopyBytesToStream(stream, count);
var buffer = reader.Buffer;
long remainingBytes = count;
while (remainingBytes > 0)
{
int bytesToRead = buffer.Length;
if (remainingBytes < bytesToRead)
{
bytesToRead = (int)remainingBytes;
}
int bytesRead = await reader.ReadBytesAsync(buffer, bytesToRead);
if (bytesRead == 0)
{
break;
}
remainingBytes -= bytesRead;
await stream.WriteAsync(buffer, 0, bytesRead);
}
}
}
}
......@@ -226,18 +226,14 @@ namespace Titanium.Web.Proxy
{
if (endPoint.EnableSsl)
{
var clientSslHelloInfo = await SslTools.PeekClientHello(clientStream);
var clientHelloInfo = await SslTools.PeekClientHello(clientStream);
if (clientSslHelloInfo != null)
if (clientHelloInfo != null)
{
var sslStream = new SslStream(clientStream);
clientStream = new CustomBufferedStream(sslStream, BufferSize);
string sniHostName = null;
if (clientSslHelloInfo.Extensions != null && clientSslHelloInfo.Extensions.TryGetValue("server_name", out var serverNameExtension))
{
sniHostName = serverNameExtension.Data;
}
string sniHostName = clientHelloInfo.GetServerName();
string certName = HttpHelper.GetWildCardDomainName(sniHostName ?? endPoint.GenericCertificateName);
var certificate = CertificateManager.CreateCertificate(certName, false);
......@@ -647,7 +643,7 @@ namespace Titanium.Web.Proxy
else
{
await args.WebSession.ServerConnection.StreamWriter.CopyBodyAsync(args.ProxyClient.ClientStreamReader,
request.IsChunked, request.ContentLength);
request.IsChunked, request.ContentLength, false);
}
}
......
......@@ -106,7 +106,7 @@ namespace Titanium.Web.Proxy
if (response.HasBody)
{
await clientStreamWriter.CopyBodyAsync(args.WebSession.ServerConnection.StreamReader,
response.IsChunked, response.ContentLength);
response.IsChunked, response.ContentLength, false);
}
}
}
......
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