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
fe4d5ee9
Commit
fe4d5ee9
authored
Jul 08, 2015
by
titanium007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Expose only properties that are safer to user
parent
214be692
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
737 additions
and
711 deletions
+737
-711
ProxyTestController.cs
Titanium.Web.Proxy.Test/ProxyTestController.cs
+10
-10
SessionEventArgs.cs
Titanium.Web.Proxy/Models/SessionEventArgs.cs
+90
-64
RequestHandler.cs
Titanium.Web.Proxy/RequestHandler.cs
+633
-633
ResponseHandler.cs
Titanium.Web.Proxy/ResponseHandler.cs
+4
-4
No files found.
Titanium.Web.Proxy.Test/ProxyTestController.cs
View file @
fe4d5ee9
...
...
@@ -76,11 +76,11 @@ namespace Titanium.Web.Proxy.Test
if
(
index
>=
0
)
{
string
URL
=
e
.
Decode
();
string
URL
=
e
.
GetRequestHtmlBody
();
if
(
_lastURL
!=
URL
)
{
OnChanged
(
new
VisitedEventArgs
()
{
hostname
=
e
.
Hostname
,
URL
=
URL
,
remoteIP
=
e
.
ipAddress
,
remotePort
=
e
.
Port
});
OnChanged
(
new
VisitedEventArgs
()
{
hostname
=
e
.
RequestHostname
,
URL
=
URL
,
remoteIP
=
e
.
ClientIpAddress
,
remotePort
=
e
.
Client
Port
});
}
...
...
@@ -106,7 +106,7 @@ namespace Titanium.Web.Proxy.Test
string
c
=
e
.
ServerResponse
.
GetResponseHeader
(
"X-Requested-With"
);
if
(
e
.
ServerResponse
.
GetResponseHeader
(
"X-Requested-With"
)
==
""
)
{
e
.
GetResponse
Body
();
string
responseHtmlBody
=
e
.
GetResponseHtml
Body
();
string
functioname
=
"fr"
+
RandomString
(
10
);
string
VisitedURL
=
RandomString
(
5
);
...
...
@@ -116,10 +116,10 @@ namespace Titanium.Web.Proxy.Test
string
RandomLastRequest
=
RandomString
(
10
);
string
LocalRequest
;
if
(
e
.
IsS
ecure
)
LocalRequest
=
"https://"
+
e
.
Hostname
+
"/"
+
RandomURLEnding
;
if
(
e
.
IsS
SLRequest
)
LocalRequest
=
"https://"
+
e
.
Request
Hostname
+
"/"
+
RandomURLEnding
;
else
LocalRequest
=
"http://"
+
e
.
Hostname
+
"/"
+
RandomURLEnding
;
LocalRequest
=
"http://"
+
e
.
Request
Hostname
+
"/"
+
RandomURLEnding
;
string
script
=
"var "
+
RandomLastRequest
+
" = null;"
+
"if(window.top==self) { "
+
"\n"
+
...
...
@@ -135,13 +135,13 @@ namespace Titanium.Web.Proxy.Test
RequestVariable
+
".open(\"POST\",\""
+
LocalRequest
+
"\", true); "
+
"\n"
+
RequestVariable
+
".send("
+
VisitedURL
+
");} "
+
RandomLastRequest
+
" = "
+
VisitedURL
+
"}"
;
string
response
=
e
.
ResponseString
;
Regex
RE
=
new
Regex
(
"</body>"
,
RegexOptions
.
RightToLeft
|
RegexOptions
.
IgnoreCase
|
RegexOptions
.
Multiline
);
string
replaced
=
RE
.
Replace
(
response
,
"<script type =\"text/javascript\">"
+
script
+
"</script></body>"
,
1
);
if
(
replaced
.
Length
!=
response
.
Length
)
string
modifiedResponseHtmlBody
=
RE
.
Replace
(
responseHtmlBody
,
"<script type =\"text/javascript\">"
+
script
+
"</script></body>"
,
1
);
if
(
modifiedResponseHtmlBody
.
Length
!=
responseHtmlBody
.
Length
)
{
e
.
ResponseString
=
replaced
;
e
.
SetRequestHtmlBody
(
modifiedResponseHtmlBody
)
;
_URLList
.
Add
(
RandomURLEnding
);
}
...
...
Titanium.Web.Proxy/Models/SessionEventArgs.cs
View file @
fe4d5ee9
...
...
@@ -9,84 +9,70 @@ namespace Titanium.Web.Proxy.Models
{
public
class
SessionEventArgs
:
EventArgs
{
public
string
RequestURL
{
get
;
set
;
}
public
string
Hostname
{
get
;
set
;
}
public
CustomBinaryReader
ClientStreamReader
{
get
;
set
;
}
public
string
ResponseString
{
get
;
set
;
}
public
int
RequestLength
{
get
;
set
;
}
public
Stream
ClientStream
{
get
;
set
;
}
public
Version
HttpVersion
{
get
;
set
;
}
public
bool
IsAlive
{
get
;
set
;
}
public
bool
Cancel
{
get
;
set
;
}
public
bool
IsSecure
{
get
;
set
;
}
public
int
Port
{
get
;
set
;
}
private
int
BUFFER_SIZE
;
public
HttpWebResponse
ServerResponse
{
get
;
set
;
}
public
Stream
ServerResponseStream
{
get
;
set
;
}
public
string
RequestHostname
{
get
;
set
;
}
public
bool
IsSSLRequest
{
get
;
set
;
}
public
int
ClientPort
{
get
;
set
;
}
public
IPAddress
ClientIpAddress
{
get
;
set
;
}
public
HttpWebRequest
ProxyRequest
{
get
;
set
;
}
public
Encoding
Encoding
{
get
;
set
;
}
public
bool
WasModified
{
get
;
set
;
}
public
System
.
Threading
.
ManualResetEvent
FinishedRequestEvent
{
get
;
set
;
}
public
string
UpgradeProtocol
{
get
;
set
;
}
public
HttpWebResponse
ServerResponse
{
get
;
set
;
}
internal
int
BUFFER_SIZE
;
internal
int
RequestLength
{
get
;
set
;
}
internal
Version
RequestHttpVersion
{
get
;
set
;
}
internal
bool
RequestIsAlive
{
get
;
set
;
}
internal
bool
CancelRequest
{
get
;
set
;
}
internal
CustomBinaryReader
ClientStreamReader
{
get
;
set
;
}
internal
Stream
ClientStream
{
get
;
set
;
}
internal
Stream
ServerResponseStream
{
get
;
set
;
}
internal
Encoding
Encoding
{
get
;
set
;
}
internal
bool
WasModified
{
get
;
set
;
}
internal
System
.
Threading
.
ManualResetEvent
FinishedRequestEvent
{
get
;
set
;
}
internal
string
UpgradeProtocol
{
get
;
set
;
}
internal
string
RequestHtmlBody
{
get
;
set
;
}
internal
string
ResponseHtmlBody
{
get
;
set
;
}
public
SessionEventArgs
(
int
BufferSize
)
{
BUFFER_SIZE
=
BufferSize
;
}
public
string
Decode
()
public
string
GetRequestHtmlBody
()
{
if
(
RequestHtmlBody
==
null
)
{
int
bytesRead
;
int
totalBytesRead
=
0
;
MemoryStream
mw
=
new
MemoryStream
();
var
buffer
=
ClientStreamReader
.
ReadBytes
(
RequestLength
);
while
(
totalBytesRead
<
RequestLength
&&
(
bytesRead
=
buffer
.
Length
)
>
0
)
{
totalBytesRead
+=
bytesRead
;
mw
.
Write
(
buffer
,
0
,
bytesRead
);
int
bytesRead
;
int
totalBytesRead
=
0
;
MemoryStream
mw
=
new
MemoryStream
();
var
buffer
=
ClientStreamReader
.
ReadBytes
(
RequestLength
);
while
(
totalBytesRead
<
RequestLength
&&
(
bytesRead
=
buffer
.
Length
)
>
0
)
{
totalBytesRead
+=
bytesRead
;
mw
.
Write
(
buffer
,
0
,
bytesRead
);
}
mw
.
Close
();
RequestHtmlBody
=
Encoding
.
Default
.
GetString
(
mw
.
ToArray
());
}
mw
.
Close
();
return
Encoding
.
Default
.
GetString
(
mw
.
ToArray
());
return
RequestHtmlBody
;
}
public
void
Ok
(
string
Html
)
public
void
SetRequestHtmlBody
(
string
Body
)
{
if
(
Html
==
null
)
Html
=
string
.
Empty
;
var
result
=
Encoding
.
Default
.
GetBytes
(
Html
);
StreamWriter
connectStreamWriter
=
new
StreamWriter
(
ClientStream
);
var
s
=
String
.
Format
(
"HTTP/{0}.{1} {2} {3}"
,
HttpVersion
.
Major
,
HttpVersion
.
Minor
,
200
,
"Ok"
);
connectStreamWriter
.
WriteLine
(
s
);
connectStreamWriter
.
WriteLine
(
String
.
Format
(
"Timestamp: {0}"
,
DateTime
.
Now
.
ToString
()));
connectStreamWriter
.
WriteLine
(
"content-length: "
+
result
.
Length
);
connectStreamWriter
.
WriteLine
(
"Cache-Control: no-cache, no-store, must-revalidate"
);
connectStreamWriter
.
WriteLine
(
"Pragma: no-cache"
);
connectStreamWriter
.
WriteLine
(
"Expires: 0"
);
if
(
IsAlive
)
{
connectStreamWriter
.
WriteLine
(
"Connection: Keep-Alive"
);
}
else
connectStreamWriter
.
WriteLine
(
"Connection: close"
);
connectStreamWriter
.
WriteLine
();
connectStreamWriter
.
Flush
();
ClientStream
.
Write
(
result
,
0
,
result
.
Length
);
Cancel
=
true
;
this
.
RequestHtmlBody
=
Body
;
}
public
void
GetResponse
Body
()
public
string
GetResponseHtml
Body
()
{
if
(
Response
String
==
null
)
if
(
Response
HtmlBody
==
null
)
{
Encoding
=
Encoding
.
GetEncoding
(
ServerResponse
.
CharacterSet
);
...
...
@@ -110,9 +96,16 @@ namespace Titanium.Web.Proxy.Models
ResponseData
=
DecodeData
(
ServerResponseStream
,
Encoding
);
break
;
}
Response
String
=
ResponseData
;
Response
HtmlBody
=
ResponseData
;
WasModified
=
true
;
}
return
ResponseHtmlBody
;
}
public
void
SetResponseHtmlBody
(
string
Body
)
{
this
.
ResponseHtmlBody
=
Body
;
}
//stream reader not recomended for images
private
string
DecodeData
(
Stream
ResponseStream
,
Encoding
e
)
...
...
@@ -122,12 +115,45 @@ namespace Titanium.Web.Proxy.Models
}
public
void
Ok
(
string
Html
)
{
if
(
Html
==
null
)
Html
=
string
.
Empty
;
var
result
=
Encoding
.
Default
.
GetBytes
(
Html
);
StreamWriter
connectStreamWriter
=
new
StreamWriter
(
ClientStream
);
var
s
=
String
.
Format
(
"HTTP/{0}.{1} {2} {3}"
,
RequestHttpVersion
.
Major
,
RequestHttpVersion
.
Minor
,
200
,
"Ok"
);
connectStreamWriter
.
WriteLine
(
s
);
connectStreamWriter
.
WriteLine
(
String
.
Format
(
"Timestamp: {0}"
,
DateTime
.
Now
.
ToString
()));
connectStreamWriter
.
WriteLine
(
"content-length: "
+
result
.
Length
);
connectStreamWriter
.
WriteLine
(
"Cache-Control: no-cache, no-store, must-revalidate"
);
connectStreamWriter
.
WriteLine
(
"Pragma: no-cache"
);
connectStreamWriter
.
WriteLine
(
"Expires: 0"
);
if
(
RequestIsAlive
)
{
connectStreamWriter
.
WriteLine
(
"Connection: Keep-Alive"
);
}
else
connectStreamWriter
.
WriteLine
(
"Connection: close"
);
connectStreamWriter
.
WriteLine
();
connectStreamWriter
.
Flush
();
ClientStream
.
Write
(
result
,
0
,
result
.
Length
);
CancelRequest
=
true
;
}
public
IPAddress
ipAddress
{
get
;
set
;
}
}
}
\ No newline at end of file
Titanium.Web.Proxy/RequestHandler.cs
View file @
fe4d5ee9
using
System
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Text
;
using
System.Threading
;
using
System.IO
;
using
System.Net
;
using
System.Net.Security
;
using
System.Security.Authentication
;
using
System.Net.Sockets
;
using
System.Diagnostics
;
using
System.Security.Cryptography.X509Certificates
;
using
System.Reflection
;
using
Titanium.Web.Proxy.Helpers
;
using
Titanium.Web.Proxy.Models
;
namespace
Titanium.Web.Proxy
{
partial
class
ProxyServer
{
private
static
void
HandleClientRequest
(
TcpClient
Client
)
{
string
connectionGroup
=
null
;
Stream
clientStream
=
null
;
CustomBinaryReader
clientStreamReader
=
null
;
StreamWriter
connectStreamWriter
=
null
;
string
tunnelHostName
=
null
;
int
tunnelPort
=
0
;
try
{
connectionGroup
=
Dns
.
GetHostEntry
(((
IPEndPoint
)
Client
.
Client
.
RemoteEndPoint
).
Address
).
HostName
;
clientStream
=
Client
.
GetStream
();
clientStreamReader
=
new
CustomBinaryReader
(
clientStream
,
Encoding
.
ASCII
);
string
securehost
=
null
;
List
<
string
>
requestLines
=
new
List
<
string
>();
string
tmpLine
;
while
(!
String
.
IsNullOrEmpty
(
tmpLine
=
clientStreamReader
.
ReadLine
()))
{
requestLines
.
Add
(
tmpLine
);
}
//read the first line HTTP command
String
httpCmd
=
requestLines
.
Count
>
0
?
requestLines
[
0
]
:
null
;
if
(
String
.
IsNullOrEmpty
(
httpCmd
))
{
throw
new
EndOfStreamException
();
}
//break up the line into three components
String
[]
splitBuffer
=
httpCmd
.
Split
(
spaceSplit
,
3
);
String
method
=
splitBuffer
[
0
];
String
remoteUri
=
splitBuffer
[
1
];
Version
version
;
string
RequestVersion
;
if
(
splitBuffer
[
2
]
==
"HTTP/1.1"
)
{
version
=
new
Version
(
1
,
1
);
RequestVersion
=
"HTTP/1.1"
;
}
else
{
version
=
new
Version
(
1
,
0
);
RequestVersion
=
"HTTP/1.0"
;
}
if
(
splitBuffer
[
0
].
ToUpper
()
==
"CONNECT"
)
{
//Browser wants to create a secure tunnel
//instead = we are going to perform a man in the middle "attack"
//the user's browser should warn them of the certification errors,
//so we need to install our root certficate in users machine as Certificate Authority.
remoteUri
=
"https://"
+
splitBuffer
[
1
];
tunnelHostName
=
splitBuffer
[
1
].
Split
(
':'
)[
0
];
int
.
TryParse
(
splitBuffer
[
1
].
Split
(
':'
)[
1
],
out
tunnelPort
);
if
(
tunnelPort
==
0
)
tunnelPort
=
80
;
var
isSecure
=
true
;
for
(
int
i
=
1
;
i
<
requestLines
.
Count
;
i
++)
{
var
rawHeader
=
requestLines
[
i
];
String
[]
header
=
rawHeader
.
ToLower
().
Trim
().
Split
(
colonSpaceSplit
,
2
,
StringSplitOptions
.
None
);
if
((
header
[
0
]
==
"host"
))
{
var
hostDetails
=
header
[
1
].
ToLower
().
Trim
().
Split
(
':'
);
if
(
hostDetails
.
Length
>
1
)
{
isSecure
=
false
;
}
}
}
requestLines
.
Clear
();
connectStreamWriter
=
new
StreamWriter
(
clientStream
);
connectStreamWriter
.
WriteLine
(
RequestVersion
+
" 200 Connection established"
);
connectStreamWriter
.
WriteLine
(
String
.
Format
(
"Timestamp: {0}"
,
DateTime
.
Now
.
ToString
()));
connectStreamWriter
.
WriteLine
(
String
.
Format
(
"connection:close"
));
connectStreamWriter
.
WriteLine
();
connectStreamWriter
.
Flush
();
if
(
tunnelPort
!=
443
)
{
TcpHelper
.
SendRaw
(
tunnelHostName
,
tunnelPort
,
clientStreamReader
.
BaseStream
);
if
(
clientStream
!=
null
)
clientStream
.
Close
();
return
;
}
using
System
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Text
;
using
System.Threading
;
using
System.IO
;
using
System.Net
;
using
System.Net.Security
;
using
System.Security.Authentication
;
using
System.Net.Sockets
;
using
System.Diagnostics
;
using
System.Security.Cryptography.X509Certificates
;
using
System.Reflection
;
using
Titanium.Web.Proxy.Helpers
;
using
Titanium.Web.Proxy.Models
;
namespace
Titanium.Web.Proxy
{
partial
class
ProxyServer
{
private
static
void
HandleClientRequest
(
TcpClient
Client
)
{
string
connectionGroup
=
null
;
Stream
clientStream
=
null
;
CustomBinaryReader
clientStreamReader
=
null
;
StreamWriter
connectStreamWriter
=
null
;
string
tunnelHostName
=
null
;
int
tunnelPort
=
0
;
try
{
connectionGroup
=
Dns
.
GetHostEntry
(((
IPEndPoint
)
Client
.
Client
.
RemoteEndPoint
).
Address
).
HostName
;
clientStream
=
Client
.
GetStream
();
clientStreamReader
=
new
CustomBinaryReader
(
clientStream
,
Encoding
.
ASCII
);
string
securehost
=
null
;
List
<
string
>
requestLines
=
new
List
<
string
>();
string
tmpLine
;
while
(!
String
.
IsNullOrEmpty
(
tmpLine
=
clientStreamReader
.
ReadLine
()))
{
requestLines
.
Add
(
tmpLine
);
}
//read the first line HTTP command
String
httpCmd
=
requestLines
.
Count
>
0
?
requestLines
[
0
]
:
null
;
if
(
String
.
IsNullOrEmpty
(
httpCmd
))
{
throw
new
EndOfStreamException
();
}
//break up the line into three components
String
[]
splitBuffer
=
httpCmd
.
Split
(
spaceSplit
,
3
);
String
method
=
splitBuffer
[
0
];
String
remoteUri
=
splitBuffer
[
1
];
Version
version
;
string
RequestVersion
;
if
(
splitBuffer
[
2
]
==
"HTTP/1.1"
)
{
version
=
new
Version
(
1
,
1
);
RequestVersion
=
"HTTP/1.1"
;
}
else
{
version
=
new
Version
(
1
,
0
);
RequestVersion
=
"HTTP/1.0"
;
}
if
(
splitBuffer
[
0
].
ToUpper
()
==
"CONNECT"
)
{
//Browser wants to create a secure tunnel
//instead = we are going to perform a man in the middle "attack"
//the user's browser should warn them of the certification errors,
//so we need to install our root certficate in users machine as Certificate Authority.
remoteUri
=
"https://"
+
splitBuffer
[
1
];
tunnelHostName
=
splitBuffer
[
1
].
Split
(
':'
)[
0
];
int
.
TryParse
(
splitBuffer
[
1
].
Split
(
':'
)[
1
],
out
tunnelPort
);
if
(
tunnelPort
==
0
)
tunnelPort
=
80
;
var
isSecure
=
true
;
for
(
int
i
=
1
;
i
<
requestLines
.
Count
;
i
++)
{
var
rawHeader
=
requestLines
[
i
];
String
[]
header
=
rawHeader
.
ToLower
().
Trim
().
Split
(
colonSpaceSplit
,
2
,
StringSplitOptions
.
None
);
if
((
header
[
0
]
==
"host"
))
{
var
hostDetails
=
header
[
1
].
ToLower
().
Trim
().
Split
(
':'
);
if
(
hostDetails
.
Length
>
1
)
{
isSecure
=
false
;
}
}
}
requestLines
.
Clear
();
connectStreamWriter
=
new
StreamWriter
(
clientStream
);
connectStreamWriter
.
WriteLine
(
RequestVersion
+
" 200 Connection established"
);
connectStreamWriter
.
WriteLine
(
String
.
Format
(
"Timestamp: {0}"
,
DateTime
.
Now
.
ToString
()));
connectStreamWriter
.
WriteLine
(
String
.
Format
(
"connection:close"
));
connectStreamWriter
.
WriteLine
();
connectStreamWriter
.
Flush
();
if
(
tunnelPort
!=
443
)
{
TcpHelper
.
SendRaw
(
tunnelHostName
,
tunnelPort
,
clientStreamReader
.
BaseStream
);
if
(
clientStream
!=
null
)
clientStream
.
Close
();
return
;
}
Monitor
.
Enter
(
certificateAccessLock
);
var
_certificate
=
ProxyServer
.
CertManager
.
CreateCertificate
(
tunnelHostName
);
//CertificateHelper.GetCertificate(RootCertificateName, tunnelHostName);
Monitor
.
Exit
(
certificateAccessLock
);
SslStream
sslStream
=
null
;
if
(!
pinnedCertificateClients
.
Contains
(
tunnelHostName
)
&&
isSecure
)
{
sslStream
=
new
SslStream
(
clientStream
,
true
);
try
{
sslStream
.
AuthenticateAsServer
(
_certificate
,
false
,
SslProtocols
.
Tls
|
SslProtocols
.
Ssl3
|
SslProtocols
.
Ssl2
,
false
);
}
catch
(
AuthenticationException
ex
)
{
if
(
pinnedCertificateClients
.
Contains
(
tunnelHostName
)
==
false
)
{
pinnedCertificateClients
.
Add
(
tunnelHostName
);
}
throw
ex
;
}
}
else
{
TcpHelper
.
SendRaw
(
tunnelHostName
,
tunnelPort
,
clientStreamReader
.
BaseStream
);
if
(
clientStream
!=
null
)
clientStream
.
Close
();
return
;
}
clientStreamReader
=
new
CustomBinaryReader
(
sslStream
,
Encoding
.
ASCII
);
//HTTPS server created - we can now decrypt the client's traffic
clientStream
=
sslStream
;
while
(!
String
.
IsNullOrEmpty
(
tmpLine
=
clientStreamReader
.
ReadLine
()))
{
requestLines
.
Add
(
tmpLine
);
}
//read the new http command.
httpCmd
=
requestLines
.
Count
>
0
?
requestLines
[
0
]
:
null
;
if
(
String
.
IsNullOrEmpty
(
httpCmd
))
{
throw
new
EndOfStreamException
();
}
securehost
=
remoteUri
;
}
int
count
=
0
;
SessionEventArgs
args
=
new
SessionEventArgs
(
BUFFER_SIZE
);
while
(!
String
.
IsNullOrEmpty
(
httpCmd
))
{
count
++;
MemoryStream
mw
=
null
;
StreamWriter
sw
=
null
;
args
=
new
SessionEventArgs
(
BUFFER_SIZE
);
try
{
splitBuffer
=
httpCmd
.
Split
(
spaceSplit
,
3
);
if
(
splitBuffer
.
Length
!=
3
)
{
TcpHelper
.
SendRaw
(
httpCmd
,
tunnelHostName
,
ref
requestLines
,
args
.
IsS
ecure
,
clientStreamReader
.
BaseStream
);
if
(
clientStream
!=
null
)
clientStream
.
Close
();
return
;
}
method
=
splitBuffer
[
0
];
remoteUri
=
splitBuffer
[
1
];
if
(
splitBuffer
[
2
]
==
"HTTP/1.1"
)
{
version
=
new
Version
(
1
,
1
);
}
else
{
version
=
new
Version
(
1
,
0
);
}
if
(
securehost
!=
null
)
{
remoteUri
=
securehost
+
remoteUri
;
args
.
IsS
ecure
=
true
;
}
//construct the web request that we are going to issue on behalf of the client.
args
.
ProxyRequest
=
(
HttpWebRequest
)
HttpWebRequest
.
Create
(
remoteUri
.
Trim
());
args
.
ProxyRequest
.
Proxy
=
null
;
args
.
ProxyRequest
.
UseDefaultCredentials
=
true
;
args
.
ProxyRequest
.
Method
=
method
;
args
.
ProxyRequest
.
ProtocolVersion
=
version
;
args
.
ClientStream
=
clientStream
;
args
.
ClientStreamReader
=
clientStreamReader
;
for
(
int
i
=
1
;
i
<
requestLines
.
Count
;
i
++)
{
var
rawHeader
=
requestLines
[
i
];
String
[]
header
=
rawHeader
.
ToLower
().
Trim
().
Split
(
colonSpaceSplit
,
2
,
StringSplitOptions
.
None
);
if
((
header
[
0
]
==
"upgrade"
)
&&
(
header
[
1
]
==
"websocket"
))
{
TcpHelper
.
SendRaw
(
httpCmd
,
tunnelHostName
,
ref
requestLines
,
args
.
IsS
ecure
,
clientStreamReader
.
BaseStream
);
if
(
clientStream
!=
null
)
clientStream
.
Close
();
return
;
}
}
ReadRequestHeaders
(
ref
requestLines
,
args
.
ProxyRequest
);
int
contentLen
=
(
int
)
args
.
ProxyRequest
.
ContentLength
;
args
.
ProxyRequest
.
AllowAutoRedirect
=
false
;
args
.
ProxyRequest
.
AutomaticDecompression
=
DecompressionMethods
.
None
;
if
(
BeforeRequest
!=
null
)
{
args
.
Hostname
=
args
.
ProxyRequest
.
RequestUri
.
Host
;
args
.
RequestURL
=
args
.
ProxyRequest
.
RequestUri
.
OriginalString
;
args
.
RequestLength
=
contentLen
;
args
.
HttpVersion
=
version
;
args
.
Port
=
((
IPEndPoint
)
Client
.
Client
.
RemoteEndPoint
).
Port
;
args
.
ipAddress
=
((
IPEndPoint
)
Client
.
Client
.
RemoteEndPoint
).
Address
;
args
.
IsAlive
=
args
.
ProxyRequest
.
KeepAlive
;
BeforeRequest
(
null
,
args
);
}
if
(
args
.
Cancel
)
{
if
(
args
.
IsAlive
)
{
requestLines
.
Clear
();
while
(!
String
.
IsNullOrEmpty
(
tmpLine
=
clientStreamReader
.
ReadLine
()))
{
requestLines
.
Add
(
tmpLine
);
}
httpCmd
=
requestLines
.
Count
>
0
?
requestLines
[
0
]
:
null
;
continue
;
}
else
break
;
}
args
.
ProxyRequest
.
ConnectionGroupName
=
connectionGroup
;
args
.
ProxyRequest
.
AllowWriteStreamBuffering
=
true
;
args
.
FinishedRequestEvent
=
new
ManualResetEvent
(
false
);
if
(
method
.
ToUpper
()
==
"POST"
||
method
.
ToUpper
()
==
"PUT"
)
{
args
.
ProxyRequest
.
BeginGetRequestStream
(
new
AsyncCallback
(
GetRequestStreamCallback
),
args
);
}
else
{
args
.
ProxyRequest
.
BeginGetResponse
(
new
AsyncCallback
(
HandleServerResponse
),
args
);
}
if
(
args
.
IsS
ecure
)
{
if
(
args
.
ProxyRequest
.
Method
==
"POST"
||
args
.
ProxyRequest
.
Method
==
"PUT"
)
args
.
FinishedRequestEvent
.
WaitOne
();
else
args
.
FinishedRequestEvent
.
Set
();
}
else
args
.
FinishedRequestEvent
.
WaitOne
();
httpCmd
=
null
;
if
(
args
.
ProxyRequest
.
KeepAlive
)
{
requestLines
.
Clear
();
while
(!
String
.
IsNullOrEmpty
(
tmpLine
=
clientStreamReader
.
ReadLine
()))
{
requestLines
.
Add
(
tmpLine
);
}
httpCmd
=
requestLines
.
Count
()
>
0
?
requestLines
[
0
]
:
null
;
}
if
(
args
.
ServerResponse
!=
null
)
args
.
ServerResponse
.
Close
();
}
catch
(
IOException
ex
)
{
throw
ex
;
}
catch
(
UriFormatException
ex
)
{
throw
ex
;
}
catch
(
WebException
ex
)
{
throw
ex
;
}
finally
{
if
(
sw
!=
null
)
sw
.
Close
();
if
(
mw
!=
null
)
mw
.
Close
();
if
(
args
.
ProxyRequest
!=
null
)
args
.
ProxyRequest
.
Abort
();
if
(
args
.
ServerResponseStream
!=
null
)
args
.
ServerResponseStream
.
Close
();
}
}
}
catch
(
AuthenticationException
ex
)
{
Debug
.
WriteLine
(
ex
.
Message
);
}
catch
(
EndOfStreamException
ex
)
{
Debug
.
WriteLine
(
ex
.
Message
);
}
catch
(
IOException
ex
)
{
Debug
.
WriteLine
(
ex
.
Message
);
}
catch
(
UriFormatException
ex
)
{
Debug
.
WriteLine
(
ex
.
Message
);
}
catch
(
WebException
ex
)
{
Debug
.
WriteLine
(
ex
.
Message
);
}
finally
{
if
(
connectStreamWriter
!=
null
)
connectStreamWriter
.
Close
();
if
(
clientStreamReader
!=
null
)
clientStreamReader
.
Close
();
if
(
clientStream
!=
null
)
clientStream
.
Close
();
}
}
private
static
void
ReadRequestHeaders
(
ref
List
<
string
>
RequestLines
,
HttpWebRequest
WebRequest
)
{
for
(
int
i
=
1
;
i
<
RequestLines
.
Count
;
i
++)
{
String
httpCmd
=
RequestLines
[
i
];
String
[]
header
=
httpCmd
.
Split
(
colonSpaceSplit
,
2
,
StringSplitOptions
.
None
);
if
(!
String
.
IsNullOrEmpty
(
header
[
0
].
Trim
()))
switch
(
header
[
0
].
ToLower
())
{
case
"accept"
:
WebRequest
.
Accept
=
header
[
1
];
break
;
case
"accept-encoding"
:
WebRequest
.
Headers
.
Add
(
header
[
0
],
"gzip,deflate,zlib"
);
break
;
case
"cookie"
:
WebRequest
.
Headers
[
"Cookie"
]
=
header
[
1
];
break
;
case
"connection"
:
if
(
header
[
1
].
ToLower
()
==
"keep-alive"
)
WebRequest
.
KeepAlive
=
true
;
break
;
case
"content-length"
:
int
contentLen
;
int
.
TryParse
(
header
[
1
],
out
contentLen
);
if
(
contentLen
!=
0
)
WebRequest
.
ContentLength
=
contentLen
;
break
;
case
"content-type"
:
WebRequest
.
ContentType
=
header
[
1
];
break
;
case
"expect"
:
if
(
header
[
1
].
ToLower
()
==
"100-continue"
)
WebRequest
.
ServicePoint
.
Expect100Continue
=
true
;
else
WebRequest
.
Expect
=
header
[
1
];
break
;
case
"host"
:
WebRequest
.
Host
=
header
[
1
];
break
;
case
"if-modified-since"
:
String
[]
sb
=
header
[
1
].
Trim
().
Split
(
semiSplit
);
DateTime
d
;
if
(
DateTime
.
TryParse
(
sb
[
0
],
out
d
))
WebRequest
.
IfModifiedSince
=
d
;
break
;
case
"proxy-connection"
:
break
;
case
"range"
:
var
startEnd
=
header
[
1
].
Replace
(
Environment
.
NewLine
,
""
).
Remove
(
0
,
6
).
Split
(
'-'
);
if
(
startEnd
.
Length
>
1
)
{
if
(!
String
.
IsNullOrEmpty
(
startEnd
[
1
]))
WebRequest
.
AddRange
(
int
.
Parse
(
startEnd
[
0
]),
int
.
Parse
(
startEnd
[
1
]));
else
WebRequest
.
AddRange
(
int
.
Parse
(
startEnd
[
0
]));
}
else
WebRequest
.
AddRange
(
int
.
Parse
(
startEnd
[
0
]));
break
;
case
"referer"
:
WebRequest
.
Referer
=
header
[
1
];
break
;
case
"user-agent"
:
WebRequest
.
UserAgent
=
header
[
1
];
break
;
case
"transfer-encoding"
:
if
(
header
[
1
].
ToLower
()
==
"chunked"
)
WebRequest
.
SendChunked
=
true
;
else
WebRequest
.
SendChunked
=
false
;
break
;
case
"upgrade"
:
if
(
header
[
1
].
ToLower
()
==
"http/1.1"
)
WebRequest
.
Headers
.
Add
(
header
[
0
],
header
[
1
]);
break
;
default
:
if
(
header
.
Length
>
0
)
WebRequest
.
Headers
.
Add
(
header
[
0
],
header
[
1
]);
else
WebRequest
.
Headers
.
Add
(
header
[
0
],
""
);
break
;
}
}
}
private
static
void
GetRequestStreamCallback
(
IAsyncResult
AsynchronousResult
)
{
var
args
=
(
SessionEventArgs
)
AsynchronousResult
.
AsyncState
;
// End the operation
Stream
postStream
=
args
.
ProxyRequest
.
EndGetRequestStream
(
AsynchronousResult
);
if
(
args
.
ProxyRequest
.
ContentLength
>
0
)
{
args
.
ProxyRequest
.
AllowWriteStreamBuffering
=
true
;
try
{
int
totalbytesRead
=
0
;
int
bytesToRead
;
if
(
args
.
ProxyRequest
.
ContentLength
<
BUFFER_SIZE
)
{
bytesToRead
=
(
int
)
args
.
ProxyRequest
.
ContentLength
;
}
else
bytesToRead
=
BUFFER_SIZE
;
while
(
totalbytesRead
<
(
int
)
args
.
ProxyRequest
.
ContentLength
)
{
var
buffer
=
args
.
ClientStreamReader
.
ReadBytes
(
bytesToRead
);
totalbytesRead
+=
buffer
.
Length
;
int
RemainingBytes
=
(
int
)
args
.
ProxyRequest
.
ContentLength
-
totalbytesRead
;
if
(
RemainingBytes
<
bytesToRead
)
{
bytesToRead
=
RemainingBytes
;
}
postStream
.
Write
(
buffer
,
0
,
buffer
.
Length
);
}
postStream
.
Close
();
}
catch
(
IOException
ex
)
{
args
.
ProxyRequest
.
KeepAlive
=
false
;
args
.
FinishedRequestEvent
.
Set
();
Debug
.
WriteLine
(
ex
.
Message
);
return
;
}
catch
(
WebException
ex
)
{
args
.
ProxyRequest
.
KeepAlive
=
false
;
args
.
FinishedRequestEvent
.
Set
();
Debug
.
WriteLine
(
ex
.
Message
);
return
;
}
}
else
if
(
args
.
ProxyRequest
.
SendChunked
)
{
args
.
ProxyRequest
.
AllowWriteStreamBuffering
=
true
;
try
{
StringBuilder
sb
=
new
StringBuilder
();
byte
[]
byteRead
=
new
byte
[
1
];
while
(
true
)
{
args
.
ClientStream
.
Read
(
byteRead
,
0
,
1
);
sb
.
Append
(
Encoding
.
ASCII
.
GetString
(
byteRead
));
if
(
sb
.
ToString
().
EndsWith
(
Environment
.
NewLine
))
{
var
chunkSizeInHex
=
sb
.
ToString
().
Replace
(
Environment
.
NewLine
,
String
.
Empty
);
var
chunckSize
=
int
.
Parse
(
chunkSizeInHex
,
System
.
Globalization
.
NumberStyles
.
HexNumber
);
if
(
chunckSize
==
0
)
{
for
(
int
i
=
0
;
i
<
Encoding
.
ASCII
.
GetByteCount
(
Environment
.
NewLine
);
i
++)
{
args
.
ClientStream
.
ReadByte
();
}
break
;
}
var
totalbytesRead
=
0
;
int
bytesToRead
;
if
(
chunckSize
<
BUFFER_SIZE
)
{
bytesToRead
=
chunckSize
;
}
else
bytesToRead
=
BUFFER_SIZE
;
while
(
totalbytesRead
<
chunckSize
)
{
var
buffer
=
args
.
ClientStreamReader
.
ReadBytes
(
bytesToRead
);
totalbytesRead
+=
buffer
.
Length
;
int
RemainingBytes
=
chunckSize
-
totalbytesRead
;
if
(
RemainingBytes
<
bytesToRead
)
{
bytesToRead
=
RemainingBytes
;
}
postStream
.
Write
(
buffer
,
0
,
buffer
.
Length
);
}
for
(
int
i
=
0
;
i
<
Encoding
.
ASCII
.
GetByteCount
(
Environment
.
NewLine
);
i
++)
{
args
.
ClientStream
.
ReadByte
();
}
sb
.
Clear
();
}
}
postStream
.
Close
();
}
catch
(
IOException
ex
)
{
if
(
postStream
!=
null
)
postStream
.
Close
();
args
.
ProxyRequest
.
KeepAlive
=
false
;
args
.
FinishedRequestEvent
.
Set
();
Debug
.
WriteLine
(
ex
.
Message
);
return
;
}
catch
(
WebException
ex
)
{
if
(
postStream
!=
null
)
postStream
.
Close
();
args
.
ProxyRequest
.
KeepAlive
=
false
;
args
.
FinishedRequestEvent
.
Set
();
Debug
.
WriteLine
(
ex
.
Message
);
return
;
}
}
args
.
ProxyRequest
.
BeginGetResponse
(
new
AsyncCallback
(
HandleServerResponse
),
args
);
}
}
var
_certificate
=
ProxyServer
.
CertManager
.
CreateCertificate
(
tunnelHostName
);
//CertificateHelper.GetCertificate(RootCertificateName, tunnelHostName);
Monitor
.
Exit
(
certificateAccessLock
);
SslStream
sslStream
=
null
;
if
(!
pinnedCertificateClients
.
Contains
(
tunnelHostName
)
&&
isSecure
)
{
sslStream
=
new
SslStream
(
clientStream
,
true
);
try
{
sslStream
.
AuthenticateAsServer
(
_certificate
,
false
,
SslProtocols
.
Tls
|
SslProtocols
.
Ssl3
|
SslProtocols
.
Ssl2
,
false
);
}
catch
(
AuthenticationException
ex
)
{
if
(
pinnedCertificateClients
.
Contains
(
tunnelHostName
)
==
false
)
{
pinnedCertificateClients
.
Add
(
tunnelHostName
);
}
throw
ex
;
}
}
else
{
TcpHelper
.
SendRaw
(
tunnelHostName
,
tunnelPort
,
clientStreamReader
.
BaseStream
);
if
(
clientStream
!=
null
)
clientStream
.
Close
();
return
;
}
clientStreamReader
=
new
CustomBinaryReader
(
sslStream
,
Encoding
.
ASCII
);
//HTTPS server created - we can now decrypt the client's traffic
clientStream
=
sslStream
;
while
(!
String
.
IsNullOrEmpty
(
tmpLine
=
clientStreamReader
.
ReadLine
()))
{
requestLines
.
Add
(
tmpLine
);
}
//read the new http command.
httpCmd
=
requestLines
.
Count
>
0
?
requestLines
[
0
]
:
null
;
if
(
String
.
IsNullOrEmpty
(
httpCmd
))
{
throw
new
EndOfStreamException
();
}
securehost
=
remoteUri
;
}
int
count
=
0
;
SessionEventArgs
args
=
new
SessionEventArgs
(
BUFFER_SIZE
);
while
(!
String
.
IsNullOrEmpty
(
httpCmd
))
{
count
++;
MemoryStream
mw
=
null
;
StreamWriter
sw
=
null
;
args
=
new
SessionEventArgs
(
BUFFER_SIZE
);
try
{
splitBuffer
=
httpCmd
.
Split
(
spaceSplit
,
3
);
if
(
splitBuffer
.
Length
!=
3
)
{
TcpHelper
.
SendRaw
(
httpCmd
,
tunnelHostName
,
ref
requestLines
,
args
.
IsS
SLRequest
,
clientStreamReader
.
BaseStream
);
if
(
clientStream
!=
null
)
clientStream
.
Close
();
return
;
}
method
=
splitBuffer
[
0
];
remoteUri
=
splitBuffer
[
1
];
if
(
splitBuffer
[
2
]
==
"HTTP/1.1"
)
{
version
=
new
Version
(
1
,
1
);
}
else
{
version
=
new
Version
(
1
,
0
);
}
if
(
securehost
!=
null
)
{
remoteUri
=
securehost
+
remoteUri
;
args
.
IsS
SLRequest
=
true
;
}
//construct the web request that we are going to issue on behalf of the client.
args
.
ProxyRequest
=
(
HttpWebRequest
)
HttpWebRequest
.
Create
(
remoteUri
.
Trim
());
args
.
ProxyRequest
.
Proxy
=
null
;
args
.
ProxyRequest
.
UseDefaultCredentials
=
true
;
args
.
ProxyRequest
.
Method
=
method
;
args
.
ProxyRequest
.
ProtocolVersion
=
version
;
args
.
ClientStream
=
clientStream
;
args
.
ClientStreamReader
=
clientStreamReader
;
for
(
int
i
=
1
;
i
<
requestLines
.
Count
;
i
++)
{
var
rawHeader
=
requestLines
[
i
];
String
[]
header
=
rawHeader
.
ToLower
().
Trim
().
Split
(
colonSpaceSplit
,
2
,
StringSplitOptions
.
None
);
if
((
header
[
0
]
==
"upgrade"
)
&&
(
header
[
1
]
==
"websocket"
))
{
TcpHelper
.
SendRaw
(
httpCmd
,
tunnelHostName
,
ref
requestLines
,
args
.
IsS
SLRequest
,
clientStreamReader
.
BaseStream
);
if
(
clientStream
!=
null
)
clientStream
.
Close
();
return
;
}
}
ReadRequestHeaders
(
ref
requestLines
,
args
.
ProxyRequest
);
int
contentLen
=
(
int
)
args
.
ProxyRequest
.
ContentLength
;
args
.
ProxyRequest
.
AllowAutoRedirect
=
false
;
args
.
ProxyRequest
.
AutomaticDecompression
=
DecompressionMethods
.
None
;
if
(
BeforeRequest
!=
null
)
{
args
.
RequestHostname
=
args
.
ProxyRequest
.
RequestUri
.
Host
;
args
.
RequestURL
=
args
.
ProxyRequest
.
RequestUri
.
OriginalString
;
args
.
RequestLength
=
contentLen
;
args
.
RequestHttpVersion
=
version
;
args
.
ClientPort
=
((
IPEndPoint
)
Client
.
Client
.
RemoteEndPoint
).
Port
;
args
.
ClientIpAddress
=
((
IPEndPoint
)
Client
.
Client
.
RemoteEndPoint
).
Address
;
args
.
RequestIsAlive
=
args
.
ProxyRequest
.
KeepAlive
;
BeforeRequest
(
null
,
args
);
}
if
(
args
.
Cancel
Request
)
{
if
(
args
.
RequestIsAlive
)
{
requestLines
.
Clear
();
while
(!
String
.
IsNullOrEmpty
(
tmpLine
=
clientStreamReader
.
ReadLine
()))
{
requestLines
.
Add
(
tmpLine
);
}
httpCmd
=
requestLines
.
Count
>
0
?
requestLines
[
0
]
:
null
;
continue
;
}
else
break
;
}
args
.
ProxyRequest
.
ConnectionGroupName
=
connectionGroup
;
args
.
ProxyRequest
.
AllowWriteStreamBuffering
=
true
;
args
.
FinishedRequestEvent
=
new
ManualResetEvent
(
false
);
if
(
method
.
ToUpper
()
==
"POST"
||
method
.
ToUpper
()
==
"PUT"
)
{
args
.
ProxyRequest
.
BeginGetRequestStream
(
new
AsyncCallback
(
GetRequestStreamCallback
),
args
);
}
else
{
args
.
ProxyRequest
.
BeginGetResponse
(
new
AsyncCallback
(
HandleServerResponse
),
args
);
}
if
(
args
.
IsS
SLRequest
)
{
if
(
args
.
ProxyRequest
.
Method
==
"POST"
||
args
.
ProxyRequest
.
Method
==
"PUT"
)
args
.
FinishedRequestEvent
.
WaitOne
();
else
args
.
FinishedRequestEvent
.
Set
();
}
else
args
.
FinishedRequestEvent
.
WaitOne
();
httpCmd
=
null
;
if
(
args
.
ProxyRequest
.
KeepAlive
)
{
requestLines
.
Clear
();
while
(!
String
.
IsNullOrEmpty
(
tmpLine
=
clientStreamReader
.
ReadLine
()))
{
requestLines
.
Add
(
tmpLine
);
}
httpCmd
=
requestLines
.
Count
()
>
0
?
requestLines
[
0
]
:
null
;
}
if
(
args
.
ServerResponse
!=
null
)
args
.
ServerResponse
.
Close
();
}
catch
(
IOException
ex
)
{
throw
ex
;
}
catch
(
UriFormatException
ex
)
{
throw
ex
;
}
catch
(
WebException
ex
)
{
throw
ex
;
}
finally
{
if
(
sw
!=
null
)
sw
.
Close
();
if
(
mw
!=
null
)
mw
.
Close
();
if
(
args
.
ProxyRequest
!=
null
)
args
.
ProxyRequest
.
Abort
();
if
(
args
.
ServerResponseStream
!=
null
)
args
.
ServerResponseStream
.
Close
();
}
}
}
catch
(
AuthenticationException
ex
)
{
Debug
.
WriteLine
(
ex
.
Message
);
}
catch
(
EndOfStreamException
ex
)
{
Debug
.
WriteLine
(
ex
.
Message
);
}
catch
(
IOException
ex
)
{
Debug
.
WriteLine
(
ex
.
Message
);
}
catch
(
UriFormatException
ex
)
{
Debug
.
WriteLine
(
ex
.
Message
);
}
catch
(
WebException
ex
)
{
Debug
.
WriteLine
(
ex
.
Message
);
}
finally
{
if
(
connectStreamWriter
!=
null
)
connectStreamWriter
.
Close
();
if
(
clientStreamReader
!=
null
)
clientStreamReader
.
Close
();
if
(
clientStream
!=
null
)
clientStream
.
Close
();
}
}
private
static
void
ReadRequestHeaders
(
ref
List
<
string
>
RequestLines
,
HttpWebRequest
WebRequest
)
{
for
(
int
i
=
1
;
i
<
RequestLines
.
Count
;
i
++)
{
String
httpCmd
=
RequestLines
[
i
];
String
[]
header
=
httpCmd
.
Split
(
colonSpaceSplit
,
2
,
StringSplitOptions
.
None
);
if
(!
String
.
IsNullOrEmpty
(
header
[
0
].
Trim
()))
switch
(
header
[
0
].
ToLower
())
{
case
"accept"
:
WebRequest
.
Accept
=
header
[
1
];
break
;
case
"accept-encoding"
:
WebRequest
.
Headers
.
Add
(
header
[
0
],
"gzip,deflate,zlib"
);
break
;
case
"cookie"
:
WebRequest
.
Headers
[
"Cookie"
]
=
header
[
1
];
break
;
case
"connection"
:
if
(
header
[
1
].
ToLower
()
==
"keep-alive"
)
WebRequest
.
KeepAlive
=
true
;
break
;
case
"content-length"
:
int
contentLen
;
int
.
TryParse
(
header
[
1
],
out
contentLen
);
if
(
contentLen
!=
0
)
WebRequest
.
ContentLength
=
contentLen
;
break
;
case
"content-type"
:
WebRequest
.
ContentType
=
header
[
1
];
break
;
case
"expect"
:
if
(
header
[
1
].
ToLower
()
==
"100-continue"
)
WebRequest
.
ServicePoint
.
Expect100Continue
=
true
;
else
WebRequest
.
Expect
=
header
[
1
];
break
;
case
"host"
:
WebRequest
.
Host
=
header
[
1
];
break
;
case
"if-modified-since"
:
String
[]
sb
=
header
[
1
].
Trim
().
Split
(
semiSplit
);
DateTime
d
;
if
(
DateTime
.
TryParse
(
sb
[
0
],
out
d
))
WebRequest
.
IfModifiedSince
=
d
;
break
;
case
"proxy-connection"
:
break
;
case
"range"
:
var
startEnd
=
header
[
1
].
Replace
(
Environment
.
NewLine
,
""
).
Remove
(
0
,
6
).
Split
(
'-'
);
if
(
startEnd
.
Length
>
1
)
{
if
(!
String
.
IsNullOrEmpty
(
startEnd
[
1
]))
WebRequest
.
AddRange
(
int
.
Parse
(
startEnd
[
0
]),
int
.
Parse
(
startEnd
[
1
]));
else
WebRequest
.
AddRange
(
int
.
Parse
(
startEnd
[
0
]));
}
else
WebRequest
.
AddRange
(
int
.
Parse
(
startEnd
[
0
]));
break
;
case
"referer"
:
WebRequest
.
Referer
=
header
[
1
];
break
;
case
"user-agent"
:
WebRequest
.
UserAgent
=
header
[
1
];
break
;
case
"transfer-encoding"
:
if
(
header
[
1
].
ToLower
()
==
"chunked"
)
WebRequest
.
SendChunked
=
true
;
else
WebRequest
.
SendChunked
=
false
;
break
;
case
"upgrade"
:
if
(
header
[
1
].
ToLower
()
==
"http/1.1"
)
WebRequest
.
Headers
.
Add
(
header
[
0
],
header
[
1
]);
break
;
default
:
if
(
header
.
Length
>
0
)
WebRequest
.
Headers
.
Add
(
header
[
0
],
header
[
1
]);
else
WebRequest
.
Headers
.
Add
(
header
[
0
],
""
);
break
;
}
}
}
private
static
void
GetRequestStreamCallback
(
IAsyncResult
AsynchronousResult
)
{
var
args
=
(
SessionEventArgs
)
AsynchronousResult
.
AsyncState
;
// End the operation
Stream
postStream
=
args
.
ProxyRequest
.
EndGetRequestStream
(
AsynchronousResult
);
if
(
args
.
ProxyRequest
.
ContentLength
>
0
)
{
args
.
ProxyRequest
.
AllowWriteStreamBuffering
=
true
;
try
{
int
totalbytesRead
=
0
;
int
bytesToRead
;
if
(
args
.
ProxyRequest
.
ContentLength
<
BUFFER_SIZE
)
{
bytesToRead
=
(
int
)
args
.
ProxyRequest
.
ContentLength
;
}
else
bytesToRead
=
BUFFER_SIZE
;
while
(
totalbytesRead
<
(
int
)
args
.
ProxyRequest
.
ContentLength
)
{
var
buffer
=
args
.
ClientStreamReader
.
ReadBytes
(
bytesToRead
);
totalbytesRead
+=
buffer
.
Length
;
int
RemainingBytes
=
(
int
)
args
.
ProxyRequest
.
ContentLength
-
totalbytesRead
;
if
(
RemainingBytes
<
bytesToRead
)
{
bytesToRead
=
RemainingBytes
;
}
postStream
.
Write
(
buffer
,
0
,
buffer
.
Length
);
}
postStream
.
Close
();
}
catch
(
IOException
ex
)
{
args
.
ProxyRequest
.
KeepAlive
=
false
;
args
.
FinishedRequestEvent
.
Set
();
Debug
.
WriteLine
(
ex
.
Message
);
return
;
}
catch
(
WebException
ex
)
{
args
.
ProxyRequest
.
KeepAlive
=
false
;
args
.
FinishedRequestEvent
.
Set
();
Debug
.
WriteLine
(
ex
.
Message
);
return
;
}
}
else
if
(
args
.
ProxyRequest
.
SendChunked
)
{
args
.
ProxyRequest
.
AllowWriteStreamBuffering
=
true
;
try
{
StringBuilder
sb
=
new
StringBuilder
();
byte
[]
byteRead
=
new
byte
[
1
];
while
(
true
)
{
args
.
ClientStream
.
Read
(
byteRead
,
0
,
1
);
sb
.
Append
(
Encoding
.
ASCII
.
GetString
(
byteRead
));
if
(
sb
.
ToString
().
EndsWith
(
Environment
.
NewLine
))
{
var
chunkSizeInHex
=
sb
.
ToString
().
Replace
(
Environment
.
NewLine
,
String
.
Empty
);
var
chunckSize
=
int
.
Parse
(
chunkSizeInHex
,
System
.
Globalization
.
NumberStyles
.
HexNumber
);
if
(
chunckSize
==
0
)
{
for
(
int
i
=
0
;
i
<
Encoding
.
ASCII
.
GetByteCount
(
Environment
.
NewLine
);
i
++)
{
args
.
ClientStream
.
ReadByte
();
}
break
;
}
var
totalbytesRead
=
0
;
int
bytesToRead
;
if
(
chunckSize
<
BUFFER_SIZE
)
{
bytesToRead
=
chunckSize
;
}
else
bytesToRead
=
BUFFER_SIZE
;
while
(
totalbytesRead
<
chunckSize
)
{
var
buffer
=
args
.
ClientStreamReader
.
ReadBytes
(
bytesToRead
);
totalbytesRead
+=
buffer
.
Length
;
int
RemainingBytes
=
chunckSize
-
totalbytesRead
;
if
(
RemainingBytes
<
bytesToRead
)
{
bytesToRead
=
RemainingBytes
;
}
postStream
.
Write
(
buffer
,
0
,
buffer
.
Length
);
}
for
(
int
i
=
0
;
i
<
Encoding
.
ASCII
.
GetByteCount
(
Environment
.
NewLine
);
i
++)
{
args
.
ClientStream
.
ReadByte
();
}
sb
.
Clear
();
}
}
postStream
.
Close
();
}
catch
(
IOException
ex
)
{
if
(
postStream
!=
null
)
postStream
.
Close
();
args
.
ProxyRequest
.
KeepAlive
=
false
;
args
.
FinishedRequestEvent
.
Set
();
Debug
.
WriteLine
(
ex
.
Message
);
return
;
}
catch
(
WebException
ex
)
{
if
(
postStream
!=
null
)
postStream
.
Close
();
args
.
ProxyRequest
.
KeepAlive
=
false
;
args
.
FinishedRequestEvent
.
Set
();
Debug
.
WriteLine
(
ex
.
Message
);
return
;
}
}
args
.
ProxyRequest
.
BeginGetResponse
(
new
AsyncCallback
(
HandleServerResponse
),
args
);
}
}
}
\ No newline at end of file
Titanium.Web.Proxy/ResponseHandler.cs
View file @
fe4d5ee9
...
...
@@ -62,25 +62,25 @@ namespace Titanium.Web.Proxy
switch
(
args
.
ServerResponse
.
ContentEncoding
)
{
case
"gzip"
:
data
=
CompressionHelper
.
CompressGzip
(
args
.
Response
String
,
args
.
Encoding
);
data
=
CompressionHelper
.
CompressGzip
(
args
.
Response
HtmlBody
,
args
.
Encoding
);
WriteResponseStatus
(
args
.
ServerResponse
.
ProtocolVersion
,
args
.
ServerResponse
.
StatusCode
,
args
.
ServerResponse
.
StatusDescription
,
responseWriter
);
WriteResponseHeaders
(
responseWriter
,
responseHeaders
,
data
.
Length
);
SendData
(
clientWriteStream
,
data
,
isChunked
);
break
;
case
"deflate"
:
data
=
CompressionHelper
.
CompressDeflate
(
args
.
Response
String
,
args
.
Encoding
);
data
=
CompressionHelper
.
CompressDeflate
(
args
.
Response
HtmlBody
,
args
.
Encoding
);
WriteResponseStatus
(
args
.
ServerResponse
.
ProtocolVersion
,
args
.
ServerResponse
.
StatusCode
,
args
.
ServerResponse
.
StatusDescription
,
responseWriter
);
WriteResponseHeaders
(
responseWriter
,
responseHeaders
,
data
.
Length
);
SendData
(
clientWriteStream
,
data
,
isChunked
);
break
;
case
"zlib"
:
data
=
CompressionHelper
.
CompressZlib
(
args
.
Response
String
,
args
.
Encoding
);
data
=
CompressionHelper
.
CompressZlib
(
args
.
Response
HtmlBody
,
args
.
Encoding
);
WriteResponseStatus
(
args
.
ServerResponse
.
ProtocolVersion
,
args
.
ServerResponse
.
StatusCode
,
args
.
ServerResponse
.
StatusDescription
,
responseWriter
);
WriteResponseHeaders
(
responseWriter
,
responseHeaders
,
data
.
Length
);
SendData
(
clientWriteStream
,
data
,
isChunked
);
break
;
default
:
data
=
EncodeData
(
args
.
Response
String
,
args
.
Encoding
);
data
=
EncodeData
(
args
.
Response
HtmlBody
,
args
.
Encoding
);
WriteResponseStatus
(
args
.
ServerResponse
.
ProtocolVersion
,
args
.
ServerResponse
.
StatusCode
,
args
.
ServerResponse
.
StatusDescription
,
responseWriter
);
WriteResponseHeaders
(
responseWriter
,
responseHeaders
,
data
.
Length
);
SendData
(
clientWriteStream
,
data
,
isChunked
);
...
...
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