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
2b1ad86f
Commit
2b1ad86f
authored
May 23, 2016
by
titanium007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use Version instead of string object
parent
9cfe6e7e
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
88 additions
and
54 deletions
+88
-54
SessionEventArgs.cs
Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
+3
-3
HttpWebClient.cs
Titanium.Web.Proxy/Http/HttpWebClient.cs
+12
-2
Request.cs
Titanium.Web.Proxy/Http/Request.cs
+1
-1
Response.cs
Titanium.Web.Proxy/Http/Response.cs
+2
-1
TcpConnectionManager.cs
Titanium.Web.Proxy/Network/TcpConnectionManager.cs
+28
-19
RequestHandler.cs
Titanium.Web.Proxy/RequestHandler.cs
+38
-25
ResponseHandler.cs
Titanium.Web.Proxy/ResponseHandler.cs
+4
-3
No files found.
Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
View file @
2b1ad86f
...
...
@@ -36,7 +36,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// <summary>
/// Does this session uses SSL
/// </summary>
public
bool
IsHttps
{
get
;
internal
set
;
}
public
bool
IsHttps
=>
WebSession
.
Request
.
RequestUri
.
Scheme
==
Uri
.
UriSchemeHttps
;
/// <summary>
/// A web session corresponding to a single request/response sequence
...
...
@@ -87,7 +87,7 @@ namespace Titanium.Web.Proxy.EventArguments
await
this
.
Client
.
ClientStreamReader
.
CopyBytesToStream
(
requestBodyStream
,
WebSession
.
Request
.
ContentLength
).
ConfigureAwait
(
false
);
}
else
if
(
WebSession
.
Request
.
HttpVersion
.
ToLower
().
Trim
().
Equals
(
"http/1.0"
)
)
else
if
(
WebSession
.
Response
.
HttpVersion
.
Major
==
1
&&
WebSession
.
Response
.
HttpVersion
.
Minor
==
0
)
await
WebSession
.
ServerConnection
.
StreamReader
.
CopyBytesToStream
(
requestBodyStream
,
long
.
MaxValue
).
ConfigureAwait
(
false
);
}
WebSession
.
Request
.
RequestBody
=
await
GetDecompressedResponseBody
(
WebSession
.
Request
.
ContentEncoding
,
requestBodyStream
.
ToArray
()).
ConfigureAwait
(
false
);
...
...
@@ -123,7 +123,7 @@ namespace Titanium.Web.Proxy.EventArguments
await
WebSession
.
ServerConnection
.
StreamReader
.
CopyBytesToStream
(
responseBodyStream
,
WebSession
.
Response
.
ContentLength
).
ConfigureAwait
(
false
);
}
else
if
(
WebSession
.
Response
.
HttpVersion
.
ToLower
().
Trim
().
Equals
(
"http/1.0"
)
)
else
if
(
WebSession
.
Response
.
HttpVersion
.
Major
==
1
&&
WebSession
.
Response
.
HttpVersion
.
Minor
==
0
)
await
WebSession
.
ServerConnection
.
StreamReader
.
CopyBytesToStream
(
responseBodyStream
,
long
.
MaxValue
).
ConfigureAwait
(
false
);
}
...
...
Titanium.Web.Proxy/Http/HttpWebClient.cs
View file @
2b1ad86f
...
...
@@ -46,7 +46,7 @@ namespace Titanium.Web.Proxy.Http
{
this
.
Request
.
Method
,
this
.
Request
.
RequestUri
.
PathAndQuery
,
this
.
Request
.
HttpVersion
string
.
Format
(
"HTTP/{0}.{1}"
,
this
.
Request
.
HttpVersion
.
Major
,
this
.
Request
.
HttpVersion
.
Minor
)
}));
foreach
(
HttpHeader
httpHeader
in
this
.
Request
.
RequestHeaders
)
...
...
@@ -95,8 +95,18 @@ namespace Titanium.Web.Proxy.Http
{
await
ServerConnection
.
StreamReader
.
ReadLineAsync
().
ConfigureAwait
(
false
);
}
var
httpVersion
=
httpResult
[
0
].
Trim
().
ToLower
();
Version
version
;
if
(
httpVersion
==
"http/1.1"
)
{
version
=
new
Version
(
1
,
1
);
}
else
{
version
=
new
Version
(
1
,
0
);
}
this
.
Response
.
HttpVersion
=
httpResult
[
0
].
Trim
()
;
this
.
Response
.
HttpVersion
=
version
;
this
.
Response
.
ResponseStatusCode
=
httpResult
[
1
].
Trim
();
this
.
Response
.
ResponseStatusDescription
=
httpResult
[
2
].
Trim
();
...
...
Titanium.Web.Proxy/Http/Request.cs
View file @
2b1ad86f
...
...
@@ -11,7 +11,7 @@ namespace Titanium.Web.Proxy.Http
{
public
string
Method
{
get
;
set
;
}
public
Uri
RequestUri
{
get
;
set
;
}
public
string
HttpVersion
{
get
;
set
;
}
public
Version
HttpVersion
{
get
;
set
;
}
internal
string
Host
{
...
...
Titanium.Web.Proxy/Http/Response.cs
View file @
2b1ad86f
...
...
@@ -4,6 +4,7 @@ using System.Linq;
using
System.Text
;
using
Titanium.Web.Proxy.Models
;
using
Titanium.Web.Proxy.Extensions
;
using
System
;
namespace
Titanium.Web.Proxy.Http
{
...
...
@@ -31,7 +32,7 @@ namespace Titanium.Web.Proxy.Http
}
}
internal
string
HttpVersion
{
get
;
set
;
}
internal
Version
HttpVersion
{
get
;
set
;
}
internal
bool
ResponseKeepAlive
{
get
...
...
Titanium.Web.Proxy/Network/TcpConnectionManager.cs
View file @
2b1ad86f
...
...
@@ -37,21 +37,31 @@ namespace Titanium.Web.Proxy.Network
internal
class
TcpConnectionManager
{
static
List
<
TcpConnection
>
C
onnectionCache
=
new
List
<
TcpConnection
>();
static
List
<
TcpConnection
>
c
onnectionCache
=
new
List
<
TcpConnection
>();
static
SemaphoreSlim
connectionAccessLock
=
new
SemaphoreSlim
(
1
);
internal
static
async
Task
<
TcpConnection
>
GetClient
(
SessionEventArgs
sessionArgs
,
string
hostname
,
int
port
,
bool
isSecure
,
Version
version
)
{
TcpConnection
cached
=
null
;
while
(
true
)
{
lock
(
ConnectionCache
)
await
connectionAccessLock
.
WaitAsync
();
try
{
cached
=
C
onnectionCache
.
FirstOrDefault
(
x
=>
x
.
HostName
==
hostname
&&
x
.
port
==
port
&&
cached
=
c
onnectionCache
.
FirstOrDefault
(
x
=>
x
.
HostName
==
hostname
&&
x
.
port
==
port
&&
x
.
IsSecure
==
isSecure
&&
x
.
TcpClient
.
Connected
&&
x
.
Version
.
Equals
(
version
));
//just create one more preemptively
if
(
connectionCache
.
Where
(
x
=>
x
.
HostName
==
hostname
&&
x
.
port
==
port
&&
x
.
IsSecure
==
isSecure
&&
x
.
TcpClient
.
Connected
&&
x
.
Version
.
Equals
(
version
)).
Count
()
<
2
)
{
var
task
=
CreateClient
(
sessionArgs
,
hostname
,
port
,
isSecure
,
version
)
.
ContinueWith
(
async
(
x
)
=>
{
if
(
x
.
Status
==
TaskStatus
.
RanToCompletion
)
await
ReleaseClient
(
x
.
Result
);
});
}
if
(
cached
!=
null
)
C
onnectionCache
.
Remove
(
cached
);
c
onnectionCache
.
Remove
(
cached
);
}
finally
{
connectionAccessLock
.
Release
();
}
if
(
cached
!=
null
&&
!
cached
.
TcpClient
.
Client
.
IsConnected
())
continue
;
...
...
@@ -62,15 +72,7 @@ namespace Titanium.Web.Proxy.Network
if
(
cached
==
null
)
cached
=
await
CreateClient
(
sessionArgs
,
hostname
,
port
,
isSecure
,
version
).
ConfigureAwait
(
false
);
//just create one more preemptively
if
(
ConnectionCache
.
Where
(
x
=>
x
.
HostName
==
hostname
&&
x
.
port
==
port
&&
x
.
IsSecure
==
isSecure
&&
x
.
TcpClient
.
Connected
&&
x
.
Version
.
Equals
(
version
)).
Count
()
<
2
)
{
var
task
=
CreateClient
(
sessionArgs
,
hostname
,
port
,
isSecure
,
version
)
.
ContinueWith
(
x
=>
{
if
(
x
.
Status
==
TaskStatus
.
RanToCompletion
)
ReleaseClient
(
x
.
Result
);
});
}
return
cached
;
}
...
...
@@ -155,27 +157,34 @@ namespace Titanium.Web.Proxy.Network
}
internal
static
void
ReleaseClient
(
TcpConnection
Connection
)
internal
static
async
Task
ReleaseClient
(
TcpConnection
Connection
)
{
Connection
.
LastAccess
=
DateTime
.
Now
;
ConnectionCache
.
Add
(
Connection
);
await
connectionAccessLock
.
WaitAsync
();
try
{
connectionCache
.
Add
(
Connection
);
}
finally
{
connectionAccessLock
.
Release
();
}
}
internal
async
static
void
ClearIdleConnections
()
{
while
(
true
)
{
lock
(
ConnectionCache
)
await
connectionAccessLock
.
WaitAsync
();
try
{
var
cutOff
=
DateTime
.
Now
.
AddSeconds
(-
60
);
C
onnectionCache
c
onnectionCache
.
Where
(
x
=>
x
.
LastAccess
<
cutOff
)
.
ToList
()
.
ForEach
(
x
=>
x
.
TcpClient
.
Close
());
C
onnectionCache
.
RemoveAll
(
x
=>
x
.
LastAccess
<
cutOff
);
c
onnectionCache
.
RemoveAll
(
x
=>
x
.
LastAccess
<
cutOff
);
}
finally
{
connectionAccessLock
.
Release
();
}
await
Task
.
Delay
(
1000
*
60
*
3
).
ConfigureAwait
(
false
);
}
...
...
Titanium.Web.Proxy/RequestHandler.cs
View file @
2b1ad86f
...
...
@@ -52,10 +52,21 @@ namespace Titanium.Web.Proxy
else
httpRemoteUri
=
new
Uri
(
httpCmdSplit
[
1
]);
string
httpVersion
=
"HTTP/1.1"
;
Version
version
=
new
Version
(
1
,
1
);
if
(
httpCmdSplit
.
Length
==
3
)
httpVersion
=
httpCmdSplit
[
2
];
{
string
httpVersion
=
httpCmdSplit
[
1
].
Trim
();
if
(
httpVersion
==
"http/1.1"
)
{
version
=
new
Version
(
1
,
1
);
}
else
{
version
=
new
Version
(
1
,
0
);
}
}
var
excluded
=
endPoint
.
ExcludedHttpsHostNameRegex
!=
null
?
endPoint
.
ExcludedHttpsHostNameRegex
.
Any
(
x
=>
Regex
.
IsMatch
(
httpRemoteUri
.
Host
,
x
))
:
false
;
...
...
@@ -65,7 +76,7 @@ namespace Titanium.Web.Proxy
httpRemoteUri
=
new
Uri
(
"https://"
+
httpCmdSplit
[
1
]);
await
clientStreamReader
.
ReadAllLinesAsync
().
ConfigureAwait
(
false
);
await
WriteConnectResponse
(
clientStreamWriter
,
httpV
ersion
).
ConfigureAwait
(
false
);
await
WriteConnectResponse
(
clientStreamWriter
,
v
ersion
).
ConfigureAwait
(
false
);
var
certificate
=
await
CertManager
.
CreateCertificate
(
httpRemoteUri
.
Host
);
...
...
@@ -101,7 +112,7 @@ namespace Titanium.Web.Proxy
else
if
(
httpVerb
.
ToUpper
()
==
"CONNECT"
)
{
await
clientStreamReader
.
ReadAllLinesAsync
().
ConfigureAwait
(
false
);
await
WriteConnectResponse
(
clientStreamWriter
,
httpV
ersion
).
ConfigureAwait
(
false
);
await
WriteConnectResponse
(
clientStreamWriter
,
v
ersion
).
ConfigureAwait
(
false
);
await
TcpHelper
.
SendRaw
(
clientStream
,
null
,
null
,
httpRemoteUri
.
Host
,
httpRemoteUri
.
Port
,
false
).
ConfigureAwait
(
false
);
...
...
@@ -178,7 +189,7 @@ namespace Titanium.Web.Proxy
CustomBinaryReader
clientStreamReader
,
StreamWriter
clientStreamWriter
,
bool
IsHttps
)
{
TcpConnection
connection
=
null
;
string
lastRequest
HostName
=
null
;
string
lastRequest
=
null
;
while
(
true
)
{
...
...
@@ -197,10 +208,10 @@ namespace Titanium.Web.Proxy
var
httpCmdSplit
=
httpCmd
.
Split
(
Constants
.
SpaceSplit
,
3
);
var
httpMethod
=
httpCmdSplit
[
0
];
var
httpVersion
=
httpCmdSplit
[
2
];
var
httpVersion
=
httpCmdSplit
[
2
]
.
ToLower
().
Trim
()
;
Version
version
;
if
(
httpVersion
==
"
HTTP
/1.1"
)
if
(
httpVersion
==
"
http
/1.1"
)
{
version
=
new
Version
(
1
,
1
);
}
...
...
@@ -219,26 +230,18 @@ namespace Titanium.Web.Proxy
}
var
httpRemoteUri
=
new
Uri
(!
IsHttps
?
httpCmdSplit
[
1
]
:
(
string
.
Concat
(
"https://"
,
args
.
WebSession
.
Request
.
Host
,
httpCmdSplit
[
1
])));
args
.
IsHttps
=
IsHttps
;
args
.
WebSession
.
Request
.
RequestUri
=
httpRemoteUri
;
args
.
WebSession
.
Request
.
Method
=
httpMethod
;
args
.
WebSession
.
Request
.
HttpVersion
=
httpV
ersion
;
args
.
WebSession
.
Request
.
HttpVersion
=
v
ersion
;
args
.
Client
.
ClientStream
=
clientStream
;
args
.
Client
.
ClientStreamReader
=
clientStreamReader
;
args
.
Client
.
ClientStreamWriter
=
clientStreamWriter
;
if
(
args
.
WebSession
.
Request
.
UpgradeToWebSocket
)
{
await
TcpHelper
.
SendRaw
(
clientStream
,
httpCmd
,
args
.
WebSession
.
Request
.
RequestHeaders
,
httpRemoteUri
.
Host
,
httpRemoteUri
.
Port
,
args
.
IsHttps
).
ConfigureAwait
(
false
);
Dispose
(
client
,
clientStream
,
clientStreamReader
,
clientStreamWriter
,
args
);
return
;
}
PrepareRequestHeaders
(
args
.
WebSession
.
Request
.
RequestHeaders
,
args
.
WebSession
);
args
.
WebSession
.
Request
.
Host
=
args
.
WebSession
.
Request
.
RequestUri
.
Host
;
args
.
WebSession
.
Request
.
Host
=
args
.
WebSession
.
Request
.
RequestUri
.
Authority
;
//If requested interception
if
(
BeforeRequest
!=
null
)
...
...
@@ -251,16 +254,26 @@ namespace Titanium.Web.Proxy
handlerTasks
[
i
]
=
((
Func
<
object
,
SessionEventArgs
,
Task
>)
invocationList
[
i
])(
null
,
args
);
}
await
Task
.
WhenAll
(
handlerTasks
).
ConfigureAwait
(
false
);
await
Task
.
WhenAll
(
handlerTasks
).
ConfigureAwait
(
false
);
}
if
(
args
.
WebSession
.
Request
.
UpgradeToWebSocket
)
{
await
TcpHelper
.
SendRaw
(
clientStream
,
httpCmd
,
args
.
WebSession
.
Request
.
RequestHeaders
,
httpRemoteUri
.
Host
,
httpRemoteUri
.
Port
,
args
.
IsHttps
).
ConfigureAwait
(
false
);
Dispose
(
client
,
clientStream
,
clientStreamReader
,
clientStreamWriter
,
args
);
return
;
}
//construct the web request that we are going to issue on behalf of the client.
connection
=
connection
==
null
?
await
TcpConnectionManager
.
GetClient
(
args
,
args
.
WebSession
.
Request
.
RequestUri
.
Host
,
args
.
WebSession
.
Request
.
RequestUri
.
Port
,
args
.
IsHttps
,
version
).
ConfigureAwait
(
false
)
:
lastRequest
HostName
!=
args
.
WebSession
.
Request
.
RequestUri
.
Host
?
await
TcpConnectionManager
.
GetClient
(
args
,
args
.
WebSession
.
Request
.
RequestUri
.
Host
,
args
.
WebSession
.
Request
.
RequestUri
.
Port
,
args
.
IsHttps
,
version
).
ConfigureAwait
(
false
)
:
lastRequest
!=
args
.
WebSession
.
Request
.
RequestUri
.
Host
?
await
TcpConnectionManager
.
GetClient
(
args
,
args
.
WebSession
.
Request
.
RequestUri
.
Host
,
args
.
WebSession
.
Request
.
RequestUri
.
Port
,
args
.
IsHttps
,
version
).
ConfigureAwait
(
false
)
:
connection
;
lastRequestHostName
=
args
.
WebSession
.
Request
.
RequestUri
.
Host
;
lastRequest
=
string
.
Concat
(
args
.
WebSession
.
Request
.
RequestUri
.
Host
,
":"
,
args
.
WebSession
.
Request
.
RequestUri
.
Port
,
":"
,
args
.
IsHttps
,
":"
,
version
.
ToString
());
args
.
WebSession
.
Request
.
RequestLocked
=
true
;
...
...
@@ -347,12 +360,12 @@ namespace Titanium.Web.Proxy
}
if
(
connection
!=
null
)
TcpConnectionManager
.
ReleaseClient
(
connection
);
await
TcpConnectionManager
.
ReleaseClient
(
connection
);
}
private
static
async
Task
WriteConnectResponse
(
StreamWriter
clientStreamWriter
,
string
httpVersion
)
private
static
async
Task
WriteConnectResponse
(
StreamWriter
clientStreamWriter
,
Version
httpVersion
)
{
await
clientStreamWriter
.
WriteLineAsync
(
httpVersion
+
" 200 Connection established"
).
ConfigureAwait
(
false
);
await
clientStreamWriter
.
WriteLineAsync
(
string
.
Format
(
"HTTP/{0}.{1} {2}"
,
httpVersion
.
Major
,
httpVersion
.
Minor
,
"200 Connection established"
)
).
ConfigureAwait
(
false
);
await
clientStreamWriter
.
WriteLineAsync
(
string
.
Format
(
"Timestamp: {0}"
,
DateTime
.
Now
)).
ConfigureAwait
(
false
);
await
clientStreamWriter
.
WriteLineAsync
().
ConfigureAwait
(
false
);
await
clientStreamWriter
.
FlushAsync
().
ConfigureAwait
(
false
);
...
...
Titanium.Web.Proxy/ResponseHandler.cs
View file @
2b1ad86f
...
...
@@ -80,7 +80,8 @@ namespace Titanium.Web.Proxy
{
await
WriteResponseHeaders
(
args
.
Client
.
ClientStreamWriter
,
args
.
WebSession
.
Response
.
ResponseHeaders
);
if
(
args
.
WebSession
.
Response
.
IsChunked
||
args
.
WebSession
.
Response
.
ContentLength
>
0
||
args
.
WebSession
.
Response
.
HttpVersion
.
ToLower
().
Trim
()
==
"http/1.0"
)
if
(
args
.
WebSession
.
Response
.
IsChunked
||
args
.
WebSession
.
Response
.
ContentLength
>
0
||
(
args
.
WebSession
.
Response
.
HttpVersion
.
Major
==
1
&&
args
.
WebSession
.
Response
.
HttpVersion
.
Minor
==
0
))
await
WriteResponseBody
(
args
.
WebSession
.
ServerConnection
.
StreamReader
,
args
.
Client
.
ClientStream
,
args
.
WebSession
.
Response
.
IsChunked
,
args
.
WebSession
.
Response
.
ContentLength
).
ConfigureAwait
(
false
);
}
...
...
@@ -105,10 +106,10 @@ namespace Titanium.Web.Proxy
}
private
static
void
WriteResponseStatus
(
string
version
,
string
code
,
string
description
,
private
static
void
WriteResponseStatus
(
Version
version
,
string
code
,
string
description
,
StreamWriter
responseWriter
)
{
responseWriter
.
WriteLineAsync
(
string
.
Format
(
"
{0} {1} {2}"
,
version
,
code
,
description
));
responseWriter
.
WriteLineAsync
(
string
.
Format
(
"
HTTP/{0}.{1} {2} {3}"
,
version
.
Major
,
version
.
Minor
,
code
,
description
));
}
private
static
async
Task
WriteResponseHeaders
(
StreamWriter
responseWriter
,
List
<
HttpHeader
>
headers
)
...
...
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