Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
T
Titanium-Web-Proxy
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
Titanium-Web-Proxy
Commits
b6140f19
Commit
b6140f19
authored
Sep 23, 2017
by
Honfika
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
multi-target csproj
parent
65983798
Hide whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
947 additions
and
1186 deletions
+947
-1186
default.ps1
.build/default.ps1
+8
-16
README.md
README.md
+1
-1
Titanium.Web.Proxy.Standard.sln
Titanium.Web.Proxy.Standard.sln
+0
-58
Firefox.cs
Titanium.Web.Proxy/Helpers/Firefox.cs
+3
-1
NativeMethods.SystemProxy.cs
Titanium.Web.Proxy/Helpers/NativeMethods.SystemProxy.cs
+4
-2
NativeMethods.Tcp.cs
Titanium.Web.Proxy/Helpers/NativeMethods.Tcp.cs
+3
-1
ProxyInfo.cs
Titanium.Web.Proxy/Helpers/ProxyInfo.cs
+3
-1
RunTime.cs
Titanium.Web.Proxy/Helpers/RunTime.cs
+3
-1
SystemProxy.cs
Titanium.Web.Proxy/Helpers/SystemProxy.cs
+3
-1
NativeMethods.WinHttp.cs
Titanium.Web.Proxy/Helpers/WinHttp/NativeMethods.WinHttp.cs
+3
-1
WinHttpHandle.cs
Titanium.Web.Proxy/Helpers/WinHttp/WinHttpHandle.cs
+2
-0
WinHttpWebProxyFinder.cs
Titanium.Web.Proxy/Helpers/WinHttp/WinHttpWebProxyFinder.cs
+2
-0
WinCertificateMaker.cs
...nium.Web.Proxy/Network/Certificate/WinCertificateMaker.cs
+3
-1
TcpRow.cs
Titanium.Web.Proxy/Network/Tcp/TcpRow.cs
+3
-1
TcpTable.cs
Titanium.Web.Proxy/Network/Tcp/TcpTable.cs
+3
-1
Common.cs
Titanium.Web.Proxy/Network/WinAuth/Security/Common.cs
+3
-1
LittleEndian.cs
Titanium.Web.Proxy/Network/WinAuth/Security/LittleEndian.cs
+2
-0
Message.cs
Titanium.Web.Proxy/Network/WinAuth/Security/Message.cs
+2
-0
State.cs
Titanium.Web.Proxy/Network/WinAuth/Security/State.cs
+3
-1
WinAuthEndPoint.cs
...ium.Web.Proxy/Network/WinAuth/Security/WinAuthEndPoint.cs
+3
-1
WinAuthHandler.cs
Titanium.Web.Proxy/Network/WinAuth/WinAuthHandler.cs
+3
-1
ProxyServer.cs
Titanium.Web.Proxy/ProxyServer.cs
+868
-868
RequestHandler.cs
Titanium.Web.Proxy/RequestHandler.cs
+0
-1
Titanium.Web.Proxy.Standard.csproj
Titanium.Web.Proxy/Titanium.Web.Proxy.Standard.csproj
+0
-47
Titanium.Web.Proxy.csproj
Titanium.Web.Proxy/Titanium.Web.Proxy.csproj
+11
-174
Titanium.Web.Proxy.nuspec
Titanium.Web.Proxy/Titanium.Web.Proxy.nuspec
+5
-5
WinAuthHandler.cs
Titanium.Web.Proxy/WinAuthHandler.cs
+3
-1
No files found.
.build/default.ps1
View file @
b6140f19
...
...
@@ -6,8 +6,7 @@ $SolutionRoot = (Split-Path -parent $Here)
$ProjectName
=
"Titanium.Web.Proxy"
$SolutionFile14
=
"
$SolutionRoot
\
$ProjectName
.sln"
$SolutionFile
=
"
$SolutionRoot
\
$ProjectName
.Standard.sln"
$SolutionFile
=
"
$SolutionRoot
\
$ProjectName
.sln"
## This comes from the build server iteration
if
(!
$BuildNumber
)
{
$BuildNumber
=
$env
:APPVEYOR_BUILD_NUMBER
}
...
...
@@ -29,8 +28,6 @@ Import-Module "$Here\Common" -DisableNameChecking
$NuGet
=
Join-Path
$SolutionRoot
".nuget\nuget.exe"
$MSBuild14
=
"
${
env
:ProgramFiles
(x86)
}
\MSBuild\14.0\Bin\msbuild.exe"
$MSBuild
=
"
${
env
:ProgramFiles
(x86)
}
\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\msbuild.exe"
$MSBuild
-replace
' '
,
'` '
...
...
@@ -40,32 +37,27 @@ FormatTaskName (("-"*25) + "[{0}]" + ("-"*25))
Task default -depends Clean, Build, Package
Task Build -depends Restore-Packages
{
exec
{
.
$MSBuild14
$SolutionFile14
/t:Build /v:normal /p:Configuration
=
$Configuration
}
exec
{
.
$MSBuild
$SolutionFile
/t:Build /v:normal /p:Configuration
=
$Configuration
/t:restore
}
}
Task Package -depends Build
{
exec
{
.
$NuGet
pack
"
$SolutionRoot
\Titanium.Web.Proxy\Titanium.Web.Proxy.nuspec"
-Properties
Configuration
=
$Configuration
-OutputDirectory
"
$SolutionRoot
"
-Version
"
$Version
"
}
exec
{
.
$NuGet
pack
"
$SolutionRoot
\Titanium.Web.Proxy\Titanium.Web.Proxy.nuspec"
-Properties
Configuration
=
$Configuration
-OutputDirectory
"
$SolutionRoot
"
-Version
"
$Version
"
}
}
Task Clean -depends Install-BuildTools
{
Get-ChildItem
.\ -include bin,obj -Recurse |
foreach
(
$_
)
{
Remove-Item
$_
.fullname -Force -Recurse
}
exec
{
.
$MSBuild14
$SolutionFile14
/t:Clean /v:quiet
}
exec
{
.
$MSBuild
$SolutionFile
/t:Clean /v:quiet
}
Get-ChildItem
.\ -include bin,obj -Recurse |
foreach
(
$_
)
{
Remove-Item
$_
.fullname -Force -Recurse
}
exec
{
.
$MSBuild
$SolutionFile
/t:Clean /v:quiet
}
}
Task Restore-Packages
{
exec
{
.
dotnet restore
"
$SolutionRoot
\Titanium.Web.Proxy.sln"
}
exec
{
.
dotnet restore
"
$SolutionRoot
\Titanium.Web.Proxy.Standard.sln"
}
exec
{
.
dotnet restore
"
$SolutionRoot
\Titanium.Web.Proxy.sln"
}
}
Task Install-MSBuild
{
if
(!(
Test-Path
$MSBuild14
))
{
cinst microsoft-build-tools -y
}
{
cinst microsoft-build-tools -y
}
}
Task Install-BuildTools -depends Install-MSBuild
\ No newline at end of file
README.md
View file @
b6140f19
...
...
@@ -45,7 +45,7 @@ For stable releases on [stable branch](https://github.com/justcoding121/Titanium
Supports
*
.Net Standard
1.6
or above
*
.Net Standard
2.0
or above
*
.Net Framework 4.5 or above
Setup HTTP proxy:
...
...
Titanium.Web.Proxy.Standard.sln
deleted
100644 → 0
View file @
65983798
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26430.14
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{B6DBABDC-C985-4872-9C38-B4E5079CBC4B}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{6FD3B84B-9283-4E9C-8C43-A234E9AA3EAA}"
ProjectSection(SolutionItems) = preProject
.nuget\NuGet.Config = .nuget\NuGet.Config
.nuget\NuGet.exe = .nuget\NuGet.exe
.nuget\NuGet.targets = .nuget\NuGet.targets
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Documentation", "Documentation", "{38EA62D0-D2CB-465D-AF4F-407C5B4D4A1E}"
ProjectSection(SolutionItems) = preProject
LICENSE = LICENSE
README.md = README.md
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{AC9AE37A-3059-4FDB-9A5C-363AD86F2EEF}"
ProjectSection(SolutionItems) = preProject
.build\Bootstrap.ps1 = .build\Bootstrap.ps1
.build\Common.psm1 = .build\Common.psm1
.build\default.ps1 = .build\default.ps1
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{BC1E0789-D348-49CF-8B67-5E99D50EDF64}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Titanium.Web.Proxy.Standard", "Titanium.Web.Proxy\Titanium.Web.Proxy.Standard.csproj", "{9F983536-C482-4BA0-BEE9-C59FC4221F76}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Titanium.Web.Proxy.Examples.Basic.Standard", "Examples\Titanium.Web.Proxy.Examples.Basic.Standard\Titanium.Web.Proxy.Examples.Basic.Standard.csproj", "{EEE97BBC-6898-41DE-B97B-BE0157A816CD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{9F983536-C482-4BA0-BEE9-C59FC4221F76}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9F983536-C482-4BA0-BEE9-C59FC4221F76}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9F983536-C482-4BA0-BEE9-C59FC4221F76}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9F983536-C482-4BA0-BEE9-C59FC4221F76}.Release|Any CPU.Build.0 = Release|Any CPU
{EEE97BBC-6898-41DE-B97B-BE0157A816CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EEE97BBC-6898-41DE-B97B-BE0157A816CD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EEE97BBC-6898-41DE-B97B-BE0157A816CD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EEE97BBC-6898-41DE-B97B-BE0157A816CD}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{EEE97BBC-6898-41DE-B97B-BE0157A816CD} = {B6DBABDC-C985-4872-9C38-B4E5079CBC4B}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EnterpriseLibraryConfigurationToolBinariesPath = .1.505.2\lib\NET35
EndGlobalSection
EndGlobal
Titanium.Web.Proxy/Helpers/Firefox.cs
View file @
b6140f19
using
System
;
#
if
NET45
using
System
;
using
System.IO
;
namespace
Titanium.Web.Proxy.Helpers
...
...
@@ -50,3 +51,4 @@ namespace Titanium.Web.Proxy.Helpers
}
}
}
#endif
Titanium.Web.Proxy/Helpers/NativeMethods.SystemProxy.cs
View file @
b6140f19
using
System
;
#
if
NET45
using
System
;
using
System.Runtime.InteropServices
;
namespace
Titanium.Web.Proxy.Helpers
...
...
@@ -20,4 +21,5 @@ namespace Titanium.Web.Proxy.Helpers
// Pinvoke
internal
delegate
bool
ConsoleEventDelegate
(
int
eventType
);
}
}
\ No newline at end of file
}
#endif
Titanium.Web.Proxy/Helpers/NativeMethods.Tcp.cs
View file @
b6140f19
#if NET45
using
System
;
using
System.Net.NetworkInformation
;
using
System.Runtime.InteropServices
;
...
...
@@ -58,4 +59,5 @@ namespace Titanium.Web.Proxy.Helpers
[
DllImport
(
"iphlpapi.dll"
,
SetLastError
=
true
)]
internal
static
extern
uint
GetExtendedTcpTable
(
IntPtr
tcpTable
,
ref
int
size
,
bool
sort
,
int
ipVersion
,
int
tableClass
,
int
reserved
);
}
}
\ No newline at end of file
}
#endif
Titanium.Web.Proxy/Helpers/ProxyInfo.cs
View file @
b6140f19
using
System
;
#
if
NET45
using
System
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Text
;
...
...
@@ -198,3 +199,4 @@ namespace Titanium.Web.Proxy.Helpers
}
}
}
#endif
Titanium.Web.Proxy/Helpers/RunTime.cs
View file @
b6140f19
using
System
;
#
if
NET45
using
System
;
namespace
Titanium.Web.Proxy.Helpers
{
...
...
@@ -19,3 +20,4 @@ namespace Titanium.Web.Proxy.Helpers
internal
static
bool
IsRunningOnMono
=>
isRunningOnMono
.
Value
;
}
}
#endif
Titanium.Web.Proxy/Helpers/SystemProxy.cs
View file @
b6140f19
using
System
;
#
if
NET45
using
System
;
using
System.Linq
;
using
Microsoft.Win32
;
...
...
@@ -327,3 +328,4 @@ namespace Titanium.Web.Proxy.Helpers
}
}
}
#endif
Titanium.Web.Proxy/Helpers/WinHttp/NativeMethods.WinHttp.cs
View file @
b6140f19
using
System
;
#
if
NET45
using
System
;
using
System.Runtime.InteropServices
;
// Helper classes for setting system proxy settings
...
...
@@ -130,3 +131,4 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
}
}
}
#endif
Titanium.Web.Proxy/Helpers/WinHttp/WinHttpHandle.cs
View file @
b6140f19
#if NET45
using
System
;
using
System.Runtime.InteropServices
;
...
...
@@ -17,3 +18,4 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
public
override
bool
IsInvalid
=>
handle
==
IntPtr
.
Zero
;
}
}
#endif
Titanium.Web.Proxy/Helpers/WinHttp/WinHttpWebProxyFinder.cs
View file @
b6140f19
#if NET45
using
System
;
using
System.Collections.Generic
;
using
System.Net
;
...
...
@@ -330,3 +331,4 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
}
}
}
#endif
Titanium.Web.Proxy/Network/Certificate/WinCertificateMaker.cs
View file @
b6140f19
using
System
;
#
if
NET45
using
System
;
using
System.Reflection
;
using
System.Security.Cryptography.X509Certificates
;
using
System.Threading
;
...
...
@@ -296,3 +297,4 @@ namespace Titanium.Web.Proxy.Network.Certificate
}
}
}
#endif
Titanium.Web.Proxy/Network/Tcp/TcpRow.cs
View file @
b6140f19
using
System.Net
;
#
if
NET45
using
System.Net
;
using
Titanium.Web.Proxy.Extensions
;
using
Titanium.Web.Proxy.Helpers
;
...
...
@@ -61,3 +62,4 @@ namespace Titanium.Web.Proxy.Network.Tcp
internal
int
ProcessId
{
get
;
}
}
}
#endif
Titanium.Web.Proxy/Network/Tcp/TcpTable.cs
View file @
b6140f19
using
System.Collections
;
#
if
NET45
using
System.Collections
;
using
System.Collections.Generic
;
namespace
Titanium.Web.Proxy.Network.Tcp
...
...
@@ -44,3 +45,4 @@ namespace Titanium.Web.Proxy.Network.Tcp
}
}
}
#endif
Titanium.Web.Proxy/Network/WinAuth/Security/Common.cs
View file @
b6140f19
using
System
;
#
if
NET45
using
System
;
using
System.Runtime.InteropServices
;
namespace
Titanium.Web.Proxy.Network.WinAuth.Security
...
...
@@ -280,3 +281,4 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
#
endregion
}
}
#endif
Titanium.Web.Proxy/Network/WinAuth/Security/LittleEndian.cs
View file @
b6140f19
#if NET45
//
// Mono.Security.BitConverterLE.cs
// Like System.BitConverter but always little endian
...
...
@@ -250,3 +251,4 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
}
}
}
#endif
Titanium.Web.Proxy/Network/WinAuth/Security/Message.cs
View file @
b6140f19
#if NET45
//
// Nancy.Authentication.Ntlm.Protocol.Type3Message - Authentication
//
...
...
@@ -128,3 +129,4 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
}
}
}
#endif
Titanium.Web.Proxy/Network/WinAuth/Security/State.cs
View file @
b6140f19
using
System
;
#
if
NET45
using
System
;
namespace
Titanium.Web.Proxy.Network.WinAuth.Security
{
...
...
@@ -42,3 +43,4 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
}
}
}
#endif
Titanium.Web.Proxy/Network/WinAuth/Security/WinAuthEndPoint.cs
View file @
b6140f19
// http://pinvoke.net/default.aspx/secur32/InitializeSecurityContext.html
#
if
NET45
// http://pinvoke.net/default.aspx/secur32/InitializeSecurityContext.html
using
System
;
using
System.Collections.Concurrent
;
...
...
@@ -211,3 +212,4 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
#
endregion
}
}
#endif
Titanium.Web.Proxy/Network/WinAuth/WinAuthHandler.cs
View file @
b6140f19
using
System
;
#
if
NET45
using
System
;
using
Titanium.Web.Proxy.Network.WinAuth.Security
;
namespace
Titanium.Web.Proxy.Network.WinAuth
...
...
@@ -40,3 +41,4 @@ namespace Titanium.Web.Proxy.Network.WinAuth
}
}
}
#endif
Titanium.Web.Proxy/ProxyServer.cs
View file @
b6140f19
using
StreamExtended.Network
;
using
System
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Net
;
using
System.Net.Sockets
;
using
System.Security.Authentication
;
using
System.Security.Cryptography.X509Certificates
;
using
System.Threading
;
using
System.Threading.Tasks
;
using
Titanium.Web.Proxy.EventArguments
;
using
Titanium.Web.Proxy.Extensions
;
using
Titanium.Web.Proxy.Helpers
;
#if NET45
using
Titanium.Web.Proxy.Helpers.WinHttp
;
#endif
using
Titanium.Web.Proxy.Models
;
using
Titanium.Web.Proxy.Network
;
using
Titanium.Web.Proxy.Network.Tcp
;
#if NET45
using
Titanium.Web.Proxy.Network.WinAuth.Security
;
#endif
namespace
Titanium.Web.Proxy
{
/// <summary>
/// Proxy Server Main class
/// </summary>
public
partial
class
ProxyServer
:
IDisposable
{
#if NET45
internal
static
readonly
string
UriSchemeHttp
=
Uri
.
UriSchemeHttp
;
internal
static
readonly
string
UriSchemeHttps
=
Uri
.
UriSchemeHttps
;
#else
internal
const
string
UriSchemeHttp
=
"http"
;
internal
const
string
UriSchemeHttps
=
"https"
;
#endif
/// <summary>
/// Is the proxy currently running
/// </summary>
private
bool
proxyRunning
{
get
;
set
;
}
/// <summary>
/// An default exception log func
/// </summary>
private
readonly
Lazy
<
Action
<
Exception
>>
defaultExceptionFunc
=
new
Lazy
<
Action
<
Exception
>>(()
=>
(
e
=>
{
}));
/// <summary>
/// backing exception func for exposed public property
/// </summary>
private
Action
<
Exception
>
exceptionFunc
;
/// <summary>
/// Backing field for corresponding public property
/// </summary>
private
bool
trustRootCertificate
;
/// <summary>
/// Backing field for corresponding public property
/// </summary>
private
int
clientConnectionCount
;
/// <summary>
/// Backing field for corresponding public property
/// </summary>
private
int
serverConnectionCount
;
/// <summary>
/// A object that creates tcp connection to server
/// </summary>
private
TcpConnectionFactory
tcpConnectionFactory
{
get
;
}
#if NET45
private
WinHttpWebProxyFinder
systemProxyResolver
;
/// <summary>
/// Manage system proxy settings
/// </summary>
private
SystemProxyManager
systemProxySettingsManager
{
get
;
}
/// <summary>
/// Set firefox to use default system proxy
/// </summary>
private
readonly
FireFoxProxySettingsManager
firefoxProxySettingsManager
=
new
FireFoxProxySettingsManager
();
#endif
/// <summary>
/// Buffer size used throughout this proxy
/// </summary>
public
int
BufferSize
{
get
;
set
;
}
=
8192
;
/// <summary>
/// Manages certificates used by this proxy
/// </summary>
public
CertificateManager
CertificateManager
{
get
;
}
/// <summary>
/// The root certificate
/// </summary>
public
X509Certificate2
RootCertificate
{
get
{
return
CertificateManager
.
RootCertificate
;
}
set
{
CertificateManager
.
RootCertificate
=
value
;
}
}
/// <summary>
/// Name of the root certificate issuer
/// (This is valid only when RootCertificate property is not set)
/// </summary>
public
string
RootCertificateIssuerName
{
get
{
return
CertificateManager
.
Issuer
;
}
set
{
CertificateManager
.
Issuer
=
value
;
}
}
/// <summary>
/// Name of the root certificate
/// (This is valid only when RootCertificate property is not set)
/// If no certificate is provided then a default Root Certificate will be created and used
/// The provided root certificate will be stored in proxy exe directory with the private key
/// Root certificate file will be named as "rootCert.pfx"
/// </summary>
public
string
RootCertificateName
{
get
{
return
CertificateManager
.
RootCertificateName
;
}
set
{
CertificateManager
.
RootCertificateName
=
value
;
}
}
/// <summary>
/// Trust the RootCertificate used by this proxy server
/// Note that this do not make the client trust the certificate!
/// This would import the root certificate to the certificate store of machine that runs this proxy server
/// </summary>
public
bool
TrustRootCertificate
{
get
{
return
trustRootCertificate
;
}
set
{
trustRootCertificate
=
value
;
if
(
value
)
{
EnsureRootCertificate
();
}
}
}
/// <summary>
/// Select Certificate Engine
/// Optionally set to BouncyCastle
/// Mono only support BouncyCastle and it is the default
/// </summary>
public
CertificateEngine
CertificateEngine
{
get
{
return
CertificateManager
.
Engine
;
}
set
{
CertificateManager
.
Engine
=
value
;
}
}
/// <summary>
/// Should we check for certificare revocation during SSL authentication to servers
/// Note: If enabled can reduce performance (Default disabled)
/// </summary>
public
bool
CheckCertificateRevocation
{
get
;
set
;
}
/// <summary>
/// Does this proxy uses the HTTP protocol 100 continue behaviour strictly?
/// Broken 100 contunue implementations on server/client may cause problems if enabled
/// </summary>
public
bool
Enable100ContinueBehaviour
{
get
;
set
;
}
/// <summary>
/// Minutes certificates should be kept in cache when not used
/// </summary>
public
int
CertificateCacheTimeOutMinutes
{
get
;
set
;
}
/// <summary>
/// Seconds client/server connection are to be kept alive when waiting for read/write to complete
/// </summary>
public
int
ConnectionTimeOutSeconds
{
get
;
set
;
}
/// <summary>
/// Intercept request to server
/// </summary>
public
event
Func
<
object
,
SessionEventArgs
,
Task
>
BeforeRequest
;
/// <summary>
/// Intercept response from server
/// </summary>
public
event
Func
<
object
,
SessionEventArgs
,
Task
>
BeforeResponse
;
/// <summary>
/// Intercept tunnel connect reques
/// </summary>
public
event
Func
<
object
,
TunnelConnectSessionEventArgs
,
Task
>
TunnelConnectRequest
;
/// <summary>
/// Intercept tunnel connect response
/// </summary>
public
event
Func
<
object
,
TunnelConnectSessionEventArgs
,
Task
>
TunnelConnectResponse
;
/// <summary>
/// Occurs when client connection count changed.
/// </summary>
public
event
EventHandler
ClientConnectionCountChanged
;
/// <summary>
/// Occurs when server connection count changed.
/// </summary>
public
event
EventHandler
ServerConnectionCountChanged
;
/// <summary>
/// External proxy for Http
/// </summary>
public
ExternalProxy
UpStreamHttpProxy
{
get
;
set
;
}
/// <summary>
/// External proxy for Http
/// </summary>
public
ExternalProxy
UpStreamHttpsProxy
{
get
;
set
;
}
/// <summary>
/// Local adapter/NIC endpoint (where proxy makes request via)
/// default via any IP addresses of this machine
/// </summary>
public
IPEndPoint
UpStreamEndPoint
{
get
;
set
;
}
=
new
IPEndPoint
(
IPAddress
.
Any
,
0
);
/// <summary>
/// Is the proxy currently running
/// </summary>
public
bool
ProxyRunning
=>
proxyRunning
;
/// <summary>
/// Gets or sets a value indicating whether requests will be chained to upstream gateway.
/// </summary>
public
bool
ForwardToUpstreamGateway
{
get
;
set
;
}
/// <summary>
/// Enable disable Windows Authentication (NTLM/Kerberos)
/// Note: NTLM/Kerberos will always send local credentials of current user
/// who is running the proxy process. This is because a man
/// in middle attack is not currently supported
/// (which would require windows delegation enabled for this server process)
/// </summary>
public
bool
EnableWinAuth
{
get
;
set
;
}
/// <summary>
/// Verifies the remote Secure Sockets Layer (SSL) certificate used for authentication
/// </summary>
public
event
Func
<
object
,
CertificateValidationEventArgs
,
Task
>
ServerCertificateValidationCallback
;
/// <summary>
/// Callback tooverride client certificate during SSL mutual authentication
/// </summary>
public
event
Func
<
object
,
CertificateSelectionEventArgs
,
Task
>
ClientCertificateSelectionCallback
;
/// <summary>
/// Callback for error events in proxy
/// </summary>
public
Action
<
Exception
>
ExceptionFunc
{
get
{
return
exceptionFunc
??
defaultExceptionFunc
.
Value
;
}
set
{
exceptionFunc
=
value
;
}
}
/// <summary>
/// A callback to authenticate clients
/// Parameters are username, password provided by client
/// return true for successful authentication
/// </summary>
public
Func
<
string
,
string
,
Task
<
bool
>>
AuthenticateUserFunc
{
get
;
set
;
}
/// <summary>
/// Realm used during Proxy Basic Authentication
/// </summary>
public
string
ProxyRealm
{
get
;
set
;
}
=
"TitaniumProxy"
;
/// <summary>
/// A callback to provide authentication credentials for up stream proxy this proxy is using for HTTP requests
/// return the ExternalProxy object with valid credentials
/// </summary>
public
Func
<
SessionEventArgs
,
Task
<
ExternalProxy
>>
GetCustomUpStreamHttpProxyFunc
{
get
;
set
;
}
/// <summary>
/// A callback to provide authentication credentials for up stream proxy this proxy is using for HTTPS requests
/// return the ExternalProxy object with valid credentials
/// </summary>
public
Func
<
SessionEventArgs
,
Task
<
ExternalProxy
>>
GetCustomUpStreamHttpsProxyFunc
{
get
;
set
;
}
/// <summary>
/// A list of IpAddress and port this proxy is listening to
/// </summary>
using
StreamExtended.Network
;
using
System
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Net
;
using
System.Net.Sockets
;
using
System.Security.Authentication
;
using
System.Security.Cryptography.X509Certificates
;
using
System.Threading
;
using
System.Threading.Tasks
;
using
Titanium.Web.Proxy.EventArguments
;
using
Titanium.Web.Proxy.Extensions
;
using
Titanium.Web.Proxy.Helpers
;
#if NET45
using
Titanium.Web.Proxy.Helpers.WinHttp
;
#endif
using
Titanium.Web.Proxy.Models
;
using
Titanium.Web.Proxy.Network
;
using
Titanium.Web.Proxy.Network.Tcp
;
#if NET45
using
Titanium.Web.Proxy.Network.WinAuth.Security
;
#endif
namespace
Titanium.Web.Proxy
{
/// <summary>
/// Proxy Server Main class
/// </summary>
public
partial
class
ProxyServer
:
IDisposable
{
#if NET45
internal
static
readonly
string
UriSchemeHttp
=
Uri
.
UriSchemeHttp
;
internal
static
readonly
string
UriSchemeHttps
=
Uri
.
UriSchemeHttps
;
#else
internal
const
string
UriSchemeHttp
=
"http"
;
internal
const
string
UriSchemeHttps
=
"https"
;
#endif
/// <summary>
/// Is the proxy currently running
/// </summary>
private
bool
proxyRunning
{
get
;
set
;
}
/// <summary>
/// An default exception log func
/// </summary>
private
readonly
Lazy
<
Action
<
Exception
>>
defaultExceptionFunc
=
new
Lazy
<
Action
<
Exception
>>(()
=>
(
e
=>
{
}));
/// <summary>
/// backing exception func for exposed public property
/// </summary>
private
Action
<
Exception
>
exceptionFunc
;
/// <summary>
/// Backing field for corresponding public property
/// </summary>
private
bool
trustRootCertificate
;
/// <summary>
/// Backing field for corresponding public property
/// </summary>
private
int
clientConnectionCount
;
/// <summary>
/// Backing field for corresponding public property
/// </summary>
private
int
serverConnectionCount
;
/// <summary>
/// A object that creates tcp connection to server
/// </summary>
private
TcpConnectionFactory
tcpConnectionFactory
{
get
;
}
#if NET45
private
WinHttpWebProxyFinder
systemProxyResolver
;
/// <summary>
/// Manage system proxy settings
/// </summary>
private
SystemProxyManager
systemProxySettingsManager
{
get
;
}
/// <summary>
/// Set firefox to use default system proxy
/// </summary>
private
readonly
FireFoxProxySettingsManager
firefoxProxySettingsManager
=
new
FireFoxProxySettingsManager
();
#endif
/// <summary>
/// Buffer size used throughout this proxy
/// </summary>
public
int
BufferSize
{
get
;
set
;
}
=
8192
;
/// <summary>
/// Manages certificates used by this proxy
/// </summary>
public
CertificateManager
CertificateManager
{
get
;
}
/// <summary>
/// The root certificate
/// </summary>
public
X509Certificate2
RootCertificate
{
get
{
return
CertificateManager
.
RootCertificate
;
}
set
{
CertificateManager
.
RootCertificate
=
value
;
}
}
/// <summary>
/// Name of the root certificate issuer
/// (This is valid only when RootCertificate property is not set)
/// </summary>
public
string
RootCertificateIssuerName
{
get
{
return
CertificateManager
.
Issuer
;
}
set
{
CertificateManager
.
Issuer
=
value
;
}
}
/// <summary>
/// Name of the root certificate
/// (This is valid only when RootCertificate property is not set)
/// If no certificate is provided then a default Root Certificate will be created and used
/// The provided root certificate will be stored in proxy exe directory with the private key
/// Root certificate file will be named as "rootCert.pfx"
/// </summary>
public
string
RootCertificateName
{
get
{
return
CertificateManager
.
RootCertificateName
;
}
set
{
CertificateManager
.
RootCertificateName
=
value
;
}
}
/// <summary>
/// Trust the RootCertificate used by this proxy server
/// Note that this do not make the client trust the certificate!
/// This would import the root certificate to the certificate store of machine that runs this proxy server
/// </summary>
public
bool
TrustRootCertificate
{
get
{
return
trustRootCertificate
;
}
set
{
trustRootCertificate
=
value
;
if
(
value
)
{
EnsureRootCertificate
();
}
}
}
/// <summary>
/// Select Certificate Engine
/// Optionally set to BouncyCastle
/// Mono only support BouncyCastle and it is the default
/// </summary>
public
CertificateEngine
CertificateEngine
{
get
{
return
CertificateManager
.
Engine
;
}
set
{
CertificateManager
.
Engine
=
value
;
}
}
/// <summary>
/// Should we check for certificare revocation during SSL authentication to servers
/// Note: If enabled can reduce performance (Default disabled)
/// </summary>
public
bool
CheckCertificateRevocation
{
get
;
set
;
}
/// <summary>
/// Does this proxy uses the HTTP protocol 100 continue behaviour strictly?
/// Broken 100 contunue implementations on server/client may cause problems if enabled
/// </summary>
public
bool
Enable100ContinueBehaviour
{
get
;
set
;
}
/// <summary>
/// Minutes certificates should be kept in cache when not used
/// </summary>
public
int
CertificateCacheTimeOutMinutes
{
get
;
set
;
}
/// <summary>
/// Seconds client/server connection are to be kept alive when waiting for read/write to complete
/// </summary>
public
int
ConnectionTimeOutSeconds
{
get
;
set
;
}
/// <summary>
/// Intercept request to server
/// </summary>
public
event
Func
<
object
,
SessionEventArgs
,
Task
>
BeforeRequest
;
/// <summary>
/// Intercept response from server
/// </summary>
public
event
Func
<
object
,
SessionEventArgs
,
Task
>
BeforeResponse
;
/// <summary>
/// Intercept tunnel connect reques
/// </summary>
public
event
Func
<
object
,
TunnelConnectSessionEventArgs
,
Task
>
TunnelConnectRequest
;
/// <summary>
/// Intercept tunnel connect response
/// </summary>
public
event
Func
<
object
,
TunnelConnectSessionEventArgs
,
Task
>
TunnelConnectResponse
;
/// <summary>
/// Occurs when client connection count changed.
/// </summary>
public
event
EventHandler
ClientConnectionCountChanged
;
/// <summary>
/// Occurs when server connection count changed.
/// </summary>
public
event
EventHandler
ServerConnectionCountChanged
;
/// <summary>
/// External proxy for Http
/// </summary>
public
ExternalProxy
UpStreamHttpProxy
{
get
;
set
;
}
/// <summary>
/// External proxy for Http
/// </summary>
public
ExternalProxy
UpStreamHttpsProxy
{
get
;
set
;
}
/// <summary>
/// Local adapter/NIC endpoint (where proxy makes request via)
/// default via any IP addresses of this machine
/// </summary>
public
IPEndPoint
UpStreamEndPoint
{
get
;
set
;
}
=
new
IPEndPoint
(
IPAddress
.
Any
,
0
);
/// <summary>
/// Is the proxy currently running
/// </summary>
public
bool
ProxyRunning
=>
proxyRunning
;
/// <summary>
/// Gets or sets a value indicating whether requests will be chained to upstream gateway.
/// </summary>
public
bool
ForwardToUpstreamGateway
{
get
;
set
;
}
/// <summary>
/// Enable disable Windows Authentication (NTLM/Kerberos)
/// Note: NTLM/Kerberos will always send local credentials of current user
/// who is running the proxy process. This is because a man
/// in middle attack is not currently supported
/// (which would require windows delegation enabled for this server process)
/// </summary>
public
bool
EnableWinAuth
{
get
;
set
;
}
/// <summary>
/// Verifies the remote Secure Sockets Layer (SSL) certificate used for authentication
/// </summary>
public
event
Func
<
object
,
CertificateValidationEventArgs
,
Task
>
ServerCertificateValidationCallback
;
/// <summary>
/// Callback tooverride client certificate during SSL mutual authentication
/// </summary>
public
event
Func
<
object
,
CertificateSelectionEventArgs
,
Task
>
ClientCertificateSelectionCallback
;
/// <summary>
/// Callback for error events in proxy
/// </summary>
public
Action
<
Exception
>
ExceptionFunc
{
get
{
return
exceptionFunc
??
defaultExceptionFunc
.
Value
;
}
set
{
exceptionFunc
=
value
;
}
}
/// <summary>
/// A callback to authenticate clients
/// Parameters are username, password provided by client
/// return true for successful authentication
/// </summary>
public
Func
<
string
,
string
,
Task
<
bool
>>
AuthenticateUserFunc
{
get
;
set
;
}
/// <summary>
/// Realm used during Proxy Basic Authentication
/// </summary>
public
string
ProxyRealm
{
get
;
set
;
}
=
"TitaniumProxy"
;
/// <summary>
/// A callback to provide authentication credentials for up stream proxy this proxy is using for HTTP requests
/// return the ExternalProxy object with valid credentials
/// </summary>
public
Func
<
SessionEventArgs
,
Task
<
ExternalProxy
>>
GetCustomUpStreamHttpProxyFunc
{
get
;
set
;
}
/// <summary>
/// A callback to provide authentication credentials for up stream proxy this proxy is using for HTTPS requests
/// return the ExternalProxy object with valid credentials
/// </summary>
public
Func
<
SessionEventArgs
,
Task
<
ExternalProxy
>>
GetCustomUpStreamHttpsProxyFunc
{
get
;
set
;
}
/// <summary>
/// A list of IpAddress and port this proxy is listening to
/// </summary>
public
List
<
ProxyEndPoint
>
ProxyEndPoints
{
get
;
set
;
}
/// <summary>
/// List of supported Ssl versions
/// </summary>
#if NET45
public
SslProtocols
SupportedSslProtocols
{
get
;
set
;
}
=
SslProtocols
.
Tls
|
SslProtocols
.
Tls11
|
SslProtocols
.
Tls12
|
SslProtocols
.
Ssl3
;
#else
public
SslProtocols
SupportedSslProtocols
{
get
;
set
;
}
=
SslProtocols
.
Tls
|
SslProtocols
.
Tls11
|
SslProtocols
.
Tls12
;
#endif
/// <summary>
/// Total number of active client connections
/// </summary>
public
int
ClientConnectionCount
=>
clientConnectionCount
;
/// <summary>
/// Total number of active server connections
/// </summary>
public
int
ServerConnectionCount
=>
serverConnectionCount
;
/// <summary>
/// Constructor
/// </summary>
public
ProxyServer
()
:
this
(
null
,
null
)
{
}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="rootCertificateName">Name of root certificate.</param>
/// <param name="rootCertificateIssuerName">Name of root certificate issuer.</param>
public
ProxyServer
(
string
rootCertificateName
,
string
rootCertificateIssuerName
)
{
//default values
ConnectionTimeOutSeconds
=
30
;
CertificateCacheTimeOutMinutes
=
60
;
ProxyEndPoints
=
new
List
<
ProxyEndPoint
>();
tcpConnectionFactory
=
new
TcpConnectionFactory
();
#if NET45
if
(!
RunTime
.
IsRunningOnMono
)
{
systemProxySettingsManager
=
new
SystemProxyManager
();
}
#endif
CertificateManager
=
new
CertificateManager
(
ExceptionFunc
);
if
(
rootCertificateName
!=
null
)
{
RootCertificateName
=
rootCertificateName
;
}
if
(
rootCertificateIssuerName
!=
null
)
{
RootCertificateIssuerName
=
rootCertificateIssuerName
;
}
}
/// <summary>
/// Add a proxy end point
/// </summary>
/// <param name="endPoint"></param>
public
void
AddEndPoint
(
ProxyEndPoint
endPoint
)
{
if
(
ProxyEndPoints
.
Any
(
x
=>
x
.
IpAddress
.
Equals
(
endPoint
.
IpAddress
)
&&
endPoint
.
Port
!=
0
&&
x
.
Port
==
endPoint
.
Port
))
{
throw
new
Exception
(
"Cannot add another endpoint to same port & ip address"
);
}
ProxyEndPoints
.
Add
(
endPoint
);
if
(
proxyRunning
)
{
Listen
(
endPoint
);
}
}
/// <summary>
/// Remove a proxy end point
/// Will throw error if the end point does'nt exist
/// </summary>
/// <param name="endPoint"></param>
public
void
RemoveEndPoint
(
ProxyEndPoint
endPoint
)
{
if
(
ProxyEndPoints
.
Contains
(
endPoint
)
==
false
)
{
throw
new
Exception
(
"Cannot remove endPoints not added to proxy"
);
}
ProxyEndPoints
.
Remove
(
endPoint
);
if
(
proxyRunning
)
{
QuitListen
(
endPoint
);
}
}
#if NET45
/// <summary>
/// Set the given explicit end point as the default proxy server for current machine
/// </summary>
/// <param name="endPoint"></param>
public
void
SetAsSystemHttpProxy
(
ExplicitProxyEndPoint
endPoint
)
{
SetAsSystemProxy
(
endPoint
,
ProxyProtocolType
.
Http
);
}
/// <summary>
/// Set the given explicit end point as the default proxy server for current machine
/// </summary>
/// <param name="endPoint"></param>
public
void
SetAsSystemHttpsProxy
(
ExplicitProxyEndPoint
endPoint
)
{
SetAsSystemProxy
(
endPoint
,
ProxyProtocolType
.
Https
);
}
/// <summary>
/// Set the given explicit end point as the default proxy server for current machine
/// </summary>
/// <param name="endPoint"></param>
/// <param name="protocolType"></param>
public
void
SetAsSystemProxy
(
ExplicitProxyEndPoint
endPoint
,
ProxyProtocolType
protocolType
)
{
if
(
RunTime
.
IsRunningOnMono
)
{
throw
new
Exception
(
"Mono Runtime do not support system proxy settings."
);
}
ValidateEndPointAsSystemProxy
(
endPoint
);
bool
isHttp
=
(
protocolType
&
ProxyProtocolType
.
Http
)
>
0
;
bool
isHttps
=
(
protocolType
&
ProxyProtocolType
.
Https
)
>
0
;
if
(
isHttps
)
{
if
(!
endPoint
.
EnableSsl
)
{
throw
new
Exception
(
"Endpoint do not support Https connections"
);
}
EnsureRootCertificate
();
//If certificate was trusted by the machine
if
(!
CertificateManager
.
CertValidated
)
{
protocolType
=
protocolType
&
~
ProxyProtocolType
.
Https
;
isHttps
=
false
;
}
}
//clear any settings previously added
if
(
isHttp
)
{
ProxyEndPoints
.
OfType
<
ExplicitProxyEndPoint
>().
ToList
().
ForEach
(
x
=>
x
.
IsSystemHttpProxy
=
false
);
}
if
(
isHttps
)
{
ProxyEndPoints
.
OfType
<
ExplicitProxyEndPoint
>().
ToList
().
ForEach
(
x
=>
x
.
IsSystemHttpsProxy
=
false
);
}
systemProxySettingsManager
.
SetProxy
(
Equals
(
endPoint
.
IpAddress
,
IPAddress
.
Any
)
|
Equals
(
endPoint
.
IpAddress
,
IPAddress
.
Loopback
)
?
"127.0.0.1"
:
endPoint
.
IpAddress
.
ToString
(),
endPoint
.
Port
,
protocolType
);
if
(
isHttp
)
{
endPoint
.
IsSystemHttpsProxy
=
true
;
}
if
(
isHttps
)
{
endPoint
.
IsSystemHttpsProxy
=
true
;
}
firefoxProxySettingsManager
.
UseSystemProxy
();
string
proxyType
=
null
;
switch
(
protocolType
)
{
case
ProxyProtocolType
.
Http
:
proxyType
=
"HTTP"
;
break
;
case
ProxyProtocolType
.
Https
:
proxyType
=
"HTTPS"
;
break
;
case
ProxyProtocolType
.
AllHttp
:
proxyType
=
"HTTP and HTTPS"
;
break
;
}
if
(
protocolType
!=
ProxyProtocolType
.
None
)
{
Console
.
WriteLine
(
"Set endpoint at Ip {0} and port: {1} as System {2} Proxy"
,
endPoint
.
IpAddress
,
endPoint
.
Port
,
proxyType
);
}
}
/// <summary>
/// Remove any HTTP proxy setting of current machien
/// </summary>
public
void
DisableSystemHttpProxy
()
{
DisableSystemProxy
(
ProxyProtocolType
.
Http
);
}
/// <summary>
/// Remove any HTTPS proxy setting for current machine
/// </summary>
public
void
DisableSystemHttpsProxy
()
{
DisableSystemProxy
(
ProxyProtocolType
.
Https
);
}
/// <summary>
/// Remove the specified proxy settings for current machine
/// </summary>
public
void
DisableSystemProxy
(
ProxyProtocolType
protocolType
)
{
if
(
RunTime
.
IsRunningOnMono
)
{
throw
new
Exception
(
"Mono Runtime do not support system proxy settings."
);
}
systemProxySettingsManager
.
RemoveProxy
(
protocolType
);
}
/// <summary>
/// Clear all proxy settings for current machine
/// </summary>
public
void
DisableAllSystemProxies
()
{
if
(
RunTime
.
IsRunningOnMono
)
{
throw
new
Exception
(
"Mono Runtime do not support system proxy settings."
);
}
systemProxySettingsManager
.
DisableAllProxy
();
}
#endif
/// <summary>
/// Start this proxy server
/// </summary>
public
void
Start
()
{
if
(
proxyRunning
)
{
throw
new
Exception
(
"Proxy is already running."
);
}
#if NET45
//clear any system proxy settings which is pointing to our own endpoint (causing a cycle)
//due to non gracious proxy shutdown before or something else
if
(
systemProxySettingsManager
!=
null
)
{
var
proxyInfo
=
systemProxySettingsManager
.
GetProxyInfoFromRegistry
();
if
(
proxyInfo
.
Proxies
!=
null
)
{
var
protocolToRemove
=
ProxyProtocolType
.
None
;
foreach
(
var
proxy
in
proxyInfo
.
Proxies
.
Values
)
{
/// <summary>
/// List of supported Ssl versions
/// </summary>
#if NET45
public
SslProtocols
SupportedSslProtocols
{
get
;
set
;
}
=
SslProtocols
.
Tls
|
SslProtocols
.
Tls11
|
SslProtocols
.
Tls12
|
SslProtocols
.
Ssl3
;
#else
public
SslProtocols
SupportedSslProtocols
{
get
;
set
;
}
=
SslProtocols
.
Tls
|
SslProtocols
.
Tls11
|
SslProtocols
.
Tls12
;
#endif
/// <summary>
/// Total number of active client connections
/// </summary>
public
int
ClientConnectionCount
=>
clientConnectionCount
;
/// <summary>
/// Total number of active server connections
/// </summary>
public
int
ServerConnectionCount
=>
serverConnectionCount
;
/// <summary>
/// Constructor
/// </summary>
public
ProxyServer
()
:
this
(
null
,
null
)
{
}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="rootCertificateName">Name of root certificate.</param>
/// <param name="rootCertificateIssuerName">Name of root certificate issuer.</param>
public
ProxyServer
(
string
rootCertificateName
,
string
rootCertificateIssuerName
)
{
//default values
ConnectionTimeOutSeconds
=
30
;
CertificateCacheTimeOutMinutes
=
60
;
ProxyEndPoints
=
new
List
<
ProxyEndPoint
>();
tcpConnectionFactory
=
new
TcpConnectionFactory
();
#if NET45
if
(!
RunTime
.
IsRunningOnMono
)
{
systemProxySettingsManager
=
new
SystemProxyManager
();
}
#endif
CertificateManager
=
new
CertificateManager
(
ExceptionFunc
);
if
(
rootCertificateName
!=
null
)
{
RootCertificateName
=
rootCertificateName
;
}
if
(
rootCertificateIssuerName
!=
null
)
{
RootCertificateIssuerName
=
rootCertificateIssuerName
;
}
}
/// <summary>
/// Add a proxy end point
/// </summary>
/// <param name="endPoint"></param>
public
void
AddEndPoint
(
ProxyEndPoint
endPoint
)
{
if
(
ProxyEndPoints
.
Any
(
x
=>
x
.
IpAddress
.
Equals
(
endPoint
.
IpAddress
)
&&
endPoint
.
Port
!=
0
&&
x
.
Port
==
endPoint
.
Port
))
{
throw
new
Exception
(
"Cannot add another endpoint to same port & ip address"
);
}
ProxyEndPoints
.
Add
(
endPoint
);
if
(
proxyRunning
)
{
Listen
(
endPoint
);
}
}
/// <summary>
/// Remove a proxy end point
/// Will throw error if the end point does'nt exist
/// </summary>
/// <param name="endPoint"></param>
public
void
RemoveEndPoint
(
ProxyEndPoint
endPoint
)
{
if
(
ProxyEndPoints
.
Contains
(
endPoint
)
==
false
)
{
throw
new
Exception
(
"Cannot remove endPoints not added to proxy"
);
}
ProxyEndPoints
.
Remove
(
endPoint
);
if
(
proxyRunning
)
{
QuitListen
(
endPoint
);
}
}
#if NET45
/// <summary>
/// Set the given explicit end point as the default proxy server for current machine
/// </summary>
/// <param name="endPoint"></param>
public
void
SetAsSystemHttpProxy
(
ExplicitProxyEndPoint
endPoint
)
{
SetAsSystemProxy
(
endPoint
,
ProxyProtocolType
.
Http
);
}
/// <summary>
/// Set the given explicit end point as the default proxy server for current machine
/// </summary>
/// <param name="endPoint"></param>
public
void
SetAsSystemHttpsProxy
(
ExplicitProxyEndPoint
endPoint
)
{
SetAsSystemProxy
(
endPoint
,
ProxyProtocolType
.
Https
);
}
/// <summary>
/// Set the given explicit end point as the default proxy server for current machine
/// </summary>
/// <param name="endPoint"></param>
/// <param name="protocolType"></param>
public
void
SetAsSystemProxy
(
ExplicitProxyEndPoint
endPoint
,
ProxyProtocolType
protocolType
)
{
if
(
RunTime
.
IsRunningOnMono
)
{
throw
new
Exception
(
"Mono Runtime do not support system proxy settings."
);
}
ValidateEndPointAsSystemProxy
(
endPoint
);
bool
isHttp
=
(
protocolType
&
ProxyProtocolType
.
Http
)
>
0
;
bool
isHttps
=
(
protocolType
&
ProxyProtocolType
.
Https
)
>
0
;
if
(
isHttps
)
{
if
(!
endPoint
.
EnableSsl
)
{
throw
new
Exception
(
"Endpoint do not support Https connections"
);
}
EnsureRootCertificate
();
//If certificate was trusted by the machine
if
(!
CertificateManager
.
CertValidated
)
{
protocolType
=
protocolType
&
~
ProxyProtocolType
.
Https
;
isHttps
=
false
;
}
}
//clear any settings previously added
if
(
isHttp
)
{
ProxyEndPoints
.
OfType
<
ExplicitProxyEndPoint
>().
ToList
().
ForEach
(
x
=>
x
.
IsSystemHttpProxy
=
false
);
}
if
(
isHttps
)
{
ProxyEndPoints
.
OfType
<
ExplicitProxyEndPoint
>().
ToList
().
ForEach
(
x
=>
x
.
IsSystemHttpsProxy
=
false
);
}
systemProxySettingsManager
.
SetProxy
(
Equals
(
endPoint
.
IpAddress
,
IPAddress
.
Any
)
|
Equals
(
endPoint
.
IpAddress
,
IPAddress
.
Loopback
)
?
"127.0.0.1"
:
endPoint
.
IpAddress
.
ToString
(),
endPoint
.
Port
,
protocolType
);
if
(
isHttp
)
{
endPoint
.
IsSystemHttpsProxy
=
true
;
}
if
(
isHttps
)
{
endPoint
.
IsSystemHttpsProxy
=
true
;
}
firefoxProxySettingsManager
.
UseSystemProxy
();
string
proxyType
=
null
;
switch
(
protocolType
)
{
case
ProxyProtocolType
.
Http
:
proxyType
=
"HTTP"
;
break
;
case
ProxyProtocolType
.
Https
:
proxyType
=
"HTTPS"
;
break
;
case
ProxyProtocolType
.
AllHttp
:
proxyType
=
"HTTP and HTTPS"
;
break
;
}
if
(
protocolType
!=
ProxyProtocolType
.
None
)
{
Console
.
WriteLine
(
"Set endpoint at Ip {0} and port: {1} as System {2} Proxy"
,
endPoint
.
IpAddress
,
endPoint
.
Port
,
proxyType
);
}
}
/// <summary>
/// Remove any HTTP proxy setting of current machien
/// </summary>
public
void
DisableSystemHttpProxy
()
{
DisableSystemProxy
(
ProxyProtocolType
.
Http
);
}
/// <summary>
/// Remove any HTTPS proxy setting for current machine
/// </summary>
public
void
DisableSystemHttpsProxy
()
{
DisableSystemProxy
(
ProxyProtocolType
.
Https
);
}
/// <summary>
/// Remove the specified proxy settings for current machine
/// </summary>
public
void
DisableSystemProxy
(
ProxyProtocolType
protocolType
)
{
if
(
RunTime
.
IsRunningOnMono
)
{
throw
new
Exception
(
"Mono Runtime do not support system proxy settings."
);
}
systemProxySettingsManager
.
RemoveProxy
(
protocolType
);
}
/// <summary>
/// Clear all proxy settings for current machine
/// </summary>
public
void
DisableAllSystemProxies
()
{
if
(
RunTime
.
IsRunningOnMono
)
{
throw
new
Exception
(
"Mono Runtime do not support system proxy settings."
);
}
systemProxySettingsManager
.
DisableAllProxy
();
}
#endif
/// <summary>
/// Start this proxy server
/// </summary>
public
void
Start
()
{
if
(
proxyRunning
)
{
throw
new
Exception
(
"Proxy is already running."
);
}
#if NET45
//clear any system proxy settings which is pointing to our own endpoint (causing a cycle)
//due to non gracious proxy shutdown before or something else
if
(
systemProxySettingsManager
!=
null
)
{
var
proxyInfo
=
systemProxySettingsManager
.
GetProxyInfoFromRegistry
();
if
(
proxyInfo
.
Proxies
!=
null
)
{
var
protocolToRemove
=
ProxyProtocolType
.
None
;
foreach
(
var
proxy
in
proxyInfo
.
Proxies
.
Values
)
{
if
((
proxy
.
HostName
==
"127.0.0.1"
||
proxy
.
HostName
.
Equals
(
"localhost"
,
StringComparison
.
OrdinalIgnoreCase
))
&&
ProxyEndPoints
.
Any
(
x
=>
x
.
Port
==
proxy
.
Port
))
{
protocolToRemove
|=
proxy
.
ProtocolType
;
}
}
if
(
protocolToRemove
!=
ProxyProtocolType
.
None
)
{
//do not restore to any of listening address when we quit
systemProxySettingsManager
.
RemoveProxy
(
protocolToRemove
,
false
);
}
}
}
if
(
ForwardToUpstreamGateway
&&
GetCustomUpStreamHttpProxyFunc
==
null
&&
GetCustomUpStreamHttpsProxyFunc
==
null
&&
systemProxySettingsManager
!=
null
)
{
// Use WinHttp to handle PAC/WAPD scripts.
systemProxyResolver
=
new
WinHttpWebProxyFinder
();
systemProxyResolver
.
LoadFromIE
();
GetCustomUpStreamHttpProxyFunc
=
GetSystemUpStreamProxy
;
GetCustomUpStreamHttpsProxyFunc
=
GetSystemUpStreamProxy
;
}
#endif
foreach
(
var
endPoint
in
ProxyEndPoints
)
{
Listen
(
endPoint
);
}
CertificateManager
.
ClearIdleCertificates
(
CertificateCacheTimeOutMinutes
);
#if NET45
if
(!
RunTime
.
IsRunningOnMono
)
{
//clear orphaned windows auth states every 2 minutes
WinAuthEndPoint
.
ClearIdleStates
(
2
);
}
#endif
proxyRunning
=
true
;
}
/// <summary>
/// Stop this proxy server
/// </summary>
public
void
Stop
()
{
if
(!
proxyRunning
)
{
throw
new
Exception
(
"Proxy is not running."
);
}
#if NET45
if
(!
RunTime
.
IsRunningOnMono
)
{
bool
setAsSystemProxy
=
ProxyEndPoints
.
OfType
<
ExplicitProxyEndPoint
>().
Any
(
x
=>
x
.
IsSystemHttpProxy
||
x
.
IsSystemHttpsProxy
);
if
(
setAsSystemProxy
)
{
systemProxySettingsManager
.
RestoreOriginalSettings
();
}
}
#endif
foreach
(
var
endPoint
in
ProxyEndPoints
)
{
QuitListen
(
endPoint
);
}
ProxyEndPoints
.
Clear
();
CertificateManager
?.
StopClearIdleCertificates
();
proxyRunning
=
false
;
}
/// <summary>
/// Handle dispose of a client/server session
/// </summary>
/// <param name="clientStream"></param>
/// <param name="clientStreamReader"></param>
/// <param name="clientStreamWriter"></param>
/// <param name="serverConnection"></param>
private
void
Dispose
(
CustomBufferedStream
clientStream
,
CustomBinaryReader
clientStreamReader
,
HttpResponseWriter
clientStreamWriter
,
TcpConnection
serverConnection
)
{
clientStream
?.
Dispose
();
clientStreamReader
?.
Dispose
();
clientStreamWriter
?.
Dispose
();
if
(
serverConnection
!=
null
)
{
serverConnection
.
Dispose
();
serverConnection
=
null
;
UpdateServerConnectionCount
(
false
);
}
}
/// <summary>
/// Dispose Proxy.
/// </summary>
public
void
Dispose
()
{
if
(
proxyRunning
)
{
Stop
();
}
CertificateManager
?.
Dispose
();
}
#if NET45
/// <summary>
/// Listen on the given end point on local machine
/// </summary>
/// <param name="endPoint"></param>
private
void
Listen
(
ProxyEndPoint
endPoint
)
{
endPoint
.
Listener
=
new
TcpListener
(
endPoint
.
IpAddress
,
endPoint
.
Port
);
endPoint
.
Listener
.
Start
();
endPoint
.
Port
=
((
IPEndPoint
)
endPoint
.
Listener
.
LocalEndpoint
).
Port
;
// accept clients asynchronously
endPoint
.
Listener
.
BeginAcceptTcpClient
(
OnAcceptConnection
,
endPoint
);
}
#else
private
async
void
Listen
(
ProxyEndPoint
endPoint
)
{
endPoint
.
Listener
=
new
TcpListener
(
endPoint
.
IpAddress
,
endPoint
.
Port
);
endPoint
.
Listener
.
Start
();
endPoint
.
Port
=
((
IPEndPoint
)
endPoint
.
Listener
.
LocalEndpoint
).
Port
;
while
(
true
)
{
TcpClient
tcpClient
=
await
endPoint
.
Listener
.
AcceptTcpClientAsync
();
if
(
tcpClient
!=
null
)
Task
.
Run
(
async
()
=>
HandleClient
(
tcpClient
,
endPoint
));
}
}
#endif
/// <summary>
/// Verifiy if its safe to set this end point as System proxy
/// </summary>
/// <param name="endPoint"></param>
private
void
ValidateEndPointAsSystemProxy
(
ExplicitProxyEndPoint
endPoint
)
{
if
(
endPoint
==
null
)
throw
new
ArgumentNullException
(
nameof
(
endPoint
));
if
(
ProxyEndPoints
.
Contains
(
endPoint
)
==
false
)
{
throw
new
Exception
(
"Cannot set endPoints not added to proxy as system proxy"
);
}
if
(!
proxyRunning
)
{
throw
new
Exception
(
"Cannot set system proxy settings before proxy has been started."
);
}
}
#if NET45
/// <summary>
/// Gets the system up stream proxy.
/// </summary>
/// <param name="sessionEventArgs">The <see cref="SessionEventArgs"/> instance containing the event data.</param>
/// <returns><see cref="ExternalProxy"/> instance containing valid proxy configuration from PAC/WAPD scripts if any exists.</returns>
private
Task
<
ExternalProxy
>
GetSystemUpStreamProxy
(
SessionEventArgs
sessionEventArgs
)
{
var
proxy
=
systemProxyResolver
.
GetProxy
(
sessionEventArgs
.
WebSession
.
Request
.
RequestUri
);
return
Task
.
FromResult
(
proxy
);
}
#endif
private
void
EnsureRootCertificate
()
{
if
(!
CertificateManager
.
CertValidated
)
{
CertificateManager
.
CreateTrustedRootCertificate
();
if
(
TrustRootCertificate
)
{
CertificateManager
.
TrustRootCertificate
();
}
}
}
#if NET45
/// <summary>
/// When a connection is received from client act
/// </summary>
/// <param name="asyn"></param>
private
void
OnAcceptConnection
(
IAsyncResult
asyn
)
{
var
endPoint
=
(
ProxyEndPoint
)
asyn
.
AsyncState
;
TcpClient
tcpClient
=
null
;
try
{
//based on end point type call appropriate request handlers
tcpClient
=
endPoint
.
Listener
.
EndAcceptTcpClient
(
asyn
);
}
catch
(
ObjectDisposedException
)
{
// The listener was Stop()'d, disposing the underlying socket and
// triggering the completion of the callback. We're already exiting,
// so just return.
return
;
}
catch
{
//Other errors are discarded to keep proxy running
}
if
(
tcpClient
!=
null
)
{
Task
.
Run
(
async
()
=>
{
await
HandleClient
(
tcpClient
,
endPoint
);
});
}
// Get the listener that handles the client request.
endPoint
.
Listener
.
BeginAcceptTcpClient
(
OnAcceptConnection
,
endPoint
);
}
#endif
private
async
Task
HandleClient
(
TcpClient
tcpClient
,
ProxyEndPoint
endPoint
)
{
UpdateClientConnectionCount
(
true
);
tcpClient
.
ReceiveTimeout
=
ConnectionTimeOutSeconds
*
1000
;
tcpClient
.
SendTimeout
=
ConnectionTimeOutSeconds
*
1000
;
try
{
if
(
endPoint
.
GetType
()
==
typeof
(
TransparentProxyEndPoint
))
{
await
HandleClient
(
endPoint
as
TransparentProxyEndPoint
,
tcpClient
);
}
else
{
await
HandleClient
(
endPoint
as
ExplicitProxyEndPoint
,
tcpClient
);
}
}
finally
{
UpdateClientConnectionCount
(
false
);
try
{
if
(
tcpClient
!=
null
)
{
//This line is important!
//contributors please don't remove it without discussion
//It helps to avoid eventual deterioration of performance due to TCP port exhaustion
//due to default TCP CLOSE_WAIT timeout for 4 minutes
tcpClient
.
LingerState
=
new
LingerOption
(
true
,
0
);
tcpClient
.
Dispose
();
}
}
catch
{
}
}
}
/// <summary>
/// Quit listening on the given end point
/// </summary>
/// <param name="endPoint"></param>
private
void
QuitListen
(
ProxyEndPoint
endPoint
)
{
endPoint
.
Listener
.
Stop
();
endPoint
.
Listener
.
Server
.
Dispose
();
}
internal
void
UpdateClientConnectionCount
(
bool
increment
)
{
if
(
increment
)
{
Interlocked
.
Increment
(
ref
clientConnectionCount
);
}
else
{
Interlocked
.
Decrement
(
ref
clientConnectionCount
);
}
ClientConnectionCountChanged
?.
Invoke
(
this
,
EventArgs
.
Empty
);
}
internal
void
UpdateServerConnectionCount
(
bool
increment
)
{
if
(
increment
)
{
Interlocked
.
Increment
(
ref
serverConnectionCount
);
}
else
{
Interlocked
.
Decrement
(
ref
serverConnectionCount
);
}
ServerConnectionCountChanged
?.
Invoke
(
this
,
EventArgs
.
Empty
);
}
}
}
{
protocolToRemove
|=
proxy
.
ProtocolType
;
}
}
if
(
protocolToRemove
!=
ProxyProtocolType
.
None
)
{
//do not restore to any of listening address when we quit
systemProxySettingsManager
.
RemoveProxy
(
protocolToRemove
,
false
);
}
}
}
if
(
ForwardToUpstreamGateway
&&
GetCustomUpStreamHttpProxyFunc
==
null
&&
GetCustomUpStreamHttpsProxyFunc
==
null
&&
systemProxySettingsManager
!=
null
)
{
// Use WinHttp to handle PAC/WAPD scripts.
systemProxyResolver
=
new
WinHttpWebProxyFinder
();
systemProxyResolver
.
LoadFromIE
();
GetCustomUpStreamHttpProxyFunc
=
GetSystemUpStreamProxy
;
GetCustomUpStreamHttpsProxyFunc
=
GetSystemUpStreamProxy
;
}
#endif
foreach
(
var
endPoint
in
ProxyEndPoints
)
{
Listen
(
endPoint
);
}
CertificateManager
.
ClearIdleCertificates
(
CertificateCacheTimeOutMinutes
);
#if NET45
if
(!
RunTime
.
IsRunningOnMono
)
{
//clear orphaned windows auth states every 2 minutes
WinAuthEndPoint
.
ClearIdleStates
(
2
);
}
#endif
proxyRunning
=
true
;
}
/// <summary>
/// Stop this proxy server
/// </summary>
public
void
Stop
()
{
if
(!
proxyRunning
)
{
throw
new
Exception
(
"Proxy is not running."
);
}
#if NET45
if
(!
RunTime
.
IsRunningOnMono
)
{
bool
setAsSystemProxy
=
ProxyEndPoints
.
OfType
<
ExplicitProxyEndPoint
>().
Any
(
x
=>
x
.
IsSystemHttpProxy
||
x
.
IsSystemHttpsProxy
);
if
(
setAsSystemProxy
)
{
systemProxySettingsManager
.
RestoreOriginalSettings
();
}
}
#endif
foreach
(
var
endPoint
in
ProxyEndPoints
)
{
QuitListen
(
endPoint
);
}
ProxyEndPoints
.
Clear
();
CertificateManager
?.
StopClearIdleCertificates
();
proxyRunning
=
false
;
}
/// <summary>
/// Handle dispose of a client/server session
/// </summary>
/// <param name="clientStream"></param>
/// <param name="clientStreamReader"></param>
/// <param name="clientStreamWriter"></param>
/// <param name="serverConnection"></param>
private
void
Dispose
(
CustomBufferedStream
clientStream
,
CustomBinaryReader
clientStreamReader
,
HttpResponseWriter
clientStreamWriter
,
TcpConnection
serverConnection
)
{
clientStream
?.
Dispose
();
clientStreamReader
?.
Dispose
();
clientStreamWriter
?.
Dispose
();
if
(
serverConnection
!=
null
)
{
serverConnection
.
Dispose
();
serverConnection
=
null
;
UpdateServerConnectionCount
(
false
);
}
}
/// <summary>
/// Dispose Proxy.
/// </summary>
public
void
Dispose
()
{
if
(
proxyRunning
)
{
Stop
();
}
CertificateManager
?.
Dispose
();
}
#if NET45
/// <summary>
/// Listen on the given end point on local machine
/// </summary>
/// <param name="endPoint"></param>
private
void
Listen
(
ProxyEndPoint
endPoint
)
{
endPoint
.
Listener
=
new
TcpListener
(
endPoint
.
IpAddress
,
endPoint
.
Port
);
endPoint
.
Listener
.
Start
();
endPoint
.
Port
=
((
IPEndPoint
)
endPoint
.
Listener
.
LocalEndpoint
).
Port
;
// accept clients asynchronously
endPoint
.
Listener
.
BeginAcceptTcpClient
(
OnAcceptConnection
,
endPoint
);
}
#else
private
async
void
Listen
(
ProxyEndPoint
endPoint
)
{
endPoint
.
Listener
=
new
TcpListener
(
endPoint
.
IpAddress
,
endPoint
.
Port
);
endPoint
.
Listener
.
Start
();
endPoint
.
Port
=
((
IPEndPoint
)
endPoint
.
Listener
.
LocalEndpoint
).
Port
;
while
(
true
)
{
TcpClient
tcpClient
=
await
endPoint
.
Listener
.
AcceptTcpClientAsync
();
if
(
tcpClient
!=
null
)
Task
.
Run
(
async
()
=>
HandleClient
(
tcpClient
,
endPoint
));
}
}
#endif
/// <summary>
/// Verifiy if its safe to set this end point as System proxy
/// </summary>
/// <param name="endPoint"></param>
private
void
ValidateEndPointAsSystemProxy
(
ExplicitProxyEndPoint
endPoint
)
{
if
(
endPoint
==
null
)
throw
new
ArgumentNullException
(
nameof
(
endPoint
));
if
(
ProxyEndPoints
.
Contains
(
endPoint
)
==
false
)
{
throw
new
Exception
(
"Cannot set endPoints not added to proxy as system proxy"
);
}
if
(!
proxyRunning
)
{
throw
new
Exception
(
"Cannot set system proxy settings before proxy has been started."
);
}
}
#if NET45
/// <summary>
/// Gets the system up stream proxy.
/// </summary>
/// <param name="sessionEventArgs">The <see cref="SessionEventArgs"/> instance containing the event data.</param>
/// <returns><see cref="ExternalProxy"/> instance containing valid proxy configuration from PAC/WAPD scripts if any exists.</returns>
private
Task
<
ExternalProxy
>
GetSystemUpStreamProxy
(
SessionEventArgs
sessionEventArgs
)
{
var
proxy
=
systemProxyResolver
.
GetProxy
(
sessionEventArgs
.
WebSession
.
Request
.
RequestUri
);
return
Task
.
FromResult
(
proxy
);
}
#endif
private
void
EnsureRootCertificate
()
{
if
(!
CertificateManager
.
CertValidated
)
{
CertificateManager
.
CreateTrustedRootCertificate
();
if
(
TrustRootCertificate
)
{
CertificateManager
.
TrustRootCertificate
();
}
}
}
#if NET45
/// <summary>
/// When a connection is received from client act
/// </summary>
/// <param name="asyn"></param>
private
void
OnAcceptConnection
(
IAsyncResult
asyn
)
{
var
endPoint
=
(
ProxyEndPoint
)
asyn
.
AsyncState
;
TcpClient
tcpClient
=
null
;
try
{
//based on end point type call appropriate request handlers
tcpClient
=
endPoint
.
Listener
.
EndAcceptTcpClient
(
asyn
);
}
catch
(
ObjectDisposedException
)
{
// The listener was Stop()'d, disposing the underlying socket and
// triggering the completion of the callback. We're already exiting,
// so just return.
return
;
}
catch
{
//Other errors are discarded to keep proxy running
}
if
(
tcpClient
!=
null
)
{
Task
.
Run
(
async
()
=>
{
await
HandleClient
(
tcpClient
,
endPoint
);
});
}
// Get the listener that handles the client request.
endPoint
.
Listener
.
BeginAcceptTcpClient
(
OnAcceptConnection
,
endPoint
);
}
#endif
private
async
Task
HandleClient
(
TcpClient
tcpClient
,
ProxyEndPoint
endPoint
)
{
UpdateClientConnectionCount
(
true
);
tcpClient
.
ReceiveTimeout
=
ConnectionTimeOutSeconds
*
1000
;
tcpClient
.
SendTimeout
=
ConnectionTimeOutSeconds
*
1000
;
try
{
if
(
endPoint
.
GetType
()
==
typeof
(
TransparentProxyEndPoint
))
{
await
HandleClient
(
endPoint
as
TransparentProxyEndPoint
,
tcpClient
);
}
else
{
await
HandleClient
(
endPoint
as
ExplicitProxyEndPoint
,
tcpClient
);
}
}
finally
{
UpdateClientConnectionCount
(
false
);
try
{
if
(
tcpClient
!=
null
)
{
//This line is important!
//contributors please don't remove it without discussion
//It helps to avoid eventual deterioration of performance due to TCP port exhaustion
//due to default TCP CLOSE_WAIT timeout for 4 minutes
tcpClient
.
LingerState
=
new
LingerOption
(
true
,
0
);
tcpClient
.
Dispose
();
}
}
catch
{
}
}
}
/// <summary>
/// Quit listening on the given end point
/// </summary>
/// <param name="endPoint"></param>
private
void
QuitListen
(
ProxyEndPoint
endPoint
)
{
endPoint
.
Listener
.
Stop
();
endPoint
.
Listener
.
Server
.
Dispose
();
}
internal
void
UpdateClientConnectionCount
(
bool
increment
)
{
if
(
increment
)
{
Interlocked
.
Increment
(
ref
clientConnectionCount
);
}
else
{
Interlocked
.
Decrement
(
ref
clientConnectionCount
);
}
ClientConnectionCountChanged
?.
Invoke
(
this
,
EventArgs
.
Empty
);
}
internal
void
UpdateServerConnectionCount
(
bool
increment
)
{
if
(
increment
)
{
Interlocked
.
Increment
(
ref
serverConnectionCount
);
}
else
{
Interlocked
.
Decrement
(
ref
serverConnectionCount
);
}
ServerConnectionCountChanged
?.
Invoke
(
this
,
EventArgs
.
Empty
);
}
}
}
Titanium.Web.Proxy/RequestHandler.cs
View file @
b6140f19
...
...
@@ -132,7 +132,6 @@ namespace Titanium.Web.Proxy
try
{
sslStream
=
new
SslStream
(
clientStream
);
string
certName
=
HttpHelper
.
GetWildCardDomainName
(
httpRemoteUri
.
Host
);
...
...
Titanium.Web.Proxy/Titanium.Web.Proxy.Standard.csproj
deleted
100644 → 0
View file @
65983798
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.6</TargetFramework>
<RootNamespace>Titanium.Web.Proxy</RootNamespace>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<SignAssembly>True</SignAssembly>
<AssemblyOriginatorKeyFile>StrongNameKey.snk</AssemblyOriginatorKeyFile>
<DelaySign>False</DelaySign>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<Compile Remove="Helpers\WinHttp\NativeMethods.WinHttp.cs" />
<Compile Remove="Helpers\WinHttp\WinHttpHandle.cs" />
<Compile Remove="Helpers\WinHttp\WinHttpWebProxyFinder.cs" />
<Compile Remove="Helpers\NativeMethods.SystemProxy.cs" />
<Compile Remove="Helpers\NativeMethods.Tcp.cs" />
<Compile Remove="Helpers\Firefox.cs" />
<Compile Remove="Helpers\ProxyInfo.cs" />
<Compile Remove="Helpers\RunTime.cs" />
<Compile Remove="Helpers\SystemProxy.cs" />
<Compile Remove="Network\Certificate\WinCertificateMaker.cs" />
<Compile Remove="Network\Tcp\TcpRow.cs" />
<Compile Remove="Network\Tcp\TcpTable.cs" />
<Compile Remove="Network\WinAuth\Security\Common.cs" />
<Compile Remove="Network\WinAuth\Security\LittleEndian.cs" />
<Compile Remove="Network\WinAuth\Security\Message.cs" />
<Compile Remove="Network\WinAuth\Security\State.cs" />
<Compile Remove="Network\WinAuth\Security\WinAuthEndPoint.cs" />
<Compile Remove="Network\WinAuth\WinAuthHandler.cs" />
<Compile Remove="WinAuthHandler.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Portable.BouncyCastle" Version="1.8.1.2" />
<PackageReference Include="StreamExtended" Version="1.0.18" />
<PackageReference Include="System.Net.NameResolution" Version="4.3.0" />
<PackageReference Include="System.Net.Security" Version="4.3.1" />
<PackageReference Include="System.Runtime.Serialization.Formatters" Version="4.3.0" />
<PackageReference Include="System.Security.SecureString" Version="4.3.0" />
</ItemGroup>
</Project>
\ No newline at end of file
Titanium.Web.Proxy/Titanium.Web.Proxy.csproj
View file @
b6140f19
<
?xml version="1.0" encoding="utf-8"?
>
<Project
ToolsVersion=
"4.0"
DefaultTargets=
"Build"
xmlns=
"http://schemas.microsoft.com/developer/msbuild/2003"
>
<
Project Sdk="Microsoft.NET.Sdk"
>
<PropertyGroup>
<Configuration
Condition=
" '$(Configuration)' == '' "
>
Debug
</Configuration>
<Platform
Condition=
" '$(Platform)' == '' "
>
x86
</Platform>
<ProductVersion>
8.0.30703
</ProductVersion>
<SchemaVersion>
2.0
</SchemaVersion>
<ProjectGuid>
{8D73A1BE-868C-42D2-9ECE-F32CC1A02906}
</ProjectGuid>
<OutputType>
Library
</OutputType>
<AppDesignerFolder>
Properties
</AppDesignerFolder>
<TargetFrameworks>net45;netstandard2.0</TargetFrameworks>
<RootNamespace>Titanium.Web.Proxy</RootNamespace>
<AssemblyName>
Titanium.Web.Proxy
</AssemblyName>
<FileAlignment>
512
</FileAlignment>
<SolutionDir
Condition=
"$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'"
>
..\
</SolutionDir>
<RestorePackages>
true
</RestorePackages>
<TargetFrameworkProfile
/>
</PropertyGroup>
<PropertyGroup>
<StartupObject
/>
</PropertyGroup>
<PropertyGroup
Condition=
"'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'"
>
<PlatformTarget>
AnyCPU
</PlatformTarget>
<OutputPath>
bin\Debug\
</OutputPath>
<DefineConstants>
DEBUG;NET45
</DefineConstants>
<AllowUnsafeBlocks>
true
</AllowUnsafeBlocks>
<TargetFrameworkVersion>
v4.5
</TargetFrameworkVersion>
<Prefer32Bit>
false
</Prefer32Bit>
<DocumentationFile>
bin\Debug\Titanium.Web.Proxy.XML
</DocumentationFile>
<LangVersion>
6
</LangVersion>
</PropertyGroup>
<PropertyGroup
Condition=
"'$(Configuration)|$(Platform)' == 'Release|AnyCPU'"
>
<PlatformTarget>
AnyCPU
</PlatformTarget>
<OutputPath>
bin\Release\
</OutputPath>
<TargetFrameworkVersion>
v4.5
</TargetFrameworkVersion>
<DefineConstants>
NET45
</DefineConstants>
<Prefer32Bit>
false
</Prefer32Bit>
<DocumentationFile>
bin\Release\Titanium.Web.Proxy.XML
</DocumentationFile>
<DebugType>
none
</DebugType>
<DebugSymbols>
false
</DebugSymbols>
<AllowUnsafeBlocks>
true
</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup>
<SignAssembly>
true
</SignAssembly>
</PropertyGroup>
<PropertyGroup>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<SignAssembly>True</SignAssembly>
<AssemblyOriginatorKeyFile>StrongNameKey.snk</AssemblyOriginatorKeyFile>
<DelaySign>False</DelaySign>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<Reference
Include=
"BouncyCastle.Crypto"
>
<HintPath>
..\packages\Portable.BouncyCastle.1.8.1.2\lib\net4\BouncyCastle.Crypto.dll
</HintPath>
<Private>
True
</Private>
</Reference>
<Reference
Include=
"StreamExtended, Version=1.0.1.0, Culture=neutral, PublicKeyToken=bbfa0f1d54f50043, processorArchitecture=MSIL"
>
<HintPath>
..\packages\StreamExtended.1.0.18\lib\net45\StreamExtended.dll
</HintPath>
<Private>
True
</Private>
</Reference>
<Reference
Include=
"System"
/>
<Reference
Include=
"System.Configuration"
/>
<Reference
Include=
"System.Core"
/>
<Reference
Include=
"System.Data"
/>
<Reference
Include=
"System.Data.DataSetExtensions"
/>
<Reference
Include=
"System.Net"
/>
<Reference
Include=
"System.Xml"
/>
<Reference
Include=
"System.Xml.Linq"
/>
<Reference
Include=
"Microsoft.CSharp"
/>
</ItemGroup>
<ItemGroup>
<Compile
Include=
"Compression\CompressionFactory.cs"
/>
<Compile
Include=
"Compression\DeflateCompression.cs"
/>
<Compile
Include=
"Compression\GZipCompression.cs"
/>
<Compile
Include=
"Compression\ICompression.cs"
/>
<Compile
Include=
"Decompression\DecompressionFactory.cs"
/>
<Compile
Include=
"Decompression\DefaultDecompression.cs"
/>
<Compile
Include=
"Decompression\DeflateDecompression.cs"
/>
<Compile
Include=
"Decompression\GZipDecompression.cs"
/>
<Compile
Include=
"Decompression\IDecompression.cs"
/>
<Compile
Include=
"EventArguments\CertificateSelectionEventArgs.cs"
/>
<Compile
Include=
"EventArguments\CertificateValidationEventArgs.cs"
/>
<Compile
Include=
"EventArguments\DataEventArgs.cs"
/>
<Compile
Include=
"EventArguments\SessionEventArgs.cs"
/>
<Compile
Include=
"EventArguments\TunnelConnectEventArgs.cs"
/>
<Compile
Include=
"Exceptions\BodyNotFoundException.cs"
/>
<Compile
Include=
"Exceptions\ProxyAuthorizationException.cs"
/>
<Compile
Include=
"Exceptions\ProxyException.cs"
/>
<Compile
Include=
"Exceptions\ProxyHttpException.cs"
/>
<Compile
Include=
"Extensions\ByteArrayExtensions.cs"
/>
<Compile
Include=
"Extensions\DotNet45Extensions.cs"
/>
<Compile
Include=
"Extensions\FuncExtensions.cs"
/>
<Compile
Include=
"Extensions\HttpWebRequestExtensions.cs"
/>
<Compile
Include=
"Extensions\HttpWebResponseExtensions.cs"
/>
<Compile
Include=
"Extensions\StreamExtensions.cs"
/>
<Compile
Include=
"Extensions\StringExtensions.cs"
/>
<Compile
Include=
"Extensions\TcpExtensions.cs"
/>
<Compile
Include=
"Helpers\Firefox.cs"
/>
<Compile
Include=
"Helpers\HttpRequestWriter.cs"
/>
<Compile
Include=
"Helpers\HttpResponseWriter.cs"
/>
<Compile
Include=
"Helpers\HttpWriter.cs"
/>
<Compile
Include=
"Helpers\HttpHelper.cs"
/>
<Compile
Include=
"Helpers\Network.cs"
/>
<Compile
Include=
"Helpers\Tcp.cs"
/>
<Compile
Include=
"Http\ConnectRequest.cs"
/>
<Compile
Include=
"Http\ConnectResponse.cs"
/>
<Compile
Include=
"Http\HeaderCollection.cs"
/>
<Compile
Include=
"Http\HeaderParser.cs"
/>
<Compile
Include=
"Http\HttpWebClient.cs"
/>
<Compile
Include=
"Http\Request.cs"
/>
<Compile
Include=
"Http\Response.cs"
/>
<Compile
Include=
"Http\Responses\GenericResponse.cs"
/>
<Compile
Include=
"Http\Responses\OkResponse.cs"
/>
<Compile
Include=
"Http\Responses\RedirectResponse.cs"
/>
<Compile
Include=
"Models\EndPoint.cs"
/>
<Compile
Include=
"Models\ExternalProxy.cs"
/>
<Compile
Include=
"Models\HttpHeader.cs"
/>
<Compile
Include=
"Network\CachedCertificate.cs"
/>
<Compile
Include=
"Network\Certificate\BCCertificateMaker.cs"
/>
<Compile
Include=
"Network\Certificate\ICertificateMaker.cs"
/>
<Compile
Include=
"Network\Certificate\WinCertificateMaker.cs"
/>
<Compile
Include=
"Network\CertificateManager.cs"
/>
<Compile
Include=
"Network\ProxyClient.cs"
/>
<Compile
Include=
"Network\Tcp\TcpConnection.cs"
/>
<Compile
Include=
"Network\Tcp\TcpConnectionFactory.cs"
/>
<Compile
Include=
"Network\WinAuth\Security\Common.cs"
/>
<Compile
Include=
"Network\WinAuth\Security\LittleEndian.cs"
/>
<Compile
Include=
"Network\WinAuth\Security\Message.cs"
/>
<Compile
Include=
"Network\WinAuth\Security\State.cs"
/>
<Compile
Include=
"Network\WinAuth\Security\WinAuthEndPoint.cs"
/>
<Compile
Include=
"Network\WinAuth\WinAuthHandler.cs"
/>
<Compile
Include=
"Properties\AssemblyInfo.cs"
/>
<Compile
Include=
"Shared\ProxyConstants.cs"
/>
<Compile
Include=
"WinAuthHandler.cs"
/>
<Compile
Include=
"CertificateHandler.cs"
/>
<Compile
Include=
"ProxyAuthorizationHandler.cs"
/>
<Compile
Include=
"ProxyServer.cs"
/>
<Compile
Include=
"RequestHandler.cs"
/>
<Compile
Include=
"ResponseHandler.cs"
/>
</ItemGroup>
<ItemGroup>
<Compile
Include=
"Helpers\WinHttp\NativeMethods.WinHttp.cs"
/>
<Compile
Include=
"Helpers\WinHttp\WinHttpHandle.cs"
/>
<Compile
Include=
"Helpers\WinHttp\WinHttpWebProxyFinder.cs"
/>
<Compile
Include=
"Helpers\NativeMethods.SystemProxy.cs"
/>
<Compile
Include=
"Helpers\NativeMethods.Tcp.cs"
/>
<Compile
Include=
"Helpers\ProxyInfo.cs"
/>
<Compile
Include=
"Helpers\RunTime.cs"
/>
<Compile
Include=
"Helpers\SystemProxy.cs"
/>
<Compile
Include=
"Network\Tcp\TcpRow.cs"
/>
<Compile
Include=
"Network\Tcp\TcpTable.cs"
/>
</ItemGroup>
<ItemGroup>
<COMReference
Include=
"CERTENROLLLib"
Condition=
"'$(OS)' != 'Unix'"
>
<Guid>
{728AB348-217D-11DA-B2A4-000E7BBB2B09}
</Guid>
<VersionMajor>
1
</VersionMajor>
<VersionMinor>
0
</VersionMinor>
<Lcid>
0
</Lcid>
<WrapperTool>
tlbimp
</WrapperTool>
<Isolated>
False
</Isolated>
<EmbedInteropTypes>
True
</EmbedInteropTypes>
</COMReference>
</ItemGroup>
<ItemGroup>
<None
Include=
"app.config"
/>
<None
Include=
"packages.config"
/>
<None
Include=
"StrongNameKey.snk"
/>
<PackageReference Include="Portable.BouncyCastle" Version="1.8.1.2" />
<PackageReference Include="StreamExtended" Version="1.0.18" />
</ItemGroup>
<ItemGroup
/>
<Import
Project=
"$(MSBuildToolsPath)\Microsoft.CSharp.targets"
/>
<Import
Project=
"$(SolutionDir)\.nuget\NuGet.targets"
Condition=
"Exists('$(SolutionDir)\.nuget\NuGet.targets')"
/>
<Target
Name=
"EnsureNuGetPackageBuildImports"
BeforeTargets=
"PrepareForBuild"
>
<PropertyGroup>
<ErrorText>
This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
</ErrorText>
</PropertyGroup>
<Error
Condition=
"!Exists('$(SolutionDir)\.nuget\NuGet.targets')"
Text=
"$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))"
/>
</Target>
<!-- 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>
\ No newline at end of file
Titanium.Web.Proxy/Titanium.Web.Proxy.nuspec
View file @
b6140f19
...
...
@@ -13,13 +13,13 @@
<releaseNotes></releaseNotes>
<copyright>
Copyright
©
Titanium. All rights reserved.
</copyright>
<tags></tags>
<dependencies>
<dependency
id=
"StreamExtended"
version=
"1.0.18"
/>
<dependency
id=
"Portable.BouncyCastle"
version=
"1.8.1.2"
/>
<dependencies>
<dependency
id=
"StreamExtended"
version=
"1.0.18"
/>
<dependency
id=
"Portable.BouncyCastle"
version=
"1.8.1.2"
/>
</dependencies>
</metadata>
<files>
<file
src=
"bin\$configuration$
\Titanium.Web.Proxy.dll"
target=
"lib\net45"
/>
<file
src=
"bin\$configuration$\netstandard1.6\Titanium.Web.Proxy.*"
target=
"lib\netstandard1.6
"
/>
<file
src=
"bin\$configuration$\net45
\Titanium.Web.Proxy.dll"
target=
"lib\net45"
/>
<file
src=
"bin\$configuration$\netstandard2.0\Titanium.Web.Proxy.*"
target=
"lib\netstandard2.0
"
/>
</files>
</package>
Titanium.Web.Proxy/WinAuthHandler.cs
View file @
b6140f19
using
System
;
#
if
NET45
using
System
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Threading.Tasks
;
...
...
@@ -148,3 +149,4 @@ namespace Titanium.Web.Proxy
}
}
}
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment