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
ee9a0929
Commit
ee9a0929
authored
Sep 07, 2015
by
justcoding121
Committed by
justcoding121
Sep 07, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix POST chunked file upload
parent
1379388d
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
235 additions
and
190 deletions
+235
-190
README.md
README.md
+5
-4
ProxyTestController.cs
Titanium.Web.Proxy.Test/ProxyTestController.cs
+4
-4
SessionEventArgs.cs
Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
+111
-36
Compression.cs
Titanium.Web.Proxy/Helpers/Compression.cs
+1
-1
RequestHandler.cs
Titanium.Web.Proxy/RequestHandler.cs
+104
-135
ResponseHandler.cs
Titanium.Web.Proxy/ResponseHandler.cs
+10
-10
No files found.
README.md
View file @
ee9a0929
...
...
@@ -57,9 +57,9 @@ Sample request and response event handlers
{
Console
.
WriteLine
(
e
.
RequestURL
);
Console
.
WriteLine
(
e
.
RequestURL
);
//
modify
request headers
//
read
request headers
var
requestHeaders
=
e
.
RequestHeaders
;
if
((
e
.
RequestMethod
.
ToUpper
()
==
"POST"
||
e
.
RequestMethod
.
ToUpper
()
==
"PUT"
)
&&
e
.
RequestContentLength
>
0
)
...
...
@@ -87,9 +87,10 @@ Sample request and response event handlers
public
void
OnResponse
(
object
sender
,
SessionEventArgs
e
)
{
//modify
response headers
//read
response headers
var
responseHeaders
=
e
.
ResponseHeaders
;
if
(
e
.
ResponseStatusCode
==
HttpStatusCode
.
OK
)
{
if
(
e
.
ResponseContentType
.
Trim
().
ToLower
().
Contains
(
"text/html"
))
...
...
@@ -101,7 +102,7 @@ Sample request and response event handlers
//Get response body as string
string
responseBody
=
e
.
GetResponseBodyAsString
();
//
Inject script in to body
//
Modify e.ServerResponse
Regex
rex
=
new
Regex
(
"</body>"
,
RegexOptions
.
RightToLeft
|
RegexOptions
.
IgnoreCase
|
RegexOptions
.
Multiline
);
string
modified
=
rex
.
Replace
(
responseBody
,
"<script type =\"text/javascript\">alert('Response was modified by this script!');</script></body>"
,
1
);
...
...
Titanium.Web.Proxy.Test/ProxyTestController.cs
View file @
ee9a0929
...
...
@@ -60,10 +60,10 @@ namespace Titanium.Web.Proxy.Test
Console
.
WriteLine
(
e
.
RequestURL
);
////
modify
request headers
////
read
request headers
//var requestHeaders = e.RequestHeaders;
//if ((e.RequestMethod.ToUpper() == "POST" || e.RequestMethod.ToUpper() == "PUT")
&& e.RequestContentLength > 0
)
//if ((e.RequestMethod.ToUpper() == "POST" || e.RequestMethod.ToUpper() == "PUT"))
//{
// //Get/Set request body bytes
// byte[] bodyBytes = e.GetRequestBody();
...
...
@@ -89,9 +89,9 @@ namespace Titanium.Web.Proxy.Test
//Insert script to read the Browser URL and send it back to proxy
public
void
OnResponse
(
object
sender
,
SessionEventArgs
e
)
{
////
modify
response headers
////
read
response headers
//var responseHeaders = e.ResponseHeaders;
//if (e.ResponseStatusCode == HttpStatusCode.OK)
//{
...
...
Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
View file @
ee9a0929
...
...
@@ -21,6 +21,14 @@ namespace Titanium.Web.Proxy.EventArguments
internal
CustomBinaryReader
clientStreamReader
{
get
;
set
;
}
internal
StreamWriter
clientStreamWriter
{
get
;
set
;
}
internal
bool
isHttps
{
get
;
set
;
}
internal
string
requestURL
{
get
;
set
;
}
internal
string
requestHostname
{
get
;
set
;
}
internal
int
clientPort
{
get
;
set
;
}
internal
IPAddress
clientIpAddress
{
get
;
set
;
}
internal
Encoding
requestEncoding
{
get
;
set
;
}
internal
Version
requestHttpVersion
{
get
;
set
;
}
internal
bool
requestIsAlive
{
get
;
set
;
}
...
...
@@ -28,25 +36,19 @@ namespace Titanium.Web.Proxy.EventArguments
internal
byte
[]
requestBody
{
get
;
set
;
}
internal
string
requestBodyString
{
get
;
set
;
}
internal
bool
requestBodyRead
{
get
;
set
;
}
internal
List
<
HttpHeader
>
requestHeaders
{
get
;
set
;
}
internal
bool
RequestLocked
{
get
;
set
;
}
internal
HttpWebRequest
proxyRequest
{
get
;
set
;
}
internal
Encoding
responseEncoding
{
get
;
set
;
}
internal
Stream
responseStream
{
get
;
set
;
}
internal
byte
[]
responseBody
{
get
;
set
;
}
internal
string
responseBodyString
{
get
;
set
;
}
internal
bool
responseBodyRead
{
get
;
set
;
}
internal
bool
RequestLocked
{
get
;
set
;
}
internal
HttpWebRequest
proxyRequest
{
get
;
set
;
}
internal
List
<
HttpHeader
>
responseHeaders
{
get
;
set
;
}
internal
bool
ResponseLocked
{
get
;
set
;
}
internal
HttpWebResponse
serverResponse
{
get
;
set
;
}
internal
bool
isHttps
{
get
;
set
;
}
internal
string
requestURL
{
get
;
set
;
}
internal
string
requestHostname
{
get
;
set
;
}
internal
int
clientPort
{
get
;
set
;
}
internal
IPAddress
clientIpAddress
{
get
;
set
;
}
public
int
ClientPort
{
get
{
return
this
.
clientPort
;
}
}
public
IPAddress
ClientIpAddress
{
get
{
return
this
.
clientIpAddress
;
}
}
...
...
@@ -56,14 +58,17 @@ namespace Titanium.Web.Proxy.EventArguments
public
string
RequestURL
{
get
{
return
this
.
requestURL
;
}
}
public
string
RequestHostname
{
get
{
return
this
.
requestHostname
;
}
}
public
List
<
HttpHeader
>
RequestHeaders
{
get
{
return
this
.
requestHeaders
;
}
}
public
List
<
HttpHeader
>
ResponseHeaders
{
get
{
return
this
.
responseHeaders
;
}
}
public
int
RequestContentLength
{
get
{
if
(
this
.
R
equestHeaders
.
Any
(
x
=>
x
.
Name
.
ToLower
()
==
"content-length"
))
if
(
this
.
r
equestHeaders
.
Any
(
x
=>
x
.
Name
.
ToLower
()
==
"content-length"
))
{
int
contentLen
;
int
.
TryParse
(
this
.
R
equestHeaders
.
First
(
x
=>
x
.
Name
.
ToLower
()
==
"content-length"
).
Value
,
out
contentLen
);
int
.
TryParse
(
this
.
r
equestHeaders
.
First
(
x
=>
x
.
Name
.
ToLower
()
==
"content-length"
).
Value
,
out
contentLen
);
if
(
contentLen
!=
0
)
return
contentLen
;
}
...
...
@@ -72,11 +77,11 @@ namespace Titanium.Web.Proxy.EventArguments
}
public
string
RequestMethod
{
get
{
return
this
.
proxyRequest
.
Method
;
}
}
public
List
<
HttpHeader
>
RequestHeaders
{
get
;
set
;
}
public
HttpStatusCode
ResponseStatusCode
{
get
{
return
this
.
serverResponse
.
StatusCode
;
}
}
public
string
ResponseContentType
{
get
{
return
this
.
ResponseHeaders
.
Any
(
x
=>
x
.
Name
.
ToLower
()
==
"content-type"
)
?
this
.
R
esponseHeaders
.
First
(
x
=>
x
.
Name
.
ToLower
()
==
"content-type"
).
Value
:
null
;
}
}
public
List
<
HttpHeader
>
ResponseHeaders
{
get
;
set
;
}
public
string
ResponseContentType
{
get
{
return
this
.
responseHeaders
.
Any
(
x
=>
x
.
Name
.
ToLower
()
==
"content-type"
)
?
this
.
r
esponseHeaders
.
First
(
x
=>
x
.
Name
.
ToLower
()
==
"content-type"
).
Value
:
null
;
}
}
internal
SessionEventArgs
(
int
bufferSize
)
{
...
...
@@ -85,9 +90,88 @@ namespace Titanium.Web.Proxy.EventArguments
private
void
readRequestBody
()
{
if
((
proxyRequest
.
Method
.
ToUpper
()
!=
"POST"
&&
proxyRequest
.
Method
.
ToUpper
()
!=
"PUT"
))
{
throw
new
BodyNotFoundException
(
"Request don't have a body."
+
"Please verify that this request is a Http POST/PUT and request content length is greater than zero before accessing the body."
);
}
if
(
requestBody
==
null
)
{
requestBody
=
clientStreamReader
.
ReadBytes
(
RequestContentLength
);
bool
isChunked
=
false
;
string
requestContentEncoding
=
null
;
if
(
requestHeaders
.
Any
(
x
=>
x
.
Name
.
ToLower
()
==
"content-encoding"
))
{
requestContentEncoding
=
requestHeaders
.
First
(
x
=>
x
.
Name
.
ToLower
()
==
"content-encoding"
).
Value
;
}
if
(
requestHeaders
.
Any
(
x
=>
x
.
Name
.
ToLower
()
==
"transfer-encoding"
))
{
var
transferEncoding
=
requestHeaders
.
First
(
x
=>
x
.
Name
.
ToLower
()
==
"transfer-encoding"
).
Value
.
ToLower
();
if
(
transferEncoding
.
Contains
(
"chunked"
))
{
isChunked
=
true
;
}
}
if
(
requestContentEncoding
==
null
&&
!
isChunked
)
requestBody
=
clientStreamReader
.
ReadBytes
(
RequestContentLength
);
else
{
using
(
var
requestBodyStream
=
new
MemoryStream
())
{
if
(
isChunked
)
{
while
(
true
)
{
var
chuchkHead
=
clientStreamReader
.
ReadLine
();
var
chunkSize
=
int
.
Parse
(
chuchkHead
,
System
.
Globalization
.
NumberStyles
.
HexNumber
);
if
(
chunkSize
!=
0
)
{
var
buffer
=
clientStreamReader
.
ReadBytes
(
chunkSize
);
requestBodyStream
.
Write
(
buffer
,
0
,
buffer
.
Length
);
var
chunkTrail
=
clientStreamReader
.
ReadLine
();
}
else
{
clientStreamReader
.
ReadLine
();
break
;
}
}
}
try
{
switch
(
requestContentEncoding
)
{
case
"gzip"
:
requestBody
=
CompressionHelper
.
DecompressGzip
(
requestBodyStream
);
break
;
case
"deflate"
:
requestBody
=
CompressionHelper
.
DecompressDeflate
(
requestBodyStream
);
break
;
case
"zlib"
:
requestBody
=
CompressionHelper
.
DecompressGzip
(
requestBodyStream
);
break
;
default
:
requestBody
=
requestBodyStream
.
ToArray
();
break
;
}
}
catch
{
requestBody
=
requestBodyStream
.
ToArray
();
}
}
}
}
requestBodyRead
=
true
;
}
...
...
@@ -95,6 +179,7 @@ namespace Titanium.Web.Proxy.EventArguments
{
if
(
responseBody
==
null
)
{
switch
(
serverResponse
.
ContentEncoding
)
{
case
"gzip"
:
...
...
@@ -144,34 +229,25 @@ namespace Titanium.Web.Proxy.EventArguments
{
if
(
RequestLocked
)
throw
new
Exception
(
"You cannot call this function after request is made to server."
);
if
((
proxyRequest
.
Method
.
ToUpper
()
==
"POST"
||
proxyRequest
.
Method
.
ToUpper
()
==
"PUT"
)
&&
RequestContentLength
>
0
)
{
readRequestBody
();
readRequestBody
();
return
requestBody
;
return
requestBody
;
}
else
throw
new
BodyNotFoundException
(
"Request don't have a body."
+
"Please verify that this request is a Http POST/PUT and request content length is greater than zero before accessing the body."
);
}
public
string
GetRequestBodyAsString
()
{
if
(
RequestLocked
)
throw
new
Exception
(
"You cannot call this function after request is made to server."
);
if
((
proxyRequest
.
Method
.
ToUpper
()
==
"POST"
||
proxyRequest
.
Method
.
ToUpper
()
==
"PUT"
)
&&
RequestContentLength
>
0
)
{
readRequestBody
();
if
(
requestBodyString
==
null
)
{
requestBodyString
=
requestEncoding
.
GetString
(
requestBody
);
}
re
turn
requestBodyString
;
readRequestBody
();
if
(
requestBodyString
==
null
)
{
re
questBodyString
=
requestEncoding
.
GetString
(
requestBody
)
;
}
else
throw
new
BodyNotFoundException
(
"Request don't have a body."
+
"Please verify that this request is a Http POST/PUT and request content length is greater than zero before accessing the body."
);
return
requestBodyString
;
}
...
...
@@ -302,7 +378,6 @@ namespace Titanium.Web.Proxy.EventArguments
}
}
}
\ No newline at end of file
Titanium.Web.Proxy/Helpers/Compression.cs
View file @
ee9a0929
...
...
@@ -59,7 +59,7 @@ namespace Titanium.Web.Proxy.Helpers
public
static
byte
[]
DecompressGzip
(
Stream
input
)
{
using
(
System
.
IO
.
Compression
.
GZipStream
decompressor
=
new
System
.
IO
.
Compression
.
GZipStream
(
input
,
System
.
IO
.
Compression
.
CompressionMode
.
Decompress
))
using
(
var
decompressor
=
new
System
.
IO
.
Compression
.
GZipStream
(
input
,
System
.
IO
.
Compression
.
CompressionMode
.
Decompress
))
{
int
read
=
0
;
...
...
Titanium.Web.Proxy/RequestHandler.cs
View file @
ee9a0929
...
...
@@ -50,7 +50,7 @@ namespace Titanium.Web.Proxy
httpRemoteUri
=
new
Uri
(
httpCmdSplit
[
1
]);
var
httpVersion
=
httpCmdSplit
[
2
];
var
excluded
=
ExcludedHttpsHostNameRegex
.
Any
(
x
=>
Regex
.
IsMatch
(
httpRemoteUri
.
Host
,
x
));
//Client wants to create a secure tcp tunnel (its a HTTPS request)
...
...
@@ -59,11 +59,11 @@ namespace Titanium.Web.Proxy
httpRemoteUri
=
new
Uri
(
"https://"
+
httpCmdSplit
[
1
]);
clientStreamReader
.
ReadAllLines
();
WriteConnectResponse
(
clientStreamWriter
,
httpVersion
);
var
certificate
=
ProxyServer
.
CertManager
.
CreateCertificate
(
httpRemoteUri
.
Host
);
SslStream
sslStream
=
null
;
try
...
...
@@ -112,7 +112,7 @@ namespace Titanium.Web.Proxy
}
private
static
void
HandleHttpSessionRequest
(
TcpClient
client
,
string
httpCmd
,
Stream
clientStream
,
CustomBinaryReader
clientStreamReader
,
StreamWriter
clientStreamWriter
,
string
secureTunnelHostName
)
{
...
...
@@ -124,7 +124,7 @@ namespace Titanium.Web.Proxy
var
args
=
new
SessionEventArgs
(
BUFFER_SIZE
);
args
.
client
=
client
;
try
{
...
...
@@ -150,26 +150,26 @@ namespace Titanium.Web.Proxy
args
.
isHttps
=
true
;
}
args
.
R
equestHeaders
=
new
List
<
HttpHeader
>();
args
.
r
equestHeaders
=
new
List
<
HttpHeader
>();
string
tmpLine
=
null
;
while
(!
String
.
IsNullOrEmpty
(
tmpLine
=
clientStreamReader
.
ReadLine
()))
{
String
[]
header
=
tmpLine
.
Split
(
colonSpaceSplit
,
2
,
StringSplitOptions
.
None
);
args
.
R
equestHeaders
.
Add
(
new
HttpHeader
(
header
[
0
],
header
[
1
]));
args
.
r
equestHeaders
.
Add
(
new
HttpHeader
(
header
[
0
],
header
[
1
]));
}
for
(
int
i
=
0
;
i
<
args
.
R
equestHeaders
.
Count
;
i
++)
for
(
int
i
=
0
;
i
<
args
.
r
equestHeaders
.
Count
;
i
++)
{
var
rawHeader
=
args
.
R
equestHeaders
[
i
];
var
rawHeader
=
args
.
r
equestHeaders
[
i
];
//if request was upgrade to web-socket protocol then relay the request without proxying
if
((
rawHeader
.
Name
.
ToLower
()
==
"upgrade"
)
&&
(
rawHeader
.
Value
.
ToLower
()
==
"websocket"
))
{
TcpHelper
.
SendRaw
(
clientStreamReader
.
BaseStream
,
httpCmd
,
args
.
R
equestHeaders
,
httpRemoteUri
.
Host
,
httpRemoteUri
.
Port
,
httpRemoteUri
.
Scheme
==
Uri
.
UriSchemeHttps
);
TcpHelper
.
SendRaw
(
clientStreamReader
.
BaseStream
,
httpCmd
,
args
.
r
equestHeaders
,
httpRemoteUri
.
Host
,
httpRemoteUri
.
Port
,
httpRemoteUri
.
Scheme
==
Uri
.
UriSchemeHttps
);
Dispose
(
client
,
clientStream
,
clientStreamReader
,
clientStreamWriter
,
args
);
return
;
}
...
...
@@ -184,7 +184,7 @@ namespace Titanium.Web.Proxy
args
.
proxyRequest
.
ProtocolVersion
=
version
;
args
.
clientStream
=
clientStream
;
args
.
clientStreamReader
=
clientStreamReader
;
args
.
clientStreamWriter
=
clientStreamWriter
;
args
.
clientStreamWriter
=
clientStreamWriter
;
args
.
proxyRequest
.
AllowAutoRedirect
=
false
;
args
.
proxyRequest
.
AutomaticDecompression
=
DecompressionMethods
.
None
;
args
.
requestHostname
=
args
.
proxyRequest
.
RequestUri
.
Host
;
...
...
@@ -195,7 +195,7 @@ namespace Titanium.Web.Proxy
args
.
requestIsAlive
=
args
.
proxyRequest
.
KeepAlive
;
args
.
proxyRequest
.
ConnectionGroupName
=
args
.
requestHostname
;
args
.
proxyRequest
.
AllowWriteStreamBuffering
=
true
;
//If requested interception
if
(
BeforeRequest
!=
null
)
...
...
@@ -212,7 +212,7 @@ namespace Titanium.Web.Proxy
return
;
}
SetRequestHeaders
(
args
.
R
equestHeaders
,
args
.
proxyRequest
);
SetRequestHeaders
(
args
.
r
equestHeaders
,
args
.
proxyRequest
);
//If request was modified by user
if
(
args
.
requestBodyRead
)
...
...
@@ -230,7 +230,6 @@ namespace Titanium.Web.Proxy
if
(
httpMethod
.
ToUpper
()
==
"POST"
||
httpMethod
.
ToUpper
()
==
"PUT"
)
{
SendClientRequestBody
(
args
);
}
//Http request body sent, now wait asynchronously for response
args
.
proxyRequest
.
BeginGetResponse
(
new
AsyncCallback
(
HandleHttpSessionResponse
),
args
);
...
...
@@ -267,79 +266,80 @@ namespace Titanium.Web.Proxy
for
(
int
i
=
0
;
i
<
requestHeaders
.
Count
;
i
++)
{
switch
(
requestHeaders
[
i
].
Name
.
ToLower
())
{
case
"accept"
:
webRequest
.
Accept
=
requestHeaders
[
i
].
Value
;
break
;
case
"accept-encoding"
:
webRequest
.
Headers
.
Add
(
"Accept-Encoding"
,
"gzip,deflate,zlib"
);
break
;
case
"cookie"
:
webRequest
.
Headers
[
"Cookie"
]
=
requestHeaders
[
i
].
Value
;
break
;
case
"connection"
:
if
(
requestHeaders
[
i
].
Value
.
ToLower
()
==
"keep-alive"
)
webRequest
.
KeepAlive
=
true
;
break
;
case
"content-length"
:
int
contentLen
;
int
.
TryParse
(
requestHeaders
[
i
].
Value
,
out
contentLen
);
if
(
contentLen
!=
0
)
webRequest
.
ContentLength
=
contentLen
;
break
;
case
"content-type"
:
webRequest
.
ContentType
=
requestHeaders
[
i
].
Value
;
break
;
case
"expect"
:
if
(
requestHeaders
[
i
].
Value
.
ToLower
()
==
"100-continue"
)
webRequest
.
ServicePoint
.
Expect100Continue
=
true
;
else
webRequest
.
Expect
=
requestHeaders
[
i
].
Value
;
break
;
case
"host"
:
webRequest
.
Host
=
requestHeaders
[
i
].
Value
;
break
;
case
"if-modified-since"
:
String
[]
sb
=
requestHeaders
[
i
].
Value
.
Trim
().
Split
(
semiSplit
);
DateTime
d
;
if
(
DateTime
.
TryParse
(
sb
[
0
],
out
d
))
webRequest
.
IfModifiedSince
=
d
;
break
;
case
"proxy-connection"
:
if
(
requestHeaders
[
i
].
Value
.
ToLower
()
==
"keep-alive"
)
webRequest
.
KeepAlive
=
true
;
break
;
case
"range"
:
var
startEnd
=
requestHeaders
[
i
].
Value
.
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
=
requestHeaders
[
i
].
Value
;
break
;
case
"user-agent"
:
webRequest
.
UserAgent
=
requestHeaders
[
i
].
Value
;
break
;
//revisit this, transfer-encoding is not a request header according to spec
//But how to identify if client is sending chunked body for PUT/POST?
case
"transfer-encoding"
:
if
(
requestHeaders
[
i
].
Value
.
ToLower
()
==
"chunked"
)
webRequest
.
SendChunked
=
true
;
else
webRequest
.
SendChunked
=
false
;
break
;
case
"upgrade"
:
if
(
requestHeaders
[
i
].
Value
.
ToLower
()
==
"http/1.1"
)
webRequest
.
Headers
.
Add
(
"Upgrade"
,
requestHeaders
[
i
].
Value
);
break
;
default
:
webRequest
.
Headers
.
Add
(
requestHeaders
[
i
].
Name
,
requestHeaders
[
i
].
Value
);
break
;
}
{
case
"accept"
:
webRequest
.
Accept
=
requestHeaders
[
i
].
Value
;
break
;
case
"accept-encoding"
:
webRequest
.
Headers
.
Add
(
"Accept-Encoding"
,
"gzip,deflate,zlib"
);
break
;
case
"cookie"
:
webRequest
.
Headers
[
"Cookie"
]
=
requestHeaders
[
i
].
Value
;
break
;
case
"connection"
:
if
(
requestHeaders
[
i
].
Value
.
ToLower
()
==
"keep-alive"
)
webRequest
.
KeepAlive
=
true
;
break
;
case
"content-length"
:
int
contentLen
;
int
.
TryParse
(
requestHeaders
[
i
].
Value
,
out
contentLen
);
if
(
contentLen
!=
0
)
webRequest
.
ContentLength
=
contentLen
;
break
;
case
"content-type"
:
webRequest
.
ContentType
=
requestHeaders
[
i
].
Value
;
break
;
case
"expect"
:
if
(
requestHeaders
[
i
].
Value
.
ToLower
()
==
"100-continue"
)
webRequest
.
ServicePoint
.
Expect100Continue
=
true
;
else
webRequest
.
Expect
=
requestHeaders
[
i
].
Value
;
break
;
case
"host"
:
webRequest
.
Host
=
requestHeaders
[
i
].
Value
;
break
;
case
"if-modified-since"
:
String
[]
sb
=
requestHeaders
[
i
].
Value
.
Trim
().
Split
(
semiSplit
);
DateTime
d
;
if
(
DateTime
.
TryParse
(
sb
[
0
],
out
d
))
webRequest
.
IfModifiedSince
=
d
;
break
;
case
"proxy-connection"
:
if
(
requestHeaders
[
i
].
Value
.
ToLower
()
==
"keep-alive"
)
webRequest
.
KeepAlive
=
true
;
break
;
case
"range"
:
var
startEnd
=
requestHeaders
[
i
].
Value
.
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
=
requestHeaders
[
i
].
Value
;
break
;
case
"user-agent"
:
webRequest
.
UserAgent
=
requestHeaders
[
i
].
Value
;
break
;
//revisit this, transfer-encoding is not a request header according to spec
//But how to identify if client is sending chunked body for PUT/POST?
case
"transfer-encoding"
:
if
(
requestHeaders
[
i
].
Value
.
ToLower
().
Contains
(
"chunked"
))
webRequest
.
SendChunked
=
true
;
else
webRequest
.
SendChunked
=
false
;
break
;
case
"upgrade"
:
if
(
requestHeaders
[
i
].
Value
.
ToLower
()
==
"http/1.1"
)
webRequest
.
Headers
.
Add
(
"Upgrade"
,
requestHeaders
[
i
].
Value
);
break
;
default
:
webRequest
.
Headers
.
Add
(
requestHeaders
[
i
].
Name
,
requestHeaders
[
i
].
Value
);
break
;
}
}
...
...
@@ -357,7 +357,7 @@ namespace Titanium.Web.Proxy
args
.
proxyRequest
.
AllowWriteStreamBuffering
=
true
;
try
{
int
totalbytesRead
=
0
;
int
bytesToRead
;
...
...
@@ -401,62 +401,31 @@ namespace Titanium.Web.Proxy
else
if
(
args
.
proxyRequest
.
SendChunked
)
{
args
.
proxyRequest
.
AllowWriteStreamBuffering
=
true
;
try
{
StringBuilder
sb
=
new
StringBuilder
();
byte
[]
byteRead
=
new
byte
[
1
];
while
(
true
)
{
var
chuchkHead
=
args
.
clientStreamReader
.
ReadLine
();
var
chunkSize
=
int
.
Parse
(
chuchkHead
,
System
.
Globalization
.
NumberStyles
.
HexNumber
);
args
.
clientStream
.
Read
(
byteRead
,
0
,
1
);
sb
.
Append
(
Encoding
.
ASCII
.
GetString
(
byteRead
));
if
(
chunkSize
!=
0
)
{
var
buffer
=
args
.
clientStreamReader
.
ReadBytes
(
chunkSize
);
postStream
.
Write
(
buffer
,
0
,
buffer
.
Length
);
if
(
sb
.
ToString
().
EndsWith
(
Environment
.
NewLine
))
var
chunkTrail
=
args
.
clientStreamReader
.
ReadLine
();
}
else
{
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
();
args
.
clientStreamReader
.
ReadLine
();
break
;
}
}
postStream
.
Close
();
}
catch
...
...
@@ -474,6 +443,6 @@ namespace Titanium.Web.Proxy
}
}
}
\ No newline at end of file
Titanium.Web.Proxy/ResponseHandler.cs
View file @
ee9a0929
...
...
@@ -38,10 +38,10 @@ namespace Titanium.Web.Proxy
{
if
(
args
.
serverResponse
!=
null
)
{
args
.
R
esponseHeaders
=
ReadResponseHeaders
(
args
.
serverResponse
);
args
.
r
esponseHeaders
=
ReadResponseHeaders
(
args
.
serverResponse
);
args
.
responseStream
=
args
.
serverResponse
.
GetResponseStream
();
if
(
BeforeResponse
!=
null
)
{
args
.
responseEncoding
=
args
.
serverResponse
.
GetEncoding
();
...
...
@@ -52,11 +52,11 @@ namespace Titanium.Web.Proxy
if
(
args
.
responseBodyRead
)
{
bool
isChunked
=
args
.
ResponseHeaders
.
Any
(
x
=>
x
.
Name
.
ToLower
()
==
"transfer-encoding"
)
==
false
?
false
:
args
.
ResponseHeaders
.
First
(
x
=>
x
.
Name
.
ToLower
()
==
"transfer-encoding"
).
Value
.
ToLower
()
==
"chunked"
?
true
:
false
;
var
contentEncoding
=
args
.
ResponseHeaders
.
FirstOrDefault
(
x
=>
x
.
Name
.
ToLower
()
==
"content-encoding"
)
;
bool
isChunked
=
args
.
serverResponse
.
GetResponseHeader
(
"transfer-encoding"
)
==
null
?
false
:
args
.
serverResponse
.
GetResponseHeader
(
"transfer-encoding"
).
ToLower
().
Contains
(
"chunked"
)
?
true
:
false
;
var
contentEncoding
=
args
.
serverResponse
.
ContentEncoding
;
if
(
contentEncoding
!=
null
)
switch
(
contentEncoding
.
Value
.
ToLower
())
switch
(
contentEncoding
.
ToLower
())
{
case
"gzip"
:
args
.
responseBody
=
CompressionHelper
.
CompressGzip
(
args
.
responseBody
);
...
...
@@ -68,20 +68,20 @@ namespace Titanium.Web.Proxy
args
.
responseBody
=
CompressionHelper
.
CompressZlib
(
args
.
responseBody
);
break
;
default
:
throw
new
Exception
(
"Specified content-encoding header is not supported"
)
;
break
;
}
WriteResponseStatus
(
args
.
serverResponse
.
ProtocolVersion
,
args
.
serverResponse
.
StatusCode
,
args
.
serverResponse
.
StatusDescription
,
args
.
clientStreamWriter
);
WriteResponseHeaders
(
args
.
clientStreamWriter
,
args
.
R
esponseHeaders
,
args
.
responseBody
.
Length
,
isChunked
);
WriteResponseHeaders
(
args
.
clientStreamWriter
,
args
.
r
esponseHeaders
,
args
.
responseBody
.
Length
,
isChunked
);
WriteResponseBody
(
args
.
clientStream
,
args
.
responseBody
,
isChunked
);
}
else
{
bool
isChunked
=
args
.
serverResponse
.
GetResponseHeader
(
"transfer-encoding"
)
==
null
?
false
:
args
.
serverResponse
.
GetResponseHeader
(
"transfer-encoding"
).
ToLower
()
==
"chunked"
?
true
:
false
;
bool
isChunked
=
args
.
serverResponse
.
GetResponseHeader
(
"transfer-encoding"
)
==
null
?
false
:
args
.
serverResponse
.
GetResponseHeader
(
"transfer-encoding"
).
ToLower
()
.
Contains
(
"chunked"
)
?
true
:
false
;
WriteResponseStatus
(
args
.
serverResponse
.
ProtocolVersion
,
args
.
serverResponse
.
StatusCode
,
args
.
serverResponse
.
StatusDescription
,
args
.
clientStreamWriter
);
WriteResponseHeaders
(
args
.
clientStreamWriter
,
args
.
R
esponseHeaders
);
WriteResponseHeaders
(
args
.
clientStreamWriter
,
args
.
r
esponseHeaders
);
WriteResponseBody
(
args
.
responseStream
,
args
.
clientStream
,
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