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
b0607472
Commit
b0607472
authored
May 14, 2017
by
Honfika
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Performance improvements: Buffered stream, avoid string concatenation in header writer
parent
26338fba
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
497 additions
and
31 deletions
+497
-31
CustomBinaryReader.cs
Titanium.Web.Proxy/Helpers/CustomBinaryReader.cs
+29
-9
CustomBufferedStream.cs
Titanium.Web.Proxy/Helpers/CustomBufferedStream.cs
+440
-0
HttpHeader.cs
Titanium.Web.Proxy/Models/HttpHeader.cs
+10
-0
TcpConnectionFactory.cs
Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs
+6
-7
RequestHandler.cs
Titanium.Web.Proxy/RequestHandler.cs
+8
-12
ResponseHandler.cs
Titanium.Web.Proxy/ResponseHandler.cs
+2
-3
Titanium.Web.Proxy.csproj
Titanium.Web.Proxy/Titanium.Web.Proxy.csproj
+2
-0
No files found.
Titanium.Web.Proxy/Helpers/CustomBinaryReader.cs
View file @
b0607472
...
@@ -14,18 +14,33 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -14,18 +14,33 @@ namespace Titanium.Web.Proxy.Helpers
/// </summary>
/// </summary>
internal
class
CustomBinaryReader
:
IDisposable
internal
class
CustomBinaryReader
:
IDisposable
{
{
private
readonly
Stream
stream
;
private
readonly
CustomBufferedStream
stream
;
private
readonly
int
bufferSize
;
private
readonly
Encoding
encoding
;
private
readonly
Encoding
encoding
;
private
readonly
byte
[]
buffer
;
internal
CustomBinaryReader
(
Stream
stream
,
int
bufferSize
)
[
ThreadStatic
]
private
static
byte
[]
staticBuffer
;
private
byte
[]
buffer
{
get
{
if
(
staticBuffer
==
null
||
staticBuffer
.
Length
!=
bufferSize
)
{
staticBuffer
=
new
byte
[
bufferSize
];
}
return
staticBuffer
;
}
}
internal
CustomBinaryReader
(
CustomBufferedStream
stream
,
int
bufferSize
)
{
{
this
.
stream
=
stream
;
this
.
stream
=
stream
;
this
.
bufferSize
=
bufferSize
;
//default to UTF-8
//default to UTF-8
encoding
=
Encoding
.
UTF8
;
encoding
=
Encoding
.
UTF8
;
buffer
=
new
byte
[
bufferSize
];
}
}
internal
Stream
BaseStream
=>
stream
;
internal
Stream
BaseStream
=>
stream
;
...
@@ -40,12 +55,13 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -40,12 +55,13 @@ namespace Titanium.Web.Proxy.Helpers
int
bufferDataLength
=
0
;
int
bufferDataLength
=
0
;
// try to use the
instance
buffer, usually it is enough
// try to use the
thread static
buffer, usually it is enough
var
buffer
=
this
.
buffer
;
var
buffer
=
this
.
buffer
;
while
(
await
stream
.
ReadAsync
(
buffer
,
bufferDataLength
,
1
)
>
0
)
while
(
stream
.
DataAvailable
||
await
stream
.
FillBufferAsync
()
)
{
{
var
newChar
=
buffer
[
bufferDataLength
];
var
newChar
=
stream
.
ReadByteFromBuffer
();
buffer
[
bufferDataLength
]
=
newChar
;
//if new line
//if new line
if
(
lastChar
==
'\r'
&&
newChar
==
'\n'
)
if
(
lastChar
==
'\r'
&&
newChar
==
'\n'
)
...
@@ -111,7 +127,11 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -111,7 +127,11 @@ namespace Titanium.Web.Proxy.Helpers
if
(
totalBytesToRead
<
bufferSize
)
if
(
totalBytesToRead
<
bufferSize
)
bytesToRead
=
(
int
)
totalBytesToRead
;
bytesToRead
=
(
int
)
totalBytesToRead
;
var
buffer
=
bytesToRead
>
this
.
buffer
.
Length
?
new
byte
[
bytesToRead
]
:
this
.
buffer
;
var
buffer
=
this
.
buffer
;
if
(
bytesToRead
>
buffer
.
Length
)
{
buffer
=
new
byte
[
bytesToRead
];
}
int
bytesRead
;
int
bytesRead
;
var
totalBytesRead
=
0
;
var
totalBytesRead
=
0
;
...
...
Titanium.Web.Proxy/Helpers/CustomBufferedStream.cs
0 → 100644
View file @
b0607472
This diff is collapsed.
Click to expand it.
Titanium.Web.Proxy/Models/HttpHeader.cs
View file @
b0607472
using
System
;
using
System
;
using
System.IO
;
using
System.Threading.Tasks
;
namespace
Titanium.Web.Proxy.Models
namespace
Titanium.Web.Proxy.Models
{
{
...
@@ -28,6 +30,7 @@ namespace Titanium.Web.Proxy.Models
...
@@ -28,6 +30,7 @@ namespace Titanium.Web.Proxy.Models
/// Header Name.
/// Header Name.
/// </summary>
/// </summary>
public
string
Name
{
get
;
set
;
}
public
string
Name
{
get
;
set
;
}
/// <summary>
/// <summary>
/// Header Value.
/// Header Value.
/// </summary>
/// </summary>
...
@@ -41,5 +44,12 @@ namespace Titanium.Web.Proxy.Models
...
@@ -41,5 +44,12 @@ namespace Titanium.Web.Proxy.Models
{
{
return
$"
{
Name
}
:
{
Value
}
"
;
return
$"
{
Name
}
:
{
Value
}
"
;
}
}
internal
async
Task
WriteToStream
(
StreamWriter
writer
)
{
await
writer
.
WriteAsync
(
Name
);
await
writer
.
WriteAsync
(
": "
);
await
writer
.
WriteLineAsync
(
Value
);
}
}
}
}
}
\ No newline at end of file
Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs
View file @
b0607472
...
@@ -45,7 +45,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
...
@@ -45,7 +45,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
Stream
clientStream
,
IPEndPoint
upStreamEndPoint
)
Stream
clientStream
,
IPEndPoint
upStreamEndPoint
)
{
{
TcpClient
client
;
TcpClient
client
;
Stream
stream
;
CustomBuffered
Stream
stream
;
bool
isLocalhost
=
(
externalHttpsProxy
==
null
&&
externalHttpProxy
==
null
)
?
false
:
NetworkHelper
.
IsLocalIpAddress
(
remoteHostName
);
bool
isLocalhost
=
(
externalHttpsProxy
==
null
&&
externalHttpProxy
==
null
)
?
false
:
NetworkHelper
.
IsLocalIpAddress
(
remoteHostName
);
...
@@ -61,7 +61,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
...
@@ -61,7 +61,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
{
{
client
=
new
TcpClient
(
upStreamEndPoint
);
client
=
new
TcpClient
(
upStreamEndPoint
);
await
client
.
ConnectAsync
(
externalHttpsProxy
.
HostName
,
externalHttpsProxy
.
Port
);
await
client
.
ConnectAsync
(
externalHttpsProxy
.
HostName
,
externalHttpsProxy
.
Port
);
stream
=
client
.
GetStream
(
);
stream
=
new
CustomBufferedStream
(
client
.
GetStream
(),
bufferSize
);
using
(
var
writer
=
new
StreamWriter
(
stream
,
Encoding
.
ASCII
,
bufferSize
,
true
)
{
NewLine
=
ProxyConstants
.
NewLine
})
using
(
var
writer
=
new
StreamWriter
(
stream
,
Encoding
.
ASCII
,
bufferSize
,
true
)
{
NewLine
=
ProxyConstants
.
NewLine
})
{
{
...
@@ -83,7 +83,6 @@ namespace Titanium.Web.Proxy.Network.Tcp
...
@@ -83,7 +83,6 @@ namespace Titanium.Web.Proxy.Network.Tcp
{
{
var
result
=
await
reader
.
ReadLineAsync
();
var
result
=
await
reader
.
ReadLineAsync
();
if
(!
new
[]
{
"200 OK"
,
"connection established"
}.
Any
(
s
=>
result
.
ContainsIgnoreCase
(
s
)))
if
(!
new
[]
{
"200 OK"
,
"connection established"
}.
Any
(
s
=>
result
.
ContainsIgnoreCase
(
s
)))
{
{
throw
new
Exception
(
"Upstream proxy failed to create a secure tunnel"
);
throw
new
Exception
(
"Upstream proxy failed to create a secure tunnel"
);
...
@@ -96,7 +95,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
...
@@ -96,7 +95,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
{
{
client
=
new
TcpClient
(
upStreamEndPoint
);
client
=
new
TcpClient
(
upStreamEndPoint
);
await
client
.
ConnectAsync
(
remoteHostName
,
remotePort
);
await
client
.
ConnectAsync
(
remoteHostName
,
remotePort
);
stream
=
client
.
GetStream
(
);
stream
=
new
CustomBufferedStream
(
client
.
GetStream
(),
bufferSize
);
}
}
try
try
...
@@ -106,7 +105,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
...
@@ -106,7 +105,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
await
sslStream
.
AuthenticateAsClientAsync
(
remoteHostName
,
null
,
supportedSslProtocols
,
false
);
await
sslStream
.
AuthenticateAsClientAsync
(
remoteHostName
,
null
,
supportedSslProtocols
,
false
);
stream
=
sslStream
;
stream
=
new
CustomBufferedStream
(
sslStream
,
bufferSize
)
;
}
}
catch
catch
{
{
...
@@ -121,13 +120,13 @@ namespace Titanium.Web.Proxy.Network.Tcp
...
@@ -121,13 +120,13 @@ namespace Titanium.Web.Proxy.Network.Tcp
{
{
client
=
new
TcpClient
(
upStreamEndPoint
);
client
=
new
TcpClient
(
upStreamEndPoint
);
await
client
.
ConnectAsync
(
externalHttpProxy
.
HostName
,
externalHttpProxy
.
Port
);
await
client
.
ConnectAsync
(
externalHttpProxy
.
HostName
,
externalHttpProxy
.
Port
);
stream
=
client
.
GetStream
(
);
stream
=
new
CustomBufferedStream
(
client
.
GetStream
(),
bufferSize
);
}
}
else
else
{
{
client
=
new
TcpClient
(
upStreamEndPoint
);
client
=
new
TcpClient
(
upStreamEndPoint
);
await
client
.
ConnectAsync
(
remoteHostName
,
remotePort
);
await
client
.
ConnectAsync
(
remoteHostName
,
remotePort
);
stream
=
client
.
GetStream
(
);
stream
=
new
CustomBufferedStream
(
client
.
GetStream
(),
bufferSize
);
}
}
}
}
...
...
Titanium.Web.Proxy/RequestHandler.cs
View file @
b0607472
...
@@ -6,7 +6,6 @@ using System.Net;
...
@@ -6,7 +6,6 @@ using System.Net;
using
System.Net.Security
;
using
System.Net.Security
;
using
System.Net.Sockets
;
using
System.Net.Sockets
;
using
System.Security.Authentication
;
using
System.Security.Authentication
;
using
System.Text.RegularExpressions
;
using
Titanium.Web.Proxy.Exceptions
;
using
Titanium.Web.Proxy.Exceptions
;
using
Titanium.Web.Proxy.EventArguments
;
using
Titanium.Web.Proxy.EventArguments
;
using
Titanium.Web.Proxy.Helpers
;
using
Titanium.Web.Proxy.Helpers
;
...
@@ -30,7 +29,7 @@ namespace Titanium.Web.Proxy
...
@@ -30,7 +29,7 @@ namespace Titanium.Web.Proxy
private
async
Task
HandleClient
(
ExplicitProxyEndPoint
endPoint
,
TcpClient
tcpClient
)
private
async
Task
HandleClient
(
ExplicitProxyEndPoint
endPoint
,
TcpClient
tcpClient
)
{
{
Stream
clientStream
=
tcpClient
.
GetStream
(
);
CustomBufferedStream
clientStream
=
new
CustomBufferedStream
(
tcpClient
.
GetStream
(),
BufferSize
);
clientStream
.
ReadTimeout
=
ConnectionTimeOutSeconds
*
1000
;
clientStream
.
ReadTimeout
=
ConnectionTimeOutSeconds
*
1000
;
clientStream
.
WriteTimeout
=
ConnectionTimeOutSeconds
*
1000
;
clientStream
.
WriteTimeout
=
ConnectionTimeOutSeconds
*
1000
;
...
@@ -112,7 +111,6 @@ namespace Titanium.Web.Proxy
...
@@ -112,7 +111,6 @@ namespace Titanium.Web.Proxy
try
try
{
{
sslStream
=
new
SslStream
(
clientStream
,
true
);
sslStream
=
new
SslStream
(
clientStream
,
true
);
var
certificate
=
endPoint
.
GenericCertificate
??
certificateManager
.
CreateCertificate
(
httpRemoteUri
.
Host
,
false
);
var
certificate
=
endPoint
.
GenericCertificate
??
certificateManager
.
CreateCertificate
(
httpRemoteUri
.
Host
,
false
);
...
@@ -121,11 +119,10 @@ namespace Titanium.Web.Proxy
...
@@ -121,11 +119,10 @@ namespace Titanium.Web.Proxy
await
sslStream
.
AuthenticateAsServerAsync
(
certificate
,
false
,
await
sslStream
.
AuthenticateAsServerAsync
(
certificate
,
false
,
SupportedSslProtocols
,
false
);
SupportedSslProtocols
,
false
);
//HTTPS server created - we can now decrypt the client's traffic
//HTTPS server created - we can now decrypt the client's traffic
clientStream
=
sslStream
;
clientStream
=
new
CustomBufferedStream
(
sslStream
,
BufferSize
);
clientStreamReader
=
new
CustomBinaryReader
(
sslStream
,
BufferSize
);
clientStreamWriter
=
new
StreamWriter
(
sslStream
)
{
NewLine
=
ProxyConstants
.
NewLine
};
clientStreamReader
=
new
CustomBinaryReader
(
clientStream
,
BufferSize
);
clientStreamWriter
=
new
StreamWriter
(
clientStream
)
{
NewLine
=
ProxyConstants
.
NewLine
};
}
}
catch
catch
{
{
...
@@ -171,8 +168,7 @@ namespace Titanium.Web.Proxy
...
@@ -171,8 +168,7 @@ namespace Titanium.Web.Proxy
//So for HTTPS requests we would start SSL negotiation right away without expecting a CONNECT request from client
//So for HTTPS requests we would start SSL negotiation right away without expecting a CONNECT request from client
private
async
Task
HandleClient
(
TransparentProxyEndPoint
endPoint
,
TcpClient
tcpClient
)
private
async
Task
HandleClient
(
TransparentProxyEndPoint
endPoint
,
TcpClient
tcpClient
)
{
{
CustomBufferedStream
clientStream
=
new
CustomBufferedStream
(
tcpClient
.
GetStream
(),
BufferSize
);
Stream
clientStream
=
tcpClient
.
GetStream
();
clientStream
.
ReadTimeout
=
ConnectionTimeOutSeconds
*
1000
;
clientStream
.
ReadTimeout
=
ConnectionTimeOutSeconds
*
1000
;
clientStream
.
WriteTimeout
=
ConnectionTimeOutSeconds
*
1000
;
clientStream
.
WriteTimeout
=
ConnectionTimeOutSeconds
*
1000
;
...
@@ -193,8 +189,9 @@ namespace Titanium.Web.Proxy
...
@@ -193,8 +189,9 @@ namespace Titanium.Web.Proxy
await
sslStream
.
AuthenticateAsServerAsync
(
certificate
,
false
,
await
sslStream
.
AuthenticateAsServerAsync
(
certificate
,
false
,
SslProtocols
.
Tls
,
false
);
SslProtocols
.
Tls
,
false
);
clientStreamReader
=
new
CustomBinaryReader
(
sslStream
,
BufferSize
);
clientStream
=
new
CustomBufferedStream
(
sslStream
,
BufferSize
);
clientStreamWriter
=
new
StreamWriter
(
sslStream
)
{
NewLine
=
ProxyConstants
.
NewLine
};
clientStreamReader
=
new
CustomBinaryReader
(
clientStream
,
BufferSize
);
clientStreamWriter
=
new
StreamWriter
(
clientStream
)
{
NewLine
=
ProxyConstants
.
NewLine
};
//HTTPS server created - we can now decrypt the client's traffic
//HTTPS server created - we can now decrypt the client's traffic
}
}
...
@@ -205,7 +202,6 @@ namespace Titanium.Web.Proxy
...
@@ -205,7 +202,6 @@ namespace Titanium.Web.Proxy
Dispose
(
sslStream
,
clientStreamReader
,
clientStreamWriter
,
null
);
Dispose
(
sslStream
,
clientStreamReader
,
clientStreamWriter
,
null
);
return
;
return
;
}
}
clientStream
=
sslStream
;
}
}
else
else
{
{
...
...
Titanium.Web.Proxy/ResponseHandler.cs
View file @
b0607472
...
@@ -175,7 +175,7 @@ namespace Titanium.Web.Proxy
...
@@ -175,7 +175,7 @@ namespace Titanium.Web.Proxy
foreach
(
var
header
in
response
.
ResponseHeaders
)
foreach
(
var
header
in
response
.
ResponseHeaders
)
{
{
await
responseWriter
.
WriteLineAsync
(
header
.
Value
.
ToString
()
);
await
header
.
Value
.
WriteToStream
(
responseWriter
);
}
}
//write non unique request headers
//write non unique request headers
...
@@ -184,11 +184,10 @@ namespace Titanium.Web.Proxy
...
@@ -184,11 +184,10 @@ namespace Titanium.Web.Proxy
var
headers
=
headerItem
.
Value
;
var
headers
=
headerItem
.
Value
;
foreach
(
var
header
in
headers
)
foreach
(
var
header
in
headers
)
{
{
await
responseWriter
.
WriteLineAsync
(
header
.
ToString
()
);
await
header
.
WriteToStream
(
responseWriter
);
}
}
}
}
await
responseWriter
.
WriteLineAsync
();
await
responseWriter
.
WriteLineAsync
();
await
responseWriter
.
FlushAsync
();
await
responseWriter
.
FlushAsync
();
}
}
...
...
Titanium.Web.Proxy/Titanium.Web.Proxy.csproj
View file @
b0607472
...
@@ -26,6 +26,7 @@
...
@@ -26,6 +26,7 @@
<TargetFrameworkVersion>
v4.5
</TargetFrameworkVersion>
<TargetFrameworkVersion>
v4.5
</TargetFrameworkVersion>
<Prefer32Bit>
false
</Prefer32Bit>
<Prefer32Bit>
false
</Prefer32Bit>
<DocumentationFile>
bin\Debug\Titanium.Web.Proxy.XML
</DocumentationFile>
<DocumentationFile>
bin\Debug\Titanium.Web.Proxy.XML
</DocumentationFile>
<LangVersion>
6
</LangVersion>
</PropertyGroup>
</PropertyGroup>
<PropertyGroup
Condition=
"'$(Configuration)|$(Platform)' == 'Release|AnyCPU'"
>
<PropertyGroup
Condition=
"'$(Configuration)|$(Platform)' == 'Release|AnyCPU'"
>
<PlatformTarget>
AnyCPU
</PlatformTarget>
<PlatformTarget>
AnyCPU
</PlatformTarget>
...
@@ -73,6 +74,7 @@
...
@@ -73,6 +74,7 @@
<Compile
Include=
"EventArguments\CertificateValidationEventArgs.cs"
/>
<Compile
Include=
"EventArguments\CertificateValidationEventArgs.cs"
/>
<Compile
Include=
"Extensions\ByteArrayExtensions.cs"
/>
<Compile
Include=
"Extensions\ByteArrayExtensions.cs"
/>
<Compile
Include=
"Extensions\StringExtensions.cs"
/>
<Compile
Include=
"Extensions\StringExtensions.cs"
/>
<Compile
Include=
"Helpers\CustomBufferedStream.cs"
/>
<Compile
Include=
"Helpers\Network.cs"
/>
<Compile
Include=
"Helpers\Network.cs"
/>
<Compile
Include=
"Helpers\RunTime.cs"
/>
<Compile
Include=
"Helpers\RunTime.cs"
/>
<Compile
Include=
"Http\Responses\GenericResponse.cs"
/>
<Compile
Include=
"Http\Responses\GenericResponse.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