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
1057c2ff
Commit
1057c2ff
authored
Apr 10, 2017
by
Jehonathan Thomas
Committed by
GitHub
Apr 10, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #187 from robgarrett/develop
Resharper cleanup
parents
4ef9a02d
8022c434
Hide whitespace changes
Inline
Side-by-side
Showing
33 changed files
with
622 additions
and
493 deletions
+622
-493
CertificateHandler.cs
Titanium.Web.Proxy/CertificateHandler.cs
+14
-12
GZipDecompression.cs
Titanium.Web.Proxy/Decompression/GZipDecompression.cs
+0
-1
CertificateSelectionEventArgs.cs
...Web.Proxy/EventArguments/CertificateSelectionEventArgs.cs
+18
-1
CertificateValidationEventArgs.cs
...eb.Proxy/EventArguments/CertificateValidationEventArgs.cs
+13
-6
SessionEventArgs.cs
Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
+21
-6
BodyNotFoundException.cs
Titanium.Web.Proxy/Exceptions/BodyNotFoundException.cs
+5
-2
ByteArrayExtensions.cs
Titanium.Web.Proxy/Extensions/ByteArrayExtensions.cs
+4
-1
TcpExtensions.cs
Titanium.Web.Proxy/Extensions/TcpExtensions.cs
+3
-10
CustomBinaryReader.cs
Titanium.Web.Proxy/Helpers/CustomBinaryReader.cs
+6
-6
Firefox.cs
Titanium.Web.Proxy/Helpers/Firefox.cs
+28
-28
Network.cs
Titanium.Web.Proxy/Helpers/Network.cs
+6
-24
SystemProxy.cs
Titanium.Web.Proxy/Helpers/SystemProxy.cs
+1
-4
Tcp.cs
Titanium.Web.Proxy/Helpers/Tcp.cs
+1
-0
HttpWebClient.cs
Titanium.Web.Proxy/Http/HttpWebClient.cs
+42
-36
Request.cs
Titanium.Web.Proxy/Http/Request.cs
+10
-22
Response.cs
Titanium.Web.Proxy/Http/Response.cs
+14
-9
GenericResponse.cs
Titanium.Web.Proxy/Http/Responses/GenericResponse.cs
+10
-1
OkResponse.cs
Titanium.Web.Proxy/Http/Responses/OkResponse.cs
+3
-0
RedirectResponse.cs
Titanium.Web.Proxy/Http/Responses/RedirectResponse.cs
+3
-0
EndPoint.cs
Titanium.Web.Proxy/Models/EndPoint.cs
+47
-11
ExternalProxy.cs
Titanium.Web.Proxy/Models/ExternalProxy.cs
+17
-2
HttpHeader.cs
Titanium.Web.Proxy/Models/HttpHeader.cs
+13
-1
CertificateMaker.cs
Titanium.Web.Proxy/Network/CertificateMaker.cs
+115
-118
CertificateManager.cs
Titanium.Web.Proxy/Network/CertificateManager.cs
+38
-48
TcpConnection.cs
Titanium.Web.Proxy/Network/Tcp/TcpConnection.cs
+3
-0
TcpConnectionFactory.cs
Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs
+2
-4
TcpRow.cs
Titanium.Web.Proxy/Network/Tcp/TcpRow.cs
+3
-3
TcpTable.cs
Titanium.Web.Proxy/Network/Tcp/TcpTable.cs
+3
-1
ProxyAuthorizationHandler.cs
Titanium.Web.Proxy/ProxyAuthorizationHandler.cs
+64
-40
ProxyServer.cs
Titanium.Web.Proxy/ProxyServer.cs
+61
-14
RequestHandler.cs
Titanium.Web.Proxy/RequestHandler.cs
+41
-63
ResponseHandler.cs
Titanium.Web.Proxy/ResponseHandler.cs
+12
-17
ProxyConstants.cs
Titanium.Web.Proxy/Shared/ProxyConstants.cs
+1
-2
No files found.
Titanium.Web.Proxy/CertificateHandler.cs
View file @
1057c2ff
using
System
;
using
System
;
using
System.Linq
;
using
System.Net.Security
;
using
System.Net.Security
;
using
System.Security.Cryptography.X509Certificates
;
using
System.Security.Cryptography.X509Certificates
;
using
System.Threading.Tasks
;
using
System.Threading.Tasks
;
...
@@ -26,11 +25,13 @@ namespace Titanium.Web.Proxy
...
@@ -26,11 +25,13 @@ namespace Titanium.Web.Proxy
//if user callback is registered then do it
//if user callback is registered then do it
if
(
ServerCertificateValidationCallback
!=
null
)
if
(
ServerCertificateValidationCallback
!=
null
)
{
{
var
args
=
new
CertificateValidationEventArgs
();
var
args
=
new
CertificateValidationEventArgs
{
Certificate
=
certificate
,
Chain
=
chain
,
SslPolicyErrors
=
sslPolicyErrors
};
args
.
Certificate
=
certificate
;
args
.
Chain
=
chain
;
args
.
SslPolicyErrors
=
sslPolicyErrors
;
Delegate
[]
invocationList
=
ServerCertificateValidationCallback
.
GetInvocationList
();
Delegate
[]
invocationList
=
ServerCertificateValidationCallback
.
GetInvocationList
();
...
@@ -73,7 +74,6 @@ namespace Titanium.Web.Proxy
...
@@ -73,7 +74,6 @@ namespace Titanium.Web.Proxy
string
[]
acceptableIssuers
)
string
[]
acceptableIssuers
)
{
{
X509Certificate
clientCertificate
=
null
;
X509Certificate
clientCertificate
=
null
;
var
customSslStream
=
sender
as
SslStream
;
if
(
acceptableIssuers
!=
null
&&
if
(
acceptableIssuers
!=
null
&&
acceptableIssuers
.
Length
>
0
&&
acceptableIssuers
.
Length
>
0
&&
...
@@ -100,13 +100,15 @@ namespace Titanium.Web.Proxy
...
@@ -100,13 +100,15 @@ namespace Titanium.Web.Proxy
//If user call back is registered
//If user call back is registered
if
(
ClientCertificateSelectionCallback
!=
null
)
if
(
ClientCertificateSelectionCallback
!=
null
)
{
{
var
args
=
new
CertificateSelectionEventArgs
();
var
args
=
new
CertificateSelectionEventArgs
{
TargetHost
=
targetHost
,
LocalCertificates
=
localCertificates
,
RemoteCertificate
=
remoteCertificate
,
AcceptableIssuers
=
acceptableIssuers
,
ClientCertificate
=
clientCertificate
};
args
.
TargetHost
=
targetHost
;
args
.
LocalCertificates
=
localCertificates
;
args
.
RemoteCertificate
=
remoteCertificate
;
args
.
AcceptableIssuers
=
acceptableIssuers
;
args
.
ClientCertificate
=
clientCertificate
;
Delegate
[]
invocationList
=
ClientCertificateSelectionCallback
.
GetInvocationList
();
Delegate
[]
invocationList
=
ClientCertificateSelectionCallback
.
GetInvocationList
();
Task
[]
handlerTasks
=
new
Task
[
invocationList
.
Length
];
Task
[]
handlerTasks
=
new
Task
[
invocationList
.
Length
];
...
...
Titanium.Web.Proxy/Decompression/GZipDecompression.cs
View file @
1057c2ff
using
System.IO
;
using
System.IO
;
using
System.IO.Compression
;
using
System.IO.Compression
;
using
System.Threading.Tasks
;
using
System.Threading.Tasks
;
using
Titanium.Web.Proxy.Shared
;
namespace
Titanium.Web.Proxy.Decompression
namespace
Titanium.Web.Proxy.Decompression
{
{
...
...
Titanium.Web.Proxy/EventArguments/CertificateSelectionEventArgs.cs
View file @
1057c2ff
...
@@ -8,12 +8,29 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -8,12 +8,29 @@ namespace Titanium.Web.Proxy.EventArguments
/// </summary>
/// </summary>
public
class
CertificateSelectionEventArgs
:
EventArgs
public
class
CertificateSelectionEventArgs
:
EventArgs
{
{
/// <summary>
/// Sender object.
/// </summary>
public
object
Sender
{
get
;
internal
set
;
}
public
object
Sender
{
get
;
internal
set
;
}
/// <summary>
/// Target host.
/// </summary>
public
string
TargetHost
{
get
;
internal
set
;
}
public
string
TargetHost
{
get
;
internal
set
;
}
/// <summary>
/// Local certificates.
/// </summary>
public
X509CertificateCollection
LocalCertificates
{
get
;
internal
set
;
}
public
X509CertificateCollection
LocalCertificates
{
get
;
internal
set
;
}
/// <summary>
/// Remote certificate.
/// </summary>
public
X509Certificate
RemoteCertificate
{
get
;
internal
set
;
}
public
X509Certificate
RemoteCertificate
{
get
;
internal
set
;
}
/// <summary>
/// Acceptable issuers.
/// </summary>
public
string
[]
AcceptableIssuers
{
get
;
internal
set
;
}
public
string
[]
AcceptableIssuers
{
get
;
internal
set
;
}
/// <summary>
/// Client Certificate.
/// </summary>
public
X509Certificate
ClientCertificate
{
get
;
set
;
}
public
X509Certificate
ClientCertificate
{
get
;
set
;
}
}
}
...
...
Titanium.Web.Proxy/EventArguments/CertificateValidationEventArgs.cs
View file @
1057c2ff
...
@@ -7,17 +7,24 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -7,17 +7,24 @@ namespace Titanium.Web.Proxy.EventArguments
/// <summary>
/// <summary>
/// An argument passed on to the user for validating the server certificate during SSL authentication
/// An argument passed on to the user for validating the server certificate during SSL authentication
/// </summary>
/// </summary>
public
class
CertificateValidationEventArgs
:
EventArgs
,
IDisposable
public
class
CertificateValidationEventArgs
:
EventArgs
{
{
/// <summary>
/// Certificate
/// </summary>
public
X509Certificate
Certificate
{
get
;
internal
set
;
}
public
X509Certificate
Certificate
{
get
;
internal
set
;
}
/// <summary>
/// Certificate chain
/// </summary>
public
X509Chain
Chain
{
get
;
internal
set
;
}
public
X509Chain
Chain
{
get
;
internal
set
;
}
/// <summary>
/// SSL policy errors.
/// </summary>
public
SslPolicyErrors
SslPolicyErrors
{
get
;
internal
set
;
}
public
SslPolicyErrors
SslPolicyErrors
{
get
;
internal
set
;
}
/// <summary>
/// is a valid certificate?
/// </summary>
public
bool
IsValid
{
get
;
set
;
}
public
bool
IsValid
{
get
;
set
;
}
public
void
Dispose
()
{
}
}
}
}
}
Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
View file @
1057c2ff
...
@@ -44,7 +44,9 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -44,7 +44,9 @@ namespace Titanium.Web.Proxy.EventArguments
/// </summary>
/// </summary>
public
Guid
Id
=>
WebSession
.
RequestId
;
public
Guid
Id
=>
WebSession
.
RequestId
;
//Should we send a rerequest
/// <summary>
/// Should we send a rerequest
/// </summary>
public
bool
ReRequest
public
bool
ReRequest
{
{
get
;
get
;
...
@@ -56,7 +58,9 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -56,7 +58,9 @@ namespace Titanium.Web.Proxy.EventArguments
/// </summary>
/// </summary>
public
bool
IsHttps
=>
WebSession
.
Request
.
RequestUri
.
Scheme
==
Uri
.
UriSchemeHttps
;
public
bool
IsHttps
=>
WebSession
.
Request
.
RequestUri
.
Scheme
==
Uri
.
UriSchemeHttps
;
/// <summary>
/// Client End Point.
/// </summary>
public
IPEndPoint
ClientEndPoint
=>
(
IPEndPoint
)
ProxyClient
.
TcpClient
.
Client
.
RemoteEndPoint
;
public
IPEndPoint
ClientEndPoint
=>
(
IPEndPoint
)
ProxyClient
.
TcpClient
.
Client
.
RemoteEndPoint
;
/// <summary>
/// <summary>
...
@@ -65,8 +69,14 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -65,8 +69,14 @@ namespace Titanium.Web.Proxy.EventArguments
/// </summary>
/// </summary>
public
HttpWebClient
WebSession
{
get
;
set
;
}
public
HttpWebClient
WebSession
{
get
;
set
;
}
/// <summary>
/// Are we using a custom upstream HTTP proxy?
/// </summary>
public
ExternalProxy
CustomUpStreamHttpProxyUsed
{
get
;
set
;
}
public
ExternalProxy
CustomUpStreamHttpProxyUsed
{
get
;
set
;
}
/// <summary>
/// Are we using a custom upstream HTTPS proxy?
/// </summary>
public
ExternalProxy
CustomUpStreamHttpsProxyUsed
{
get
;
set
;
}
public
ExternalProxy
CustomUpStreamHttpsProxyUsed
{
get
;
set
;
}
/// <summary>
/// <summary>
...
@@ -105,7 +115,7 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -105,7 +115,7 @@ namespace Titanium.Web.Proxy.EventArguments
//For chunked request we need to read data as they arrive, until we reach a chunk end symbol
//For chunked request we need to read data as they arrive, until we reach a chunk end symbol
if
(
WebSession
.
Request
.
IsChunked
)
if
(
WebSession
.
Request
.
IsChunked
)
{
{
await
this
.
ProxyClient
.
ClientStreamReader
.
CopyBytesToStreamChunked
(
bufferSize
,
requestBodyStream
);
await
ProxyClient
.
ClientStreamReader
.
CopyBytesToStreamChunked
(
bufferSize
,
requestBodyStream
);
}
}
else
else
{
{
...
@@ -113,7 +123,7 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -113,7 +123,7 @@ namespace Titanium.Web.Proxy.EventArguments
if
(
WebSession
.
Request
.
ContentLength
>
0
)
if
(
WebSession
.
Request
.
ContentLength
>
0
)
{
{
//If not chunked then its easy just read the amount of bytes mentioned in content length header of response
//If not chunked then its easy just read the amount of bytes mentioned in content length header of response
await
this
.
ProxyClient
.
ClientStreamReader
.
CopyBytesToStream
(
bufferSize
,
requestBodyStream
,
await
ProxyClient
.
ClientStreamReader
.
CopyBytesToStream
(
bufferSize
,
requestBodyStream
,
WebSession
.
Request
.
ContentLength
);
WebSession
.
Request
.
ContentLength
);
}
}
...
@@ -431,7 +441,7 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -431,7 +441,7 @@ namespace Titanium.Web.Proxy.EventArguments
await
GenericResponse
(
html
,
null
,
status
);
await
GenericResponse
(
html
,
null
,
status
);
}
}
///
<summary>
///
<summary>
/// Before request is made to server
/// Before request is made to server
/// Respond with the specified HTML string to client
/// Respond with the specified HTML string to client
/// and the specified status
/// and the specified status
...
@@ -485,12 +495,17 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -485,12 +495,17 @@ namespace Titanium.Web.Proxy.EventArguments
WebSession
.
Request
.
CancelRequest
=
true
;
WebSession
.
Request
.
CancelRequest
=
true
;
}
}
/// <summary>
/// Redirect to URL.
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public
async
Task
Redirect
(
string
url
)
public
async
Task
Redirect
(
string
url
)
{
{
var
response
=
new
RedirectResponse
();
var
response
=
new
RedirectResponse
();
response
.
HttpVersion
=
WebSession
.
Request
.
HttpVersion
;
response
.
HttpVersion
=
WebSession
.
Request
.
HttpVersion
;
response
.
ResponseHeaders
.
Add
(
"Location"
,
new
Models
.
HttpHeader
(
"Location"
,
url
));
response
.
ResponseHeaders
.
Add
(
"Location"
,
new
HttpHeader
(
"Location"
,
url
));
response
.
ResponseBody
=
Encoding
.
ASCII
.
GetBytes
(
string
.
Empty
);
response
.
ResponseBody
=
Encoding
.
ASCII
.
GetBytes
(
string
.
Empty
);
await
Respond
(
response
);
await
Respond
(
response
);
...
...
Titanium.Web.Proxy/Exceptions/BodyNotFoundException.cs
View file @
1057c2ff
using
System
;
namespace
Titanium.Web.Proxy.Exceptions
namespace
Titanium.Web.Proxy.Exceptions
{
{
/// <summary>
/// <summary>
...
@@ -7,6 +6,10 @@ namespace Titanium.Web.Proxy.Exceptions
...
@@ -7,6 +6,10 @@ namespace Titanium.Web.Proxy.Exceptions
/// </summary>
/// </summary>
public
class
BodyNotFoundException
:
ProxyException
public
class
BodyNotFoundException
:
ProxyException
{
{
/// <summary>
/// Constructor.
/// </summary>
/// <param name="message"></param>
public
BodyNotFoundException
(
string
message
)
public
BodyNotFoundException
(
string
message
)
:
base
(
message
)
:
base
(
message
)
{
{
...
...
Titanium.Web.Proxy/Extensions/ByteArrayExtensions.cs
View file @
1057c2ff
...
@@ -2,6 +2,9 @@
...
@@ -2,6 +2,9 @@
namespace
Titanium.Web.Proxy.Extensions
namespace
Titanium.Web.Proxy.Extensions
{
{
/// <summary>
/// Extension methods for Byte Arrays.
/// </summary>
public
static
class
ByteArrayExtensions
public
static
class
ByteArrayExtensions
{
{
/// <summary>
/// <summary>
...
@@ -14,7 +17,7 @@ namespace Titanium.Web.Proxy.Extensions
...
@@ -14,7 +17,7 @@ namespace Titanium.Web.Proxy.Extensions
/// <returns></returns>
/// <returns></returns>
public
static
T
[]
SubArray
<
T
>(
this
T
[]
data
,
int
index
,
int
length
)
public
static
T
[]
SubArray
<
T
>(
this
T
[]
data
,
int
index
,
int
length
)
{
{
T
[]
result
=
new
T
[
length
];
var
result
=
new
T
[
length
];
Array
.
Copy
(
data
,
index
,
result
,
0
,
length
);
Array
.
Copy
(
data
,
index
,
result
,
0
,
length
);
return
result
;
return
result
;
}
}
...
...
Titanium.Web.Proxy/Extensions/TcpExtensions.cs
View file @
1057c2ff
...
@@ -12,11 +12,11 @@ namespace Titanium.Web.Proxy.Extensions
...
@@ -12,11 +12,11 @@ namespace Titanium.Web.Proxy.Extensions
internal
static
bool
IsConnected
(
this
Socket
client
)
internal
static
bool
IsConnected
(
this
Socket
client
)
{
{
// This is how you can determine whether a socket is still connected.
// This is how you can determine whether a socket is still connected.
bool
blockingState
=
client
.
Blocking
;
var
blockingState
=
client
.
Blocking
;
try
try
{
{
byte
[]
tmp
=
new
byte
[
1
];
var
tmp
=
new
byte
[
1
];
client
.
Blocking
=
false
;
client
.
Blocking
=
false
;
client
.
Send
(
tmp
,
0
,
0
);
client
.
Send
(
tmp
,
0
,
0
);
...
@@ -25,14 +25,7 @@ namespace Titanium.Web.Proxy.Extensions
...
@@ -25,14 +25,7 @@ namespace Titanium.Web.Proxy.Extensions
catch
(
SocketException
e
)
catch
(
SocketException
e
)
{
{
// 10035 == WSAEWOULDBLOCK
// 10035 == WSAEWOULDBLOCK
if
(
e
.
NativeErrorCode
.
Equals
(
10035
))
return
e
.
NativeErrorCode
.
Equals
(
10035
);
{
return
true
;
}
else
{
return
false
;
}
}
}
finally
finally
{
{
...
...
Titanium.Web.Proxy/Helpers/CustomBinaryReader.cs
View file @
1057c2ff
...
@@ -4,7 +4,6 @@ using System.IO;
...
@@ -4,7 +4,6 @@ using System.IO;
using
System.Text
;
using
System.Text
;
using
System.Threading.Tasks
;
using
System.Threading.Tasks
;
using
Titanium.Web.Proxy.Extensions
;
using
Titanium.Web.Proxy.Extensions
;
using
Titanium.Web.Proxy.Shared
;
namespace
Titanium.Web.Proxy.Helpers
namespace
Titanium.Web.Proxy.Helpers
{
{
...
@@ -16,15 +15,15 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -16,15 +15,15 @@ namespace Titanium.Web.Proxy.Helpers
/// </summary>
/// </summary>
internal
class
CustomBinaryReader
:
IDisposable
internal
class
CustomBinaryReader
:
IDisposable
{
{
private
Stream
stream
;
private
readonly
Stream
stream
;
private
Encoding
encoding
;
private
readonly
Encoding
encoding
;
internal
CustomBinaryReader
(
Stream
stream
)
internal
CustomBinaryReader
(
Stream
stream
)
{
{
this
.
stream
=
stream
;
this
.
stream
=
stream
;
//default to UTF-8
//default to UTF-8
this
.
encoding
=
Encoding
.
UTF8
;
encoding
=
Encoding
.
UTF8
;
}
}
internal
Stream
BaseStream
=>
stream
;
internal
Stream
BaseStream
=>
stream
;
...
@@ -40,7 +39,7 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -40,7 +39,7 @@ namespace Titanium.Web.Proxy.Helpers
var
lastChar
=
default
(
char
);
var
lastChar
=
default
(
char
);
var
buffer
=
new
byte
[
1
];
var
buffer
=
new
byte
[
1
];
while
((
await
this
.
stream
.
ReadAsync
(
buffer
,
0
,
1
))
>
0
)
while
((
await
stream
.
ReadAsync
(
buffer
,
0
,
1
))
>
0
)
{
{
//if new line
//if new line
if
(
lastChar
==
'\r'
&&
buffer
[
0
]
==
'\n'
)
if
(
lastChar
==
'\r'
&&
buffer
[
0
]
==
'\n'
)
...
@@ -82,6 +81,7 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -82,6 +81,7 @@ namespace Titanium.Web.Proxy.Helpers
/// <summary>
/// <summary>
/// Read the specified number of raw bytes from the base stream
/// Read the specified number of raw bytes from the base stream
/// </summary>
/// </summary>
/// <param name="bufferSize"></param>
/// <param name="totalBytesToRead"></param>
/// <param name="totalBytesToRead"></param>
/// <returns></returns>
/// <returns></returns>
internal
async
Task
<
byte
[
]>
ReadBytesAsync
(
int
bufferSize
,
long
totalBytesToRead
)
internal
async
Task
<
byte
[
]>
ReadBytesAsync
(
int
bufferSize
,
long
totalBytesToRead
)
...
@@ -98,7 +98,7 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -98,7 +98,7 @@ namespace Titanium.Web.Proxy.Helpers
using
(
var
outStream
=
new
MemoryStream
())
using
(
var
outStream
=
new
MemoryStream
())
{
{
while
((
bytesRead
+=
await
this
.
stream
.
ReadAsync
(
buffer
,
0
,
bytesToRead
))
>
0
)
while
((
bytesRead
+=
await
stream
.
ReadAsync
(
buffer
,
0
,
bytesToRead
))
>
0
)
{
{
await
outStream
.
WriteAsync
(
buffer
,
0
,
bytesRead
);
await
outStream
.
WriteAsync
(
buffer
,
0
,
bytesRead
);
totalBytesRead
+=
bytesRead
;
totalBytesRead
+=
bytesRead
;
...
...
Titanium.Web.Proxy/Helpers/Firefox.cs
View file @
1057c2ff
...
@@ -8,7 +8,10 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -8,7 +8,10 @@ namespace Titanium.Web.Proxy.Helpers
/// </summary>
/// </summary>
public
class
FireFoxProxySettingsManager
public
class
FireFoxProxySettingsManager
{
{
public
void
AddFirefox
()
/// <summary>
/// Add Firefox settings.
/// </summary>
public
void
AddFirefox
()
{
{
try
try
{
{
...
@@ -16,21 +19,17 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -16,21 +19,17 @@ namespace Titanium.Web.Proxy.Helpers
new
DirectoryInfo
(
Environment
.
GetFolderPath
(
Environment
.
SpecialFolder
.
ApplicationData
)
+
new
DirectoryInfo
(
Environment
.
GetFolderPath
(
Environment
.
SpecialFolder
.
ApplicationData
)
+
"\\Mozilla\\Firefox\\Profiles\\"
).
GetDirectories
(
"*.default"
);
"\\Mozilla\\Firefox\\Profiles\\"
).
GetDirectories
(
"*.default"
);
var
myFfPrefFile
=
myProfileDirectory
[
0
].
FullName
+
"\\prefs.js"
;
var
myFfPrefFile
=
myProfileDirectory
[
0
].
FullName
+
"\\prefs.js"
;
if
(
File
.
Exists
(
myFfPrefFile
))
if
(!
File
.
Exists
(
myFfPrefFile
))
return
;
{
// We have a pref file so let''s make sure it has the proxy setting
// We have a pref file so let''s make sure it has the proxy setting
var
myReader
=
new
StreamReader
(
myFfPrefFile
);
var
myReader
=
new
StreamReader
(
myFfPrefFile
);
var
myPrefContents
=
myReader
.
ReadToEnd
();
var
myPrefContents
=
myReader
.
ReadToEnd
();
myReader
.
Close
();
myReader
.
Close
();
if
(!
myPrefContents
.
Contains
(
"user_pref(\"network.proxy.type\", 0);"
))
return
;
if
(
myPrefContents
.
Contains
(
"user_pref(\"network.proxy.type\", 0);"
))
// Add the proxy enable line and write it back to the file
{
myPrefContents
=
myPrefContents
.
Replace
(
"user_pref(\"network.proxy.type\", 0);"
,
""
);
// Add the proxy enable line and write it back to the file
myPrefContents
=
myPrefContents
.
Replace
(
"user_pref(\"network.proxy.type\", 0);"
,
""
);
File
.
Delete
(
myFfPrefFile
);
File
.
Delete
(
myFfPrefFile
);
File
.
WriteAllText
(
myFfPrefFile
,
myPrefContents
);
File
.
WriteAllText
(
myFfPrefFile
,
myPrefContents
);
}
}
}
}
catch
(
Exception
)
catch
(
Exception
)
{
{
...
@@ -38,7 +37,10 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -38,7 +37,10 @@ namespace Titanium.Web.Proxy.Helpers
}
}
}
}
public
void
RemoveFirefox
()
/// <summary>
/// Remove firefox settings.
/// </summary>
public
void
RemoveFirefox
()
{
{
try
try
{
{
...
@@ -46,20 +48,18 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -46,20 +48,18 @@ namespace Titanium.Web.Proxy.Helpers
new
DirectoryInfo
(
Environment
.
GetFolderPath
(
Environment
.
SpecialFolder
.
ApplicationData
)
+
new
DirectoryInfo
(
Environment
.
GetFolderPath
(
Environment
.
SpecialFolder
.
ApplicationData
)
+
"\\Mozilla\\Firefox\\Profiles\\"
).
GetDirectories
(
"*.default"
);
"\\Mozilla\\Firefox\\Profiles\\"
).
GetDirectories
(
"*.default"
);
var
myFfPrefFile
=
myProfileDirectory
[
0
].
FullName
+
"\\prefs.js"
;
var
myFfPrefFile
=
myProfileDirectory
[
0
].
FullName
+
"\\prefs.js"
;
if
(
File
.
Exists
(
myFfPrefFile
))
if
(!
File
.
Exists
(
myFfPrefFile
))
return
;
// We have a pref file so let''s make sure it has the proxy setting
var
myReader
=
new
StreamReader
(
myFfPrefFile
);
var
myPrefContents
=
myReader
.
ReadToEnd
();
myReader
.
Close
();
if
(!
myPrefContents
.
Contains
(
"user_pref(\"network.proxy.type\", 0);"
))
{
{
// We have a pref file so let''s make sure it has the proxy setting
// Add the proxy enable line and write it back to the file
var
myReader
=
new
StreamReader
(
myFfPrefFile
);
myPrefContents
=
myPrefContents
+
"\n\r"
+
"user_pref(\"network.proxy.type\", 0);"
;
var
myPrefContents
=
myReader
.
ReadToEnd
();
myReader
.
Close
();
if
(!
myPrefContents
.
Contains
(
"user_pref(\"network.proxy.type\", 0);"
))
{
// Add the proxy enable line and write it back to the file
myPrefContents
=
myPrefContents
+
"\n\r"
+
"user_pref(\"network.proxy.type\", 0);"
;
File
.
Delete
(
myFfPrefFile
);
File
.
Delete
(
myFfPrefFile
);
File
.
WriteAllText
(
myFfPrefFile
,
myPrefContents
);
File
.
WriteAllText
(
myFfPrefFile
,
myPrefContents
);
}
}
}
}
}
catch
(
Exception
)
catch
(
Exception
)
...
...
Titanium.Web.Proxy/Helpers/Network.cs
View file @
1057c2ff
using
System
;
using
System.Linq
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Net
;
using
System.Net
;
using
System.Text
;
using
System.Threading.Tasks
;
namespace
Titanium.Web.Proxy.Helpers
namespace
Titanium.Web.Proxy.Helpers
{
{
...
@@ -33,28 +29,14 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -33,28 +29,14 @@ namespace Titanium.Web.Proxy.Helpers
/// Adapated from below link
/// Adapated from below link
/// http://stackoverflow.com/questions/11834091/how-to-check-if-localhost
/// http://stackoverflow.com/questions/11834091/how-to-check-if-localhost
/// </summary>
/// </summary>
/// <param name="address></param>
/// <param name="address
"
></param>
/// <returns></returns>
/// <returns></returns>
internal
static
bool
IsLocalIpAddress
(
IPAddress
address
)
internal
static
bool
IsLocalIpAddress
(
IPAddress
address
)
{
{
try
// get local IP addresses
{
var
localIPs
=
Dns
.
GetHostAddresses
(
Dns
.
GetHostName
());
// get local IP addresses
// test if any host IP equals to any local IP or to localhost
IPAddress
[]
localIPs
=
Dns
.
GetHostAddresses
(
Dns
.
GetHostName
());
return
IPAddress
.
IsLoopback
(
address
)
||
localIPs
.
Contains
(
address
);
// test if any host IP equals to any local IP or to localhost
// is localhost
if
(
IPAddress
.
IsLoopback
(
address
))
return
true
;
// is local address
foreach
(
IPAddress
localIP
in
localIPs
)
{
if
(
address
.
Equals
(
localIP
))
return
true
;
}
}
catch
{
}
return
false
;
}
}
}
}
}
}
Titanium.Web.Proxy/Helpers/SystemProxy.cs
View file @
1057c2ff
...
@@ -4,11 +4,8 @@ using Microsoft.Win32;
...
@@ -4,11 +4,8 @@ using Microsoft.Win32;
using
System.Text.RegularExpressions
;
using
System.Text.RegularExpressions
;
using
System.Collections.Generic
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Linq
;
using
System.Net.Sockets
;
/// <summary>
// Helper classes for setting system proxy settings
/// Helper classes for setting system proxy settings
/// </summary>
namespace
Titanium.Web.Proxy.Helpers
namespace
Titanium.Web.Proxy.Helpers
{
{
internal
enum
ProxyProtocolType
internal
enum
ProxyProtocolType
...
...
Titanium.Web.Proxy/Helpers/Tcp.cs
View file @
1057c2ff
...
@@ -140,6 +140,7 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -140,6 +140,7 @@ namespace Titanium.Web.Proxy.Helpers
/// <param name="localCertificateSelectionCallback"></param>
/// <param name="localCertificateSelectionCallback"></param>
/// <param name="clientStream"></param>
/// <param name="clientStream"></param>
/// <param name="tcpConnectionFactory"></param>
/// <param name="tcpConnectionFactory"></param>
/// <param name="upStreamEndPoint"></param>
/// <returns></returns>
/// <returns></returns>
internal
static
async
Task
SendRaw
(
int
bufferSize
,
int
connectionTimeOutSeconds
,
internal
static
async
Task
SendRaw
(
int
bufferSize
,
int
connectionTimeOutSeconds
,
string
remoteHostName
,
int
remotePort
,
string
httpCmd
,
Version
httpVersion
,
Dictionary
<
string
,
HttpHeader
>
requestHeaders
,
string
remoteHostName
,
int
remotePort
,
string
httpCmd
,
Version
httpVersion
,
Dictionary
<
string
,
HttpHeader
>
requestHeaders
,
...
...
Titanium.Web.Proxy/Http/HttpWebClient.cs
View file @
1057c2ff
using
System
;
using
System
;
using
System.Collections.Generic
;
using
System.Collections.Generic
;
using
System.IO
;
using
System.Text
;
using
System.Text
;
using
System.Threading.Tasks
;
using
System.Threading.Tasks
;
using
Titanium.Web.Proxy.Models
;
using
Titanium.Web.Proxy.Models
;
using
Titanium.Web.Proxy.Network
;
using
Titanium.Web.Proxy.Network.Tcp
;
using
Titanium.Web.Proxy.Network.Tcp
;
using
Titanium.Web.Proxy.Shared
;
using
Titanium.Web.Proxy.Shared
;
...
@@ -15,17 +13,26 @@ namespace Titanium.Web.Proxy.Http
...
@@ -15,17 +13,26 @@ namespace Titanium.Web.Proxy.Http
/// </summary>
/// </summary>
public
class
HttpWebClient
public
class
HttpWebClient
{
{
/// <summary>
/// <summary>
/// Connection to server
/// Connection to server
/// </summary>
/// </summary>
internal
TcpConnection
ServerConnection
{
get
;
set
;
}
internal
TcpConnection
ServerConnection
{
get
;
set
;
}
public
Guid
RequestId
{
get
;
private
set
;
}
/// <summary>
/// Request ID.
/// </summary>
public
Guid
RequestId
{
get
;
}
/// <summary>
/// Headers passed with Connect.
/// </summary>
public
List
<
HttpHeader
>
ConnectHeaders
{
get
;
set
;
}
public
List
<
HttpHeader
>
ConnectHeaders
{
get
;
set
;
}
/// <summary>
/// Web Request.
/// </summary>
public
Request
Request
{
get
;
set
;
}
public
Request
Request
{
get
;
set
;
}
/// <summary>
/// Web Response.
/// </summary>
public
Response
Response
{
get
;
set
;
}
public
Response
Response
{
get
;
set
;
}
/// <summary>
/// <summary>
...
@@ -37,15 +44,14 @@ namespace Titanium.Web.Proxy.Http
...
@@ -37,15 +44,14 @@ namespace Titanium.Web.Proxy.Http
/// <summary>
/// <summary>
/// Is Https?
/// Is Https?
/// </summary>
/// </summary>
public
bool
IsHttps
=>
this
.
Request
.
RequestUri
.
Scheme
==
Uri
.
UriSchemeHttps
;
public
bool
IsHttps
=>
Request
.
RequestUri
.
Scheme
==
Uri
.
UriSchemeHttps
;
internal
HttpWebClient
()
internal
HttpWebClient
()
{
{
this
.
RequestId
=
Guid
.
NewGuid
();
RequestId
=
Guid
.
NewGuid
();
Request
=
new
Request
();
this
.
Request
=
new
Request
();
Response
=
new
Response
();
this
.
Response
=
new
Response
();
}
}
/// <summary>
/// <summary>
...
@@ -65,18 +71,18 @@ namespace Titanium.Web.Proxy.Http
...
@@ -65,18 +71,18 @@ namespace Titanium.Web.Proxy.Http
/// <returns></returns>
/// <returns></returns>
internal
async
Task
SendRequest
(
bool
enable100ContinueBehaviour
)
internal
async
Task
SendRequest
(
bool
enable100ContinueBehaviour
)
{
{
Stream
stream
=
ServerConnection
.
Stream
;
var
stream
=
ServerConnection
.
Stream
;
StringBuilde
r
requestLines
=
new
StringBuilder
();
va
r
requestLines
=
new
StringBuilder
();
//prepare the request & headers
//prepare the request & headers
if
((
ServerConnection
.
UpStreamHttpProxy
!=
null
&&
ServerConnection
.
IsHttps
==
false
)
||
(
ServerConnection
.
UpStreamHttpsProxy
!=
null
&&
ServerConnection
.
IsHttps
==
true
))
if
((
ServerConnection
.
UpStreamHttpProxy
!=
null
&&
ServerConnection
.
IsHttps
==
false
)
||
(
ServerConnection
.
UpStreamHttpsProxy
!=
null
&&
ServerConnection
.
IsHttps
))
{
{
requestLines
.
AppendLine
(
string
.
Join
(
" "
,
this
.
Request
.
Method
,
this
.
Request
.
RequestUri
.
AbsoluteUri
,
$"HTTP/
{
this
.
Request
.
HttpVersion
.
Major
}
.
{
this
.
Request
.
HttpVersion
.
Minor
}
"
));
requestLines
.
AppendLine
(
string
.
Join
(
" "
,
Request
.
Method
,
Request
.
RequestUri
.
AbsoluteUri
,
$"HTTP/
{
Request
.
HttpVersion
.
Major
}
.
{
Request
.
HttpVersion
.
Minor
}
"
));
}
}
else
else
{
{
requestLines
.
AppendLine
(
string
.
Join
(
" "
,
this
.
Request
.
Method
,
this
.
Request
.
RequestUri
.
PathAndQuery
,
$"HTTP/
{
this
.
Request
.
HttpVersion
.
Major
}
.
{
this
.
Request
.
HttpVersion
.
Minor
}
"
));
requestLines
.
AppendLine
(
string
.
Join
(
" "
,
Request
.
Method
,
Request
.
RequestUri
.
PathAndQuery
,
$"HTTP/
{
Request
.
HttpVersion
.
Major
}
.
{
Request
.
HttpVersion
.
Minor
}
"
));
}
}
//Send Authentication to Upstream proxy if needed
//Send Authentication to Upstream proxy if needed
...
@@ -86,7 +92,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -86,7 +92,7 @@ namespace Titanium.Web.Proxy.Http
requestLines
.
AppendLine
(
"Proxy-Authorization"
+
": Basic "
+
Convert
.
ToBase64String
(
Encoding
.
UTF8
.
GetBytes
(
ServerConnection
.
UpStreamHttpProxy
.
UserName
+
":"
+
ServerConnection
.
UpStreamHttpProxy
.
Password
)));
requestLines
.
AppendLine
(
"Proxy-Authorization"
+
": Basic "
+
Convert
.
ToBase64String
(
Encoding
.
UTF8
.
GetBytes
(
ServerConnection
.
UpStreamHttpProxy
.
UserName
+
":"
+
ServerConnection
.
UpStreamHttpProxy
.
Password
)));
}
}
//write request headers
//write request headers
foreach
(
var
headerItem
in
this
.
Request
.
RequestHeaders
)
foreach
(
var
headerItem
in
Request
.
RequestHeaders
)
{
{
var
header
=
headerItem
.
Value
;
var
header
=
headerItem
.
Value
;
if
(
headerItem
.
Key
!=
"Proxy-Authorization"
)
if
(
headerItem
.
Key
!=
"Proxy-Authorization"
)
...
@@ -96,7 +102,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -96,7 +102,7 @@ namespace Titanium.Web.Proxy.Http
}
}
//write non unique request headers
//write non unique request headers
foreach
(
var
headerItem
in
this
.
Request
.
NonUniqueRequestHeaders
)
foreach
(
var
headerItem
in
Request
.
NonUniqueRequestHeaders
)
{
{
var
headers
=
headerItem
.
Value
;
var
headers
=
headerItem
.
Value
;
foreach
(
var
header
in
headers
)
foreach
(
var
header
in
headers
)
...
@@ -110,15 +116,15 @@ namespace Titanium.Web.Proxy.Http
...
@@ -110,15 +116,15 @@ namespace Titanium.Web.Proxy.Http
requestLines
.
AppendLine
();
requestLines
.
AppendLine
();
string
request
=
requestLines
.
ToString
();
var
request
=
requestLines
.
ToString
();
byte
[]
requestBytes
=
Encoding
.
ASCII
.
GetBytes
(
request
);
var
requestBytes
=
Encoding
.
ASCII
.
GetBytes
(
request
);
await
stream
.
WriteAsync
(
requestBytes
,
0
,
requestBytes
.
Length
);
await
stream
.
WriteAsync
(
requestBytes
,
0
,
requestBytes
.
Length
);
await
stream
.
FlushAsync
();
await
stream
.
FlushAsync
();
if
(
enable100ContinueBehaviour
)
if
(
enable100ContinueBehaviour
)
{
{
if
(
this
.
Request
.
ExpectContinue
)
if
(
Request
.
ExpectContinue
)
{
{
var
httpResult
=
(
await
ServerConnection
.
StreamReader
.
ReadLineAsync
()).
Split
(
ProxyConstants
.
SpaceSplit
,
3
);
var
httpResult
=
(
await
ServerConnection
.
StreamReader
.
ReadLineAsync
()).
Split
(
ProxyConstants
.
SpaceSplit
,
3
);
var
responseStatusCode
=
httpResult
[
1
].
Trim
();
var
responseStatusCode
=
httpResult
[
1
].
Trim
();
...
@@ -128,13 +134,13 @@ namespace Titanium.Web.Proxy.Http
...
@@ -128,13 +134,13 @@ namespace Titanium.Web.Proxy.Http
if
(
responseStatusCode
.
Equals
(
"100"
)
if
(
responseStatusCode
.
Equals
(
"100"
)
&&
responseStatusDescription
.
ToLower
().
Equals
(
"continue"
))
&&
responseStatusDescription
.
ToLower
().
Equals
(
"continue"
))
{
{
this
.
Request
.
Is100Continue
=
true
;
Request
.
Is100Continue
=
true
;
await
ServerConnection
.
StreamReader
.
ReadLineAsync
();
await
ServerConnection
.
StreamReader
.
ReadLineAsync
();
}
}
else
if
(
responseStatusCode
.
Equals
(
"417"
)
else
if
(
responseStatusCode
.
Equals
(
"417"
)
&&
responseStatusDescription
.
ToLower
().
Equals
(
"expectation failed"
))
&&
responseStatusDescription
.
ToLower
().
Equals
(
"expectation failed"
))
{
{
this
.
Request
.
ExpectationFailed
=
true
;
Request
.
ExpectationFailed
=
true
;
await
ServerConnection
.
StreamReader
.
ReadLineAsync
();
await
ServerConnection
.
StreamReader
.
ReadLineAsync
();
}
}
}
}
...
@@ -148,7 +154,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -148,7 +154,7 @@ namespace Titanium.Web.Proxy.Http
internal
async
Task
ReceiveResponse
()
internal
async
Task
ReceiveResponse
()
{
{
//return if this is already read
//return if this is already read
if
(
this
.
Response
.
ResponseStatusCode
!=
null
)
return
;
if
(
Response
.
ResponseStatusCode
!=
null
)
return
;
var
httpResult
=
(
await
ServerConnection
.
StreamReader
.
ReadLineAsync
()).
Split
(
ProxyConstants
.
SpaceSplit
,
3
);
var
httpResult
=
(
await
ServerConnection
.
StreamReader
.
ReadLineAsync
()).
Split
(
ProxyConstants
.
SpaceSplit
,
3
);
...
@@ -161,33 +167,33 @@ namespace Titanium.Web.Proxy.Http
...
@@ -161,33 +167,33 @@ namespace Titanium.Web.Proxy.Http
var
httpVersion
=
httpResult
[
0
].
Trim
().
ToLower
();
var
httpVersion
=
httpResult
[
0
].
Trim
().
ToLower
();
var
version
=
new
Version
(
1
,
1
);
var
version
=
new
Version
(
1
,
1
);
if
(
httpVersion
==
"http/1.0"
)
if
(
0
==
string
.
CompareOrdinal
(
httpVersion
,
"http/1.0"
)
)
{
{
version
=
new
Version
(
1
,
0
);
version
=
new
Version
(
1
,
0
);
}
}
this
.
Response
.
HttpVersion
=
version
;
Response
.
HttpVersion
=
version
;
this
.
Response
.
ResponseStatusCode
=
httpResult
[
1
].
Trim
();
Response
.
ResponseStatusCode
=
httpResult
[
1
].
Trim
();
this
.
Response
.
ResponseStatusDescription
=
httpResult
[
2
].
Trim
();
Response
.
ResponseStatusDescription
=
httpResult
[
2
].
Trim
();
//For HTTP 1.1 comptibility server may send expect-continue even if not asked for it in request
//For HTTP 1.1 comptibility server may send expect-continue even if not asked for it in request
if
(
this
.
Response
.
ResponseStatusCode
.
Equals
(
"100"
)
if
(
Response
.
ResponseStatusCode
.
Equals
(
"100"
)
&&
this
.
Response
.
ResponseStatusDescription
.
ToLower
().
Equals
(
"continue"
))
&&
Response
.
ResponseStatusDescription
.
ToLower
().
Equals
(
"continue"
))
{
{
//Read the next line after 100-continue
//Read the next line after 100-continue
this
.
Response
.
Is100Continue
=
true
;
Response
.
Is100Continue
=
true
;
this
.
Response
.
ResponseStatusCode
=
null
;
Response
.
ResponseStatusCode
=
null
;
await
ServerConnection
.
StreamReader
.
ReadLineAsync
();
await
ServerConnection
.
StreamReader
.
ReadLineAsync
();
//now receive response
//now receive response
await
ReceiveResponse
();
await
ReceiveResponse
();
return
;
return
;
}
}
else
if
(
this
.
Response
.
ResponseStatusCode
.
Equals
(
"417"
)
else
if
(
Response
.
ResponseStatusCode
.
Equals
(
"417"
)
&&
this
.
Response
.
ResponseStatusDescription
.
ToLower
().
Equals
(
"expectation failed"
))
&&
Response
.
ResponseStatusDescription
.
ToLower
().
Equals
(
"expectation failed"
))
{
{
//read next line after expectation failed response
//read next line after expectation failed response
this
.
Response
.
ExpectationFailed
=
true
;
Response
.
ExpectationFailed
=
true
;
this
.
Response
.
ResponseStatusCode
=
null
;
Response
.
ResponseStatusCode
=
null
;
await
ServerConnection
.
StreamReader
.
ReadLineAsync
();
await
ServerConnection
.
StreamReader
.
ReadLineAsync
();
//now receive response
//now receive response
await
ReceiveResponse
();
await
ReceiveResponse
();
...
...
Titanium.Web.Proxy/Http/Request.cs
View file @
1057c2ff
...
@@ -34,12 +34,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -34,12 +34,7 @@ namespace Titanium.Web.Proxy.Http
get
get
{
{
var
hasHeader
=
RequestHeaders
.
ContainsKey
(
"host"
);
var
hasHeader
=
RequestHeaders
.
ContainsKey
(
"host"
);
if
(
hasHeader
)
return
hasHeader
?
RequestHeaders
[
"host"
].
Value
:
null
;
{
return
RequestHeaders
[
"host"
].
Value
;
}
return
null
;
}
}
set
set
{
{
...
@@ -154,11 +149,11 @@ namespace Titanium.Web.Proxy.Http
...
@@ -154,11 +149,11 @@ namespace Titanium.Web.Proxy.Http
if
(
hasHeader
)
if
(
hasHeader
)
{
{
var
header
=
RequestHeaders
[
"content-type"
];
var
header
=
RequestHeaders
[
"content-type"
];
header
.
Value
=
value
.
ToString
()
;
header
.
Value
=
value
;
}
}
else
else
{
{
RequestHeaders
.
Add
(
"content-type"
,
new
HttpHeader
(
"content-type"
,
value
.
ToString
()
));
RequestHeaders
.
Add
(
"content-type"
,
new
HttpHeader
(
"content-type"
,
value
));
}
}
}
}
...
@@ -219,14 +214,10 @@ namespace Titanium.Web.Proxy.Http
...
@@ -219,14 +214,10 @@ namespace Titanium.Web.Proxy.Http
{
{
var
hasHeader
=
RequestHeaders
.
ContainsKey
(
"expect"
);
var
hasHeader
=
RequestHeaders
.
ContainsKey
(
"expect"
);
if
(
hasHeader
)
if
(!
hasHeader
)
return
false
;
{
var
header
=
RequestHeaders
[
"expect"
];
var
header
=
RequestHeaders
[
"expect"
];
return
header
.
Value
.
Equals
(
"100-continue"
);
}
return
false
;
return
header
.
Value
.
Equals
(
"100-continue"
)
;
}
}
}
}
...
@@ -275,13 +266,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -275,13 +266,7 @@ namespace Titanium.Web.Proxy.Http
var
header
=
RequestHeaders
[
"upgrade"
];
var
header
=
RequestHeaders
[
"upgrade"
];
if
(
header
.
Value
.
ToLower
()
==
"websocket"
)
return
header
.
Value
.
ToLower
()
==
"websocket"
;
{
return
true
;
}
return
false
;
}
}
}
}
...
@@ -305,6 +290,9 @@ namespace Titanium.Web.Proxy.Http
...
@@ -305,6 +290,9 @@ namespace Titanium.Web.Proxy.Http
/// </summary>
/// </summary>
public
bool
ExpectationFailed
{
get
;
internal
set
;
}
public
bool
ExpectationFailed
{
get
;
internal
set
;
}
/// <summary>
/// Constructor.
/// </summary>
public
Request
()
public
Request
()
{
{
RequestHeaders
=
new
Dictionary
<
string
,
HttpHeader
>(
StringComparer
.
OrdinalIgnoreCase
);
RequestHeaders
=
new
Dictionary
<
string
,
HttpHeader
>(
StringComparer
.
OrdinalIgnoreCase
);
...
...
Titanium.Web.Proxy/Http/Response.cs
View file @
1057c2ff
...
@@ -12,7 +12,13 @@ namespace Titanium.Web.Proxy.Http
...
@@ -12,7 +12,13 @@ namespace Titanium.Web.Proxy.Http
/// </summary>
/// </summary>
public
class
Response
public
class
Response
{
{
/// <summary>
/// Response Status Code.
/// </summary>
public
string
ResponseStatusCode
{
get
;
set
;
}
public
string
ResponseStatusCode
{
get
;
set
;
}
/// <summary>
/// Response Status description.
/// </summary>
public
string
ResponseStatusDescription
{
get
;
set
;
}
public
string
ResponseStatusDescription
{
get
;
set
;
}
internal
Encoding
Encoding
=>
this
.
GetResponseCharacterEncoding
();
internal
Encoding
Encoding
=>
this
.
GetResponseCharacterEncoding
();
...
@@ -26,14 +32,10 @@ namespace Titanium.Web.Proxy.Http
...
@@ -26,14 +32,10 @@ namespace Titanium.Web.Proxy.Http
{
{
var
hasHeader
=
ResponseHeaders
.
ContainsKey
(
"content-encoding"
);
var
hasHeader
=
ResponseHeaders
.
ContainsKey
(
"content-encoding"
);
if
(
hasHeader
)
if
(!
hasHeader
)
return
null
;
{
var
header
=
ResponseHeaders
[
"content-encoding"
];
var
header
=
ResponseHeaders
[
"content-encoding"
];
return
header
.
Value
.
Trim
();
return
header
.
Value
.
Trim
();
}
return
null
;
}
}
}
}
...
@@ -229,10 +231,13 @@ namespace Titanium.Web.Proxy.Http
...
@@ -229,10 +231,13 @@ namespace Titanium.Web.Proxy.Http
/// </summary>
/// </summary>
public
bool
ExpectationFailed
{
get
;
internal
set
;
}
public
bool
ExpectationFailed
{
get
;
internal
set
;
}
/// <summary>
/// Constructor.
/// </summary>
public
Response
()
public
Response
()
{
{
this
.
ResponseHeaders
=
new
Dictionary
<
string
,
HttpHeader
>(
StringComparer
.
OrdinalIgnoreCase
);
ResponseHeaders
=
new
Dictionary
<
string
,
HttpHeader
>(
StringComparer
.
OrdinalIgnoreCase
);
this
.
NonUniqueResponseHeaders
=
new
Dictionary
<
string
,
List
<
HttpHeader
>>(
StringComparer
.
OrdinalIgnoreCase
);
NonUniqueResponseHeaders
=
new
Dictionary
<
string
,
List
<
HttpHeader
>>(
StringComparer
.
OrdinalIgnoreCase
);
}
}
}
}
...
...
Titanium.Web.Proxy/Http/Responses/GenericResponse.cs
View file @
1057c2ff
...
@@ -7,16 +7,25 @@ namespace Titanium.Web.Proxy.Http.Responses
...
@@ -7,16 +7,25 @@ namespace Titanium.Web.Proxy.Http.Responses
/// </summary>
/// </summary>
public
class
GenericResponse
:
Response
public
class
GenericResponse
:
Response
{
{
/// <summary>
/// Constructor.
/// </summary>
/// <param name="status"></param>
public
GenericResponse
(
HttpStatusCode
status
)
public
GenericResponse
(
HttpStatusCode
status
)
{
{
ResponseStatusCode
=
((
int
)
status
).
ToString
();
ResponseStatusCode
=
((
int
)
status
).
ToString
();
ResponseStatusDescription
=
status
.
ToString
();
ResponseStatusDescription
=
status
.
ToString
();
}
}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="statusCode"></param>
/// <param name="statusDescription"></param>
public
GenericResponse
(
string
statusCode
,
string
statusDescription
)
public
GenericResponse
(
string
statusCode
,
string
statusDescription
)
{
{
ResponseStatusCode
=
statusCode
;
ResponseStatusCode
=
statusCode
;
ResponseStatusDescription
=
statusCode
;
ResponseStatusDescription
=
statusDescription
;
}
}
}
}
}
}
Titanium.Web.Proxy/Http/Responses/OkResponse.cs
View file @
1057c2ff
...
@@ -5,6 +5,9 @@
...
@@ -5,6 +5,9 @@
/// </summary>
/// </summary>
public
sealed
class
OkResponse
:
Response
public
sealed
class
OkResponse
:
Response
{
{
/// <summary>
/// Constructor.
/// </summary>
public
OkResponse
()
public
OkResponse
()
{
{
ResponseStatusCode
=
"200"
;
ResponseStatusCode
=
"200"
;
...
...
Titanium.Web.Proxy/Http/Responses/RedirectResponse.cs
View file @
1057c2ff
...
@@ -5,6 +5,9 @@
...
@@ -5,6 +5,9 @@
/// </summary>
/// </summary>
public
sealed
class
RedirectResponse
:
Response
public
sealed
class
RedirectResponse
:
Response
{
{
/// <summary>
/// Constructor.
/// </summary>
public
RedirectResponse
()
public
RedirectResponse
()
{
{
ResponseStatusCode
=
"302"
;
ResponseStatusCode
=
"302"
;
...
...
Titanium.Web.Proxy/Models/EndPoint.cs
View file @
1057c2ff
...
@@ -10,20 +10,38 @@ namespace Titanium.Web.Proxy.Models
...
@@ -10,20 +10,38 @@ namespace Titanium.Web.Proxy.Models
/// </summary>
/// </summary>
public
abstract
class
ProxyEndPoint
public
abstract
class
ProxyEndPoint
{
{
public
ProxyEndPoint
(
IPAddress
IpAddress
,
int
Port
,
bool
EnableSsl
)
/// <summary>
/// Constructor.
/// </summary>
/// <param name="IpAddress"></param>
/// <param name="Port"></param>
/// <param name="EnableSsl"></param>
protected
ProxyEndPoint
(
IPAddress
IpAddress
,
int
Port
,
bool
EnableSsl
)
{
{
this
.
IpAddress
=
IpAddress
;
this
.
IpAddress
=
IpAddress
;
this
.
Port
=
Port
;
this
.
Port
=
Port
;
this
.
EnableSsl
=
EnableSsl
;
this
.
EnableSsl
=
EnableSsl
;
}
}
/// <summary>
/// Ip Address.
/// </summary>
public
IPAddress
IpAddress
{
get
;
internal
set
;
}
public
IPAddress
IpAddress
{
get
;
internal
set
;
}
/// <summary>
/// Port.
/// </summary>
public
int
Port
{
get
;
internal
set
;
}
public
int
Port
{
get
;
internal
set
;
}
/// <summary>
/// Enable SSL?
/// </summary>
public
bool
EnableSsl
{
get
;
internal
set
;
}
public
bool
EnableSsl
{
get
;
internal
set
;
}
public
bool
IpV6Enabled
=>
IpAddress
==
IPAddress
.
IPv6Any
/// <summary>
||
IpAddress
==
IPAddress
.
IPv6Loopback
/// Is IPv6 enabled?
||
IpAddress
==
IPAddress
.
IPv6None
;
/// </summary>
public
bool
IpV6Enabled
=>
Equals
(
IpAddress
,
IPAddress
.
IPv6Any
)
||
Equals
(
IpAddress
,
IPAddress
.
IPv6Loopback
)
||
Equals
(
IpAddress
,
IPAddress
.
IPv6None
);
internal
TcpListener
listener
{
get
;
set
;
}
internal
TcpListener
listener
{
get
;
set
;
}
}
}
...
@@ -37,14 +55,26 @@ namespace Titanium.Web.Proxy.Models
...
@@ -37,14 +55,26 @@ namespace Titanium.Web.Proxy.Models
internal
bool
IsSystemHttpProxy
{
get
;
set
;
}
internal
bool
IsSystemHttpProxy
{
get
;
set
;
}
internal
bool
IsSystemHttpsProxy
{
get
;
set
;
}
internal
bool
IsSystemHttpsProxy
{
get
;
set
;
}
public
List
<
string
>
ExcludedHttpsHostNameRegex
{
get
;
set
;
}
/// <summary>
/// List of host names to exclude using Regular Expressions.
/// </summary>
public
List
<
string
>
ExcludedHttpsHostNameRegex
{
get
;
set
;
}
/// <summary>
/// Generic certificate to use for SSL decryption.
/// </summary>
public
X509Certificate2
GenericCertificate
{
get
;
set
;
}
public
X509Certificate2
GenericCertificate
{
get
;
set
;
}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="IpAddress"></param>
/// <param name="Port"></param>
/// <param name="EnableSsl"></param>
public
ExplicitProxyEndPoint
(
IPAddress
IpAddress
,
int
Port
,
bool
EnableSsl
)
public
ExplicitProxyEndPoint
(
IPAddress
IpAddress
,
int
Port
,
bool
EnableSsl
)
:
base
(
IpAddress
,
Port
,
EnableSsl
)
:
base
(
IpAddress
,
Port
,
EnableSsl
)
{
{
}
}
}
}
...
@@ -54,13 +84,19 @@ namespace Titanium.Web.Proxy.Models
...
@@ -54,13 +84,19 @@ namespace Titanium.Web.Proxy.Models
/// </summary>
/// </summary>
public
class
TransparentProxyEndPoint
:
ProxyEndPoint
public
class
TransparentProxyEndPoint
:
ProxyEndPoint
{
{
//Name of the Certificate need to be sent (same as the hostname we want to proxy)
//This is valid only when UseServerNameIndication is set to false
public
string
GenericCertificateName
{
get
;
set
;
}
/// <summary>
// public bool UseServerNameIndication { get; set; }
/// Name of the Certificate need to be sent (same as the hostname we want to proxy)
/// This is valid only when UseServerNameIndication is set to false
/// </summary>
public
string
GenericCertificateName
{
get
;
set
;
}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="IpAddress"></param>
/// <param name="Port"></param>
/// <param name="EnableSsl"></param>
public
TransparentProxyEndPoint
(
IPAddress
IpAddress
,
int
Port
,
bool
EnableSsl
)
public
TransparentProxyEndPoint
(
IPAddress
IpAddress
,
int
Port
,
bool
EnableSsl
)
:
base
(
IpAddress
,
Port
,
EnableSsl
)
:
base
(
IpAddress
,
Port
,
EnableSsl
)
{
{
...
...
Titanium.Web.Proxy/Models/ExternalProxy.cs
View file @
1057c2ff
...
@@ -13,10 +13,16 @@ namespace Titanium.Web.Proxy.Models
...
@@ -13,10 +13,16 @@ namespace Titanium.Web.Proxy.Models
private
string
userName
;
private
string
userName
;
private
string
password
;
private
string
password
;
/// <summary>
/// Use default windows credentials?
/// </summary>
public
bool
UseDefaultCredentials
{
get
;
set
;
}
public
bool
UseDefaultCredentials
{
get
;
set
;
}
/// <summary>
/// Username.
/// </summary>
public
string
UserName
{
public
string
UserName
{
get
{
return
UseDefaultCredentials
?
DefaultCredentials
.
Value
.
UserName
:
userName
;
}
get
=>
UseDefaultCredentials
?
DefaultCredentials
.
Value
.
UserName
:
userName
;
set
set
{
{
userName
=
value
;
userName
=
value
;
...
@@ -28,9 +34,12 @@ namespace Titanium.Web.Proxy.Models
...
@@ -28,9 +34,12 @@ namespace Titanium.Web.Proxy.Models
}
}
}
}
/// <summary>
/// Password.
/// </summary>
public
string
Password
public
string
Password
{
{
get
{
return
UseDefaultCredentials
?
DefaultCredentials
.
Value
.
Password
:
password
;
}
get
=>
UseDefaultCredentials
?
DefaultCredentials
.
Value
.
Password
:
password
;
set
set
{
{
password
=
value
;
password
=
value
;
...
@@ -42,7 +51,13 @@ namespace Titanium.Web.Proxy.Models
...
@@ -42,7 +51,13 @@ namespace Titanium.Web.Proxy.Models
}
}
}
}
/// <summary>
/// Host name.
/// </summary>
public
string
HostName
{
get
;
set
;
}
public
string
HostName
{
get
;
set
;
}
/// <summary>
/// Port.
/// </summary>
public
int
Port
{
get
;
set
;
}
public
int
Port
{
get
;
set
;
}
}
}
}
}
Titanium.Web.Proxy/Models/HttpHeader.cs
View file @
1057c2ff
...
@@ -7,6 +7,12 @@ namespace Titanium.Web.Proxy.Models
...
@@ -7,6 +7,12 @@ namespace Titanium.Web.Proxy.Models
/// </summary>
/// </summary>
public
class
HttpHeader
public
class
HttpHeader
{
{
/// <summary>
/// Constructor.
/// </summary>
/// <param name="name"></param>
/// <param name="value"></param>
/// <exception cref="Exception"></exception>
public
HttpHeader
(
string
name
,
string
value
)
public
HttpHeader
(
string
name
,
string
value
)
{
{
if
(
string
.
IsNullOrEmpty
(
name
))
if
(
string
.
IsNullOrEmpty
(
name
))
...
@@ -18,7 +24,13 @@ namespace Titanium.Web.Proxy.Models
...
@@ -18,7 +24,13 @@ namespace Titanium.Web.Proxy.Models
Value
=
value
.
Trim
();
Value
=
value
.
Trim
();
}
}
/// <summary>
/// Header Name.
/// </summary>
public
string
Name
{
get
;
set
;
}
public
string
Name
{
get
;
set
;
}
/// <summary>
/// Header Value.
/// </summary>
public
string
Value
{
get
;
set
;
}
public
string
Value
{
get
;
set
;
}
/// <summary>
/// <summary>
...
@@ -27,7 +39,7 @@ namespace Titanium.Web.Proxy.Models
...
@@ -27,7 +39,7 @@ namespace Titanium.Web.Proxy.Models
/// <returns></returns>
/// <returns></returns>
public
override
string
ToString
()
public
override
string
ToString
()
{
{
return
string
.
Format
(
"{0}: {1}"
,
Name
,
Value
)
;
return
$"
{
Name
}
:
{
Value
}
"
;
}
}
}
}
}
}
\ No newline at end of file
Titanium.Web.Proxy/Network/CertificateMaker.cs
View file @
1057c2ff
...
@@ -6,187 +6,197 @@ using System.Threading;
...
@@ -6,187 +6,197 @@ using System.Threading;
namespace
Titanium.Web.Proxy.Network
namespace
Titanium.Web.Proxy.Network
{
{
/// <summary>
/// Certificate Maker - uses MakeCert
/// </summary>
public
class
CertificateMaker
public
class
CertificateMaker
{
{
private
Type
typeX500DN
;
private
readonly
Type
typeX500DN
;
private
Type
typeX509PrivateKey
;
private
readonly
Type
typeX509PrivateKey
;
private
Type
typeOID
;
private
readonly
Type
typeOID
;
private
Type
typeOIDS
;
private
readonly
Type
typeOIDS
;
private
Type
typeKUExt
;
private
readonly
Type
typeKUExt
;
private
Type
typeEKUExt
;
private
readonly
Type
typeEKUExt
;
private
Type
typeRequestCert
;
private
readonly
Type
typeRequestCert
;
private
Type
typeX509Extensions
;
private
readonly
Type
typeX509Extensions
;
private
Type
typeBasicConstraints
;
private
readonly
Type
typeBasicConstraints
;
private
Type
typeSignerCertificate
;
private
readonly
Type
typeSignerCertificate
;
private
Type
typeX509Enrollment
;
private
readonly
Type
typeX509Enrollment
;
private
Type
typeAlternativeName
;
//
private Type typeAlternativeName;
private
Type
typeAlternativeNames
;
//
private Type typeAlternativeNames;
private
Type
typeAlternativeNamesExt
;
//
private Type typeAlternativeNamesExt;
private
string
sProviderName
=
"Microsoft Enhanced Cryptographic Provider v1.0"
;
private
readonly
string
sProviderName
=
"Microsoft Enhanced Cryptographic Provider v1.0"
;
private
object
_SharedPrivateKey
;
private
object
_SharedPrivateKey
;
/// <summary>
/// Constructor.
/// </summary>
public
CertificateMaker
()
public
CertificateMaker
()
{
{
t
his
.
t
ypeX500DN
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CX500DistinguishedName"
,
true
);
typeX500DN
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CX500DistinguishedName"
,
true
);
t
his
.
t
ypeX509PrivateKey
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CX509PrivateKey"
,
true
);
typeX509PrivateKey
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CX509PrivateKey"
,
true
);
t
his
.
t
ypeOID
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CObjectId"
,
true
);
typeOID
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CObjectId"
,
true
);
t
his
.
t
ypeOIDS
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CObjectIds.1"
,
true
);
typeOIDS
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CObjectIds.1"
,
true
);
t
his
.
t
ypeEKUExt
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CX509ExtensionEnhancedKeyUsage"
);
typeEKUExt
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CX509ExtensionEnhancedKeyUsage"
);
t
his
.
t
ypeKUExt
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CX509ExtensionKeyUsage"
);
typeKUExt
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CX509ExtensionKeyUsage"
);
t
his
.
t
ypeRequestCert
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CX509CertificateRequestCertificate"
);
typeRequestCert
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CX509CertificateRequestCertificate"
);
t
his
.
t
ypeX509Extensions
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CX509Extensions"
);
typeX509Extensions
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CX509Extensions"
);
t
his
.
t
ypeBasicConstraints
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CX509ExtensionBasicConstraints"
);
typeBasicConstraints
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CX509ExtensionBasicConstraints"
);
t
his
.
t
ypeSignerCertificate
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CSignerCertificate"
);
typeSignerCertificate
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CSignerCertificate"
);
t
his
.
t
ypeX509Enrollment
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CX509Enrollment"
);
typeX509Enrollment
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CX509Enrollment"
);
this
.
typeAlternativeName
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CAlternativeName"
);
//
this.typeAlternativeName = Type.GetTypeFromProgID("X509Enrollment.CAlternativeName");
this
.
typeAlternativeNames
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CAlternativeNames"
);
//
this.typeAlternativeNames = Type.GetTypeFromProgID("X509Enrollment.CAlternativeNames");
this
.
typeAlternativeNamesExt
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CX509ExtensionAlternativeNames"
);
//
this.typeAlternativeNamesExt = Type.GetTypeFromProgID("X509Enrollment.CX509ExtensionAlternativeNames");
}
}
/// <summary>
/// Make certificate.
/// </summary>
/// <param name="sSubjectCN"></param>
/// <param name="isRoot"></param>
/// <param name="signingCert"></param>
/// <returns></returns>
public
X509Certificate2
MakeCertificate
(
string
sSubjectCN
,
bool
isRoot
,
X509Certificate2
signingCert
=
null
)
public
X509Certificate2
MakeCertificate
(
string
sSubjectCN
,
bool
isRoot
,
X509Certificate2
signingCert
=
null
)
{
{
return
this
.
MakeCertificateInternal
(
sSubjectCN
,
isRoot
,
true
,
signingCert
);
return
MakeCertificateInternal
(
sSubjectCN
,
isRoot
,
true
,
signingCert
);
}
}
private
X509Certificate2
MakeCertificate
(
bool
IsRoot
,
string
SubjectCN
,
string
FullSubject
,
int
PrivateKeyLength
,
string
HashAlg
,
DateTime
ValidFrom
,
DateTime
ValidTo
,
X509Certificate2
SigningCertificate
)
private
X509Certificate2
MakeCertificate
(
bool
IsRoot
,
string
FullSubject
,
int
PrivateKeyLength
,
string
HashAlg
,
DateTime
ValidFrom
,
DateTime
ValidTo
,
X509Certificate2
SigningCertificate
)
{
{
X509Certificate2
cert
;
if
(
IsRoot
!=
(
null
==
SigningCertificate
))
if
(
IsRoot
!=
(
null
==
SigningCertificate
))
{
{
throw
new
ArgumentException
(
"You must specify a Signing Certificate if and only if you are not creating a root."
,
"oSigningCertificate"
);
throw
new
ArgumentException
(
"You must specify a Signing Certificate if and only if you are not creating a root."
,
nameof
(
IsRoot
)
);
}
}
object
x500DN
=
Activator
.
CreateInstance
(
this
.
typeX500DN
);
var
x500DN
=
Activator
.
CreateInstance
(
typeX500DN
);
object
[]
subject
=
new
object
[]
{
FullSubject
,
0
};
var
subject
=
new
object
[]
{
FullSubject
,
0
};
t
his
.
t
ypeX500DN
.
InvokeMember
(
"Encode"
,
BindingFlags
.
InvokeMethod
,
null
,
x500DN
,
subject
);
typeX500DN
.
InvokeMember
(
"Encode"
,
BindingFlags
.
InvokeMethod
,
null
,
x500DN
,
subject
);
object
x500DN2
=
Activator
.
CreateInstance
(
this
.
typeX500DN
);
var
x500DN2
=
Activator
.
CreateInstance
(
typeX500DN
);
if
(!
IsRoot
)
if
(!
IsRoot
)
{
{
subject
[
0
]
=
SigningCertificate
.
Subject
;
subject
[
0
]
=
SigningCertificate
.
Subject
;
}
}
t
his
.
t
ypeX500DN
.
InvokeMember
(
"Encode"
,
BindingFlags
.
InvokeMethod
,
null
,
x500DN2
,
subject
);
typeX500DN
.
InvokeMember
(
"Encode"
,
BindingFlags
.
InvokeMethod
,
null
,
x500DN2
,
subject
);
object
sharedPrivateKey
=
null
;
object
sharedPrivateKey
=
null
;
if
(!
IsRoot
)
if
(!
IsRoot
)
{
{
sharedPrivateKey
=
this
.
_SharedPrivateKey
;
sharedPrivateKey
=
_SharedPrivateKey
;
}
}
if
(
sharedPrivateKey
==
null
)
if
(
sharedPrivateKey
==
null
)
{
{
sharedPrivateKey
=
Activator
.
CreateInstance
(
t
his
.
t
ypeX509PrivateKey
);
sharedPrivateKey
=
Activator
.
CreateInstance
(
typeX509PrivateKey
);
subject
=
new
object
[]
{
this
.
sProviderName
};
subject
=
new
object
[]
{
sProviderName
};
t
his
.
t
ypeX509PrivateKey
.
InvokeMember
(
"ProviderName"
,
BindingFlags
.
PutDispProperty
,
null
,
sharedPrivateKey
,
subject
);
typeX509PrivateKey
.
InvokeMember
(
"ProviderName"
,
BindingFlags
.
PutDispProperty
,
null
,
sharedPrivateKey
,
subject
);
subject
[
0
]
=
2
;
subject
[
0
]
=
2
;
t
his
.
t
ypeX509PrivateKey
.
InvokeMember
(
"ExportPolicy"
,
BindingFlags
.
PutDispProperty
,
null
,
sharedPrivateKey
,
subject
);
typeX509PrivateKey
.
InvokeMember
(
"ExportPolicy"
,
BindingFlags
.
PutDispProperty
,
null
,
sharedPrivateKey
,
subject
);
subject
=
new
object
[]
{
(
IsRoot
?
2
:
1
)
};
subject
=
new
object
[]
{
(
IsRoot
?
2
:
1
)
};
t
his
.
t
ypeX509PrivateKey
.
InvokeMember
(
"KeySpec"
,
BindingFlags
.
PutDispProperty
,
null
,
sharedPrivateKey
,
subject
);
typeX509PrivateKey
.
InvokeMember
(
"KeySpec"
,
BindingFlags
.
PutDispProperty
,
null
,
sharedPrivateKey
,
subject
);
if
(!
IsRoot
)
if
(!
IsRoot
)
{
{
subject
=
new
object
[]
{
176
};
subject
=
new
object
[]
{
176
};
t
his
.
t
ypeX509PrivateKey
.
InvokeMember
(
"KeyUsage"
,
BindingFlags
.
PutDispProperty
,
null
,
sharedPrivateKey
,
subject
);
typeX509PrivateKey
.
InvokeMember
(
"KeyUsage"
,
BindingFlags
.
PutDispProperty
,
null
,
sharedPrivateKey
,
subject
);
}
}
subject
[
0
]
=
PrivateKeyLength
;
subject
[
0
]
=
PrivateKeyLength
;
t
his
.
t
ypeX509PrivateKey
.
InvokeMember
(
"Length"
,
BindingFlags
.
PutDispProperty
,
null
,
sharedPrivateKey
,
subject
);
typeX509PrivateKey
.
InvokeMember
(
"Length"
,
BindingFlags
.
PutDispProperty
,
null
,
sharedPrivateKey
,
subject
);
t
his
.
t
ypeX509PrivateKey
.
InvokeMember
(
"Create"
,
BindingFlags
.
InvokeMethod
,
null
,
sharedPrivateKey
,
null
);
typeX509PrivateKey
.
InvokeMember
(
"Create"
,
BindingFlags
.
InvokeMethod
,
null
,
sharedPrivateKey
,
null
);
if
(!
IsRoot
)
if
(!
IsRoot
)
{
{
this
.
_SharedPrivateKey
=
sharedPrivateKey
;
_SharedPrivateKey
=
sharedPrivateKey
;
}
}
}
}
subject
=
new
object
[
1
];
subject
=
new
object
[
1
];
object
obj3
=
Activator
.
CreateInstance
(
this
.
typeOID
);
var
obj3
=
Activator
.
CreateInstance
(
typeOID
);
subject
[
0
]
=
"1.3.6.1.5.5.7.3.1"
;
subject
[
0
]
=
"1.3.6.1.5.5.7.3.1"
;
t
his
.
t
ypeOID
.
InvokeMember
(
"InitializeFromValue"
,
BindingFlags
.
InvokeMethod
,
null
,
obj3
,
subject
);
typeOID
.
InvokeMember
(
"InitializeFromValue"
,
BindingFlags
.
InvokeMethod
,
null
,
obj3
,
subject
);
object
obj4
=
Activator
.
CreateInstance
(
this
.
typeOIDS
);
var
obj4
=
Activator
.
CreateInstance
(
typeOIDS
);
subject
[
0
]
=
obj3
;
subject
[
0
]
=
obj3
;
t
his
.
t
ypeOIDS
.
InvokeMember
(
"Add"
,
BindingFlags
.
InvokeMethod
,
null
,
obj4
,
subject
);
typeOIDS
.
InvokeMember
(
"Add"
,
BindingFlags
.
InvokeMethod
,
null
,
obj4
,
subject
);
object
obj5
=
Activator
.
CreateInstance
(
this
.
typeEKUExt
);
var
obj5
=
Activator
.
CreateInstance
(
typeEKUExt
);
subject
[
0
]
=
obj4
;
subject
[
0
]
=
obj4
;
t
his
.
t
ypeEKUExt
.
InvokeMember
(
"InitializeEncode"
,
BindingFlags
.
InvokeMethod
,
null
,
obj5
,
subject
);
typeEKUExt
.
InvokeMember
(
"InitializeEncode"
,
BindingFlags
.
InvokeMethod
,
null
,
obj5
,
subject
);
object
obj6
=
Activator
.
CreateInstance
(
this
.
typeRequestCert
);
var
obj6
=
Activator
.
CreateInstance
(
typeRequestCert
);
subject
=
new
object
[]
{
1
,
sharedPrivateKey
,
string
.
Empty
};
subject
=
new
[]
{
1
,
sharedPrivateKey
,
string
.
Empty
};
t
his
.
t
ypeRequestCert
.
InvokeMember
(
"InitializeFromPrivateKey"
,
BindingFlags
.
InvokeMethod
,
null
,
obj6
,
subject
);
typeRequestCert
.
InvokeMember
(
"InitializeFromPrivateKey"
,
BindingFlags
.
InvokeMethod
,
null
,
obj6
,
subject
);
subject
=
new
object
[]
{
x500DN
};
subject
=
new
[]
{
x500DN
};
t
his
.
t
ypeRequestCert
.
InvokeMember
(
"Subject"
,
BindingFlags
.
PutDispProperty
,
null
,
obj6
,
subject
);
typeRequestCert
.
InvokeMember
(
"Subject"
,
BindingFlags
.
PutDispProperty
,
null
,
obj6
,
subject
);
subject
[
0
]
=
x500DN
;
subject
[
0
]
=
x500DN
;
t
his
.
t
ypeRequestCert
.
InvokeMember
(
"Issuer"
,
BindingFlags
.
PutDispProperty
,
null
,
obj6
,
subject
);
typeRequestCert
.
InvokeMember
(
"Issuer"
,
BindingFlags
.
PutDispProperty
,
null
,
obj6
,
subject
);
subject
[
0
]
=
ValidFrom
;
subject
[
0
]
=
ValidFrom
;
t
his
.
t
ypeRequestCert
.
InvokeMember
(
"NotBefore"
,
BindingFlags
.
PutDispProperty
,
null
,
obj6
,
subject
);
typeRequestCert
.
InvokeMember
(
"NotBefore"
,
BindingFlags
.
PutDispProperty
,
null
,
obj6
,
subject
);
subject
[
0
]
=
ValidTo
;
subject
[
0
]
=
ValidTo
;
t
his
.
t
ypeRequestCert
.
InvokeMember
(
"NotAfter"
,
BindingFlags
.
PutDispProperty
,
null
,
obj6
,
subject
);
typeRequestCert
.
InvokeMember
(
"NotAfter"
,
BindingFlags
.
PutDispProperty
,
null
,
obj6
,
subject
);
object
obj7
=
Activator
.
CreateInstance
(
this
.
typeKUExt
);
var
obj7
=
Activator
.
CreateInstance
(
typeKUExt
);
subject
[
0
]
=
176
;
subject
[
0
]
=
176
;
t
his
.
t
ypeKUExt
.
InvokeMember
(
"InitializeEncode"
,
BindingFlags
.
InvokeMethod
,
null
,
obj7
,
subject
);
typeKUExt
.
InvokeMember
(
"InitializeEncode"
,
BindingFlags
.
InvokeMethod
,
null
,
obj7
,
subject
);
object
obj8
=
this
.
typeRequestCert
.
InvokeMember
(
"X509Extensions"
,
BindingFlags
.
GetProperty
,
null
,
obj6
,
null
);
var
obj8
=
typeRequestCert
.
InvokeMember
(
"X509Extensions"
,
BindingFlags
.
GetProperty
,
null
,
obj6
,
null
);
subject
=
new
object
[
1
];
subject
=
new
object
[
1
];
if
(!
IsRoot
)
if
(!
IsRoot
)
{
{
subject
[
0
]
=
obj7
;
subject
[
0
]
=
obj7
;
t
his
.
t
ypeX509Extensions
.
InvokeMember
(
"Add"
,
BindingFlags
.
InvokeMethod
,
null
,
obj8
,
subject
);
typeX509Extensions
.
InvokeMember
(
"Add"
,
BindingFlags
.
InvokeMethod
,
null
,
obj8
,
subject
);
}
}
subject
[
0
]
=
obj5
;
subject
[
0
]
=
obj5
;
t
his
.
t
ypeX509Extensions
.
InvokeMember
(
"Add"
,
BindingFlags
.
InvokeMethod
,
null
,
obj8
,
subject
);
typeX509Extensions
.
InvokeMember
(
"Add"
,
BindingFlags
.
InvokeMethod
,
null
,
obj8
,
subject
);
if
(!
IsRoot
)
if
(!
IsRoot
)
{
{
object
obj12
=
Activator
.
CreateInstance
(
this
.
typeSignerCertificate
);
var
obj12
=
Activator
.
CreateInstance
(
typeSignerCertificate
);
subject
=
new
object
[]
{
0
,
0
,
12
,
SigningCertificate
.
Thumbprint
};
subject
=
new
object
[]
{
0
,
0
,
12
,
SigningCertificate
.
Thumbprint
};
t
his
.
t
ypeSignerCertificate
.
InvokeMember
(
"Initialize"
,
BindingFlags
.
InvokeMethod
,
null
,
obj12
,
subject
);
typeSignerCertificate
.
InvokeMember
(
"Initialize"
,
BindingFlags
.
InvokeMethod
,
null
,
obj12
,
subject
);
subject
=
new
object
[]
{
obj12
};
subject
=
new
[]
{
obj12
};
t
his
.
t
ypeRequestCert
.
InvokeMember
(
"SignerCertificate"
,
BindingFlags
.
PutDispProperty
,
null
,
obj6
,
subject
);
typeRequestCert
.
InvokeMember
(
"SignerCertificate"
,
BindingFlags
.
PutDispProperty
,
null
,
obj6
,
subject
);
}
}
else
else
{
{
object
obj13
=
Activator
.
CreateInstance
(
this
.
typeBasicConstraints
);
var
obj13
=
Activator
.
CreateInstance
(
typeBasicConstraints
);
subject
=
new
object
[]
{
"true"
,
"0"
};
subject
=
new
object
[]
{
"true"
,
"0"
};
t
his
.
t
ypeBasicConstraints
.
InvokeMember
(
"InitializeEncode"
,
BindingFlags
.
InvokeMethod
,
null
,
obj13
,
subject
);
typeBasicConstraints
.
InvokeMember
(
"InitializeEncode"
,
BindingFlags
.
InvokeMethod
,
null
,
obj13
,
subject
);
subject
=
new
object
[]
{
obj13
};
subject
=
new
[]
{
obj13
};
t
his
.
t
ypeX509Extensions
.
InvokeMember
(
"Add"
,
BindingFlags
.
InvokeMethod
,
null
,
obj8
,
subject
);
typeX509Extensions
.
InvokeMember
(
"Add"
,
BindingFlags
.
InvokeMethod
,
null
,
obj8
,
subject
);
}
}
object
obj14
=
Activator
.
CreateInstance
(
this
.
typeOID
);
var
obj14
=
Activator
.
CreateInstance
(
typeOID
);
subject
=
new
object
[]
{
1
,
0
,
0
,
HashAlg
};
subject
=
new
object
[]
{
1
,
0
,
0
,
HashAlg
};
t
his
.
t
ypeOID
.
InvokeMember
(
"InitializeFromAlgorithmName"
,
BindingFlags
.
InvokeMethod
,
null
,
obj14
,
subject
);
typeOID
.
InvokeMember
(
"InitializeFromAlgorithmName"
,
BindingFlags
.
InvokeMethod
,
null
,
obj14
,
subject
);
subject
=
new
object
[]
{
obj14
};
subject
=
new
[]
{
obj14
};
t
his
.
t
ypeRequestCert
.
InvokeMember
(
"HashAlgorithm"
,
BindingFlags
.
PutDispProperty
,
null
,
obj6
,
subject
);
typeRequestCert
.
InvokeMember
(
"HashAlgorithm"
,
BindingFlags
.
PutDispProperty
,
null
,
obj6
,
subject
);
t
his
.
t
ypeRequestCert
.
InvokeMember
(
"Encode"
,
BindingFlags
.
InvokeMethod
,
null
,
obj6
,
null
);
typeRequestCert
.
InvokeMember
(
"Encode"
,
BindingFlags
.
InvokeMethod
,
null
,
obj6
,
null
);
object
obj15
=
Activator
.
CreateInstance
(
this
.
typeX509Enrollment
);
var
obj15
=
Activator
.
CreateInstance
(
typeX509Enrollment
);
subject
[
0
]
=
obj6
;
subject
[
0
]
=
obj6
;
t
his
.
t
ypeX509Enrollment
.
InvokeMember
(
"InitializeFromRequest"
,
BindingFlags
.
InvokeMethod
,
null
,
obj15
,
subject
);
typeX509Enrollment
.
InvokeMember
(
"InitializeFromRequest"
,
BindingFlags
.
InvokeMethod
,
null
,
obj15
,
subject
);
if
(
IsRoot
)
if
(
IsRoot
)
{
{
subject
[
0
]
=
"DO_NOT_TRUST_TitaniumProxy-CE"
;
subject
[
0
]
=
"DO_NOT_TRUST_TitaniumProxy-CE"
;
t
his
.
t
ypeX509Enrollment
.
InvokeMember
(
"CertificateFriendlyName"
,
BindingFlags
.
PutDispProperty
,
null
,
obj15
,
subject
);
typeX509Enrollment
.
InvokeMember
(
"CertificateFriendlyName"
,
BindingFlags
.
PutDispProperty
,
null
,
obj15
,
subject
);
}
}
subject
[
0
]
=
0
;
subject
[
0
]
=
0
;
object
obj16
=
this
.
typeX509Enrollment
.
InvokeMember
(
"CreateRequest"
,
BindingFlags
.
InvokeMethod
,
null
,
obj15
,
subject
);
var
obj16
=
typeX509Enrollment
.
InvokeMember
(
"CreateRequest"
,
BindingFlags
.
InvokeMethod
,
null
,
obj15
,
subject
);
subject
=
new
object
[]
{
2
,
obj16
,
0
,
string
.
Empty
};
subject
=
new
[]
{
2
,
obj16
,
0
,
string
.
Empty
};
t
his
.
t
ypeX509Enrollment
.
InvokeMember
(
"InstallResponse"
,
BindingFlags
.
InvokeMethod
,
null
,
obj15
,
subject
);
typeX509Enrollment
.
InvokeMember
(
"InstallResponse"
,
BindingFlags
.
InvokeMethod
,
null
,
obj15
,
subject
);
subject
=
new
object
[]
{
null
,
0
,
1
};
subject
=
new
object
[]
{
null
,
0
,
1
};
string
empty
=
string
.
Empty
;
try
try
{
{
empty
=
(
string
)
this
.
typeX509Enrollment
.
InvokeMember
(
"CreatePFX"
,
BindingFlags
.
InvokeMethod
,
null
,
obj15
,
subject
);
var
empty
=
(
string
)
typeX509Enrollment
.
InvokeMember
(
"CreatePFX"
,
BindingFlags
.
InvokeMethod
,
null
,
obj15
,
subject
);
return
new
X509Certificate2
(
Convert
.
FromBase64String
(
empty
),
string
.
Empty
,
X509KeyStorageFlags
.
Exportable
);
return
new
X509Certificate2
(
Convert
.
FromBase64String
(
empty
),
string
.
Empty
,
X509KeyStorageFlags
.
Exportable
);
}
}
catch
(
Exception
exception1
)
catch
(
Exception
)
{
{
Exception
exception
=
exception1
;
// ignored
cert
=
null
;
}
}
return
cert
;
return
null
;
}
}
private
X509Certificate2
MakeCertificateInternal
(
string
sSubjectCN
,
bool
isRoot
,
bool
switchToMTAIfNeeded
,
X509Certificate2
signingCert
=
null
)
private
X509Certificate2
MakeCertificateInternal
(
string
sSubjectCN
,
bool
isRoot
,
bool
switchToMTAIfNeeded
,
X509Certificate2
signingCert
=
null
)
...
@@ -194,39 +204,26 @@ namespace Titanium.Web.Proxy.Network
...
@@ -194,39 +204,26 @@ namespace Titanium.Web.Proxy.Network
X509Certificate2
rCert
=
null
;
X509Certificate2
rCert
=
null
;
if
(
switchToMTAIfNeeded
&&
Thread
.
CurrentThread
.
GetApartmentState
()
!=
ApartmentState
.
MTA
)
if
(
switchToMTAIfNeeded
&&
Thread
.
CurrentThread
.
GetApartmentState
()
!=
ApartmentState
.
MTA
)
{
{
ManualResetEvent
manualResetEvent
=
new
ManualResetEvent
(
false
);
var
manualResetEvent
=
new
ManualResetEvent
(
false
);
ThreadPool
.
QueueUserWorkItem
(
(
object
o
)
=>
ThreadPool
.
QueueUserWorkItem
(
o
=>
{
{
rCert
=
this
.
MakeCertificateInternal
(
sSubjectCN
,
isRoot
,
false
,
signingCert
);
rCert
=
MakeCertificateInternal
(
sSubjectCN
,
isRoot
,
false
,
signingCert
);
manualResetEvent
.
Set
();
manualResetEvent
.
Set
();
});
});
manualResetEvent
.
WaitOne
();
manualResetEvent
.
WaitOne
();
manualResetEvent
.
Close
();
manualResetEvent
.
Close
();
return
rCert
;
return
rCert
;
}
}
string
fullSubject
=
string
.
Format
(
"CN={0}{1}"
,
sSubjectCN
,
""
);
//Subject
var
fullSubject
=
$"CN=
{
sSubjectCN
}
"
;
//Subject
string
HashAlgo
=
"SHA256"
;
//Sig Algo
var
HashAlgo
=
"SHA256"
;
//Sig Algo
int
GraceDays
=
-
366
;
//Grace Days
var
GraceDays
=
-
366
;
//Grace Days
int
ValidDays
=
1825
;
//ValiDays
var
ValidDays
=
1825
;
//ValiDays
int
keyLength
=
2048
;
//KeyLength
var
keyLength
=
2048
;
//KeyLength
DateTime
graceTime
=
DateTime
.
Now
.
AddDays
((
double
)
GraceDays
);
var
graceTime
=
DateTime
.
Now
.
AddDays
(
GraceDays
);
DateTime
now
=
DateTime
.
Now
;
var
now
=
DateTime
.
Now
;
try
rCert
=
!
isRoot
?
MakeCertificate
(
false
,
fullSubject
,
keyLength
,
HashAlgo
,
graceTime
,
now
.
AddDays
(
ValidDays
),
signingCert
)
:
{
MakeCertificate
(
true
,
fullSubject
,
keyLength
,
HashAlgo
,
graceTime
,
now
.
AddDays
(
ValidDays
),
null
);
if
(!
isRoot
)
{
rCert
=
this
.
MakeCertificate
(
false
,
sSubjectCN
,
fullSubject
,
keyLength
,
HashAlgo
,
graceTime
,
now
.
AddDays
((
double
)
ValidDays
),
signingCert
);
}
else
{
rCert
=
this
.
MakeCertificate
(
true
,
sSubjectCN
,
fullSubject
,
keyLength
,
HashAlgo
,
graceTime
,
now
.
AddDays
((
double
)
ValidDays
),
null
);
}
}
catch
(
Exception
e
)
{
throw
e
;
}
return
rCert
;
return
rCert
;
}
}
}
}
...
...
Titanium.Web.Proxy/Network/CertificateManager.cs
View file @
1057c2ff
...
@@ -13,7 +13,7 @@ namespace Titanium.Web.Proxy.Network
...
@@ -13,7 +13,7 @@ namespace Titanium.Web.Proxy.Network
/// </summary>
/// </summary>
internal
class
CertificateManager
:
IDisposable
internal
class
CertificateManager
:
IDisposable
{
{
private
CertificateMaker
certEngine
=
null
;
private
readonly
CertificateMaker
certEngine
;
private
bool
clearCertificates
{
get
;
set
;
}
private
bool
clearCertificates
{
get
;
set
;
}
/// <summary>
/// <summary>
...
@@ -21,10 +21,10 @@ namespace Titanium.Web.Proxy.Network
...
@@ -21,10 +21,10 @@ namespace Titanium.Web.Proxy.Network
/// </summary>
/// </summary>
private
readonly
IDictionary
<
string
,
CachedCertificate
>
certificateCache
;
private
readonly
IDictionary
<
string
,
CachedCertificate
>
certificateCache
;
private
Action
<
Exception
>
exceptionFunc
;
private
readonly
Action
<
Exception
>
exceptionFunc
;
internal
string
Issuer
{
get
;
private
set
;
}
internal
string
Issuer
{
get
;
}
internal
string
RootCertificateName
{
get
;
private
set
;
}
internal
string
RootCertificateName
{
get
;
}
internal
X509Certificate2
rootCertificate
{
get
;
set
;
}
internal
X509Certificate2
rootCertificate
{
get
;
set
;
}
...
@@ -35,29 +35,28 @@ namespace Titanium.Web.Proxy.Network
...
@@ -35,29 +35,28 @@ namespace Titanium.Web.Proxy.Network
certEngine
=
new
CertificateMaker
();
certEngine
=
new
CertificateMaker
();
Issuer
=
issuer
;
Issuer
=
issuer
;
RootCertificateName
=
rootCertificateName
;
RootCertificateName
=
rootCertificateName
;
certificateCache
=
new
ConcurrentDictionary
<
string
,
CachedCertificate
>();
certificateCache
=
new
ConcurrentDictionary
<
string
,
CachedCertificate
>();
}
}
internal
X509Certificate2
GetRootCertificate
()
internal
X509Certificate2
GetRootCertificate
()
{
{
var
fileName
=
Path
.
Combine
(
System
.
IO
.
Path
.
GetDirectoryName
(
System
.
Reflection
.
Assembly
.
GetExecutingAssembly
().
Location
),
"rootCert.pfx"
);
var
path
=
Path
.
GetDirectoryName
(
System
.
Reflection
.
Assembly
.
GetExecutingAssembly
().
Location
);
if
(
null
==
path
)
throw
new
NullReferenceException
();
var
fileName
=
Path
.
Combine
(
path
,
"rootCert.pfx"
);
if
(
File
.
Exists
(
fileName
))
if
(!
File
.
Exists
(
fileName
))
return
null
;
try
{
{
try
return
new
X509Certificate2
(
fileName
,
string
.
Empty
,
X509KeyStorageFlags
.
Exportable
);
{
return
new
X509Certificate2
(
fileName
,
string
.
Empty
,
X509KeyStorageFlags
.
Exportable
);
}
catch
(
Exception
e
)
}
{
catch
(
Exception
e
)
exceptionFunc
(
e
);
{
return
null
;
exceptionFunc
(
e
);
return
null
;
}
}
}
return
null
;
}
}
/// <summary>
/// <summary>
/// Attempts to create a RootCertificate
/// Attempts to create a RootCertificate
...
@@ -75,7 +74,7 @@ namespace Titanium.Web.Proxy.Network
...
@@ -75,7 +74,7 @@ namespace Titanium.Web.Proxy.Network
{
{
rootCertificate
=
CreateCertificate
(
RootCertificateName
,
true
);
rootCertificate
=
CreateCertificate
(
RootCertificateName
,
true
);
}
}
catch
(
Exception
e
)
catch
(
Exception
e
)
{
{
exceptionFunc
(
e
);
exceptionFunc
(
e
);
}
}
...
@@ -83,38 +82,36 @@ namespace Titanium.Web.Proxy.Network
...
@@ -83,38 +82,36 @@ namespace Titanium.Web.Proxy.Network
{
{
try
try
{
{
var
fileName
=
Path
.
Combine
(
System
.
IO
.
Path
.
GetDirectoryName
(
System
.
Reflection
.
Assembly
.
GetExecutingAssembly
().
Location
),
"rootCert.pfx"
);
var
path
=
Path
.
GetDirectoryName
(
System
.
Reflection
.
Assembly
.
GetExecutingAssembly
().
Location
);
if
(
null
==
path
)
throw
new
NullReferenceException
();
var
fileName
=
Path
.
Combine
(
path
,
"rootCert.pfx"
);
File
.
WriteAllBytes
(
fileName
,
rootCertificate
.
Export
(
X509ContentType
.
Pkcs12
));
File
.
WriteAllBytes
(
fileName
,
rootCertificate
.
Export
(
X509ContentType
.
Pkcs12
));
}
}
catch
(
Exception
e
)
catch
(
Exception
e
)
{
{
exceptionFunc
(
e
);
exceptionFunc
(
e
);
}
}
}
}
return
rootCertificate
!=
null
;
return
rootCertificate
!=
null
;
}
}
/// <summary>
/// <summary>
/// Create an SSL certificate
/// Create an SSL certificate
/// </summary>
/// </summary>
/// <param name="store"></param>
/// <param name="certificateName"></param>
/// <param name="certificateName"></param>
/// <param name="isRootCertificate"></param>
/// <param name="isRootCertificate"></param>
/// <returns></returns>
/// <returns></returns>
internal
virtual
X509Certificate2
CreateCertificate
(
string
certificateName
,
bool
isRootCertificate
)
internal
virtual
X509Certificate2
CreateCertificate
(
string
certificateName
,
bool
isRootCertificate
)
{
{
try
if
(
certificateCache
.
ContainsKey
(
certificateName
))
{
{
if
(
certificateCache
.
ContainsKey
(
certificateName
))
var
cached
=
certificateCache
[
certificateName
];
{
cached
.
LastAccess
=
DateTime
.
Now
;
var
cached
=
certificateCache
[
certificateName
];
return
cached
.
Certificate
;
cached
.
LastAccess
=
DateTime
.
Now
;
return
cached
.
Certificate
;
}
}
}
catch
{
}
X509Certificate2
certificate
=
null
;
X509Certificate2
certificate
=
null
;
lock
(
string
.
Intern
(
certificateName
))
lock
(
string
.
Intern
(
certificateName
))
{
{
...
@@ -124,7 +121,7 @@ namespace Titanium.Web.Proxy.Network
...
@@ -124,7 +121,7 @@ namespace Titanium.Web.Proxy.Network
{
{
certificate
=
certEngine
.
MakeCertificate
(
certificateName
,
isRootCertificate
,
rootCertificate
);
certificate
=
certEngine
.
MakeCertificate
(
certificateName
,
isRootCertificate
,
rootCertificate
);
}
}
catch
(
Exception
e
)
catch
(
Exception
e
)
{
{
exceptionFunc
(
e
);
exceptionFunc
(
e
);
}
}
...
@@ -166,27 +163,20 @@ namespace Titanium.Web.Proxy.Network
...
@@ -166,27 +163,20 @@ namespace Titanium.Web.Proxy.Network
clearCertificates
=
true
;
clearCertificates
=
true
;
while
(
clearCertificates
)
while
(
clearCertificates
)
{
{
var
cutOff
=
DateTime
.
Now
.
AddMinutes
(-
1
*
certificateCacheTimeOutMinutes
);
try
var
outdated
=
certificateCache
{
.
Where
(
x
=>
x
.
Value
.
LastAccess
<
cutOff
)
var
cutOff
=
DateTime
.
Now
.
AddMinutes
(-
1
*
certificateCacheTimeOutMinutes
);
.
ToList
(
);
var
outdated
=
certificateCache
foreach
(
var
cache
in
outdated
)
.
Where
(
x
=>
x
.
Value
.
LastAccess
<
cutOff
)
certificateCache
.
Remove
(
cache
.
Key
);
.
ToList
();
foreach
(
var
cache
in
outdated
)
certificateCache
.
Remove
(
cache
.
Key
);
}
finally
{
}
//after a minute come back to check for outdated certificates in cache
//after a minute come back to check for outdated certificates in cache
await
Task
.
Delay
(
1000
*
60
);
await
Task
.
Delay
(
1000
*
60
);
}
}
}
}
internal
bool
TrustRootCertificate
()
internal
bool
TrustRootCertificate
()
{
{
if
(
rootCertificate
==
null
)
if
(
rootCertificate
==
null
)
...
@@ -213,7 +203,7 @@ namespace Titanium.Web.Proxy.Network
...
@@ -213,7 +203,7 @@ namespace Titanium.Web.Proxy.Network
}
}
return
true
;
return
true
;
}
}
catch
catch
{
{
return
false
;
return
false
;
}
}
...
...
Titanium.Web.Proxy/Network/Tcp/TcpConnection.cs
View file @
1057c2ff
...
@@ -47,6 +47,9 @@ namespace Titanium.Web.Proxy.Network.Tcp
...
@@ -47,6 +47,9 @@ namespace Titanium.Web.Proxy.Network.Tcp
LastAccess
=
DateTime
.
Now
;
LastAccess
=
DateTime
.
Now
;
}
}
/// <summary>
/// Dispose.
/// </summary>
public
void
Dispose
()
public
void
Dispose
()
{
{
Stream
.
Close
();
Stream
.
Close
();
...
...
Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs
View file @
1057c2ff
...
@@ -19,14 +19,12 @@ namespace Titanium.Web.Proxy.Network.Tcp
...
@@ -19,14 +19,12 @@ namespace Titanium.Web.Proxy.Network.Tcp
/// </summary>
/// </summary>
internal
class
TcpConnectionFactory
internal
class
TcpConnectionFactory
{
{
/// <summary>
/// <summary>
/// Creates a TCP connection to server
/// Creates a TCP connection to server
/// </summary>
/// </summary>
/// <param name="bufferSize"></param>
/// <param name="bufferSize"></param>
/// <param name="connectionTimeOutSeconds"></param>
/// <param name="connectionTimeOutSeconds"></param>
/// <param name="remoteHostName"></param>
/// <param name="remoteHostName"></param>
/// <param name="httpCmd"></param>
/// <param name="httpVersion"></param>
/// <param name="httpVersion"></param>
/// <param name="isHttps"></param>
/// <param name="isHttps"></param>
/// <param name="remotePort"></param>
/// <param name="remotePort"></param>
...
@@ -69,7 +67,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
...
@@ -69,7 +67,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
if
(!
string
.
IsNullOrEmpty
(
externalHttpsProxy
.
UserName
)
&&
externalHttpsProxy
.
Password
!=
null
)
if
(!
string
.
IsNullOrEmpty
(
externalHttpsProxy
.
UserName
)
&&
externalHttpsProxy
.
Password
!=
null
)
{
{
await
writer
.
WriteLineAsync
(
"Proxy-Connection: keep-alive"
);
await
writer
.
WriteLineAsync
(
"Proxy-Connection: keep-alive"
);
await
writer
.
WriteLineAsync
(
"Proxy-Authorization"
+
": Basic "
+
Convert
.
ToBase64String
(
System
.
Text
.
Encoding
.
UTF8
.
GetBytes
(
externalHttpsProxy
.
UserName
+
":"
+
externalHttpsProxy
.
Password
)));
await
writer
.
WriteLineAsync
(
"Proxy-Authorization"
+
": Basic "
+
Convert
.
ToBase64String
(
Encoding
.
UTF8
.
GetBytes
(
externalHttpsProxy
.
UserName
+
":"
+
externalHttpsProxy
.
Password
)));
}
}
await
writer
.
WriteLineAsync
();
await
writer
.
WriteLineAsync
();
await
writer
.
FlushAsync
();
await
writer
.
FlushAsync
();
...
@@ -81,7 +79,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
...
@@ -81,7 +79,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
var
result
=
await
reader
.
ReadLineAsync
();
var
result
=
await
reader
.
ReadLineAsync
();
if
(!
new
string
[]
{
"200 OK"
,
"connection established"
}.
Any
(
s
=>
result
.
ToLower
().
Contains
(
s
.
ToLower
())))
if
(!
new
[]
{
"200 OK"
,
"connection established"
}.
Any
(
s
=>
result
.
ToLower
().
Contains
(
s
.
ToLower
())))
{
{
throw
new
Exception
(
"Upstream proxy failed to create a secure tunnel"
);
throw
new
Exception
(
"Upstream proxy failed to create a secure tunnel"
);
}
}
...
...
Titanium.Web.Proxy/Network/Tcp/TcpRow.cs
View file @
1057c2ff
...
@@ -29,16 +29,16 @@ namespace Titanium.Web.Proxy.Network.Tcp
...
@@ -29,16 +29,16 @@ namespace Titanium.Web.Proxy.Network.Tcp
/// <summary>
/// <summary>
/// Gets the local end point.
/// Gets the local end point.
/// </summary>
/// </summary>
public
IPEndPoint
LocalEndPoint
{
get
;
private
set
;
}
public
IPEndPoint
LocalEndPoint
{
get
;
}
/// <summary>
/// <summary>
/// Gets the remote end point.
/// Gets the remote end point.
/// </summary>
/// </summary>
public
IPEndPoint
RemoteEndPoint
{
get
;
private
set
;
}
public
IPEndPoint
RemoteEndPoint
{
get
;
}
/// <summary>
/// <summary>
/// Gets the process identifier.
/// Gets the process identifier.
/// </summary>
/// </summary>
public
int
ProcessId
{
get
;
private
set
;
}
public
int
ProcessId
{
get
;
}
}
}
}
}
\ No newline at end of file
Titanium.Web.Proxy/Network/Tcp/TcpTable.cs
View file @
1057c2ff
...
@@ -6,7 +6,9 @@ namespace Titanium.Web.Proxy.Network.Tcp
...
@@ -6,7 +6,9 @@ namespace Titanium.Web.Proxy.Network.Tcp
/// <summary>
/// <summary>
/// Represents collection of TcpRows
/// Represents collection of TcpRows
/// </summary>
/// </summary>
/// <seealso cref="System.Collections.Generic.IEnumerable{Proxy.Tcp.TcpRow}" />
/// <seealso>
/// <cref>System.Collections.Generic.IEnumerable{Proxy.Tcp.TcpRow}</cref>
/// </seealso>
internal
class
TcpTable
:
IEnumerable
<
TcpRow
>
internal
class
TcpTable
:
IEnumerable
<
TcpRow
>
{
{
private
readonly
IEnumerable
<
TcpRow
>
tcpRows
;
private
readonly
IEnumerable
<
TcpRow
>
tcpRows
;
...
...
Titanium.Web.Proxy/ProxyAuthorizationHandler.cs
View file @
1057c2ff
...
@@ -24,58 +24,78 @@ namespace Titanium.Web.Proxy
...
@@ -24,58 +24,78 @@ namespace Titanium.Web.Proxy
try
try
{
{
if
(
!
httpHeaders
.
Where
(
t
=>
t
.
Name
==
"Proxy-Authorization"
).
Any
(
))
if
(
httpHeaders
.
All
(
t
=>
t
.
Name
!=
"Proxy-Authorization"
))
{
{
await
WriteResponseStatus
(
new
Version
(
1
,
1
),
"407"
,
await
WriteResponseStatus
(
new
Version
(
1
,
1
),
"407"
,
"Proxy Authentication Required"
,
clientStreamWriter
);
"Proxy Authentication Required"
,
clientStreamWriter
);
var
response
=
new
Response
();
var
response
=
new
Response
response
.
ResponseHeaders
=
new
Dictionary
<
string
,
HttpHeader
>();
{
response
.
ResponseHeaders
.
Add
(
"Proxy-Authenticate"
,
new
HttpHeader
(
"Proxy-Authenticate"
,
"Basic realm=\"TitaniumProxy\""
));
ResponseHeaders
=
new
Dictionary
<
string
,
HttpHeader
>
response
.
ResponseHeaders
.
Add
(
"Proxy-Connection"
,
new
HttpHeader
(
"Proxy-Connection"
,
"close"
));
{
{
"Proxy-Authenticate"
,
new
HttpHeader
(
"Proxy-Authenticate"
,
"Basic realm=\"TitaniumProxy\""
)
},
{
"Proxy-Connection"
,
new
HttpHeader
(
"Proxy-Connection"
,
"close"
)}
}
};
await
WriteResponseHeaders
(
clientStreamWriter
,
response
);
await
WriteResponseHeaders
(
clientStreamWriter
,
response
);
await
clientStreamWriter
.
WriteLineAsync
();
await
clientStreamWriter
.
WriteLineAsync
();
return
false
;
return
false
;
}
}
else
var
header
=
httpHeaders
.
FirstOrDefault
(
t
=>
t
.
Name
==
"Proxy-Authorization"
);
if
(
null
==
header
)
throw
new
NullReferenceException
();
var
headerValue
=
header
.
Value
.
Trim
();
if
(!
headerValue
.
ToLower
().
StartsWith
(
"basic"
))
{
{
var
headerValue
=
httpHeaders
.
Where
(
t
=>
t
.
Name
==
"Proxy-Authorization"
).
FirstOrDefault
().
Value
.
Trim
();
//Return not authorized
if
(!
headerValue
.
ToLower
().
StartsWith
(
"basic"
))
await
WriteResponseStatus
(
new
Version
(
1
,
1
),
"407"
,
"Proxy Authentication Invalid"
,
clientStreamWriter
);
var
response
=
new
Response
{
{
//Return not authorized
ResponseHeaders
=
new
Dictionary
<
string
,
HttpHeader
>
await
WriteResponseStatus
(
new
Version
(
1
,
1
),
"407"
,
{
"Proxy Authentication Invalid"
,
clientStreamWriter
);
{
var
response
=
new
Response
();
"Proxy-Authenticate"
,
response
.
ResponseHeaders
=
new
Dictionary
<
string
,
HttpHeader
>();
new
HttpHeader
(
"Proxy-Authenticate"
,
"Basic realm=\"TitaniumProxy\""
)
response
.
ResponseHeaders
.
Add
(
"Proxy-Authenticate"
,
new
HttpHeader
(
"Proxy-Authenticate"
,
"Basic realm=\"TitaniumProxy\""
));
},
response
.
ResponseHeaders
.
Add
(
"Proxy-Connection"
,
new
HttpHeader
(
"Proxy-Connection"
,
"close"
));
{
"Proxy-Connection"
,
new
HttpHeader
(
"Proxy-Connection"
,
"close"
)}
await
WriteResponseHeaders
(
clientStreamWriter
,
response
);
}
};
await
WriteResponseHeaders
(
clientStreamWriter
,
response
);
await
clientStreamWriter
.
WriteLineAsync
();
await
clientStreamWriter
.
WriteLineAsync
();
return
false
;
return
false
;
}
}
headerValue
=
headerValue
.
Substring
(
5
).
Trim
();
headerValue
=
headerValue
.
Substring
(
5
).
Trim
();
var
decoded
=
Encoding
.
UTF8
.
GetString
(
Convert
.
FromBase64String
(
headerValue
));
var
decoded
=
Encoding
.
UTF8
.
GetString
(
Convert
.
FromBase64String
(
headerValue
));
if
(
decoded
.
Contains
(
":"
)
==
false
)
if
(
decoded
.
Contains
(
":"
)
==
false
)
{
//Return not authorized
await
WriteResponseStatus
(
new
Version
(
1
,
1
),
"407"
,
"Proxy Authentication Invalid"
,
clientStreamWriter
);
var
response
=
new
Response
{
{
//Return not authorized
ResponseHeaders
=
new
Dictionary
<
string
,
HttpHeader
>
await
WriteResponseStatus
(
new
Version
(
1
,
1
),
"407"
,
{
"Proxy Authentication Invalid"
,
clientStreamWriter
);
{
var
response
=
new
Response
();
"Proxy-Authenticate"
,
response
.
ResponseHeaders
=
new
Dictionary
<
string
,
HttpHeader
>();
new
HttpHeader
(
"Proxy-Authenticate"
,
"Basic realm=\"TitaniumProxy\""
)
response
.
ResponseHeaders
.
Add
(
"Proxy-Authenticate"
,
new
HttpHeader
(
"Proxy-Authenticate"
,
"Basic realm=\"TitaniumProxy\""
));
},
response
.
ResponseHeaders
.
Add
(
"Proxy-Connection"
,
new
HttpHeader
(
"Proxy-Connection"
,
"close"
));
{
"Proxy-Connection"
,
new
HttpHeader
(
"Proxy-Connection"
,
"close"
)}
await
WriteResponseHeaders
(
clientStreamWriter
,
response
);
}
};
await
WriteResponseHeaders
(
clientStreamWriter
,
response
);
await
clientStreamWriter
.
WriteLineAsync
();
await
clientStreamWriter
.
WriteLineAsync
();
return
false
;
return
false
;
}
var
username
=
decoded
.
Substring
(
0
,
decoded
.
IndexOf
(
':'
));
var
password
=
decoded
.
Substring
(
decoded
.
IndexOf
(
':'
)
+
1
);
return
await
AuthenticateUserFunc
(
username
,
password
).
ConfigureAwait
(
false
);
}
}
var
username
=
decoded
.
Substring
(
0
,
decoded
.
IndexOf
(
':'
));
var
password
=
decoded
.
Substring
(
decoded
.
IndexOf
(
':'
)
+
1
);
return
await
AuthenticateUserFunc
(
username
,
password
).
ConfigureAwait
(
false
);
}
}
catch
(
Exception
e
)
catch
(
Exception
e
)
{
{
...
@@ -83,10 +103,14 @@ namespace Titanium.Web.Proxy
...
@@ -83,10 +103,14 @@ namespace Titanium.Web.Proxy
//Return not authorized
//Return not authorized
await
WriteResponseStatus
(
new
Version
(
1
,
1
),
"407"
,
await
WriteResponseStatus
(
new
Version
(
1
,
1
),
"407"
,
"Proxy Authentication Invalid"
,
clientStreamWriter
);
"Proxy Authentication Invalid"
,
clientStreamWriter
);
var
response
=
new
Response
();
var
response
=
new
Response
response
.
ResponseHeaders
=
new
Dictionary
<
string
,
HttpHeader
>();
{
response
.
ResponseHeaders
.
Add
(
"Proxy-Authenticate"
,
new
HttpHeader
(
"Proxy-Authenticate"
,
"Basic realm=\"TitaniumProxy\""
));
ResponseHeaders
=
new
Dictionary
<
string
,
HttpHeader
>
response
.
ResponseHeaders
.
Add
(
"Proxy-Connection"
,
new
HttpHeader
(
"Proxy-Connection"
,
"close"
));
{
{
"Proxy-Authenticate"
,
new
HttpHeader
(
"Proxy-Authenticate"
,
"Basic realm=\"TitaniumProxy\""
)},
{
"Proxy-Connection"
,
new
HttpHeader
(
"Proxy-Connection"
,
"close"
)}
}
};
await
WriteResponseHeaders
(
clientStreamWriter
,
response
);
await
WriteResponseHeaders
(
clientStreamWriter
,
response
);
await
clientStreamWriter
.
WriteLineAsync
();
await
clientStreamWriter
.
WriteLineAsync
();
...
...
Titanium.Web.Proxy/ProxyServer.cs
View file @
1057c2ff
...
@@ -47,14 +47,16 @@ namespace Titanium.Web.Proxy
...
@@ -47,14 +47,16 @@ namespace Titanium.Web.Proxy
/// <summary>
/// <summary>
/// A object that creates tcp connection to server
/// A object that creates tcp connection to server
/// </summary>
/// </summary>
private
TcpConnectionFactory
tcpConnectionFactory
{
get
;
set
;
}
private
TcpConnectionFactory
tcpConnectionFactory
{
get
;
}
/// <summary>
/// <summary>
/// Manage system proxy settings
/// Manage system proxy settings
/// </summary>
/// </summary>
private
SystemProxyManager
systemProxySettingsManager
{
get
;
set
;
}
private
SystemProxyManager
systemProxySettingsManager
{
get
;
}
#if !DEBUG
private
FireFoxProxySettingsManager
firefoxProxySettingsManager
{
get
;
set
;
}
private
FireFoxProxySettingsManager
firefoxProxySettingsManager
{
get
;
set
;
}
#endif
/// <summary>
/// <summary>
/// Buffer size used throughout this proxy
/// Buffer size used throughout this proxy
...
@@ -138,14 +140,8 @@ namespace Titanium.Web.Proxy
...
@@ -138,14 +140,8 @@ namespace Titanium.Web.Proxy
/// </summary>
/// </summary>
public
Action
<
Exception
>
ExceptionFunc
public
Action
<
Exception
>
ExceptionFunc
{
{
get
get
=>
exceptionFunc
??
defaultExceptionFunc
.
Value
;
{
set
=>
exceptionFunc
=
value
;
return
exceptionFunc
??
defaultExceptionFunc
.
Value
;
}
set
{
exceptionFunc
=
value
;
}
}
}
/// <summary>
/// <summary>
...
@@ -172,6 +168,7 @@ namespace Titanium.Web.Proxy
...
@@ -172,6 +168,7 @@ namespace Titanium.Web.Proxy
/// <summary>
/// <summary>
/// A callback to provide authentication credentials for up stream proxy this proxy is using for HTTPS requests
/// A callback to provide authentication credentials for up stream proxy this proxy is using for HTTPS requests
/// return the ExternalProxy object with valid credentials
/// return the ExternalProxy object with valid credentials
/// </summary>
public
Func
<
SessionEventArgs
,
Task
<
ExternalProxy
>>
GetCustomUpStreamHttpsProxyFunc
public
Func
<
SessionEventArgs
,
Task
<
ExternalProxy
>>
GetCustomUpStreamHttpsProxyFunc
{
{
get
;
get
;
...
@@ -203,6 +200,11 @@ namespace Titanium.Web.Proxy
...
@@ -203,6 +200,11 @@ namespace Titanium.Web.Proxy
/// </summary>
/// </summary>
public
ProxyServer
()
:
this
(
null
,
null
)
{
}
public
ProxyServer
()
:
this
(
null
,
null
)
{
}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="rootCertificateName">Name of root certificate.</param>
/// <param name="rootCertificateIssuerName">Name of root certificate issuer.</param>
public
ProxyServer
(
string
rootCertificateName
,
string
rootCertificateIssuerName
)
public
ProxyServer
(
string
rootCertificateName
,
string
rootCertificateIssuerName
)
{
{
RootCertificateName
=
rootCertificateName
;
RootCertificateName
=
rootCertificateName
;
...
@@ -214,8 +216,9 @@ namespace Titanium.Web.Proxy
...
@@ -214,8 +216,9 @@ namespace Titanium.Web.Proxy
ProxyEndPoints
=
new
List
<
ProxyEndPoint
>();
ProxyEndPoints
=
new
List
<
ProxyEndPoint
>();
tcpConnectionFactory
=
new
TcpConnectionFactory
();
tcpConnectionFactory
=
new
TcpConnectionFactory
();
systemProxySettingsManager
=
new
SystemProxyManager
();
systemProxySettingsManager
=
new
SystemProxyManager
();
firefoxProxySettingsManager
=
new
FireFoxProxySettingsManager
();
#if !DEBUG
new
FireFoxProxySettingsManager
();
#endif
RootCertificateName
=
RootCertificateName
??
"Titanium Root Certificate Authority"
;
RootCertificateName
=
RootCertificateName
??
"Titanium Root Certificate Authority"
;
RootCertificateIssuerName
=
RootCertificateIssuerName
??
"Titanium"
;
RootCertificateIssuerName
=
RootCertificateIssuerName
??
"Titanium"
;
}
}
...
@@ -277,7 +280,7 @@ namespace Titanium.Web.Proxy
...
@@ -277,7 +280,7 @@ namespace Titanium.Web.Proxy
#if !DEBUG
#if !DEBUG
firefoxProxySettingsManager
.
AddFirefox
();
firefoxProxySettingsManager
.
AddFirefox
();
#endif
#endif
Console
.
WriteLine
(
"Set endpoint at Ip {
1} and port: {2} as System HTTP Proxy"
,
endPoint
.
GetType
().
Name
,
endPoint
.
IpAddress
,
endPoint
.
Port
);
Console
.
WriteLine
(
"Set endpoint at Ip {
0} and port: {1} as System HTTP Proxy"
,
endPoint
.
IpAddress
,
endPoint
.
Port
);
}
}
...
@@ -313,7 +316,7 @@ namespace Titanium.Web.Proxy
...
@@ -313,7 +316,7 @@ namespace Titanium.Web.Proxy
#if !DEBUG
#if !DEBUG
firefoxProxySettingsManager
.
AddFirefox
();
firefoxProxySettingsManager
.
AddFirefox
();
#endif
#endif
Console
.
WriteLine
(
"Set endpoint at Ip {
1} and port: {2} as System HTTPS Proxy"
,
endPoint
.
GetType
().
Name
,
endPoint
.
IpAddress
,
endPoint
.
Port
);
Console
.
WriteLine
(
"Set endpoint at Ip {
0} and port: {1} as System HTTPS Proxy"
,
endPoint
.
IpAddress
,
endPoint
.
Port
);
}
}
/// <summary>
/// <summary>
...
@@ -461,6 +464,7 @@ namespace Titanium.Web.Proxy
...
@@ -461,6 +464,7 @@ namespace Titanium.Web.Proxy
/// <param name="endPoint"></param>
/// <param name="endPoint"></param>
private
void
ValidateEndPointAsSystemProxy
(
ExplicitProxyEndPoint
endPoint
)
private
void
ValidateEndPointAsSystemProxy
(
ExplicitProxyEndPoint
endPoint
)
{
{
if
(
endPoint
==
null
)
throw
new
ArgumentNullException
(
nameof
(
endPoint
));
if
(
ProxyEndPoints
.
Contains
(
endPoint
)
==
false
)
if
(
ProxyEndPoints
.
Contains
(
endPoint
)
==
false
)
{
{
throw
new
Exception
(
"Cannot set endPoints not added to proxy as system proxy"
);
throw
new
Exception
(
"Cannot set endPoints not added to proxy as system proxy"
);
...
@@ -542,6 +546,9 @@ namespace Titanium.Web.Proxy
...
@@ -542,6 +546,9 @@ namespace Titanium.Web.Proxy
endPoint
.
listener
.
BeginAcceptTcpClient
(
OnAcceptConnection
,
endPoint
);
endPoint
.
listener
.
BeginAcceptTcpClient
(
OnAcceptConnection
,
endPoint
);
}
}
/// <summary>
/// Dispose Proxy.
/// </summary>
public
void
Dispose
()
public
void
Dispose
()
{
{
if
(
proxyRunning
)
if
(
proxyRunning
)
...
@@ -551,5 +558,45 @@ namespace Titanium.Web.Proxy
...
@@ -551,5 +558,45 @@ namespace Titanium.Web.Proxy
certificateCacheManager
?.
Dispose
();
certificateCacheManager
?.
Dispose
();
}
}
/// <summary>
/// Invocator for BeforeRequest event.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected
virtual
void
OnBeforeRequest
(
object
sender
,
SessionEventArgs
e
)
{
BeforeRequest
?.
Invoke
(
sender
,
e
);
}
/// <summary>
/// Invocator for BeforeResponse event.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <returns></returns>
protected
virtual
void
OnBeforeResponse
(
object
sender
,
SessionEventArgs
e
)
{
BeforeResponse
?.
Invoke
(
sender
,
e
);
}
/// <summary>
/// Invocator for ServerCertificateValidationCallback event.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected
virtual
void
OnServerCertificateValidationCallback
(
object
sender
,
CertificateValidationEventArgs
e
)
{
ServerCertificateValidationCallback
?.
Invoke
(
sender
,
e
);
}
/// <summary>
/// Invocator for ClientCertifcateSelectionCallback event.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected
virtual
void
OnClientCertificateSelectionCallback
(
object
sender
,
CertificateSelectionEventArgs
e
)
{
ClientCertificateSelectionCallback
?.
Invoke
(
sender
,
e
);
}
}
}
}
}
\ No newline at end of file
Titanium.Web.Proxy/RequestHandler.cs
View file @
1057c2ff
...
@@ -11,7 +11,6 @@ using Titanium.Web.Proxy.Exceptions;
...
@@ -11,7 +11,6 @@ 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
;
using
Titanium.Web.Proxy.Models
;
using
Titanium.Web.Proxy.Models
;
using
System.Security.Cryptography.X509Certificates
;
using
Titanium.Web.Proxy.Shared
;
using
Titanium.Web.Proxy.Shared
;
using
Titanium.Web.Proxy.Http
;
using
Titanium.Web.Proxy.Http
;
using
System.Threading.Tasks
;
using
System.Threading.Tasks
;
...
@@ -58,29 +57,21 @@ namespace Titanium.Web.Proxy
...
@@ -58,29 +57,21 @@ namespace Titanium.Web.Proxy
//Find the request Verb
//Find the request Verb
var
httpVerb
=
httpCmdSplit
[
0
];
var
httpVerb
=
httpCmdSplit
[
0
];
if
(
httpVerb
.
ToUpper
()
==
"CONNECT"
)
httpRemoteUri
=
httpVerb
.
ToUpper
()
==
"CONNECT"
?
new
Uri
(
"http://"
+
httpCmdSplit
[
1
])
:
new
Uri
(
httpCmdSplit
[
1
]);
{
httpRemoteUri
=
new
Uri
(
"http://"
+
httpCmdSplit
[
1
]);
}
else
{
httpRemoteUri
=
new
Uri
(
httpCmdSplit
[
1
]);
}
//parse the HTTP version
//parse the HTTP version
Version
version
=
new
Version
(
1
,
1
);
var
version
=
new
Version
(
1
,
1
);
if
(
httpCmdSplit
.
Length
==
3
)
if
(
httpCmdSplit
.
Length
==
3
)
{
{
string
httpVersion
=
httpCmdSplit
[
2
].
Trim
();
var
httpVersion
=
httpCmdSplit
[
2
].
Trim
();
if
(
httpVersion
==
"http/1.0"
)
if
(
0
==
string
.
CompareOrdinal
(
httpVersion
,
"http/1.0"
)
)
{
{
version
=
new
Version
(
1
,
0
);
version
=
new
Version
(
1
,
0
);
}
}
}
}
//filter out excluded host names
//filter out excluded host names
var
excluded
=
endPoint
.
ExcludedHttpsHostNameRegex
!=
null
?
var
excluded
=
endPoint
.
ExcludedHttpsHostNameRegex
!=
null
&&
endPoint
.
ExcludedHttpsHostNameRegex
.
Any
(
x
=>
Regex
.
IsMatch
(
httpRemoteUri
.
Host
,
x
));
endPoint
.
ExcludedHttpsHostNameRegex
.
Any
(
x
=>
Regex
.
IsMatch
(
httpRemoteUri
.
Host
,
x
))
:
false
;
List
<
HttpHeader
>
connectRequestHeaders
=
null
;
List
<
HttpHeader
>
connectRequestHeaders
=
null
;
...
@@ -89,7 +80,7 @@ namespace Titanium.Web.Proxy
...
@@ -89,7 +80,7 @@ namespace Titanium.Web.Proxy
if
(
httpVerb
.
ToUpper
()
==
"CONNECT"
&&
!
excluded
&&
httpRemoteUri
.
Port
!=
80
)
if
(
httpVerb
.
ToUpper
()
==
"CONNECT"
&&
!
excluded
&&
httpRemoteUri
.
Port
!=
80
)
{
{
httpRemoteUri
=
new
Uri
(
"https://"
+
httpCmdSplit
[
1
]);
httpRemoteUri
=
new
Uri
(
"https://"
+
httpCmdSplit
[
1
]);
string
tmpLine
=
null
;
string
tmpLine
;
connectRequestHeaders
=
new
List
<
HttpHeader
>();
connectRequestHeaders
=
new
List
<
HttpHeader
>();
while
(!
string
.
IsNullOrEmpty
(
tmpLine
=
await
clientStreamReader
.
ReadLineAsync
()))
while
(!
string
.
IsNullOrEmpty
(
tmpLine
=
await
clientStreamReader
.
ReadLineAsync
()))
{
{
...
@@ -114,15 +105,7 @@ namespace Titanium.Web.Proxy
...
@@ -114,15 +105,7 @@ namespace Titanium.Web.Proxy
sslStream
=
new
SslStream
(
clientStream
,
true
);
sslStream
=
new
SslStream
(
clientStream
,
true
);
X509Certificate2
certificate
;
var
certificate
=
endPoint
.
GenericCertificate
??
certificateCacheManager
.
CreateCertificate
(
httpRemoteUri
.
Host
,
false
);
if
(
endPoint
.
GenericCertificate
!=
null
)
{
certificate
=
endPoint
.
GenericCertificate
;
}
else
{
certificate
=
certificateCacheManager
.
CreateCertificate
(
httpRemoteUri
.
Host
,
false
);
}
//Successfully managed to authenticate the client using the fake certificate
//Successfully managed to authenticate the client using the fake certificate
await
sslStream
.
AuthenticateAsServerAsync
(
certificate
,
false
,
await
sslStream
.
AuthenticateAsServerAsync
(
certificate
,
false
,
...
@@ -136,10 +119,7 @@ namespace Titanium.Web.Proxy
...
@@ -136,10 +119,7 @@ namespace Titanium.Web.Proxy
}
}
catch
catch
{
{
if
(
sslStream
!=
null
)
sslStream
?.
Dispose
();
{
sslStream
.
Dispose
();
}
Dispose
(
clientStream
,
clientStreamReader
,
clientStreamWriter
,
null
);
Dispose
(
clientStream
,
clientStreamReader
,
clientStreamWriter
,
null
);
return
;
return
;
...
@@ -160,8 +140,8 @@ namespace Titanium.Web.Proxy
...
@@ -160,8 +140,8 @@ namespace Titanium.Web.Proxy
await
TcpHelper
.
SendRaw
(
BUFFER_SIZE
,
ConnectionTimeOutSeconds
,
httpRemoteUri
.
Host
,
httpRemoteUri
.
Port
,
await
TcpHelper
.
SendRaw
(
BUFFER_SIZE
,
ConnectionTimeOutSeconds
,
httpRemoteUri
.
Host
,
httpRemoteUri
.
Port
,
httpCmd
,
version
,
null
,
httpCmd
,
version
,
null
,
false
,
SupportedSslProtocols
,
false
,
SupportedSslProtocols
,
new
RemoteCertificateValidationCallback
(
ValidateServerCertificate
)
,
ValidateServerCertificate
,
new
LocalCertificateSelectionCallback
(
SelectClientCertificate
)
,
SelectClientCertificate
,
clientStream
,
tcpConnectionFactory
,
UpStreamEndPoint
);
clientStream
,
tcpConnectionFactory
,
UpStreamEndPoint
);
Dispose
(
clientStream
,
clientStreamReader
,
clientStreamWriter
,
null
);
Dispose
(
clientStream
,
clientStreamReader
,
clientStreamWriter
,
null
);
...
@@ -169,7 +149,7 @@ namespace Titanium.Web.Proxy
...
@@ -169,7 +149,7 @@ namespace Titanium.Web.Proxy
}
}
//Now create the request
//Now create the request
await
HandleHttpSessionRequest
(
tcpClient
,
httpCmd
,
clientStream
,
clientStreamReader
,
clientStreamWriter
,
await
HandleHttpSessionRequest
(
tcpClient
,
httpCmd
,
clientStream
,
clientStreamReader
,
clientStreamWriter
,
httpRemoteUri
.
Scheme
==
Uri
.
UriSchemeHttps
?
httpRemoteUri
.
Host
:
null
,
endPoint
,
connectRequestHeaders
,
null
,
null
);
httpRemoteUri
.
Scheme
==
Uri
.
UriSchemeHttps
?
httpRemoteUri
.
Host
:
null
,
endPoint
,
connectRequestHeaders
);
}
}
catch
(
Exception
)
catch
(
Exception
)
{
{
...
@@ -189,14 +169,13 @@ namespace Titanium.Web.Proxy
...
@@ -189,14 +169,13 @@ namespace Titanium.Web.Proxy
CustomBinaryReader
clientStreamReader
=
null
;
CustomBinaryReader
clientStreamReader
=
null
;
StreamWriter
clientStreamWriter
=
null
;
StreamWriter
clientStreamWriter
=
null
;
X509Certificate2
certificate
=
null
;
if
(
endPoint
.
EnableSsl
)
if
(
endPoint
.
EnableSsl
)
{
{
var
sslStream
=
new
SslStream
(
clientStream
,
true
);
var
sslStream
=
new
SslStream
(
clientStream
,
true
);
//implement in future once SNI supported by SSL stream, for now use the same certificate
//implement in future once SNI supported by SSL stream, for now use the same certificate
certificate
=
certificateCacheManager
.
CreateCertificate
(
endPoint
.
GenericCertificateName
,
false
);
var
certificate
=
certificateCacheManager
.
CreateCertificate
(
endPoint
.
GenericCertificateName
,
false
);
try
try
{
{
...
@@ -259,8 +238,8 @@ namespace Titanium.Web.Proxy
...
@@ -259,8 +238,8 @@ namespace Titanium.Web.Proxy
connection
=
await
tcpConnectionFactory
.
CreateClient
(
BUFFER_SIZE
,
ConnectionTimeOutSeconds
,
connection
=
await
tcpConnectionFactory
.
CreateClient
(
BUFFER_SIZE
,
ConnectionTimeOutSeconds
,
args
.
WebSession
.
Request
.
RequestUri
.
Host
,
args
.
WebSession
.
Request
.
RequestUri
.
Port
,
args
.
WebSession
.
Request
.
HttpVersion
,
args
.
WebSession
.
Request
.
RequestUri
.
Host
,
args
.
WebSession
.
Request
.
RequestUri
.
Port
,
args
.
WebSession
.
Request
.
HttpVersion
,
args
.
IsHttps
,
SupportedSslProtocols
,
args
.
IsHttps
,
SupportedSslProtocols
,
new
RemoteCertificateValidationCallback
(
ValidateServerCertificate
)
,
ValidateServerCertificate
,
new
LocalCertificateSelectionCallback
(
SelectClientCertificate
)
,
SelectClientCertificate
,
customUpStreamHttpProxy
??
UpStreamHttpProxy
,
customUpStreamHttpsProxy
??
UpStreamHttpsProxy
,
args
.
ProxyClient
.
ClientStream
,
UpStreamEndPoint
);
customUpStreamHttpProxy
??
UpStreamHttpProxy
,
customUpStreamHttpsProxy
??
UpStreamHttpsProxy
,
args
.
ProxyClient
.
ClientStream
,
UpStreamEndPoint
);
}
}
...
@@ -367,9 +346,14 @@ namespace Titanium.Web.Proxy
...
@@ -367,9 +346,14 @@ namespace Titanium.Web.Proxy
/// <param name="clientStreamReader"></param>
/// <param name="clientStreamReader"></param>
/// <param name="clientStreamWriter"></param>
/// <param name="clientStreamWriter"></param>
/// <param name="httpsHostName"></param>
/// <param name="httpsHostName"></param>
/// <param name="endPoint"></param>
/// <param name="connectHeaders"></param>
/// <param name="customUpStreamHttpProxy"></param>
/// <param name="customUpStreamHttpsProxy"></param>
/// <returns></returns>
/// <returns></returns>
private
async
Task
HandleHttpSessionRequest
(
TcpClient
client
,
string
httpCmd
,
Stream
clientStream
,
private
async
Task
HandleHttpSessionRequest
(
TcpClient
client
,
string
httpCmd
,
Stream
clientStream
,
CustomBinaryReader
clientStreamReader
,
StreamWriter
clientStreamWriter
,
string
httpsHostName
,
ProxyEndPoint
endPoint
,
List
<
HttpHeader
>
connectHeaders
,
ExternalProxy
customUpStreamHttpProxy
=
null
,
ExternalProxy
customUpStreamHttpsProxy
=
null
)
CustomBinaryReader
clientStreamReader
,
StreamWriter
clientStreamWriter
,
string
httpsHostName
,
ProxyEndPoint
endPoint
,
List
<
HttpHeader
>
connectHeaders
,
ExternalProxy
customUpStreamHttpProxy
=
null
,
ExternalProxy
customUpStreamHttpsProxy
=
null
)
{
{
TcpConnection
connection
=
null
;
TcpConnection
connection
=
null
;
...
@@ -383,9 +367,12 @@ namespace Titanium.Web.Proxy
...
@@ -383,9 +367,12 @@ namespace Titanium.Web.Proxy
break
;
break
;
}
}
var
args
=
new
SessionEventArgs
(
BUFFER_SIZE
,
HandleHttpSessionResponse
);
var
args
=
args
.
ProxyClient
.
TcpClient
=
client
;
new
SessionEventArgs
(
BUFFER_SIZE
,
HandleHttpSessionResponse
)
args
.
WebSession
.
ConnectHeaders
=
connectHeaders
;
{
ProxyClient
=
{
TcpClient
=
client
},
WebSession
=
{
ConnectHeaders
=
connectHeaders
}
};
args
.
WebSession
.
ProcessId
=
new
Lazy
<
int
>(()
=>
args
.
WebSession
.
ProcessId
=
new
Lazy
<
int
>(()
=>
{
{
...
@@ -409,12 +396,12 @@ namespace Titanium.Web.Proxy
...
@@ -409,12 +396,12 @@ namespace Titanium.Web.Proxy
var
httpMethod
=
httpCmdSplit
[
0
];
var
httpMethod
=
httpCmdSplit
[
0
];
//find the request HTTP version
//find the request HTTP version
Version
httpVersion
=
new
Version
(
1
,
1
);
var
httpVersion
=
new
Version
(
1
,
1
);
if
(
httpCmdSplit
.
Length
==
3
)
if
(
httpCmdSplit
.
Length
==
3
)
{
{
var
httpVersionString
=
httpCmdSplit
[
2
].
ToLower
().
Trim
();
var
httpVersionString
=
httpCmdSplit
[
2
].
ToLower
().
Trim
();
if
(
httpVersionString
==
"http/1.0"
)
if
(
0
==
string
.
CompareOrdinal
(
httpVersionString
,
"http/1.0"
)
)
{
{
httpVersion
=
new
Version
(
1
,
0
);
httpVersion
=
new
Version
(
1
,
0
);
}
}
...
@@ -439,10 +426,8 @@ namespace Titanium.Web.Proxy
...
@@ -439,10 +426,8 @@ namespace Titanium.Web.Proxy
{
{
var
existing
=
args
.
WebSession
.
Request
.
RequestHeaders
[
newHeader
.
Name
];
var
existing
=
args
.
WebSession
.
Request
.
RequestHeaders
[
newHeader
.
Name
];
var
nonUniqueHeaders
=
new
List
<
HttpHeader
>
()
;
var
nonUniqueHeaders
=
new
List
<
HttpHeader
>
{
existing
,
newHeader
}
;
nonUniqueHeaders
.
Add
(
existing
);
nonUniqueHeaders
.
Add
(
newHeader
);
args
.
WebSession
.
Request
.
NonUniqueRequestHeaders
.
Add
(
newHeader
.
Name
,
nonUniqueHeaders
);
args
.
WebSession
.
Request
.
NonUniqueRequestHeaders
.
Add
(
newHeader
.
Name
,
nonUniqueHeaders
);
args
.
WebSession
.
Request
.
RequestHeaders
.
Remove
(
newHeader
.
Name
);
args
.
WebSession
.
Request
.
RequestHeaders
.
Remove
(
newHeader
.
Name
);
...
@@ -455,8 +440,7 @@ namespace Titanium.Web.Proxy
...
@@ -455,8 +440,7 @@ namespace Titanium.Web.Proxy
}
}
var
httpRemoteUri
=
new
Uri
(
httpsHostName
==
null
?
httpCmdSplit
[
1
]
var
httpRemoteUri
=
new
Uri
(
httpsHostName
==
null
?
httpCmdSplit
[
1
]
:
(
string
.
Concat
(
"https://"
,
args
.
WebSession
.
Request
.
Host
==
null
?
:
(
string
.
Concat
(
"https://"
,
args
.
WebSession
.
Request
.
Host
??
httpsHostName
,
httpCmdSplit
[
1
])));
httpsHostName
:
args
.
WebSession
.
Request
.
Host
,
httpCmdSplit
[
1
])));
args
.
WebSession
.
Request
.
RequestUri
=
httpRemoteUri
;
args
.
WebSession
.
Request
.
RequestUri
=
httpRemoteUri
;
...
@@ -479,10 +463,10 @@ namespace Titanium.Web.Proxy
...
@@ -479,10 +463,10 @@ namespace Titanium.Web.Proxy
//If user requested interception do it
//If user requested interception do it
if
(
BeforeRequest
!=
null
)
if
(
BeforeRequest
!=
null
)
{
{
Delegate
[]
invocationList
=
BeforeRequest
.
GetInvocationList
();
var
invocationList
=
BeforeRequest
.
GetInvocationList
();
Task
[]
handlerTasks
=
new
Task
[
invocationList
.
Length
];
var
handlerTasks
=
new
Task
[
invocationList
.
Length
];
for
(
int
i
=
0
;
i
<
invocationList
.
Length
;
i
++)
for
(
var
i
=
0
;
i
<
invocationList
.
Length
;
i
++)
{
{
handlerTasks
[
i
]
=
((
Func
<
object
,
SessionEventArgs
,
Task
>)
invocationList
[
i
])(
null
,
args
);
handlerTasks
[
i
]
=
((
Func
<
object
,
SessionEventArgs
,
Task
>)
invocationList
[
i
])(
null
,
args
);
}
}
...
@@ -495,8 +479,8 @@ namespace Titanium.Web.Proxy
...
@@ -495,8 +479,8 @@ namespace Titanium.Web.Proxy
{
{
await
TcpHelper
.
SendRaw
(
BUFFER_SIZE
,
ConnectionTimeOutSeconds
,
httpRemoteUri
.
Host
,
httpRemoteUri
.
Port
,
await
TcpHelper
.
SendRaw
(
BUFFER_SIZE
,
ConnectionTimeOutSeconds
,
httpRemoteUri
.
Host
,
httpRemoteUri
.
Port
,
httpCmd
,
httpVersion
,
args
.
WebSession
.
Request
.
RequestHeaders
,
args
.
IsHttps
,
httpCmd
,
httpVersion
,
args
.
WebSession
.
Request
.
RequestHeaders
,
args
.
IsHttps
,
SupportedSslProtocols
,
new
RemoteCertificateValidationCallback
(
ValidateServerCertificate
)
,
SupportedSslProtocols
,
ValidateServerCertificate
,
new
LocalCertificateSelectionCallback
(
SelectClientCertificate
)
,
SelectClientCertificate
,
clientStream
,
tcpConnectionFactory
,
UpStreamEndPoint
);
clientStream
,
tcpConnectionFactory
,
UpStreamEndPoint
);
Dispose
(
clientStream
,
clientStreamReader
,
clientStreamWriter
,
args
);
Dispose
(
clientStream
,
clientStreamReader
,
clientStreamWriter
,
args
);
...
@@ -504,7 +488,7 @@ namespace Titanium.Web.Proxy
...
@@ -504,7 +488,7 @@ namespace Titanium.Web.Proxy
}
}
//construct the web request that we are going to issue on behalf of the client.
//construct the web request that we are going to issue on behalf of the client.
await
HandleHttpSessionRequestInternal
(
connection
,
args
,
customUpStreamHttpProxy
,
customUpStreamHttpsProxy
,
false
).
ConfigureAwait
(
false
);
await
HandleHttpSessionRequestInternal
(
null
,
args
,
customUpStreamHttpProxy
,
customUpStreamHttpsProxy
,
false
).
ConfigureAwait
(
false
);
if
(
args
.
WebSession
.
Request
.
CancelRequest
)
if
(
args
.
WebSession
.
Request
.
CancelRequest
)
...
@@ -531,12 +515,8 @@ namespace Titanium.Web.Proxy
...
@@ -531,12 +515,8 @@ namespace Titanium.Web.Proxy
}
}
if
(
connection
!=
null
)
//dispose
{
connection
?.
Dispose
();
//dispose
connection
.
Dispose
();
}
}
}
/// <summary>
/// <summary>
...
@@ -547,8 +527,9 @@ namespace Titanium.Web.Proxy
...
@@ -547,8 +527,9 @@ namespace Titanium.Web.Proxy
/// <returns></returns>
/// <returns></returns>
private
async
Task
WriteConnectResponse
(
StreamWriter
clientStreamWriter
,
Version
httpVersion
)
private
async
Task
WriteConnectResponse
(
StreamWriter
clientStreamWriter
,
Version
httpVersion
)
{
{
await
clientStreamWriter
.
WriteLineAsync
(
string
.
Format
(
"HTTP/{0}.{1} {2}"
,
httpVersion
.
Major
,
httpVersion
.
Minor
,
"200 Connection established"
));
await
clientStreamWriter
.
WriteLineAsync
(
await
clientStreamWriter
.
WriteLineAsync
(
string
.
Format
(
"Timestamp: {0}"
,
DateTime
.
Now
));
$"HTTP/
{
httpVersion
.
Major
}
.
{
httpVersion
.
Minor
}
200 Connection established"
);
await
clientStreamWriter
.
WriteLineAsync
(
$"Timestamp:
{
DateTime
.
Now
}
"
);
await
clientStreamWriter
.
WriteLineAsync
();
await
clientStreamWriter
.
WriteLineAsync
();
await
clientStreamWriter
.
FlushAsync
();
await
clientStreamWriter
.
FlushAsync
();
}
}
...
@@ -570,9 +551,6 @@ namespace Titanium.Web.Proxy
...
@@ -570,9 +551,6 @@ namespace Titanium.Web.Proxy
case
"accept-encoding"
:
case
"accept-encoding"
:
header
.
Value
=
"gzip,deflate"
;
header
.
Value
=
"gzip,deflate"
;
break
;
break
;
default
:
break
;
}
}
}
}
...
...
Titanium.Web.Proxy/ResponseHandler.cs
View file @
1057c2ff
...
@@ -17,7 +17,11 @@ namespace Titanium.Web.Proxy
...
@@ -17,7 +17,11 @@ namespace Titanium.Web.Proxy
/// </summary>
/// </summary>
partial
class
ProxyServer
partial
class
ProxyServer
{
{
//Called asynchronously when a request was successfully and we received the response
/// <summary>
/// Called asynchronously when a request was successfully and we received the response
/// </summary>
/// <param name="args"></param>
/// <returns></returns>
public
async
Task
HandleHttpSessionResponse
(
SessionEventArgs
args
)
public
async
Task
HandleHttpSessionResponse
(
SessionEventArgs
args
)
{
{
//read response & headers from server
//read response & headers from server
...
@@ -156,14 +160,14 @@ namespace Titanium.Web.Proxy
...
@@ -156,14 +160,14 @@ namespace Titanium.Web.Proxy
private
async
Task
WriteResponseStatus
(
Version
version
,
string
code
,
string
description
,
private
async
Task
WriteResponseStatus
(
Version
version
,
string
code
,
string
description
,
StreamWriter
responseWriter
)
StreamWriter
responseWriter
)
{
{
await
responseWriter
.
WriteLineAsync
(
string
.
Format
(
"HTTP/{0}.{1} {2} {3}"
,
version
.
Major
,
version
.
Minor
,
code
,
description
)
);
await
responseWriter
.
WriteLineAsync
(
$"HTTP/
{
version
.
Major
}
.
{
version
.
Minor
}
{
code
}
{
description
}
"
);
}
}
/// <summary>
/// <summary>
/// Write response headers to client
/// Write response headers to client
/// </summary>
/// </summary>
/// <param name="responseWriter"></param>
/// <param name="responseWriter"></param>
/// <param name="
headers
"></param>
/// <param name="
response
"></param>
/// <returns></returns>
/// <returns></returns>
private
async
Task
WriteResponseHeaders
(
StreamWriter
responseWriter
,
Response
response
)
private
async
Task
WriteResponseHeaders
(
StreamWriter
responseWriter
,
Response
response
)
{
{
...
@@ -220,7 +224,6 @@ namespace Titanium.Web.Proxy
...
@@ -220,7 +224,6 @@ namespace Titanium.Web.Proxy
/// <summary>
/// <summary>
/// Handle dispose of a client/server session
/// Handle dispose of a client/server session
/// </summary>
/// </summary>
/// <param name="tcpClient"></param>
/// <param name="clientStream"></param>
/// <param name="clientStream"></param>
/// <param name="clientStreamReader"></param>
/// <param name="clientStreamReader"></param>
/// <param name="clientStreamWriter"></param>
/// <param name="clientStreamWriter"></param>
...
@@ -235,21 +238,13 @@ namespace Titanium.Web.Proxy
...
@@ -235,21 +238,13 @@ namespace Titanium.Web.Proxy
clientStream
.
Dispose
();
clientStream
.
Dispose
();
}
}
if
(
args
!=
null
)
args
?.
Dispose
();
{
args
.
Dispose
();
}
if
(
clientStreamReader
!=
null
)
clientStreamReader
?.
Dispose
();
{
clientStreamReader
.
Dispose
();
}
if
(
clientStreamWriter
!=
null
)
if
(
clientStreamWriter
==
null
)
return
;
{
clientStreamWriter
.
Close
();
clientStreamWriter
.
Close
();
clientStreamWriter
.
Dispose
();
clientStreamWriter
.
Dispose
();
}
}
}
}
}
}
}
\ No newline at end of file
Titanium.Web.Proxy/Shared/ProxyConstants.cs
View file @
1057c2ff
using
System
;
using
System.Text
;
using
System.Text
;
namespace
Titanium.Web.Proxy.Shared
namespace
Titanium.Web.Proxy.Shared
{
{
...
...
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