Commit 9f3e9d92 authored by Honfika's avatar Honfika

alpn improvement

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