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
f59fb6a3
Commit
f59fb6a3
authored
Jun 16, 2016
by
justcoding121
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
clean up;add comments
parent
a4e2e3ed
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
293 additions
and
212 deletions
+293
-212
DeflateCompression.cs
Titanium.Web.Proxy/Compression/DeflateCompression.cs
+1
-1
GZipCompression.cs
Titanium.Web.Proxy/Compression/GZipCompression.cs
+1
-1
ZlibCompression.cs
Titanium.Web.Proxy/Compression/ZlibCompression.cs
+1
-1
DeflateDecompression.cs
Titanium.Web.Proxy/Decompression/DeflateDecompression.cs
+1
-1
GZipDecompression.cs
Titanium.Web.Proxy/Decompression/GZipDecompression.cs
+1
-1
ZlibDecompression.cs
Titanium.Web.Proxy/Decompression/ZlibDecompression.cs
+1
-1
SessionEventArgs.cs
Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
+22
-22
ByteArrayExtensions.cs
Titanium.Web.Proxy/Extensions/ByteArrayExtensions.cs
+27
-0
HttpWebRequestExtensions.cs
Titanium.Web.Proxy/Extensions/HttpWebRequestExtensions.cs
+5
-1
HttpWebResponseExtensions.cs
Titanium.Web.Proxy/Extensions/HttpWebResponseExtensions.cs
+5
-0
StreamExtensions.cs
Titanium.Web.Proxy/Extensions/StreamExtensions.cs
+138
-5
TcpExtensions.cs
Titanium.Web.Proxy/Extensions/TcpExtensions.cs
+5
-0
CertificateManager.cs
Titanium.Web.Proxy/Helpers/CertificateManager.cs
+1
-1
CustomBinaryReader.cs
Titanium.Web.Proxy/Helpers/CustomBinaryReader.cs
+28
-26
Tcp.cs
Titanium.Web.Proxy/Helpers/Tcp.cs
+1
-1
HttpWebClient.cs
Titanium.Web.Proxy/Http/HttpWebClient.cs
+6
-6
TcpConnectionManager.cs
Titanium.Web.Proxy/Network/TcpConnectionManager.cs
+10
-10
RequestHandler.cs
Titanium.Web.Proxy/RequestHandler.cs
+29
-34
ResponseHandler.cs
Titanium.Web.Proxy/ResponseHandler.cs
+9
-100
Titanium.Web.Proxy.csproj
Titanium.Web.Proxy/Titanium.Web.Proxy.csproj
+1
-0
No files found.
Titanium.Web.Proxy/Compression/DeflateCompression.cs
View file @
f59fb6a3
...
...
@@ -12,7 +12,7 @@ namespace Titanium.Web.Proxy.Compression
{
using
(
var
zip
=
new
DeflateStream
(
ms
,
CompressionMode
.
Compress
,
true
))
{
await
zip
.
WriteAsync
(
responseBody
,
0
,
responseBody
.
Length
)
.
ConfigureAwait
(
false
)
;
await
zip
.
WriteAsync
(
responseBody
,
0
,
responseBody
.
Length
);
}
return
ms
.
ToArray
();
...
...
Titanium.Web.Proxy/Compression/GZipCompression.cs
View file @
f59fb6a3
...
...
@@ -12,7 +12,7 @@ namespace Titanium.Web.Proxy.Compression
{
using
(
var
zip
=
new
GZipStream
(
ms
,
CompressionMode
.
Compress
,
true
))
{
await
zip
.
WriteAsync
(
responseBody
,
0
,
responseBody
.
Length
)
.
ConfigureAwait
(
false
)
;
await
zip
.
WriteAsync
(
responseBody
,
0
,
responseBody
.
Length
);
}
return
ms
.
ToArray
();
...
...
Titanium.Web.Proxy/Compression/ZlibCompression.cs
View file @
f59fb6a3
...
...
@@ -12,7 +12,7 @@ namespace Titanium.Web.Proxy.Compression
{
using
(
var
zip
=
new
ZlibStream
(
ms
,
CompressionMode
.
Compress
,
true
))
{
await
zip
.
WriteAsync
(
responseBody
,
0
,
responseBody
.
Length
)
.
ConfigureAwait
(
false
)
;
await
zip
.
WriteAsync
(
responseBody
,
0
,
responseBody
.
Length
);
}
return
ms
.
ToArray
();
...
...
Titanium.Web.Proxy/Decompression/DeflateDecompression.cs
View file @
f59fb6a3
...
...
@@ -20,7 +20,7 @@ namespace Titanium.Web.Proxy.Decompression
int
read
;
while
((
read
=
await
decompressor
.
ReadAsync
(
buffer
,
0
,
buffer
.
Length
).
ConfigureAwait
(
false
))
>
0
)
{
await
output
.
WriteAsync
(
buffer
,
0
,
read
)
.
ConfigureAwait
(
false
)
;
await
output
.
WriteAsync
(
buffer
,
0
,
read
);
}
return
output
.
ToArray
();
...
...
Titanium.Web.Proxy/Decompression/GZipDecompression.cs
View file @
f59fb6a3
...
...
@@ -17,7 +17,7 @@ namespace Titanium.Web.Proxy.Decompression
int
read
;
while
((
read
=
await
decompressor
.
ReadAsync
(
buffer
,
0
,
buffer
.
Length
).
ConfigureAwait
(
false
))
>
0
)
{
await
output
.
WriteAsync
(
buffer
,
0
,
read
)
.
ConfigureAwait
(
false
)
;
await
output
.
WriteAsync
(
buffer
,
0
,
read
);
}
return
output
.
ToArray
();
}
...
...
Titanium.Web.Proxy/Decompression/ZlibDecompression.cs
View file @
f59fb6a3
...
...
@@ -19,7 +19,7 @@ namespace Titanium.Web.Proxy.Decompression
int
read
;
while
((
read
=
await
decompressor
.
ReadAsync
(
buffer
,
0
,
buffer
.
Length
).
ConfigureAwait
(
false
))
>
0
)
{
await
output
.
WriteAsync
(
buffer
,
0
,
read
)
.
ConfigureAwait
(
false
)
;
await
output
.
WriteAsync
(
buffer
,
0
,
read
);
}
return
output
.
ToArray
();
}
...
...
Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
View file @
f59fb6a3
...
...
@@ -81,7 +81,7 @@ namespace Titanium.Web.Proxy.EventArguments
//For chunked request we need to read data as they arrive, until we reach a chunk end symbol
if
(
WebSession
.
Request
.
IsChunked
)
{
await
this
.
ProxyClient
.
ClientStreamReader
.
CopyBytesToStreamChunked
(
requestBodyStream
)
.
ConfigureAwait
(
false
)
;
await
this
.
ProxyClient
.
ClientStreamReader
.
CopyBytesToStreamChunked
(
requestBodyStream
);
}
else
{
...
...
@@ -89,13 +89,13 @@ namespace Titanium.Web.Proxy.EventArguments
if
(
WebSession
.
Request
.
ContentLength
>
0
)
{
//If not chunked then its easy just read the amount of bytes mentioned in content length header of response
await
this
.
ProxyClient
.
ClientStreamReader
.
CopyBytesToStream
(
requestBodyStream
,
WebSession
.
Request
.
ContentLength
)
.
ConfigureAwait
(
false
)
;
await
this
.
ProxyClient
.
ClientStreamReader
.
CopyBytesToStream
(
requestBodyStream
,
WebSession
.
Request
.
ContentLength
);
}
else
if
(
WebSession
.
Request
.
HttpVersion
.
Major
==
1
&&
WebSession
.
Request
.
HttpVersion
.
Minor
==
0
)
await
WebSession
.
ServerConnection
.
StreamReader
.
CopyBytesToStream
(
requestBodyStream
,
long
.
MaxValue
)
.
ConfigureAwait
(
false
)
;
await
WebSession
.
ServerConnection
.
StreamReader
.
CopyBytesToStream
(
requestBodyStream
,
long
.
MaxValue
);
}
WebSession
.
Request
.
RequestBody
=
await
GetDecompressedResponseBody
(
WebSession
.
Request
.
ContentEncoding
,
requestBodyStream
.
ToArray
())
.
ConfigureAwait
(
false
)
;
WebSession
.
Request
.
RequestBody
=
await
GetDecompressedResponseBody
(
WebSession
.
Request
.
ContentEncoding
,
requestBodyStream
.
ToArray
());
}
//Now set the flag to true
...
...
@@ -118,21 +118,21 @@ namespace Titanium.Web.Proxy.EventArguments
//If chuncked the read chunk by chunk until we hit chunk end symbol
if
(
WebSession
.
Response
.
IsChunked
)
{
await
WebSession
.
ServerConnection
.
StreamReader
.
CopyBytesToStreamChunked
(
responseBodyStream
)
.
ConfigureAwait
(
false
)
;
await
WebSession
.
ServerConnection
.
StreamReader
.
CopyBytesToStreamChunked
(
responseBodyStream
);
}
else
{
if
(
WebSession
.
Response
.
ContentLength
>
0
)
{
//If not chunked then its easy just read the amount of bytes mentioned in content length header of response
await
WebSession
.
ServerConnection
.
StreamReader
.
CopyBytesToStream
(
responseBodyStream
,
WebSession
.
Response
.
ContentLength
)
.
ConfigureAwait
(
false
)
;
await
WebSession
.
ServerConnection
.
StreamReader
.
CopyBytesToStream
(
responseBodyStream
,
WebSession
.
Response
.
ContentLength
);
}
else
if
(
WebSession
.
Response
.
HttpVersion
.
Major
==
1
&&
WebSession
.
Response
.
HttpVersion
.
Minor
==
0
)
await
WebSession
.
ServerConnection
.
StreamReader
.
CopyBytesToStream
(
responseBodyStream
,
long
.
MaxValue
)
.
ConfigureAwait
(
false
)
;
await
WebSession
.
ServerConnection
.
StreamReader
.
CopyBytesToStream
(
responseBodyStream
,
long
.
MaxValue
);
}
WebSession
.
Response
.
ResponseBody
=
await
GetDecompressedResponseBody
(
WebSession
.
Response
.
ContentEncoding
,
responseBodyStream
.
ToArray
())
.
ConfigureAwait
(
false
)
;
WebSession
.
Response
.
ResponseBody
=
await
GetDecompressedResponseBody
(
WebSession
.
Response
.
ContentEncoding
,
responseBodyStream
.
ToArray
());
}
//set this to true for caching
...
...
@@ -149,7 +149,7 @@ namespace Titanium.Web.Proxy.EventArguments
if
(
WebSession
.
Request
.
RequestLocked
)
throw
new
Exception
(
"You cannot call this function after request is made to server."
);
await
ReadRequestBody
()
.
ConfigureAwait
(
false
)
;
await
ReadRequestBody
();
return
WebSession
.
Request
.
RequestBody
;
}
/// <summary>
...
...
@@ -162,7 +162,7 @@ namespace Titanium.Web.Proxy.EventArguments
throw
new
Exception
(
"You cannot call this function after request is made to server."
);
await
ReadRequestBody
()
.
ConfigureAwait
(
false
)
;
await
ReadRequestBody
();
//Use the encoding specified in request to decode the byte[] data to string
return
WebSession
.
Request
.
RequestBodyString
??
(
WebSession
.
Request
.
RequestBodyString
=
WebSession
.
Request
.
Encoding
.
GetString
(
WebSession
.
Request
.
RequestBody
));
...
...
@@ -180,7 +180,7 @@ namespace Titanium.Web.Proxy.EventArguments
//syphon out the request body from client before setting the new body
if
(!
WebSession
.
Request
.
RequestBodyRead
)
{
await
ReadRequestBody
()
.
ConfigureAwait
(
false
)
;
await
ReadRequestBody
();
}
WebSession
.
Request
.
RequestBody
=
body
;
...
...
@@ -203,7 +203,7 @@ namespace Titanium.Web.Proxy.EventArguments
//syphon out the request body from client before setting the new body
if
(!
WebSession
.
Request
.
RequestBodyRead
)
{
await
ReadRequestBody
()
.
ConfigureAwait
(
false
)
;
await
ReadRequestBody
();
}
await
SetRequestBody
(
WebSession
.
Request
.
Encoding
.
GetBytes
(
body
));
...
...
@@ -219,7 +219,7 @@ namespace Titanium.Web.Proxy.EventArguments
if
(!
WebSession
.
Request
.
RequestLocked
)
throw
new
Exception
(
"You cannot call this function before request is made to server."
);
await
ReadResponseBody
()
.
ConfigureAwait
(
false
)
;
await
ReadResponseBody
();
return
WebSession
.
Response
.
ResponseBody
;
}
...
...
@@ -232,7 +232,7 @@ namespace Titanium.Web.Proxy.EventArguments
if
(!
WebSession
.
Request
.
RequestLocked
)
throw
new
Exception
(
"You cannot call this function before request is made to server."
);
await
GetResponseBody
()
.
ConfigureAwait
(
false
)
;
await
GetResponseBody
();
return
WebSession
.
Response
.
ResponseBodyString
??
(
WebSession
.
Response
.
ResponseBodyString
=
WebSession
.
Response
.
Encoding
.
GetString
(
WebSession
.
Response
.
ResponseBody
));
}
...
...
@@ -249,7 +249,7 @@ namespace Titanium.Web.Proxy.EventArguments
//syphon out the response body from server before setting the new body
if
(
WebSession
.
Response
.
ResponseBody
==
null
)
{
await
GetResponseBody
()
.
ConfigureAwait
(
false
)
;
await
GetResponseBody
();
}
WebSession
.
Response
.
ResponseBody
=
body
;
...
...
@@ -273,12 +273,12 @@ namespace Titanium.Web.Proxy.EventArguments
//syphon out the response body from server before setting the new body
if
(
WebSession
.
Response
.
ResponseBody
==
null
)
{
await
GetResponseBody
()
.
ConfigureAwait
(
false
)
;
await
GetResponseBody
();
}
var
bodyBytes
=
WebSession
.
Response
.
Encoding
.
GetBytes
(
body
);
await
SetResponseBody
(
bodyBytes
)
.
ConfigureAwait
(
false
)
;
await
SetResponseBody
(
bodyBytes
);
}
private
async
Task
<
byte
[
]>
GetDecompressedResponseBody
(
string
encodingType
,
byte
[]
responseBodyStream
)
...
...
@@ -286,7 +286,7 @@ namespace Titanium.Web.Proxy.EventArguments
var
decompressionFactory
=
new
DecompressionFactory
();
var
decompressor
=
decompressionFactory
.
Create
(
encodingType
);
return
await
decompressor
.
Decompress
(
responseBodyStream
)
.
ConfigureAwait
(
false
)
;
return
await
decompressor
.
Decompress
(
responseBodyStream
);
}
...
...
@@ -306,7 +306,7 @@ namespace Titanium.Web.Proxy.EventArguments
var
result
=
Encoding
.
Default
.
GetBytes
(
html
);
await
Ok
(
result
)
.
ConfigureAwait
(
false
)
;
await
Ok
(
result
);
}
/// <summary>
...
...
@@ -322,7 +322,7 @@ namespace Titanium.Web.Proxy.EventArguments
response
.
HttpVersion
=
WebSession
.
Request
.
HttpVersion
;
response
.
ResponseBody
=
result
;
await
Respond
(
response
)
.
ConfigureAwait
(
false
)
;
await
Respond
(
response
);
WebSession
.
Request
.
CancelRequest
=
true
;
}
...
...
@@ -335,7 +335,7 @@ namespace Titanium.Web.Proxy.EventArguments
response
.
ResponseHeaders
.
Add
(
new
Models
.
HttpHeader
(
"Location"
,
url
));
response
.
ResponseBody
=
Encoding
.
ASCII
.
GetBytes
(
string
.
Empty
);
await
Respond
(
response
)
.
ConfigureAwait
(
false
)
;
await
Respond
(
response
);
WebSession
.
Request
.
CancelRequest
=
true
;
}
...
...
@@ -350,7 +350,7 @@ namespace Titanium.Web.Proxy.EventArguments
WebSession
.
Response
=
response
;
await
ProxyServer
.
HandleHttpSessionResponse
(
this
)
.
ConfigureAwait
(
false
)
;
await
ProxyServer
.
HandleHttpSessionResponse
(
this
);
}
}
...
...
Titanium.Web.Proxy/Extensions/ByteArrayExtensions.cs
0 → 100644
View file @
f59fb6a3
using
System
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Text
;
using
System.Threading.Tasks
;
namespace
Titanium.Web.Proxy.Extensions
{
public
static
class
ByteArrayExtensions
{
/// <summary>
/// Get the sub array from byte of data
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="data"></param>
/// <param name="index"></param>
/// <param name="length"></param>
/// <returns></returns>
public
static
T
[]
SubArray
<
T
>(
this
T
[]
data
,
int
index
,
int
length
)
{
T
[]
result
=
new
T
[
length
];
Array
.
Copy
(
data
,
index
,
result
,
0
,
length
);
return
result
;
}
}
}
Titanium.Web.Proxy/Extensions/HttpWebRequestExtensions.cs
View file @
f59fb6a3
...
...
@@ -9,7 +9,11 @@ namespace Titanium.Web.Proxy.Extensions
/// </summary>
internal
static
class
HttpWebRequestExtensions
{
//Get encoding of the HTTP request
/// <summary>
/// parse the character encoding of request from request headers
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
internal
static
Encoding
GetEncoding
(
this
Request
request
)
{
try
...
...
Titanium.Web.Proxy/Extensions/HttpWebResponseExtensions.cs
View file @
f59fb6a3
...
...
@@ -6,6 +6,11 @@ namespace Titanium.Web.Proxy.Extensions
{
internal
static
class
HttpWebResponseExtensions
{
/// <summary>
/// Gets the character encoding of response from response headers
/// </summary>
/// <param name="response"></param>
/// <returns></returns>
internal
static
Encoding
GetResponseCharacterEncoding
(
this
Response
response
)
{
try
...
...
Titanium.Web.Proxy/Extensions/StreamExtensions.cs
View file @
f59fb6a3
...
...
@@ -8,8 +8,15 @@ using Titanium.Web.Proxy.Shared;
namespace
Titanium.Web.Proxy.Extensions
{
internal
static
class
Stream
Helper
internal
static
class
Stream
Extensions
{
/// <summary>
/// Copy streams asynchronously with an initial data inserted to the beginning of stream
/// </summary>
/// <param name="input"></param>
/// <param name="initialData"></param>
/// <param name="output"></param>
/// <returns></returns>
internal
static
async
Task
CopyToAsync
(
this
Stream
input
,
string
initialData
,
Stream
output
)
{
if
(!
string
.
IsNullOrEmpty
(
initialData
))
...
...
@@ -19,7 +26,13 @@ namespace Titanium.Web.Proxy.Extensions
}
await
input
.
CopyToAsync
(
output
);
}
/// <summary>
/// copies the specified bytes to the stream from the input stream
/// </summary>
/// <param name="streamReader"></param>
/// <param name="stream"></param>
/// <param name="totalBytesToRead"></param>
/// <returns></returns>
internal
static
async
Task
CopyBytesToStream
(
this
CustomBinaryReader
streamReader
,
Stream
stream
,
long
totalBytesToRead
)
{
var
totalbytesRead
=
0
;
...
...
@@ -50,11 +63,18 @@ namespace Titanium.Web.Proxy.Extensions
await
stream
.
WriteAsync
(
buffer
,
0
,
buffer
.
Length
);
}
}
/// <summary>
/// Copies the stream chunked
/// </summary>
/// <param name="clientStreamReader"></param>
/// <param name="stream"></param>
/// <returns></returns>
internal
static
async
Task
CopyBytesToStreamChunked
(
this
CustomBinaryReader
clientStreamReader
,
Stream
stream
)
{
while
(
true
)
{
var
chuchkHead
=
await
clientStreamReader
.
ReadLineAsync
()
.
ConfigureAwait
(
false
)
;
var
chuchkHead
=
await
clientStreamReader
.
ReadLineAsync
();
var
chunkSize
=
int
.
Parse
(
chuchkHead
,
NumberStyles
.
HexNumber
);
if
(
chunkSize
!=
0
)
...
...
@@ -62,14 +82,127 @@ namespace Titanium.Web.Proxy.Extensions
var
buffer
=
await
clientStreamReader
.
ReadBytesAsync
(
chunkSize
);
await
stream
.
WriteAsync
(
buffer
,
0
,
buffer
.
Length
);
//chunk trail
await
clientStreamReader
.
ReadLineAsync
().
ConfigureAwait
(
false
);
await
clientStreamReader
.
ReadLineAsync
();
}
else
{
await
clientStreamReader
.
ReadLineAsync
();
break
;
}
}
}
/// <summary>
/// Writes the byte array body to the given stream; optionally chunked
/// </summary>
/// <param name="clientStream"></param>
/// <param name="data"></param>
/// <param name="isChunked"></param>
/// <returns></returns>
internal
static
async
Task
WriteResponseBody
(
this
Stream
clientStream
,
byte
[]
data
,
bool
isChunked
)
{
if
(!
isChunked
)
{
await
clientStream
.
WriteAsync
(
data
,
0
,
data
.
Length
);
}
else
await
WriteResponseBodyChunked
(
data
,
clientStream
);
}
/// <summary>
/// Copies the specified content length number of bytes to the output stream from the given inputs stream
/// optionally chunked
/// </summary>
/// <param name="inStreamReader"></param>
/// <param name="outStream"></param>
/// <param name="isChunked"></param>
/// <param name="ContentLength"></param>
/// <returns></returns>
internal
static
async
Task
WriteResponseBody
(
this
CustomBinaryReader
inStreamReader
,
Stream
outStream
,
bool
isChunked
,
long
ContentLength
)
{
if
(!
isChunked
)
{
//http 1.0
if
(
ContentLength
==
-
1
)
ContentLength
=
long
.
MaxValue
;
int
bytesToRead
=
ProxyConstants
.
BUFFER_SIZE
;
if
(
ContentLength
<
ProxyConstants
.
BUFFER_SIZE
)
bytesToRead
=
(
int
)
ContentLength
;
var
buffer
=
new
byte
[
ProxyConstants
.
BUFFER_SIZE
];
var
bytesRead
=
0
;
var
totalBytesRead
=
0
;
while
((
bytesRead
+=
await
inStreamReader
.
BaseStream
.
ReadAsync
(
buffer
,
0
,
bytesToRead
).
ConfigureAwait
(
false
))
>
0
)
{
await
outStream
.
WriteAsync
(
buffer
,
0
,
bytesRead
);
totalBytesRead
+=
bytesRead
;
if
(
totalBytesRead
==
ContentLength
)
break
;
bytesRead
=
0
;
var
remainingBytes
=
(
ContentLength
-
totalBytesRead
);
bytesToRead
=
remainingBytes
>
(
long
)
ProxyConstants
.
BUFFER_SIZE
?
ProxyConstants
.
BUFFER_SIZE
:
(
int
)
remainingBytes
;
}
}
else
await
WriteResponseBodyChunked
(
inStreamReader
,
outStream
);
}
/// <summary>
/// Copies the streams chunked
/// </summary>
/// <param name="inStreamReader"></param>
/// <param name="outStream"></param>
/// <returns></returns>
internal
static
async
Task
WriteResponseBodyChunked
(
this
CustomBinaryReader
inStreamReader
,
Stream
outStream
)
{
while
(
true
)
{
var
chunkHead
=
await
inStreamReader
.
ReadLineAsync
();
var
chunkSize
=
int
.
Parse
(
chunkHead
,
NumberStyles
.
HexNumber
);
if
(
chunkSize
!=
0
)
{
var
buffer
=
await
inStreamReader
.
ReadBytesAsync
(
chunkSize
);
var
chunkHeadBytes
=
Encoding
.
ASCII
.
GetBytes
(
chunkSize
.
ToString
(
"x2"
));
await
outStream
.
WriteAsync
(
chunkHeadBytes
,
0
,
chunkHeadBytes
.
Length
);
await
outStream
.
WriteAsync
(
ProxyConstants
.
NewLineBytes
,
0
,
ProxyConstants
.
NewLineBytes
.
Length
);
await
outStream
.
WriteAsync
(
buffer
,
0
,
chunkSize
);
await
outStream
.
WriteAsync
(
ProxyConstants
.
NewLineBytes
,
0
,
ProxyConstants
.
NewLineBytes
.
Length
);
await
inStreamReader
.
ReadLineAsync
();
}
else
{
await
clientStreamReader
.
ReadLineAsync
().
ConfigureAwait
(
false
);
await
inStreamReader
.
ReadLineAsync
();
await
outStream
.
WriteAsync
(
ProxyConstants
.
ChunkEnd
,
0
,
ProxyConstants
.
ChunkEnd
.
Length
);
break
;
}
}
}
/// <summary>
/// Copies the given input bytes to output stream chunked
/// </summary>
/// <param name="data"></param>
/// <param name="outStream"></param>
/// <returns></returns>
internal
static
async
Task
WriteResponseBodyChunked
(
this
byte
[]
data
,
Stream
outStream
)
{
var
chunkHead
=
Encoding
.
ASCII
.
GetBytes
(
data
.
Length
.
ToString
(
"x2"
));
await
outStream
.
WriteAsync
(
chunkHead
,
0
,
chunkHead
.
Length
);
await
outStream
.
WriteAsync
(
ProxyConstants
.
NewLineBytes
,
0
,
ProxyConstants
.
NewLineBytes
.
Length
);
await
outStream
.
WriteAsync
(
data
,
0
,
data
.
Length
);
await
outStream
.
WriteAsync
(
ProxyConstants
.
NewLineBytes
,
0
,
ProxyConstants
.
NewLineBytes
.
Length
);
await
outStream
.
WriteAsync
(
ProxyConstants
.
ChunkEnd
,
0
,
ProxyConstants
.
ChunkEnd
.
Length
);
}
}
}
\ No newline at end of file
Titanium.Web.Proxy/Extensions/TcpExtensions.cs
View file @
f59fb6a3
...
...
@@ -4,6 +4,11 @@ namespace Titanium.Web.Proxy.Extensions
{
internal
static
class
TcpExtensions
{
/// <summary>
/// verifies if the underlying socket is connected before using a TcpClient connection
/// </summary>
/// <param name="client"></param>
/// <returns></returns>
internal
static
bool
IsConnected
(
this
Socket
client
)
{
// This is how you can determine whether a socket is still connected.
...
...
Titanium.Web.Proxy/Helpers/CertificateManager.cs
View file @
f59fb6a3
...
...
@@ -248,7 +248,7 @@ namespace Titanium.Web.Proxy.Helpers
}
finally
{
semaphoreLock
.
Release
();
}
await
Task
.
Delay
(
1000
*
60
*
3
)
.
ConfigureAwait
(
false
)
;
await
Task
.
Delay
(
1000
*
60
*
3
);
}
}
...
...
Titanium.Web.Proxy/Helpers/CustomBinaryReader.cs
View file @
f59fb6a3
using
System
;
using
System.Collections.Generic
;
using
System.IO
;
using
System.Net.Security
;
using
System.Net.Sockets
;
using
System.Text
;
using
System.Threading.Tasks
;
using
Titanium.Web.Proxy.
Network
;
using
Titanium.Web.Proxy.
Extensions
;
using
Titanium.Web.Proxy.Shared
;
namespace
Titanium.Web.Proxy.Helpers
{
/// <summary>
/// A custom binary reader that would allo us to read string line by line
/// using the specified encoding
...
...
@@ -18,10 +17,11 @@ namespace Titanium.Web.Proxy.Helpers
internal
class
CustomBinaryReader
:
IDisposable
{
private
Stream
stream
;
private
Encoding
encoding
;
internal
CustomBinaryReader
(
Stream
stream
)
{
this
.
stream
=
stream
;
this
.
encoding
=
Encoding
.
UTF8
;
}
internal
Stream
BaseStream
=>
stream
;
...
...
@@ -32,32 +32,34 @@ namespace Titanium.Web.Proxy.Helpers
/// <returns></returns>
internal
async
Task
<
string
>
ReadLineAsync
()
{
var
readBuffer
=
new
StringBuilder
();
try
using
(
var
readBuffer
=
new
MemoryStream
())
{
var
lastChar
=
default
(
char
);
var
buffer
=
new
byte
[
1
];
while
((
await
this
.
stream
.
ReadAsync
(
buffer
,
0
,
1
))
>
0
)
try
{
if
(
lastChar
==
'\r'
&&
buffer
[
0
]
==
'\n'
)
{
return
await
Task
.
FromResult
(
readBuffer
.
Remove
(
readBuffer
.
Length
-
1
,
1
).
ToString
());
}
if
(
buffer
[
0
]
==
'\0'
)
var
lastChar
=
default
(
char
);
var
buffer
=
new
byte
[
1
];
while
((
await
this
.
stream
.
ReadAsync
(
buffer
,
0
,
1
))
>
0
)
{
return
await
Task
.
FromResult
(
readBuffer
.
ToString
());
if
(
lastChar
==
'\r'
&&
buffer
[
0
]
==
'\n'
)
{
var
result
=
readBuffer
.
ToArray
();
return
encoding
.
GetString
(
result
.
SubArray
(
0
,
result
.
Length
-
1
));
}
if
(
buffer
[
0
]
==
'\0'
)
{
return
encoding
.
GetString
(
readBuffer
.
ToArray
());
}
await
readBuffer
.
WriteAsync
(
buffer
,
0
,
1
);
lastChar
=
(
char
)
buffer
[
0
];
}
readBuffer
.
Append
((
char
)
buffer
[
0
]);
lastChar
=
(
char
)
buffer
[
0
];
}
return
await
Task
.
FromResult
(
readBuffer
.
ToString
());
}
catch
(
IOException
)
{
return
await
Task
.
FromResult
(
readBuffer
.
ToString
());
return
encoding
.
GetString
(
readBuffer
.
ToArray
());
}
catch
(
IOException
)
{
return
encoding
.
GetString
(
readBuffer
.
ToArray
());
}
}
}
...
...
@@ -92,7 +94,7 @@ namespace Titanium.Web.Proxy.Helpers
{
while
((
bytesRead
+=
await
this
.
stream
.
ReadAsync
(
buffer
,
0
,
bytesToRead
).
ConfigureAwait
(
false
))
>
0
)
{
await
outStream
.
WriteAsync
(
buffer
,
0
,
bytesRead
)
.
ConfigureAwait
(
false
)
;
await
outStream
.
WriteAsync
(
buffer
,
0
,
bytesRead
);
totalBytesRead
+=
bytesRead
;
if
(
totalBytesRead
==
totalBytesToRead
)
...
...
Titanium.Web.Proxy/Helpers/Tcp.cs
View file @
f59fb6a3
...
...
@@ -72,7 +72,7 @@ namespace Titanium.Web.Proxy.Helpers
var
receiveRelay
=
tunnelStream
.
CopyToAsync
(
string
.
Empty
,
clientStream
);
await
Task
.
WhenAll
(
sendRelay
,
receiveRelay
)
.
ConfigureAwait
(
false
)
;
await
Task
.
WhenAll
(
sendRelay
,
receiveRelay
);
}
catch
{
...
...
Titanium.Web.Proxy/Http/HttpWebClient.cs
View file @
f59fb6a3
...
...
@@ -76,13 +76,13 @@ namespace Titanium.Web.Proxy.Http
&&
responseStatusDescription
.
ToLower
().
Equals
(
"continue"
))
{
this
.
Request
.
Is100Continue
=
true
;
await
ServerConnection
.
StreamReader
.
ReadLineAsync
()
.
ConfigureAwait
(
false
)
;
await
ServerConnection
.
StreamReader
.
ReadLineAsync
();
}
else
if
(
responseStatusCode
.
Equals
(
"417"
)
&&
responseStatusDescription
.
ToLower
().
Equals
(
"expectation failed"
))
{
this
.
Request
.
ExpectationFailed
=
true
;
await
ServerConnection
.
StreamReader
.
ReadLineAsync
()
.
ConfigureAwait
(
false
)
;
await
ServerConnection
.
StreamReader
.
ReadLineAsync
();
}
}
}
...
...
@@ -96,7 +96,7 @@ namespace Titanium.Web.Proxy.Http
if
(
string
.
IsNullOrEmpty
(
httpResult
[
0
]))
{
await
ServerConnection
.
StreamReader
.
ReadLineAsync
()
.
ConfigureAwait
(
false
)
;
await
ServerConnection
.
StreamReader
.
ReadLineAsync
();
}
var
httpVersion
=
httpResult
[
0
].
Trim
().
ToLower
();
...
...
@@ -116,7 +116,7 @@ namespace Titanium.Web.Proxy.Http
{
this
.
Response
.
Is100Continue
=
true
;
this
.
Response
.
ResponseStatusCode
=
null
;
await
ServerConnection
.
StreamReader
.
ReadLineAsync
()
.
ConfigureAwait
(
false
)
;
await
ServerConnection
.
StreamReader
.
ReadLineAsync
();
await
ReceiveResponse
();
return
;
}
...
...
@@ -125,12 +125,12 @@ namespace Titanium.Web.Proxy.Http
{
this
.
Response
.
ExpectationFailed
=
true
;
this
.
Response
.
ResponseStatusCode
=
null
;
await
ServerConnection
.
StreamReader
.
ReadLineAsync
()
.
ConfigureAwait
(
false
)
;
await
ServerConnection
.
StreamReader
.
ReadLineAsync
();
await
ReceiveResponse
();
return
;
}
List
<
string
>
responseLines
=
await
ServerConnection
.
StreamReader
.
ReadAllLinesAsync
()
.
ConfigureAwait
(
false
)
;
List
<
string
>
responseLines
=
await
ServerConnection
.
StreamReader
.
ReadAllLinesAsync
();
for
(
int
index
=
0
;
index
<
responseLines
.
Count
;
++
index
)
{
...
...
Titanium.Web.Proxy/Network/TcpConnectionManager.cs
View file @
f59fb6a3
...
...
@@ -79,7 +79,7 @@ namespace Titanium.Web.Proxy.Network
}
if
(
cached
==
null
)
cached
=
await
CreateClient
(
hostname
,
port
,
isHttps
,
version
)
.
ConfigureAwait
(
false
)
;
cached
=
await
CreateClient
(
hostname
,
port
,
isHttps
,
version
);
if
(
cachedConnections
==
null
||
cachedConnections
.
Count
()
<=
2
)
{
...
...
@@ -111,22 +111,22 @@ namespace Titanium.Web.Proxy.Network
using
(
var
writer
=
new
StreamWriter
(
stream
,
Encoding
.
ASCII
,
ProxyConstants
.
BUFFER_SIZE
,
true
))
{
await
writer
.
WriteLineAsync
(
string
.
Format
(
"CONNECT {0}:{1} {2}"
,
hostname
,
port
,
version
))
.
ConfigureAwait
(
false
)
;
await
writer
.
WriteLineAsync
(
string
.
Format
(
"Host: {0}:{1}"
,
hostname
,
port
))
.
ConfigureAwait
(
false
)
;
await
writer
.
WriteLineAsync
(
"Connection: Keep-Alive"
)
.
ConfigureAwait
(
false
)
;
await
writer
.
WriteLineAsync
()
.
ConfigureAwait
(
false
)
;
await
writer
.
FlushAsync
()
.
ConfigureAwait
(
false
)
;
await
writer
.
WriteLineAsync
(
string
.
Format
(
"CONNECT {0}:{1} {2}"
,
hostname
,
port
,
version
));
await
writer
.
WriteLineAsync
(
string
.
Format
(
"Host: {0}:{1}"
,
hostname
,
port
));
await
writer
.
WriteLineAsync
(
"Connection: Keep-Alive"
);
await
writer
.
WriteLineAsync
();
await
writer
.
FlushAsync
();
writer
.
Close
();
}
using
(
var
reader
=
new
CustomBinaryReader
(
stream
))
{
var
result
=
await
reader
.
ReadLineAsync
()
.
ConfigureAwait
(
false
)
;
var
result
=
await
reader
.
ReadLineAsync
();
if
(!
result
.
ToLower
().
Contains
(
"200 connection established"
))
throw
new
Exception
(
"Upstream proxy failed to create a secure tunnel"
);
await
reader
.
ReadAllLinesAsync
()
.
ConfigureAwait
(
false
)
;
await
reader
.
ReadAllLinesAsync
();
}
}
else
...
...
@@ -139,7 +139,7 @@ namespace Titanium.Web.Proxy.Network
{
sslStream
=
new
SslStream
(
stream
,
true
,
new
RemoteCertificateValidationCallback
(
ProxyServer
.
ValidateServerCertificate
),
new
LocalCertificateSelectionCallback
(
ProxyServer
.
SelectClientCertificate
));
await
sslStream
.
AuthenticateAsClientAsync
(
hostname
,
null
,
ProxyConstants
.
SupportedSslProtocols
,
false
)
.
ConfigureAwait
(
false
)
;
await
sslStream
.
AuthenticateAsClientAsync
(
hostname
,
null
,
ProxyConstants
.
SupportedSslProtocols
,
false
);
stream
=
(
Stream
)
sslStream
;
}
catch
...
...
@@ -224,7 +224,7 @@ namespace Titanium.Web.Proxy.Network
}
finally
{
connectionAccessLock
.
Release
();
}
await
Task
.
Delay
(
1000
*
60
*
3
).
ConfigureAwait
(
false
);
await
Task
.
Delay
(
1000
*
60
);
}
}
...
...
Titanium.Web.Proxy/RequestHandler.cs
View file @
f59fb6a3
This diff is collapsed.
Click to expand it.
Titanium.Web.Proxy/ResponseHandler.cs
View file @
f59fb6a3
using
System
;
using
System.Collections.Generic
;
using
System.Globalization
;
using
System.IO
;
using
System.Linq
;
using
System.Net.Sockets
;
using
System.Text
;
using
Titanium.Web.Proxy.EventArguments
;
using
Titanium.Web.Proxy.Helpers
;
using
Titanium.Web.Proxy.Models
;
using
Titanium.Web.Proxy.Compression
;
using
Titanium.Web.Proxy.Shared
;
using
System.Threading.Tasks
;
using
Titanium.Web.Proxy.Extensions
;
namespace
Titanium.Web.Proxy
{
...
...
@@ -19,7 +16,7 @@ namespace Titanium.Web.Proxy
//Called asynchronously when a request was successfully and we received the response
public
static
async
Task
HandleHttpSessionResponse
(
SessionEventArgs
args
)
{
await
args
.
WebSession
.
ReceiveResponse
()
.
ConfigureAwait
(
false
)
;
await
args
.
WebSession
.
ReceiveResponse
();
try
{
...
...
@@ -37,7 +34,7 @@ namespace Titanium.Web.Proxy
handlerTasks
[
i
]
=
((
Func
<
object
,
SessionEventArgs
,
Task
>)
invocationList
[
i
])(
null
,
args
);
}
await
Task
.
WhenAll
(
handlerTasks
)
.
ConfigureAwait
(
false
)
;
await
Task
.
WhenAll
(
handlerTasks
);
}
args
.
WebSession
.
Response
.
ResponseLocked
=
true
;
...
...
@@ -65,7 +62,7 @@ namespace Titanium.Web.Proxy
if
(
contentEncoding
!=
null
)
{
args
.
WebSession
.
Response
.
ResponseBody
=
await
GetCompressedResponseBody
(
contentEncoding
,
args
.
WebSession
.
Response
.
ResponseBody
)
.
ConfigureAwait
(
false
)
;
args
.
WebSession
.
Response
.
ResponseBody
=
await
GetCompressedResponseBody
(
contentEncoding
,
args
.
WebSession
.
Response
.
ResponseBody
);
if
(
isChunked
==
false
)
args
.
WebSession
.
Response
.
ContentLength
=
args
.
WebSession
.
Response
.
ResponseBody
.
Length
;
...
...
@@ -73,8 +70,8 @@ namespace Titanium.Web.Proxy
args
.
WebSession
.
Response
.
ContentLength
=
-
1
;
}
await
WriteResponseHeaders
(
args
.
ProxyClient
.
ClientStreamWriter
,
args
.
WebSession
.
Response
.
ResponseHeaders
)
.
ConfigureAwait
(
false
)
;
await
WriteResponseBody
(
args
.
ProxyClient
.
ClientStream
,
args
.
WebSession
.
Response
.
ResponseBody
,
isChunked
).
ConfigureAwait
(
false
);
await
WriteResponseHeaders
(
args
.
ProxyClient
.
ClientStreamWriter
,
args
.
WebSession
.
Response
.
ResponseHeaders
);
await
args
.
ProxyClient
.
ClientStream
.
WriteResponseBody
(
args
.
WebSession
.
Response
.
ResponseBody
,
isChunked
);
}
else
{
...
...
@@ -82,7 +79,7 @@ namespace Titanium.Web.Proxy
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
.
ProxyClient
.
ClientStream
,
args
.
WebSession
.
Response
.
IsChunked
,
args
.
WebSession
.
Response
.
ContentLength
).
ConfigureAwait
(
false
);
await
args
.
WebSession
.
ServerConnection
.
StreamReader
.
WriteResponseBody
(
args
.
ProxyClient
.
ClientStream
,
args
.
WebSession
.
Response
.
IsChunked
,
args
.
WebSession
.
Response
.
ContentLength
);
}
await
args
.
ProxyClient
.
ClientStream
.
FlushAsync
();
...
...
@@ -102,7 +99,7 @@ namespace Titanium.Web.Proxy
{
var
compressionFactory
=
new
CompressionFactory
();
var
compressor
=
compressionFactory
.
Create
(
encodingType
);
return
await
compressor
.
Compress
(
responseBodyStream
)
.
ConfigureAwait
(
false
)
;
return
await
compressor
.
Compress
(
responseBodyStream
);
}
...
...
@@ -145,95 +142,7 @@ namespace Titanium.Web.Proxy
headers
.
RemoveAll
(
x
=>
x
.
Name
.
ToLower
()
==
"proxy-connection"
);
}
private
static
async
Task
WriteResponseBody
(
Stream
clientStream
,
byte
[]
data
,
bool
isChunked
)
{
if
(!
isChunked
)
{
await
clientStream
.
WriteAsync
(
data
,
0
,
data
.
Length
).
ConfigureAwait
(
false
);
}
else
await
WriteResponseBodyChunked
(
data
,
clientStream
).
ConfigureAwait
(
false
);
}
private
static
async
Task
WriteResponseBody
(
CustomBinaryReader
inStreamReader
,
Stream
outStream
,
bool
isChunked
,
long
ContentLength
)
{
if
(!
isChunked
)
{
//http 1.0
if
(
ContentLength
==
-
1
)
ContentLength
=
long
.
MaxValue
;
int
bytesToRead
=
ProxyConstants
.
BUFFER_SIZE
;
if
(
ContentLength
<
ProxyConstants
.
BUFFER_SIZE
)
bytesToRead
=
(
int
)
ContentLength
;
var
buffer
=
new
byte
[
ProxyConstants
.
BUFFER_SIZE
];
var
bytesRead
=
0
;
var
totalBytesRead
=
0
;
while
((
bytesRead
+=
await
inStreamReader
.
BaseStream
.
ReadAsync
(
buffer
,
0
,
bytesToRead
).
ConfigureAwait
(
false
))
>
0
)
{
await
outStream
.
WriteAsync
(
buffer
,
0
,
bytesRead
).
ConfigureAwait
(
false
);
totalBytesRead
+=
bytesRead
;
if
(
totalBytesRead
==
ContentLength
)
break
;
bytesRead
=
0
;
var
remainingBytes
=
(
ContentLength
-
totalBytesRead
);
bytesToRead
=
remainingBytes
>
(
long
)
ProxyConstants
.
BUFFER_SIZE
?
ProxyConstants
.
BUFFER_SIZE
:
(
int
)
remainingBytes
;
}
}
else
await
WriteResponseBodyChunked
(
inStreamReader
,
outStream
).
ConfigureAwait
(
false
);
}
//Send chunked response
private
static
async
Task
WriteResponseBodyChunked
(
CustomBinaryReader
inStreamReader
,
Stream
outStream
)
{
while
(
true
)
{
var
chunkHead
=
await
inStreamReader
.
ReadLineAsync
().
ConfigureAwait
(
false
);
var
chunkSize
=
int
.
Parse
(
chunkHead
,
NumberStyles
.
HexNumber
);
if
(
chunkSize
!=
0
)
{
var
buffer
=
await
inStreamReader
.
ReadBytesAsync
(
chunkSize
).
ConfigureAwait
(
false
);
var
chunkHeadBytes
=
Encoding
.
ASCII
.
GetBytes
(
chunkSize
.
ToString
(
"x2"
));
await
outStream
.
WriteAsync
(
chunkHeadBytes
,
0
,
chunkHeadBytes
.
Length
).
ConfigureAwait
(
false
);
await
outStream
.
WriteAsync
(
ProxyConstants
.
NewLineBytes
,
0
,
ProxyConstants
.
NewLineBytes
.
Length
).
ConfigureAwait
(
false
);
await
outStream
.
WriteAsync
(
buffer
,
0
,
chunkSize
).
ConfigureAwait
(
false
);
await
outStream
.
WriteAsync
(
ProxyConstants
.
NewLineBytes
,
0
,
ProxyConstants
.
NewLineBytes
.
Length
).
ConfigureAwait
(
false
);
await
inStreamReader
.
ReadLineAsync
().
ConfigureAwait
(
false
);
}
else
{
await
inStreamReader
.
ReadLineAsync
().
ConfigureAwait
(
false
);
await
outStream
.
WriteAsync
(
ProxyConstants
.
ChunkEnd
,
0
,
ProxyConstants
.
ChunkEnd
.
Length
).
ConfigureAwait
(
false
);
break
;
}
}
}
private
static
async
Task
WriteResponseBodyChunked
(
byte
[]
data
,
Stream
outStream
)
{
var
chunkHead
=
Encoding
.
ASCII
.
GetBytes
(
data
.
Length
.
ToString
(
"x2"
));
await
outStream
.
WriteAsync
(
chunkHead
,
0
,
chunkHead
.
Length
).
ConfigureAwait
(
false
);
await
outStream
.
WriteAsync
(
ProxyConstants
.
NewLineBytes
,
0
,
ProxyConstants
.
NewLineBytes
.
Length
).
ConfigureAwait
(
false
);
await
outStream
.
WriteAsync
(
data
,
0
,
data
.
Length
).
ConfigureAwait
(
false
);
await
outStream
.
WriteAsync
(
ProxyConstants
.
NewLineBytes
,
0
,
ProxyConstants
.
NewLineBytes
.
Length
).
ConfigureAwait
(
false
);
await
outStream
.
WriteAsync
(
ProxyConstants
.
ChunkEnd
,
0
,
ProxyConstants
.
ChunkEnd
.
Length
).
ConfigureAwait
(
false
);
}
private
static
void
Dispose
(
TcpClient
client
,
IDisposable
clientStream
,
IDisposable
clientStreamReader
,
IDisposable
clientStreamWriter
,
IDisposable
args
)
...
...
Titanium.Web.Proxy/Titanium.Web.Proxy.csproj
View file @
f59fb6a3
...
...
@@ -62,6 +62,7 @@
<Compile
Include=
"Decompression\ZlibDecompression.cs"
/>
<Compile
Include=
"EventArguments\CertificateSelectionEventArgs.cs"
/>
<Compile
Include=
"EventArguments\CertificateValidationEventArgs.cs"
/>
<Compile
Include=
"Extensions\ByteArrayExtensions.cs"
/>
<Compile
Include=
"Network\ProxyClient.cs"
/>
<Compile
Include=
"Exceptions\BodyNotFoundException.cs"
/>
<Compile
Include=
"Extensions\HttpWebResponseExtensions.cs"
/>
...
...
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