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
b27ba8cf
Unverified
Commit
b27ba8cf
authored
Mar 23, 2018
by
honfika
Committed by
GitHub
Mar 23, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #387 from justcoding121/develop
Merge to beta
parents
553c89ba
2b9a7d35
Show whitespace changes
Inline
Side-by-side
Showing
29 changed files
with
295 additions
and
286 deletions
+295
-286
ProxyTestController.cs
.../Titanium.Web.Proxy.Examples.Basic/ProxyTestController.cs
+10
-20
MainWindow.xaml.cs
Examples/Titanium.Web.Proxy.Examples.Wpf/MainWindow.xaml.cs
+10
-4
Titanium.Web.Proxy.Examples.Wpf.csproj
...Proxy.Examples.Wpf/Titanium.Web.Proxy.Examples.Wpf.csproj
+2
-2
packages.config
Examples/Titanium.Web.Proxy.Examples.Wpf/packages.config
+1
-1
README.md
README.md
+4
-6
CertificateManagerTests.cs
...s/Titanium.Web.Proxy.UnitTests/CertificateManagerTests.cs
+2
-2
CertificateHandler.cs
Titanium.Web.Proxy/CertificateHandler.cs
+2
-2
SessionEventArgs.cs
Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
+2
-2
TunnelConnectEventArgs.cs
Titanium.Web.Proxy/EventArguments/TunnelConnectEventArgs.cs
+4
-2
ExceptionHandler.cs
Titanium.Web.Proxy/ExceptionHandler.cs
+6
-0
BodyNotFoundException.cs
Titanium.Web.Proxy/Exceptions/BodyNotFoundException.cs
+1
-1
ProxyAuthorizationException.cs
Titanium.Web.Proxy/Exceptions/ProxyAuthorizationException.cs
+6
-1
ProxyHttpException.cs
Titanium.Web.Proxy/Exceptions/ProxyHttpException.cs
+1
-1
FuncExtensions.cs
Titanium.Web.Proxy/Extensions/FuncExtensions.cs
+4
-30
Tcp.cs
Titanium.Web.Proxy/Helpers/Tcp.cs
+4
-4
EndPoint.cs
Titanium.Web.Proxy/Models/EndPoint.cs
+0
-154
ExplicitProxyEndPoint.cs
Titanium.Web.Proxy/Models/ExplicitProxyEndPoint.cs
+65
-0
ProxyEndPoint.cs
Titanium.Web.Proxy/Models/ProxyEndPoint.cs
+54
-0
TransparentProxyEndPoint.cs
Titanium.Web.Proxy/Models/TransparentProxyEndPoint.cs
+28
-0
BCCertificateMaker.cs
Titanium.Web.Proxy/Network/Certificate/BCCertificateMaker.cs
+2
-2
WinCertificateMaker.cs
...nium.Web.Proxy/Network/Certificate/WinCertificateMaker.cs
+2
-2
CertificateManager.cs
Titanium.Web.Proxy/Network/CertificateManager.cs
+9
-4
ProxyAuthorizationHandler.cs
Titanium.Web.Proxy/ProxyAuthorizationHandler.cs
+15
-9
ProxyServer.cs
Titanium.Web.Proxy/ProxyServer.cs
+6
-5
RequestHandler.cs
Titanium.Web.Proxy/RequestHandler.cs
+40
-26
ResponseHandler.cs
Titanium.Web.Proxy/ResponseHandler.cs
+12
-3
Titanium.Web.Proxy.csproj
Titanium.Web.Proxy/Titanium.Web.Proxy.csproj
+1
-1
Titanium.Web.Proxy.nuspec
Titanium.Web.Proxy/Titanium.Web.Proxy.nuspec
+1
-1
packages.config
Titanium.Web.Proxy/packages.config
+1
-1
No files found.
Examples/Titanium.Web.Proxy.Examples.Basic/ProxyTestController.cs
View file @
b27ba8cf
...
...
@@ -69,11 +69,8 @@ namespace Titanium.Web.Proxy.Examples.Basic
};
//Fired when a CONNECT request is received
explicitEndPoint
.
BeforeTunnelConnect
+=
OnBeforeTunnelConnect
;
explicitEndPoint
.
TunnelConnectRequest
+=
OnTunnelConnectRequest
;
explicitEndPoint
.
TunnelConnectResponse
+=
OnTunnelConnectResponse
;
explicitEndPoint
.
BeforeTunnelConnectRequest
+=
OnBeforeTunnelConnectRequest
;
explicitEndPoint
.
BeforeTunnelConnectResponse
+=
OnBeforeTunnelConnectResponse
;
//An explicit endpoint is where the client knows about the existence of a proxy
//So client sends request in a proxy friendly manner
...
...
@@ -111,9 +108,8 @@ namespace Titanium.Web.Proxy.Examples.Basic
public
void
Stop
()
{
explicitEndPoint
.
BeforeTunnelConnect
-=
OnBeforeTunnelConnect
;
explicitEndPoint
.
TunnelConnectRequest
-=
OnTunnelConnectRequest
;
explicitEndPoint
.
TunnelConnectResponse
-=
OnTunnelConnectResponse
;
explicitEndPoint
.
BeforeTunnelConnectRequest
-=
OnBeforeTunnelConnectRequest
;
explicitEndPoint
.
BeforeTunnelConnectResponse
-=
OnBeforeTunnelConnectResponse
;
proxyServer
.
BeforeRequest
-=
OnRequest
;
proxyServer
.
BeforeResponse
-=
OnResponse
;
...
...
@@ -126,27 +122,21 @@ namespace Titanium.Web.Proxy.Examples.Basic
//proxyServer.CertificateManager.RemoveTrustedRootCertificates();
}
private
async
Task
<
bool
>
OnBeforeTunnelConnect
(
string
hostnam
e
)
private
async
Task
OnBeforeTunnelConnectRequest
(
object
sender
,
TunnelConnectSessionEventArgs
e
)
{
string
hostname
=
e
.
WebSession
.
Request
.
RequestUri
.
Host
;
Console
.
WriteLine
(
"Tunnel to: "
+
hostname
);
if
(
hostname
.
Contains
(
"dropbox.com"
))
{
//Exclude Https addresses you don't want to proxy
//Useful for clients that use certificate pinning
//for example dropbox.com
return
await
Task
.
FromResult
(
true
);
}
else
{
return
await
Task
.
FromResult
(
false
);
}
e
.
Excluded
=
true
;
}
private
async
Task
OnTunnelConnectRequest
(
object
sender
,
TunnelConnectSessionEventArgs
e
)
{
Console
.
WriteLine
(
"Tunnel to: "
+
e
.
WebSession
.
Request
.
Host
);
}
private
async
Task
OnTunnelConnectResponse
(
object
sender
,
TunnelConnectSessionEventArgs
e
)
private
async
Task
On
Before
TunnelConnectResponse
(
object
sender
,
TunnelConnectSessionEventArgs
e
)
{
}
...
...
Examples/Titanium.Web.Proxy.Examples.Wpf/MainWindow.xaml.cs
View file @
b27ba8cf
...
...
@@ -102,8 +102,8 @@ namespace Titanium.Web.Proxy.Examples.Wpf
proxyServer
.
BeforeRequest
+=
ProxyServer_BeforeRequest
;
proxyServer
.
BeforeResponse
+=
ProxyServer_BeforeResponse
;
explicitEndPoint
.
TunnelConnectRequest
+=
ProxyServer_
TunnelConnectRequest
;
explicitEndPoint
.
TunnelConnectResponse
+=
ProxyServer_
TunnelConnectResponse
;
explicitEndPoint
.
BeforeTunnelConnectRequest
+=
ProxyServer_Before
TunnelConnectRequest
;
explicitEndPoint
.
BeforeTunnelConnectResponse
+=
ProxyServer_Before
TunnelConnectResponse
;
proxyServer
.
ClientConnectionCountChanged
+=
delegate
{
Dispatcher
.
Invoke
(()
=>
{
ClientConnectionCount
=
proxyServer
.
ClientConnectionCount
;
});
};
proxyServer
.
ServerConnectionCountChanged
+=
delegate
{
Dispatcher
.
Invoke
(()
=>
{
ServerConnectionCount
=
proxyServer
.
ServerConnectionCount
;
});
};
proxyServer
.
Start
();
...
...
@@ -113,15 +113,21 @@ namespace Titanium.Web.Proxy.Examples.Wpf
InitializeComponent
();
}
private
async
Task
ProxyServer_TunnelConnectRequest
(
object
sender
,
TunnelConnectSessionEventArgs
e
)
private
async
Task
ProxyServer_
Before
TunnelConnectRequest
(
object
sender
,
TunnelConnectSessionEventArgs
e
)
{
string
hostname
=
e
.
WebSession
.
Request
.
RequestUri
.
Host
;
if
(
hostname
.
EndsWith
(
"webex.com"
))
{
e
.
Excluded
=
true
;
}
await
Dispatcher
.
InvokeAsync
(()
=>
{
AddSession
(
e
);
});
}
private
async
Task
ProxyServer_TunnelConnectResponse
(
object
sender
,
SessionEventArgs
e
)
private
async
Task
ProxyServer_
Before
TunnelConnectResponse
(
object
sender
,
SessionEventArgs
e
)
{
await
Dispatcher
.
InvokeAsync
(()
=>
{
...
...
Examples/Titanium.Web.Proxy.Examples.Wpf/Titanium.Web.Proxy.Examples.Wpf.csproj
View file @
b27ba8cf
...
...
@@ -51,8 +51,8 @@
<WarningLevel>
4
</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference
Include=
"StreamExtended, Version=1.0.13
5
.0, Culture=neutral, PublicKeyToken=bbfa0f1d54f50043, processorArchitecture=MSIL"
>
<HintPath>
..\..\packages\StreamExtended.1.0.13
5
-beta\lib\net45\StreamExtended.dll
</HintPath>
<Reference
Include=
"StreamExtended, Version=1.0.13
8
.0, Culture=neutral, PublicKeyToken=bbfa0f1d54f50043, processorArchitecture=MSIL"
>
<HintPath>
..\..\packages\StreamExtended.1.0.13
8
-beta\lib\net45\StreamExtended.dll
</HintPath>
</Reference>
<Reference
Include=
"System"
/>
<Reference
Include=
"System.Data"
/>
...
...
Examples/Titanium.Web.Proxy.Examples.Wpf/packages.config
View file @
b27ba8cf
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<
packages
>
<
package
id
=
"StreamExtended"
version
=
"1.0.13
5
-beta"
targetFramework
=
"net45"
/>
<
package
id
=
"StreamExtended"
version
=
"1.0.13
8
-beta"
targetFramework
=
"net45"
/>
</
packages
>
\ No newline at end of file
README.md
View file @
b27ba8cf
...
...
@@ -126,18 +126,16 @@ Sample request and response event handlers
private
IDictionary
<
Guid
,
string
>
requestBodyHistory
=
new
ConcurrentDictionary
<
Guid
,
string
>();
private
async
Task
<
bool
>
OnBeforeTunnelConnect
(
string
hostnam
e
)
private
async
Task
OnBeforeTunnelConnectRequest
(
object
sender
,
TunnelConnectSessionEventArgs
e
)
{
string
hostname
=
e
.
WebSession
.
Request
.
RequestUri
.
Host
;
if
(
hostname
.
Contains
(
"dropbox.com"
))
{
//Exclude Https addresses you don't want to proxy
//Useful for clients that use certificate pinning
//for example dropbox.com
return
await
Task
.
FromResult
(
true
);
}
else
{
return
await
Task
.
FromResult
(
false
);
e
.
Excluded
=
true
;
}
}
...
...
Tests/Titanium.Web.Proxy.UnitTests/CertificateManagerTests.cs
View file @
b27ba8cf
...
...
@@ -19,7 +19,7 @@ namespace Titanium.Web.Proxy.UnitTests
{
var
tasks
=
new
List
<
Task
>();
var
mgr
=
new
CertificateManager
(
null
,
null
,
false
,
false
,
false
,
new
Lazy
<
Action
<
Exception
>
>(()
=>
(
e
=>
var
mgr
=
new
CertificateManager
(
null
,
null
,
false
,
false
,
false
,
new
Lazy
<
ExceptionHandler
>(()
=>
(
e
=>
{
//Console.WriteLine(e.ToString() + e.InnerException != null ? e.InnerException.ToString() : string.Empty);
})).
Value
);
...
...
@@ -48,7 +48,7 @@ namespace Titanium.Web.Proxy.UnitTests
{
var
tasks
=
new
List
<
Task
>();
var
mgr
=
new
CertificateManager
(
null
,
null
,
false
,
false
,
false
,
new
Lazy
<
Action
<
Exception
>
>(()
=>
(
e
=>
var
mgr
=
new
CertificateManager
(
null
,
null
,
false
,
false
,
false
,
new
Lazy
<
ExceptionHandler
>(()
=>
(
e
=>
{
//Console.WriteLine(e.ToString() + e.InnerException != null ? e.InnerException.ToString() : string.Empty);
})).
Value
);
...
...
Titanium.Web.Proxy/CertificateHandler.cs
View file @
b27ba8cf
...
...
@@ -29,7 +29,7 @@ namespace Titanium.Web.Proxy
};
//why is the sender null?
ServerCertificateValidationCallback
.
Invoke
Parallel
(
this
,
args
);
ServerCertificateValidationCallback
.
Invoke
Async
(
this
,
args
,
exceptionFunc
).
Wait
(
);
return
args
.
IsValid
;
}
...
...
@@ -88,7 +88,7 @@ namespace Titanium.Web.Proxy
};
//why is the sender null?
ClientCertificateSelectionCallback
.
Invoke
Parallel
(
this
,
args
);
ClientCertificateSelectionCallback
.
Invoke
Async
(
this
,
args
,
exceptionFunc
).
Wait
(
);
return
args
.
ClientCertificate
;
}
...
...
Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
View file @
b27ba8cf
...
...
@@ -29,7 +29,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// </summary>
private
readonly
int
bufferSize
;
private
readonly
Action
<
Exception
>
exceptionFunc
;
private
readonly
ExceptionHandler
exceptionFunc
;
/// <summary>
/// Backing field for corresponding public property
...
...
@@ -105,7 +105,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// </summary>
internal
SessionEventArgs
(
int
bufferSize
,
ProxyEndPoint
endPoint
,
Action
<
Exception
>
exceptionFunc
)
ExceptionHandler
exceptionFunc
)
{
this
.
bufferSize
=
bufferSize
;
this
.
exceptionFunc
=
exceptionFunc
;
...
...
Titanium.Web.Proxy/EventArguments/TunnelConnectEventArgs.cs
View file @
b27ba8cf
...
...
@@ -6,9 +6,11 @@ namespace Titanium.Web.Proxy.EventArguments
{
public
class
TunnelConnectSessionEventArgs
:
SessionEventArgs
{
public
bool
IsHttpsConnect
{
get
;
set
;
}
public
bool
Excluded
{
get
;
set
;
}
internal
TunnelConnectSessionEventArgs
(
int
bufferSize
,
ProxyEndPoint
endPoint
,
ConnectRequest
connectRequest
,
Action
<
Exception
>
exceptionFunc
)
public
bool
IsHttpsConnect
{
get
;
internal
set
;
}
internal
TunnelConnectSessionEventArgs
(
int
bufferSize
,
ProxyEndPoint
endPoint
,
ConnectRequest
connectRequest
,
ExceptionHandler
exceptionFunc
)
:
base
(
bufferSize
,
endPoint
,
exceptionFunc
)
{
WebSession
.
Request
=
connectRequest
;
...
...
Titanium.Web.Proxy/ExceptionHandler.cs
0 → 100644
View file @
b27ba8cf
using
System
;
namespace
Titanium.Web.Proxy
{
public
delegate
void
ExceptionHandler
(
Exception
exception
);
}
\ No newline at end of file
Titanium.Web.Proxy/Exceptions/BodyNotFoundException.cs
View file @
b27ba8cf
...
...
@@ -9,7 +9,7 @@
/// Constructor.
/// </summary>
/// <param name="message"></param>
public
BodyNotFoundException
(
string
message
)
:
base
(
message
)
internal
BodyNotFoundException
(
string
message
)
:
base
(
message
)
{
}
}
...
...
Titanium.Web.Proxy/Exceptions/ProxyAuthorizationException.cs
View file @
b27ba8cf
using
System
;
using
System.Collections.Generic
;
using
Titanium.Web.Proxy.EventArguments
;
using
Titanium.Web.Proxy.Models
;
namespace
Titanium.Web.Proxy.Exceptions
...
...
@@ -13,13 +14,17 @@ namespace Titanium.Web.Proxy.Exceptions
/// Instantiate new instance
/// </summary>
/// <param name="message">Exception message</param>
/// <param name="session">The <see cref="SessionEventArgs"/> instance containing the event data.</param>
/// <param name="innerException">Inner exception associated to upstream proxy authorization</param>
/// <param name="headers">Http's headers associated</param>
public
ProxyAuthorizationException
(
string
message
,
Exception
innerException
,
IEnumerable
<
HttpHeader
>
headers
)
:
base
(
message
,
innerException
)
internal
ProxyAuthorizationException
(
string
message
,
SessionEventArgs
session
,
Exception
innerException
,
IEnumerable
<
HttpHeader
>
headers
)
:
base
(
message
,
innerException
)
{
Session
=
session
;
Headers
=
headers
;
}
public
SessionEventArgs
Session
{
get
;
}
/// <summary>
/// Headers associated with the authorization exception
/// </summary>
...
...
Titanium.Web.Proxy/Exceptions/ProxyHttpException.cs
View file @
b27ba8cf
...
...
@@ -14,7 +14,7 @@ namespace Titanium.Web.Proxy.Exceptions
/// <param name="message">Message for this exception</param>
/// <param name="innerException">Associated inner exception</param>
/// <param name="sessionEventArgs">Instance of <see cref="EventArguments.SessionEventArgs"/> associated to the exception</param>
public
ProxyHttpException
(
string
message
,
Exception
innerException
,
SessionEventArgs
sessionEventArgs
)
:
base
(
message
,
innerException
)
internal
ProxyHttpException
(
string
message
,
Exception
innerException
,
SessionEventArgs
sessionEventArgs
)
:
base
(
message
,
innerException
)
{
SessionEventArgs
=
sessionEventArgs
;
}
...
...
Titanium.Web.Proxy/Extensions/FuncExtensions.cs
View file @
b27ba8cf
...
...
@@ -6,33 +6,8 @@ namespace Titanium.Web.Proxy.Extensions
{
internal
static
class
FuncExtensions
{
public
static
void
InvokeParallel
<
T
>(
this
AsyncEventHandler
<
T
>
callback
,
object
sender
,
T
args
)
{
var
invocationList
=
callback
.
GetInvocationList
();
var
handlerTasks
=
new
Task
[
invocationList
.
Length
];
for
(
int
i
=
0
;
i
<
invocationList
.
Length
;
i
++)
{
handlerTasks
[
i
]
=
((
AsyncEventHandler
<
T
>)
invocationList
[
i
])(
sender
,
args
);
}
Task
.
WhenAll
(
handlerTasks
).
Wait
();
}
public
static
async
Task
InvokeParallelAsync
<
T
>(
this
AsyncEventHandler
<
T
>
callback
,
object
sender
,
T
args
,
Action
<
Exception
>
exceptionFunc
)
{
var
invocationList
=
callback
.
GetInvocationList
();
var
handlerTasks
=
new
Task
[
invocationList
.
Length
];
for
(
int
i
=
0
;
i
<
invocationList
.
Length
;
i
++)
{
handlerTasks
[
i
]
=
InternalInvokeAsync
((
AsyncEventHandler
<
T
>)
invocationList
[
i
],
sender
,
args
,
exceptionFunc
);
}
await
Task
.
WhenAll
(
handlerTasks
);
}
public
static
async
Task
InvokeAsync
<
T
>(
this
AsyncEventHandler
<
T
>
callback
,
object
sender
,
T
args
,
Action
<
Exception
>
exceptionFunc
)
public
static
async
Task
InvokeAsync
<
T
>(
this
AsyncEventHandler
<
T
>
callback
,
object
sender
,
T
args
,
ExceptionHandler
exceptionFunc
)
{
var
invocationList
=
callback
.
GetInvocationList
();
...
...
@@ -42,16 +17,15 @@ namespace Titanium.Web.Proxy.Extensions
}
}
private
static
async
Task
InternalInvokeAsync
<
T
>(
AsyncEventHandler
<
T
>
callback
,
object
sender
,
T
args
,
Action
<
Exception
>
exceptionFunc
)
private
static
async
Task
InternalInvokeAsync
<
T
>(
AsyncEventHandler
<
T
>
callback
,
object
sender
,
T
args
,
ExceptionHandler
exceptionFunc
)
{
try
{
await
callback
(
sender
,
args
);
}
catch
(
Exception
e
x
)
catch
(
Exception
e
)
{
var
ex2
=
new
Exception
(
"Exception thrown in user event"
,
ex
);
exceptionFunc
(
ex2
);
exceptionFunc
(
new
Exception
(
"Exception thrown in user event"
,
e
));
}
}
}
...
...
Titanium.Web.Proxy/Helpers/Tcp.cs
View file @
b27ba8cf
...
...
@@ -122,7 +122,7 @@ namespace Titanium.Web.Proxy.Helpers
/// <param name="exceptionFunc"></param>
/// <returns></returns>
internal
static
async
Task
SendRawApm
(
Stream
clientStream
,
Stream
serverStream
,
int
bufferSize
,
Action
<
byte
[],
int
,
int
>
onDataSend
,
Action
<
byte
[],
int
,
int
>
onDataReceive
,
Action
<
Exception
>
exceptionFunc
)
Action
<
byte
[],
int
,
int
>
onDataSend
,
Action
<
byte
[],
int
,
int
>
onDataReceive
,
ExceptionHandler
exceptionFunc
)
{
var
tcs
=
new
TaskCompletionSource
<
bool
>();
var
cts
=
new
CancellationTokenSource
();
...
...
@@ -145,7 +145,7 @@ namespace Titanium.Web.Proxy.Helpers
}
private
static
void
BeginRead
(
Stream
inputStream
,
Stream
outputStream
,
byte
[]
buffer
,
CancellationTokenSource
cts
,
Action
<
byte
[],
int
,
int
>
onCopy
,
Action
<
Exception
>
exceptionFunc
)
ExceptionHandler
exceptionFunc
)
{
if
(
cts
.
IsCancellationRequested
)
{
...
...
@@ -221,7 +221,7 @@ namespace Titanium.Web.Proxy.Helpers
/// <param name="exceptionFunc"></param>
/// <returns></returns>
internal
static
async
Task
SendRawTap
(
Stream
clientStream
,
Stream
serverStream
,
int
bufferSize
,
Action
<
byte
[],
int
,
int
>
onDataSend
,
Action
<
byte
[],
int
,
int
>
onDataReceive
,
Action
<
Exception
>
exceptionFunc
)
Action
<
byte
[],
int
,
int
>
onDataSend
,
Action
<
byte
[],
int
,
int
>
onDataReceive
,
ExceptionHandler
exceptionFunc
)
{
var
cts
=
new
CancellationTokenSource
();
...
...
@@ -247,7 +247,7 @@ namespace Titanium.Web.Proxy.Helpers
/// <param name="exceptionFunc"></param>
/// <returns></returns>
internal
static
Task
SendRaw
(
Stream
clientStream
,
Stream
serverStream
,
int
bufferSize
,
Action
<
byte
[],
int
,
int
>
onDataSend
,
Action
<
byte
[],
int
,
int
>
onDataReceive
,
Action
<
Exception
>
exceptionFunc
)
Action
<
byte
[],
int
,
int
>
onDataSend
,
Action
<
byte
[],
int
,
int
>
onDataReceive
,
ExceptionHandler
exceptionFunc
)
{
#if NET45
return
SendRawApm
(
clientStream
,
serverStream
,
bufferSize
,
onDataSend
,
onDataReceive
,
exceptionFunc
);
...
...
Titanium.Web.Proxy/Models/EndPoint.cs
deleted
100644 → 0
View file @
553c89ba
using
System
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Net
;
using
System.Net.Sockets
;
using
System.Security.Cryptography.X509Certificates
;
using
System.Text.RegularExpressions
;
using
System.Threading.Tasks
;
using
Titanium.Web.Proxy.EventArguments
;
using
Titanium.Web.Proxy.Extensions
;
namespace
Titanium.Web.Proxy.Models
{
/// <summary>
/// An abstract endpoint where the proxy listens
/// </summary>
public
abstract
class
ProxyEndPoint
{
/// <summary>
/// Constructor.
/// </summary>
/// <param name="ipAddress"></param>
/// <param name="port"></param>
/// <param name="enableSsl"></param>
protected
ProxyEndPoint
(
IPAddress
ipAddress
,
int
port
,
bool
enableSsl
)
{
IpAddress
=
ipAddress
;
Port
=
port
;
EnableSsl
=
enableSsl
;
}
/// <summary>
/// underlying TCP Listener object
/// </summary>
internal
TcpListener
Listener
{
get
;
set
;
}
/// <summary>
/// Ip Address we are listening.
/// </summary>
public
IPAddress
IpAddress
{
get
;
internal
set
;
}
/// <summary>
/// Port we are listening.
/// </summary>
public
int
Port
{
get
;
internal
set
;
}
/// <summary>
/// Enable SSL?
/// </summary>
public
bool
EnableSsl
{
get
;
internal
set
;
}
/// <summary>
/// Is IPv6 enabled?
/// </summary>
public
bool
IpV6Enabled
=>
Equals
(
IpAddress
,
IPAddress
.
IPv6Any
)
||
Equals
(
IpAddress
,
IPAddress
.
IPv6Loopback
)
||
Equals
(
IpAddress
,
IPAddress
.
IPv6None
);
}
/// <summary>
/// A proxy endpoint that the client is aware of
/// So client application know that it is communicating with a proxy server
/// </summary>
public
class
ExplicitProxyEndPoint
:
ProxyEndPoint
{
internal
List
<
Regex
>
ExcludedHttpsHostNameRegexList
;
internal
List
<
Regex
>
IncludedHttpsHostNameRegexList
;
internal
bool
IsSystemHttpProxy
{
get
;
set
;
}
internal
bool
IsSystemHttpsProxy
{
get
;
set
;
}
/// <summary>
/// Generic certificate to use for SSL decryption.
/// </summary>
public
X509Certificate2
GenericCertificate
{
get
;
set
;
}
/// <summary>
/// Return true if this HTTP connect request should'nt be decrypted and instead be relayed
/// Valid only for explicit endpoints
/// </summary>
public
Func
<
string
,
Task
<
bool
>>
BeforeTunnelConnect
;
/// <summary>
/// Intercept tunnel connect request
/// Valid only for explicit endpoints
/// </summary>
public
event
AsyncEventHandler
<
TunnelConnectSessionEventArgs
>
TunnelConnectRequest
;
/// <summary>
/// Intercept tunnel connect response
/// Valid only for explicit endpoints
/// </summary>
public
event
AsyncEventHandler
<
TunnelConnectSessionEventArgs
>
TunnelConnectResponse
;
/// <summary>
/// Constructor.
/// </summary>
/// <param name="ipAddress"></param>
/// <param name="port"></param>
/// <param name="enableSsl"></param>
public
ExplicitProxyEndPoint
(
IPAddress
ipAddress
,
int
port
,
bool
enableSsl
)
:
base
(
ipAddress
,
port
,
enableSsl
)
{
}
internal
async
Task
InvokeTunnectConnectRequest
(
ProxyServer
proxyServer
,
TunnelConnectSessionEventArgs
connectArgs
,
Action
<
Exception
>
exceptionFunc
)
{
if
(
TunnelConnectRequest
!=
null
)
{
await
TunnelConnectRequest
.
InvokeAsync
(
proxyServer
,
connectArgs
,
exceptionFunc
);
}
}
internal
async
Task
InvokeTunnectConnectResponse
(
ProxyServer
proxyServer
,
TunnelConnectSessionEventArgs
connectArgs
,
Action
<
Exception
>
exceptionFunc
)
{
if
(
TunnelConnectResponse
!=
null
)
{
await
TunnelConnectResponse
.
InvokeAsync
(
proxyServer
,
connectArgs
,
exceptionFunc
);
}
}
internal
async
Task
InvokeTunnectConnectResponse
(
ProxyServer
proxyServer
,
TunnelConnectSessionEventArgs
connectArgs
,
Action
<
Exception
>
exceptionFunc
,
bool
isClientHello
)
{
if
(
TunnelConnectResponse
!=
null
)
{
connectArgs
.
IsHttpsConnect
=
isClientHello
;
await
TunnelConnectResponse
.
InvokeAsync
(
proxyServer
,
connectArgs
,
exceptionFunc
);
}
}
}
/// <summary>
/// A proxy end point client is not aware of
/// Usefull when requests are redirected to this proxy end point through port forwarding
/// </summary>
public
class
TransparentProxyEndPoint
:
ProxyEndPoint
{
/// <summary>
/// Name of the Certificate need to be sent (same as the hostname we want to proxy)
/// This is valid only when UseServerNameIndication is set to false
/// </summary>
public
string
GenericCertificateName
{
get
;
set
;
}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="ipAddress"></param>
/// <param name="port"></param>
/// <param name="enableSsl"></param>
public
TransparentProxyEndPoint
(
IPAddress
ipAddress
,
int
port
,
bool
enableSsl
)
:
base
(
ipAddress
,
port
,
enableSsl
)
{
GenericCertificateName
=
"localhost"
;
}
}
}
Titanium.Web.Proxy/Models/ExplicitProxyEndPoint.cs
0 → 100644
View file @
b27ba8cf
using
System
;
using
System.Net
;
using
System.Security.Cryptography.X509Certificates
;
using
System.Threading.Tasks
;
using
Titanium.Web.Proxy.EventArguments
;
using
Titanium.Web.Proxy.Extensions
;
namespace
Titanium.Web.Proxy.Models
{
/// <summary>
/// A proxy endpoint that the client is aware of
/// So client application know that it is communicating with a proxy server
/// </summary>
public
class
ExplicitProxyEndPoint
:
ProxyEndPoint
{
internal
bool
IsSystemHttpProxy
{
get
;
set
;
}
internal
bool
IsSystemHttpsProxy
{
get
;
set
;
}
/// <summary>
/// Generic certificate to use for SSL decryption.
/// </summary>
public
X509Certificate2
GenericCertificate
{
get
;
set
;
}
/// <summary>
/// Intercept tunnel connect request
/// Valid only for explicit endpoints
/// Set the <see cref="TunnelConnectSessionEventArgs.Excluded"/> property to true if this HTTP connect request should'nt be decrypted and instead be relayed
/// </summary>
public
event
AsyncEventHandler
<
TunnelConnectSessionEventArgs
>
BeforeTunnelConnectRequest
;
/// <summary>
/// Intercept tunnel connect response
/// Valid only for explicit endpoints
/// </summary>
public
event
AsyncEventHandler
<
TunnelConnectSessionEventArgs
>
BeforeTunnelConnectResponse
;
/// <summary>
/// Constructor.
/// </summary>
/// <param name="ipAddress"></param>
/// <param name="port"></param>
/// <param name="enableSsl"></param>
public
ExplicitProxyEndPoint
(
IPAddress
ipAddress
,
int
port
,
bool
enableSsl
)
:
base
(
ipAddress
,
port
,
enableSsl
)
{
}
internal
async
Task
InvokeBeforeTunnelConnectRequest
(
ProxyServer
proxyServer
,
TunnelConnectSessionEventArgs
connectArgs
,
ExceptionHandler
exceptionFunc
)
{
if
(
BeforeTunnelConnectRequest
!=
null
)
{
await
BeforeTunnelConnectRequest
.
InvokeAsync
(
proxyServer
,
connectArgs
,
exceptionFunc
);
}
}
internal
async
Task
InvokeBeforeTunnectConnectResponse
(
ProxyServer
proxyServer
,
TunnelConnectSessionEventArgs
connectArgs
,
ExceptionHandler
exceptionFunc
,
bool
isClientHello
=
false
)
{
if
(
BeforeTunnelConnectResponse
!=
null
)
{
connectArgs
.
IsHttpsConnect
=
isClientHello
;
await
BeforeTunnelConnectResponse
.
InvokeAsync
(
proxyServer
,
connectArgs
,
exceptionFunc
);
}
}
}
}
\ No newline at end of file
Titanium.Web.Proxy/Models/ProxyEndPoint.cs
0 → 100644
View file @
b27ba8cf
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Net
;
using
System.Net.Sockets
;
using
System.Text.RegularExpressions
;
namespace
Titanium.Web.Proxy.Models
{
/// <summary>
/// An abstract endpoint where the proxy listens
/// </summary>
public
abstract
class
ProxyEndPoint
{
/// <summary>
/// Constructor.
/// </summary>
/// <param name="ipAddress"></param>
/// <param name="port"></param>
/// <param name="enableSsl"></param>
protected
ProxyEndPoint
(
IPAddress
ipAddress
,
int
port
,
bool
enableSsl
)
{
IpAddress
=
ipAddress
;
Port
=
port
;
EnableSsl
=
enableSsl
;
}
/// <summary>
/// underlying TCP Listener object
/// </summary>
internal
TcpListener
Listener
{
get
;
set
;
}
/// <summary>
/// Ip Address we are listening.
/// </summary>
public
IPAddress
IpAddress
{
get
;
}
/// <summary>
/// Port we are listening.
/// </summary>
public
int
Port
{
get
;
internal
set
;
}
/// <summary>
/// Enable SSL?
/// </summary>
public
bool
EnableSsl
{
get
;
}
/// <summary>
/// Is IPv6 enabled?
/// </summary>
public
bool
IpV6Enabled
=>
Equals
(
IpAddress
,
IPAddress
.
IPv6Any
)
||
Equals
(
IpAddress
,
IPAddress
.
IPv6Loopback
)
||
Equals
(
IpAddress
,
IPAddress
.
IPv6None
);
}
}
Titanium.Web.Proxy/Models/TransparentProxyEndPoint.cs
0 → 100644
View file @
b27ba8cf
using
System.Net
;
namespace
Titanium.Web.Proxy.Models
{
/// <summary>
/// A proxy end point client is not aware of
/// Usefull when requests are redirected to this proxy end point through port forwarding
/// </summary>
public
class
TransparentProxyEndPoint
:
ProxyEndPoint
{
/// <summary>
/// Name of the Certificate need to be sent (same as the hostname we want to proxy)
/// This is valid only when UseServerNameIndication is set to false
/// </summary>
public
string
GenericCertificateName
{
get
;
set
;
}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="ipAddress"></param>
/// <param name="port"></param>
/// <param name="enableSsl"></param>
public
TransparentProxyEndPoint
(
IPAddress
ipAddress
,
int
port
,
bool
enableSsl
)
:
base
(
ipAddress
,
port
,
enableSsl
)
{
GenericCertificateName
=
"localhost"
;
}
}
}
\ No newline at end of file
Titanium.Web.Proxy/Network/Certificate/BCCertificateMaker.cs
View file @
b27ba8cf
...
...
@@ -33,9 +33,9 @@ namespace Titanium.Web.Proxy.Network.Certificate
// Set this flag to true when exception detected to avoid further exceptions
private
static
bool
doNotSetFriendlyName
;
private
readonly
Action
<
Exception
>
exceptionFunc
;
private
readonly
ExceptionHandler
exceptionFunc
;
internal
BCCertificateMaker
(
Action
<
Exception
>
exceptionFunc
)
internal
BCCertificateMaker
(
ExceptionHandler
exceptionFunc
)
{
this
.
exceptionFunc
=
exceptionFunc
;
}
...
...
Titanium.Web.Proxy/Network/Certificate/WinCertificateMaker.cs
View file @
b27ba8cf
...
...
@@ -43,12 +43,12 @@ namespace Titanium.Web.Proxy.Network.Certificate
private
object
sharedPrivateKey
;
private
readonly
Action
<
Exception
>
exceptionFunc
;
private
readonly
ExceptionHandler
exceptionFunc
;
/// <summary>
/// Constructor.
/// </summary>
internal
WinCertificateMaker
(
Action
<
Exception
>
exceptionFunc
)
internal
WinCertificateMaker
(
ExceptionHandler
exceptionFunc
)
{
this
.
exceptionFunc
=
exceptionFunc
;
typeX500DN
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CX500DistinguishedName"
,
true
);
...
...
Titanium.Web.Proxy/Network/CertificateManager.cs
View file @
b27ba8cf
...
...
@@ -59,7 +59,7 @@ namespace Titanium.Web.Proxy.Network
private
readonly
ConcurrentDictionary
<
string
,
CachedCertificate
>
certificateCache
;
private
readonly
ConcurrentDictionary
<
string
,
Task
<
X509Certificate2
>>
pendingCertificateCreationTasks
;
private
readonly
Action
<
Exception
>
exceptionFunc
;
private
readonly
ExceptionHandler
exceptionFunc
;
/// <summary>
/// Is the root certificate used by this proxy is valid?
...
...
@@ -107,7 +107,9 @@ namespace Titanium.Web.Proxy.Network
if
(
certEngine
==
null
)
{
certEngine
=
engine
==
CertificateEngine
.
BouncyCastle
?
(
ICertificateMaker
)
new
BCCertificateMaker
(
exceptionFunc
)
:
new
WinCertificateMaker
(
exceptionFunc
);
certEngine
=
engine
==
CertificateEngine
.
BouncyCastle
?
(
ICertificateMaker
)
new
BCCertificateMaker
(
exceptionFunc
)
:
new
WinCertificateMaker
(
exceptionFunc
);
}
}
}
...
...
@@ -196,9 +198,9 @@ namespace Titanium.Web.Proxy.Network
/// <param name="rootCertificateIssuerName">Name of root certificate issuer.</param>
/// <param name="userTrustRootCertificate"></param>
/// <param name="machineTrustRootCertificate">Note:setting machineTrustRootCertificate to true will force userTrustRootCertificate to true</param>
/// <param name="trustRootCertificateAsAdmin
"></param>
/// <param name="trustRootCertificateAsAdmin"></param>
/// <param name="exceptionFunc"></param>
internal
CertificateManager
(
string
rootCertificateName
,
string
rootCertificateIssuerName
,
bool
userTrustRootCertificate
,
bool
machineTrustRootCertificate
,
bool
trustRootCertificateAsAdmin
,
Action
<
Exception
>
exceptionFunc
)
internal
CertificateManager
(
string
rootCertificateName
,
string
rootCertificateIssuerName
,
bool
userTrustRootCertificate
,
bool
machineTrustRootCertificate
,
bool
trustRootCertificateAsAdmin
,
ExceptionHandler
exceptionFunc
)
{
this
.
exceptionFunc
=
exceptionFunc
;
...
...
@@ -310,6 +312,7 @@ namespace Titanium.Web.Proxy.Network
/// <summary>
/// Make current machine trust the Root Certificate used by this proxy
/// </summary>
/// <param name="storeName"></param>
/// <param name="storeLocation"></param>
/// <returns></returns>
private
void
InstallCertificate
(
StoreName
storeName
,
StoreLocation
storeLocation
)
...
...
@@ -348,7 +351,9 @@ namespace Titanium.Web.Proxy.Network
/// <summary>
/// Remove the Root Certificate trust
/// </summary>
/// <param name="storeName"></param>
/// <param name="storeLocation"></param>
/// <param name="certificate"></param>
/// <returns></returns>
private
void
UninstallCertificate
(
StoreName
storeName
,
StoreLocation
storeLocation
,
X509Certificate2
certificate
)
{
...
...
Titanium.Web.Proxy/ProxyAuthorizationHandler.cs
View file @
b27ba8cf
...
...
@@ -15,7 +15,7 @@ namespace Titanium.Web.Proxy
{
public
partial
class
ProxyServer
{
private
async
Task
<
bool
>
CheckAuthorization
(
HttpResponseWriter
clientStreamWriter
,
SessionEventArgs
session
)
private
async
Task
<
bool
>
CheckAuthorization
(
SessionEventArgs
session
)
{
if
(
AuthenticateUserFunc
==
null
)
{
...
...
@@ -29,7 +29,7 @@ namespace Titanium.Web.Proxy
var
header
=
httpHeaders
.
GetFirstHeader
(
KnownHeaders
.
ProxyAuthorization
);
if
(
header
==
null
)
{
session
.
WebSession
.
Response
=
await
SendAuthentication407Response
(
clientStreamWriter
,
"Proxy Authentication Required"
);
session
.
WebSession
.
Response
=
CreateAuthentication407Response
(
"Proxy Authentication Required"
);
return
false
;
}
...
...
@@ -37,7 +37,7 @@ namespace Titanium.Web.Proxy
if
(
headerValueParts
.
Length
!=
2
||
!
headerValueParts
[
0
].
EqualsIgnoreCase
(
KnownHeaders
.
ProxyAuthorizationBasic
))
{
//Return not authorized
session
.
WebSession
.
Response
=
await
SendAuthentication407Response
(
clientStreamWriter
,
"Proxy Authentication Invalid"
);
session
.
WebSession
.
Response
=
CreateAuthentication407Response
(
"Proxy Authentication Invalid"
);
return
false
;
}
...
...
@@ -46,25 +46,32 @@ namespace Titanium.Web.Proxy
if
(
colonIndex
==
-
1
)
{
//Return not authorized
session
.
WebSession
.
Response
=
await
SendAuthentication407Response
(
clientStreamWriter
,
"Proxy Authentication Invalid"
);
session
.
WebSession
.
Response
=
CreateAuthentication407Response
(
"Proxy Authentication Invalid"
);
return
false
;
}
string
username
=
decoded
.
Substring
(
0
,
colonIndex
);
string
password
=
decoded
.
Substring
(
colonIndex
+
1
);
return
await
AuthenticateUserFunc
(
username
,
password
);
bool
authenticated
=
await
AuthenticateUserFunc
(
username
,
password
);
if
(!
authenticated
)
{
//Return not authorized
session
.
WebSession
.
Response
=
CreateAuthentication407Response
(
"Proxy Authentication Invalid"
);
}
return
authenticated
;
}
catch
(
Exception
e
)
{
ExceptionFunc
(
new
ProxyAuthorizationException
(
"Error whilst authorizing request"
,
e
,
httpHeaders
));
ExceptionFunc
(
new
ProxyAuthorizationException
(
"Error whilst authorizing request"
,
session
,
e
,
httpHeaders
));
//Return not authorized
session
.
WebSession
.
Response
=
await
SendAuthentication407Response
(
clientStreamWriter
,
"Proxy Authentication Invalid"
);
session
.
WebSession
.
Response
=
CreateAuthentication407Response
(
"Proxy Authentication Invalid"
);
return
false
;
}
}
private
async
Task
<
Response
>
SendAuthentication407Response
(
HttpResponseWriter
clientStreamWriter
,
string
description
)
private
Response
CreateAuthentication407Response
(
string
description
)
{
var
response
=
new
Response
{
...
...
@@ -77,7 +84,6 @@ namespace Titanium.Web.Proxy
response
.
Headers
.
AddHeader
(
KnownHeaders
.
ProxyConnection
,
KnownHeaders
.
ProxyConnectionClose
);
response
.
Headers
.
FixProxyHeaders
();
await
clientStreamWriter
.
WriteResponseAsync
(
response
);
return
response
;
}
}
...
...
Titanium.Web.Proxy/ProxyServer.cs
View file @
b27ba8cf
...
...
@@ -53,12 +53,12 @@ namespace Titanium.Web.Proxy
/// <summary>
/// An default exception log func
/// </summary>
private
readonly
Lazy
<
Action
<
Exception
>>
defaultExceptionFunc
=
new
Lazy
<
Action
<
Exception
>
>(()
=>
(
e
=>
{
}));
private
readonly
Lazy
<
ExceptionHandler
>
defaultExceptionFunc
=
new
Lazy
<
ExceptionHandler
>(()
=>
(
e
=>
{
}));
/// <summary>
/// backing exception func for exposed public property
/// </summary>
private
Action
<
Exception
>
exceptionFunc
;
private
ExceptionHandler
exceptionFunc
;
/// <summary>
/// Is the proxy currently running
...
...
@@ -192,7 +192,7 @@ namespace Titanium.Web.Proxy
/// <summary>
/// Callback for error events in proxy
/// </summary>
public
Action
<
Exception
>
ExceptionFunc
public
ExceptionHandler
ExceptionFunc
{
get
=>
exceptionFunc
??
defaultExceptionFunc
.
Value
;
set
=>
exceptionFunc
=
value
;
...
...
@@ -210,7 +210,7 @@ namespace Titanium.Web.Proxy
/// </summary>
/// <param name="userTrustRootCertificate"></param>
/// <param name="machineTrustRootCertificate">Note:setting machineTrustRootCertificate to true will force userTrustRootCertificate to true</param>
/// <param name="trustRootCertificateAsAdmin
"></param>
/// <param name="trustRootCertificateAsAdmin"></param>
public
ProxyServer
(
bool
userTrustRootCertificate
=
true
,
bool
machineTrustRootCertificate
=
false
,
bool
trustRootCertificateAsAdmin
=
false
)
:
this
(
null
,
null
,
userTrustRootCertificate
,
machineTrustRootCertificate
,
trustRootCertificateAsAdmin
)
{
}
...
...
@@ -222,7 +222,7 @@ namespace Titanium.Web.Proxy
/// <param name="rootCertificateIssuerName">Name of root certificate issuer.</param>
/// <param name="userTrustRootCertificate"></param>
/// <param name="machineTrustRootCertificate">Note:setting machineTrustRootCertificate to true will force userTrustRootCertificate to true</param>
/// <param name="trustRootCertificateAsAdmin
"></param>
/// <param name="trustRootCertificateAsAdmin"></param>
public
ProxyServer
(
string
rootCertificateName
,
string
rootCertificateIssuerName
,
bool
userTrustRootCertificate
=
true
,
bool
machineTrustRootCertificate
=
false
,
bool
trustRootCertificateAsAdmin
=
false
)
{
//default values
...
...
@@ -660,6 +660,7 @@ namespace Titanium.Web.Proxy
endPoint
.
Listener
.
Server
.
Dispose
();
}
internal
void
UpdateClientConnectionCount
(
bool
increment
)
{
if
(
increment
)
...
...
Titanium.Web.Proxy/RequestHandler.cs
View file @
b27ba8cf
...
...
@@ -64,14 +64,6 @@ namespace Titanium.Web.Proxy
var
httpRemoteUri
=
new
Uri
(
"http://"
+
httpUrl
);
connectHostname
=
httpRemoteUri
.
Host
;
//filter out excluded host names
bool
excluded
=
false
;
if
(
endPoint
.
BeforeTunnelConnect
!=
null
)
{
excluded
=
await
endPoint
.
BeforeTunnelConnect
(
connectHostname
);
}
connectRequest
=
new
ConnectRequest
{
RequestUri
=
httpRemoteUri
,
...
...
@@ -85,12 +77,17 @@ namespace Titanium.Web.Proxy
connectArgs
.
ProxyClient
.
TcpClient
=
tcpClient
;
connectArgs
.
ProxyClient
.
ClientStream
=
clientStream
;
await
endPoint
.
Invoke
Tunnect
ConnectRequest
(
this
,
connectArgs
,
ExceptionFunc
);
await
endPoint
.
Invoke
BeforeTunnel
ConnectRequest
(
this
,
connectArgs
,
ExceptionFunc
);
//filter out excluded host names
bool
excluded
=
connectArgs
.
Excluded
;
if
(
await
CheckAuthorization
(
c
lientStreamWriter
,
c
onnectArgs
)
==
false
)
if
(
await
CheckAuthorization
(
connectArgs
)
==
false
)
{
await
endPoint
.
InvokeTunnectConnectResponse
(
this
,
connectArgs
,
ExceptionFunc
);
await
endPoint
.
InvokeBeforeTunnectConnectResponse
(
this
,
connectArgs
,
ExceptionFunc
);
//send the response
await
clientStreamWriter
.
WriteResponseAsync
(
connectArgs
.
WebSession
.
Response
);
return
;
}
...
...
@@ -108,7 +105,7 @@ namespace Titanium.Web.Proxy
connectRequest
.
ClientHelloInfo
=
clientHelloInfo
;
}
await
endPoint
.
InvokeTunnectConnectResponse
(
this
,
connectArgs
,
ExceptionFunc
,
isClientHello
);
await
endPoint
.
Invoke
Before
TunnectConnectResponse
(
this
,
connectArgs
,
ExceptionFunc
,
isClientHello
);
if
(!
excluded
&&
isClientHello
)
{
...
...
@@ -134,8 +131,9 @@ namespace Titanium.Web.Proxy
clientStreamReader
=
new
CustomBinaryReader
(
clientStream
,
BufferSize
);
clientStreamWriter
=
new
HttpResponseWriter
(
clientStream
,
BufferSize
);
}
catch
catch
(
Exception
e
)
{
ExceptionFunc
(
new
Exception
(
$"Could'nt authenticate client '
{
connectHostname
}
' with fake certificate."
,
e
));
sslStream
?.
Dispose
();
return
;
}
...
...
@@ -239,14 +237,21 @@ namespace Titanium.Web.Proxy
var
sslStream
=
new
SslStream
(
clientStream
);
clientStream
=
new
CustomBufferedStream
(
sslStream
,
BufferSize
);
string
sniHostName
=
clientHelloInfo
.
GetServerName
();
string
sniHostName
=
clientHelloInfo
.
GetServerName
()
??
endPoint
.
GenericCertificateName
;
string
certName
=
HttpHelper
.
GetWildCardDomainName
(
sniHostName
??
endPoint
.
GenericCertificateName
);
string
certName
=
HttpHelper
.
GetWildCardDomainName
(
sniHostName
);
var
certificate
=
await
CertificateManager
.
CreateCertificateAsync
(
certName
);
try
{
//Successfully managed to authenticate the client using the fake certificate
await
sslStream
.
AuthenticateAsServerAsync
(
certificate
,
false
,
SslProtocols
.
Tls
,
false
);
}
catch
(
Exception
e
)
{
ExceptionFunc
(
new
Exception
(
$"Could'nt authenticate client '
{
sniHostName
}
' with fake certificate."
,
e
));
return
;
}
}
//HTTPS server created - we can now decrypt the client's traffic
}
...
...
@@ -350,8 +355,12 @@ namespace Titanium.Web.Proxy
args
.
ProxyClient
.
ClientStreamWriter
=
clientStreamWriter
;
//proxy authorization check
if
(!
args
.
IsTransparent
&&
httpsConnectHostname
==
null
&&
await
CheckAuthorization
(
clientStreamWriter
,
args
)
==
false
)
if
(!
args
.
IsTransparent
&&
httpsConnectHostname
==
null
&&
await
CheckAuthorization
(
args
)
==
false
)
{
await
InvokeBeforeResponse
(
args
);
//send the response
await
clientStreamWriter
.
WriteResponseAsync
(
args
.
WebSession
.
Response
);
break
;
}
...
...
@@ -370,10 +379,7 @@ namespace Titanium.Web.Proxy
}
//If user requested interception do it
if
(
BeforeRequest
!=
null
)
{
await
BeforeRequest
.
InvokeAsync
(
this
,
args
,
ExceptionFunc
);
}
await
InvokeBeforeRequest
(
args
);
var
response
=
args
.
WebSession
.
Response
;
...
...
@@ -426,9 +432,9 @@ namespace Titanium.Web.Proxy
}
//If user requested call back then do it
if
(
BeforeResponse
!=
null
&&
!
args
.
WebSession
.
Response
.
ResponseLocked
)
if
(!
args
.
WebSession
.
Response
.
ResponseLocked
)
{
await
BeforeResponse
.
InvokeAsync
(
this
,
args
,
ExceptionFunc
);
await
InvokeBeforeResponse
(
args
);
}
await
TcpHelper
.
SendRaw
(
clientStream
,
connection
.
Stream
,
BufferSize
,
...
...
@@ -593,5 +599,13 @@ namespace Titanium.Web.Proxy
requestHeaders
.
FixProxyHeaders
();
}
private
async
Task
InvokeBeforeRequest
(
SessionEventArgs
args
)
{
if
(
BeforeRequest
!=
null
)
{
await
BeforeRequest
.
InvokeAsync
(
this
,
args
,
ExceptionFunc
);
}
}
}
}
Titanium.Web.Proxy/ResponseHandler.cs
View file @
b27ba8cf
...
...
@@ -35,10 +35,10 @@ namespace Titanium.Web.Proxy
args
.
ReRequest
=
false
;
//
I
f user requested call back then do it
if
(
BeforeResponse
!=
null
&&
!
response
.
ResponseLocked
)
//
i
f user requested call back then do it
if
(!
response
.
ResponseLocked
)
{
await
BeforeResponse
.
InvokeAsync
(
this
,
args
,
ExceptionFunc
);
await
InvokeBeforeResponse
(
args
);
}
//if user requested to send request again
...
...
@@ -125,5 +125,14 @@ namespace Titanium.Web.Proxy
var
compressor
=
CompressionFactory
.
GetCompression
(
encodingType
);
return
await
compressor
.
Compress
(
responseBodyStream
);
}
private
async
Task
InvokeBeforeResponse
(
SessionEventArgs
args
)
{
if
(
BeforeResponse
!=
null
)
{
await
BeforeResponse
.
InvokeAsync
(
this
,
args
,
ExceptionFunc
);
}
}
}
}
Titanium.Web.Proxy/Titanium.Web.Proxy.csproj
View file @
b27ba8cf
...
...
@@ -13,7 +13,7 @@
<ItemGroup>
<PackageReference Include="Portable.BouncyCastle" Version="1.8.1.4" />
<PackageReference Include="StreamExtended" Version="1.0.13
5
-beta" />
<PackageReference Include="StreamExtended" Version="1.0.13
8
-beta" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
...
...
Titanium.Web.Proxy/Titanium.Web.Proxy.nuspec
View file @
b27ba8cf
...
...
@@ -14,7 +14,7 @@
<copyright>
Copyright
©
Titanium. All rights reserved.
</copyright>
<tags></tags>
<dependencies>
<dependency
id=
"StreamExtended"
version=
"1.0.1
10
-beta"
/>
<dependency
id=
"StreamExtended"
version=
"1.0.1
38
-beta"
/>
<dependency
id=
"Portable.BouncyCastle"
version=
"1.8.1.4"
/>
</dependencies>
</metadata>
...
...
Titanium.Web.Proxy/packages.config
View file @
b27ba8cf
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<
packages
>
<
package
id
=
"Portable.BouncyCastle"
version
=
"1.8.1.4"
targetFramework
=
"net45"
/>
<
package
id
=
"StreamExtended"
version
=
"1.0.1
10
-beta"
targetFramework
=
"net45"
/>
<
package
id
=
"StreamExtended"
version
=
"1.0.1
38
-beta"
targetFramework
=
"net45"
/>
</
packages
>
\ No newline at end of file
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