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
8b46f917
Commit
8b46f917
authored
Jul 17, 2016
by
justcoding121
Committed by
GitHub
Jul 17, 2016
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #99 from justcoding121/release
Performance: Fix abrupt termination of SSL requests
parents
4456a224
e1cf60d6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
163 additions
and
146 deletions
+163
-146
Tcp.cs
Titanium.Web.Proxy/Helpers/Tcp.cs
+30
-48
TcpConnection.cs
Titanium.Web.Proxy/Network/TcpConnection.cs
+7
-3
TcpConnectionFactory.cs
Titanium.Web.Proxy/Network/TcpConnectionFactory.cs
+34
-44
ProxyServer.cs
Titanium.Web.Proxy/ProxyServer.cs
+43
-11
RequestHandler.cs
Titanium.Web.Proxy/RequestHandler.cs
+39
-26
ResponseHandler.cs
Titanium.Web.Proxy/ResponseHandler.cs
+10
-14
No files found.
Titanium.Web.Proxy/Helpers/Tcp.cs
View file @
8b46f917
...
@@ -9,26 +9,37 @@ using System.Text;
...
@@ -9,26 +9,37 @@ using System.Text;
using
System.Threading.Tasks
;
using
System.Threading.Tasks
;
using
Titanium.Web.Proxy.Extensions
;
using
Titanium.Web.Proxy.Extensions
;
using
Titanium.Web.Proxy.Models
;
using
Titanium.Web.Proxy.Models
;
using
Titanium.Web.Proxy.
Shared
;
using
Titanium.Web.Proxy.
Network
;
namespace
Titanium.Web.Proxy.Helpers
namespace
Titanium.Web.Proxy.Helpers
{
{
internal
class
TcpHelper
internal
class
TcpHelper
{
{
/// <summary>
/// <summary>
/// relays the input clientStream to the server at the specified host name & port with the given httpCmd & headers as prefix
/// relays the input clientStream to the server at the specified host name & port with the given httpCmd & headers as prefix
/// Usefull for websocket requests
/// Usefull for websocket requests
/// </summary>
/// </summary>
/// <param name="clientStream"></param>
/// <param name="bufferSize"></param>
/// <param name="connectionTimeOutSeconds"></param>
/// <param name="remoteHostName"></param>
/// <param name="httpCmd"></param>
/// <param name="httpCmd"></param>
/// <param name="httpVersion"></param>
/// <param name="requestHeaders"></param>
/// <param name="requestHeaders"></param>
/// <param name="hostName"></param>
/// <param name="tunnelPort"></param>
/// <param name="isHttps"></param>
/// <param name="isHttps"></param>
/// <param name="remotePort"></param>
/// <param name="supportedProtocols"></param>
/// <param name="remoteCertificateValidationCallback"></param>
/// <param name="localCertificateSelectionCallback"></param>
/// <param name="clientStream"></param>
/// <param name="tcpConnectionFactory"></param>
/// <returns></returns>
/// <returns></returns>
internal
static
async
Task
SendRaw
(
Stream
clientStream
,
string
httpCmd
,
Dictionary
<
string
,
HttpHeader
>
requestHeaders
,
string
hostName
,
internal
static
async
Task
SendRaw
(
int
bufferSize
,
int
connectionTimeOutSeconds
,
int
tunnelPort
,
bool
isHttps
,
SslProtocols
supportedProtocols
,
int
connectionTimeOutSeconds
)
string
remoteHostName
,
int
remotePort
,
string
httpCmd
,
Version
httpVersion
,
Dictionary
<
string
,
HttpHeader
>
requestHeaders
,
bool
isHttps
,
SslProtocols
supportedProtocols
,
RemoteCertificateValidationCallback
remoteCertificateValidationCallback
,
LocalCertificateSelectionCallback
localCertificateSelectionCallback
,
Stream
clientStream
,
TcpConnectionFactory
tcpConnectionFactory
)
{
{
//prepare the prefix content
//prepare the prefix content
StringBuilder
sb
=
null
;
StringBuilder
sb
=
null
;
...
@@ -54,40 +65,17 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -54,40 +65,17 @@ namespace Titanium.Web.Proxy.Helpers
sb
.
Append
(
Environment
.
NewLine
);
sb
.
Append
(
Environment
.
NewLine
);
}
}
var
tcpConnection
=
await
tcpConnectionFactory
.
CreateClient
(
bufferSize
,
connectionTimeOutSeconds
,
TcpClient
tunnelClient
=
null
;
remoteHostName
,
remotePort
,
Stream
tunnelStream
=
null
;
httpVersion
,
isHttps
,
//create the TcpClient to the server
supportedProtocols
,
remoteCertificateValidationCallback
,
localCertificateSelectionCallback
,
null
,
null
,
clientStream
);
try
try
{
{
tunnelClient
=
new
TcpClient
(
hostName
,
tunnelPort
);
TcpClient
tunnelClient
=
tcpConnection
.
TcpClient
;
tunnelStream
=
tunnelClient
.
GetStream
();
if
(
isHttps
)
{
SslStream
sslStream
=
null
;
try
{
sslStream
=
new
SslStream
(
tunnelStream
);
await
sslStream
.
AuthenticateAsClientAsync
(
hostName
,
null
,
supportedProtocols
,
false
);
tunnelStream
=
sslStream
;
}
catch
{
if
(
sslStream
!=
null
)
{
sslStream
.
Dispose
();
}
throw
;
}
}
tunnelClient
.
SendTimeout
=
connectionTimeOutSeconds
*
1000
;
tunnelClient
.
ReceiveTimeout
=
connectionTimeOutSeconds
*
1000
;
tunnelStream
.
ReadTimeout
=
connectionTimeOutSeconds
*
1000
;
Stream
tunnelStream
=
tcpConnection
.
Stream
;
tunnelStream
.
WriteTimeout
=
connectionTimeOutSeconds
*
1000
;
Task
sendRelay
;
Task
sendRelay
;
...
@@ -108,19 +96,13 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -108,19 +96,13 @@ namespace Titanium.Web.Proxy.Helpers
}
}
catch
catch
{
{
if
(
tunnelStream
!=
null
)
{
tunnelStream
.
Close
();
tunnelStream
.
Dispose
();
}
if
(
tunnelClient
!=
null
)
{
tunnelClient
.
Close
();
}
throw
;
throw
;
}
}
finally
{
tcpConnection
.
Dispose
();
}
}
}
}
}
}
}
\ No newline at end of file
Titanium.Web.Proxy/Network/TcpConnection.cs
View file @
8b46f917
...
@@ -8,7 +8,7 @@ namespace Titanium.Web.Proxy.Network
...
@@ -8,7 +8,7 @@ namespace Titanium.Web.Proxy.Network
/// <summary>
/// <summary>
/// An object that holds TcpConnection to a particular server & port
/// An object that holds TcpConnection to a particular server & port
/// </summary>
/// </summary>
public
class
TcpConnection
:
IDisposable
public
class
TcpConnection
:
IDisposable
{
{
internal
string
HostName
{
get
;
set
;
}
internal
string
HostName
{
get
;
set
;
}
internal
int
port
{
get
;
set
;
}
internal
int
port
{
get
;
set
;
}
...
@@ -44,11 +44,15 @@ namespace Titanium.Web.Proxy.Network
...
@@ -44,11 +44,15 @@ namespace Titanium.Web.Proxy.Network
public
void
Dispose
()
public
void
Dispose
()
{
{
Stream
.
Close
();
Stream
.
Dispose
();
Stream
.
Dispose
();
TcpClient
.
LingerState
=
new
LingerOption
(
true
,
0
);
TcpClient
.
Client
.
Shutdown
(
SocketShutdown
.
Both
);
TcpClient
.
Client
.
Close
();
TcpClient
.
Client
.
Close
();
TcpClient
.
Close
();
TcpClient
.
Client
.
Dispose
();
TcpClient
.
Client
.
Dispose
();
TcpClient
.
Close
();
}
}
}
}
}
}
Titanium.Web.Proxy/Network/TcpConnectionFactory.cs
View file @
8b46f917
using
System
;
using
System
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Net.Sockets
;
using
System.Net.Sockets
;
using
System.Text
;
using
System.Text
;
using
System.Threading.Tasks
;
using
System.Threading.Tasks
;
using
System.IO
;
using
System.IO
;
using
System.Net.Security
;
using
System.Net.Security
;
using
Titanium.Web.Proxy.Helpers
;
using
Titanium.Web.Proxy.Helpers
;
using
System.Threading
;
using
Titanium.Web.Proxy.Extensions
;
using
Titanium.Web.Proxy.Models
;
using
Titanium.Web.Proxy.Models
;
using
System.Security.Authentication
;
using
System.Security.Authentication
;
...
@@ -19,38 +15,30 @@ namespace Titanium.Web.Proxy.Network
...
@@ -19,38 +15,30 @@ namespace Titanium.Web.Proxy.Network
/// </summary>
/// </summary>
internal
class
TcpConnectionFactory
internal
class
TcpConnectionFactory
{
{
/// <summary>
/// Get a TcpConnection to the specified host, port optionally HTTPS and a particular HTTP version
/// </summary>
/// <param name="hostname"></param>
/// <param name="port"></param>
/// <param name="isHttps"></param>
/// <param name="version"></param>
/// <returns></returns>
internal
async
Task
<
TcpConnection
>
GetClient
(
string
hostname
,
int
port
,
bool
isHttps
,
Version
version
,
ExternalProxy
upStreamHttpProxy
,
ExternalProxy
upStreamHttpsProxy
,
int
bufferSize
,
SslProtocols
supportedSslProtocols
,
int
connectionTimeOutSeconds
,
RemoteCertificateValidationCallback
remoteCertificateValidationCallBack
,
LocalCertificateSelectionCallback
localCertificateSelectionCallback
)
{
//not in cache so create and return
return
await
CreateClient
(
hostname
,
port
,
isHttps
,
version
,
connectionTimeOutSeconds
,
upStreamHttpProxy
,
upStreamHttpsProxy
,
bufferSize
,
supportedSslProtocols
,
remoteCertificateValidationCallBack
,
localCertificateSelectionCallback
);
}
/// <summary>
/// <summary>
/// Create
connection to a particular host/port optionally with SSL and a particular HTTP version
/// Create
s a TCP connection to server
/// </summary>
/// </summary>
/// <param name="hostname"></param>
/// <param name="bufferSize"></param>
/// <param name="port"></param>
/// <param name="connectionTimeOutSeconds"></param>
/// <param name="remoteHostName"></param>
/// <param name="httpCmd"></param>
/// <param name="httpVersion"></param>
/// <param name="isHttps"></param>
/// <param name="isHttps"></param>
/// <param name="version"></param>
/// <param name="remotePort"></param>
/// <param name="supportedSslProtocols"></param>
/// <param name="remoteCertificateValidationCallback"></param>
/// <param name="localCertificateSelectionCallback"></param>
/// <param name="externalHttpProxy"></param>
/// <param name="externalHttpsProxy"></param>
/// <param name="clientStream"></param>
/// <returns></returns>
/// <returns></returns>
private
async
Task
<
TcpConnection
>
CreateClient
(
string
hostname
,
int
port
,
bool
isHttps
,
Version
version
,
int
connectionTimeOutSeconds
,
internal
async
Task
<
TcpConnection
>
CreateClient
(
int
bufferSize
,
int
connectionTimeOutSeconds
,
ExternalProxy
upStreamHttpProxy
,
ExternalProxy
upStreamHttpsProxy
,
int
bufferSize
,
SslProtocols
supportedSslProtocols
,
string
remoteHostName
,
int
remotePort
,
Version
httpVersion
,
RemoteCertificateValidationCallback
remoteCertificateValidationCallBack
,
LocalCertificateSelectionCallback
localCertificateSelectionCallback
)
bool
isHttps
,
SslProtocols
supportedSslProtocols
,
RemoteCertificateValidationCallback
remoteCertificateValidationCallback
,
LocalCertificateSelectionCallback
localCertificateSelectionCallback
,
ExternalProxy
externalHttpProxy
,
ExternalProxy
externalHttpsProxy
,
Stream
clientStream
)
{
{
TcpClient
client
;
TcpClient
client
;
Stream
stream
;
Stream
stream
;
...
@@ -60,15 +48,15 @@ namespace Titanium.Web.Proxy.Network
...
@@ -60,15 +48,15 @@ namespace Titanium.Web.Proxy.Network
SslStream
sslStream
=
null
;
SslStream
sslStream
=
null
;
//If this proxy uses another external proxy then create a tunnel request for HTTPS connections
//If this proxy uses another external proxy then create a tunnel request for HTTPS connections
if
(
upStream
HttpsProxy
!=
null
)
if
(
external
HttpsProxy
!=
null
)
{
{
client
=
new
TcpClient
(
upStreamHttpsProxy
.
HostName
,
upStream
HttpsProxy
.
Port
);
client
=
new
TcpClient
(
externalHttpsProxy
.
HostName
,
external
HttpsProxy
.
Port
);
stream
=
client
.
GetStream
();
stream
=
client
.
GetStream
();
using
(
var
writer
=
new
StreamWriter
(
stream
,
Encoding
.
ASCII
,
bufferSize
,
true
))
using
(
var
writer
=
new
StreamWriter
(
stream
,
Encoding
.
ASCII
,
bufferSize
,
true
))
{
{
await
writer
.
WriteLineAsync
(
string
.
Format
(
"CONNECT {0}:{1} {2}"
,
hostname
,
port
,
v
ersion
));
await
writer
.
WriteLineAsync
(
string
.
Format
(
"CONNECT {0}:{1} {2}"
,
remoteHostName
,
remotePort
,
httpV
ersion
));
await
writer
.
WriteLineAsync
(
string
.
Format
(
"Host: {0}:{1}"
,
hostname
,
p
ort
));
await
writer
.
WriteLineAsync
(
string
.
Format
(
"Host: {0}:{1}"
,
remoteHostName
,
remoteP
ort
));
await
writer
.
WriteLineAsync
(
"Connection: Keep-Alive"
);
await
writer
.
WriteLineAsync
(
"Connection: Keep-Alive"
);
await
writer
.
WriteLineAsync
();
await
writer
.
WriteLineAsync
();
await
writer
.
FlushAsync
();
await
writer
.
FlushAsync
();
...
@@ -89,16 +77,16 @@ namespace Titanium.Web.Proxy.Network
...
@@ -89,16 +77,16 @@ namespace Titanium.Web.Proxy.Network
}
}
else
else
{
{
client
=
new
TcpClient
(
hostname
,
p
ort
);
client
=
new
TcpClient
(
remoteHostName
,
remoteP
ort
);
stream
=
client
.
GetStream
();
stream
=
client
.
GetStream
();
}
}
try
try
{
{
sslStream
=
new
SslStream
(
stream
,
true
,
remoteCertificateValidationCall
B
ack
,
sslStream
=
new
SslStream
(
stream
,
true
,
remoteCertificateValidationCall
b
ack
,
localCertificateSelectionCallback
);
localCertificateSelectionCallback
);
await
sslStream
.
AuthenticateAsClientAsync
(
hostn
ame
,
null
,
supportedSslProtocols
,
false
);
await
sslStream
.
AuthenticateAsClientAsync
(
remoteHostN
ame
,
null
,
supportedSslProtocols
,
false
);
stream
=
sslStream
;
stream
=
sslStream
;
}
}
...
@@ -114,14 +102,14 @@ namespace Titanium.Web.Proxy.Network
...
@@ -114,14 +102,14 @@ namespace Titanium.Web.Proxy.Network
}
}
else
else
{
{
if
(
upStream
HttpProxy
!=
null
)
if
(
external
HttpProxy
!=
null
)
{
{
client
=
new
TcpClient
(
upStreamHttpProxy
.
HostName
,
upStream
HttpProxy
.
Port
);
client
=
new
TcpClient
(
externalHttpProxy
.
HostName
,
external
HttpProxy
.
Port
);
stream
=
client
.
GetStream
();
stream
=
client
.
GetStream
();
}
}
else
else
{
{
client
=
new
TcpClient
(
hostname
,
p
ort
);
client
=
new
TcpClient
(
remoteHostName
,
remoteP
ort
);
stream
=
client
.
GetStream
();
stream
=
client
.
GetStream
();
}
}
}
}
...
@@ -132,15 +120,17 @@ namespace Titanium.Web.Proxy.Network
...
@@ -132,15 +120,17 @@ namespace Titanium.Web.Proxy.Network
stream
.
ReadTimeout
=
connectionTimeOutSeconds
*
1000
;
stream
.
ReadTimeout
=
connectionTimeOutSeconds
*
1000
;
stream
.
WriteTimeout
=
connectionTimeOutSeconds
*
1000
;
stream
.
WriteTimeout
=
connectionTimeOutSeconds
*
1000
;
client
.
NoDelay
=
true
;
return
new
TcpConnection
()
return
new
TcpConnection
()
{
{
HostName
=
hostn
ame
,
HostName
=
remoteHostN
ame
,
port
=
p
ort
,
port
=
remoteP
ort
,
IsHttps
=
isHttps
,
IsHttps
=
isHttps
,
TcpClient
=
client
,
TcpClient
=
client
,
StreamReader
=
new
CustomBinaryReader
(
stream
),
StreamReader
=
new
CustomBinaryReader
(
stream
),
Stream
=
stream
,
Stream
=
stream
,
Version
=
v
ersion
Version
=
httpV
ersion
};
};
}
}
...
...
Titanium.Web.Proxy/ProxyServer.cs
View file @
8b46f917
...
@@ -15,9 +15,9 @@ namespace Titanium.Web.Proxy
...
@@ -15,9 +15,9 @@ namespace Titanium.Web.Proxy
/// <summary>
/// <summary>
/// Proxy Server Main class
/// Proxy Server Main class
/// </summary>
/// </summary>
public
partial
class
ProxyServer
:
IDisposable
public
partial
class
ProxyServer
:
IDisposable
{
{
/// <summary>
/// <summary>
/// Manages certificates used by this proxy
/// Manages certificates used by this proxy
/// </summary>
/// </summary>
...
@@ -197,7 +197,7 @@ namespace Titanium.Web.Proxy
...
@@ -197,7 +197,7 @@ namespace Titanium.Web.Proxy
Console
.
WriteLine
(
"Set endpoint at Ip {1} and port: {2} as System HTTP Proxy"
,
endPoint
.
GetType
().
Name
,
endPoint
.
IpAddress
,
endPoint
.
Port
);
Console
.
WriteLine
(
"Set endpoint at Ip {1} and port: {2} as System HTTP Proxy"
,
endPoint
.
GetType
().
Name
,
endPoint
.
IpAddress
,
endPoint
.
Port
);
}
}
/// <summary>
/// <summary>
/// Set the given explicit end point as the default proxy server for current machine
/// Set the given explicit end point as the default proxy server for current machine
...
@@ -360,17 +360,12 @@ namespace Titanium.Web.Proxy
...
@@ -360,17 +360,12 @@ namespace Titanium.Web.Proxy
{
{
var
endPoint
=
(
ProxyEndPoint
)
asyn
.
AsyncState
;
var
endPoint
=
(
ProxyEndPoint
)
asyn
.
AsyncState
;
TcpClient
tcpClient
=
null
;
try
try
{
{
//based on end point type call appropriate request handlers
//based on end point type call appropriate request handlers
var
client
=
endPoint
.
listener
.
EndAcceptTcpClient
(
asyn
);
tcpClient
=
endPoint
.
listener
.
EndAcceptTcpClient
(
asyn
);
if
(
endPoint
.
GetType
()
==
typeof
(
TransparentProxyEndPoint
))
HandleClient
(
endPoint
as
TransparentProxyEndPoint
,
client
);
else
HandleClient
(
endPoint
as
ExplicitProxyEndPoint
,
client
);
// Get the listener that handles the client request.
endPoint
.
listener
.
BeginAcceptTcpClient
(
OnAcceptConnection
,
endPoint
);
}
}
catch
(
ObjectDisposedException
)
catch
(
ObjectDisposedException
)
{
{
...
@@ -384,6 +379,43 @@ namespace Titanium.Web.Proxy
...
@@ -384,6 +379,43 @@ namespace Titanium.Web.Proxy
//Other errors are discarded to keep proxy running
//Other errors are discarded to keep proxy running
}
}
if
(
tcpClient
!=
null
)
{
Task
.
Run
(
async
()
=>
{
try
{
tcpClient
.
NoDelay
=
true
;
if
(
endPoint
.
GetType
()
==
typeof
(
TransparentProxyEndPoint
))
{
await
HandleClient
(
endPoint
as
TransparentProxyEndPoint
,
tcpClient
);
}
else
{
await
HandleClient
(
endPoint
as
ExplicitProxyEndPoint
,
tcpClient
);
}
}
finally
{
if
(
tcpClient
!=
null
)
{
tcpClient
.
LingerState
=
new
LingerOption
(
true
,
0
);
tcpClient
.
Client
.
Shutdown
(
SocketShutdown
.
Both
);
tcpClient
.
Client
.
Close
();
tcpClient
.
Client
.
Dispose
();
tcpClient
.
Close
();
}
}
});
}
// Get the listener that handles the client request.
endPoint
.
listener
.
BeginAcceptTcpClient
(
OnAcceptConnection
,
endPoint
);
}
}
public
void
Dispose
()
public
void
Dispose
()
...
...
Titanium.Web.Proxy/RequestHandler.cs
View file @
8b46f917
...
@@ -25,7 +25,7 @@ namespace Titanium.Web.Proxy
...
@@ -25,7 +25,7 @@ namespace Titanium.Web.Proxy
{
{
//This is called when client is aware of proxy
//This is called when client is aware of proxy
//So for HTTPS requests client would send CONNECT header to negotiate a secure tcp tunnel via proxy
//So for HTTPS requests client would send CONNECT header to negotiate a secure tcp tunnel via proxy
private
async
void
HandleClient
(
ExplicitProxyEndPoint
endPoint
,
TcpClient
client
)
private
async
Task
HandleClient
(
ExplicitProxyEndPoint
endPoint
,
TcpClient
client
)
{
{
Stream
clientStream
=
client
.
GetStream
();
Stream
clientStream
=
client
.
GetStream
();
...
@@ -43,7 +43,7 @@ namespace Titanium.Web.Proxy
...
@@ -43,7 +43,7 @@ namespace Titanium.Web.Proxy
if
(
string
.
IsNullOrEmpty
(
httpCmd
))
if
(
string
.
IsNullOrEmpty
(
httpCmd
))
{
{
Dispose
(
client
,
client
Stream
,
clientStreamReader
,
clientStreamWriter
,
null
);
Dispose
(
clientStream
,
clientStreamReader
,
clientStreamWriter
,
null
);
return
;
return
;
}
}
...
@@ -109,7 +109,7 @@ namespace Titanium.Web.Proxy
...
@@ -109,7 +109,7 @@ namespace Titanium.Web.Proxy
sslStream
.
Dispose
();
sslStream
.
Dispose
();
}
}
Dispose
(
client
,
client
Stream
,
clientStreamReader
,
clientStreamWriter
,
null
);
Dispose
(
clientStream
,
clientStreamReader
,
clientStreamWriter
,
null
);
return
;
return
;
}
}
...
@@ -125,11 +125,15 @@ namespace Titanium.Web.Proxy
...
@@ -125,11 +125,15 @@ namespace Titanium.Web.Proxy
//write back successfull CONNECT response
//write back successfull CONNECT response
await
WriteConnectResponse
(
clientStreamWriter
,
version
);
await
WriteConnectResponse
(
clientStreamWriter
,
version
);
//Just relay the request/response without decrypting it
await
TcpHelper
.
SendRaw
(
clientStream
,
null
,
null
,
httpRemoteUri
.
Host
,
httpRemoteUri
.
Port
,
false
,
SupportedSslProtocols
,
ConnectionTimeOutSeconds
);
Dispose
(
client
,
clientStream
,
clientStreamReader
,
clientStreamWriter
,
null
);
await
TcpHelper
.
SendRaw
(
BUFFER_SIZE
,
ConnectionTimeOutSeconds
,
httpRemoteUri
.
Host
,
httpRemoteUri
.
Port
,
httpCmd
,
version
,
null
,
false
,
SupportedSslProtocols
,
new
RemoteCertificateValidationCallback
(
ValidateServerCertificate
),
new
LocalCertificateSelectionCallback
(
SelectClientCertificate
),
clientStream
,
tcpConnectionFactory
);
Dispose
(
clientStream
,
clientStreamReader
,
clientStreamWriter
,
null
);
return
;
return
;
}
}
...
@@ -139,13 +143,13 @@ namespace Titanium.Web.Proxy
...
@@ -139,13 +143,13 @@ namespace Titanium.Web.Proxy
}
}
catch
catch
{
{
Dispose
(
client
,
client
Stream
,
clientStreamReader
,
clientStreamWriter
,
null
);
Dispose
(
clientStream
,
clientStreamReader
,
clientStreamWriter
,
null
);
}
}
}
}
//This is called when this proxy acts as a reverse proxy (like a real http server)
//This is called when this proxy acts as a reverse proxy (like a real http server)
//So for HTTPS requests we would start SSL negotiation right away without expecting a CONNECT request from client
//So for HTTPS requests we would start SSL negotiation right away without expecting a CONNECT request from client
private
async
void
HandleClient
(
TransparentProxyEndPoint
endPoint
,
TcpClient
tcpClient
)
private
async
Task
HandleClient
(
TransparentProxyEndPoint
endPoint
,
TcpClient
tcpClient
)
{
{
Stream
clientStream
=
tcpClient
.
GetStream
();
Stream
clientStream
=
tcpClient
.
GetStream
();
...
@@ -181,7 +185,7 @@ namespace Titanium.Web.Proxy
...
@@ -181,7 +185,7 @@ namespace Titanium.Web.Proxy
sslStream
.
Dispose
();
sslStream
.
Dispose
();
}
}
Dispose
(
tcpClient
,
sslStream
,
clientStreamReader
,
clientStreamWriter
,
null
);
Dispose
(
sslStream
,
clientStreamReader
,
clientStreamWriter
,
null
);
return
;
return
;
}
}
clientStream
=
sslStream
;
clientStream
=
sslStream
;
...
@@ -219,7 +223,7 @@ namespace Titanium.Web.Proxy
...
@@ -219,7 +223,7 @@ namespace Titanium.Web.Proxy
{
{
if
(
string
.
IsNullOrEmpty
(
httpCmd
))
if
(
string
.
IsNullOrEmpty
(
httpCmd
))
{
{
Dispose
(
client
,
client
Stream
,
clientStreamReader
,
clientStreamWriter
,
null
);
Dispose
(
clientStream
,
clientStreamReader
,
clientStreamWriter
,
null
);
break
;
break
;
}
}
...
@@ -234,14 +238,14 @@ namespace Titanium.Web.Proxy
...
@@ -234,14 +238,14 @@ namespace Titanium.Web.Proxy
var
httpMethod
=
httpCmdSplit
[
0
];
var
httpMethod
=
httpCmdSplit
[
0
];
//find the request HTTP version
//find the request HTTP version
Version
v
ersion
=
new
Version
(
1
,
1
);
Version
httpV
ersion
=
new
Version
(
1
,
1
);
if
(
httpCmdSplit
.
Length
==
3
)
if
(
httpCmdSplit
.
Length
==
3
)
{
{
var
httpVersion
=
httpCmdSplit
[
2
].
ToLower
().
Trim
();
var
httpVersion
String
=
httpCmdSplit
[
2
].
ToLower
().
Trim
();
if
(
httpVersion
==
"http/1.0"
)
if
(
httpVersion
String
==
"http/1.0"
)
{
{
v
ersion
=
new
Version
(
1
,
0
);
httpV
ersion
=
new
Version
(
1
,
0
);
}
}
}
}
...
@@ -285,7 +289,7 @@ namespace Titanium.Web.Proxy
...
@@ -285,7 +289,7 @@ namespace Titanium.Web.Proxy
args
.
WebSession
.
Request
.
RequestUri
=
httpRemoteUri
;
args
.
WebSession
.
Request
.
RequestUri
=
httpRemoteUri
;
args
.
WebSession
.
Request
.
Method
=
httpMethod
;
args
.
WebSession
.
Request
.
Method
=
httpMethod
;
args
.
WebSession
.
Request
.
HttpVersion
=
v
ersion
;
args
.
WebSession
.
Request
.
HttpVersion
=
httpV
ersion
;
args
.
ProxyClient
.
ClientStream
=
clientStream
;
args
.
ProxyClient
.
ClientStream
=
clientStream
;
args
.
ProxyClient
.
ClientStreamReader
=
clientStreamReader
;
args
.
ProxyClient
.
ClientStreamReader
=
clientStreamReader
;
args
.
ProxyClient
.
ClientStreamWriter
=
clientStreamWriter
;
args
.
ProxyClient
.
ClientStreamWriter
=
clientStreamWriter
;
...
@@ -310,24 +314,33 @@ namespace Titanium.Web.Proxy
...
@@ -310,24 +314,33 @@ namespace Titanium.Web.Proxy
//if upgrading to websocket then relay the requet without reading the contents
//if upgrading to websocket then relay the requet without reading the contents
if
(
args
.
WebSession
.
Request
.
UpgradeToWebSocket
)
if
(
args
.
WebSession
.
Request
.
UpgradeToWebSocket
)
{
{
await
TcpHelper
.
SendRaw
(
clientStream
,
httpCmd
,
args
.
WebSession
.
Request
.
RequestHeaders
,
await
TcpHelper
.
SendRaw
(
BUFFER_SIZE
,
ConnectionTimeOutSeconds
,
httpRemoteUri
.
Host
,
httpRemoteUri
.
Port
,
httpRemoteUri
.
Host
,
httpRemoteUri
.
Port
,
args
.
IsHttps
,
SupportedSslProtocols
,
ConnectionTimeOutSeconds
);
httpCmd
,
httpVersion
,
args
.
WebSession
.
Request
.
RequestHeaders
,
args
.
IsHttps
,
SupportedSslProtocols
,
new
RemoteCertificateValidationCallback
(
ValidateServerCertificate
),
new
LocalCertificateSelectionCallback
(
SelectClientCertificate
),
clientStream
,
tcpConnectionFactory
);
Dispose
(
client
,
client
Stream
,
clientStreamReader
,
clientStreamWriter
,
args
);
Dispose
(
clientStream
,
clientStreamReader
,
clientStreamWriter
,
args
);
break
;
break
;
}
}
//construct the web request that we are going to issue on behalf of the client.
//construct the web request that we are going to issue on behalf of the client.
connection
=
connection
!=
null
?
connection
:
await
tcpConnectionFactory
.
GetClient
(
args
.
WebSession
.
Request
.
RequestUri
.
Host
,
args
.
WebSession
.
Request
.
RequestUri
.
Port
,
args
.
IsHttps
,
version
,
if
(
connection
==
null
)
UpStreamHttpProxy
,
UpStreamHttpsProxy
,
BUFFER_SIZE
,
SupportedSslProtocols
,
ConnectionTimeOutSeconds
,
new
RemoteCertificateValidationCallback
(
ValidateServerCertificate
),
{
new
LocalCertificateSelectionCallback
(
SelectClientCertificate
));
connection
=
await
tcpConnectionFactory
.
CreateClient
(
BUFFER_SIZE
,
ConnectionTimeOutSeconds
,
args
.
WebSession
.
Request
.
RequestUri
.
Host
,
args
.
WebSession
.
Request
.
RequestUri
.
Port
,
httpVersion
,
args
.
IsHttps
,
SupportedSslProtocols
,
new
RemoteCertificateValidationCallback
(
ValidateServerCertificate
),
new
LocalCertificateSelectionCallback
(
SelectClientCertificate
),
UpStreamHttpProxy
,
UpStreamHttpsProxy
,
clientStream
);
}
args
.
WebSession
.
Request
.
RequestLocked
=
true
;
args
.
WebSession
.
Request
.
RequestLocked
=
true
;
//If request was cancelled by user then dispose the client
//If request was cancelled by user then dispose the client
if
(
args
.
WebSession
.
Request
.
CancelRequest
)
if
(
args
.
WebSession
.
Request
.
CancelRequest
)
{
{
Dispose
(
client
,
client
Stream
,
clientStreamReader
,
clientStreamWriter
,
args
);
Dispose
(
clientStream
,
clientStreamReader
,
clientStreamWriter
,
args
);
break
;
break
;
}
}
...
@@ -397,7 +410,7 @@ namespace Titanium.Web.Proxy
...
@@ -397,7 +410,7 @@ namespace Titanium.Web.Proxy
//if connection is closing exit
//if connection is closing exit
if
(
args
.
WebSession
.
Response
.
ResponseKeepAlive
==
false
)
if
(
args
.
WebSession
.
Response
.
ResponseKeepAlive
==
false
)
{
{
Dispose
(
client
,
client
Stream
,
clientStreamReader
,
clientStreamWriter
,
args
);
Dispose
(
clientStream
,
clientStreamReader
,
clientStreamWriter
,
args
);
break
;
break
;
}
}
...
@@ -407,7 +420,7 @@ namespace Titanium.Web.Proxy
...
@@ -407,7 +420,7 @@ namespace Titanium.Web.Proxy
}
}
catch
catch
{
{
Dispose
(
client
,
client
Stream
,
clientStreamReader
,
clientStreamWriter
,
args
);
Dispose
(
clientStream
,
clientStreamReader
,
clientStreamWriter
,
args
);
break
;
break
;
}
}
...
...
Titanium.Web.Proxy/ResponseHandler.cs
View file @
8b46f917
using
System
;
using
System
;
using
System.Collections.Generic
;
using
System.Collections.Generic
;
using
System.IO
;
using
System.IO
;
using
System.Linq
;
using
System.Net.Sockets
;
using
Titanium.Web.Proxy.EventArguments
;
using
Titanium.Web.Proxy.EventArguments
;
using
Titanium.Web.Proxy.Models
;
using
Titanium.Web.Proxy.Models
;
using
Titanium.Web.Proxy.Compression
;
using
Titanium.Web.Proxy.Compression
;
...
@@ -114,7 +112,7 @@ namespace Titanium.Web.Proxy
...
@@ -114,7 +112,7 @@ namespace Titanium.Web.Proxy
}
}
catch
catch
{
{
Dispose
(
args
.
ProxyClient
.
TcpClient
,
args
.
ProxyClient
.
ClientStream
,
args
.
ProxyClient
.
ClientStreamReader
,
Dispose
(
args
.
ProxyClient
.
ClientStream
,
args
.
ProxyClient
.
ClientStreamReader
,
args
.
ProxyClient
.
ClientStreamWriter
,
args
);
args
.
ProxyClient
.
ClientStreamWriter
,
args
);
}
}
finally
finally
...
@@ -216,32 +214,30 @@ namespace Titanium.Web.Proxy
...
@@ -216,32 +214,30 @@ namespace Titanium.Web.Proxy
/// <param name="clientStreamReader"></param>
/// <param name="clientStreamReader"></param>
/// <param name="clientStreamWriter"></param>
/// <param name="clientStreamWriter"></param>
/// <param name="args"></param>
/// <param name="args"></param>
private
void
Dispose
(
TcpClient
tcpClient
,
IDisposable
clientStream
,
IDisposable
clientStreamReader
,
private
void
Dispose
(
Stream
clientStream
,
IDisposable
clientStreamReader
,
IDisposable
clientStreamWriter
,
IDisposable
args
)
IDisposable
clientStreamWriter
,
IDisposable
args
)
{
{
if
(
clientStream
!=
null
)
if
(
clientStream
!=
null
)
{
{
(
clientStream
as
Stream
).
Close
();
clientStream
.
Close
();
(
clientStream
as
Stream
).
Dispose
();
clientStream
.
Dispose
();
}
if
(
tcpClient
!=
null
)
{
tcpClient
.
Client
.
Close
();
tcpClient
.
Close
();
tcpClient
.
Client
.
Dispose
();
}
}
if
(
args
!=
null
)
if
(
args
!=
null
)
{
args
.
Dispose
();
args
.
Dispose
();
}
if
(
clientStreamReader
!=
null
)
if
(
clientStreamReader
!=
null
)
{
clientStreamReader
.
Dispose
();
clientStreamReader
.
Dispose
();
}
if
(
clientStreamWriter
!=
null
)
if
(
clientStreamWriter
!=
null
)
{
clientStreamWriter
.
Dispose
();
clientStreamWriter
.
Dispose
();
}
}
}
}
}
}
}
\ 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