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
9df31edd
Commit
9df31edd
authored
Oct 13, 2019
by
Honfika
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Nullable reference fixes
parent
e3c1483f
Show whitespace changes
Inline
Side-by-side
Showing
54 changed files
with
354 additions
and
318 deletions
+354
-318
CertificateHandler.cs
src/Titanium.Web.Proxy/CertificateHandler.cs
+2
-2
BeforeSslAuthenticateEventArgs.cs
...eb.Proxy/EventArguments/BeforeSslAuthenticateEventArgs.cs
+3
-2
CertificateSelectionEventArgs.cs
...Web.Proxy/EventArguments/CertificateSelectionEventArgs.cs
+6
-6
SessionEventArgs.cs
src/Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
+8
-8
SessionEventArgsBase.cs
...Titanium.Web.Proxy/EventArguments/SessionEventArgsBase.cs
+5
-5
ProxyException.cs
src/Titanium.Web.Proxy/Exceptions/ProxyException.cs
+1
-1
ProxyHttpException.cs
src/Titanium.Web.Proxy/Exceptions/ProxyHttpException.cs
+2
-2
ExplicitClientHandler.cs
src/Titanium.Web.Proxy/ExplicitClientHandler.cs
+9
-9
SslExtensions.cs
src/Titanium.Web.Proxy/Extensions/SslExtensions.cs
+5
-5
HttpHelper.cs
src/Titanium.Web.Proxy/Helpers/HttpHelper.cs
+1
-1
HttpWriter.cs
src/Titanium.Web.Proxy/Helpers/HttpWriter.cs
+1
-1
ProxyInfo.cs
src/Titanium.Web.Proxy/Helpers/ProxyInfo.cs
+6
-6
SystemProxy.cs
src/Titanium.Web.Proxy/Helpers/SystemProxy.cs
+6
-6
TcpHelper.cs
src/Titanium.Web.Proxy/Helpers/TcpHelper.cs
+2
-2
NativeMethods.WinHttp.cs
...tanium.Web.Proxy/Helpers/WinHttp/NativeMethods.WinHttp.cs
+3
-3
WinHttpWebProxyFinder.cs
...tanium.Web.Proxy/Helpers/WinHttp/WinHttpWebProxyFinder.cs
+10
-10
ConnectResponse.cs
src/Titanium.Web.Proxy/Http/ConnectResponse.cs
+1
-1
HeaderCollection.cs
src/Titanium.Web.Proxy/Http/HeaderCollection.cs
+12
-6
HttpWebClient.cs
src/Titanium.Web.Proxy/Http/HttpWebClient.cs
+20
-5
InternalDataStore.cs
src/Titanium.Web.Proxy/Http/InternalDataStore.cs
+4
-3
Request.cs
src/Titanium.Web.Proxy/Http/Request.cs
+3
-3
RequestResponseBase.cs
src/Titanium.Web.Proxy/Http/RequestResponseBase.cs
+13
-13
Response.cs
src/Titanium.Web.Proxy/Http/Response.cs
+1
-1
GenericResponse.cs
src/Titanium.Web.Proxy/Http/Responses/GenericResponse.cs
+1
-1
Decoder.cs
src/Titanium.Web.Proxy/Http2/Hpack/Decoder.cs
+4
-5
DynamicTable.cs
src/Titanium.Web.Proxy/Http2/Hpack/DynamicTable.cs
+6
-6
Encoder.cs
src/Titanium.Web.Proxy/Http2/Hpack/Encoder.cs
+6
-6
HuffmanDecoder.cs
src/Titanium.Web.Proxy/Http2/Hpack/HuffmanDecoder.cs
+5
-5
Http2Helper.cs
src/Titanium.Web.Proxy/Http2/Http2Helper.cs
+23
-16
ExplicitProxyEndPoint.cs
src/Titanium.Web.Proxy/Models/ExplicitProxyEndPoint.cs
+2
-2
HttpHeader.cs
src/Titanium.Web.Proxy/Models/HttpHeader.cs
+13
-4
ProxyAuthenticationContext.cs
src/Titanium.Web.Proxy/Models/ProxyAuthenticationContext.cs
+1
-1
TransparentProxyEndPoint.cs
src/Titanium.Web.Proxy/Models/TransparentProxyEndPoint.cs
+1
-1
BCCertificateMaker.cs
...anium.Web.Proxy/Network/Certificate/BCCertificateMaker.cs
+13
-23
ICertificateMaker.cs
...tanium.Web.Proxy/Network/Certificate/ICertificateMaker.cs
+1
-1
WinCertificateMaker.cs
...nium.Web.Proxy/Network/Certificate/WinCertificateMaker.cs
+20
-27
CertificateManager.cs
src/Titanium.Web.Proxy/Network/CertificateManager.cs
+22
-11
DefaultCertificateDiskCache.cs
...Titanium.Web.Proxy/Network/DefaultCertificateDiskCache.cs
+5
-5
RetryPolicy.cs
src/Titanium.Web.Proxy/Network/RetryPolicy.cs
+7
-4
TcpConnectionFactory.cs
src/Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs
+22
-24
TcpServerConnection.cs
src/Titanium.Web.Proxy/Network/Tcp/TcpServerConnection.cs
+3
-3
Common.cs
src/Titanium.Web.Proxy/Network/WinAuth/Security/Common.cs
+2
-2
WinAuthEndPoint.cs
...ium.Web.Proxy/Network/WinAuth/Security/WinAuthEndPoint.cs
+9
-9
ProxyAuthorizationHandler.cs
src/Titanium.Web.Proxy/ProxyAuthorizationHandler.cs
+1
-1
ProxyServer.cs
src/Titanium.Web.Proxy/ProxyServer.cs
+13
-11
RequestHandler.cs
src/Titanium.Web.Proxy/RequestHandler.cs
+10
-8
ResponseHandler.cs
src/Titanium.Web.Proxy/ResponseHandler.cs
+5
-3
ClientHelloInfo.cs
src/Titanium.Web.Proxy/StreamExtended/ClientHelloInfo.cs
+7
-2
CopyStream.cs
src/Titanium.Web.Proxy/StreamExtended/Network/CopyStream.cs
+2
-4
CustomBufferedStream.cs
....Web.Proxy/StreamExtended/Network/CustomBufferedStream.cs
+3
-5
ServerHelloInfo.cs
src/Titanium.Web.Proxy/StreamExtended/ServerHelloInfo.cs
+3
-3
SslTools.cs
src/Titanium.Web.Proxy/StreamExtended/SslTools.cs
+8
-10
TransparentClientHandler.cs
src/Titanium.Web.Proxy/TransparentClientHandler.cs
+9
-11
WinAuthHandler.cs
src/Titanium.Web.Proxy/WinAuthHandler.cs
+3
-3
No files found.
src/Titanium.Web.Proxy/CertificateHandler.cs
View file @
9df31edd
...
@@ -53,11 +53,11 @@ namespace Titanium.Web.Proxy
...
@@ -53,11 +53,11 @@ namespace Titanium.Web.Proxy
/// <param name="remoteCertificate">The remote certificate of server.</param>
/// <param name="remoteCertificate">The remote certificate of server.</param>
/// <param name="acceptableIssuers">The acceptable issues for client certificate as listed by server.</param>
/// <param name="acceptableIssuers">The acceptable issues for client certificate as listed by server.</param>
/// <returns></returns>
/// <returns></returns>
internal
X509Certificate
SelectClientCertificate
(
object
sender
,
string
targetHost
,
internal
X509Certificate
?
SelectClientCertificate
(
object
sender
,
string
targetHost
,
X509CertificateCollection
localCertificates
,
X509CertificateCollection
localCertificates
,
X509Certificate
remoteCertificate
,
string
[]
acceptableIssuers
)
X509Certificate
remoteCertificate
,
string
[]
acceptableIssuers
)
{
{
X509Certificate
clientCertificate
=
null
;
X509Certificate
?
clientCertificate
=
null
;
if
(
acceptableIssuers
!=
null
&&
acceptableIssuers
.
Length
>
0
&&
localCertificates
!=
null
&&
if
(
acceptableIssuers
!=
null
&&
acceptableIssuers
.
Length
>
0
&&
localCertificates
!=
null
&&
localCertificates
.
Count
>
0
)
localCertificates
.
Count
>
0
)
...
...
src/Titanium.Web.Proxy/EventArguments/BeforeSslAuthenticateEventArgs.cs
View file @
9df31edd
...
@@ -10,16 +10,17 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -10,16 +10,17 @@ namespace Titanium.Web.Proxy.EventArguments
{
{
internal
readonly
CancellationTokenSource
TaskCancellationSource
;
internal
readonly
CancellationTokenSource
TaskCancellationSource
;
internal
BeforeSslAuthenticateEventArgs
(
CancellationTokenSource
taskCancellationSource
)
internal
BeforeSslAuthenticateEventArgs
(
CancellationTokenSource
taskCancellationSource
,
string
sniHostName
)
{
{
TaskCancellationSource
=
taskCancellationSource
;
TaskCancellationSource
=
taskCancellationSource
;
SniHostName
=
sniHostName
;
}
}
/// <summary>
/// <summary>
/// The server name indication hostname if available. Otherwise the generic certificate hostname of
/// The server name indication hostname if available. Otherwise the generic certificate hostname of
/// TransparentEndPoint.
/// TransparentEndPoint.
/// </summary>
/// </summary>
public
string
SniHostName
{
get
;
internal
set
;
}
public
string
SniHostName
{
get
;
}
/// <summary>
/// <summary>
/// Should we decrypt the SSL request?
/// Should we decrypt the SSL request?
...
...
src/Titanium.Web.Proxy/EventArguments/CertificateSelectionEventArgs.cs
View file @
9df31edd
...
@@ -11,31 +11,31 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -11,31 +11,31 @@ namespace Titanium.Web.Proxy.EventArguments
/// <summary>
/// <summary>
/// The proxy server instance.
/// The proxy server instance.
/// </summary>
/// </summary>
public
object
Sender
{
get
;
internal
set
;
}
public
object
?
Sender
{
get
;
internal
set
;
}
/// <summary>
/// <summary>
/// The remote hostname to which we are authenticating against.
/// The remote hostname to which we are authenticating against.
/// </summary>
/// </summary>
public
string
TargetHost
{
get
;
internal
set
;
}
public
string
?
TargetHost
{
get
;
internal
set
;
}
/// <summary>
/// <summary>
/// Local certificates in store with matching issuers requested by TargetHost website.
/// Local certificates in store with matching issuers requested by TargetHost website.
/// </summary>
/// </summary>
public
X509CertificateCollection
LocalCertificates
{
get
;
internal
set
;
}
public
X509CertificateCollection
?
LocalCertificates
{
get
;
internal
set
;
}
/// <summary>
/// <summary>
/// Certificate of the remote server.
/// Certificate of the remote server.
/// </summary>
/// </summary>
public
X509Certificate
RemoteCertificate
{
get
;
internal
set
;
}
public
X509Certificate
?
RemoteCertificate
{
get
;
internal
set
;
}
/// <summary>
/// <summary>
/// Acceptable issuers as listed by remote server.
/// Acceptable issuers as listed by remote server.
/// </summary>
/// </summary>
public
string
[]
AcceptableIssuers
{
get
;
internal
set
;
}
public
string
[]
?
AcceptableIssuers
{
get
;
internal
set
;
}
/// <summary>
/// <summary>
/// Client Certificate we selected. Set this value to override.
/// Client Certificate we selected. Set this value to override.
/// </summary>
/// </summary>
public
X509Certificate
ClientCertificate
{
get
;
set
;
}
public
X509Certificate
?
ClientCertificate
{
get
;
set
;
}
}
}
}
}
src/Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
View file @
9df31edd
...
@@ -70,7 +70,7 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -70,7 +70,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// <summary>
/// <summary>
/// Occurs when multipart request part sent.
/// Occurs when multipart request part sent.
/// </summary>
/// </summary>
public
event
EventHandler
<
MultipartRequestPartSentEventArgs
>
MultipartRequestPartSent
;
public
event
EventHandler
<
MultipartRequestPartSentEventArgs
>
?
MultipartRequestPartSent
;
private
ICustomStreamReader
getStreamReader
(
bool
isRequest
)
private
ICustomStreamReader
getStreamReader
(
bool
isRequest
)
{
{
...
@@ -105,7 +105,7 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -105,7 +105,7 @@ namespace Titanium.Web.Proxy.EventArguments
request
.
ReadHttp2BodyTaskCompletionSource
=
tcs
;
request
.
ReadHttp2BodyTaskCompletionSource
=
tcs
;
// signal to HTTP/2 copy frame method to continue
// signal to HTTP/2 copy frame method to continue
request
.
ReadHttp2BeforeHandlerTaskCompletionSource
.
SetResult
(
true
);
request
.
ReadHttp2BeforeHandlerTaskCompletionSource
!
.
SetResult
(
true
);
await
tcs
.
Task
;
await
tcs
.
Task
;
...
@@ -177,7 +177,7 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -177,7 +177,7 @@ namespace Titanium.Web.Proxy.EventArguments
response
.
ReadHttp2BodyTaskCompletionSource
=
tcs
;
response
.
ReadHttp2BodyTaskCompletionSource
=
tcs
;
// signal to HTTP/2 copy frame method to continue
// signal to HTTP/2 copy frame method to continue
response
.
ReadHttp2BeforeHandlerTaskCompletionSource
.
SetResult
(
true
);
response
.
ReadHttp2BeforeHandlerTaskCompletionSource
!
.
SetResult
(
true
);
await
tcs
.
Task
;
await
tcs
.
Task
;
...
@@ -286,7 +286,7 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -286,7 +286,7 @@ namespace Titanium.Web.Proxy.EventArguments
await
copyBodyAsync
(
false
,
false
,
writer
,
transformation
,
OnDataReceived
,
cancellationToken
);
await
copyBodyAsync
(
false
,
false
,
writer
,
transformation
,
OnDataReceived
,
cancellationToken
);
}
}
private
async
Task
copyBodyAsync
(
bool
isRequest
,
bool
useOriginalHeaderValues
,
HttpWriter
writer
,
TransformationMode
transformation
,
Action
<
byte
[],
int
,
int
>
onCopy
,
CancellationToken
cancellationToken
)
private
async
Task
copyBodyAsync
(
bool
isRequest
,
bool
useOriginalHeaderValues
,
HttpWriter
writer
,
TransformationMode
transformation
,
Action
<
byte
[],
int
,
int
>
?
onCopy
,
CancellationToken
cancellationToken
)
{
{
var
stream
=
getStreamReader
(
isRequest
);
var
stream
=
getStreamReader
(
isRequest
);
...
@@ -302,9 +302,9 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -302,9 +302,9 @@ namespace Titanium.Web.Proxy.EventArguments
}
}
LimitedStream
limitedStream
;
LimitedStream
limitedStream
;
Stream
decompressStream
=
null
;
Stream
?
decompressStream
=
null
;
string
contentEncoding
=
useOriginalHeaderValues
?
requestResponse
.
OriginalContentEncoding
:
requestResponse
.
ContentEncoding
;
string
?
contentEncoding
=
useOriginalHeaderValues
?
requestResponse
.
OriginalContentEncoding
:
requestResponse
.
ContentEncoding
;
Stream
s
=
limitedStream
=
new
LimitedStream
(
stream
,
BufferPool
,
isChunked
,
contentLength
);
Stream
s
=
limitedStream
=
new
LimitedStream
(
stream
,
BufferPool
,
isChunked
,
contentLength
);
...
@@ -541,7 +541,7 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -541,7 +541,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// <param name="result">The html content bytes.</param>
/// <param name="result">The html content bytes.</param>
/// <param name="headers">The HTTP headers.</param>
/// <param name="headers">The HTTP headers.</param>
/// <param name="closeServerConnection">Close the server connection used by request if any?</param>
/// <param name="closeServerConnection">Close the server connection used by request if any?</param>
public
void
Ok
(
byte
[]
result
,
Dictionary
<
string
,
HttpHeader
>
headers
=
null
,
public
void
Ok
(
byte
[]
result
,
Dictionary
<
string
,
HttpHeader
>
?
headers
=
null
,
bool
closeServerConnection
=
false
)
bool
closeServerConnection
=
false
)
{
{
var
response
=
new
OkResponse
();
var
response
=
new
OkResponse
();
...
@@ -562,7 +562,7 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -562,7 +562,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// <param name="headers">The HTTP headers.</param>
/// <param name="headers">The HTTP headers.</param>
/// <param name="closeServerConnection">Close the server connection used by request if any?</param>
/// <param name="closeServerConnection">Close the server connection used by request if any?</param>
public
void
GenericResponse
(
string
html
,
HttpStatusCode
status
,
public
void
GenericResponse
(
string
html
,
HttpStatusCode
status
,
Dictionary
<
string
,
HttpHeader
>
headers
=
null
,
bool
closeServerConnection
=
false
)
Dictionary
<
string
,
HttpHeader
>
?
headers
=
null
,
bool
closeServerConnection
=
false
)
{
{
var
response
=
new
GenericResponse
(
status
);
var
response
=
new
GenericResponse
(
status
);
response
.
HttpVersion
=
HttpClient
.
Request
.
HttpVersion
;
response
.
HttpVersion
=
HttpClient
.
Request
.
HttpVersion
;
...
...
src/Titanium.Web.Proxy/EventArguments/SessionEventArgsBase.cs
View file @
9df31edd
...
@@ -70,7 +70,7 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -70,7 +70,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// Returns a user data for this request/response session which is
/// Returns a user data for this request/response session which is
/// same as the user data of HttpClient.
/// same as the user data of HttpClient.
/// </summary>
/// </summary>
public
object
UserData
public
object
?
UserData
{
{
get
=>
HttpClient
.
UserData
;
get
=>
HttpClient
.
UserData
;
set
=>
HttpClient
.
UserData
=
value
;
set
=>
HttpClient
.
UserData
=
value
;
...
@@ -112,7 +112,7 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -112,7 +112,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// <summary>
/// <summary>
/// Are we using a custom upstream HTTP(S) proxy?
/// Are we using a custom upstream HTTP(S) proxy?
/// </summary>
/// </summary>
public
ExternalProxy
CustomUpStreamProxyUsed
{
get
;
internal
set
;
}
public
ExternalProxy
?
CustomUpStreamProxyUsed
{
get
;
internal
set
;
}
/// <summary>
/// <summary>
/// Local endpoint via which we make the request.
/// Local endpoint via which we make the request.
...
@@ -127,7 +127,7 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -127,7 +127,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// <summary>
/// <summary>
/// The last exception that happened.
/// The last exception that happened.
/// </summary>
/// </summary>
public
Exception
Exception
{
get
;
internal
set
;
}
public
Exception
?
Exception
{
get
;
internal
set
;
}
/// <summary>
/// <summary>
/// Implements cleanup here.
/// Implements cleanup here.
...
@@ -146,12 +146,12 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -146,12 +146,12 @@ namespace Titanium.Web.Proxy.EventArguments
/// <summary>
/// <summary>
/// Fired when data is sent within this session to server/client.
/// Fired when data is sent within this session to server/client.
/// </summary>
/// </summary>
public
event
EventHandler
<
DataEventArgs
>
DataSent
;
public
event
EventHandler
<
DataEventArgs
>
?
DataSent
;
/// <summary>
/// <summary>
/// Fired when data is received within this session from client/server.
/// Fired when data is received within this session from client/server.
/// </summary>
/// </summary>
public
event
EventHandler
<
DataEventArgs
>
DataReceived
;
public
event
EventHandler
<
DataEventArgs
>
?
DataReceived
;
internal
void
OnDataSent
(
byte
[]
buffer
,
int
offset
,
int
count
)
internal
void
OnDataSent
(
byte
[]
buffer
,
int
offset
,
int
count
)
{
{
...
...
src/Titanium.Web.Proxy/Exceptions/ProxyException.cs
View file @
9df31edd
...
@@ -22,7 +22,7 @@ namespace Titanium.Web.Proxy.Exceptions
...
@@ -22,7 +22,7 @@ namespace Titanium.Web.Proxy.Exceptions
/// </summary>
/// </summary>
/// <param name="message">Exception message</param>
/// <param name="message">Exception message</param>
/// <param name="innerException">Inner exception associated</param>
/// <param name="innerException">Inner exception associated</param>
protected
ProxyException
(
string
message
,
Exception
innerException
)
:
base
(
message
,
innerException
)
protected
ProxyException
(
string
message
,
Exception
?
innerException
)
:
base
(
message
,
innerException
)
{
{
}
}
}
}
...
...
src/Titanium.Web.Proxy/Exceptions/ProxyHttpException.cs
View file @
9df31edd
...
@@ -14,7 +14,7 @@ namespace Titanium.Web.Proxy.Exceptions
...
@@ -14,7 +14,7 @@ namespace Titanium.Web.Proxy.Exceptions
/// <param name="message">Message for this exception</param>
/// <param name="message">Message for this exception</param>
/// <param name="innerException">Associated inner exception</param>
/// <param name="innerException">Associated inner exception</param>
/// <param name="session">Instance of <see cref="EventArguments.SessionEventArgs" /> associated to the exception</param>
/// <param name="session">Instance of <see cref="EventArguments.SessionEventArgs" /> associated to the exception</param>
internal
ProxyHttpException
(
string
message
,
Exception
?
innerException
,
SessionEventArgs
session
)
:
base
(
internal
ProxyHttpException
(
string
message
,
Exception
?
innerException
,
SessionEventArgs
?
session
)
:
base
(
message
,
innerException
)
message
,
innerException
)
{
{
Session
=
session
;
Session
=
session
;
...
@@ -26,6 +26,6 @@ namespace Titanium.Web.Proxy.Exceptions
...
@@ -26,6 +26,6 @@ namespace Titanium.Web.Proxy.Exceptions
/// <remarks>
/// <remarks>
/// This object properties should not be edited.
/// This object properties should not be edited.
/// </remarks>
/// </remarks>
public
SessionEventArgs
Session
{
get
;
}
public
SessionEventArgs
?
Session
{
get
;
}
}
}
}
}
src/Titanium.Web.Proxy/ExplicitClientHandler.cs
View file @
9df31edd
...
@@ -38,16 +38,16 @@ namespace Titanium.Web.Proxy
...
@@ -38,16 +38,16 @@ namespace Titanium.Web.Proxy
var
clientStream
=
new
CustomBufferedStream
(
clientConnection
.
GetStream
(),
BufferPool
);
var
clientStream
=
new
CustomBufferedStream
(
clientConnection
.
GetStream
(),
BufferPool
);
var
clientStreamWriter
=
new
HttpResponseWriter
(
clientStream
,
BufferPool
);
var
clientStreamWriter
=
new
HttpResponseWriter
(
clientStream
,
BufferPool
);
Task
<
TcpServerConnection
>
prefetchConnectionTask
=
null
;
Task
<
TcpServerConnection
>
?
prefetchConnectionTask
=
null
;
bool
closeServerConnection
=
false
;
bool
closeServerConnection
=
false
;
bool
calledRequestHandler
=
false
;
bool
calledRequestHandler
=
false
;
SslStream
sslStream
=
null
;
SslStream
?
sslStream
=
null
;
try
try
{
{
string
connectHostname
=
null
;
string
?
connectHostname
=
null
;
TunnelConnectSessionEventArgs
connectArgs
=
null
;
TunnelConnectSessionEventArgs
?
connectArgs
=
null
;
// Client wants to create a secure tcp tunnel (probably its a HTTPS or Websocket request)
// Client wants to create a secure tcp tunnel (probably its a HTTPS or Websocket request)
if
(
await
HttpHelper
.
IsConnectMethod
(
clientStream
,
BufferPool
,
cancellationToken
)
==
1
)
if
(
await
HttpHelper
.
IsConnectMethod
(
clientStream
,
BufferPool
,
cancellationToken
)
==
1
)
...
@@ -126,7 +126,7 @@ namespace Titanium.Web.Proxy
...
@@ -126,7 +126,7 @@ namespace Titanium.Web.Proxy
var
clientHelloInfo
=
await
SslTools
.
PeekClientHello
(
clientStream
,
BufferPool
,
cancellationToken
);
var
clientHelloInfo
=
await
SslTools
.
PeekClientHello
(
clientStream
,
BufferPool
,
cancellationToken
);
bool
isClientHello
=
clientHelloInfo
!=
null
;
bool
isClientHello
=
clientHelloInfo
!=
null
;
if
(
isClientHello
)
if
(
clientHelloInfo
!=
null
)
{
{
connectRequest
.
TunnelType
=
TunnelType
.
Https
;
connectRequest
.
TunnelType
=
TunnelType
.
Https
;
connectRequest
.
ClientHelloInfo
=
clientHelloInfo
;
connectRequest
.
ClientHelloInfo
=
clientHelloInfo
;
...
@@ -134,7 +134,7 @@ namespace Titanium.Web.Proxy
...
@@ -134,7 +134,7 @@ namespace Titanium.Web.Proxy
await
endPoint
.
InvokeBeforeTunnelConnectResponse
(
this
,
connectArgs
,
ExceptionFunc
,
isClientHello
);
await
endPoint
.
InvokeBeforeTunnelConnectResponse
(
this
,
connectArgs
,
ExceptionFunc
,
isClientHello
);
if
(
decryptSsl
&&
isClientHello
)
if
(
decryptSsl
&&
clientHelloInfo
!=
null
)
{
{
clientConnection
.
SslProtocol
=
clientHelloInfo
.
SslProtocol
;
clientConnection
.
SslProtocol
=
clientHelloInfo
.
SslProtocol
;
connectRequest
.
RequestUri
=
new
Uri
(
"https://"
+
httpUrl
);
connectRequest
.
RequestUri
=
new
Uri
(
"https://"
+
httpUrl
);
...
@@ -166,7 +166,7 @@ namespace Titanium.Web.Proxy
...
@@ -166,7 +166,7 @@ namespace Titanium.Web.Proxy
if
(
EnableTcpServerConnectionPrefetch
)
if
(
EnableTcpServerConnectionPrefetch
)
{
{
IPAddress
[]
ipAddresses
=
null
;
IPAddress
[]
?
ipAddresses
=
null
;
try
try
{
{
// make sure the host can be resolved before creating the prefetch task
// make sure the host can be resolved before creating the prefetch task
...
@@ -184,7 +184,7 @@ namespace Titanium.Web.Proxy
...
@@ -184,7 +184,7 @@ namespace Titanium.Web.Proxy
}
}
}
}
X509Certificate2
certificate
=
null
;
X509Certificate2
?
certificate
=
null
;
try
try
{
{
sslStream
=
new
SslStream
(
clientStream
,
false
);
sslStream
=
new
SslStream
(
clientStream
,
false
);
...
@@ -306,7 +306,7 @@ namespace Titanium.Web.Proxy
...
@@ -306,7 +306,7 @@ namespace Titanium.Web.Proxy
string
httpCmd
=
await
clientStream
.
ReadLineAsync
(
cancellationToken
);
string
httpCmd
=
await
clientStream
.
ReadLineAsync
(
cancellationToken
);
if
(
httpCmd
==
"PRI * HTTP/2.0"
)
if
(
httpCmd
==
"PRI * HTTP/2.0"
)
{
{
connectArgs
.
HttpClient
.
ConnectRequest
.
TunnelType
=
TunnelType
.
Http2
;
connectArgs
.
HttpClient
.
ConnectRequest
!
.
TunnelType
=
TunnelType
.
Http2
;
// HTTP/2 Connection Preface
// HTTP/2 Connection Preface
string
line
=
await
clientStream
.
ReadLineAsync
(
cancellationToken
);
string
line
=
await
clientStream
.
ReadLineAsync
(
cancellationToken
);
...
...
src/Titanium.Web.Proxy/Extensions/SslExtensions.cs
View file @
9df31edd
...
@@ -17,7 +17,7 @@ namespace Titanium.Web.Proxy.Extensions
...
@@ -17,7 +17,7 @@ namespace Titanium.Web.Proxy.Extensions
internal
static
readonly
List
<
SslApplicationProtocol
>
Http2ProtocolAsList
=
internal
static
readonly
List
<
SslApplicationProtocol
>
Http2ProtocolAsList
=
new
List
<
SslApplicationProtocol
>
{
SslApplicationProtocol
.
Http2
};
new
List
<
SslApplicationProtocol
>
{
SslApplicationProtocol
.
Http2
};
internal
static
string
GetServerName
(
this
ClientHelloInfo
clientHelloInfo
)
internal
static
string
?
GetServerName
(
this
ClientHelloInfo
clientHelloInfo
)
{
{
if
(
clientHelloInfo
.
Extensions
!=
null
&&
if
(
clientHelloInfo
.
Extensions
!=
null
&&
clientHelloInfo
.
Extensions
.
TryGetValue
(
"server_name"
,
out
var
serverNameExtension
))
clientHelloInfo
.
Extensions
.
TryGetValue
(
"server_name"
,
out
var
serverNameExtension
))
...
@@ -29,7 +29,7 @@ namespace Titanium.Web.Proxy.Extensions
...
@@ -29,7 +29,7 @@ namespace Titanium.Web.Proxy.Extensions
}
}
#if NETSTANDARD2_1
#if NETSTANDARD2_1
internal
static
List
<
SslApplicationProtocol
>
GetAlpn
(
this
ClientHelloInfo
clientHelloInfo
)
internal
static
List
<
SslApplicationProtocol
>
?
GetAlpn
(
this
ClientHelloInfo
clientHelloInfo
)
{
{
if
(
clientHelloInfo
.
Extensions
!=
null
&&
clientHelloInfo
.
Extensions
.
TryGetValue
(
"ALPN"
,
out
var
alpnExtension
))
if
(
clientHelloInfo
.
Extensions
!=
null
&&
clientHelloInfo
.
Extensions
.
TryGetValue
(
"ALPN"
,
out
var
alpnExtension
))
{
{
...
@@ -111,7 +111,7 @@ namespace Titanium.Web.Proxy.Extensions
...
@@ -111,7 +111,7 @@ namespace Titanium.Web.Proxy.Extensions
{
{
internal
bool
AllowRenegotiation
{
get
;
set
;
}
internal
bool
AllowRenegotiation
{
get
;
set
;
}
internal
X509Certificate
ServerCertificate
{
get
;
set
;
}
internal
X509Certificate
?
ServerCertificate
{
get
;
set
;
}
internal
bool
ClientCertificateRequired
{
get
;
set
;
}
internal
bool
ClientCertificateRequired
{
get
;
set
;
}
...
@@ -119,9 +119,9 @@ namespace Titanium.Web.Proxy.Extensions
...
@@ -119,9 +119,9 @@ namespace Titanium.Web.Proxy.Extensions
internal
X509RevocationMode
CertificateRevocationCheckMode
{
get
;
set
;
}
internal
X509RevocationMode
CertificateRevocationCheckMode
{
get
;
set
;
}
internal
List
<
SslApplicationProtocol
>
ApplicationProtocols
{
get
;
set
;
}
internal
List
<
SslApplicationProtocol
>
?
ApplicationProtocols
{
get
;
set
;
}
internal
RemoteCertificateValidationCallback
RemoteCertificateValidationCallback
{
get
;
set
;
}
internal
RemoteCertificateValidationCallback
?
RemoteCertificateValidationCallback
{
get
;
set
;
}
internal
EncryptionPolicy
EncryptionPolicy
{
get
;
set
;
}
internal
EncryptionPolicy
EncryptionPolicy
{
get
;
set
;
}
}
}
...
...
src/Titanium.Web.Proxy/Helpers/HttpHelper.cs
View file @
9df31edd
...
@@ -197,7 +197,7 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -197,7 +197,7 @@ namespace Titanium.Web.Proxy.Helpers
private
static
async
Task
<
int
>
startsWith
(
ICustomStreamReader
clientStreamReader
,
IBufferPool
bufferPool
,
string
expectedStart
,
CancellationToken
cancellationToken
=
default
)
private
static
async
Task
<
int
>
startsWith
(
ICustomStreamReader
clientStreamReader
,
IBufferPool
bufferPool
,
string
expectedStart
,
CancellationToken
cancellationToken
=
default
)
{
{
const
int
lengthToCheck
=
10
;
const
int
lengthToCheck
=
10
;
byte
[]
buffer
=
null
;
byte
[]
?
buffer
=
null
;
try
try
{
{
if
(
bufferPool
.
BufferSize
<
lengthToCheck
)
if
(
bufferPool
.
BufferSize
<
lengthToCheck
)
...
...
src/Titanium.Web.Proxy/Helpers/HttpWriter.cs
View file @
9df31edd
...
@@ -148,7 +148,7 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -148,7 +148,7 @@ namespace Titanium.Web.Proxy.Helpers
/// <param name="cancellationToken"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
/// <returns></returns>
internal
Task
CopyBodyAsync
(
ICustomStreamReader
streamReader
,
bool
isChunked
,
long
contentLength
,
internal
Task
CopyBodyAsync
(
ICustomStreamReader
streamReader
,
bool
isChunked
,
long
contentLength
,
Action
<
byte
[],
int
,
int
>
onCopy
,
CancellationToken
cancellationToken
)
Action
<
byte
[],
int
,
int
>
?
onCopy
,
CancellationToken
cancellationToken
)
{
{
// 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
(
isChunked
)
if
(
isChunked
)
...
...
src/Titanium.Web.Proxy/Helpers/ProxyInfo.cs
View file @
9df31edd
...
@@ -9,8 +9,8 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -9,8 +9,8 @@ namespace Titanium.Web.Proxy.Helpers
{
{
internal
class
ProxyInfo
internal
class
ProxyInfo
{
{
internal
ProxyInfo
(
bool
?
autoDetect
,
string
autoConfigUrl
,
int
?
proxyEnable
,
string
proxyServer
,
internal
ProxyInfo
(
bool
?
autoDetect
,
string
?
autoConfigUrl
,
int
?
proxyEnable
,
string
?
proxyServer
,
string
proxyOverride
)
string
?
proxyOverride
)
{
{
AutoDetect
=
autoDetect
;
AutoDetect
=
autoDetect
;
AutoConfigUrl
=
autoConfigUrl
;
AutoConfigUrl
=
autoConfigUrl
;
...
@@ -54,13 +54,13 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -54,13 +54,13 @@ namespace Titanium.Web.Proxy.Helpers
internal
bool
?
AutoDetect
{
get
;
}
internal
bool
?
AutoDetect
{
get
;
}
internal
string
AutoConfigUrl
{
get
;
}
internal
string
?
AutoConfigUrl
{
get
;
}
internal
int
?
ProxyEnable
{
get
;
}
internal
int
?
ProxyEnable
{
get
;
}
internal
string
ProxyServer
{
get
;
}
internal
string
?
ProxyServer
{
get
;
}
internal
string
ProxyOverride
{
get
;
}
internal
string
?
ProxyOverride
{
get
;
}
internal
bool
BypassLoopback
{
get
;
}
internal
bool
BypassLoopback
{
get
;
}
...
@@ -190,7 +190,7 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -190,7 +190,7 @@ namespace Titanium.Web.Proxy.Helpers
/// </summary>
/// </summary>
/// <param name="value"></param>
/// <param name="value"></param>
/// <returns></returns>
/// <returns></returns>
private
static
HttpSystemProxyValue
parseProxyValue
(
string
value
)
private
static
HttpSystemProxyValue
?
parseProxyValue
(
string
value
)
{
{
string
tmp
=
Regex
.
Replace
(
value
,
@"\s+"
,
" "
).
Trim
();
string
tmp
=
Regex
.
Replace
(
value
,
@"\s+"
,
" "
).
Trim
();
...
...
src/Titanium.Web.Proxy/Helpers/SystemProxy.cs
View file @
9df31edd
...
@@ -49,7 +49,7 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -49,7 +49,7 @@ namespace Titanium.Web.Proxy.Helpers
internal
const
int
InternetOptionSettingsChanged
=
39
;
internal
const
int
InternetOptionSettingsChanged
=
39
;
internal
const
int
InternetOptionRefresh
=
37
;
internal
const
int
InternetOptionRefresh
=
37
;
private
ProxyInfo
originalValues
;
private
ProxyInfo
?
originalValues
;
public
SystemProxyManager
()
public
SystemProxyManager
()
{
{
...
@@ -90,8 +90,8 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -90,8 +90,8 @@ namespace Titanium.Web.Proxy.Helpers
saveOriginalProxyConfiguration
(
reg
);
saveOriginalProxyConfiguration
(
reg
);
prepareRegistry
(
reg
);
prepareRegistry
(
reg
);
string
exisi
tingContent
=
reg
.
GetValue
(
regProxyServer
)
as
string
;
string
?
exis
tingContent
=
reg
.
GetValue
(
regProxyServer
)
as
string
;
var
existingSystemProxyValues
=
ProxyInfo
.
GetSystemProxyValues
(
exis
i
tingContent
);
var
existingSystemProxyValues
=
ProxyInfo
.
GetSystemProxyValues
(
existingContent
);
existingSystemProxyValues
.
RemoveAll
(
x
=>
(
protocolType
&
x
.
ProtocolType
)
!=
0
);
existingSystemProxyValues
.
RemoveAll
(
x
=>
(
protocolType
&
x
.
ProtocolType
)
!=
0
);
if
((
protocolType
&
ProxyProtocolType
.
Http
)
!=
0
)
if
((
protocolType
&
ProxyProtocolType
.
Http
)
!=
0
)
{
{
...
@@ -141,9 +141,9 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -141,9 +141,9 @@ namespace Titanium.Web.Proxy.Helpers
if
(
reg
.
GetValue
(
regProxyServer
)
!=
null
)
if
(
reg
.
GetValue
(
regProxyServer
)
!=
null
)
{
{
string
exisi
tingContent
=
reg
.
GetValue
(
regProxyServer
)
as
string
;
string
?
exis
tingContent
=
reg
.
GetValue
(
regProxyServer
)
as
string
;
var
existingSystemProxyValues
=
ProxyInfo
.
GetSystemProxyValues
(
exis
i
tingContent
);
var
existingSystemProxyValues
=
ProxyInfo
.
GetSystemProxyValues
(
existingContent
);
existingSystemProxyValues
.
RemoveAll
(
x
=>
(
protocolType
&
x
.
ProtocolType
)
!=
0
);
existingSystemProxyValues
.
RemoveAll
(
x
=>
(
protocolType
&
x
.
ProtocolType
)
!=
0
);
if
(
existingSystemProxyValues
.
Count
!=
0
)
if
(
existingSystemProxyValues
.
Count
!=
0
)
...
@@ -284,7 +284,7 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -284,7 +284,7 @@ namespace Titanium.Web.Proxy.Helpers
}
}
}
}
internal
ProxyInfo
GetProxyInfoFromRegistry
()
internal
ProxyInfo
?
GetProxyInfoFromRegistry
()
{
{
using
(
var
reg
=
openInternetSettingsKey
())
using
(
var
reg
=
openInternetSettingsKey
())
{
{
...
...
src/Titanium.Web.Proxy/Helpers/TcpHelper.cs
View file @
9df31edd
...
@@ -103,7 +103,7 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -103,7 +103,7 @@ namespace Titanium.Web.Proxy.Helpers
/// <param name="exceptionFunc"></param>
/// <param name="exceptionFunc"></param>
/// <returns></returns>
/// <returns></returns>
private
static
async
Task
sendRawTap
(
Stream
clientStream
,
Stream
serverStream
,
IBufferPool
bufferPool
,
private
static
async
Task
sendRawTap
(
Stream
clientStream
,
Stream
serverStream
,
IBufferPool
bufferPool
,
Action
<
byte
[],
int
,
int
>
onDataSend
,
Action
<
byte
[],
int
,
int
>
onDataReceive
,
Action
<
byte
[],
int
,
int
>
?
onDataSend
,
Action
<
byte
[],
int
,
int
>?
onDataReceive
,
CancellationTokenSource
cancellationTokenSource
,
CancellationTokenSource
cancellationTokenSource
,
ExceptionHandler
exceptionFunc
)
ExceptionHandler
exceptionFunc
)
{
{
...
@@ -133,7 +133,7 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -133,7 +133,7 @@ namespace Titanium.Web.Proxy.Helpers
/// <param name="exceptionFunc"></param>
/// <param name="exceptionFunc"></param>
/// <returns></returns>
/// <returns></returns>
internal
static
Task
SendRaw
(
Stream
clientStream
,
Stream
serverStream
,
IBufferPool
bufferPool
,
internal
static
Task
SendRaw
(
Stream
clientStream
,
Stream
serverStream
,
IBufferPool
bufferPool
,
Action
<
byte
[],
int
,
int
>
onDataSend
,
Action
<
byte
[],
int
,
int
>
onDataReceive
,
Action
<
byte
[],
int
,
int
>
?
onDataSend
,
Action
<
byte
[],
int
,
int
>?
onDataReceive
,
CancellationTokenSource
cancellationTokenSource
,
CancellationTokenSource
cancellationTokenSource
,
ExceptionHandler
exceptionFunc
)
ExceptionHandler
exceptionFunc
)
{
{
...
...
src/Titanium.Web.Proxy/Helpers/WinHttp/NativeMethods.WinHttp.cs
View file @
9df31edd
...
@@ -13,8 +13,8 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
...
@@ -13,8 +13,8 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
ref
WINHTTP_CURRENT_USER_IE_PROXY_CONFIG
proxyConfig
);
ref
WINHTTP_CURRENT_USER_IE_PROXY_CONFIG
proxyConfig
);
[
DllImport
(
"winhttp.dll"
,
CharSet
=
CharSet
.
Unicode
,
SetLastError
=
true
)]
[
DllImport
(
"winhttp.dll"
,
CharSet
=
CharSet
.
Unicode
,
SetLastError
=
true
)]
internal
static
extern
WinHttpHandle
WinHttpOpen
(
string
userAgent
,
AccessType
accessType
,
string
proxyName
,
internal
static
extern
WinHttpHandle
WinHttpOpen
(
string
?
userAgent
,
AccessType
accessType
,
string
?
proxyName
,
string
proxyBypass
,
int
dwFlags
);
string
?
proxyBypass
,
int
dwFlags
);
[
DllImport
(
"winhttp.dll"
,
CharSet
=
CharSet
.
Unicode
,
SetLastError
=
true
)]
[
DllImport
(
"winhttp.dll"
,
CharSet
=
CharSet
.
Unicode
,
SetLastError
=
true
)]
internal
static
extern
bool
WinHttpSetTimeouts
(
WinHttpHandle
session
,
int
resolveTimeout
,
internal
static
extern
bool
WinHttpSetTimeouts
(
WinHttpHandle
session
,
int
resolveTimeout
,
...
@@ -66,7 +66,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
...
@@ -66,7 +66,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
{
{
public
AutoProxyFlags
Flags
;
public
AutoProxyFlags
Flags
;
public
AutoDetectType
AutoDetectFlags
;
public
AutoDetectType
AutoDetectFlags
;
[
MarshalAs
(
UnmanagedType
.
LPWStr
)]
public
string
AutoConfigUrl
;
[
MarshalAs
(
UnmanagedType
.
LPWStr
)]
public
string
?
AutoConfigUrl
;
private
readonly
IntPtr
lpvReserved
;
private
readonly
IntPtr
lpvReserved
;
private
readonly
int
dwReserved
;
private
readonly
int
dwReserved
;
public
bool
AutoLogonIfChallenged
;
public
bool
AutoLogonIfChallenged
;
...
...
src/Titanium.Web.Proxy/Helpers/WinHttp/WinHttpWebProxyFinder.cs
View file @
9df31edd
using
System
;
using
System
;
using
System.Collections.Generic
;
using
System.Collections.Generic
;
using
System.Net
;
using
System.Net
;
using
System.Runtime.CompilerServices
;
using
System.Runtime.CompilerServices
;
...
@@ -42,7 +42,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
...
@@ -42,7 +42,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
public
bool
BypassOnLocal
{
get
;
internal
set
;
}
public
bool
BypassOnLocal
{
get
;
internal
set
;
}
public
Uri
AutomaticConfigurationScript
{
get
;
internal
set
;
}
public
Uri
?
AutomaticConfigurationScript
{
get
;
internal
set
;
}
public
bool
AutomaticallyDetectSettings
{
get
;
internal
set
;
}
public
bool
AutomaticallyDetectSettings
{
get
;
internal
set
;
}
...
@@ -53,7 +53,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
...
@@ -53,7 +53,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
dispose
(
true
);
dispose
(
true
);
}
}
public
bool
GetAutoProxies
(
Uri
destination
,
out
IList
<
string
>
proxyList
)
public
bool
GetAutoProxies
(
Uri
destination
,
out
IList
<
string
>
?
proxyList
)
{
{
proxyList
=
null
;
proxyList
=
null
;
if
(
session
==
null
||
session
.
IsInvalid
||
state
==
AutoWebProxyState
.
UnrecognizedScheme
)
if
(
session
==
null
||
session
.
IsInvalid
||
state
==
AutoWebProxyState
.
UnrecognizedScheme
)
...
@@ -61,7 +61,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
...
@@ -61,7 +61,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
return
false
;
return
false
;
}
}
string
proxyListString
=
null
;
string
?
proxyListString
=
null
;
var
errorCode
=
NativeMethods
.
WinHttp
.
ErrorCodes
.
AudodetectionFailed
;
var
errorCode
=
NativeMethods
.
WinHttp
.
ErrorCodes
.
AudodetectionFailed
;
if
(
AutomaticallyDetectSettings
&&
!
autoDetectFailed
)
if
(
AutomaticallyDetectSettings
&&
!
autoDetectFailed
)
{
{
...
@@ -88,14 +88,14 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
...
@@ -88,14 +88,14 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
if
(!
string
.
IsNullOrEmpty
(
proxyListString
))
if
(!
string
.
IsNullOrEmpty
(
proxyListString
))
{
{
proxyListString
=
removeWhitespaces
(
proxyListString
);
proxyListString
=
removeWhitespaces
(
proxyListString
!
);
proxyList
=
proxyListString
.
Split
(
';'
);
proxyList
=
proxyListString
.
Split
(
';'
);
}
}
return
true
;
return
true
;
}
}
public
ExternalProxy
GetProxy
(
Uri
destination
)
public
ExternalProxy
?
GetProxy
(
Uri
destination
)
{
{
if
(
GetAutoProxies
(
destination
,
out
var
proxies
))
if
(
GetAutoProxies
(
destination
,
out
var
proxies
))
{
{
...
@@ -131,12 +131,12 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
...
@@ -131,12 +131,12 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
var
protocolType
=
ProxyInfo
.
ParseProtocolType
(
destination
.
Scheme
);
var
protocolType
=
ProxyInfo
.
ParseProtocolType
(
destination
.
Scheme
);
if
(
protocolType
.
HasValue
)
if
(
protocolType
.
HasValue
)
{
{
HttpSystemProxyValue
value
=
null
;
HttpSystemProxyValue
?
value
=
null
;
if
(
ProxyInfo
?.
Proxies
?.
TryGetValue
(
protocolType
.
Value
,
out
value
)
==
true
)
if
(
ProxyInfo
?.
Proxies
?.
TryGetValue
(
protocolType
.
Value
,
out
value
)
==
true
)
{
{
var
systemProxy
=
new
ExternalProxy
var
systemProxy
=
new
ExternalProxy
{
{
HostName
=
value
.
HostName
,
HostName
=
value
!
.
HostName
,
Port
=
value
.
Port
Port
=
value
.
Port
};
};
...
@@ -210,7 +210,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
...
@@ -210,7 +210,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
session
.
Close
();
session
.
Close
();
}
}
private
int
getAutoProxies
(
Uri
destination
,
Uri
scriptLocation
,
out
string
proxyListString
)
private
int
getAutoProxies
(
Uri
destination
,
Uri
?
scriptLocation
,
out
string
?
proxyListString
)
{
{
int
num
=
0
;
int
num
=
0
;
var
autoProxyOptions
=
new
NativeMethods
.
WinHttp
.
WINHTTP_AUTOPROXY_OPTIONS
();
var
autoProxyOptions
=
new
NativeMethods
.
WinHttp
.
WINHTTP_AUTOPROXY_OPTIONS
();
...
@@ -247,7 +247,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
...
@@ -247,7 +247,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
}
}
private
bool
winHttpGetProxyForUrl
(
string
destination
,
private
bool
winHttpGetProxyForUrl
(
string
destination
,
ref
NativeMethods
.
WinHttp
.
WINHTTP_AUTOPROXY_OPTIONS
autoProxyOptions
,
out
string
proxyListString
)
ref
NativeMethods
.
WinHttp
.
WINHTTP_AUTOPROXY_OPTIONS
autoProxyOptions
,
out
string
?
proxyListString
)
{
{
proxyListString
=
null
;
proxyListString
=
null
;
bool
flag
;
bool
flag
;
...
...
src/Titanium.Web.Proxy/Http/ConnectResponse.cs
View file @
9df31edd
...
@@ -9,7 +9,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -9,7 +9,7 @@ namespace Titanium.Web.Proxy.Http
/// </summary>
/// </summary>
public
class
ConnectResponse
:
Response
public
class
ConnectResponse
:
Response
{
{
public
ServerHelloInfo
ServerHelloInfo
{
get
;
set
;
}
public
ServerHelloInfo
?
ServerHelloInfo
{
get
;
set
;
}
/// <summary>
/// <summary>
/// Creates a successful CONNECT response
/// Creates a successful CONNECT response
...
...
src/Titanium.Web.Proxy/Http/HeaderCollection.cs
View file @
9df31edd
...
@@ -71,7 +71,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -71,7 +71,7 @@ namespace Titanium.Web.Proxy.Http
/// </summary>
/// </summary>
/// <param name="name"></param>
/// <param name="name"></param>
/// <returns></returns>
/// <returns></returns>
public
List
<
HttpHeader
>
GetHeaders
(
string
name
)
public
List
<
HttpHeader
>
?
GetHeaders
(
string
name
)
{
{
if
(
headers
.
ContainsKey
(
name
))
if
(
headers
.
ContainsKey
(
name
))
{
{
...
@@ -89,7 +89,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -89,7 +89,7 @@ namespace Titanium.Web.Proxy.Http
return
null
;
return
null
;
}
}
public
HttpHeader
GetFirstHeader
(
string
name
)
public
HttpHeader
?
GetFirstHeader
(
string
name
)
{
{
if
(
headers
.
TryGetValue
(
name
,
out
var
header
))
if
(
headers
.
TryGetValue
(
name
,
out
var
header
))
{
{
...
@@ -198,7 +198,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -198,7 +198,7 @@ namespace Titanium.Web.Proxy.Http
/// Adds the given header objects to Request
/// Adds the given header objects to Request
/// </summary>
/// </summary>
/// <param name="newHeaders"></param>
/// <param name="newHeaders"></param>
public
void
AddHeaders
(
IEnumerable
<
KeyValuePair
<
string
,
HttpHeader
>>
newHeaders
)
public
void
AddHeaders
(
IEnumerable
<
KeyValuePair
<
string
,
HttpHeader
>>
?
newHeaders
)
{
{
if
(
newHeaders
==
null
)
if
(
newHeaders
==
null
)
{
{
...
@@ -272,7 +272,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -272,7 +272,7 @@ namespace Titanium.Web.Proxy.Http
nonUniqueHeaders
.
Clear
();
nonUniqueHeaders
.
Clear
();
}
}
internal
string
GetHeaderValueOrNull
(
string
headerName
)
internal
string
?
GetHeaderValueOrNull
(
string
headerName
)
{
{
if
(
headers
.
TryGetValue
(
headerName
,
out
var
header
))
if
(
headers
.
TryGetValue
(
headerName
,
out
var
header
))
{
{
...
@@ -282,8 +282,14 @@ namespace Titanium.Web.Proxy.Http
...
@@ -282,8 +282,14 @@ namespace Titanium.Web.Proxy.Http
return
null
;
return
null
;
}
}
internal
void
SetOrAddHeaderValue
(
string
headerName
,
string
value
)
internal
void
SetOrAddHeaderValue
(
string
headerName
,
string
?
value
)
{
{
if
(
value
==
null
)
{
RemoveHeader
(
headerName
);
return
;
}
if
(
headers
.
TryGetValue
(
headerName
,
out
var
header
))
if
(
headers
.
TryGetValue
(
headerName
,
out
var
header
))
{
{
header
.
Value
=
value
;
header
.
Value
=
value
;
...
@@ -300,7 +306,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -300,7 +306,7 @@ namespace Titanium.Web.Proxy.Http
internal
void
FixProxyHeaders
()
internal
void
FixProxyHeaders
()
{
{
// If proxy-connection close was returned inform to close the connection
// If proxy-connection close was returned inform to close the connection
string
proxyHeader
=
GetHeaderValueOrNull
(
KnownHeaders
.
ProxyConnection
);
string
?
proxyHeader
=
GetHeaderValueOrNull
(
KnownHeaders
.
ProxyConnection
);
RemoveHeader
(
KnownHeaders
.
ProxyConnection
);
RemoveHeader
(
KnownHeaders
.
ProxyConnection
);
if
(
proxyHeader
!=
null
)
if
(
proxyHeader
!=
null
)
...
...
src/Titanium.Web.Proxy/Http/HttpWebClient.cs
View file @
9df31edd
...
@@ -17,6 +17,8 @@ namespace Titanium.Web.Proxy.Http
...
@@ -17,6 +17,8 @@ namespace Titanium.Web.Proxy.Http
/// </summary>
/// </summary>
public
class
HttpWebClient
public
class
HttpWebClient
{
{
private
TcpServerConnection
?
connection
;
internal
HttpWebClient
(
Request
?
request
)
internal
HttpWebClient
(
Request
?
request
)
{
{
Request
=
request
??
new
Request
();
Request
=
request
??
new
Request
();
...
@@ -26,7 +28,20 @@ namespace Titanium.Web.Proxy.Http
...
@@ -26,7 +28,20 @@ namespace Titanium.Web.Proxy.Http
/// <summary>
/// <summary>
/// Connection to server
/// Connection to server
/// </summary>
/// </summary>
internal
TcpServerConnection
Connection
{
get
;
set
;
}
internal
TcpServerConnection
Connection
{
get
{
if
(
connection
==
null
)
{
throw
new
Exception
(
"Connection is null"
);
}
return
connection
;
}
}
internal
bool
HasConnection
=>
connection
!=
null
;
/// <summary>
/// <summary>
/// Should we close the server connection at the end of this HTTP request/response session.
/// Should we close the server connection at the end of this HTTP request/response session.
...
@@ -41,7 +56,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -41,7 +56,7 @@ namespace Titanium.Web.Proxy.Http
/// <summary>
/// <summary>
/// Gets or sets the user data.
/// Gets or sets the user data.
/// </summary>
/// </summary>
public
object
UserData
{
get
;
set
;
}
public
object
?
UserData
{
get
;
set
;
}
/// <summary>
/// <summary>
/// Override UpStreamEndPoint for this request; Local NIC via request is made
/// Override UpStreamEndPoint for this request; Local NIC via request is made
...
@@ -51,7 +66,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -51,7 +66,7 @@ namespace Titanium.Web.Proxy.Http
/// <summary>
/// <summary>
/// Headers passed with Connect.
/// Headers passed with Connect.
/// </summary>
/// </summary>
public
ConnectRequest
ConnectRequest
{
get
;
internal
set
;
}
public
ConnectRequest
?
ConnectRequest
{
get
;
internal
set
;
}
/// <summary>
/// <summary>
/// Web Request.
/// Web Request.
...
@@ -81,7 +96,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -81,7 +96,7 @@ namespace Titanium.Web.Proxy.Http
internal
void
SetConnection
(
TcpServerConnection
serverConnection
)
internal
void
SetConnection
(
TcpServerConnection
serverConnection
)
{
{
serverConnection
.
LastAccess
=
DateTime
.
Now
;
serverConnection
.
LastAccess
=
DateTime
.
Now
;
C
onnection
=
serverConnection
;
c
onnection
=
serverConnection
;
}
}
/// <summary>
/// <summary>
...
@@ -199,7 +214,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -199,7 +214,7 @@ namespace Titanium.Web.Proxy.Http
/// </summary>
/// </summary>
internal
void
FinishSession
()
internal
void
FinishSession
()
{
{
C
onnection
=
null
;
c
onnection
=
null
;
ConnectRequest
?.
FinishSession
();
ConnectRequest
?.
FinishSession
();
Request
?.
FinishSession
();
Request
?.
FinishSession
();
...
...
src/Titanium.Web.Proxy/Http/InternalDataStore.cs
View file @
9df31edd
using
System.Collections.Generic
;
using
System.Collections.Generic
;
namespace
Titanium.Web.Proxy.Http
namespace
Titanium.Web.Proxy.Http
{
{
...
@@ -13,7 +13,8 @@ namespace Titanium.Web.Proxy.Http
...
@@ -13,7 +13,8 @@ namespace Titanium.Web.Proxy.Http
}
}
else
else
{
{
value
=
default
;
// hack: https://stackoverflow.com/questions/54593923/nullable-reference-types-with-generic-return-type
value
=
default
!;
}
}
return
result
;
return
result
;
...
...
src/Titanium.Web.Proxy/Http/Request.cs
View file @
9df31edd
...
@@ -86,7 +86,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -86,7 +86,7 @@ namespace Titanium.Web.Proxy.Http
/// Note: Changing this does NOT change host in RequestUri.
/// Note: Changing this does NOT change host in RequestUri.
/// Users can set new RequestUri separately.
/// Users can set new RequestUri separately.
/// </summary>
/// </summary>
public
string
Host
public
string
?
Host
{
{
get
=>
Headers
.
GetHeaderValueOrNull
(
KnownHeaders
.
Host
);
get
=>
Headers
.
GetHeaderValueOrNull
(
KnownHeaders
.
Host
);
set
=>
Headers
.
SetOrAddHeaderValue
(
KnownHeaders
.
Host
,
value
);
set
=>
Headers
.
SetOrAddHeaderValue
(
KnownHeaders
.
Host
,
value
);
...
@@ -99,7 +99,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -99,7 +99,7 @@ namespace Titanium.Web.Proxy.Http
{
{
get
get
{
{
string
headerValue
=
Headers
.
GetHeaderValueOrNull
(
KnownHeaders
.
Expect
);
string
?
headerValue
=
Headers
.
GetHeaderValueOrNull
(
KnownHeaders
.
Expect
);
return
headerValue
!=
null
&&
headerValue
.
Equals
(
KnownHeaders
.
Expect100Continue
);
return
headerValue
!=
null
&&
headerValue
.
Equals
(
KnownHeaders
.
Expect100Continue
);
}
}
}
}
...
@@ -127,7 +127,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -127,7 +127,7 @@ namespace Titanium.Web.Proxy.Http
{
{
get
get
{
{
string
headerValue
=
Headers
.
GetHeaderValueOrNull
(
KnownHeaders
.
Upgrade
);
string
?
headerValue
=
Headers
.
GetHeaderValueOrNull
(
KnownHeaders
.
Upgrade
);
if
(
headerValue
==
null
)
if
(
headerValue
==
null
)
{
{
...
...
src/Titanium.Web.Proxy/Http/RequestResponseBase.cs
View file @
9df31edd
...
@@ -19,12 +19,12 @@ namespace Titanium.Web.Proxy.Http
...
@@ -19,12 +19,12 @@ namespace Titanium.Web.Proxy.Http
/// <summary>
/// <summary>
/// Cached body content as byte array.
/// Cached body content as byte array.
/// </summary>
/// </summary>
protected
byte
[]
BodyInternal
{
get
;
private
set
;
}
protected
byte
[]
?
BodyInternal
{
get
;
private
set
;
}
/// <summary>
/// <summary>
/// Cached body as string.
/// Cached body as string.
/// </summary>
/// </summary>
private
string
bodyString
;
private
string
?
bodyString
;
/// <summary>
/// <summary>
/// Store whether the original request/response has body or not, since the user may change the parameters.
/// Store whether the original request/response has body or not, since the user may change the parameters.
...
@@ -48,13 +48,13 @@ namespace Titanium.Web.Proxy.Http
...
@@ -48,13 +48,13 @@ namespace Titanium.Web.Proxy.Http
/// Store whether the original request/response content-encoding, since the user may change the parameters.
/// Store whether the original request/response content-encoding, since the user may change the parameters.
/// We need this detail to syphon out attached tcp connection for reuse.
/// We need this detail to syphon out attached tcp connection for reuse.
/// </summary>
/// </summary>
internal
string
OriginalContentEncoding
{
get
;
set
;
}
internal
string
?
OriginalContentEncoding
{
get
;
set
;
}
internal
TaskCompletionSource
<
bool
>
ReadHttp2BeforeHandlerTaskCompletionSource
;
internal
TaskCompletionSource
<
bool
>
?
ReadHttp2BeforeHandlerTaskCompletionSource
;
internal
TaskCompletionSource
<
bool
>
ReadHttp2BodyTaskCompletionSource
;
internal
TaskCompletionSource
<
bool
>
?
ReadHttp2BodyTaskCompletionSource
;
internal
MemoryStream
Http2BodyData
;
internal
MemoryStream
?
Http2BodyData
;
internal
bool
Http2IgnoreBodyFrames
;
internal
bool
Http2IgnoreBodyFrames
;
...
@@ -87,7 +87,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -87,7 +87,7 @@ namespace Titanium.Web.Proxy.Http
{
{
get
get
{
{
string
headerValue
=
Headers
.
GetHeaderValueOrNull
(
KnownHeaders
.
ContentLength
);
string
?
headerValue
=
Headers
.
GetHeaderValueOrNull
(
KnownHeaders
.
ContentLength
);
if
(
headerValue
==
null
)
if
(
headerValue
==
null
)
{
{
...
@@ -119,7 +119,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -119,7 +119,7 @@ namespace Titanium.Web.Proxy.Http
/// <summary>
/// <summary>
/// Content encoding for this request/response.
/// Content encoding for this request/response.
/// </summary>
/// </summary>
public
string
ContentEncoding
=>
Headers
.
GetHeaderValueOrNull
(
KnownHeaders
.
ContentEncoding
)?.
Trim
();
public
string
?
ContentEncoding
=>
Headers
.
GetHeaderValueOrNull
(
KnownHeaders
.
ContentEncoding
)?.
Trim
();
/// <summary>
/// <summary>
/// Encoding for this request/response.
/// Encoding for this request/response.
...
@@ -129,7 +129,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -129,7 +129,7 @@ namespace Titanium.Web.Proxy.Http
/// <summary>
/// <summary>
/// Content-type of the request/response.
/// Content-type of the request/response.
/// </summary>
/// </summary>
public
string
ContentType
public
string
?
ContentType
{
{
get
=>
Headers
.
GetHeaderValueOrNull
(
KnownHeaders
.
ContentType
);
get
=>
Headers
.
GetHeaderValueOrNull
(
KnownHeaders
.
ContentType
);
set
=>
Headers
.
SetOrAddHeaderValue
(
KnownHeaders
.
ContentType
,
value
);
set
=>
Headers
.
SetOrAddHeaderValue
(
KnownHeaders
.
ContentType
,
value
);
...
@@ -142,7 +142,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -142,7 +142,7 @@ namespace Titanium.Web.Proxy.Http
{
{
get
get
{
{
string
headerValue
=
Headers
.
GetHeaderValueOrNull
(
KnownHeaders
.
TransferEncoding
);
string
?
headerValue
=
Headers
.
GetHeaderValueOrNull
(
KnownHeaders
.
TransferEncoding
);
return
headerValue
!=
null
&&
headerValue
.
ContainsIgnoreCase
(
KnownHeaders
.
TransferEncodingChunked
);
return
headerValue
!=
null
&&
headerValue
.
ContainsIgnoreCase
(
KnownHeaders
.
TransferEncodingChunked
);
}
}
...
@@ -174,7 +174,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -174,7 +174,7 @@ namespace Titanium.Web.Proxy.Http
get
get
{
{
EnsureBodyAvailable
();
EnsureBodyAvailable
();
return
BodyInternal
;
return
BodyInternal
!
;
}
}
internal
set
internal
set
...
@@ -233,7 +233,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -233,7 +233,7 @@ namespace Titanium.Web.Proxy.Http
}
}
}
}
internal
byte
[]
CompressBodyAndUpdateContentLength
()
internal
byte
[]
?
CompressBodyAndUpdateContentLength
()
{
{
if
(!
IsBodyRead
&&
BodyInternal
==
null
)
if
(!
IsBodyRead
&&
BodyInternal
==
null
)
{
{
...
@@ -241,7 +241,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -241,7 +241,7 @@ namespace Titanium.Web.Proxy.Http
}
}
bool
isChunked
=
IsChunked
;
bool
isChunked
=
IsChunked
;
string
contentEncoding
=
ContentEncoding
;
string
?
contentEncoding
=
ContentEncoding
;
if
(
HasBody
)
if
(
HasBody
)
{
{
...
...
src/Titanium.Web.Proxy/Http/Response.cs
View file @
9df31edd
...
@@ -79,7 +79,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -79,7 +79,7 @@ namespace Titanium.Web.Proxy.Http
{
{
get
get
{
{
string
headerValue
=
Headers
.
GetHeaderValueOrNull
(
KnownHeaders
.
Connection
);
string
?
headerValue
=
Headers
.
GetHeaderValueOrNull
(
KnownHeaders
.
Connection
);
if
(
headerValue
!=
null
)
if
(
headerValue
!=
null
)
{
{
...
...
src/Titanium.Web.Proxy/Http/Responses/GenericResponse.cs
View file @
9df31edd
...
@@ -29,7 +29,7 @@ namespace Titanium.Web.Proxy.Http.Responses
...
@@ -29,7 +29,7 @@ namespace Titanium.Web.Proxy.Http.Responses
StatusDescription
=
statusDescription
;
StatusDescription
=
statusDescription
;
}
}
internal
static
string
Get
(
int
code
)
internal
static
string
?
Get
(
int
code
)
{
{
switch
(
code
)
switch
(
code
)
{
{
...
...
src/Titanium.Web.Proxy/Http2/Hpack/Decoder.cs
View file @
9df31edd
...
@@ -519,16 +519,15 @@ namespace Titanium.Web.Proxy.Http2.Hpack
...
@@ -519,16 +519,15 @@ namespace Titanium.Web.Proxy.Http2.Hpack
var
headerField
=
StaticTable
.
Get
(
index
);
var
headerField
=
StaticTable
.
Get
(
index
);
return
headerField
;
return
headerField
;
}
}
else
if
(
index
-
StaticTable
.
Length
<=
dynamicTable
.
Length
())
if
(
index
-
StaticTable
.
Length
<=
dynamicTable
.
Length
())
{
{
var
headerField
=
dynamicTable
.
GetEntry
(
index
-
StaticTable
.
Length
);
var
headerField
=
dynamicTable
.
GetEntry
(
index
-
StaticTable
.
Length
);
return
headerField
;
return
headerField
;
}
}
else
{
throw
new
IOException
(
"illegal index value ("
+
index
+
")"
);
throw
new
IOException
(
"illegal index value ("
+
index
+
")"
);
}
}
}
private
void
ReadName
(
int
index
)
private
void
ReadName
(
int
index
)
{
{
...
...
src/Titanium.Web.Proxy/Http2/Hpack/DynamicTable.cs
View file @
9df31edd
...
@@ -23,7 +23,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack
...
@@ -23,7 +23,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack
public
class
DynamicTable
public
class
DynamicTable
{
{
// a circular queue of header fields
// a circular queue of header fields
HttpHeader
[]
headerFields
;
HttpHeader
?
[]
headerFields
;
int
head
;
int
head
;
int
tail
;
int
tail
;
...
@@ -89,10 +89,10 @@ namespace Titanium.Web.Proxy.Http2.Hpack
...
@@ -89,10 +89,10 @@ namespace Titanium.Web.Proxy.Http2.Hpack
int
i
=
head
-
index
;
int
i
=
head
-
index
;
if
(
i
<
0
)
if
(
i
<
0
)
{
{
return
headerFields
[
i
+
headerFields
.
Length
];
return
headerFields
[
i
+
headerFields
.
Length
]
!
;
}
}
return
headerFields
[
i
];
return
headerFields
[
i
]
!
;
}
}
/// <summary>
/// <summary>
...
@@ -128,7 +128,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack
...
@@ -128,7 +128,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack
/// <summary>
/// <summary>
/// Remove and return the oldest header field from the dynamic table.
/// Remove and return the oldest header field from the dynamic table.
/// </summary>
/// </summary>
public
HttpHeader
Remove
()
public
HttpHeader
?
Remove
()
{
{
var
removed
=
headerFields
[
tail
];
var
removed
=
headerFields
[
tail
];
if
(
removed
==
null
)
if
(
removed
==
null
)
...
@@ -218,8 +218,8 @@ namespace Titanium.Web.Proxy.Http2.Hpack
...
@@ -218,8 +218,8 @@ namespace Titanium.Web.Proxy.Http2.Hpack
int
cursor
=
tail
;
int
cursor
=
tail
;
for
(
int
i
=
0
;
i
<
len
;
i
++)
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
{
var
entry
=
headerFields
[
cursor
++];
var
entry
=
headerFields
!
[
cursor
++];
tmp
[
i
]
=
entry
;
tmp
[
i
]
=
entry
!
;
if
(
cursor
==
headerFields
.
Length
)
if
(
cursor
==
headerFields
.
Length
)
{
{
cursor
=
0
;
cursor
=
0
;
...
...
src/Titanium.Web.Proxy/Http2/Hpack/Encoder.cs
View file @
9df31edd
...
@@ -27,7 +27,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack
...
@@ -27,7 +27,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack
private
const
int
bucketSize
=
17
;
private
const
int
bucketSize
=
17
;
// a linked hash map of header fields
// a linked hash map of header fields
private
readonly
HeaderEntry
[]
headerFields
=
new
HeaderEntry
[
bucketSize
];
private
readonly
HeaderEntry
?
[]
headerFields
=
new
HeaderEntry
[
bucketSize
];
private
readonly
HeaderEntry
head
=
new
HeaderEntry
(-
1
,
string
.
Empty
,
string
.
Empty
,
int
.
MaxValue
,
null
);
private
readonly
HeaderEntry
head
=
new
HeaderEntry
(-
1
,
string
.
Empty
,
string
.
Empty
,
int
.
MaxValue
,
null
);
private
int
size
;
private
int
size
;
...
@@ -299,7 +299,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack
...
@@ -299,7 +299,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack
/// <returns>The entry.</returns>
/// <returns>The entry.</returns>
/// <param name="name">Name.</param>
/// <param name="name">Name.</param>
/// <param name="value">Value.</param>
/// <param name="value">Value.</param>
private
HeaderEntry
getEntry
(
string
name
,
string
value
)
private
HeaderEntry
?
getEntry
(
string
name
,
string
value
)
{
{
if
(
length
()
==
0
||
name
==
null
||
value
==
null
)
if
(
length
()
==
0
||
name
==
null
||
value
==
null
)
{
{
...
@@ -400,7 +400,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack
...
@@ -400,7 +400,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack
/// <summary>
/// <summary>
/// Remove and return the oldest header field from the dynamic table.
/// Remove and return the oldest header field from the dynamic table.
/// </summary>
/// </summary>
private
HttpHeader
remove
()
private
HttpHeader
?
remove
()
{
{
if
(
size
==
0
)
if
(
size
==
0
)
{
{
...
@@ -423,7 +423,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack
...
@@ -423,7 +423,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack
}
}
else
else
{
{
prev
.
Next
=
next
;
prev
!
.
Next
=
next
;
}
}
eldest
.
Remove
();
eldest
.
Remove
();
...
@@ -500,7 +500,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack
...
@@ -500,7 +500,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack
public
HeaderEntry
After
{
get
;
set
;
}
public
HeaderEntry
After
{
get
;
set
;
}
// These fields comprise the chained list for header fields with the same hash.
// These fields comprise the chained list for header fields with the same hash.
public
HeaderEntry
Next
{
get
;
set
;
}
public
HeaderEntry
?
Next
{
get
;
set
;
}
public
int
Hash
{
get
;
}
public
int
Hash
{
get
;
}
...
@@ -514,7 +514,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack
...
@@ -514,7 +514,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack
/// <param name="value">Value.</param>
/// <param name="value">Value.</param>
/// <param name="index">Index.</param>
/// <param name="index">Index.</param>
/// <param name="next">Next.</param>
/// <param name="next">Next.</param>
public
HeaderEntry
(
int
hash
,
string
name
,
string
value
,
int
index
,
HeaderEntry
next
)
:
base
(
name
,
value
,
true
)
public
HeaderEntry
(
int
hash
,
string
name
,
string
value
,
int
index
,
HeaderEntry
?
next
)
:
base
(
name
,
value
,
true
)
{
{
Index
=
index
;
Index
=
index
;
Hash
=
hash
;
Hash
=
hash
;
...
...
src/Titanium.Web.Proxy/Http2/Hpack/HuffmanDecoder.cs
View file @
9df31edd
...
@@ -69,7 +69,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack
...
@@ -69,7 +69,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack
while
(
bits
>=
8
)
while
(
bits
>=
8
)
{
{
int
c
=
(
current
>>
(
bits
-
8
))
&
0xFF
;
int
c
=
(
current
>>
(
bits
-
8
))
&
0xFF
;
node
=
node
.
Children
[
c
];
node
=
node
.
Children
!
[
c
];
bits
-=
node
.
Bits
;
bits
-=
node
.
Bits
;
if
(
node
.
IsTerminal
)
if
(
node
.
IsTerminal
)
{
{
...
@@ -87,7 +87,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack
...
@@ -87,7 +87,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack
while
(
bits
>
0
)
while
(
bits
>
0
)
{
{
int
c
=
(
current
<<
(
8
-
bits
))
&
0xFF
;
int
c
=
(
current
<<
(
8
-
bits
))
&
0xFF
;
node
=
node
.
Children
[
c
];
node
=
node
.
Children
!
[
c
];
if
(
node
.
IsTerminal
&&
node
.
Bits
<=
bits
)
if
(
node
.
IsTerminal
&&
node
.
Bits
<=
bits
)
{
{
bits
-=
node
.
Bits
;
bits
-=
node
.
Bits
;
...
@@ -121,7 +121,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack
...
@@ -121,7 +121,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack
public
int
Bits
{
get
;
}
public
int
Bits
{
get
;
}
// internal nodes have children
// internal nodes have children
public
Node
[]
Children
{
get
;
}
public
Node
[]
?
Children
{
get
;
}
/// <summary>
/// <summary>
/// Initializes a new instance of the <see cref="HuffmanDecoder"/> class.
/// Initializes a new instance of the <see cref="HuffmanDecoder"/> class.
...
@@ -173,7 +173,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack
...
@@ -173,7 +173,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack
length
-=
8
;
length
-=
8
;
int
i
=
(
code
>>
length
)
&
0xFF
;
int
i
=
(
code
>>
length
)
&
0xFF
;
if
(
current
.
Children
[
i
]
==
null
)
if
(
current
.
Children
!
[
i
]
==
null
)
{
{
current
.
Children
[
i
]
=
new
Node
();
current
.
Children
[
i
]
=
new
Node
();
}
}
...
@@ -187,7 +187,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack
...
@@ -187,7 +187,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack
int
end
=
1
<<
shift
;
int
end
=
1
<<
shift
;
for
(
int
i
=
start
;
i
<
start
+
end
;
i
++)
for
(
int
i
=
start
;
i
<
start
+
end
;
i
++)
{
{
current
.
Children
[
i
]
=
terminal
;
current
.
Children
!
[
i
]
=
terminal
;
}
}
}
}
}
}
...
...
src/Titanium.Web.Proxy/Http2/Http2Helper.cs
View file @
9df31edd
...
@@ -59,11 +59,11 @@ namespace Titanium.Web.Proxy.Http2
...
@@ -59,11 +59,11 @@ namespace Titanium.Web.Proxy.Http2
ExceptionHandler
exceptionFunc
)
ExceptionHandler
exceptionFunc
)
{
{
int
headerTableSize
=
0
;
int
headerTableSize
=
0
;
Decoder
decoder
=
null
;
Decoder
?
decoder
=
null
;
var
frameHeader
=
new
Http2FrameHeader
();
var
frameHeader
=
new
Http2FrameHeader
();
frameHeader
.
Buffer
=
new
byte
[
9
];
frameHeader
.
Buffer
=
new
byte
[
9
];
byte
[]
buffer
=
null
;
byte
[]
?
buffer
=
null
;
while
(
true
)
while
(
true
)
{
{
var
frameHeaderBuffer
=
frameHeader
.
Buffer
;
var
frameHeaderBuffer
=
frameHeader
.
Buffer
;
...
@@ -98,8 +98,8 @@ namespace Titanium.Web.Proxy.Http2
...
@@ -98,8 +98,8 @@ namespace Titanium.Web.Proxy.Http2
bool
sendPacket
=
true
;
bool
sendPacket
=
true
;
bool
endStream
=
false
;
bool
endStream
=
false
;
SessionEventArgs
args
=
null
;
SessionEventArgs
?
args
=
null
;
RequestResponseBase
rr
=
null
;
RequestResponseBase
?
rr
=
null
;
if
(
type
==
Http2FrameType
.
Data
||
type
==
Http2FrameType
.
Headers
/* || type == Http2FrameType.PushPromise*/
)
if
(
type
==
Http2FrameType
.
Data
||
type
==
Http2FrameType
.
Headers
/* || type == Http2FrameType.PushPromise*/
)
{
{
if
(!
sessions
.
TryGetValue
(
streamId
,
out
args
))
if
(!
sessions
.
TryGetValue
(
streamId
,
out
args
))
...
@@ -156,7 +156,7 @@ namespace Titanium.Web.Proxy.Http2
...
@@ -156,7 +156,7 @@ namespace Titanium.Web.Proxy.Http2
length
-=
buffer
[
0
];
length
-=
buffer
[
0
];
}
}
data
.
Write
(
buffer
,
offset
,
length
);
data
!
.
Write
(
buffer
,
offset
,
length
);
}
}
}
}
else
if
(
type
==
Http2FrameType
.
Headers
/* || type == Http2FrameType.PushPromise*/
)
else
if
(
type
==
Http2FrameType
.
Headers
/* || type == Http2FrameType.PushPromise*/
)
...
@@ -247,9 +247,16 @@ namespace Titanium.Web.Proxy.Http2
...
@@ -247,9 +247,16 @@ namespace Titanium.Web.Proxy.Http2
if
(
rr
is
Request
request
)
if
(
rr
is
Request
request
)
{
{
string
?
method
=
headerListener
.
Method
;
string
?
path
=
headerListener
.
Path
;
if
(
method
==
null
||
path
==
null
)
{
throw
new
Exception
(
"HTTP/2 Missing method or path"
);
}
request
.
HttpVersion
=
HttpVersion
.
Version20
;
request
.
HttpVersion
=
HttpVersion
.
Version20
;
request
.
Method
=
headerListener
.
M
ethod
;
request
.
Method
=
m
ethod
;
request
.
OriginalUrl
=
headerListener
.
P
ath
;
request
.
OriginalUrl
=
p
ath
;
request
.
RequestUri
=
headerListener
.
GetUri
();
request
.
RequestUri
=
headerListener
.
GetUri
();
}
}
...
@@ -349,12 +356,12 @@ namespace Titanium.Web.Proxy.Http2
...
@@ -349,12 +356,12 @@ namespace Titanium.Web.Proxy.Http2
}
}
}
}
if
(
endStream
&&
rr
.
ReadHttp2BodyTaskCompletionSource
!=
null
)
if
(
endStream
&&
rr
!
.
ReadHttp2BodyTaskCompletionSource
!=
null
)
{
{
if
(!
rr
.
BodyAvailable
)
if
(!
rr
.
BodyAvailable
)
{
{
var
data
=
rr
.
Http2BodyData
;
var
data
=
rr
.
Http2BodyData
;
var
body
=
data
.
ToArray
();
var
body
=
data
!
.
ToArray
();
if
(
rr
.
ContentEncoding
!=
null
)
if
(
rr
.
ContentEncoding
!=
null
)
{
{
...
@@ -390,7 +397,7 @@ namespace Titanium.Web.Proxy.Http2
...
@@ -390,7 +397,7 @@ namespace Titanium.Web.Proxy.Http2
await
rr
.
Http2BeforeHandlerTask
;
await
rr
.
Http2BeforeHandlerTask
;
}
}
if
(
args
.
IsPromise
)
if
(
args
!
.
IsPromise
)
{
{
breakpoint
();
breakpoint
();
}
}
...
@@ -502,7 +509,7 @@ namespace Titanium.Web.Proxy.Http2
...
@@ -502,7 +509,7 @@ namespace Titanium.Web.Proxy.Http2
if
(
rr
.
HasBody
&&
rr
.
IsBodyRead
)
if
(
rr
.
HasBody
&&
rr
.
IsBodyRead
)
{
{
int
pos
=
0
;
int
pos
=
0
;
while
(
pos
<
body
.
Length
)
while
(
pos
<
body
!
.
Length
)
{
{
int
bodyFrameLength
=
Math
.
Min
(
buffer
.
Length
,
body
.
Length
-
pos
);
int
bodyFrameLength
=
Math
.
Min
(
buffer
.
Length
,
body
.
Length
-
pos
);
Buffer
.
BlockCopy
(
body
,
pos
,
buffer
,
0
,
bodyFrameLength
);
Buffer
.
BlockCopy
(
body
,
pos
,
buffer
,
0
,
bodyFrameLength
);
...
@@ -555,15 +562,15 @@ namespace Titanium.Web.Proxy.Http2
...
@@ -555,15 +562,15 @@ namespace Titanium.Web.Proxy.Http2
{
{
private
readonly
Action
<
string
,
string
>
addHeaderFunc
;
private
readonly
Action
<
string
,
string
>
addHeaderFunc
;
public
string
Method
{
get
;
private
set
;
}
public
string
?
Method
{
get
;
private
set
;
}
public
string
Status
{
get
;
private
set
;
}
public
string
?
Status
{
get
;
private
set
;
}
private
string
authority
;
private
string
?
authority
;
private
string
scheme
;
private
string
?
scheme
;
public
string
Path
{
get
;
private
set
;
}
public
string
?
Path
{
get
;
private
set
;
}
public
MyHeaderListener
(
Action
<
string
,
string
>
addHeaderFunc
)
public
MyHeaderListener
(
Action
<
string
,
string
>
addHeaderFunc
)
{
{
...
...
src/Titanium.Web.Proxy/Models/ExplicitProxyEndPoint.cs
View file @
9df31edd
...
@@ -33,13 +33,13 @@ namespace Titanium.Web.Proxy.Models
...
@@ -33,13 +33,13 @@ namespace Titanium.Web.Proxy.Models
/// Set the <see cref="TunnelConnectSessionEventArgs.DecryptSsl" /> property to false if this HTTP connect request
/// Set the <see cref="TunnelConnectSessionEventArgs.DecryptSsl" /> property to false if this HTTP connect request
/// shouldn't be decrypted and instead be relayed.
/// shouldn't be decrypted and instead be relayed.
/// </summary>
/// </summary>
public
event
AsyncEventHandler
<
TunnelConnectSessionEventArgs
>
BeforeTunnelConnectRequest
;
public
event
AsyncEventHandler
<
TunnelConnectSessionEventArgs
>
?
BeforeTunnelConnectRequest
;
/// <summary>
/// <summary>
/// Intercept tunnel connect response.
/// Intercept tunnel connect response.
/// Valid only for explicit endpoints.
/// Valid only for explicit endpoints.
/// </summary>
/// </summary>
public
event
AsyncEventHandler
<
TunnelConnectSessionEventArgs
>
BeforeTunnelConnectResponse
;
public
event
AsyncEventHandler
<
TunnelConnectSessionEventArgs
>
?
BeforeTunnelConnectResponse
;
internal
async
Task
InvokeBeforeTunnelConnectRequest
(
ProxyServer
proxyServer
,
internal
async
Task
InvokeBeforeTunnelConnectRequest
(
ProxyServer
proxyServer
,
TunnelConnectSessionEventArgs
connectArgs
,
ExceptionHandler
exceptionFunc
)
TunnelConnectSessionEventArgs
connectArgs
,
ExceptionHandler
exceptionFunc
)
...
...
src/Titanium.Web.Proxy/Models/HttpHeader.cs
View file @
9df31edd
using
System
;
using
System
;
using
System.Net
;
using
System.Text
;
using
System.Text
;
using
Titanium.Web.Proxy.Http
;
using
Titanium.Web.Proxy.Http
;
...
@@ -16,13 +17,21 @@ namespace Titanium.Web.Proxy.Models
...
@@ -16,13 +17,21 @@ namespace Titanium.Web.Proxy.Models
/// </summary>
/// </summary>
public
const
int
HttpHeaderOverhead
=
32
;
public
const
int
HttpHeaderOverhead
=
32
;
internal
static
readonly
Version
VersionUnknown
=
new
Version
(
0
,
0
);
#if NETSTANDARD2_1
internal
static
Version
VersionUnknown
=>
HttpVersion
.
Unknown
;
#else
internal
static
Version
VersionUnknown
{
get
;
}
=
new
Version
(
0
,
0
);
#endif
internal
static
readonly
Version
Version10
=
new
Version
(
1
,
0
)
;
internal
static
Version
Version10
=>
HttpVersion
.
Version10
;
internal
static
readonly
Version
Version11
=
new
Version
(
1
,
1
)
;
internal
static
Version
Version11
=>
HttpVersion
.
Version11
;
internal
static
readonly
Version
Version20
=
new
Version
(
2
,
0
);
#if NETSTANDARD2_1
internal
static
Version
Version20
=>
HttpVersion
.
Version20
;
#else
internal
static
Version
Version20
{
get
;
}
=
new
Version
(
2
,
0
);
#endif
internal
static
readonly
HttpHeader
ProxyConnectionKeepAlive
=
new
HttpHeader
(
"Proxy-Connection"
,
"keep-alive"
);
internal
static
readonly
HttpHeader
ProxyConnectionKeepAlive
=
new
HttpHeader
(
"Proxy-Connection"
,
"keep-alive"
);
...
...
src/Titanium.Web.Proxy/Models/ProxyAuthenticationContext.cs
View file @
9df31edd
...
@@ -30,7 +30,7 @@
...
@@ -30,7 +30,7 @@
/// <summary>
/// <summary>
/// An optional continuation token to return to the caller if set
/// An optional continuation token to return to the caller if set
/// </summary>
/// </summary>
public
string
Continuation
{
get
;
set
;
}
public
string
?
Continuation
{
get
;
set
;
}
public
static
ProxyAuthenticationContext
Failed
()
public
static
ProxyAuthenticationContext
Failed
()
{
{
...
...
src/Titanium.Web.Proxy/Models/TransparentProxyEndPoint.cs
View file @
9df31edd
...
@@ -32,7 +32,7 @@ namespace Titanium.Web.Proxy.Models
...
@@ -32,7 +32,7 @@ namespace Titanium.Web.Proxy.Models
/// <summary>
/// <summary>
/// Before Ssl authentication this event is fired.
/// Before Ssl authentication this event is fired.
/// </summary>
/// </summary>
public
event
AsyncEventHandler
<
BeforeSslAuthenticateEventArgs
>
BeforeSslAuthenticate
;
public
event
AsyncEventHandler
<
BeforeSslAuthenticateEventArgs
>
?
BeforeSslAuthenticate
;
internal
async
Task
InvokeBeforeSslAuthenticate
(
ProxyServer
proxyServer
,
internal
async
Task
InvokeBeforeSslAuthenticate
(
ProxyServer
proxyServer
,
BeforeSslAuthenticateEventArgs
connectArgs
,
ExceptionHandler
exceptionFunc
)
BeforeSslAuthenticateEventArgs
connectArgs
,
ExceptionHandler
exceptionFunc
)
...
...
src/Titanium.Web.Proxy/Network/Certificate/BCCertificateMaker.cs
View file @
9df31edd
...
@@ -48,9 +48,9 @@ namespace Titanium.Web.Proxy.Network.Certificate
...
@@ -48,9 +48,9 @@ namespace Titanium.Web.Proxy.Network.Certificate
/// <param name="isRoot">if set to <c>true</c> [is root].</param>
/// <param name="isRoot">if set to <c>true</c> [is root].</param>
/// <param name="signingCert">The signing cert.</param>
/// <param name="signingCert">The signing cert.</param>
/// <returns>X509Certificate2 instance.</returns>
/// <returns>X509Certificate2 instance.</returns>
public
X509Certificate2
MakeCertificate
(
string
sSubjectCn
,
bool
isRoot
,
X509Certificate2
signingCert
=
null
)
public
X509Certificate2
MakeCertificate
(
string
sSubjectCn
,
X509Certificate2
?
signingCert
=
null
)
{
{
return
makeCertificateInternal
(
sSubjectCn
,
isRoot
,
true
,
signingCert
);
return
makeCertificateInternal
(
sSubjectCn
,
true
,
signingCert
);
}
}
/// <summary>
/// <summary>
...
@@ -66,12 +66,12 @@ namespace Titanium.Web.Proxy.Network.Certificate
...
@@ -66,12 +66,12 @@ namespace Titanium.Web.Proxy.Network.Certificate
/// <param name="hostName">The host name</param>
/// <param name="hostName">The host name</param>
/// <returns>X509Certificate2 instance.</returns>
/// <returns>X509Certificate2 instance.</returns>
/// <exception cref="PemException">Malformed sequence in RSA private key</exception>
/// <exception cref="PemException">Malformed sequence in RSA private key</exception>
private
static
X509Certificate2
generateCertificate
(
string
hostName
,
private
static
X509Certificate2
generateCertificate
(
string
?
hostName
,
string
subjectName
,
string
subjectName
,
string
issuerName
,
DateTime
validFrom
,
string
issuerName
,
DateTime
validFrom
,
DateTime
validTo
,
int
keyStrength
=
2048
,
DateTime
validTo
,
int
keyStrength
=
2048
,
string
signatureAlgorithm
=
"SHA256WithRSA"
,
string
signatureAlgorithm
=
"SHA256WithRSA"
,
AsymmetricKeyParameter
issuerPrivateKey
=
null
)
AsymmetricKeyParameter
?
issuerPrivateKey
=
null
)
{
{
// Generating Random Numbers
// Generating Random Numbers
var
randomGenerator
=
new
CryptoApiRandomGenerator
();
var
randomGenerator
=
new
CryptoApiRandomGenerator
();
...
@@ -162,11 +162,11 @@ namespace Titanium.Web.Proxy.Network.Certificate
...
@@ -162,11 +162,11 @@ namespace Titanium.Web.Proxy.Network.Certificate
private
static
X509Certificate2
withPrivateKey
(
X509Certificate
certificate
,
AsymmetricKeyParameter
privateKey
)
private
static
X509Certificate2
withPrivateKey
(
X509Certificate
certificate
,
AsymmetricKeyParameter
privateKey
)
{
{
const
string
password
=
"password"
;
const
string
password
=
"password"
;
Pkcs12Store
store
=
null
;
Pkcs12Store
store
;
if
(
RunTime
.
IsRunningOnMono
)
if
(
RunTime
.
IsRunningOnMono
)
{
{
Pkcs12StoreBuilde
r
builder
=
new
Pkcs12StoreBuilder
();
va
r
builder
=
new
Pkcs12StoreBuilder
();
builder
.
SetUseDerEncoding
(
true
);
builder
.
SetUseDerEncoding
(
true
);
store
=
builder
.
Build
();
store
=
builder
.
Build
();
}
}
...
@@ -190,7 +190,6 @@ namespace Titanium.Web.Proxy.Network.Certificate
...
@@ -190,7 +190,6 @@ namespace Titanium.Web.Proxy.Network.Certificate
/// <summary>
/// <summary>
/// Makes the certificate internal.
/// Makes the certificate internal.
/// </summary>
/// </summary>
/// <param name="isRoot">if set to <c>true</c> [is root].</param>
/// <param name="hostName">hostname for certificate</param>
/// <param name="hostName">hostname for certificate</param>
/// <param name="subjectName">The full subject.</param>
/// <param name="subjectName">The full subject.</param>
/// <param name="validFrom">The valid from.</param>
/// <param name="validFrom">The valid from.</param>
...
@@ -201,18 +200,10 @@ namespace Titanium.Web.Proxy.Network.Certificate
...
@@ -201,18 +200,10 @@ namespace Titanium.Web.Proxy.Network.Certificate
/// You must specify a Signing Certificate if and only if you are not creating a
/// You must specify a Signing Certificate if and only if you are not creating a
/// root.
/// root.
/// </exception>
/// </exception>
private
X509Certificate2
makeCertificateInternal
(
bool
isRoot
,
private
X509Certificate2
makeCertificateInternal
(
string
hostName
,
string
subjectName
,
string
hostName
,
string
subjectName
,
DateTime
validFrom
,
DateTime
validTo
,
X509Certificate2
?
signingCertificate
)
DateTime
validFrom
,
DateTime
validTo
,
X509Certificate2
signingCertificate
)
{
{
if
(
isRoot
!=
(
null
==
signingCertificate
))
if
(
signingCertificate
==
null
)
{
throw
new
ArgumentException
(
"You must specify a Signing Certificate if and only if you are not creating a root."
,
nameof
(
signingCertificate
));
}
if
(
isRoot
)
{
{
return
generateCertificate
(
null
,
subjectName
,
subjectName
,
validFrom
,
validTo
);
return
generateCertificate
(
null
,
subjectName
,
subjectName
,
validFrom
,
validTo
);
}
}
...
@@ -226,18 +217,17 @@ namespace Titanium.Web.Proxy.Network.Certificate
...
@@ -226,18 +217,17 @@ namespace Titanium.Web.Proxy.Network.Certificate
/// Makes the certificate internal.
/// Makes the certificate internal.
/// </summary>
/// </summary>
/// <param name="subject">The s subject cn.</param>
/// <param name="subject">The s subject cn.</param>
/// <param name="isRoot">if set to <c>true</c> [is root].</param>
/// <param name="switchToMtaIfNeeded">if set to <c>true</c> [switch to MTA if needed].</param>
/// <param name="switchToMtaIfNeeded">if set to <c>true</c> [switch to MTA if needed].</param>
/// <param name="signingCert">The signing cert.</param>
/// <param name="signingCert">The signing cert.</param>
/// <param name="cancellationToken">Task cancellation token</param>
/// <param name="cancellationToken">Task cancellation token</param>
/// <returns>X509Certificate2.</returns>
/// <returns>X509Certificate2.</returns>
private
X509Certificate2
makeCertificateInternal
(
string
subject
,
bool
isRoot
,
private
X509Certificate2
makeCertificateInternal
(
string
subject
,
bool
switchToMtaIfNeeded
,
X509Certificate2
signingCert
=
null
,
bool
switchToMtaIfNeeded
,
X509Certificate2
?
signingCert
=
null
,
CancellationToken
cancellationToken
=
default
)
CancellationToken
cancellationToken
=
default
)
{
{
return
makeCertificateInternal
(
isRoot
,
subject
,
$"CN=
{
subject
}
"
,
return
makeCertificateInternal
(
subject
,
$"CN=
{
subject
}
"
,
DateTime
.
UtcNow
.
AddDays
(-
certificateGraceDays
),
DateTime
.
UtcNow
.
AddDays
(
certificateValidDays
),
DateTime
.
UtcNow
.
AddDays
(-
certificateGraceDays
),
DateTime
.
UtcNow
.
AddDays
(
certificateValidDays
),
isRoot
?
null
:
signingCert
);
signingCert
);
}
}
}
}
}
}
src/Titanium.Web.Proxy/Network/Certificate/ICertificateMaker.cs
View file @
9df31edd
...
@@ -7,6 +7,6 @@ namespace Titanium.Web.Proxy.Network.Certificate
...
@@ -7,6 +7,6 @@ namespace Titanium.Web.Proxy.Network.Certificate
/// </summary>
/// </summary>
internal
interface
ICertificateMaker
internal
interface
ICertificateMaker
{
{
X509Certificate2
MakeCertificate
(
string
sSubjectCn
,
bool
isRoot
,
X509Certificate2
signingCert
);
X509Certificate2
MakeCertificate
(
string
sSubjectCn
,
X509Certificate2
?
signingCert
);
}
}
}
}
src/Titanium.Web.Proxy/Network/Certificate/WinCertificateMaker.cs
View file @
9df31edd
...
@@ -75,18 +75,18 @@ namespace Titanium.Web.Proxy.Network.Certificate
...
@@ -75,18 +75,18 @@ namespace Titanium.Web.Proxy.Network.Certificate
/// <summary>
/// <summary>
/// Make certificate.
/// Make certificate.
/// </summary>
/// </summary>
public
X509Certificate2
MakeCertificate
(
string
sSubjectCN
,
bool
isRoot
,
X509Certificate2
signingCert
=
null
)
public
X509Certificate2
MakeCertificate
(
string
sSubjectCN
,
X509Certificate2
?
signingCert
=
null
)
{
{
return
makeCertificate
(
sSubjectCN
,
isRoot
,
true
,
signingCert
);
return
makeCertificate
(
sSubjectCN
,
true
,
signingCert
);
}
}
private
X509Certificate2
makeCertificate
(
string
sSubjectCN
,
bool
isRoot
,
private
X509Certificate2
makeCertificate
(
string
sSubjectCN
,
bool
switchToMTAIfNeeded
,
X509Certificate2
signingCert
=
null
,
bool
switchToMTAIfNeeded
,
X509Certificate2
?
signingCertificate
=
null
,
CancellationToken
cancellationToken
=
default
)
CancellationToken
cancellationToken
=
default
)
{
{
if
(
switchToMTAIfNeeded
&&
Thread
.
CurrentThread
.
GetApartmentState
()
!=
ApartmentState
.
MTA
)
if
(
switchToMTAIfNeeded
&&
Thread
.
CurrentThread
.
GetApartmentState
()
!=
ApartmentState
.
MTA
)
{
{
return
Task
.
Run
(()
=>
makeCertificate
(
sSubjectCN
,
isRoot
,
false
,
signingCert
),
return
Task
.
Run
(()
=>
makeCertificate
(
sSubjectCN
,
false
,
signingCertificate
),
cancellationToken
).
Result
;
cancellationToken
).
Result
;
}
}
...
@@ -107,37 +107,30 @@ namespace Titanium.Web.Proxy.Network.Certificate
...
@@ -107,37 +107,30 @@ namespace Titanium.Web.Proxy.Network.Certificate
var
now
=
DateTime
.
Now
;
var
now
=
DateTime
.
Now
;
var
graceTime
=
now
.
AddDays
(
graceDays
);
var
graceTime
=
now
.
AddDays
(
graceDays
);
var
certificate
=
makeCertificate
(
isRoot
,
sSubjectCN
,
fullSubject
,
keyLength
,
hashAlgo
,
graceTime
,
var
certificate
=
makeCertificate
(
sSubjectCN
,
fullSubject
,
keyLength
,
hashAlgo
,
graceTime
,
now
.
AddDays
(
validDays
),
isRoot
?
null
:
signingCert
);
now
.
AddDays
(
validDays
),
signingCertificate
);
return
certificate
;
return
certificate
;
}
}
private
X509Certificate2
makeCertificate
(
bool
isRoot
,
string
subject
,
string
fullSubject
,
private
X509Certificate2
makeCertificate
(
string
subject
,
string
fullSubject
,
int
privateKeyLength
,
string
hashAlg
,
DateTime
validFrom
,
DateTime
validTo
,
int
privateKeyLength
,
string
hashAlg
,
DateTime
validFrom
,
DateTime
validTo
,
X509Certificate2
signingCertificate
)
X509Certificate2
?
signingCertificate
)
{
{
if
(
isRoot
!=
(
null
==
signingCertificate
))
{
throw
new
ArgumentException
(
"You must specify a Signing Certificate if and only if you are not creating a root."
,
nameof
(
isRoot
));
}
var
x500CertDN
=
Activator
.
CreateInstance
(
typeX500DN
);
var
x500CertDN
=
Activator
.
CreateInstance
(
typeX500DN
);
var
typeValue
=
new
object
[]
{
fullSubject
,
0
};
var
typeValue
=
new
object
[]
{
fullSubject
,
0
};
typeX500DN
.
InvokeMember
(
"Encode"
,
BindingFlags
.
InvokeMethod
,
null
,
x500CertDN
,
typeValue
);
typeX500DN
.
InvokeMember
(
"Encode"
,
BindingFlags
.
InvokeMethod
,
null
,
x500CertDN
,
typeValue
);
var
x500RootCertDN
=
Activator
.
CreateInstance
(
typeX500DN
);
var
x500RootCertDN
=
Activator
.
CreateInstance
(
typeX500DN
);
if
(
!
isRoot
)
if
(
signingCertificate
!=
null
)
{
{
typeValue
[
0
]
=
signingCertificate
.
Subject
;
typeValue
[
0
]
=
signingCertificate
.
Subject
;
}
}
typeX500DN
.
InvokeMember
(
"Encode"
,
BindingFlags
.
InvokeMethod
,
null
,
x500RootCertDN
,
typeValue
);
typeX500DN
.
InvokeMember
(
"Encode"
,
BindingFlags
.
InvokeMethod
,
null
,
x500RootCertDN
,
typeValue
);
object
sharedPrivateKey
=
null
;
object
?
sharedPrivateKey
=
null
;
if
(
!
isRoot
)
if
(
signingCertificate
!=
null
)
{
{
sharedPrivateKey
=
this
.
sharedPrivateKey
;
sharedPrivateKey
=
this
.
sharedPrivateKey
;
}
}
...
@@ -151,11 +144,11 @@ namespace Titanium.Web.Proxy.Network.Certificate
...
@@ -151,11 +144,11 @@ namespace Titanium.Web.Proxy.Network.Certificate
typeValue
[
0
]
=
2
;
typeValue
[
0
]
=
2
;
typeX509PrivateKey
.
InvokeMember
(
"ExportPolicy"
,
BindingFlags
.
PutDispProperty
,
null
,
sharedPrivateKey
,
typeX509PrivateKey
.
InvokeMember
(
"ExportPolicy"
,
BindingFlags
.
PutDispProperty
,
null
,
sharedPrivateKey
,
typeValue
);
typeValue
);
typeValue
=
new
object
[]
{
isRoot
?
2
:
1
};
typeValue
=
new
object
[]
{
signingCertificate
==
null
?
2
:
1
};
typeX509PrivateKey
.
InvokeMember
(
"KeySpec"
,
BindingFlags
.
PutDispProperty
,
null
,
sharedPrivateKey
,
typeX509PrivateKey
.
InvokeMember
(
"KeySpec"
,
BindingFlags
.
PutDispProperty
,
null
,
sharedPrivateKey
,
typeValue
);
typeValue
);
if
(
!
isRoot
)
if
(
signingCertificate
!=
null
)
{
{
typeValue
=
new
object
[]
{
176
};
typeValue
=
new
object
[]
{
176
};
typeX509PrivateKey
.
InvokeMember
(
"KeyUsage"
,
BindingFlags
.
PutDispProperty
,
null
,
sharedPrivateKey
,
typeX509PrivateKey
.
InvokeMember
(
"KeyUsage"
,
BindingFlags
.
PutDispProperty
,
null
,
sharedPrivateKey
,
...
@@ -167,7 +160,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
...
@@ -167,7 +160,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
typeValue
);
typeValue
);
typeX509PrivateKey
.
InvokeMember
(
"Create"
,
BindingFlags
.
InvokeMethod
,
null
,
sharedPrivateKey
,
null
);
typeX509PrivateKey
.
InvokeMember
(
"Create"
,
BindingFlags
.
InvokeMethod
,
null
,
sharedPrivateKey
,
null
);
if
(
!
isRoot
)
if
(
signingCertificate
!=
null
)
{
{
this
.
sharedPrivateKey
=
sharedPrivateKey
;
this
.
sharedPrivateKey
=
sharedPrivateKey
;
}
}
...
@@ -210,7 +203,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
...
@@ -210,7 +203,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
typeRequestCert
.
InvokeMember
(
"X509Extensions"
,
BindingFlags
.
GetProperty
,
null
,
requestCert
,
null
);
typeRequestCert
.
InvokeMember
(
"X509Extensions"
,
BindingFlags
.
GetProperty
,
null
,
requestCert
,
null
);
typeValue
=
new
object
[
1
];
typeValue
=
new
object
[
1
];
if
(
!
isRoot
)
if
(
signingCertificate
!=
null
)
{
{
typeValue
[
0
]
=
kuExt
;
typeValue
[
0
]
=
kuExt
;
typeX509Extensions
.
InvokeMember
(
"Add"
,
BindingFlags
.
InvokeMethod
,
null
,
certificate
,
typeValue
);
typeX509Extensions
.
InvokeMember
(
"Add"
,
BindingFlags
.
InvokeMethod
,
null
,
certificate
,
typeValue
);
...
@@ -219,7 +212,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
...
@@ -219,7 +212,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
typeValue
[
0
]
=
ekuExt
;
typeValue
[
0
]
=
ekuExt
;
typeX509Extensions
.
InvokeMember
(
"Add"
,
BindingFlags
.
InvokeMethod
,
null
,
certificate
,
typeValue
);
typeX509Extensions
.
InvokeMember
(
"Add"
,
BindingFlags
.
InvokeMethod
,
null
,
certificate
,
typeValue
);
if
(
!
isRoot
)
if
(
signingCertificate
!=
null
)
{
{
// add alternative names
// add alternative names
// https://forums.iis.net/t/1180823.aspx
// https://forums.iis.net/t/1180823.aspx
...
@@ -244,7 +237,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
...
@@ -244,7 +237,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
typeX509Extensions
.
InvokeMember
(
"Add"
,
BindingFlags
.
InvokeMethod
,
null
,
certificate
,
typeValue
);
typeX509Extensions
.
InvokeMember
(
"Add"
,
BindingFlags
.
InvokeMethod
,
null
,
certificate
,
typeValue
);
}
}
if
(
!
isRoot
)
if
(
signingCertificate
!=
null
)
{
{
var
signerCertificate
=
Activator
.
CreateInstance
(
typeSignerCertificate
);
var
signerCertificate
=
Activator
.
CreateInstance
(
typeSignerCertificate
);
...
@@ -281,7 +274,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
...
@@ -281,7 +274,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
typeX509Enrollment
.
InvokeMember
(
"InitializeFromRequest"
,
BindingFlags
.
InvokeMethod
,
null
,
x509Enrollment
,
typeX509Enrollment
.
InvokeMember
(
"InitializeFromRequest"
,
BindingFlags
.
InvokeMethod
,
null
,
x509Enrollment
,
typeValue
);
typeValue
);
if
(
isRoot
)
if
(
signingCertificate
==
null
)
{
{
typeValue
[
0
]
=
fullSubject
;
typeValue
[
0
]
=
fullSubject
;
typeX509Enrollment
.
InvokeMember
(
"CertificateFriendlyName"
,
BindingFlags
.
PutDispProperty
,
null
,
typeX509Enrollment
.
InvokeMember
(
"CertificateFriendlyName"
,
BindingFlags
.
PutDispProperty
,
null
,
...
@@ -296,7 +289,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
...
@@ -296,7 +289,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
typeX509Enrollment
.
InvokeMember
(
"InstallResponse"
,
BindingFlags
.
InvokeMethod
,
null
,
x509Enrollment
,
typeX509Enrollment
.
InvokeMember
(
"InstallResponse"
,
BindingFlags
.
InvokeMethod
,
null
,
x509Enrollment
,
typeValue
);
typeValue
);
typeValue
=
new
object
[]
{
null
,
0
,
1
};
typeValue
=
new
object
[]
{
null
!
,
0
,
1
};
string
empty
=
(
string
)
typeX509Enrollment
.
InvokeMember
(
"CreatePFX"
,
BindingFlags
.
InvokeMethod
,
null
,
string
empty
=
(
string
)
typeX509Enrollment
.
InvokeMember
(
"CreatePFX"
,
BindingFlags
.
InvokeMethod
,
null
,
x509Enrollment
,
typeValue
);
x509Enrollment
,
typeValue
);
...
...
src/Titanium.Web.Proxy/Network/CertificateManager.cs
View file @
9df31edd
...
@@ -66,7 +66,7 @@ namespace Titanium.Web.Proxy.Network
...
@@ -66,7 +66,7 @@ namespace Titanium.Web.Proxy.Network
private
string
issuer
;
private
string
issuer
;
private
X509Certificate2
rootCertificate
;
private
X509Certificate2
?
rootCertificate
;
private
string
rootCertificateName
;
private
string
rootCertificateName
;
...
@@ -87,7 +87,7 @@ namespace Titanium.Web.Proxy.Network
...
@@ -87,7 +87,7 @@ namespace Titanium.Web.Proxy.Network
/// prompting for UAC if required?
/// prompting for UAC if required?
/// </param>
/// </param>
/// <param name="exceptionFunc"></param>
/// <param name="exceptionFunc"></param>
internal
CertificateManager
(
string
rootCertificateName
,
string
rootCertificateIssuerName
,
internal
CertificateManager
(
string
?
rootCertificateName
,
string
?
rootCertificateIssuerName
,
bool
userTrustRootCertificate
,
bool
machineTrustRootCertificate
,
bool
trustRootCertificateAsAdmin
,
bool
userTrustRootCertificate
,
bool
machineTrustRootCertificate
,
bool
trustRootCertificateAsAdmin
,
ExceptionHandler
exceptionFunc
)
ExceptionHandler
exceptionFunc
)
{
{
...
@@ -156,7 +156,7 @@ namespace Titanium.Web.Proxy.Network
...
@@ -156,7 +156,7 @@ namespace Titanium.Web.Proxy.Network
if
(
value
!=
engine
)
if
(
value
!=
engine
)
{
{
certEngine
=
null
;
certEngine
=
null
!
;
engine
=
value
;
engine
=
value
;
}
}
...
@@ -210,7 +210,7 @@ namespace Titanium.Web.Proxy.Network
...
@@ -210,7 +210,7 @@ namespace Titanium.Web.Proxy.Network
/// <summary>
/// <summary>
/// The root certificate.
/// The root certificate.
/// </summary>
/// </summary>
public
X509Certificate2
RootCertificate
public
X509Certificate2
?
RootCertificate
{
{
get
=>
rootCertificate
;
get
=>
rootCertificate
;
set
set
...
@@ -268,6 +268,11 @@ namespace Titanium.Web.Proxy.Network
...
@@ -268,6 +268,11 @@ namespace Titanium.Web.Proxy.Network
/// <returns></returns>
/// <returns></returns>
private
bool
rootCertificateInstalled
(
StoreLocation
storeLocation
)
private
bool
rootCertificateInstalled
(
StoreLocation
storeLocation
)
{
{
if
(
RootCertificate
==
null
)
{
throw
new
Exception
(
"Root certificate is null."
);
}
string
value
=
$"
{
RootCertificate
.
Issuer
}
"
;
string
value
=
$"
{
RootCertificate
.
Issuer
}
"
;
return
findCertificates
(
StoreName
.
Root
,
storeLocation
,
value
).
Count
>
0
return
findCertificates
(
StoreName
.
Root
,
storeLocation
,
value
).
Count
>
0
&&
(
CertificateEngine
!=
CertificateEngine
.
DefaultWindows
&&
(
CertificateEngine
!=
CertificateEngine
.
DefaultWindows
...
@@ -298,8 +303,7 @@ namespace Titanium.Web.Proxy.Network
...
@@ -298,8 +303,7 @@ namespace Titanium.Web.Proxy.Network
{
{
if
(
RootCertificate
==
null
)
if
(
RootCertificate
==
null
)
{
{
ExceptionFunc
(
new
Exception
(
"Could not install certificate as it is null or empty."
));
throw
new
Exception
(
"Could not install certificate as it is null or empty."
);
return
;
}
}
var
x509Store
=
new
X509Store
(
storeName
,
storeLocation
);
var
x509Store
=
new
X509Store
(
storeName
,
storeLocation
);
...
@@ -361,12 +365,19 @@ namespace Titanium.Web.Proxy.Network
...
@@ -361,12 +365,19 @@ namespace Titanium.Web.Proxy.Network
private
X509Certificate2
makeCertificate
(
string
certificateName
,
bool
isRootCertificate
)
private
X509Certificate2
makeCertificate
(
string
certificateName
,
bool
isRootCertificate
)
{
{
//if (isRoot != (null == signingCertificate))
//{
// throw new ArgumentException(
// "You must specify a Signing Certificate if and only if you are not creating a root.",
// nameof(signingCertificate));
//}
if
(!
isRootCertificate
&&
RootCertificate
==
null
)
if
(!
isRootCertificate
&&
RootCertificate
==
null
)
{
{
CreateRootCertificate
();
CreateRootCertificate
();
}
}
var
certificate
=
certEngine
.
MakeCertificate
(
certificateName
,
isRootCertificate
,
RootCertificate
);
var
certificate
=
certEngine
.
MakeCertificate
(
certificateName
,
isRootCertificate
?
null
:
RootCertificate
);
if
(
CertificateEngine
==
CertificateEngine
.
DefaultWindows
)
if
(
CertificateEngine
==
CertificateEngine
.
DefaultWindows
)
{
{
...
@@ -382,9 +393,9 @@ namespace Titanium.Web.Proxy.Network
...
@@ -382,9 +393,9 @@ namespace Titanium.Web.Proxy.Network
/// <param name="certificateName"></param>
/// <param name="certificateName"></param>
/// <param name="isRootCertificate"></param>
/// <param name="isRootCertificate"></param>
/// <returns></returns>
/// <returns></returns>
internal
X509Certificate2
CreateCertificate
(
string
certificateName
,
bool
isRootCertificate
)
internal
X509Certificate2
?
CreateCertificate
(
string
certificateName
,
bool
isRootCertificate
)
{
{
X509Certificate2
certificate
;
X509Certificate2
?
certificate
;
try
try
{
{
if
(!
isRootCertificate
&&
SaveFakeCertificates
)
if
(!
isRootCertificate
&&
SaveFakeCertificates
)
...
@@ -589,7 +600,7 @@ namespace Titanium.Web.Proxy.Network
...
@@ -589,7 +600,7 @@ namespace Titanium.Web.Proxy.Network
/// Loads root certificate from current executing assembly location with expected name rootCert.pfx.
/// Loads root certificate from current executing assembly location with expected name rootCert.pfx.
/// </summary>
/// </summary>
/// <returns></returns>
/// <returns></returns>
public
X509Certificate2
LoadRootCertificate
()
public
X509Certificate2
?
LoadRootCertificate
()
{
{
try
try
{
{
...
@@ -671,7 +682,7 @@ namespace Titanium.Web.Proxy.Network
...
@@ -671,7 +682,7 @@ namespace Titanium.Web.Proxy.Network
installCertificate
(
StoreName
.
My
,
StoreLocation
.
CurrentUser
);
installCertificate
(
StoreName
.
My
,
StoreLocation
.
CurrentUser
);
string
pfxFileName
=
Path
.
GetTempFileName
();
string
pfxFileName
=
Path
.
GetTempFileName
();
File
.
WriteAllBytes
(
pfxFileName
,
RootCertificate
.
Export
(
X509ContentType
.
Pkcs12
,
PfxPassword
));
File
.
WriteAllBytes
(
pfxFileName
,
RootCertificate
!
.
Export
(
X509ContentType
.
Pkcs12
,
PfxPassword
));
// currentUser\Root, currentMachine\Personal & currentMachine\Root
// currentUser\Root, currentMachine\Personal & currentMachine\Root
var
info
=
new
ProcessStartInfo
var
info
=
new
ProcessStartInfo
...
...
src/Titanium.Web.Proxy/Network/DefaultCertificateDiskCache.cs
View file @
9df31edd
...
@@ -11,10 +11,10 @@ namespace Titanium.Web.Proxy.Network
...
@@ -11,10 +11,10 @@ namespace Titanium.Web.Proxy.Network
private
const
string
defaultCertificateDirectoryName
=
"crts"
;
private
const
string
defaultCertificateDirectoryName
=
"crts"
;
private
const
string
defaultCertificateFileExtension
=
".pfx"
;
private
const
string
defaultCertificateFileExtension
=
".pfx"
;
private
const
string
defaultRootCertificateFileName
=
"rootCert"
+
defaultCertificateFileExtension
;
private
const
string
defaultRootCertificateFileName
=
"rootCert"
+
defaultCertificateFileExtension
;
private
string
rootCertificatePath
;
private
string
?
rootCertificatePath
;
private
string
certificatePath
;
private
string
?
certificatePath
;
public
X509Certificate2
LoadRootCertificate
(
string
pathOrName
,
string
password
,
X509KeyStorageFlags
storageFlags
)
public
X509Certificate2
?
LoadRootCertificate
(
string
pathOrName
,
string
password
,
X509KeyStorageFlags
storageFlags
)
{
{
string
path
=
getRootCertificatePath
(
pathOrName
);
string
path
=
getRootCertificatePath
(
pathOrName
);
return
loadCertificate
(
path
,
password
,
storageFlags
);
return
loadCertificate
(
path
,
password
,
storageFlags
);
...
@@ -28,7 +28,7 @@ namespace Titanium.Web.Proxy.Network
...
@@ -28,7 +28,7 @@ namespace Titanium.Web.Proxy.Network
}
}
/// <inheritdoc />
/// <inheritdoc />
public
X509Certificate2
LoadCertificate
(
string
subjectName
,
X509KeyStorageFlags
storageFlags
)
public
X509Certificate2
?
LoadCertificate
(
string
subjectName
,
X509KeyStorageFlags
storageFlags
)
{
{
string
path
=
Path
.
Combine
(
getCertificatePath
(),
subjectName
+
defaultCertificateFileExtension
);
string
path
=
Path
.
Combine
(
getCertificatePath
(),
subjectName
+
defaultCertificateFileExtension
);
return
loadCertificate
(
path
,
string
.
Empty
,
storageFlags
);
return
loadCertificate
(
path
,
string
.
Empty
,
storageFlags
);
...
@@ -56,7 +56,7 @@ namespace Titanium.Web.Proxy.Network
...
@@ -56,7 +56,7 @@ namespace Titanium.Web.Proxy.Network
certificatePath
=
null
;
certificatePath
=
null
;
}
}
private
X509Certificate2
loadCertificate
(
string
path
,
string
password
,
X509KeyStorageFlags
storageFlags
)
private
X509Certificate2
?
loadCertificate
(
string
path
,
string
password
,
X509KeyStorageFlags
storageFlags
)
{
{
byte
[]
exported
;
byte
[]
exported
;
...
...
src/Titanium.Web.Proxy/Network/RetryPolicy.cs
View file @
9df31edd
...
@@ -9,7 +9,7 @@ namespace Titanium.Web.Proxy.Network
...
@@ -9,7 +9,7 @@ namespace Titanium.Web.Proxy.Network
private
readonly
int
retries
;
private
readonly
int
retries
;
private
readonly
TcpConnectionFactory
tcpConnectionFactory
;
private
readonly
TcpConnectionFactory
tcpConnectionFactory
;
private
TcpServerConnection
currentConnection
;
private
TcpServerConnection
?
currentConnection
;
internal
RetryPolicy
(
int
retries
,
TcpConnectionFactory
tcpConnectionFactory
)
internal
RetryPolicy
(
int
retries
,
TcpConnectionFactory
tcpConnectionFactory
)
{
{
...
@@ -29,7 +29,7 @@ namespace Titanium.Web.Proxy.Network
...
@@ -29,7 +29,7 @@ namespace Titanium.Web.Proxy.Network
{
{
currentConnection
=
initialConnection
;
currentConnection
=
initialConnection
;
bool
@continue
=
true
;
bool
@continue
=
true
;
Exception
exception
=
null
;
Exception
?
exception
=
null
;
var
attempts
=
retries
;
var
attempts
=
retries
;
...
@@ -80,11 +80,14 @@ namespace Titanium.Web.Proxy.Network
...
@@ -80,11 +80,14 @@ namespace Titanium.Web.Proxy.Network
internal
class
RetryResult
internal
class
RetryResult
{
{
internal
bool
IsSuccess
=>
Exception
==
null
;
internal
bool
IsSuccess
=>
Exception
==
null
;
internal
TcpServerConnection
LatestConnection
{
get
;
}
internal
TcpServerConnection
LatestConnection
{
get
;
}
internal
Exception
Exception
{
get
;
}
internal
Exception
?
Exception
{
get
;
}
internal
bool
Continue
{
get
;
}
internal
bool
Continue
{
get
;
}
internal
RetryResult
(
TcpServerConnection
lastConnection
,
Exception
exception
,
bool
@continue
)
internal
RetryResult
(
TcpServerConnection
lastConnection
,
Exception
?
exception
,
bool
@continue
)
{
{
LatestConnection
=
lastConnection
;
LatestConnection
=
lastConnection
;
Exception
=
exception
;
Exception
=
exception
;
...
...
src/Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs
View file @
9df31edd
...
@@ -47,7 +47,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
...
@@ -47,7 +47,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
internal
ProxyServer
Server
{
get
;
}
internal
ProxyServer
Server
{
get
;
}
internal
string
GetConnectionCacheKey
(
string
remoteHostName
,
int
remotePort
,
internal
string
GetConnectionCacheKey
(
string
remoteHostName
,
int
remotePort
,
bool
isHttps
,
List
<
SslApplicationProtocol
>
applicationProtocols
,
bool
isHttps
,
List
<
SslApplicationProtocol
>
?
applicationProtocols
,
IPEndPoint
upStreamEndPoint
,
ExternalProxy
externalProxy
)
IPEndPoint
upStreamEndPoint
,
ExternalProxy
externalProxy
)
{
{
// http version is ignored since its an application level decision b/w HTTP 1.0/1.1
// http version is ignored since its an application level decision b/w HTTP 1.0/1.1
...
@@ -83,13 +83,13 @@ namespace Titanium.Web.Proxy.Network.Tcp
...
@@ -83,13 +83,13 @@ namespace Titanium.Web.Proxy.Network.Tcp
internal
async
Task
<
string
>
GetConnectionCacheKey
(
ProxyServer
server
,
SessionEventArgsBase
session
,
internal
async
Task
<
string
>
GetConnectionCacheKey
(
ProxyServer
server
,
SessionEventArgsBase
session
,
SslApplicationProtocol
applicationProtocol
)
SslApplicationProtocol
applicationProtocol
)
{
{
List
<
SslApplicationProtocol
>
applicationProtocols
=
null
;
List
<
SslApplicationProtocol
>
?
applicationProtocols
=
null
;
if
(
applicationProtocol
!=
default
)
if
(
applicationProtocol
!=
default
)
{
{
applicationProtocols
=
new
List
<
SslApplicationProtocol
>
{
applicationProtocol
};
applicationProtocols
=
new
List
<
SslApplicationProtocol
>
{
applicationProtocol
};
}
}
ExternalProxy
customUpStreamProxy
=
null
;
ExternalProxy
?
customUpStreamProxy
=
null
;
bool
isHttps
=
session
.
IsHttps
;
bool
isHttps
=
session
.
IsHttps
;
if
(
server
.
GetCustomUpStreamProxyFunc
!=
null
)
if
(
server
.
GetCustomUpStreamProxyFunc
!=
null
)
...
@@ -121,7 +121,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
...
@@ -121,7 +121,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
internal
Task
<
TcpServerConnection
>
GetServerConnection
(
ProxyServer
server
,
SessionEventArgsBase
session
,
bool
isConnect
,
internal
Task
<
TcpServerConnection
>
GetServerConnection
(
ProxyServer
server
,
SessionEventArgsBase
session
,
bool
isConnect
,
SslApplicationProtocol
applicationProtocol
,
bool
noCache
,
CancellationToken
cancellationToken
)
SslApplicationProtocol
applicationProtocol
,
bool
noCache
,
CancellationToken
cancellationToken
)
{
{
List
<
SslApplicationProtocol
>
applicationProtocols
=
null
;
List
<
SslApplicationProtocol
>
?
applicationProtocols
=
null
;
if
(
applicationProtocol
!=
default
)
if
(
applicationProtocol
!=
default
)
{
{
applicationProtocols
=
new
List
<
SslApplicationProtocol
>
{
applicationProtocol
};
applicationProtocols
=
new
List
<
SslApplicationProtocol
>
{
applicationProtocol
};
...
@@ -141,9 +141,9 @@ namespace Titanium.Web.Proxy.Network.Tcp
...
@@ -141,9 +141,9 @@ namespace Titanium.Web.Proxy.Network.Tcp
/// <param name="cancellationToken">The cancellation token for this async task.</param>
/// <param name="cancellationToken">The cancellation token for this async task.</param>
/// <returns></returns>
/// <returns></returns>
internal
async
Task
<
TcpServerConnection
>
GetServerConnection
(
ProxyServer
server
,
SessionEventArgsBase
session
,
bool
isConnect
,
internal
async
Task
<
TcpServerConnection
>
GetServerConnection
(
ProxyServer
server
,
SessionEventArgsBase
session
,
bool
isConnect
,
List
<
SslApplicationProtocol
>
applicationProtocols
,
bool
noCache
,
CancellationToken
cancellationToken
)
List
<
SslApplicationProtocol
>
?
applicationProtocols
,
bool
noCache
,
CancellationToken
cancellationToken
)
{
{
ExternalProxy
customUpStreamProxy
=
null
;
ExternalProxy
?
customUpStreamProxy
=
null
;
bool
isHttps
=
session
.
IsHttps
;
bool
isHttps
=
session
.
IsHttps
;
if
(
server
.
GetCustomUpStreamProxyFunc
!=
null
)
if
(
server
.
GetCustomUpStreamProxyFunc
!=
null
)
...
@@ -179,11 +179,11 @@ namespace Titanium.Web.Proxy.Network.Tcp
...
@@ -179,11 +179,11 @@ namespace Titanium.Web.Proxy.Network.Tcp
/// <param name="cancellationToken">The cancellation token for this async task.</param>
/// <param name="cancellationToken">The cancellation token for this async task.</param>
/// <returns></returns>
/// <returns></returns>
internal
async
Task
<
TcpServerConnection
>
GetServerConnection
(
string
remoteHostName
,
int
remotePort
,
internal
async
Task
<
TcpServerConnection
>
GetServerConnection
(
string
remoteHostName
,
int
remotePort
,
Version
httpVersion
,
bool
isHttps
,
List
<
SslApplicationProtocol
>
applicationProtocols
,
bool
isConnect
,
Version
httpVersion
,
bool
isHttps
,
List
<
SslApplicationProtocol
>
?
applicationProtocols
,
bool
isConnect
,
ProxyServer
proxyServer
,
SessionEventArgsBase
session
,
IPEndPoint
upStreamEndPoint
,
ExternalProxy
externalProxy
,
ProxyServer
proxyServer
,
SessionEventArgsBase
?
session
,
IPEndPoint
upStreamEndPoint
,
ExternalProxy
externalProxy
,
bool
noCache
,
CancellationToken
cancellationToken
)
bool
noCache
,
CancellationToken
cancellationToken
)
{
{
var
sslProtocol
=
session
.
ProxyClient
.
Connection
.
SslProtocol
;
var
sslProtocol
=
session
?.
ProxyClient
.
Connection
.
SslProtocol
??
SslProtocols
.
None
;
var
cacheKey
=
GetConnectionCacheKey
(
remoteHostName
,
remotePort
,
var
cacheKey
=
GetConnectionCacheKey
(
remoteHostName
,
remotePort
,
isHttps
,
applicationProtocols
,
upStreamEndPoint
,
externalProxy
);
isHttps
,
applicationProtocols
,
upStreamEndPoint
,
externalProxy
);
...
@@ -269,8 +269,8 @@ namespace Titanium.Web.Proxy.Network.Tcp
...
@@ -269,8 +269,8 @@ namespace Titanium.Web.Proxy.Network.Tcp
}
}
}
}
TcpClient
tcpClient
=
null
;
TcpClient
?
tcpClient
=
null
;
CustomBufferedStream
stream
=
null
;
CustomBufferedStream
?
stream
=
null
;
SslApplicationProtocol
negotiatedApplicationProtocol
=
default
;
SslApplicationProtocol
negotiatedApplicationProtocol
=
default
;
...
@@ -280,8 +280,8 @@ namespace Titanium.Web.Proxy.Network.Tcp
...
@@ -280,8 +280,8 @@ namespace Titanium.Web.Proxy.Network.Tcp
retry
:
retry
:
try
try
{
{
var
hostname
=
useUpstreamProxy
?
externalProxy
.
HostName
:
remoteHostName
;
var
hostname
=
useUpstreamProxy
?
externalProxy
!
.
HostName
:
remoteHostName
;
var
port
=
useUpstreamProxy
?
externalProxy
.
Port
:
remotePort
;
var
port
=
useUpstreamProxy
?
externalProxy
!
.
Port
:
remotePort
;
var
ipAddresses
=
await
Dns
.
GetHostAddressesAsync
(
hostname
);
var
ipAddresses
=
await
Dns
.
GetHostAddressesAsync
(
hostname
);
if
(
ipAddresses
==
null
||
ipAddresses
.
Length
==
0
)
if
(
ipAddresses
==
null
||
ipAddresses
.
Length
==
0
)
...
@@ -341,9 +341,9 @@ namespace Titanium.Web.Proxy.Network.Tcp
...
@@ -341,9 +341,9 @@ namespace Titanium.Web.Proxy.Network.Tcp
session
.
TimeLine
[
"Connection Established"
]
=
DateTime
.
Now
;
session
.
TimeLine
[
"Connection Established"
]
=
DateTime
.
Now
;
}
}
await
proxyServer
.
InvokeConnectionCreateEvent
(
tcpClient
,
false
);
await
proxyServer
.
InvokeConnectionCreateEvent
(
tcpClient
!
,
false
);
stream
=
new
CustomBufferedStream
(
tcpClient
.
GetStream
(),
proxyServer
.
BufferPool
);
stream
=
new
CustomBufferedStream
(
tcpClient
!
.
GetStream
(),
proxyServer
.
BufferPool
);
if
(
useUpstreamProxy
&&
(
isConnect
||
isHttps
))
if
(
useUpstreamProxy
&&
(
isConnect
||
isHttps
))
{
{
...
@@ -356,7 +356,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
...
@@ -356,7 +356,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
connectRequest
.
Headers
.
AddHeader
(
KnownHeaders
.
Connection
,
KnownHeaders
.
ConnectionKeepAlive
);
connectRequest
.
Headers
.
AddHeader
(
KnownHeaders
.
Connection
,
KnownHeaders
.
ConnectionKeepAlive
);
if
(!
string
.
IsNullOrEmpty
(
externalProxy
.
UserName
)
&&
externalProxy
.
Password
!=
null
)
if
(!
string
.
IsNullOrEmpty
(
externalProxy
!
.
UserName
)
&&
externalProxy
.
Password
!=
null
)
{
{
connectRequest
.
Headers
.
AddHeader
(
HttpHeader
.
ProxyConnectionKeepAlive
);
connectRequest
.
Headers
.
AddHeader
(
HttpHeader
.
ProxyConnectionKeepAlive
);
connectRequest
.
Headers
.
AddHeader
(
connectRequest
.
Headers
.
AddHeader
(
...
@@ -388,7 +388,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
...
@@ -388,7 +388,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
{
{
ApplicationProtocols
=
applicationProtocols
,
ApplicationProtocols
=
applicationProtocols
,
TargetHost
=
remoteHostName
,
TargetHost
=
remoteHostName
,
ClientCertificates
=
null
,
ClientCertificates
=
null
!
,
EnabledSslProtocols
=
enabledSslProtocols
,
EnabledSslProtocols
=
enabledSslProtocols
,
CertificateRevocationCheckMode
=
proxyServer
.
CheckCertificateRevocation
CertificateRevocationCheckMode
=
proxyServer
.
CheckCertificateRevocation
};
};
...
@@ -440,11 +440,6 @@ namespace Titanium.Web.Proxy.Network.Tcp
...
@@ -440,11 +440,6 @@ namespace Titanium.Web.Proxy.Network.Tcp
/// <param name="close">Should we just close the connection instead of reusing?</param>
/// <param name="close">Should we just close the connection instead of reusing?</param>
internal
async
Task
Release
(
TcpServerConnection
connection
,
bool
close
=
false
)
internal
async
Task
Release
(
TcpServerConnection
connection
,
bool
close
=
false
)
{
{
if
(
connection
==
null
)
{
return
;
}
if
(
close
||
connection
.
IsWinAuthenticated
||
!
Server
.
EnableConnectionPool
||
connection
.
IsClosed
)
if
(
close
||
connection
.
IsWinAuthenticated
||
!
Server
.
EnableConnectionPool
||
connection
.
IsClosed
)
{
{
disposalBag
.
Add
(
connection
);
disposalBag
.
Add
(
connection
);
...
@@ -491,18 +486,21 @@ namespace Titanium.Web.Proxy.Network.Tcp
...
@@ -491,18 +486,21 @@ namespace Titanium.Web.Proxy.Network.Tcp
{
{
if
(
connectionCreateTask
!=
null
)
if
(
connectionCreateTask
!=
null
)
{
{
TcpServerConnection
connection
=
null
;
TcpServerConnection
?
connection
=
null
;
try
try
{
{
connection
=
await
connectionCreateTask
;
connection
=
await
connectionCreateTask
;
}
}
catch
{
}
catch
{
}
finally
finally
{
if
(
connection
!=
null
)
{
{
await
Release
(
connection
,
closeServerConnection
);
await
Release
(
connection
,
closeServerConnection
);
}
}
}
}
}
}
}
private
async
Task
clearOutdatedConnections
()
private
async
Task
clearOutdatedConnections
()
{
{
...
...
src/Titanium.Web.Proxy/Network/Tcp/TcpServerConnection.cs
View file @
9df31edd
...
@@ -29,7 +29,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
...
@@ -29,7 +29,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
internal
bool
IsClosed
=>
Stream
.
IsClosed
;
internal
bool
IsClosed
=>
Stream
.
IsClosed
;
internal
ExternalProxy
UpStreamProxy
{
get
;
set
;
}
internal
ExternalProxy
?
UpStreamProxy
{
get
;
set
;
}
internal
string
HostName
{
get
;
set
;
}
internal
string
HostName
{
get
;
set
;
}
...
@@ -44,7 +44,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
...
@@ -44,7 +44,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
/// <summary>
/// <summary>
/// Local NIC via connection is made
/// Local NIC via connection is made
/// </summary>
/// </summary>
internal
IPEndPoint
UpStreamEndPoint
{
get
;
set
;
}
internal
IPEndPoint
?
UpStreamEndPoint
{
get
;
set
;
}
/// <summary>
/// <summary>
/// Http version
/// Http version
...
@@ -61,7 +61,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
...
@@ -61,7 +61,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
/// <summary>
/// <summary>
/// Used to write lines to server
/// Used to write lines to server
/// </summary>
/// </summary>
internal
HttpRequestWriter
StreamWriter
{
get
;
set
;
}
internal
HttpRequestWriter
?
StreamWriter
{
get
;
set
;
}
/// <summary>
/// <summary>
/// Server stream
/// Server stream
...
...
src/Titanium.Web.Proxy/Network/WinAuth/Security/Common.cs
View file @
9df31edd
...
@@ -224,9 +224,9 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
...
@@ -224,9 +224,9 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
}
}
}
}
internal
byte
[]
GetBytes
()
internal
byte
[]
?
GetBytes
()
{
{
byte
[]
buffer
=
null
;
byte
[]
?
buffer
=
null
;
if
(
pBuffers
==
IntPtr
.
Zero
)
if
(
pBuffers
==
IntPtr
.
Zero
)
{
{
...
...
src/Titanium.Web.Proxy/Network/WinAuth/Security/WinAuthEndPoint.cs
View file @
9df31edd
...
@@ -24,9 +24,9 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
...
@@ -24,9 +24,9 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
/// <param name="authScheme"></param>
/// <param name="authScheme"></param>
/// <param name="data"></param>
/// <param name="data"></param>
/// <returns></returns>
/// <returns></returns>
internal
static
byte
[]
AcquireInitialSecurityToken
(
string
hostname
,
string
authScheme
,
InternalDataStore
data
)
internal
static
byte
[]
?
AcquireInitialSecurityToken
(
string
hostname
,
string
authScheme
,
InternalDataStore
data
)
{
{
byte
[]
token
;
byte
[]
?
token
;
// null for initial call
// null for initial call
var
serverToken
=
new
SecurityBufferDesciption
();
var
serverToken
=
new
SecurityBufferDesciption
();
...
@@ -91,9 +91,9 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
...
@@ -91,9 +91,9 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
/// <param name="serverChallenge"></param>
/// <param name="serverChallenge"></param>
/// <param name="data"></param>
/// <param name="data"></param>
/// <returns></returns>
/// <returns></returns>
internal
static
byte
[]
AcquireFinalSecurityToken
(
string
hostname
,
byte
[]
serverChallenge
,
InternalDataStore
data
)
internal
static
byte
[]
?
AcquireFinalSecurityToken
(
string
hostname
,
byte
[]
serverChallenge
,
InternalDataStore
data
)
{
{
byte
[]
token
;
byte
[]
?
token
;
// user server challenge
// user server challenge
var
serverToken
=
new
SecurityBufferDesciption
(
serverChallenge
);
var
serverToken
=
new
SecurityBufferDesciption
(
serverChallenge
);
...
@@ -145,19 +145,19 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
...
@@ -145,19 +145,19 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
/// <returns></returns>
/// <returns></returns>
internal
static
bool
ValidateWinAuthState
(
InternalDataStore
data
,
State
.
WinAuthState
expectedAuthState
)
internal
static
bool
ValidateWinAuthState
(
InternalDataStore
data
,
State
.
WinAuthState
expectedAuthState
)
{
{
bool
stateExists
=
data
.
TryGetValueAs
(
authStateKey
,
out
State
state
);
bool
stateExists
=
data
.
TryGetValueAs
(
authStateKey
,
out
State
?
state
);
if
(
expectedAuthState
==
State
.
WinAuthState
.
UNAUTHORIZED
)
if
(
expectedAuthState
==
State
.
WinAuthState
.
UNAUTHORIZED
)
{
{
return
!
stateExists
||
return
!
stateExists
||
state
.
AuthState
==
State
.
WinAuthState
.
UNAUTHORIZED
||
state
!
.
AuthState
==
State
.
WinAuthState
.
UNAUTHORIZED
||
state
.
AuthState
==
State
.
WinAuthState
.
AUTHORIZED
;
// Server may require re-authentication on an open connection
state
.
AuthState
==
State
.
WinAuthState
.
AUTHORIZED
;
// Server may require re-authentication on an open connection
}
}
if
(
expectedAuthState
==
State
.
WinAuthState
.
INITIAL_TOKEN
)
if
(
expectedAuthState
==
State
.
WinAuthState
.
INITIAL_TOKEN
)
{
{
return
stateExists
&&
return
stateExists
&&
(
state
.
AuthState
==
State
.
WinAuthState
.
INITIAL_TOKEN
||
(
state
!
.
AuthState
==
State
.
WinAuthState
.
INITIAL_TOKEN
||
state
.
AuthState
==
State
.
WinAuthState
.
AUTHORIZED
);
// Server may require re-authentication on an open connection
state
.
AuthState
==
State
.
WinAuthState
.
AUTHORIZED
);
// Server may require re-authentication on an open connection
}
}
...
@@ -170,9 +170,9 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
...
@@ -170,9 +170,9 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
/// <param name="data"></param>
/// <param name="data"></param>
internal
static
void
AuthenticatedResponse
(
InternalDataStore
data
)
internal
static
void
AuthenticatedResponse
(
InternalDataStore
data
)
{
{
if
(
data
.
TryGetValueAs
(
authStateKey
,
out
State
state
))
if
(
data
.
TryGetValueAs
(
authStateKey
,
out
State
?
state
))
{
{
state
.
AuthState
=
State
.
WinAuthState
.
AUTHORIZED
;
state
!
.
AuthState
=
State
.
WinAuthState
.
AUTHORIZED
;
state
.
UpdatePresence
();
state
.
UpdatePresence
();
}
}
}
}
...
...
src/Titanium.Web.Proxy/ProxyAuthorizationHandler.cs
View file @
9df31edd
...
@@ -118,7 +118,7 @@ namespace Titanium.Web.Proxy
...
@@ -118,7 +118,7 @@ namespace Titanium.Web.Proxy
/// <param name="description">Response description.</param>
/// <param name="description">Response description.</param>
/// <param name="continuation">The continuation.</param>
/// <param name="continuation">The continuation.</param>
/// <returns></returns>
/// <returns></returns>
private
Response
createAuthentication407Response
(
string
description
,
string
continuation
=
null
)
private
Response
createAuthentication407Response
(
string
description
,
string
?
continuation
=
null
)
{
{
var
response
=
new
Response
var
response
=
new
Response
{
{
...
...
src/Titanium.Web.Proxy/ProxyServer.cs
View file @
9df31edd
...
@@ -91,7 +91,7 @@ namespace Titanium.Web.Proxy
...
@@ -91,7 +91,7 @@ namespace Titanium.Web.Proxy
/// Should we attempt to trust certificates with elevated permissions by
/// Should we attempt to trust certificates with elevated permissions by
/// prompting for UAC if required?
/// prompting for UAC if required?
/// </param>
/// </param>
public
ProxyServer
(
string
rootCertificateName
,
string
rootCertificateIssuerName
,
public
ProxyServer
(
string
?
rootCertificateName
,
string
?
rootCertificateIssuerName
,
bool
userTrustRootCertificate
=
true
,
bool
machineTrustRootCertificate
=
false
,
bool
userTrustRootCertificate
=
true
,
bool
machineTrustRootCertificate
=
false
,
bool
trustRootCertificateAsAdmin
=
false
)
bool
trustRootCertificateAsAdmin
=
false
)
{
{
...
@@ -229,7 +229,9 @@ namespace Titanium.Web.Proxy
...
@@ -229,7 +229,9 @@ namespace Titanium.Web.Proxy
/// <summary>
/// <summary>
/// List of supported Ssl versions.
/// List of supported Ssl versions.
/// </summary>
/// </summary>
#pragma warning disable 618
public
SslProtocols
SupportedSslProtocols
{
get
;
set
;
}
=
SslProtocols
.
Ssl3
|
SslProtocols
.
Tls
|
SslProtocols
.
Tls11
|
SslProtocols
.
Tls12
;
public
SslProtocols
SupportedSslProtocols
{
get
;
set
;
}
=
SslProtocols
.
Ssl3
|
SslProtocols
.
Tls
|
SslProtocols
.
Tls11
|
SslProtocols
.
Tls12
;
#pragma warning restore 618
/// <summary>
/// <summary>
/// The buffer pool used throughout this proxy instance.
/// The buffer pool used throughout this proxy instance.
...
@@ -307,37 +309,37 @@ namespace Titanium.Web.Proxy
...
@@ -307,37 +309,37 @@ namespace Titanium.Web.Proxy
/// <summary>
/// <summary>
/// Event occurs when client connection count changed.
/// Event occurs when client connection count changed.
/// </summary>
/// </summary>
public
event
EventHandler
ClientConnectionCountChanged
;
public
event
EventHandler
?
ClientConnectionCountChanged
;
/// <summary>
/// <summary>
/// Event occurs when server connection count changed.
/// Event occurs when server connection count changed.
/// </summary>
/// </summary>
public
event
EventHandler
ServerConnectionCountChanged
;
public
event
EventHandler
?
ServerConnectionCountChanged
;
/// <summary>
/// <summary>
/// Event to override the default verification logic of remote SSL certificate received during authentication.
/// Event to override the default verification logic of remote SSL certificate received during authentication.
/// </summary>
/// </summary>
public
event
AsyncEventHandler
<
CertificateValidationEventArgs
>
ServerCertificateValidationCallback
;
public
event
AsyncEventHandler
<
CertificateValidationEventArgs
>
?
ServerCertificateValidationCallback
;
/// <summary>
/// <summary>
/// Event to override client certificate selection during mutual SSL authentication.
/// Event to override client certificate selection during mutual SSL authentication.
/// </summary>
/// </summary>
public
event
AsyncEventHandler
<
CertificateSelectionEventArgs
>
ClientCertificateSelectionCallback
;
public
event
AsyncEventHandler
<
CertificateSelectionEventArgs
>
?
ClientCertificateSelectionCallback
;
/// <summary>
/// <summary>
/// Intercept request event to server.
/// Intercept request event to server.
/// </summary>
/// </summary>
public
event
AsyncEventHandler
<
SessionEventArgs
>
BeforeRequest
;
public
event
AsyncEventHandler
<
SessionEventArgs
>
?
BeforeRequest
;
/// <summary>
/// <summary>
/// Intercept response event from server.
/// Intercept response event from server.
/// </summary>
/// </summary>
public
event
AsyncEventHandler
<
SessionEventArgs
>
BeforeResponse
;
public
event
AsyncEventHandler
<
SessionEventArgs
>
?
BeforeResponse
;
/// <summary>
/// <summary>
/// Intercept after response event from server.
/// Intercept after response event from server.
/// </summary>
/// </summary>
public
event
AsyncEventHandler
<
SessionEventArgs
>
AfterResponse
;
public
event
AsyncEventHandler
<
SessionEventArgs
>
?
AfterResponse
;
/// <summary>
/// <summary>
/// Customize TcpClient used for client connection upon create.
/// Customize TcpClient used for client connection upon create.
...
@@ -471,7 +473,7 @@ namespace Titanium.Web.Proxy
...
@@ -471,7 +473,7 @@ namespace Titanium.Web.Proxy
endPoint
.
IsSystemHttpsProxy
=
true
;
endPoint
.
IsSystemHttpsProxy
=
true
;
}
}
string
proxyType
=
null
;
string
?
proxyType
=
null
;
switch
(
protocolType
)
switch
(
protocolType
)
{
{
case
ProxyProtocolType
.
Http
:
case
ProxyProtocolType
.
Http
:
...
@@ -572,7 +574,7 @@ namespace Titanium.Web.Proxy
...
@@ -572,7 +574,7 @@ namespace Titanium.Web.Proxy
if
(
systemProxySettingsManager
!=
null
&&
RunTime
.
IsWindows
&&
!
RunTime
.
IsUwpOnWindows
)
if
(
systemProxySettingsManager
!=
null
&&
RunTime
.
IsWindows
&&
!
RunTime
.
IsUwpOnWindows
)
{
{
var
proxyInfo
=
systemProxySettingsManager
.
GetProxyInfoFromRegistry
();
var
proxyInfo
=
systemProxySettingsManager
.
GetProxyInfoFromRegistry
();
if
(
proxyInfo
.
Proxies
!=
null
)
if
(
proxyInfo
?
.
Proxies
!=
null
)
{
{
var
protocolToRemove
=
ProxyProtocolType
.
None
;
var
protocolToRemove
=
ProxyProtocolType
.
None
;
foreach
(
var
proxy
in
proxyInfo
.
Proxies
.
Values
)
foreach
(
var
proxy
in
proxyInfo
.
Proxies
.
Values
)
...
@@ -717,7 +719,7 @@ namespace Titanium.Web.Proxy
...
@@ -717,7 +719,7 @@ namespace Titanium.Web.Proxy
{
{
var
endPoint
=
(
ProxyEndPoint
)
asyn
.
AsyncState
;
var
endPoint
=
(
ProxyEndPoint
)
asyn
.
AsyncState
;
TcpClient
tcpClient
=
null
;
TcpClient
?
tcpClient
=
null
;
try
try
{
{
...
...
src/Titanium.Web.Proxy/RequestHandler.cs
View file @
9df31edd
...
@@ -45,7 +45,7 @@ namespace Titanium.Web.Proxy
...
@@ -45,7 +45,7 @@ namespace Titanium.Web.Proxy
/// <param name="prefetchConnectionTask">Prefetched server connection for current client using Connect/SNI headers.</param>
/// <param name="prefetchConnectionTask">Prefetched server connection for current client using Connect/SNI headers.</param>
private
async
Task
handleHttpSessionRequest
(
ProxyEndPoint
endPoint
,
TcpClientConnection
clientConnection
,
private
async
Task
handleHttpSessionRequest
(
ProxyEndPoint
endPoint
,
TcpClientConnection
clientConnection
,
CustomBufferedStream
clientStream
,
HttpResponseWriter
clientStreamWriter
,
CustomBufferedStream
clientStream
,
HttpResponseWriter
clientStreamWriter
,
CancellationTokenSource
cancellationTokenSource
,
string
httpsConnectHostname
,
TunnelConnectSessionEventArgs
connectArgs
,
CancellationTokenSource
cancellationTokenSource
,
string
?
httpsConnectHostname
,
TunnelConnectSessionEventArgs
?
connectArgs
,
Task
<
TcpServerConnection
>?
prefetchConnectionTask
=
null
)
Task
<
TcpServerConnection
>?
prefetchConnectionTask
=
null
)
{
{
var
connectRequest
=
connectArgs
?.
HttpClient
.
ConnectRequest
;
var
connectRequest
=
connectArgs
?.
HttpClient
.
ConnectRequest
;
...
@@ -107,8 +107,8 @@ namespace Titanium.Web.Proxy
...
@@ -107,8 +107,8 @@ namespace Titanium.Web.Proxy
}
}
else
else
{
{
string
host
=
args
.
HttpClient
.
Request
.
Host
??
httpsConnectHostname
;
string
?
host
=
args
.
HttpClient
.
Request
.
Host
??
httpsConnectHostname
;
string
hostAndPath
=
host
;
string
?
hostAndPath
=
host
;
if
(
httpUrl
.
StartsWith
(
"/"
))
if
(
httpUrl
.
StartsWith
(
"/"
))
{
{
hostAndPath
+=
httpUrl
;
hostAndPath
+=
httpUrl
;
...
@@ -288,15 +288,17 @@ namespace Titanium.Web.Proxy
...
@@ -288,15 +288,17 @@ namespace Titanium.Web.Proxy
}
}
finally
finally
{
{
await
tcpConnectionFactory
.
Release
(
connection
,
if
(
connection
!=
null
)
closeServerConnection
);
{
await
tcpConnectionFactory
.
Release
(
connection
,
closeServerConnection
);
}
await
tcpConnectionFactory
.
Release
(
prefetchTask
,
closeServerConnection
);
await
tcpConnectionFactory
.
Release
(
prefetchTask
,
closeServerConnection
);
}
}
}
}
private
async
Task
<
RetryResult
>
handleHttpSessionRequest
(
string
requestHttpMethod
,
string
requestHttpUrl
,
Version
requestVersion
,
SessionEventArgs
args
,
private
async
Task
<
RetryResult
>
handleHttpSessionRequest
(
string
requestHttpMethod
,
string
requestHttpUrl
,
Version
requestVersion
,
SessionEventArgs
args
,
TcpServerConnection
serverConnection
,
SslApplicationProtocol
sslApplicationProtocol
,
TcpServerConnection
?
serverConnection
,
SslApplicationProtocol
sslApplicationProtocol
,
CancellationToken
cancellationToken
,
CancellationTokenSource
cancellationTokenSource
)
CancellationToken
cancellationToken
,
CancellationTokenSource
cancellationTokenSource
)
{
{
// a connection generator task with captured parameters via closure.
// a connection generator task with captured parameters via closure.
...
@@ -312,7 +314,7 @@ namespace Titanium.Web.Proxy
...
@@ -312,7 +314,7 @@ namespace Titanium.Web.Proxy
if
(
args
.
HttpClient
.
Request
.
UpgradeToWebSocket
)
if
(
args
.
HttpClient
.
Request
.
UpgradeToWebSocket
)
{
{
args
.
HttpClient
.
ConnectRequest
.
TunnelType
=
TunnelType
.
Websocket
;
args
.
HttpClient
.
ConnectRequest
!
.
TunnelType
=
TunnelType
.
Websocket
;
// if upgrading to websocket then relay the request without reading the contents
// if upgrading to websocket then relay the request without reading the contents
await
handleWebSocketUpgrade
(
requestHttpMethod
,
requestHttpUrl
,
requestVersion
,
args
,
args
.
HttpClient
.
Request
,
await
handleWebSocketUpgrade
(
requestHttpMethod
,
requestHttpUrl
,
requestVersion
,
args
,
args
.
HttpClient
.
Request
,
...
@@ -383,7 +385,7 @@ namespace Titanium.Web.Proxy
...
@@ -383,7 +385,7 @@ namespace Titanium.Web.Proxy
/// </summary>
/// </summary>
private
void
prepareRequestHeaders
(
HeaderCollection
requestHeaders
)
private
void
prepareRequestHeaders
(
HeaderCollection
requestHeaders
)
{
{
string
acceptEncoding
=
requestHeaders
.
GetHeaderValueOrNull
(
KnownHeaders
.
AcceptEncoding
);
string
?
acceptEncoding
=
requestHeaders
.
GetHeaderValueOrNull
(
KnownHeaders
.
AcceptEncoding
);
if
(
acceptEncoding
!=
null
)
if
(
acceptEncoding
!=
null
)
{
{
...
...
src/Titanium.Web.Proxy/ResponseHandler.cs
View file @
9df31edd
...
@@ -72,8 +72,7 @@ namespace Titanium.Web.Proxy
...
@@ -72,8 +72,7 @@ namespace Titanium.Web.Proxy
// write custom user response with body and return.
// write custom user response with body and return.
await
clientStreamWriter
.
WriteResponseAsync
(
response
,
cancellationToken
:
cancellationToken
);
await
clientStreamWriter
.
WriteResponseAsync
(
response
,
cancellationToken
:
cancellationToken
);
if
(
args
.
HttpClient
.
Connection
!=
null
if
(
args
.
HttpClient
.
HasConnection
&&
!
args
.
HttpClient
.
CloseServerConnection
)
&&
!
args
.
HttpClient
.
CloseServerConnection
)
{
{
// syphon out the original response body from server connection
// syphon out the original response body from server connection
// so that connection will be good to be reused.
// so that connection will be good to be reused.
...
@@ -86,8 +85,11 @@ namespace Titanium.Web.Proxy
...
@@ -86,8 +85,11 @@ namespace Titanium.Web.Proxy
// if user requested to send request again
// if user requested to send request again
// likely after making modifications from User Response Handler
// likely after making modifications from User Response Handler
if
(
args
.
ReRequest
)
if
(
args
.
ReRequest
)
{
if
(
args
.
HttpClient
.
HasConnection
)
{
{
await
tcpConnectionFactory
.
Release
(
args
.
HttpClient
.
Connection
);
await
tcpConnectionFactory
.
Release
(
args
.
HttpClient
.
Connection
);
}
// clear current response
// clear current response
await
args
.
ClearResponse
(
cancellationToken
);
await
args
.
ClearResponse
(
cancellationToken
);
...
...
src/Titanium.Web.Proxy/StreamExtended/ClientHelloInfo.cs
View file @
9df31edd
...
@@ -40,7 +40,7 @@ namespace Titanium.Web.Proxy.StreamExtended
...
@@ -40,7 +40,7 @@ namespace Titanium.Web.Proxy.StreamExtended
}
}
}
}
public
byte
[]
SessionId
{
get
;
set
;
}
public
byte
[]
SessionId
{
get
;
}
public
int
[]
Ciphers
{
get
;
set
;
}
public
int
[]
Ciphers
{
get
;
set
;
}
...
@@ -50,7 +50,7 @@ namespace Titanium.Web.Proxy.StreamExtended
...
@@ -50,7 +50,7 @@ namespace Titanium.Web.Proxy.StreamExtended
internal
int
EntensionsStartPosition
{
get
;
set
;
}
internal
int
EntensionsStartPosition
{
get
;
set
;
}
public
Dictionary
<
string
,
SslExtension
>
Extensions
{
get
;
set
;
}
public
Dictionary
<
string
,
SslExtension
>
?
Extensions
{
get
;
set
;
}
public
SslProtocols
SslProtocol
public
SslProtocols
SslProtocol
{
{
...
@@ -79,6 +79,11 @@ namespace Titanium.Web.Proxy.StreamExtended
...
@@ -79,6 +79,11 @@ namespace Titanium.Web.Proxy.StreamExtended
}
}
}
}
public
ClientHelloInfo
(
byte
[]
sessionId
)
{
SessionId
=
sessionId
;
}
private
static
string
SslVersionToString
(
int
major
,
int
minor
)
private
static
string
SslVersionToString
(
int
major
,
int
minor
)
{
{
string
str
=
"Unknown"
;
string
str
=
"Unknown"
;
...
...
src/Titanium.Web.Proxy/StreamExtended/Network/CopyStream.cs
View file @
9df31edd
...
@@ -19,7 +19,7 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
...
@@ -19,7 +19,7 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
private
int
bufferLength
;
private
int
bufferLength
;
private
byte
[]
buffer
;
private
readonly
byte
[]
buffer
;
private
bool
disposed
;
private
bool
disposed
;
...
@@ -134,9 +134,7 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
...
@@ -134,9 +134,7 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
if
(!
disposed
)
if
(!
disposed
)
{
{
disposed
=
true
;
disposed
=
true
;
var
b
=
buffer
;
bufferPool
.
ReturnBuffer
(
buffer
);
buffer
=
null
;
bufferPool
.
ReturnBuffer
(
b
);
}
}
}
}
}
}
...
...
src/Titanium.Web.Proxy/StreamExtended/Network/CustomBufferedStream.cs
View file @
9df31edd
...
@@ -19,7 +19,7 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
...
@@ -19,7 +19,7 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
internal
class
CustomBufferedStream
:
Stream
,
ICustomStreamReader
internal
class
CustomBufferedStream
:
Stream
,
ICustomStreamReader
{
{
private
readonly
bool
leaveOpen
;
private
readonly
bool
leaveOpen
;
private
byte
[]
streamBuffer
;
private
readonly
byte
[]
streamBuffer
;
// default to UTF-8
// default to UTF-8
private
static
Encoding
encoding
=>
HttpHelper
.
HeaderEncoding
;
private
static
Encoding
encoding
=>
HttpHelper
.
HeaderEncoding
;
...
@@ -397,9 +397,7 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
...
@@ -397,9 +397,7 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
BaseStream
.
Dispose
();
BaseStream
.
Dispose
();
}
}
var
buffer
=
streamBuffer
;
bufferPool
.
ReturnBuffer
(
streamBuffer
);
streamBuffer
=
null
;
bufferPool
.
ReturnBuffer
(
buffer
);
}
}
}
}
...
@@ -569,7 +567,7 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
...
@@ -569,7 +567,7 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
/// Read a line from the byte stream
/// Read a line from the byte stream
/// </summary>
/// </summary>
/// <returns></returns>
/// <returns></returns>
internal
static
async
Task
<
string
>
ReadLineInternalAsync
(
ICustomStreamReader
reader
,
IBufferPool
bufferPool
,
CancellationToken
cancellationToken
=
default
)
internal
static
async
Task
<
string
?
>
ReadLineInternalAsync
(
ICustomStreamReader
reader
,
IBufferPool
bufferPool
,
CancellationToken
cancellationToken
=
default
)
{
{
byte
lastChar
=
default
;
byte
lastChar
=
default
;
...
...
src/Titanium.Web.Proxy/StreamExtended/ServerHelloInfo.cs
View file @
9df31edd
using
System
;
using
System
;
using
System.Collections.Generic
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Linq
;
using
System.Text
;
using
System.Text
;
...
@@ -49,7 +49,7 @@ namespace Titanium.Web.Proxy.StreamExtended
...
@@ -49,7 +49,7 @@ namespace Titanium.Web.Proxy.StreamExtended
internal
int
EntensionsStartPosition
{
get
;
set
;
}
internal
int
EntensionsStartPosition
{
get
;
set
;
}
public
Dictionary
<
string
,
SslExtension
>
Extensions
{
get
;
set
;
}
public
Dictionary
<
string
,
SslExtension
>
?
Extensions
{
get
;
set
;
}
private
static
string
SslVersionToString
(
int
major
,
int
minor
)
private
static
string
SslVersionToString
(
int
major
,
int
minor
)
{
{
...
...
src/Titanium.Web.Proxy/StreamExtended/SslTools.cs
View file @
9df31edd
...
@@ -32,7 +32,7 @@ namespace Titanium.Web.Proxy.StreamExtended
...
@@ -32,7 +32,7 @@ namespace Titanium.Web.Proxy.StreamExtended
/// <param name="bufferPool"></param>
/// <param name="bufferPool"></param>
/// <param name="cancellationToken"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
/// <returns></returns>
public
static
async
Task
<
ClientHelloInfo
>
PeekClientHello
(
CustomBufferedStream
clientStream
,
IBufferPool
bufferPool
,
CancellationToken
cancellationToken
=
default
)
public
static
async
Task
<
ClientHelloInfo
?
>
PeekClientHello
(
CustomBufferedStream
clientStream
,
IBufferPool
bufferPool
,
CancellationToken
cancellationToken
=
default
)
{
{
// detects the HTTPS ClientHello message as it is described in the following url:
// detects the HTTPS ClientHello message as it is described in the following url:
// https://stackoverflow.com/questions/3897883/how-to-detect-an-incoming-ssl-https-handshake-ssl-wire-format
// https://stackoverflow.com/questions/3897883/how-to-detect-an-incoming-ssl-https-handshake-ssl-wire-format
...
@@ -88,13 +88,12 @@ namespace Titanium.Web.Proxy.StreamExtended
...
@@ -88,13 +88,12 @@ namespace Titanium.Web.Proxy.StreamExtended
byte
[]
sessionId
=
peekStream
.
ReadBytes
(
sessionIdLength
);
byte
[]
sessionId
=
peekStream
.
ReadBytes
(
sessionIdLength
);
byte
[]
random
=
peekStream
.
ReadBytes
(
randomLength
);
byte
[]
random
=
peekStream
.
ReadBytes
(
randomLength
);
var
clientHelloInfo
=
new
ClientHelloInfo
var
clientHelloInfo
=
new
ClientHelloInfo
(
sessionId
)
{
{
HandshakeVersion
=
2
,
HandshakeVersion
=
2
,
MajorVersion
=
majorVersion
,
MajorVersion
=
majorVersion
,
MinorVersion
=
minorVersion
,
MinorVersion
=
minorVersion
,
Random
=
random
,
Random
=
random
,
SessionId
=
sessionId
,
Ciphers
=
ciphers
,
Ciphers
=
ciphers
,
ClientHelloLength
=
peekStream
.
Position
,
ClientHelloLength
=
peekStream
.
Position
,
};
};
...
@@ -171,20 +170,19 @@ namespace Titanium.Web.Proxy.StreamExtended
...
@@ -171,20 +170,19 @@ namespace Titanium.Web.Proxy.StreamExtended
int
extenstionsStartPosition
=
peekStream
.
Position
;
int
extenstionsStartPosition
=
peekStream
.
Position
;
Dictionary
<
string
,
SslExtension
>
extensions
=
null
;
Dictionary
<
string
,
SslExtension
>
?
extensions
=
null
;
if
(
extenstionsStartPosition
<
recordLength
+
5
)
if
(
extenstionsStartPosition
<
recordLength
+
5
)
{
{
extensions
=
await
ReadExtensions
(
majorVersion
,
minorVersion
,
peekStream
,
bufferPool
,
cancellationToken
);
extensions
=
await
ReadExtensions
(
majorVersion
,
minorVersion
,
peekStream
,
bufferPool
,
cancellationToken
);
}
}
var
clientHelloInfo
=
new
ClientHelloInfo
var
clientHelloInfo
=
new
ClientHelloInfo
(
sessionId
)
{
{
HandshakeVersion
=
3
,
HandshakeVersion
=
3
,
MajorVersion
=
majorVersion
,
MajorVersion
=
majorVersion
,
MinorVersion
=
minorVersion
,
MinorVersion
=
minorVersion
,
Random
=
random
,
Random
=
random
,
SessionId
=
sessionId
,
Ciphers
=
ciphers
,
Ciphers
=
ciphers
,
CompressionData
=
compressionData
,
CompressionData
=
compressionData
,
ClientHelloLength
=
peekStream
.
Position
,
ClientHelloLength
=
peekStream
.
Position
,
...
@@ -218,7 +216,7 @@ namespace Titanium.Web.Proxy.StreamExtended
...
@@ -218,7 +216,7 @@ namespace Titanium.Web.Proxy.StreamExtended
/// <param name="bufferPool"></param>
/// <param name="bufferPool"></param>
/// <param name="cancellationToken"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
/// <returns></returns>
public
static
async
Task
<
ServerHelloInfo
>
PeekServerHello
(
CustomBufferedStream
serverStream
,
IBufferPool
bufferPool
,
CancellationToken
cancellationToken
=
default
)
public
static
async
Task
<
ServerHelloInfo
?
>
PeekServerHello
(
CustomBufferedStream
serverStream
,
IBufferPool
bufferPool
,
CancellationToken
cancellationToken
=
default
)
{
{
// detects the HTTPS ClientHello message as it is described in the following url:
// detects the HTTPS ClientHello message as it is described in the following url:
// https://stackoverflow.com/questions/3897883/how-to-detect-an-incoming-ssl-https-handshake-ssl-wire-format
// https://stackoverflow.com/questions/3897883/how-to-detect-an-incoming-ssl-https-handshake-ssl-wire-format
...
@@ -324,7 +322,7 @@ namespace Titanium.Web.Proxy.StreamExtended
...
@@ -324,7 +322,7 @@ namespace Titanium.Web.Proxy.StreamExtended
int
extenstionsStartPosition
=
peekStream
.
Position
;
int
extenstionsStartPosition
=
peekStream
.
Position
;
Dictionary
<
string
,
SslExtension
>
extensions
=
null
;
Dictionary
<
string
,
SslExtension
>
?
extensions
=
null
;
if
(
extenstionsStartPosition
<
recordLength
+
5
)
if
(
extenstionsStartPosition
<
recordLength
+
5
)
{
{
...
@@ -351,9 +349,9 @@ namespace Titanium.Web.Proxy.StreamExtended
...
@@ -351,9 +349,9 @@ namespace Titanium.Web.Proxy.StreamExtended
return
null
;
return
null
;
}
}
private
static
async
Task
<
Dictionary
<
string
,
SslExtension
>>
ReadExtensions
(
int
majorVersion
,
int
minorVersion
,
CustomBufferedPeekStream
peekStream
,
IBufferPool
bufferPool
,
CancellationToken
cancellationToken
)
private
static
async
Task
<
Dictionary
<
string
,
SslExtension
>
?
>
ReadExtensions
(
int
majorVersion
,
int
minorVersion
,
CustomBufferedPeekStream
peekStream
,
IBufferPool
bufferPool
,
CancellationToken
cancellationToken
)
{
{
Dictionary
<
string
,
SslExtension
>
extensions
=
null
;
Dictionary
<
string
,
SslExtension
>
?
extensions
=
null
;
if
(
majorVersion
>
3
||
majorVersion
==
3
&&
minorVersion
>=
1
)
if
(
majorVersion
>
3
||
majorVersion
==
3
&&
minorVersion
>=
1
)
{
{
if
(
await
peekStream
.
EnsureBufferLength
(
2
,
cancellationToken
))
if
(
await
peekStream
.
EnsureBufferLength
(
2
,
cancellationToken
))
...
...
src/Titanium.Web.Proxy/TransparentClientHandler.cs
View file @
9df31edd
using
System
;
using
System
;
using
System.Collections.Generic
;
using
System.Collections.Generic
;
using
System.IO
;
using
System.IO
;
using
System.Net
;
using
System.Net.Security
;
using
System.Net.Security
;
using
System.Net.Sockets
;
using
System.Net.Sockets
;
using
System.Security.Authentication
;
using
System.Security.Authentication
;
...
@@ -35,23 +36,19 @@ namespace Titanium.Web.Proxy
...
@@ -35,23 +36,19 @@ namespace Titanium.Web.Proxy
var
clientStream
=
new
CustomBufferedStream
(
clientConnection
.
GetStream
(),
BufferPool
);
var
clientStream
=
new
CustomBufferedStream
(
clientConnection
.
GetStream
(),
BufferPool
);
var
clientStreamWriter
=
new
HttpResponseWriter
(
clientStream
,
BufferPool
);
var
clientStreamWriter
=
new
HttpResponseWriter
(
clientStream
,
BufferPool
);
SslStream
sslStream
=
null
;
SslStream
?
sslStream
=
null
;
try
try
{
{
var
clientHelloInfo
=
await
SslTools
.
PeekClientHello
(
clientStream
,
BufferPool
,
cancellationToken
);
var
clientHelloInfo
=
await
SslTools
.
PeekClientHello
(
clientStream
,
BufferPool
,
cancellationToken
);
bool
isHttps
=
clientHelloInfo
!=
null
;
string
?
httpsHostName
=
null
;
string
httpsHostName
=
null
;
if
(
isHttps
)
if
(
clientHelloInfo
!=
null
)
{
{
httpsHostName
=
clientHelloInfo
.
GetServerName
()
??
endPoint
.
GenericCertificateName
;
httpsHostName
=
clientHelloInfo
.
GetServerName
()
??
endPoint
.
GenericCertificateName
;
var
args
=
new
BeforeSslAuthenticateEventArgs
(
cancellationTokenSource
)
var
args
=
new
BeforeSslAuthenticateEventArgs
(
cancellationTokenSource
,
httpsHostName
);
{
SniHostName
=
httpsHostName
};
await
endPoint
.
InvokeBeforeSslAuthenticate
(
this
,
args
,
ExceptionFunc
);
await
endPoint
.
InvokeBeforeSslAuthenticate
(
this
,
args
,
ExceptionFunc
);
...
@@ -65,7 +62,7 @@ namespace Titanium.Web.Proxy
...
@@ -65,7 +62,7 @@ namespace Titanium.Web.Proxy
clientConnection
.
SslProtocol
=
clientHelloInfo
.
SslProtocol
;
clientConnection
.
SslProtocol
=
clientHelloInfo
.
SslProtocol
;
// do client authentication using certificate
// do client authentication using certificate
X509Certificate2
certificate
=
null
;
X509Certificate2
?
certificate
=
null
;
try
try
{
{
sslStream
=
new
SslStream
(
clientStream
,
false
);
sslStream
=
new
SslStream
(
clientStream
,
false
);
...
@@ -98,7 +95,7 @@ namespace Titanium.Web.Proxy
...
@@ -98,7 +95,7 @@ namespace Titanium.Web.Proxy
else
else
{
{
var
connection
=
await
tcpConnectionFactory
.
GetServerConnection
(
httpsHostName
,
endPoint
.
Port
,
var
connection
=
await
tcpConnectionFactory
.
GetServerConnection
(
httpsHostName
,
endPoint
.
Port
,
httpVersion
:
null
,
isHttps
:
false
,
applicationProtocols
:
null
,
httpVersion
:
HttpHeader
.
VersionUnknown
,
isHttps
:
false
,
applicationProtocols
:
null
,
isConnect
:
true
,
proxyServer
:
this
,
session
:
null
,
upStreamEndPoint
:
UpStreamEndPoint
,
isConnect
:
true
,
proxyServer
:
this
,
session
:
null
,
upStreamEndPoint
:
UpStreamEndPoint
,
externalProxy
:
UpStreamHttpsProxy
,
noCache
:
true
,
cancellationToken
:
cancellationToken
);
externalProxy
:
UpStreamHttpsProxy
,
noCache
:
true
,
cancellationToken
:
cancellationToken
);
...
@@ -136,10 +133,11 @@ namespace Titanium.Web.Proxy
...
@@ -136,10 +133,11 @@ namespace Titanium.Web.Proxy
return
;
return
;
}
}
}
}
// HTTPS server created - we can now decrypt the client's traffic
// HTTPS server created - we can now decrypt the client's traffic
// Now create the request
// Now create the request
await
handleHttpSessionRequest
(
endPoint
,
clientConnection
,
clientStream
,
clientStreamWriter
,
await
handleHttpSessionRequest
(
endPoint
,
clientConnection
,
clientStream
,
clientStreamWriter
,
cancellationTokenSource
,
isHttps
?
httpsHostName
:
null
,
null
,
null
);
cancellationTokenSource
,
httpsHostName
,
null
,
null
);
}
}
catch
(
ProxyException
e
)
catch
(
ProxyException
e
)
{
{
...
...
src/Titanium.Web.Proxy/WinAuthHandler.cs
View file @
9df31edd
...
@@ -47,8 +47,8 @@ namespace Titanium.Web.Proxy
...
@@ -47,8 +47,8 @@ namespace Titanium.Web.Proxy
/// </summary>
/// </summary>
private
async
Task
handle401UnAuthorized
(
SessionEventArgs
args
)
private
async
Task
handle401UnAuthorized
(
SessionEventArgs
args
)
{
{
string
headerName
=
null
;
string
?
headerName
=
null
;
HttpHeader
authHeader
=
null
;
HttpHeader
?
authHeader
=
null
;
var
response
=
args
.
HttpClient
.
Response
;
var
response
=
args
.
HttpClient
.
Response
;
...
@@ -91,7 +91,7 @@ namespace Titanium.Web.Proxy
...
@@ -91,7 +91,7 @@ namespace Titanium.Web.Proxy
if
(
authHeader
!=
null
)
if
(
authHeader
!=
null
)
{
{
string
scheme
=
authSchemes
.
Contains
(
authHeader
.
Value
)
?
authHeader
.
Value
:
null
;
string
?
scheme
=
authSchemes
.
Contains
(
authHeader
.
Value
)
?
authHeader
.
Value
:
null
;
var
expectedAuthState
=
var
expectedAuthState
=
scheme
==
null
?
State
.
WinAuthState
.
INITIAL_TOKEN
:
State
.
WinAuthState
.
UNAUTHORIZED
;
scheme
==
null
?
State
.
WinAuthState
.
INITIAL_TOKEN
:
State
.
WinAuthState
.
UNAUTHORIZED
;
...
...
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