Commit 9f3e9d92 authored by Honfika's avatar Honfika

alpn improvement

parent 3bf4649c
...@@ -136,9 +136,9 @@ namespace Titanium.Web.Proxy ...@@ -136,9 +136,9 @@ namespace Titanium.Web.Proxy
{ {
// test server HTTP/2 support // test server HTTP/2 support
// todo: this is a hack, because Titanium does not support HTTP protocol changing currently // todo: this is a hack, because Titanium does not support HTTP protocol changing currently
using (var connection = await GetServerConnection(connectArgs, true, cancellationToken)) using (var connection = await GetServerConnection(connectArgs, true, SslExtensions.Http2ProtocolAsList, cancellationToken))
{ {
http2Supproted = connection.IsHttp2Supported; http2Supproted = connection.NegotiatedApplicationProtocol == SslApplicationProtocol.Http2;
} }
} }
...@@ -170,6 +170,10 @@ namespace Titanium.Web.Proxy ...@@ -170,6 +170,10 @@ namespace Titanium.Web.Proxy
options.CertificateRevocationCheckMode = X509RevocationMode.NoCheck; options.CertificateRevocationCheckMode = X509RevocationMode.NoCheck;
await sslStream.AuthenticateAsServerAsync(options, cancellationToken); await sslStream.AuthenticateAsServerAsync(options, cancellationToken);
#if NETCOREAPP2_1
clientConnection.NegotiatedApplicationProtocol = sslStream.NegotiatedApplicationProtocol;
#endif
// HTTPS server created - we can now decrypt the client's traffic // HTTPS server created - we can now decrypt the client's traffic
clientStream = new CustomBufferedStream(sslStream, BufferSize); clientStream = new CustomBufferedStream(sslStream, BufferSize);
...@@ -197,7 +201,7 @@ namespace Titanium.Web.Proxy ...@@ -197,7 +201,7 @@ namespace Titanium.Web.Proxy
if (!decryptSsl || !isClientHello) if (!decryptSsl || !isClientHello)
{ {
// create new connection // create new connection
using (var connection = await GetServerConnection(connectArgs, true, cancellationToken)) using (var connection = await GetServerConnection(connectArgs, true, clientConnection.NegotiatedApplicationProtocol, cancellationToken))
{ {
if (isClientHello) if (isClientHello)
{ {
...@@ -261,7 +265,7 @@ namespace Titanium.Web.Proxy ...@@ -261,7 +265,7 @@ namespace Titanium.Web.Proxy
} }
// create new connection // create new connection
using (var connection = await GetServerConnection(connectArgs, true, cancellationToken)) using (var connection = await GetServerConnection(connectArgs, true, SslExtensions.Http2ProtocolAsList, cancellationToken))
{ {
await connection.StreamWriter.WriteLineAsync("PRI * HTTP/2.0", cancellationToken); await connection.StreamWriter.WriteLineAsync("PRI * HTTP/2.0", cancellationToken);
await connection.StreamWriter.WriteLineAsync(cancellationToken); await connection.StreamWriter.WriteLineAsync(cancellationToken);
......
...@@ -14,6 +14,9 @@ namespace Titanium.Web.Proxy.Extensions ...@@ -14,6 +14,9 @@ namespace Titanium.Web.Proxy.Extensions
internal static readonly List<SslApplicationProtocol> Http11ProtocolAsList = internal static readonly List<SslApplicationProtocol> Http11ProtocolAsList =
new List<SslApplicationProtocol> { SslApplicationProtocol.Http11 }; new List<SslApplicationProtocol> { SslApplicationProtocol.Http11 };
internal static readonly List<SslApplicationProtocol> Http2ProtocolAsList =
new List<SslApplicationProtocol> { SslApplicationProtocol.Http2 };
internal static string GetServerName(this ClientHelloInfo clientHelloInfo) internal static string GetServerName(this ClientHelloInfo clientHelloInfo)
{ {
if (clientHelloInfo.Extensions != null && if (clientHelloInfo.Extensions != null &&
......
using System; using System;
using System.IO; using System.IO;
using System.Net; using System.Net;
using System.Net.Security;
using System.Net.Sockets; using System.Net.Sockets;
using Titanium.Web.Proxy.Extensions; using Titanium.Web.Proxy.Extensions;
...@@ -26,6 +27,8 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -26,6 +27,8 @@ namespace Titanium.Web.Proxy.Network.Tcp
public EndPoint RemoteEndPoint => tcpClient.Client.RemoteEndPoint; public EndPoint RemoteEndPoint => tcpClient.Client.RemoteEndPoint;
internal SslApplicationProtocol NegotiatedApplicationProtocol { get; set; }
private readonly TcpClient tcpClient; private readonly TcpClient tcpClient;
public Stream GetStream() public Stream GetStream()
......
...@@ -23,9 +23,9 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -23,9 +23,9 @@ namespace Titanium.Web.Proxy.Network.Tcp
/// </summary> /// </summary>
/// <param name="remoteHostName"></param> /// <param name="remoteHostName"></param>
/// <param name="remotePort"></param> /// <param name="remotePort"></param>
/// <param name="applicationProtocols"></param>
/// <param name="httpVersion"></param> /// <param name="httpVersion"></param>
/// <param name="decryptSsl"></param> /// <param name="decryptSsl"></param>
/// <param name="applicationProtocols"></param>
/// <param name="isConnect"></param> /// <param name="isConnect"></param>
/// <param name="proxyServer"></param> /// <param name="proxyServer"></param>
/// <param name="upStreamEndPoint"></param> /// <param name="upStreamEndPoint"></param>
...@@ -33,7 +33,7 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -33,7 +33,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
/// <param name="cancellationToken"></param> /// <param name="cancellationToken"></param>
/// <returns></returns> /// <returns></returns>
internal async Task<TcpServerConnection> CreateClient(string remoteHostName, int remotePort, internal async Task<TcpServerConnection> CreateClient(string remoteHostName, int remotePort,
List<SslApplicationProtocol> applicationProtocols, Version httpVersion, bool decryptSsl, bool isConnect, Version httpVersion, bool decryptSsl, List<SslApplicationProtocol> applicationProtocols, bool isConnect,
ProxyServer proxyServer, IPEndPoint upStreamEndPoint, ExternalProxy externalProxy, ProxyServer proxyServer, IPEndPoint upStreamEndPoint, ExternalProxy externalProxy,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
...@@ -55,7 +55,7 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -55,7 +55,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
TcpClient tcpClient = null; TcpClient tcpClient = null;
CustomBufferedStream stream = null; CustomBufferedStream stream = null;
bool http2Supported = false; SslApplicationProtocol negotiatedApplicationProtocol = default;
try try
{ {
...@@ -114,18 +114,13 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -114,18 +114,13 @@ namespace Titanium.Web.Proxy.Network.Tcp
var options = new SslClientAuthenticationOptions(); var options = new SslClientAuthenticationOptions();
options.ApplicationProtocols = applicationProtocols; options.ApplicationProtocols = applicationProtocols;
if (options.ApplicationProtocols == null || options.ApplicationProtocols.Count == 0)
{
options.ApplicationProtocols = SslExtensions.Http11ProtocolAsList;
}
options.TargetHost = remoteHostName; options.TargetHost = remoteHostName;
options.ClientCertificates = null; options.ClientCertificates = null;
options.EnabledSslProtocols = proxyServer.SupportedSslProtocols; options.EnabledSslProtocols = proxyServer.SupportedSslProtocols;
options.CertificateRevocationCheckMode = proxyServer.CheckCertificateRevocation; options.CertificateRevocationCheckMode = proxyServer.CheckCertificateRevocation;
await sslStream.AuthenticateAsClientAsync(options, cancellationToken); await sslStream.AuthenticateAsClientAsync(options, cancellationToken);
#if NETCOREAPP2_1 #if NETCOREAPP2_1
http2Supported = sslStream.NegotiatedApplicationProtocol == SslApplicationProtocol.Http2; negotiatedApplicationProtocol = sslStream.NegotiatedApplicationProtocol;
#endif #endif
} }
...@@ -146,7 +141,7 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -146,7 +141,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
HostName = remoteHostName, HostName = remoteHostName,
Port = remotePort, Port = remotePort,
IsHttps = decryptSsl, IsHttps = decryptSsl,
IsHttp2Supported = http2Supported, NegotiatedApplicationProtocol = negotiatedApplicationProtocol,
UseUpstreamProxy = useUpstreamProxy, UseUpstreamProxy = useUpstreamProxy,
StreamWriter = new HttpRequestWriter(stream, proxyServer.BufferSize), StreamWriter = new HttpRequestWriter(stream, proxyServer.BufferSize),
Stream = stream, Stream = stream,
......
using System; using System;
using System.Net; using System.Net;
using System.Net.Security;
using System.Net.Sockets; using System.Net.Sockets;
using StreamExtended.Network; using StreamExtended.Network;
using Titanium.Web.Proxy.Extensions; using Titanium.Web.Proxy.Extensions;
...@@ -31,7 +32,7 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -31,7 +32,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
internal bool IsHttps { get; set; } internal bool IsHttps { get; set; }
internal bool IsHttp2Supported { get; set; } internal SslApplicationProtocol NegotiatedApplicationProtocol { get; set; }
internal bool UseUpstreamProxy { get; set; } internal bool UseUpstreamProxy { get; set; }
......
using System; using System;
using System.Collections.Generic;
using System.Net; using System.Net;
using System.Net.Security;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
...@@ -179,7 +181,7 @@ namespace Titanium.Web.Proxy ...@@ -179,7 +181,7 @@ namespace Titanium.Web.Proxy
if (serverConnection == null) if (serverConnection == null)
{ {
serverConnection = await GetServerConnection(args, false, cancellationToken); serverConnection = await GetServerConnection(args, false, clientConnection.NegotiatedApplicationProtocol, cancellationToken);
} }
// if upgrading to websocket then relay the requet without reading the contents // if upgrading to websocket then relay the requet without reading the contents
...@@ -353,10 +355,31 @@ namespace Titanium.Web.Proxy ...@@ -353,10 +355,31 @@ namespace Titanium.Web.Proxy
/// </summary> /// </summary>
/// <param name="args">The session event arguments.</param> /// <param name="args">The session event arguments.</param>
/// <param name="isConnect">Is this a CONNECT request.</param> /// <param name="isConnect">Is this a CONNECT request.</param>
/// <param name="applicationProtocol"></param>
/// <param name="cancellationToken">The cancellation token for this async task.</param>
/// <returns></returns>
private Task<TcpServerConnection> GetServerConnection(SessionEventArgsBase args, bool isConnect,
SslApplicationProtocol applicationProtocol, CancellationToken cancellationToken)
{
List<SslApplicationProtocol> applicationProtocols = null;
if (applicationProtocol != default)
{
applicationProtocols = new List<SslApplicationProtocol> { applicationProtocol };
}
return GetServerConnection(args, isConnect, applicationProtocols, cancellationToken);
}
/// <summary>
/// Create a server connection.
/// </summary>
/// <param name="args">The session event arguments.</param>
/// <param name="isConnect">Is this a CONNECT request.</param>
/// <param name="applicationProtocols"></param>
/// <param name="cancellationToken">The cancellation token for this async task.</param> /// <param name="cancellationToken">The cancellation token for this async task.</param>
/// <returns></returns> /// <returns></returns>
private async Task<TcpServerConnection> GetServerConnection(SessionEventArgsBase args, bool isConnect, private async Task<TcpServerConnection> GetServerConnection(SessionEventArgsBase args, bool isConnect,
CancellationToken cancellationToken) List<SslApplicationProtocol> applicationProtocols, CancellationToken cancellationToken)
{ {
ExternalProxy customUpStreamProxy = null; ExternalProxy customUpStreamProxy = null;
...@@ -371,8 +394,8 @@ namespace Titanium.Web.Proxy ...@@ -371,8 +394,8 @@ namespace Titanium.Web.Proxy
return await tcpConnectionFactory.CreateClient( return await tcpConnectionFactory.CreateClient(
args.WebSession.Request.RequestUri.Host, args.WebSession.Request.RequestUri.Host,
args.WebSession.Request.RequestUri.Port, args.WebSession.Request.RequestUri.Port,
args.WebSession.ConnectRequest?.ClientHelloInfo?.GetAlpn(), args.WebSession.Request.HttpVersion,
args.WebSession.Request.HttpVersion, isHttps, isConnect, isHttps, applicationProtocols, isConnect,
this, args.WebSession.UpStreamEndPoint ?? UpStreamEndPoint, this, args.WebSession.UpStreamEndPoint ?? UpStreamEndPoint,
customUpStreamProxy ?? (isHttps ? UpStreamHttpsProxy : UpStreamHttpProxy), customUpStreamProxy ?? (isHttps ? UpStreamHttpsProxy : UpStreamHttpProxy),
cancellationToken); cancellationToken);
......
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