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
1a14f576
Commit
1a14f576
authored
May 16, 2018
by
justcoding121
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactor connection factory
parent
35b82aa9
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
284 additions
and
265 deletions
+284
-265
ProxyTestController.cs
.../Titanium.Web.Proxy.Examples.Basic/ProxyTestController.cs
+1
-1
ExplicitClientHandler.cs
Titanium.Web.Proxy/ExplicitClientHandler.cs
+4
-4
TcpConnectionFactory.cs
Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs
+200
-112
RequestHandler.cs
Titanium.Web.Proxy/RequestHandler.cs
+5
-146
TransparentClientHandler.cs
Titanium.Web.Proxy/TransparentClientHandler.cs
+2
-2
WebSocketHandler.cs
Titanium.Web.Proxy/WebSocketHandler.cs
+72
-0
No files found.
Examples/Titanium.Web.Proxy.Examples.Basic/ProxyTestController.cs
View file @
1a14f576
...
@@ -151,7 +151,7 @@ namespace Titanium.Web.Proxy.Examples.Basic
...
@@ -151,7 +151,7 @@ namespace Titanium.Web.Proxy.Examples.Basic
private
Task
OnBeforeTunnelConnectResponse
(
object
sender
,
TunnelConnectSessionEventArgs
e
)
private
Task
OnBeforeTunnelConnectResponse
(
object
sender
,
TunnelConnectSessionEventArgs
e
)
{
{
return
default
;
return
Task
.
FromResult
(
false
)
;
}
}
// intecept & cancel redirect or update requests
// intecept & cancel redirect or update requests
...
...
Titanium.Web.Proxy/ExplicitClientHandler.cs
View file @
1a14f576
...
@@ -140,7 +140,7 @@ namespace Titanium.Web.Proxy
...
@@ -140,7 +140,7 @@ namespace Titanium.Web.Proxy
{
{
// test server HTTP/2 support
// test server HTTP/2 support
// todo: this is a hack, because Titanium does not support HTTP protocol changing currently
// todo: this is a hack, because Titanium does not support HTTP protocol changing currently
var
connection
=
await
getServerConnection
(
connectArgs
,
true
,
var
connection
=
await
tcpConnectionFactory
.
GetServerConnection
(
this
,
connectArgs
,
true
,
SslExtensions
.
Http2ProtocolAsList
,
true
,
cancellationToken
);
SslExtensions
.
Http2ProtocolAsList
,
true
,
cancellationToken
);
http2Supported
=
connection
.
NegotiatedApplicationProtocol
==
SslApplicationProtocol
.
Http2
;
http2Supported
=
connection
.
NegotiatedApplicationProtocol
==
SslApplicationProtocol
.
Http2
;
...
@@ -153,7 +153,7 @@ namespace Titanium.Web.Proxy
...
@@ -153,7 +153,7 @@ namespace Titanium.Web.Proxy
//don't pass cancellation token here
//don't pass cancellation token here
//it could cause floating server connections when client exits
//it could cause floating server connections when client exits
prefetchConnectionTask
=
getServerConnection
(
connectArgs
,
true
,
prefetchConnectionTask
=
tcpConnectionFactory
.
GetServerConnection
(
this
,
connectArgs
,
true
,
null
,
false
,
CancellationToken
.
None
);
null
,
false
,
CancellationToken
.
None
);
try
try
...
@@ -214,7 +214,7 @@ namespace Titanium.Web.Proxy
...
@@ -214,7 +214,7 @@ namespace Titanium.Web.Proxy
// create new connection to server.
// create new connection to server.
// If we detected that client tunnel CONNECTs without SSL by checking for empty client hello then
// If we detected that client tunnel CONNECTs without SSL by checking for empty client hello then
// this connection should not be HTTPS.
// this connection should not be HTTPS.
var
connection
=
await
getServerConnection
(
connectArgs
,
var
connection
=
await
tcpConnectionFactory
.
GetServerConnection
(
this
,
connectArgs
,
true
,
SslExtensions
.
Http2ProtocolAsList
,
true
,
cancellationToken
);
true
,
SslExtensions
.
Http2ProtocolAsList
,
true
,
cancellationToken
);
try
try
...
@@ -284,7 +284,7 @@ namespace Titanium.Web.Proxy
...
@@ -284,7 +284,7 @@ namespace Titanium.Web.Proxy
throw
new
Exception
(
$"HTTP/2 Protocol violation. Empty string expected, '
{
line
}
' received"
);
throw
new
Exception
(
$"HTTP/2 Protocol violation. Empty string expected, '
{
line
}
' received"
);
}
}
var
connection
=
await
getServerConnection
(
connectArgs
,
true
,
var
connection
=
await
tcpConnectionFactory
.
GetServerConnection
(
this
,
connectArgs
,
true
,
SslExtensions
.
Http2ProtocolAsList
,
true
,
SslExtensions
.
Http2ProtocolAsList
,
true
,
cancellationToken
);
cancellationToken
);
try
try
...
...
Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs
View file @
1a14f576
This diff is collapsed.
Click to expand it.
Titanium.Web.Proxy/RequestHandler.cs
View file @
1a14f576
...
@@ -196,7 +196,7 @@ namespace Titanium.Web.Proxy
...
@@ -196,7 +196,7 @@ namespace Titanium.Web.Proxy
// only gets hit when connection pool is disabled.
// only gets hit when connection pool is disabled.
// or when prefetch task has a unexpectedly different connection.
// or when prefetch task has a unexpectedly different connection.
if
(
connection
!=
null
if
(
connection
!=
null
&&
(
await
getConnectionCacheKey
(
args
,
&&
(
await
tcpConnectionFactory
.
GetConnectionCacheKey
(
this
,
args
,
clientConnection
.
NegotiatedApplicationProtocol
)
clientConnection
.
NegotiatedApplicationProtocol
)
!=
connection
.
CacheKey
))
!=
connection
.
CacheKey
))
{
{
...
@@ -205,7 +205,8 @@ namespace Titanium.Web.Proxy
...
@@ -205,7 +205,8 @@ namespace Titanium.Web.Proxy
}
}
//a connection generator task with captured parameters via closure.
//a connection generator task with captured parameters via closure.
Func
<
Task
<
TcpServerConnection
>>
generator
=
()
=>
getServerConnection
(
args
,
false
,
Func
<
Task
<
TcpServerConnection
>>
generator
=
()
=>
tcpConnectionFactory
.
GetServerConnection
(
this
,
args
,
false
,
clientConnection
.
NegotiatedApplicationProtocol
,
clientConnection
.
NegotiatedApplicationProtocol
,
false
,
cancellationToken
);
false
,
cancellationToken
);
...
@@ -373,62 +374,6 @@ namespace Titanium.Web.Proxy
...
@@ -373,62 +374,6 @@ namespace Titanium.Web.Proxy
}
}
}
}
/// <summary>
/// Handle upgrade to websocket
/// </summary>
private
async
Task
handleWebSocketUpgrade
(
string
httpCmd
,
SessionEventArgs
args
,
Request
request
,
Response
response
,
CustomBufferedStream
clientStream
,
HttpResponseWriter
clientStreamWriter
,
TcpServerConnection
serverConnection
,
CancellationTokenSource
cancellationTokenSource
,
CancellationToken
cancellationToken
)
{
// prepare the prefix content
await
serverConnection
.
StreamWriter
.
WriteLineAsync
(
httpCmd
,
cancellationToken
);
await
serverConnection
.
StreamWriter
.
WriteHeadersAsync
(
request
.
Headers
,
cancellationToken
:
cancellationToken
);
string
httpStatus
;
try
{
httpStatus
=
await
serverConnection
.
Stream
.
ReadLineAsync
(
cancellationToken
);
if
(
httpStatus
==
null
)
{
throw
new
ServerConnectionException
(
"Server connection was closed."
);
}
}
catch
(
Exception
e
)
when
(!(
e
is
ServerConnectionException
))
{
throw
new
ServerConnectionException
(
"Server connection was closed."
,
e
);
}
Response
.
ParseResponseLine
(
httpStatus
,
out
var
responseVersion
,
out
int
responseStatusCode
,
out
string
responseStatusDescription
);
response
.
HttpVersion
=
responseVersion
;
response
.
StatusCode
=
responseStatusCode
;
response
.
StatusDescription
=
responseStatusDescription
;
await
HeaderParser
.
ReadHeaders
(
serverConnection
.
Stream
,
response
.
Headers
,
cancellationToken
);
if
(!
args
.
IsTransparent
)
{
await
clientStreamWriter
.
WriteResponseAsync
(
response
,
cancellationToken
:
cancellationToken
);
}
// If user requested call back then do it
if
(!
args
.
WebSession
.
Response
.
Locked
)
{
await
invokeBeforeResponse
(
args
);
}
await
TcpHelper
.
SendRaw
(
clientStream
,
serverConnection
.
Stream
,
BufferPool
,
BufferSize
,
(
buffer
,
offset
,
count
)
=>
{
args
.
OnDataSent
(
buffer
,
offset
,
count
);
},
(
buffer
,
offset
,
count
)
=>
{
args
.
OnDataReceived
(
buffer
,
offset
,
count
);
},
cancellationTokenSource
,
ExceptionFunc
);
}
/// <summary>
/// <summary>
/// Prepare the request headers so that we can avoid encodings not parsable by this proxy
/// Prepare the request headers so that we can avoid encodings not parsable by this proxy
/// </summary>
/// </summary>
...
@@ -455,92 +400,6 @@ namespace Titanium.Web.Proxy
...
@@ -455,92 +400,6 @@ namespace Titanium.Web.Proxy
requestHeaders
.
FixProxyHeaders
();
requestHeaders
.
FixProxyHeaders
();
}
}
/// <summary>
/// Gets the connection cache key.
/// </summary>
/// <param name="args">The session event arguments.</param>
/// <param name="applicationProtocol"></param>
/// <returns></returns>
private
async
Task
<
string
>
getConnectionCacheKey
(
SessionEventArgsBase
args
,
SslApplicationProtocol
applicationProtocol
)
{
List
<
SslApplicationProtocol
>
applicationProtocols
=
null
;
if
(
applicationProtocol
!=
default
)
{
applicationProtocols
=
new
List
<
SslApplicationProtocol
>
{
applicationProtocol
};
}
ExternalProxy
customUpStreamProxy
=
null
;
bool
isHttps
=
args
.
IsHttps
;
if
(
GetCustomUpStreamProxyFunc
!=
null
)
{
customUpStreamProxy
=
await
GetCustomUpStreamProxyFunc
(
args
);
}
args
.
CustomUpStreamProxyUsed
=
customUpStreamProxy
;
return
tcpConnectionFactory
.
GetConnectionCacheKey
(
args
.
WebSession
.
Request
.
RequestUri
.
Host
,
args
.
WebSession
.
Request
.
RequestUri
.
Port
,
isHttps
,
applicationProtocols
,
this
,
args
.
WebSession
.
UpStreamEndPoint
??
UpStreamEndPoint
,
customUpStreamProxy
??
(
isHttps
?
UpStreamHttpsProxy
:
UpStreamHttpProxy
));
}
/// <summary>
/// Create a server connection.
/// </summary>
/// <param name="args">The session event arguments.</param>
/// <param name="isConnect">Is this a CONNECT request.</param>
/// <param name="applicationProtocol"></param>
/// <param name="cancellationToken">The cancellation token for this async task.</param>
/// <returns></returns>
private
Task
<
TcpServerConnection
>
getServerConnection
(
SessionEventArgsBase
args
,
bool
isConnect
,
SslApplicationProtocol
applicationProtocol
,
bool
noCache
,
CancellationToken
cancellationToken
)
{
List
<
SslApplicationProtocol
>
applicationProtocols
=
null
;
if
(
applicationProtocol
!=
default
)
{
applicationProtocols
=
new
List
<
SslApplicationProtocol
>
{
applicationProtocol
};
}
return
getServerConnection
(
args
,
isConnect
,
applicationProtocols
,
noCache
,
cancellationToken
);
}
/// <summary>
/// Create a server connection.
/// </summary>
/// <param name="args">The session event arguments.</param>
/// <param name="isConnect">Is this a CONNECT request.</param>
/// <param name="applicationProtocols"></param>
/// <param name="cancellationToken">The cancellation token for this async task.</param>
/// <returns></returns>
private
async
Task
<
TcpServerConnection
>
getServerConnection
(
SessionEventArgsBase
args
,
bool
isConnect
,
List
<
SslApplicationProtocol
>
applicationProtocols
,
bool
noCache
,
CancellationToken
cancellationToken
)
{
ExternalProxy
customUpStreamProxy
=
null
;
bool
isHttps
=
args
.
IsHttps
;
if
(
GetCustomUpStreamProxyFunc
!=
null
)
{
customUpStreamProxy
=
await
GetCustomUpStreamProxyFunc
(
args
);
}
args
.
CustomUpStreamProxyUsed
=
customUpStreamProxy
;
return
await
tcpConnectionFactory
.
GetClient
(
args
.
WebSession
.
Request
.
RequestUri
.
Host
,
args
.
WebSession
.
Request
.
RequestUri
.
Port
,
args
.
WebSession
.
Request
.
HttpVersion
,
isHttps
,
applicationProtocols
,
isConnect
,
this
,
args
.
WebSession
.
UpStreamEndPoint
??
UpStreamEndPoint
,
customUpStreamProxy
??
(
isHttps
?
UpStreamHttpsProxy
:
UpStreamHttpProxy
),
noCache
,
cancellationToken
);
}
/// <summary>
/// <summary>
/// Invoke before request handler if it is set.
/// Invoke before request handler if it is set.
/// </summary>
/// </summary>
...
...
Titanium.Web.Proxy/TransparentClientHandler.cs
View file @
1a14f576
...
@@ -65,7 +65,7 @@ namespace Titanium.Web.Proxy
...
@@ -65,7 +65,7 @@ namespace Titanium.Web.Proxy
{
{
//don't pass cancellation token here
//don't pass cancellation token here
//it could cause floating server connections when client exits
//it could cause floating server connections when client exits
prefetchConnectionTask
=
tcpConnectionFactory
.
Get
Client
(
httpsHostName
,
endPoint
.
Port
,
prefetchConnectionTask
=
tcpConnectionFactory
.
Get
ServerConnection
(
httpsHostName
,
endPoint
.
Port
,
null
,
true
,
null
,
false
,
this
,
null
,
true
,
null
,
false
,
this
,
UpStreamEndPoint
,
UpStreamHttpsProxy
,
false
,
CancellationToken
.
None
);
UpStreamEndPoint
,
UpStreamHttpsProxy
,
false
,
CancellationToken
.
None
);
...
@@ -96,7 +96,7 @@ namespace Titanium.Web.Proxy
...
@@ -96,7 +96,7 @@ namespace Titanium.Web.Proxy
}
}
else
else
{
{
var
connection
=
await
tcpConnectionFactory
.
Get
Client
(
httpsHostName
,
endPoint
.
Port
,
var
connection
=
await
tcpConnectionFactory
.
Get
ServerConnection
(
httpsHostName
,
endPoint
.
Port
,
null
,
false
,
null
,
null
,
false
,
null
,
true
,
this
,
UpStreamEndPoint
,
UpStreamHttpsProxy
,
true
,
cancellationToken
);
true
,
this
,
UpStreamEndPoint
,
UpStreamHttpsProxy
,
true
,
cancellationToken
);
...
...
Titanium.Web.Proxy/WebSocketHandler.cs
0 → 100644
View file @
1a14f576
using
StreamExtended.Network
;
using
System
;
using
System.Threading
;
using
System.Threading.Tasks
;
using
Titanium.Web.Proxy.EventArguments
;
using
Titanium.Web.Proxy.Exceptions
;
using
Titanium.Web.Proxy.Helpers
;
using
Titanium.Web.Proxy.Http
;
using
Titanium.Web.Proxy.Network.Tcp
;
namespace
Titanium.Web.Proxy
{
public
partial
class
ProxyServer
{
/// <summary>
/// Handle upgrade to websocket
/// </summary>
private
async
Task
handleWebSocketUpgrade
(
string
httpCmd
,
SessionEventArgs
args
,
Request
request
,
Response
response
,
CustomBufferedStream
clientStream
,
HttpResponseWriter
clientStreamWriter
,
TcpServerConnection
serverConnection
,
CancellationTokenSource
cancellationTokenSource
,
CancellationToken
cancellationToken
)
{
// prepare the prefix content
await
serverConnection
.
StreamWriter
.
WriteLineAsync
(
httpCmd
,
cancellationToken
);
await
serverConnection
.
StreamWriter
.
WriteHeadersAsync
(
request
.
Headers
,
cancellationToken
:
cancellationToken
);
string
httpStatus
;
try
{
httpStatus
=
await
serverConnection
.
Stream
.
ReadLineAsync
(
cancellationToken
);
if
(
httpStatus
==
null
)
{
throw
new
ServerConnectionException
(
"Server connection was closed."
);
}
}
catch
(
Exception
e
)
when
(!(
e
is
ServerConnectionException
))
{
throw
new
ServerConnectionException
(
"Server connection was closed."
,
e
);
}
Response
.
ParseResponseLine
(
httpStatus
,
out
var
responseVersion
,
out
int
responseStatusCode
,
out
string
responseStatusDescription
);
response
.
HttpVersion
=
responseVersion
;
response
.
StatusCode
=
responseStatusCode
;
response
.
StatusDescription
=
responseStatusDescription
;
await
HeaderParser
.
ReadHeaders
(
serverConnection
.
Stream
,
response
.
Headers
,
cancellationToken
);
if
(!
args
.
IsTransparent
)
{
await
clientStreamWriter
.
WriteResponseAsync
(
response
,
cancellationToken
:
cancellationToken
);
}
// If user requested call back then do it
if
(!
args
.
WebSession
.
Response
.
Locked
)
{
await
invokeBeforeResponse
(
args
);
}
await
TcpHelper
.
SendRaw
(
clientStream
,
serverConnection
.
Stream
,
BufferPool
,
BufferSize
,
(
buffer
,
offset
,
count
)
=>
{
args
.
OnDataSent
(
buffer
,
offset
,
count
);
},
(
buffer
,
offset
,
count
)
=>
{
args
.
OnDataReceived
(
buffer
,
offset
,
count
);
},
cancellationTokenSource
,
ExceptionFunc
);
}
}
}
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