Commit 65e08954 authored by justcoding121's avatar justcoding121

Merge branch 'beta' into stable

parents 4a8e65da ea064f0f
...@@ -27,7 +27,7 @@ cache: .build\cleanup-cache.txt ...@@ -27,7 +27,7 @@ cache: .build\cleanup-cache.txt
# to run your custom scripts instead of automatic MSBuild # to run your custom scripts instead of automatic MSBuild
build_script: build_script:
- cmd: build.bat Package - cmd: build.bat
assembly_info: assembly_info:
patch: true patch: true
...@@ -39,6 +39,8 @@ assembly_info: ...@@ -39,6 +39,8 @@ assembly_info:
# to disable automatic tests # to disable automatic tests
test: on test: on
test_script:
- cmd: test.bat
# skip building commits that add tags (such as release tag) # skip building commits that add tags (such as release tag)
skip_tags: true skip_tags: true
......
...@@ -552,6 +552,54 @@ Root certificate file will be named as &quot;rootCert.pfx&quot;.</p> ...@@ -552,6 +552,54 @@ Root certificate file will be named as &quot;rootCert.pfx&quot;.</p>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<span class="small pull-right mobile-hide">
<span class="divider">|</span>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_Network_CertificateManager_CreateServerCertificate_System_String_.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.Network.CertificateManager.CreateServerCertificate(System.String)%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span>
<span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/Network/CertificateManager.cs/#L439">View Source</a>
</span>
<a id="Titanium_Web_Proxy_Network_CertificateManager_CreateServerCertificate_" data-uid="Titanium.Web.Proxy.Network.CertificateManager.CreateServerCertificate*"></a>
<h4 id="Titanium_Web_Proxy_Network_CertificateManager_CreateServerCertificate_System_String_" data-uid="Titanium.Web.Proxy.Network.CertificateManager.CreateServerCertificate(System.String)">CreateServerCertificate(String)</h4>
<div class="markdown level1 summary"><p>Creates a server certificate signed by the root certificate.</p>
</div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public Task&lt;X509Certificate2&gt; CreateServerCertificate(string certificateName)</code></pre>
</div>
<h5 class="parameters">Parameters</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><a class="xref" href="https://docs.microsoft.com/dotnet/api/system.string">String</a></td>
<td><span class="parametername">certificateName</span></td>
<td></td>
</tr>
</tbody>
</table>
<h5 class="returns">Returns</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><a class="xref" href="https://docs.microsoft.com/dotnet/api/system.threading.tasks.task-1">Task</a>&lt;<a class="xref" href="https://docs.microsoft.com/dotnet/api/system.security.cryptography.x509certificates.x509certificate2">X509Certificate2</a>&gt;</td>
<td></td>
</tr>
</tbody>
</table>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<span class="divider">|</span> <span class="divider">|</span>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_Network_CertificateManager_Dispose.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.Network.CertificateManager.Dispose%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_Network_CertificateManager_Dispose.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.Network.CertificateManager.Dispose%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
......
This diff is collapsed.
...@@ -3035,6 +3035,19 @@ references: ...@@ -3035,6 +3035,19 @@ references:
isSpec: "True" isSpec: "True"
fullName: Titanium.Web.Proxy.Network.CertificateManager.CreateRootCertificate fullName: Titanium.Web.Proxy.Network.CertificateManager.CreateRootCertificate
nameWithType: CertificateManager.CreateRootCertificate nameWithType: CertificateManager.CreateRootCertificate
- uid: Titanium.Web.Proxy.Network.CertificateManager.CreateServerCertificate(System.String)
name: CreateServerCertificate(String)
href: api/Titanium.Web.Proxy.Network.CertificateManager.html#Titanium_Web_Proxy_Network_CertificateManager_CreateServerCertificate_System_String_
commentId: M:Titanium.Web.Proxy.Network.CertificateManager.CreateServerCertificate(System.String)
fullName: Titanium.Web.Proxy.Network.CertificateManager.CreateServerCertificate(System.String)
nameWithType: CertificateManager.CreateServerCertificate(String)
- uid: Titanium.Web.Proxy.Network.CertificateManager.CreateServerCertificate*
name: CreateServerCertificate
href: api/Titanium.Web.Proxy.Network.CertificateManager.html#Titanium_Web_Proxy_Network_CertificateManager_CreateServerCertificate_
commentId: Overload:Titanium.Web.Proxy.Network.CertificateManager.CreateServerCertificate
isSpec: "True"
fullName: Titanium.Web.Proxy.Network.CertificateManager.CreateServerCertificate
nameWithType: CertificateManager.CreateServerCertificate
- uid: Titanium.Web.Proxy.Network.CertificateManager.Dispose - uid: Titanium.Web.Proxy.Network.CertificateManager.Dispose
name: Dispose() name: Dispose()
href: api/Titanium.Web.Proxy.Network.CertificateManager.html#Titanium_Web_Proxy_Network_CertificateManager_Dispose href: api/Titanium.Web.Proxy.Network.CertificateManager.html#Titanium_Web_Proxy_Network_CertificateManager_Dispose
......
...@@ -25,12 +25,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Titanium.Web.Proxy", "Titan ...@@ -25,12 +25,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Titanium.Web.Proxy", "Titan
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Titanium.Web.Proxy.UnitTests", "..\tests\Titanium.Web.Proxy.UnitTests\Titanium.Web.Proxy.UnitTests.csproj", "{B517E3D0-D03B-436F-AB03-34BA0D5321AF}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Titanium.Web.Proxy.UnitTests", "..\tests\Titanium.Web.Proxy.UnitTests\Titanium.Web.Proxy.UnitTests.csproj", "{B517E3D0-D03B-436F-AB03-34BA0D5321AF}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Titanium.Web.Proxy.IntegrationTests", "..\tests\Titanium.Web.Proxy.IntegrationTests\Titanium.Web.Proxy.IntegrationTests.csproj", "{32231301-B0FB-4F9E-98DF-B3E8A88F4C16}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Titanium.Web.Proxy.Examples.Basic", "..\examples\Titanium.Web.Proxy.Examples.Basic\Titanium.Web.Proxy.Examples.Basic.csproj", "{1FAC4205-4445-4F2B-BB8F-618E8A0C15FD}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Titanium.Web.Proxy.Examples.Basic", "..\examples\Titanium.Web.Proxy.Examples.Basic\Titanium.Web.Proxy.Examples.Basic.csproj", "{1FAC4205-4445-4F2B-BB8F-618E8A0C15FD}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Titanium.Web.Proxy.Examples.Wpf", "..\examples\Titanium.Web.Proxy.Examples.Wpf\Titanium.Web.Proxy.Examples.Wpf.csproj", "{4406CE17-9A39-4F28-8363-6169A4F799C1}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Titanium.Web.Proxy.Examples.Wpf", "..\examples\Titanium.Web.Proxy.Examples.Wpf\Titanium.Web.Proxy.Examples.Wpf.csproj", "{4406CE17-9A39-4F28-8363-6169A4F799C1}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Titanium.Web.Proxy.IntegrationTests", "..\tests\Titanium.Web.Proxy.IntegrationTests\Titanium.Web.Proxy.IntegrationTests.csproj", "{1D053D72-DCB4-4517-ACDD-D35ADC186950}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
...@@ -49,20 +49,12 @@ Global ...@@ -49,20 +49,12 @@ Global
{91018B6D-A7A9-45BE-9CB3-79CBB8B169A6}.Release|x64.Build.0 = Release|x64 {91018B6D-A7A9-45BE-9CB3-79CBB8B169A6}.Release|x64.Build.0 = Release|x64
{B517E3D0-D03B-436F-AB03-34BA0D5321AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B517E3D0-D03B-436F-AB03-34BA0D5321AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B517E3D0-D03B-436F-AB03-34BA0D5321AF}.Debug|Any CPU.Build.0 = Debug|Any CPU {B517E3D0-D03B-436F-AB03-34BA0D5321AF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B517E3D0-D03B-436F-AB03-34BA0D5321AF}.Debug|x64.ActiveCfg = Debug|x64 {B517E3D0-D03B-436F-AB03-34BA0D5321AF}.Debug|x64.ActiveCfg = Debug|Any CPU
{B517E3D0-D03B-436F-AB03-34BA0D5321AF}.Debug|x64.Build.0 = Debug|x64 {B517E3D0-D03B-436F-AB03-34BA0D5321AF}.Debug|x64.Build.0 = Debug|Any CPU
{B517E3D0-D03B-436F-AB03-34BA0D5321AF}.Release|Any CPU.ActiveCfg = Release|Any CPU {B517E3D0-D03B-436F-AB03-34BA0D5321AF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B517E3D0-D03B-436F-AB03-34BA0D5321AF}.Release|Any CPU.Build.0 = Release|Any CPU {B517E3D0-D03B-436F-AB03-34BA0D5321AF}.Release|Any CPU.Build.0 = Release|Any CPU
{B517E3D0-D03B-436F-AB03-34BA0D5321AF}.Release|x64.ActiveCfg = Release|x64 {B517E3D0-D03B-436F-AB03-34BA0D5321AF}.Release|x64.ActiveCfg = Release|Any CPU
{B517E3D0-D03B-436F-AB03-34BA0D5321AF}.Release|x64.Build.0 = Release|x64 {B517E3D0-D03B-436F-AB03-34BA0D5321AF}.Release|x64.Build.0 = Release|Any CPU
{32231301-B0FB-4F9E-98DF-B3E8A88F4C16}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{32231301-B0FB-4F9E-98DF-B3E8A88F4C16}.Debug|Any CPU.Build.0 = Debug|Any CPU
{32231301-B0FB-4F9E-98DF-B3E8A88F4C16}.Debug|x64.ActiveCfg = Debug|x64
{32231301-B0FB-4F9E-98DF-B3E8A88F4C16}.Debug|x64.Build.0 = Debug|x64
{32231301-B0FB-4F9E-98DF-B3E8A88F4C16}.Release|Any CPU.ActiveCfg = Release|Any CPU
{32231301-B0FB-4F9E-98DF-B3E8A88F4C16}.Release|Any CPU.Build.0 = Release|Any CPU
{32231301-B0FB-4F9E-98DF-B3E8A88F4C16}.Release|x64.ActiveCfg = Release|x64
{32231301-B0FB-4F9E-98DF-B3E8A88F4C16}.Release|x64.Build.0 = Release|x64
{1FAC4205-4445-4F2B-BB8F-618E8A0C15FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1FAC4205-4445-4F2B-BB8F-618E8A0C15FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1FAC4205-4445-4F2B-BB8F-618E8A0C15FD}.Debug|Any CPU.Build.0 = Debug|Any CPU {1FAC4205-4445-4F2B-BB8F-618E8A0C15FD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1FAC4205-4445-4F2B-BB8F-618E8A0C15FD}.Debug|x64.ActiveCfg = Debug|x64 {1FAC4205-4445-4F2B-BB8F-618E8A0C15FD}.Debug|x64.ActiveCfg = Debug|x64
...@@ -79,18 +71,26 @@ Global ...@@ -79,18 +71,26 @@ Global
{4406CE17-9A39-4F28-8363-6169A4F799C1}.Release|Any CPU.Build.0 = Release|Any CPU {4406CE17-9A39-4F28-8363-6169A4F799C1}.Release|Any CPU.Build.0 = Release|Any CPU
{4406CE17-9A39-4F28-8363-6169A4F799C1}.Release|x64.ActiveCfg = Release|x64 {4406CE17-9A39-4F28-8363-6169A4F799C1}.Release|x64.ActiveCfg = Release|x64
{4406CE17-9A39-4F28-8363-6169A4F799C1}.Release|x64.Build.0 = Release|x64 {4406CE17-9A39-4F28-8363-6169A4F799C1}.Release|x64.Build.0 = Release|x64
{1D053D72-DCB4-4517-ACDD-D35ADC186950}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1D053D72-DCB4-4517-ACDD-D35ADC186950}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1D053D72-DCB4-4517-ACDD-D35ADC186950}.Debug|x64.ActiveCfg = Debug|Any CPU
{1D053D72-DCB4-4517-ACDD-D35ADC186950}.Debug|x64.Build.0 = Debug|Any CPU
{1D053D72-DCB4-4517-ACDD-D35ADC186950}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1D053D72-DCB4-4517-ACDD-D35ADC186950}.Release|Any CPU.Build.0 = Release|Any CPU
{1D053D72-DCB4-4517-ACDD-D35ADC186950}.Release|x64.ActiveCfg = Release|Any CPU
{1D053D72-DCB4-4517-ACDD-D35ADC186950}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
GlobalSection(NestedProjects) = preSolution GlobalSection(NestedProjects) = preSolution
{B517E3D0-D03B-436F-AB03-34BA0D5321AF} = {BC1E0789-D348-49CF-8B67-5E99D50EDF64} {B517E3D0-D03B-436F-AB03-34BA0D5321AF} = {BC1E0789-D348-49CF-8B67-5E99D50EDF64}
{32231301-B0FB-4F9E-98DF-B3E8A88F4C16} = {BC1E0789-D348-49CF-8B67-5E99D50EDF64}
{1FAC4205-4445-4F2B-BB8F-618E8A0C15FD} = {B6DBABDC-C985-4872-9C38-B4E5079CBC4B} {1FAC4205-4445-4F2B-BB8F-618E8A0C15FD} = {B6DBABDC-C985-4872-9C38-B4E5079CBC4B}
{4406CE17-9A39-4F28-8363-6169A4F799C1} = {B6DBABDC-C985-4872-9C38-B4E5079CBC4B} {4406CE17-9A39-4F28-8363-6169A4F799C1} = {B6DBABDC-C985-4872-9C38-B4E5079CBC4B}
{1D053D72-DCB4-4517-ACDD-D35ADC186950} = {BC1E0789-D348-49CF-8B67-5E99D50EDF64}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
EnterpriseLibraryConfigurationToolBinariesPath = .1.505.2\lib\NET35
SolutionGuid = {625C1EB5-44CF-47DE-A85A-B4C8C40ED90A} SolutionGuid = {625C1EB5-44CF-47DE-A85A-B4C8C40ED90A}
EnterpriseLibraryConfigurationToolBinariesPath = .1.505.2\lib\NET35
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal
...@@ -168,7 +168,7 @@ namespace Titanium.Web.Proxy ...@@ -168,7 +168,7 @@ namespace Titanium.Web.Proxy
string certName = HttpHelper.GetWildCardDomainName(connectHostname); string certName = HttpHelper.GetWildCardDomainName(connectHostname);
var certificate = endPoint.GenericCertificate ?? var certificate = endPoint.GenericCertificate ??
await CertificateManager.CreateCertificateAsync(certName); await CertificateManager.CreateServerCertificate(certName);
// Successfully managed to authenticate the client using the fake certificate // Successfully managed to authenticate the client using the fake certificate
var options = new SslServerAuthenticationOptions(); var options = new SslServerAuthenticationOptions();
...@@ -321,7 +321,7 @@ namespace Titanium.Web.Proxy ...@@ -321,7 +321,7 @@ namespace Titanium.Web.Proxy
calledRequestHandler = true; calledRequestHandler = true;
// Now create the request // Now create the request
await handleHttpSessionRequest(endPoint, clientConnection, clientStream, clientStreamWriter, await handleHttpSessionRequest(endPoint, clientConnection, clientStream, clientStreamWriter,
cancellationTokenSource, connectHostname, connectArgs?.HttpClient.ConnectRequest, prefetchConnectionTask); cancellationTokenSource, connectHostname, connectArgs, prefetchConnectionTask);
} }
catch (ProxyException e) catch (ProxyException e)
{ {
......
...@@ -432,11 +432,11 @@ namespace Titanium.Web.Proxy.Network ...@@ -432,11 +432,11 @@ namespace Titanium.Web.Proxy.Network
} }
/// <summary> /// <summary>
/// Create an SSL certificate async /// Creates a server certificate signed by the root certificate.
/// </summary> /// </summary>
/// <param name="certificateName"></param> /// <param name="certificateName"></param>
/// <returns></returns> /// <returns></returns>
internal async Task<X509Certificate2> CreateCertificateAsync(string certificateName) public async Task<X509Certificate2> CreateServerCertificate(string certificateName)
{ {
// check in cache first // check in cache first
if (cachedCertificates.TryGetValue(certificateName, out var cached)) if (cachedCertificates.TryGetValue(certificateName, out var cached))
......
...@@ -47,9 +47,11 @@ namespace Titanium.Web.Proxy ...@@ -47,9 +47,11 @@ namespace Titanium.Web.Proxy
/// <param name="prefetchConnectionTask">Prefetched server connection for current client using Connect/SNI headers.</param> /// <param name="prefetchConnectionTask">Prefetched server connection for current client using Connect/SNI headers.</param>
private async Task handleHttpSessionRequest(ProxyEndPoint endPoint, TcpClientConnection clientConnection, private async Task handleHttpSessionRequest(ProxyEndPoint endPoint, TcpClientConnection clientConnection,
CustomBufferedStream clientStream, HttpResponseWriter clientStreamWriter, CustomBufferedStream clientStream, HttpResponseWriter clientStreamWriter,
CancellationTokenSource cancellationTokenSource, string httpsConnectHostname, ConnectRequest connectRequest, CancellationTokenSource cancellationTokenSource, string httpsConnectHostname, TunnelConnectSessionEventArgs connectArgs,
Task<TcpServerConnection> prefetchConnectionTask = null) Task<TcpServerConnection> prefetchConnectionTask = null)
{ {
var connectRequest = connectArgs?.HttpClient.ConnectRequest;
var prefetchTask = prefetchConnectionTask; var prefetchTask = prefetchConnectionTask;
TcpServerConnection connection = null; TcpServerConnection connection = null;
bool closeServerConnection = false; bool closeServerConnection = false;
...@@ -73,7 +75,8 @@ namespace Titanium.Web.Proxy ...@@ -73,7 +75,8 @@ namespace Titanium.Web.Proxy
var args = new SessionEventArgs(this, endPoint, cancellationTokenSource) var args = new SessionEventArgs(this, endPoint, cancellationTokenSource)
{ {
ProxyClient = { Connection = clientConnection }, ProxyClient = { Connection = clientConnection },
HttpClient = { ConnectRequest = connectRequest } HttpClient = { ConnectRequest = connectRequest },
UserData = connectArgs?.UserData
}; };
try try
......
...@@ -34,10 +34,6 @@ namespace Titanium.Web.Proxy ...@@ -34,10 +34,6 @@ namespace Titanium.Web.Proxy
var clientStream = new CustomBufferedStream(clientConnection.GetStream(), BufferPool, BufferSize); var clientStream = new CustomBufferedStream(clientConnection.GetStream(), BufferPool, BufferSize);
var clientStreamWriter = new HttpResponseWriter(clientStream, BufferPool, BufferSize); var clientStreamWriter = new HttpResponseWriter(clientStream, BufferPool, BufferSize);
Task<TcpServerConnection> prefetchConnectionTask = null;
bool closeServerConnection = false;
bool calledRequestHandler = false;
try try
{ {
var clientHelloInfo = await SslTools.PeekClientHello(clientStream, BufferPool, cancellationToken); var clientHelloInfo = await SslTools.PeekClientHello(clientStream, BufferPool, cancellationToken);
...@@ -63,15 +59,6 @@ namespace Titanium.Web.Proxy ...@@ -63,15 +59,6 @@ namespace Titanium.Web.Proxy
if (endPoint.DecryptSsl && args.DecryptSsl) if (endPoint.DecryptSsl && args.DecryptSsl)
{ {
if(EnableTcpServerConnectionPrefetch)
{
//don't pass cancellation token here
//it could cause floating server connections when client exits
prefetchConnectionTask = tcpConnectionFactory.GetServerConnection(httpsHostName, endPoint.Port,
httpVersion: null, isHttps: true, applicationProtocols: null, isConnect: false,
proxyServer: this, session: null, upStreamEndPoint: UpStreamEndPoint, externalProxy: UpStreamHttpsProxy,
noCache: false, cancellationToken: CancellationToken.None);
}
SslStream sslStream = null; SslStream sslStream = null;
...@@ -82,7 +69,7 @@ namespace Titanium.Web.Proxy ...@@ -82,7 +69,7 @@ namespace Titanium.Web.Proxy
string certName = HttpHelper.GetWildCardDomainName(httpsHostName); string certName = HttpHelper.GetWildCardDomainName(httpsHostName);
var certificate = endPoint.GenericCertificate ?? var certificate = endPoint.GenericCertificate ??
await CertificateManager.CreateCertificateAsync(certName); await CertificateManager.CreateServerCertificate(certName);
// Successfully managed to authenticate the client using the fake certificate // Successfully managed to authenticate the client using the fake certificate
await sslStream.AuthenticateAsServerAsync(certificate, false, SslProtocols.Tls, false); await sslStream.AuthenticateAsServerAsync(certificate, false, SslProtocols.Tls, false);
...@@ -140,39 +127,29 @@ namespace Titanium.Web.Proxy ...@@ -140,39 +127,29 @@ namespace Titanium.Web.Proxy
return; return;
} }
} }
calledRequestHandler = true;
// HTTPS server created - we can now decrypt the client's traffic // HTTPS server created - we can now decrypt the client's traffic
// Now create the request // Now create the request
await handleHttpSessionRequest(endPoint, clientConnection, clientStream, clientStreamWriter, await handleHttpSessionRequest(endPoint, clientConnection, clientStream, clientStreamWriter,
cancellationTokenSource, isHttps ? httpsHostName : null, null, prefetchConnectionTask); cancellationTokenSource, isHttps ? httpsHostName : null, null, null);
} }
catch (ProxyException e) catch (ProxyException e)
{ {
closeServerConnection = true;
onException(clientStream, e); onException(clientStream, e);
} }
catch (IOException e) catch (IOException e)
{ {
closeServerConnection = true;
onException(clientStream, new Exception("Connection was aborted", e)); onException(clientStream, new Exception("Connection was aborted", e));
} }
catch (SocketException e) catch (SocketException e)
{ {
closeServerConnection = true;
onException(clientStream, new Exception("Could not connect", e)); onException(clientStream, new Exception("Could not connect", e));
} }
catch (Exception e) catch (Exception e)
{ {
closeServerConnection = true;
onException(clientStream, new Exception("Error occured in whilst handling the client", e)); onException(clientStream, new Exception("Error occured in whilst handling the client", e));
} }
finally finally
{ {
if (!calledRequestHandler)
{
await tcpConnectionFactory.Release(prefetchConnectionTask, closeServerConnection);
}
clientStream.Dispose(); clientStream.Dispose();
if (!cancellationTokenSource.IsCancellationRequested) if (!cancellationTokenSource.IsCancellationRequested)
......
@echo off
dotnet test "%APPVEYOR_BUILD_FOLDER%\tests\Titanium.Web.Proxy.IntegrationTests\Titanium.Web.Proxy.IntegrationTests.csproj" -c %CONFIGURATION%
dotnet test "%APPVEYOR_BUILD_FOLDER%\tests\Titanium.Web.Proxy.UnitTests\Titanium.Web.Proxy.UnitTests.csproj" -c %CONFIGURATION%
exit /B %errorlevel%
\ No newline at end of file
using System;
using System.Net;
using System.Net.Http;
namespace Titanium.Web.Proxy.IntegrationTests.Helpers
{
public static class TestHelper
{
public static HttpClient GetHttpClient(int localProxyPort,
bool enableBasicProxyAuthorization = false)
{
var proxy = new TestProxy($"http://localhost:{localProxyPort}", enableBasicProxyAuthorization);
var handler = new HttpClientHandler
{
Proxy = proxy,
UseProxy = true
};
return new HttpClient(handler);
}
public static HttpClient GetHttpClient()
{
return new HttpClient(new HttpClientHandler());
}
public class TestProxy : IWebProxy
{
public Uri ProxyUri { get; set; }
public ICredentials Credentials { get; set; }
public TestProxy(string proxyUri, bool enableAuthorization)
: this(new Uri(proxyUri))
{
if (enableAuthorization)
{
Credentials = new NetworkCredential("test", "Test56");
}
}
private TestProxy(Uri proxyUri)
{
this.ProxyUri = proxyUri;
}
public Uri GetProxy(Uri destination)
{
return this.ProxyUri;
}
public bool IsBypassed(Uri host)
{
return false;
}
}
}
}
using System;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Titanium.Web.Proxy.IntegrationTests
{
[TestClass]
public class HttpsTests
{
[TestMethod]
public async Task Can_Handle_Https_Request()
{
var testSuite = new TestSuite();
var server = testSuite.GetServer();
server.HandleRequest((context) =>
{
return context.Response.WriteAsync("I am server. I received your greetings.");
});
var proxy = testSuite.GetProxy();
var client = testSuite.GetClient(proxy);
var response = await client.PostAsync(new Uri(server.ListeningHttpsUrl),
new StringContent("hello server. I am a client."));
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
var body = await response.Content.ReadAsStringAsync();
Assert.AreEqual("I am server. I received your greetings.", body);
}
}
}
...@@ -2,9 +2,8 @@ ...@@ -2,9 +2,8 @@
using System.Net; using System.Net;
using System.Net.Http; using System.Net.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using Titanium.Web.Proxy.EventArguments;
using Titanium.Web.Proxy.Models;
namespace Titanium.Web.Proxy.IntegrationTests namespace Titanium.Web.Proxy.IntegrationTests
{ {
...@@ -12,61 +11,177 @@ namespace Titanium.Web.Proxy.IntegrationTests ...@@ -12,61 +11,177 @@ namespace Titanium.Web.Proxy.IntegrationTests
public class InterceptionTests public class InterceptionTests
{ {
[TestMethod] [TestMethod]
public async Task Can_Intercept_Post_Requests() public async Task Can_Intercept_Get_Requests()
{
var testSuite = new TestSuite();
var server = testSuite.GetServer();
server.HandleRequest((context) =>
{ {
string testUrl = "http://interceptthis.com"; return context.Response.WriteAsync("I am server. I received your greetings.");
});
using (var proxy = new ProxyTestController()) var proxy = testSuite.GetProxy();
proxy.BeforeRequest += async (sender, e) =>
{ {
using (var client = TestHelper.CreateHttpClient(testUrl, proxy.ListeningPort)) if (e.HttpClient.Request.Url.Contains("localhost"))
{ {
var response = await client.PostAsync(new Uri(testUrl), new StringContent("hello!")); e.Ok("<html><body>TitaniumWebProxy-Stopped!!</body></html>");
return;
}
await Task.FromResult(0);
};
var client = testSuite.GetClient(proxy);
var response = await client.GetAsync(new Uri(server.ListeningHttpUrl));
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
var body = await response.Content.ReadAsStringAsync(); var body = await response.Content.ReadAsStringAsync();
Assert.IsTrue(body.Contains("TitaniumWebProxy-Stopped!!")); Assert.IsTrue(body.Contains("TitaniumWebProxy-Stopped!!"));
} }
}
}
private class ProxyTestController : IDisposable [TestMethod]
public async Task Can_Intercept_Post_Requests()
{
var testSuite = new TestSuite();
var server = testSuite.GetServer();
server.HandleRequest((context) =>
{ {
private readonly ProxyServer proxyServer; return context.Response.WriteAsync("I am server. I received your greetings.");
public int ListeningPort => proxyServer.ProxyEndPoints[0].Port; });
public ProxyTestController() var proxy = testSuite.GetProxy();
proxy.BeforeRequest += async (sender, e) =>
{
if (e.HttpClient.Request.Url.Contains("localhost"))
{ {
proxyServer = new ProxyServer(); e.Ok("<html><body>TitaniumWebProxy-Stopped!!</body></html>");
var explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, 0, true); return;
proxyServer.AddEndPoint(explicitEndPoint); }
proxyServer.BeforeRequest += OnRequest;
proxyServer.Start(); await Task.FromResult(0);
};
var client = testSuite.GetClient(proxy);
var response = await client.PostAsync(new Uri(server.ListeningHttpUrl),
new StringContent("hello server. I am a client."));
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
var body = await response.Content.ReadAsStringAsync();
Assert.IsTrue(body.Contains("TitaniumWebProxy-Stopped!!"));
} }
public async Task OnRequest(object sender, SessionEventArgs e) [TestMethod]
public async Task Can_Intercept_Put_Requests()
{ {
if (e.HttpClient.Request.Url.Contains("interceptthis.com")) var testSuite = new TestSuite();
var server = testSuite.GetServer();
server.HandleRequest((context) =>
{
return context.Response.WriteAsync("I am server. I received your greetings.");
});
var proxy = testSuite.GetProxy();
proxy.BeforeRequest += async (sender, e) =>
{ {
if (e.HttpClient.Request.HasBody) if (e.HttpClient.Request.Url.Contains("localhost"))
{ {
var body = await e.GetRequestBodyAsString(); e.Ok("<html><body>TitaniumWebProxy-Stopped!!</body></html>");
return;
} }
await Task.FromResult(0);
};
var client = testSuite.GetClient(proxy);
var response = await client.PutAsync(new Uri(server.ListeningHttpUrl),
new StringContent("hello server. I am a client."));
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
var body = await response.Content.ReadAsStringAsync();
Assert.IsTrue(body.Contains("TitaniumWebProxy-Stopped!!"));
}
[TestMethod]
public async Task Can_Intercept_Patch_Requests()
{
var testSuite = new TestSuite();
var server = testSuite.GetServer();
server.HandleRequest((context) =>
{
return context.Response.WriteAsync("I am server. I received your greetings.");
});
var proxy = testSuite.GetProxy();
proxy.BeforeRequest += async (sender, e) =>
{
if (e.HttpClient.Request.Url.Contains("localhost"))
{
e.Ok("<html><body>TitaniumWebProxy-Stopped!!</body></html>"); e.Ok("<html><body>TitaniumWebProxy-Stopped!!</body></html>");
return; return;
} }
await Task.FromResult(0); await Task.FromResult(0);
};
var client = testSuite.GetClient(proxy);
var response = await client.PatchAsync(new Uri(server.ListeningHttpUrl),
new StringContent("hello server. I am a client."));
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
var body = await response.Content.ReadAsStringAsync();
Assert.IsTrue(body.Contains("TitaniumWebProxy-Stopped!!"));
} }
public void Dispose() [TestMethod]
public async Task Can_Intercept_Delete_Requests()
{ {
proxyServer.BeforeRequest -= OnRequest; var testSuite = new TestSuite();
proxyServer.Stop();
proxyServer.Dispose(); var server = testSuite.GetServer();
} server.HandleRequest((context) =>
{
return context.Response.WriteAsync("I am server. I received your greetings.");
});
var proxy = testSuite.GetProxy();
proxy.BeforeRequest += async (sender, e) =>
{
if (e.HttpClient.Request.Url.Contains("localhost"))
{
e.Ok("<html><body>TitaniumWebProxy-Stopped!!</body></html>");
return;
} }
await Task.FromResult(0);
};
var client = testSuite.GetClient(proxy);
var response = await client.DeleteAsync(new Uri(server.ListeningHttpUrl));
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
var body = await response.Content.ReadAsStringAsync();
Assert.IsTrue(body.Contains("TitaniumWebProxy-Stopped!!"));
}
} }
} }
\ No newline at end of file
using Microsoft.AspNetCore.Http;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
namespace Titanium.Web.Proxy.IntegrationTests
{
[TestClass]
public class NestedProxyTests
{
[TestMethod]
public async Task Smoke_Test_Nested_Proxy()
{
var testSuite = new TestSuite();
var server = testSuite.GetServer();
server.HandleRequest((context) =>
{
return context.Response.WriteAsync("I am server. I received your greetings.");
});
var proxy1 = testSuite.GetProxy();
var proxy2 = testSuite.GetProxy(proxy1);
var client = testSuite.GetClient(proxy2);
var response = await client.PostAsync(new Uri(server.ListeningHttpsUrl),
new StringContent("hello server. I am a client."));
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
var body = await response.Content.ReadAsStringAsync();
Assert.AreEqual("I am server. I received your greetings.", body);
}
[TestMethod]
public async Task Smoke_Test_Nested_Proxy_UserData()
{
var testSuite = new TestSuite();
var server = testSuite.GetServer();
server.HandleRequest((context) =>
{
return context.Response.WriteAsync("I am server. I received your greetings.");
});
var proxy1 = testSuite.GetProxy();
proxy1.ProxyBasicAuthenticateFunc = async (session, username, password) =>
{
session.UserData = "Test";
return await Task.FromResult(true);
};
var proxy2 = testSuite.GetProxy();
proxy1.GetCustomUpStreamProxyFunc = async (session) =>
{
Assert.AreEqual("Test", session.UserData);
return await Task.FromResult(new Models.ExternalProxy()
{
HostName = "localhost",
Port = proxy2.ProxyEndPoints[0].Port
});
};
var client = testSuite.GetClient(proxy1, true);
var response = await client.PostAsync(new Uri(server.ListeningHttpsUrl),
new StringContent("hello server. I am a client."));
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
var body = await response.Content.ReadAsStringAsync();
Assert.AreEqual("I am server. I received your greetings.", body);
}
}
}
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Titanium.Web.Proxy.IntegrationTests")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Titanium.Web.Proxy.IntegrationTests")]
[assembly: AssemblyCopyright("Copyright © Titanium 2015-2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("32231301-b0fb-4f9e-98df-b3e8a88f4c16")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
using Microsoft.AspNetCore.Http;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
namespace Titanium.Web.Proxy.IntegrationTests
{
[TestClass]
public class ReverseProxyTests
{
[TestMethod]
public async Task Smoke_Test_Http_To_Http_Reverse_Proxy()
{
var testSuite = new TestSuite();
var server = testSuite.GetServer();
server.HandleRequest((context) =>
{
return context.Response.WriteAsync("I am server. I received your greetings.");
});
var proxy = testSuite.GetReverseProxy();
proxy.BeforeRequest += async (sender, e) =>
{
e.HttpClient.Request.RequestUri = new Uri(server.ListeningHttpUrl);
await Task.FromResult(0);
};
var client = testSuite.GetReverseProxyClient();
var response = await client.PostAsync(new Uri($"http://localhost:{proxy.ProxyEndPoints[0].Port}"),
new StringContent("hello server. I am a client."));
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
var body = await response.Content.ReadAsStringAsync();
Assert.AreEqual("I am server. I received your greetings.", body);
}
[TestMethod]
public async Task Smoke_Test_Https_To_Http_Reverse_Proxy()
{
var testSuite = new TestSuite();
var server = testSuite.GetServer();
server.HandleRequest((context) =>
{
return context.Response.WriteAsync("I am server. I received your greetings.");
});
var proxy = testSuite.GetReverseProxy();
proxy.BeforeRequest += async (sender, e) =>
{
e.HttpClient.Request.RequestUri = new Uri(server.ListeningHttpUrl);
await Task.FromResult(0);
};
var client = testSuite.GetReverseProxyClient();
var response = await client.PostAsync(new Uri($"https://localhost:{proxy.ProxyEndPoints[0].Port}"),
new StringContent("hello server. I am a client."));
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
var body = await response.Content.ReadAsStringAsync();
Assert.AreEqual("I am server. I received your greetings.", body);
}
[TestMethod]
public async Task Smoke_Test_Http_To_Https_Reverse_Proxy()
{
var testSuite = new TestSuite();
var server = testSuite.GetServer();
server.HandleRequest((context) =>
{
return context.Response.WriteAsync("I am server. I received your greetings.");
});
var proxy = testSuite.GetReverseProxy();
proxy.BeforeRequest += async (sender, e) =>
{
e.HttpClient.Request.RequestUri = new Uri(server.ListeningHttpsUrl);
await Task.FromResult(0);
};
var client = testSuite.GetReverseProxyClient();
var response = await client.PostAsync(new Uri($"http://localhost:{proxy.ProxyEndPoints[0].Port}"),
new StringContent("hello server. I am a client."));
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
var body = await response.Content.ReadAsStringAsync();
Assert.AreEqual("I am server. I received your greetings.", body);
}
[TestMethod]
public async Task Smoke_Test_Https_To_Https_Reverse_Proxy()
{
var testSuite = new TestSuite();
var server = testSuite.GetServer();
server.HandleRequest((context) =>
{
return context.Response.WriteAsync("I am server. I received your greetings.");
});
var proxy = testSuite.GetReverseProxy();
proxy.BeforeRequest += async (sender, e) =>
{
e.HttpClient.Request.RequestUri = new Uri(server.ListeningHttpsUrl);
await Task.FromResult(0);
};
var client = testSuite.GetReverseProxyClient();
var response = await client.PostAsync(new Uri($"https://localhost:{proxy.ProxyEndPoints[0].Port}"),
new StringContent("hello server. I am a client."));
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
var body = await response.Content.ReadAsStringAsync();
Assert.AreEqual("I am server. I received your greetings.", body);
}
}
}
using System;
using System.Collections.Generic;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Titanium.Web.Proxy.EventArguments;
using Titanium.Web.Proxy.Models;
using Titanium.Web.Proxy.Network;
namespace Titanium.Web.Proxy.IntegrationTests.Setup
{
public class TestProxyServer : IDisposable
{
public ProxyServer ProxyServer { get; private set; }
public int ListeningPort => ProxyServer.ProxyEndPoints[0].Port;
public CertificateManager CertificateManager => ProxyServer.CertificateManager;
public TestProxyServer(bool isReverseProxy, ProxyServer upStreamProxy = null)
{
ProxyServer = new ProxyServer();
ProxyEndPoint explicitEndPoint = isReverseProxy ?
(ProxyEndPoint)new TransparentProxyEndPoint(IPAddress.Any, 0, true) :
new ExplicitProxyEndPoint(IPAddress.Any, 0, true);
ProxyServer.AddEndPoint(explicitEndPoint);
if (upStreamProxy != null)
{
ProxyServer.UpStreamHttpProxy = new ExternalProxy()
{
HostName = "localhost",
Port = upStreamProxy.ProxyEndPoints[0].Port
};
ProxyServer.UpStreamHttpsProxy = new ExternalProxy()
{
HostName = "localhost",
Port = upStreamProxy.ProxyEndPoints[0].Port
};
}
ProxyServer.Start();
}
public void Dispose()
{
ProxyServer.Stop();
ProxyServer.Dispose();
}
}
}
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Server.Features;
using Microsoft.AspNetCore.Http;
using System;
using Microsoft.Extensions.DependencyInjection;
using System.Linq;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
namespace Titanium.Web.Proxy.IntegrationTests.Setup
{
//set up a kestrel test server
public class TestServer : IDisposable
{
public string ListeningHttpUrl => $"http://localhost:{HttpListeningPort}";
public string ListeningHttpsUrl => $"https://localhost:{HttpsListeningPort}";
public int HttpListeningPort { get; private set; }
public int HttpsListeningPort { get; private set; }
private IWebHost host;
public TestServer(X509Certificate2 serverCertificate)
{
var startUp = new Startup(() => requestHandler);
host = WebHost.CreateDefaultBuilder()
.ConfigureServices(s =>
{
s.AddSingleton<IStartup>(startUp);
})
.UseKestrel(options =>
{
options.Listen(IPAddress.Loopback, 0);
options.Listen(IPAddress.Loopback, 0, listenOptions =>
{
listenOptions.UseHttps(serverCertificate);
});
})
.Build();
host.Start();
var addresses = host.ServerFeatures
.Get<IServerAddressesFeature>()
.Addresses.ToArray();
string httpAddress = addresses[0];
HttpListeningPort = int.Parse(httpAddress.Split(':')[2]);
string httpsAddress = addresses[1];
HttpsListeningPort = int.Parse(httpsAddress.Split(':')[2]);
}
Func<HttpContext, Task> requestHandler = null;
public void HandleRequest(Func<HttpContext, Task> requestHandler)
{
this.requestHandler = requestHandler;
}
public void Dispose()
{
host.StopAsync().Wait();
host.Dispose();
}
private class Startup : IStartup
{
Func<Func<HttpContext, Task>> requestHandler;
public Startup(Func<Func<HttpContext, Task>> requestHandler)
{
this.requestHandler = requestHandler;
}
public void Configure(IApplicationBuilder app)
{
app.Run(context =>
{
if (requestHandler == null)
{
throw new Exception("Test server not configured to handle request.");
}
return requestHandler()(context);
});
}
public IServiceProvider ConfigureServices(IServiceCollection services)
{
return services.BuildServiceProvider();
}
}
}
}
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using Titanium.Web.Proxy.IntegrationTests.Helpers;
using Titanium.Web.Proxy.IntegrationTests.Setup;
namespace Titanium.Web.Proxy.IntegrationTests
{
public class TestSuite
{
private TestServer server;
public TestSuite()
{
var dummyProxy = new ProxyServer();
var serverCertificate = dummyProxy.CertificateManager.CreateServerCertificate("localhost").Result;
server = new TestServer(serverCertificate);
}
public TestServer GetServer()
{
return server;
}
public ProxyServer GetProxy(ProxyServer upStreamProxy = null)
{
if (upStreamProxy != null)
{
return new TestProxyServer(false, upStreamProxy).ProxyServer;
}
return new TestProxyServer(false).ProxyServer;
}
public ProxyServer GetReverseProxy(ProxyServer upStreamProxy = null)
{
if (upStreamProxy != null)
{
return new TestProxyServer(true, upStreamProxy).ProxyServer;
}
return new TestProxyServer(true).ProxyServer;
}
public HttpClient GetClient(ProxyServer proxyServer, bool enableBasicProxyAuthorization = false)
{
return TestHelper.GetHttpClient(proxyServer.ProxyEndPoints[0].Port, enableBasicProxyAuthorization);
}
public HttpClient GetReverseProxyClient()
{
return TestHelper.GetHttpClient();
}
}
}
using System;
using System.Net;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Titanium.Web.Proxy.Models;
namespace Titanium.Web.Proxy.IntegrationTests
{
[TestClass]
public class SslTests
{
[TestMethod]
public async Task TestSsl()
{
string testUrl = "https://google.com";
using (var proxy = new ProxyTestController())
{
using (var client = TestHelper.CreateHttpClient(testUrl, proxy.ListeningPort))
{
var response = await client.GetAsync(new Uri(testUrl));
Assert.IsNotNull(response);
}
}
}
private class ProxyTestController : IDisposable
{
private readonly ProxyServer proxyServer;
public int ListeningPort => proxyServer.ProxyEndPoints[0].Port;
public ProxyTestController()
{
proxyServer = new ProxyServer();
var explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, 0, true);
proxyServer.AddEndPoint(explicitEndPoint);
proxyServer.Start();
}
public void Dispose()
{
proxyServer.Stop();
proxyServer.Dispose();
}
}
}
}
<?xml version="1.0" encoding="utf-8"?> <Project Sdk="Microsoft.NET.Sdk">
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <TargetFramework>netcoreapp2.2</TargetFramework>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{32231301-B0FB-4F9E-98DF-B3E8A88F4C16}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Titanium.Web.Proxy.IntegrationTests</RootNamespace>
<AssemblyName>Titanium.Web.Proxy.IntegrationTests</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
<IsCodedUITest>False</IsCodedUITest>
<TestProjectType>UnitTest</TestProjectType>
<TargetFrameworkProfile />
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Net.Http" />
</ItemGroup>
<Choose>
<When Condition="('$(VisualStudioVersion)' == '10.0' or '$(VisualStudioVersion)' == '') and '$(TargetFrameworkVersion)' == 'v3.5'">
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
</ItemGroup>
</When>
<Otherwise>
<ItemGroup> <ItemGroup>
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework" /> <None Include="..\..\.build\lib\rootCert.pfx" Link="rootCert.pfx">
</ItemGroup>
</Otherwise>
</Choose>
<ItemGroup>
<Compile Include="InterceptionTests.cs" />
<Compile Include="SslTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Utilities\TestHelper.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Titanium.Web.Proxy\Titanium.Web.Proxy.csproj">
<Project>{91018b6d-a7a9-45be-9cb3-79cbb8b169a6}</Project>
<Name>Titanium.Web.Proxy</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="..\..\.build\lib\rootCert.pfx">
<Link>rootCert.pfx</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
</ItemGroup> </ItemGroup>
<Choose>
<When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'"> <ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Https" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
<PackageReference Include="MSTest.TestAdapter" Version="1.4.0" />
<PackageReference Include="MSTest.TestFramework" Version="1.4.0" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Microsoft.VisualStudio.QualityTools.CodedUITestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> <ProjectReference Include="..\..\src\Titanium.Web.Proxy\Titanium.Web.Proxy.csproj" />
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Extension, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestTools.UITesting, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
</ItemGroup> </ItemGroup>
</When>
</Choose>
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project> </Project>
using System.Net;
using System.Net.Http;
namespace Titanium.Web.Proxy.IntegrationTests
{
public static class TestHelper
{
public static HttpClient CreateHttpClient(string url, int localProxyPort)
{
var handler = new HttpClientHandler
{
Proxy = new WebProxy($"http://localhost:{localProxyPort}", false),
UseProxy = true
};
return new HttpClient(handler);
}
}
}
...@@ -45,10 +45,9 @@ namespace Titanium.Web.Proxy.UnitTests ...@@ -45,10 +45,9 @@ namespace Titanium.Web.Proxy.UnitTests
} }
// uncomment this to compare WinCert maker performance with BC (BC takes more time for same test above) // uncomment this to compare WinCert maker performance with BC (BC takes more time for same test above)
[TestMethod] //[TestMethod]
public async Task Simple_Create_Win_Certificate_Test() public async Task Simple_Create_Win_Certificate_Test()
{ {
var tasks = new List<Task>(); var tasks = new List<Task>();
var mgr = new CertificateManager(null, null, false, false, false, new Lazy<ExceptionHandler>(() => (e => var mgr = new CertificateManager(null, null, false, false, false, new Lazy<ExceptionHandler>(() => (e =>
......
...@@ -4,11 +4,7 @@ using System.Runtime.InteropServices; ...@@ -4,11 +4,7 @@ using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following // General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information // set of attributes. Change these attribute values to modify the information
// associated with an assembly. // associated with an assembly.
[assembly: AssemblyTitle("Titanium.Web.Proxy.UnitTests")]
[assembly: AssemblyDescription("")] [assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Titanium.Web.Proxy.UnitTests")]
[assembly: AssemblyCopyright("Copyright © Titanium 2015-2017")] [assembly: AssemblyCopyright("Copyright © Titanium 2015-2017")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
...@@ -20,16 +16,3 @@ using System.Runtime.InteropServices; ...@@ -20,16 +16,3 @@ using System.Runtime.InteropServices;
// The following GUID is for the ID of the typelib if this project is exposed to COM // The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("b517e3d0-d03b-436f-ab03-34ba0d5321af")] [assembly: Guid("b517e3d0-d03b-436f-ab03-34ba0d5321af")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
<?xml version="1.0" encoding="utf-8"?> <Project Sdk="Microsoft.NET.Sdk">
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{B517E3D0-D03B-436F-AB03-34BA0D5321AF}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Titanium.Web.Proxy.UnitTests</RootNamespace>
<AssemblyName>Titanium.Web.Proxy.UnitTests</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
<IsCodedUITest>False</IsCodedUITest>
<TestProjectType>UnitTest</TestProjectType>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup> <PropertyGroup>
<TargetFramework>net45</TargetFramework>
<SignAssembly>true</SignAssembly> <SignAssembly>true</SignAssembly>
</PropertyGroup>
<PropertyGroup>
<AssemblyOriginatorKeyFile>StrongNameKey.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>StrongNameKey.snk</AssemblyOriginatorKeyFile>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
</ItemGroup>
<Choose>
<When Condition="('$(VisualStudioVersion)' == '10.0' or '$(VisualStudioVersion)' == '') and '$(TargetFrameworkVersion)' == 'v3.5'">
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
</ItemGroup>
</When>
<Otherwise>
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework" />
</ItemGroup>
</Otherwise>
</Choose>
<ItemGroup>
<Compile Include="CertificateManagerTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ProxyServerTests.cs" />
<Compile Include="SystemProxyTest.cs" />
<Compile Include="WinAuthTests.cs" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="StrongNameKey.snk" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
<PackageReference Include="MSTest.TestAdapter" Version="1.4.0" />
<PackageReference Include="MSTest.TestFramework" Version="1.4.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\src\Titanium.Web.Proxy\Titanium.Web.Proxy.csproj"> <ProjectReference Include="..\..\src\Titanium.Web.Proxy\Titanium.Web.Proxy.csproj" />
<Project>{91018b6d-a7a9-45be-9cb3-79cbb8b169a6}</Project>
<Name>Titanium.Web.Proxy</Name>
</ProjectReference>
</ItemGroup> </ItemGroup>
<Choose>
<When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'">
<ItemGroup> <ItemGroup>
<Reference Include="Microsoft.VisualStudio.QualityTools.CodedUITestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> <Folder Include="Properties\" />
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Extension, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestTools.UITesting, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
</ItemGroup> </ItemGroup>
</When>
</Choose>
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project> </Project>
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