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
f69bed23
Commit
f69bed23
authored
Jan 01, 2016
by
titanium007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix connection cache
parent
8242536d
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
137 additions
and
68 deletions
+137
-68
SessionEventArgs.cs
Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
+2
-2
HttpWebClient.cs
Titanium.Web.Proxy/Http/HttpWebClient.cs
+17
-16
TcpConnectionManager.cs
Titanium.Web.Proxy/Http/TcpConnectionManager.cs
+17
-9
ProxyServer.cs
Titanium.Web.Proxy/ProxyServer.cs
+1
-1
RequestHandler.cs
Titanium.Web.Proxy/RequestHandler.cs
+31
-10
ResponseHandler.cs
Titanium.Web.Proxy/ResponseHandler.cs
+69
-30
No files found.
Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
View file @
f69bed23
...
@@ -93,8 +93,8 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -93,8 +93,8 @@ namespace Titanium.Web.Proxy.EventArguments
//if (ProxyRequest != null)
//if (ProxyRequest != null)
// ProxyRequest.Abort();
// ProxyRequest.Abort();
if
(
ResponseStream
!=
null
)
//
if (ResponseStream != null)
ResponseStream
.
Dispose
();
//
ResponseStream.Dispose();
//if (ServerResponse != null)
//if (ServerResponse != null)
// ServerResponse.Close();
// ServerResponse.Close();
...
...
Titanium.Web.Proxy/Http/HttpWebClient.cs
View file @
f69bed23
...
@@ -81,36 +81,42 @@ namespace Titanium.Web.Proxy.Http
...
@@ -81,36 +81,42 @@ namespace Titanium.Web.Proxy.Http
public
Request
Request
{
get
;
set
;
}
public
Request
Request
{
get
;
set
;
}
public
Response
Response
{
get
;
set
;
}
public
Response
Response
{
get
;
set
;
}
public
TcpClient
Client
{
get
;
set
;
}
public
TcpConnection
Client
{
get
;
set
;
}
public
void
SetConnection
(
TcpConnection
Connection
)
{
Client
=
Connection
;
ServerStreamReader
=
Client
.
ServerStreamReader
;
}
public
HttpWebSession
()
public
HttpWebSession
()
{
{
this
.
Request
=
new
Request
();
this
.
Request
=
new
Request
();
this
.
Response
=
new
Response
();
this
.
Response
=
new
Response
();
}
}
public
CustomBinaryReader
ServerStreamReader
{
get
;
set
;
}
public
CustomBinaryReader
ServerStreamReader
{
get
;
set
;
}
public
async
Task
SendRequest
()
public
async
Task
SendRequest
()
{
{
Stream
stream
=
Client
.
GetStream
()
;
Stream
stream
=
Client
.
Stream
;
StringBuilder
requestLines
=
new
StringBuilder
();
StringBuilder
requestLines
=
new
StringBuilder
();
requestLines
.
AppendLine
(
string
.
Join
(
" "
,
new
string
[
3
]
requestLines
.
AppendLine
(
string
.
Join
(
" "
,
new
string
[
3
]
{
{
this
.
Request
.
Method
,
this
.
Request
.
Method
,
this
.
Request
.
RequestUri
.
AbsolutePath
,
this
.
Request
.
RequestUri
.
PathAndQuery
,
this
.
Request
.
Version
this
.
Request
.
Version
}));
}));
foreach
(
HttpHeader
httpHeader
in
this
.
Request
.
RequestHeaders
)
foreach
(
HttpHeader
httpHeader
in
this
.
Request
.
RequestHeaders
)
{
{
requestLines
.
AppendLine
(
httpHeader
.
Name
+
':'
+
httpHeader
.
Value
);
requestLines
.
AppendLine
(
httpHeader
.
Name
+
':'
+
httpHeader
.
Value
);
}
}
requestLines
.
AppendLine
();
requestLines
.
AppendLine
();
requestLines
.
AppendLine
();
requestLines
.
AppendLine
();
...
@@ -121,10 +127,8 @@ namespace Titanium.Web.Proxy.Http
...
@@ -121,10 +127,8 @@ namespace Titanium.Web.Proxy.Http
}
}
public
void
ReceiveResponse
()
public
void
ReceiveResponse
()
{
{
Stream
stream
=
Client
.
GetStream
();
var
httpResult
=
ServerStreamReader
.
ReadLine
().
Split
(
new
char
[]
{
' '
},
3
);
ServerStreamReader
=
new
CustomBinaryReader
(
stream
,
Encoding
.
ASCII
);
var
httpResult
=
ServerStreamReader
.
ReadLine
().
Split
(
' '
);
var
httpVersion
=
httpResult
[
0
];
var
httpVersion
=
httpResult
[
0
];
...
@@ -141,17 +145,14 @@ namespace Titanium.Web.Proxy.Http
...
@@ -141,17 +145,14 @@ namespace Titanium.Web.Proxy.Http
this
.
Response
.
ResponseProtocolVersion
=
version
;
this
.
Response
.
ResponseProtocolVersion
=
version
;
this
.
Response
.
ResponseStatusCode
=
httpResult
[
1
];
this
.
Response
.
ResponseStatusCode
=
httpResult
[
1
];
string
status
=
httpResult
[
2
];
string
status
=
httpResult
[
2
];
for
(
int
i
=
3
;
i
<
httpResult
.
Length
;
i
++)
{
status
=
status
+
Space
+
httpResult
[
i
];
}
this
.
Response
.
ResponseStatusDescription
=
status
;
this
.
Response
.
ResponseStatusDescription
=
status
;
List
<
string
>
responseLines
=
ServerStreamReader
.
ReadAllLines
();
List
<
string
>
responseLines
=
ServerStreamReader
.
ReadAllLines
();
for
(
int
index
=
0
;
index
<
responseLines
.
Count
;
++
index
)
for
(
int
index
=
0
;
index
<
responseLines
.
Count
;
++
index
)
{
{
string
[]
strArray
=
responseLines
[
index
].
Split
(
':'
);
string
[]
strArray
=
responseLines
[
index
].
Split
(
new
char
[]
{
':'
},
2
);
this
.
Response
.
ResponseHeaders
.
Add
(
new
HttpHeader
(
strArray
[
0
],
strArray
[
1
]));
this
.
Response
.
ResponseHeaders
.
Add
(
new
HttpHeader
(
strArray
[
0
],
strArray
[
1
]));
}
}
}
}
...
...
Titanium.Web.Proxy/Http/TcpConnectionManager.cs
View file @
f69bed23
...
@@ -7,25 +7,32 @@ using System.Collections.Concurrent;
...
@@ -7,25 +7,32 @@ using System.Collections.Concurrent;
using
System.Threading.Tasks
;
using
System.Threading.Tasks
;
using
System.IO
;
using
System.IO
;
using
System.Net.Security
;
using
System.Net.Security
;
using
Titanium.Web.Proxy.Helpers
;
namespace
Titanium.Web.Proxy.Http
namespace
Titanium.Web.Proxy.Http
{
{
public
class
TcpConnection
{
public
TcpClient
Client
{
get
;
set
;
}
public
CustomBinaryReader
ServerStreamReader
{
get
;
set
;
}
public
Stream
Stream
{
get
;
set
;
}
}
internal
class
TcpConnectionManager
internal
class
TcpConnectionManager
{
{
static
ConcurrentDictionary
<
string
,
ConcurrentStack
<
TcpC
lient
>>
ConnectionCache
=
new
ConcurrentDictionary
<
string
,
ConcurrentStack
<
TcpClient
>>();
static
ConcurrentDictionary
<
string
,
ConcurrentStack
<
TcpC
onnection
>>
ConnectionCache
=
new
ConcurrentDictionary
<
string
,
ConcurrentStack
<
TcpConnection
>>();
public
static
async
Task
<
TcpC
lient
>
GetClient
(
string
Hostname
,
int
port
,
bool
IsSecure
)
public
static
async
Task
<
TcpC
onnection
>
GetClient
(
string
Hostname
,
int
port
,
bool
IsSecure
)
{
{
var
key
=
string
.
Concat
(
Hostname
,
":"
,
port
,
":"
,
IsSecure
);
var
key
=
string
.
Concat
(
Hostname
,
":"
,
port
,
":"
,
IsSecure
);
ConcurrentStack
<
TcpC
lient
>
connections
;
ConcurrentStack
<
TcpC
onnection
>
connections
;
if
(!
ConnectionCache
.
TryGetValue
(
key
,
out
connections
))
if
(!
ConnectionCache
.
TryGetValue
(
key
,
out
connections
))
{
{
return
await
CreateClient
(
Hostname
,
port
,
IsSecure
);
return
await
CreateClient
(
Hostname
,
port
,
IsSecure
);
}
}
TcpC
lient
client
;
TcpC
onnection
client
;
if
(!
connections
.
TryPop
(
out
client
))
if
(!
connections
.
TryPop
(
out
client
))
{
{
return
await
CreateClient
(
Hostname
,
port
,
IsSecure
);
return
await
CreateClient
(
Hostname
,
port
,
IsSecure
);
...
@@ -33,7 +40,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -33,7 +40,7 @@ namespace Titanium.Web.Proxy.Http
return
client
;
return
client
;
}
}
private
static
async
Task
<
TcpC
lient
>
CreateClient
(
string
Hostname
,
int
port
,
bool
IsSecure
)
private
static
async
Task
<
TcpC
onnection
>
CreateClient
(
string
Hostname
,
int
port
,
bool
IsSecure
)
{
{
var
client
=
new
TcpClient
(
Hostname
,
port
);
var
client
=
new
TcpClient
(
Hostname
,
port
);
var
stream
=
(
Stream
)
client
.
GetStream
();
var
stream
=
(
Stream
)
client
.
GetStream
();
...
@@ -54,17 +61,18 @@ namespace Titanium.Web.Proxy.Http
...
@@ -54,17 +61,18 @@ namespace Titanium.Web.Proxy.Http
throw
;
throw
;
}
}
}
}
return
client
;
return
new
TcpConnection
()
{
Client
=
client
,
ServerStreamReader
=
new
CustomBinaryReader
(
stream
,
Encoding
.
ASCII
),
Stream
=
stream
};
}
}
public
static
void
AddClient
(
string
Hostname
,
int
port
,
bool
IsSecure
,
TcpC
lient
Client
)
public
static
void
AddClient
(
string
Hostname
,
int
port
,
bool
IsSecure
,
TcpC
onnection
Client
)
{
{
var
key
=
string
.
Concat
(
Hostname
,
":"
,
port
,
":"
,
IsSecure
);
var
key
=
string
.
Concat
(
Hostname
,
":"
,
port
,
":"
,
IsSecure
);
ConcurrentStack
<
TcpC
lient
>
connections
;
ConcurrentStack
<
TcpC
onnection
>
connections
;
if
(!
ConnectionCache
.
TryGetValue
(
key
,
out
connections
))
if
(!
ConnectionCache
.
TryGetValue
(
key
,
out
connections
))
{
{
connections
=
new
ConcurrentStack
<
TcpC
lient
>();
connections
=
new
ConcurrentStack
<
TcpC
onnection
>();
connections
.
Push
(
Client
);
connections
.
Push
(
Client
);
ConnectionCache
.
TryAdd
(
key
,
connections
);
ConnectionCache
.
TryAdd
(
key
,
connections
);
}
}
...
...
Titanium.Web.Proxy/ProxyServer.cs
View file @
f69bed23
...
@@ -25,7 +25,7 @@ namespace Titanium.Web.Proxy
...
@@ -25,7 +25,7 @@ namespace Titanium.Web.Proxy
private
static
readonly
Regex
CookieSplitRegEx
=
new
Regex
(
@",(?! )"
);
private
static
readonly
Regex
CookieSplitRegEx
=
new
Regex
(
@",(?! )"
);
private
static
readonly
byte
[]
ChunkTrail
=
Encoding
.
ASCII
.
GetBytes
(
Environment
.
NewLine
);
private
static
readonly
byte
[]
NewLineBytes
=
Encoding
.
ASCII
.
GetBytes
(
Environment
.
NewLine
);
private
static
readonly
byte
[]
ChunkEnd
=
private
static
readonly
byte
[]
ChunkEnd
=
Encoding
.
ASCII
.
GetBytes
(
0.
ToString
(
"x2"
)
+
Environment
.
NewLine
+
Environment
.
NewLine
);
Encoding
.
ASCII
.
GetBytes
(
0.
ToString
(
"x2"
)
+
Environment
.
NewLine
+
Environment
.
NewLine
);
...
...
Titanium.Web.Proxy/RequestHandler.cs
View file @
f69bed23
...
@@ -30,6 +30,7 @@ namespace Titanium.Web.Proxy
...
@@ -30,6 +30,7 @@ namespace Titanium.Web.Proxy
try
try
{
{
//read the first line HTTP command
//read the first line HTTP command
var
httpCmd
=
clientStreamReader
.
ReadLine
();
var
httpCmd
=
clientStreamReader
.
ReadLine
();
if
(
string
.
IsNullOrEmpty
(
httpCmd
))
if
(
string
.
IsNullOrEmpty
(
httpCmd
))
...
@@ -156,7 +157,7 @@ namespace Titanium.Web.Proxy
...
@@ -156,7 +157,7 @@ namespace Titanium.Web.Proxy
while
(!
string
.
IsNullOrEmpty
(
tmpLine
=
clientStreamReader
.
ReadLine
()))
while
(!
string
.
IsNullOrEmpty
(
tmpLine
=
clientStreamReader
.
ReadLine
()))
{
{
var
header
=
tmpLine
.
Split
(
ColonSpaceSplit
,
2
,
StringSplitOptions
.
None
);
var
header
=
tmpLine
.
Split
(
new
char
[]
{
':'
},
2
);
args
.
RequestHeaders
.
Add
(
new
HttpHeader
(
header
[
0
],
header
[
1
]));
args
.
RequestHeaders
.
Add
(
new
HttpHeader
(
header
[
0
],
header
[
1
]));
}
}
...
@@ -175,10 +176,11 @@ namespace Titanium.Web.Proxy
...
@@ -175,10 +176,11 @@ namespace Titanium.Web.Proxy
}
}
}
}
//construct the web request that we are going to issue on behalf of the client.
args
.
ProxySession
=
new
Http
.
HttpWebSession
();
args
.
ProxySession
=
new
Http
.
HttpWebSession
();
args
.
ProxySession
.
Request
.
RequestUri
=
httpRemoteUri
;
args
.
ProxySession
.
Request
.
RequestUri
=
httpRemoteUri
;
//args.ProxyRequest.Proxy = null;
//args.ProxyRequest.Proxy = null;
//args.ProxyRequest.UseDefaultCredentials = true;
//args.ProxyRequest.UseDefaultCredentials = true;
args
.
ProxySession
.
Request
.
Method
=
httpMethod
;
args
.
ProxySession
.
Request
.
Method
=
httpMethod
;
...
@@ -197,8 +199,8 @@ namespace Titanium.Web.Proxy
...
@@ -197,8 +199,8 @@ namespace Titanium.Web.Proxy
//args.RequestIsAlive = args.ProxyRequest.KeepAlive;
//args.RequestIsAlive = args.ProxyRequest.KeepAlive;
//args.ProxyRequest.AllowWriteStreamBuffering = true;
//args.ProxyRequest.AllowWriteStreamBuffering = true;
args
.
Client
=
await
TcpConnectionManager
.
GetClient
(
args
.
ProxySession
.
Request
.
RequestUri
.
Host
,
args
.
ProxySession
.
Request
.
RequestUri
.
Port
,
args
.
IsHttps
);
args
.
ProxySession
.
Client
=
args
.
Client
;
//If requested interception
//If requested interception
if
(
BeforeRequest
!=
null
)
if
(
BeforeRequest
!=
null
)
{
{
...
@@ -215,7 +217,9 @@ namespace Titanium.Web.Proxy
...
@@ -215,7 +217,9 @@ namespace Titanium.Web.Proxy
}
}
SetRequestHeaders
(
args
.
RequestHeaders
,
args
.
ProxySession
);
SetRequestHeaders
(
args
.
RequestHeaders
,
args
.
ProxySession
);
//construct the web request that we are going to issue on behalf of the client.
var
connection
=
await
TcpConnectionManager
.
GetClient
(
args
.
ProxySession
.
Request
.
RequestUri
.
Host
,
args
.
ProxySession
.
Request
.
RequestUri
.
Port
,
args
.
IsHttps
);
args
.
ProxySession
.
SetConnection
(
connection
);
await
args
.
ProxySession
.
SendRequest
();
await
args
.
ProxySession
.
SendRequest
();
//If request was modified by user
//If request was modified by user
...
@@ -233,8 +237,8 @@ namespace Titanium.Web.Proxy
...
@@ -233,8 +237,8 @@ namespace Titanium.Web.Proxy
SendClientRequestBody
(
args
);
SendClientRequestBody
(
args
);
}
}
}
}
await
HandleHttpSessionResponse
(
args
);
HandleHttpSessionResponse
(
args
);
//if connection is closing exit
//if connection is closing exit
if
(
args
.
ResponseHeaders
.
Any
(
x
=>
x
.
Name
.
ToLower
()
==
"connection"
&&
x
.
Value
.
ToLower
()
==
"close"
))
if
(
args
.
ResponseHeaders
.
Any
(
x
=>
x
.
Name
.
ToLower
()
==
"connection"
&&
x
.
Value
.
ToLower
()
==
"close"
))
...
@@ -243,7 +247,7 @@ namespace Titanium.Web.Proxy
...
@@ -243,7 +247,7 @@ namespace Titanium.Web.Proxy
return
;
return
;
}
}
//
TcpConnectionManager.AddClient(args.ProxySession.Request.RequestUri.Host, args.ProxySession.Request.RequestUri.Port, args.IsHttps, args.ProxySession.Client);
TcpConnectionManager
.
AddClient
(
args
.
ProxySession
.
Request
.
RequestUri
.
Host
,
args
.
ProxySession
.
Request
.
RequestUri
.
Port
,
args
.
IsHttps
,
args
.
ProxySession
.
Client
);
// read the next request
// read the next request
httpCmd
=
clientStreamReader
.
ReadLine
();
httpCmd
=
clientStreamReader
.
ReadLine
();
...
@@ -351,10 +355,27 @@ namespace Titanium.Web.Proxy
...
@@ -351,10 +355,27 @@ namespace Titanium.Web.Proxy
break
;
break
;
}
}
}
}
FixRequestProxyHeaders
(
requestHeaders
);
webRequest
.
Request
.
RequestHeaders
=
requestHeaders
;
webRequest
.
Request
.
RequestHeaders
=
requestHeaders
;
}
}
private
static
void
FixRequestProxyHeaders
(
List
<
HttpHeader
>
headers
)
{
//If proxy-connection close was returned inform to close the connection
var
proxyHeader
=
headers
.
FirstOrDefault
(
x
=>
x
.
Name
.
ToLower
()
==
"proxy-connection"
);
var
connectionheader
=
headers
.
FirstOrDefault
(
x
=>
x
.
Name
.
ToLower
()
==
"connection"
);
if
(
proxyHeader
!=
null
)
if
(
connectionheader
==
null
)
{
headers
.
Add
(
new
HttpHeader
(
"connection"
,
proxyHeader
.
Value
));
}
else
{
connectionheader
.
Value
=
proxyHeader
.
Value
;
}
headers
.
RemoveAll
(
x
=>
x
.
Name
.
ToLower
()
==
"proxy-connection"
);
}
//This is called when the request is PUT/POST to read the body
//This is called when the request is PUT/POST to read the body
private
static
void
SendClientRequestBody
(
SessionEventArgs
args
)
private
static
void
SendClientRequestBody
(
SessionEventArgs
args
)
{
{
...
...
Titanium.Web.Proxy/ResponseHandler.cs
View file @
f69bed23
using
System
;
using
System
;
using
System.Collections.Generic
;
using
System.Collections.Generic
;
using
System.Globalization
;
using
System.IO
;
using
System.IO
;
using
System.Linq
;
using
System.Linq
;
using
System.Net
;
using
System.Net
;
...
@@ -17,10 +18,10 @@ namespace Titanium.Web.Proxy
...
@@ -17,10 +18,10 @@ namespace Titanium.Web.Proxy
partial
class
ProxyServer
partial
class
ProxyServer
{
{
//Called asynchronously when a request was successfully and we received the response
//Called asynchronously when a request was successfully and we received the response
private
static
async
Task
HandleHttpSessionResponse
(
SessionEventArgs
args
)
private
static
void
HandleHttpSessionResponse
(
SessionEventArgs
args
)
{
{
args
.
ProxySession
.
ReceiveResponse
();
args
.
ProxySession
.
ReceiveResponse
();
try
try
{
{
...
@@ -63,12 +64,14 @@ namespace Titanium.Web.Proxy
...
@@ -63,12 +64,14 @@ namespace Titanium.Web.Proxy
}
}
else
else
{
{
// var isChunked = args.ProxySession
.ResponseHeaders.Any(x => x.Name.ToLower() == "transfer-encoding" && x.Value.ToLower().Contains("chunked"));
var
isChunked
=
args
.
ProxySession
.
Response
.
ResponseHeaders
.
Any
(
x
=>
x
.
Name
.
ToLower
()
==
"transfer-encoding"
&&
x
.
Value
.
ToLower
().
Contains
(
"chunked"
));
WriteResponseStatus
(
args
.
ProxySession
.
Response
.
ResponseProtocolVersion
,
args
.
ProxySession
.
Response
.
ResponseStatusCode
,
WriteResponseStatus
(
args
.
ProxySession
.
Response
.
ResponseProtocolVersion
,
args
.
ProxySession
.
Response
.
ResponseStatusCode
,
args
.
ProxySession
.
Response
.
ResponseStatusDescription
,
args
.
ClientStreamWriter
);
args
.
ProxySession
.
Response
.
ResponseStatusDescription
,
args
.
ClientStreamWriter
);
WriteResponseHeaders
(
args
.
ClientStreamWriter
,
args
.
ResponseHeaders
);
WriteResponseHeaders
(
args
.
ClientStreamWriter
,
args
.
ResponseHeaders
);
WriteResponseBody
(
args
.
ResponseStream
,
args
.
ClientStream
,
false
,
args
.
ProxySession
.
Response
.
ContentLength
);
if
(
isChunked
||
args
.
ProxySession
.
Response
.
ContentLength
>
0
)
WriteResponseBody
(
args
.
ResponseStream
,
args
.
ClientStream
,
isChunked
,
args
.
ProxySession
.
Response
.
ContentLength
);
}
}
args
.
ClientStream
.
Flush
();
args
.
ClientStream
.
Flush
();
...
@@ -90,6 +93,10 @@ namespace Titanium.Web.Proxy
...
@@ -90,6 +93,10 @@ namespace Titanium.Web.Proxy
{
{
switch
(
response
.
Response
.
ResponseHeaders
[
i
].
Name
.
ToLower
())
switch
(
response
.
Response
.
ResponseHeaders
[
i
].
Name
.
ToLower
())
{
{
case
"content-length"
:
response
.
Response
.
ContentLength
=
int
.
Parse
(
response
.
Response
.
ResponseHeaders
[
i
].
Value
);
break
;
case
"content-encoding"
:
case
"content-encoding"
:
response
.
Response
.
ResponseContentEncoding
=
response
.
Response
.
ResponseHeaders
[
i
].
Value
;
response
.
Response
.
ResponseContentEncoding
=
response
.
Response
.
ResponseHeaders
[
i
].
Value
;
break
;
break
;
...
@@ -105,14 +112,10 @@ namespace Titanium.Web.Proxy
...
@@ -105,14 +112,10 @@ namespace Titanium.Web.Proxy
break
;
break
;
case
"connection"
:
break
;
default
:
default
:
break
;
break
;
}
}
}
}
// response.ResponseHeaders.RemoveAll(x => x.Name.ToLower() == "connection");
return
response
.
Response
.
ResponseHeaders
;
return
response
.
Response
.
ResponseHeaders
;
}
}
...
@@ -128,7 +131,7 @@ namespace Titanium.Web.Proxy
...
@@ -128,7 +131,7 @@ namespace Titanium.Web.Proxy
{
{
if
(
headers
!=
null
)
if
(
headers
!=
null
)
{
{
//Fix
ProxyHeaders(headers);
FixResponse
ProxyHeaders
(
headers
);
foreach
(
var
header
in
headers
)
foreach
(
var
header
in
headers
)
{
{
...
@@ -139,23 +142,29 @@ namespace Titanium.Web.Proxy
...
@@ -139,23 +142,29 @@ namespace Titanium.Web.Proxy
responseWriter
.
WriteLine
();
responseWriter
.
WriteLine
();
responseWriter
.
Flush
();
responseWriter
.
Flush
();
}
}
private
static
void
FixProxyHeaders
(
List
<
HttpHeader
>
headers
)
private
static
void
Fix
Response
ProxyHeaders
(
List
<
HttpHeader
>
headers
)
{
{
//If proxy-connection close was returned inform to close the connection
//If proxy-connection close was returned inform to close the connection
if
(
headers
.
Any
(
x
=>
x
.
Name
.
ToLower
()
==
"proxy-connection"
&&
x
.
Value
.
ToLower
()
==
"close"
))
var
proxyHeader
=
headers
.
FirstOrDefault
(
x
=>
x
.
Name
.
ToLower
()
==
"proxy-connection"
);
if
(
headers
.
Any
(
x
=>
x
.
Name
.
ToLower
()
==
"connection"
)
==
false
)
var
connectionHeader
=
headers
.
FirstOrDefault
(
x
=>
x
.
Name
.
ToLower
()
==
"connection"
);
if
(
proxyHeader
!=
null
)
if
(
connectionHeader
==
null
)
{
{
headers
.
Add
(
new
HttpHeader
(
"connection"
,
"close"
));
headers
.
Add
(
new
HttpHeader
(
"connection"
,
proxyHeader
.
Value
));
headers
.
RemoveAll
(
x
=>
x
.
Name
.
ToLower
()
==
"proxy-connection"
);
}
}
else
else
headers
.
Find
(
x
=>
x
.
Name
.
ToLower
()
==
"connection"
).
Value
=
"close"
;
{
connectionHeader
.
Value
=
"close"
;
}
headers
.
RemoveAll
(
x
=>
x
.
Name
.
ToLower
()
==
"proxy-connection"
);
}
}
private
static
void
WriteResponseHeaders
(
StreamWriter
responseWriter
,
List
<
HttpHeader
>
headers
,
int
length
,
private
static
void
WriteResponseHeaders
(
StreamWriter
responseWriter
,
List
<
HttpHeader
>
headers
,
int
length
,
bool
isChunked
)
bool
isChunked
)
{
{
FixProxyHeaders
(
headers
);
Fix
Response
ProxyHeaders
(
headers
);
if
(!
isChunked
)
if
(!
isChunked
)
{
{
...
@@ -194,12 +203,27 @@ namespace Titanium.Web.Proxy
...
@@ -194,12 +203,27 @@ namespace Titanium.Web.Proxy
{
{
if
(!
isChunked
)
if
(!
isChunked
)
{
{
int
bytesToRead
=
BUFFER_SIZE
;
if
(
BodyLength
<
BUFFER_SIZE
)
bytesToRead
=
BodyLength
;
var
buffer
=
new
byte
[
BUFFER_SIZE
];
var
buffer
=
new
byte
[
BUFFER_SIZE
];
int
bytesRead
;
var
bytesRead
=
0
;
while
((
bytesRead
=
inStream
.
Read
(
buffer
,
0
,
buffer
.
Length
))
>
0
)
var
totalBytesRead
=
0
;
while
((
bytesRead
+=
inStream
.
Read
(
buffer
,
0
,
bytesToRead
))
>
0
)
{
{
outStream
.
Write
(
buffer
,
0
,
bytesRead
);
outStream
.
Write
(
buffer
,
0
,
bytesRead
);
totalBytesRead
+=
bytesRead
;
if
(
totalBytesRead
==
BodyLength
)
break
;
bytesRead
=
0
;
var
remainingBytes
=
(
BodyLength
-
totalBytesRead
);
bytesToRead
=
remainingBytes
>
BUFFER_SIZE
?
BUFFER_SIZE
:
remainingBytes
;
}
}
}
}
else
else
...
@@ -209,20 +233,35 @@ namespace Titanium.Web.Proxy
...
@@ -209,20 +233,35 @@ namespace Titanium.Web.Proxy
//Send chunked response
//Send chunked response
private
static
void
WriteResponseBodyChunked
(
Stream
inStream
,
Stream
outStream
)
private
static
void
WriteResponseBodyChunked
(
Stream
inStream
,
Stream
outStream
)
{
{
var
buffer
=
new
byte
[
BUFFER_SIZE
];
var
inStreamReader
=
new
CustomBinaryReader
(
inStream
,
Encoding
.
ASCII
);
while
(
true
)
int
bytesRead
;
while
((
bytesRead
=
inStream
.
Read
(
buffer
,
0
,
buffer
.
Length
))
>
0
)
{
{
var
chunkHead
=
Encoding
.
ASCII
.
GetBytes
(
bytesRead
.
ToString
(
"x2"
));
var
chuchkHead
=
inStreamReader
.
ReadLine
();
var
chunkSize
=
int
.
Parse
(
chuchkHead
,
NumberStyles
.
HexNumber
);
if
(
chunkSize
!=
0
)
{
var
buffer
=
inStreamReader
.
ReadBytes
(
chunkSize
);
var
chunkHead
=
Encoding
.
ASCII
.
GetBytes
(
chunkSize
.
ToString
(
"x2"
));
outStream
.
Write
(
chunkHead
,
0
,
chunkHead
.
Length
);
outStream
.
Write
(
NewLineBytes
,
0
,
NewLineBytes
.
Length
);
outStream
.
Write
(
buffer
,
0
,
chunkSize
);
outStream
.
Write
(
NewLineBytes
,
0
,
NewLineBytes
.
Length
);
outStream
.
Write
(
chunkHead
,
0
,
chunkHead
.
Length
);
inStreamReader
.
ReadLine
();
outStream
.
Write
(
ChunkTrail
,
0
,
ChunkTrail
.
Length
);
}
outStream
.
Write
(
buffer
,
0
,
bytesRead
);
else
outStream
.
Write
(
ChunkTrail
,
0
,
ChunkTrail
.
Length
);
{
inStreamReader
.
ReadLine
();
outStream
.
Write
(
ChunkEnd
,
0
,
ChunkEnd
.
Length
);
break
;
}
}
}
outStream
.
Write
(
ChunkEnd
,
0
,
ChunkEnd
.
Length
);
}
}
private
static
void
WriteResponseBodyChunked
(
byte
[]
data
,
Stream
outStream
)
private
static
void
WriteResponseBodyChunked
(
byte
[]
data
,
Stream
outStream
)
...
@@ -230,9 +269,9 @@ namespace Titanium.Web.Proxy
...
@@ -230,9 +269,9 @@ namespace Titanium.Web.Proxy
var
chunkHead
=
Encoding
.
ASCII
.
GetBytes
(
data
.
Length
.
ToString
(
"x2"
));
var
chunkHead
=
Encoding
.
ASCII
.
GetBytes
(
data
.
Length
.
ToString
(
"x2"
));
outStream
.
Write
(
chunkHead
,
0
,
chunkHead
.
Length
);
outStream
.
Write
(
chunkHead
,
0
,
chunkHead
.
Length
);
outStream
.
Write
(
ChunkTrail
,
0
,
ChunkTrail
.
Length
);
outStream
.
Write
(
NewLineBytes
,
0
,
NewLineBytes
.
Length
);
outStream
.
Write
(
data
,
0
,
data
.
Length
);
outStream
.
Write
(
data
,
0
,
data
.
Length
);
outStream
.
Write
(
ChunkTrail
,
0
,
ChunkTrail
.
Length
);
outStream
.
Write
(
NewLineBytes
,
0
,
NewLineBytes
.
Length
);
outStream
.
Write
(
ChunkEnd
,
0
,
ChunkEnd
.
Length
);
outStream
.
Write
(
ChunkEnd
,
0
,
ChunkEnd
.
Length
);
}
}
...
...
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