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
a0a6e678
Commit
a0a6e678
authored
May 11, 2017
by
Jehonathan Thomas
Committed by
GitHub
May 11, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #212 from honfika/develop
Root certificate improvements (issue #121 and #149)
parents
d386c2d1
9ee26d14
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
211 additions
and
145 deletions
+211
-145
Program.cs
Examples/Titanium.Web.Proxy.Examples.Basic/Program.cs
+4
-4
ProxyTestController.cs
.../Titanium.Web.Proxy.Examples.Basic/ProxyTestController.cs
+6
-4
Network.cs
Titanium.Web.Proxy/Helpers/Network.cs
+38
-38
EndPoint.cs
Titanium.Web.Proxy/Models/EndPoint.cs
+6
-6
ExternalProxy.cs
Titanium.Web.Proxy/Models/ExternalProxy.cs
+5
-5
WinCertificateMaker.cs
...nium.Web.Proxy/Network/Certificate/WinCertificateMaker.cs
+38
-38
CertificateManager.cs
Titanium.Web.Proxy/Network/CertificateManager.cs
+35
-11
ProxyServer.cs
Titanium.Web.Proxy/ProxyServer.cs
+71
-31
RequestHandler.cs
Titanium.Web.Proxy/RequestHandler.cs
+6
-6
ResponseHandler.cs
Titanium.Web.Proxy/ResponseHandler.cs
+2
-2
No files found.
Examples/Titanium.Web.Proxy.Examples.Basic/Program.cs
View file @
a0a6e678
...
@@ -5,7 +5,7 @@ namespace Titanium.Web.Proxy.Examples.Basic
...
@@ -5,7 +5,7 @@ namespace Titanium.Web.Proxy.Examples.Basic
{
{
public
class
Program
public
class
Program
{
{
private
static
readonly
ProxyTestController
C
ontroller
=
new
ProxyTestController
();
private
static
readonly
ProxyTestController
c
ontroller
=
new
ProxyTestController
();
public
static
void
Main
(
string
[]
args
)
public
static
void
Main
(
string
[]
args
)
{
{
...
@@ -15,13 +15,13 @@ namespace Titanium.Web.Proxy.Examples.Basic
...
@@ -15,13 +15,13 @@ namespace Titanium.Web.Proxy.Examples.Basic
//Start proxy controller
//Start proxy controller
C
ontroller
.
StartProxy
();
c
ontroller
.
StartProxy
();
Console
.
WriteLine
(
"Hit any key to exit.."
);
Console
.
WriteLine
(
"Hit any key to exit.."
);
Console
.
WriteLine
();
Console
.
WriteLine
();
Console
.
Read
();
Console
.
Read
();
C
ontroller
.
Stop
();
c
ontroller
.
Stop
();
}
}
...
@@ -30,7 +30,7 @@ namespace Titanium.Web.Proxy.Examples.Basic
...
@@ -30,7 +30,7 @@ namespace Titanium.Web.Proxy.Examples.Basic
if
(
eventType
!=
2
)
return
false
;
if
(
eventType
!=
2
)
return
false
;
try
try
{
{
C
ontroller
.
Stop
();
c
ontroller
.
Stop
();
}
}
catch
catch
{
{
...
...
Examples/Titanium.Web.Proxy.Examples.Basic/ProxyTestController.cs
View file @
a0a6e678
using
System
;
using
System
;
using
System.Collections.Generic
;
using
System.Collections.Generic
;
using
System.Net
;
using
System.Net
;
using
System.Security.Cryptography.X509Certificates
;
using
System.Threading.Tasks
;
using
System.Threading.Tasks
;
using
Titanium.Web.Proxy.EventArguments
;
using
Titanium.Web.Proxy.EventArguments
;
using
Titanium.Web.Proxy.Models
;
using
Titanium.Web.Proxy.Models
;
...
@@ -9,10 +10,10 @@ namespace Titanium.Web.Proxy.Examples.Basic
...
@@ -9,10 +10,10 @@ namespace Titanium.Web.Proxy.Examples.Basic
{
{
public
class
ProxyTestController
public
class
ProxyTestController
{
{
private
ProxyServer
proxyServer
;
private
readonly
ProxyServer
proxyServer
;
//share requestBody outside handlers
//share requestBody outside handlers
private
Dictionary
<
Guid
,
string
>
requestBodyHistory
;
private
readonly
Dictionary
<
Guid
,
string
>
requestBodyHistory
=
new
Dictionary
<
Guid
,
string
>()
;
public
ProxyTestController
()
public
ProxyTestController
()
{
{
...
@@ -23,7 +24,8 @@ namespace Titanium.Web.Proxy.Examples.Basic
...
@@ -23,7 +24,8 @@ namespace Titanium.Web.Proxy.Examples.Basic
//Under Mono only BouncyCastle will be supported
//Under Mono only BouncyCastle will be supported
//proxyServer.CertificateEngine = Network.CertificateEngine.BouncyCastle;
//proxyServer.CertificateEngine = Network.CertificateEngine.BouncyCastle;
requestBodyHistory
=
new
Dictionary
<
Guid
,
string
>();
//optionally set the Root Certificate
//proxyServer.RootCertificate = new X509Certificate2("myCert.pfx", string.Empty, X509KeyStorageFlags.Exportable);
}
}
public
void
StartProxy
()
public
void
StartProxy
()
...
...
Titanium.Web.Proxy/Helpers/Network.cs
View file @
a0a6e678
Titanium.Web.Proxy/Models/EndPoint.cs
View file @
a0a6e678
...
@@ -53,8 +53,8 @@ namespace Titanium.Web.Proxy.Models
...
@@ -53,8 +53,8 @@ namespace Titanium.Web.Proxy.Models
/// </summary>
/// </summary>
public
class
ExplicitProxyEndPoint
:
ProxyEndPoint
public
class
ExplicitProxyEndPoint
:
ProxyEndPoint
{
{
private
List
<
string
>
_
excludedHttpsHostNameRegex
;
private
List
<
string
>
excludedHttpsHostNameRegex
;
private
List
<
string
>
_
includedHttpsHostNameRegex
;
private
List
<
string
>
includedHttpsHostNameRegex
;
internal
bool
IsSystemHttpProxy
{
get
;
set
;
}
internal
bool
IsSystemHttpProxy
{
get
;
set
;
}
...
@@ -65,7 +65,7 @@ namespace Titanium.Web.Proxy.Models
...
@@ -65,7 +65,7 @@ namespace Titanium.Web.Proxy.Models
/// </summary>
/// </summary>
public
List
<
string
>
ExcludedHttpsHostNameRegex
public
List
<
string
>
ExcludedHttpsHostNameRegex
{
{
get
{
return
_
excludedHttpsHostNameRegex
;
}
get
{
return
excludedHttpsHostNameRegex
;
}
set
set
{
{
if
(
IncludedHttpsHostNameRegex
!=
null
)
if
(
IncludedHttpsHostNameRegex
!=
null
)
...
@@ -73,7 +73,7 @@ namespace Titanium.Web.Proxy.Models
...
@@ -73,7 +73,7 @@ namespace Titanium.Web.Proxy.Models
throw
new
ArgumentException
(
"Cannot set excluded when included is set"
);
throw
new
ArgumentException
(
"Cannot set excluded when included is set"
);
}
}
_
excludedHttpsHostNameRegex
=
value
;
excludedHttpsHostNameRegex
=
value
;
}
}
}
}
...
@@ -82,7 +82,7 @@ namespace Titanium.Web.Proxy.Models
...
@@ -82,7 +82,7 @@ namespace Titanium.Web.Proxy.Models
/// </summary>
/// </summary>
public
List
<
string
>
IncludedHttpsHostNameRegex
public
List
<
string
>
IncludedHttpsHostNameRegex
{
{
get
{
return
_
includedHttpsHostNameRegex
;
}
get
{
return
includedHttpsHostNameRegex
;
}
set
set
{
{
if
(
ExcludedHttpsHostNameRegex
!=
null
)
if
(
ExcludedHttpsHostNameRegex
!=
null
)
...
@@ -90,7 +90,7 @@ namespace Titanium.Web.Proxy.Models
...
@@ -90,7 +90,7 @@ namespace Titanium.Web.Proxy.Models
throw
new
ArgumentException
(
"Cannot set included when excluded is set"
);
throw
new
ArgumentException
(
"Cannot set included when excluded is set"
);
}
}
_
includedHttpsHostNameRegex
=
value
;
includedHttpsHostNameRegex
=
value
;
}
}
}
}
...
...
Titanium.Web.Proxy/Models/ExternalProxy.cs
View file @
a0a6e678
...
@@ -8,7 +8,7 @@ namespace Titanium.Web.Proxy.Models
...
@@ -8,7 +8,7 @@ namespace Titanium.Web.Proxy.Models
/// </summary>
/// </summary>
public
class
ExternalProxy
public
class
ExternalProxy
{
{
private
static
readonly
Lazy
<
NetworkCredential
>
D
efaultCredentials
=
new
Lazy
<
NetworkCredential
>(()
=>
CredentialCache
.
DefaultNetworkCredentials
);
private
static
readonly
Lazy
<
NetworkCredential
>
d
efaultCredentials
=
new
Lazy
<
NetworkCredential
>(()
=>
CredentialCache
.
DefaultNetworkCredentials
);
private
string
userName
;
private
string
userName
;
private
string
password
;
private
string
password
;
...
@@ -27,12 +27,12 @@ namespace Titanium.Web.Proxy.Models
...
@@ -27,12 +27,12 @@ namespace Titanium.Web.Proxy.Models
/// Username.
/// Username.
/// </summary>
/// </summary>
public
string
UserName
{
public
string
UserName
{
get
{
return
UseDefaultCredentials
?
D
efaultCredentials
.
Value
.
UserName
:
userName
;
}
get
{
return
UseDefaultCredentials
?
d
efaultCredentials
.
Value
.
UserName
:
userName
;
}
set
set
{
{
userName
=
value
;
userName
=
value
;
if
(
D
efaultCredentials
.
Value
.
UserName
!=
userName
)
if
(
d
efaultCredentials
.
Value
.
UserName
!=
userName
)
{
{
UseDefaultCredentials
=
false
;
UseDefaultCredentials
=
false
;
}
}
...
@@ -44,12 +44,12 @@ namespace Titanium.Web.Proxy.Models
...
@@ -44,12 +44,12 @@ namespace Titanium.Web.Proxy.Models
/// </summary>
/// </summary>
public
string
Password
public
string
Password
{
{
get
{
return
UseDefaultCredentials
?
D
efaultCredentials
.
Value
.
Password
:
password
;
}
get
{
return
UseDefaultCredentials
?
d
efaultCredentials
.
Value
.
Password
:
password
;
}
set
set
{
{
password
=
value
;
password
=
value
;
if
(
D
efaultCredentials
.
Value
.
Password
!=
password
)
if
(
d
efaultCredentials
.
Value
.
Password
!=
password
)
{
{
UseDefaultCredentials
=
false
;
UseDefaultCredentials
=
false
;
}
}
...
...
Titanium.Web.Proxy/Network/Certificate/WinCertificateMaker.cs
View file @
a0a6e678
...
@@ -42,7 +42,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
...
@@ -42,7 +42,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
private
readonly
string
sProviderName
=
"Microsoft Enhanced Cryptographic Provider v1.0"
;
private
readonly
string
sProviderName
=
"Microsoft Enhanced Cryptographic Provider v1.0"
;
private
object
_S
haredPrivateKey
;
private
object
s
haredPrivateKey
;
/// <summary>
/// <summary>
/// Constructor.
/// Constructor.
...
@@ -105,7 +105,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
...
@@ -105,7 +105,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
if
(!
isRoot
)
if
(!
isRoot
)
{
{
sharedPrivateKey
=
_S
haredPrivateKey
;
sharedPrivateKey
=
this
.
s
haredPrivateKey
;
}
}
if
(
sharedPrivateKey
==
null
)
if
(
sharedPrivateKey
==
null
)
...
@@ -130,52 +130,52 @@ namespace Titanium.Web.Proxy.Network.Certificate
...
@@ -130,52 +130,52 @@ namespace Titanium.Web.Proxy.Network.Certificate
if
(!
isRoot
)
if
(!
isRoot
)
{
{
_S
haredPrivateKey
=
sharedPrivateKey
;
this
.
s
haredPrivateKey
=
sharedPrivateKey
;
}
}
}
}
typeValue
=
new
object
[
1
];
typeValue
=
new
object
[
1
];
var
OID
=
Activator
.
CreateInstance
(
typeOID
);
var
oid
=
Activator
.
CreateInstance
(
typeOID
);
typeValue
[
0
]
=
"1.3.6.1.5.5.7.3.1"
;
typeValue
[
0
]
=
"1.3.6.1.5.5.7.3.1"
;
typeOID
.
InvokeMember
(
"InitializeFromValue"
,
BindingFlags
.
InvokeMethod
,
null
,
OID
,
typeValue
);
typeOID
.
InvokeMember
(
"InitializeFromValue"
,
BindingFlags
.
InvokeMethod
,
null
,
oid
,
typeValue
);
var
OIDS
=
Activator
.
CreateInstance
(
typeOIDS
);
var
oids
=
Activator
.
CreateInstance
(
typeOIDS
);
typeValue
[
0
]
=
OID
;
typeValue
[
0
]
=
oid
;
typeOIDS
.
InvokeMember
(
"Add"
,
BindingFlags
.
InvokeMethod
,
null
,
OIDS
,
typeValue
);
typeOIDS
.
InvokeMember
(
"Add"
,
BindingFlags
.
InvokeMethod
,
null
,
oids
,
typeValue
);
var
EKU
Ext
=
Activator
.
CreateInstance
(
typeEKUExt
);
var
eku
Ext
=
Activator
.
CreateInstance
(
typeEKUExt
);
typeValue
[
0
]
=
OIDS
;
typeValue
[
0
]
=
oids
;
typeEKUExt
.
InvokeMember
(
"InitializeEncode"
,
BindingFlags
.
InvokeMethod
,
null
,
EKU
Ext
,
typeValue
);
typeEKUExt
.
InvokeMember
(
"InitializeEncode"
,
BindingFlags
.
InvokeMethod
,
null
,
eku
Ext
,
typeValue
);
var
R
equestCert
=
Activator
.
CreateInstance
(
typeRequestCert
);
var
r
equestCert
=
Activator
.
CreateInstance
(
typeRequestCert
);
typeValue
=
new
[]
{
1
,
sharedPrivateKey
,
string
.
Empty
};
typeValue
=
new
[]
{
1
,
sharedPrivateKey
,
string
.
Empty
};
typeRequestCert
.
InvokeMember
(
"InitializeFromPrivateKey"
,
BindingFlags
.
InvokeMethod
,
null
,
R
equestCert
,
typeValue
);
typeRequestCert
.
InvokeMember
(
"InitializeFromPrivateKey"
,
BindingFlags
.
InvokeMethod
,
null
,
r
equestCert
,
typeValue
);
typeValue
=
new
[]
{
x500CertDN
};
typeValue
=
new
[]
{
x500CertDN
};
typeRequestCert
.
InvokeMember
(
"Subject"
,
BindingFlags
.
PutDispProperty
,
null
,
R
equestCert
,
typeValue
);
typeRequestCert
.
InvokeMember
(
"Subject"
,
BindingFlags
.
PutDispProperty
,
null
,
r
equestCert
,
typeValue
);
typeValue
[
0
]
=
x500RootCertDN
;
typeValue
[
0
]
=
x500RootCertDN
;
typeRequestCert
.
InvokeMember
(
"Issuer"
,
BindingFlags
.
PutDispProperty
,
null
,
R
equestCert
,
typeValue
);
typeRequestCert
.
InvokeMember
(
"Issuer"
,
BindingFlags
.
PutDispProperty
,
null
,
r
equestCert
,
typeValue
);
typeValue
[
0
]
=
validFrom
;
typeValue
[
0
]
=
validFrom
;
typeRequestCert
.
InvokeMember
(
"NotBefore"
,
BindingFlags
.
PutDispProperty
,
null
,
R
equestCert
,
typeValue
);
typeRequestCert
.
InvokeMember
(
"NotBefore"
,
BindingFlags
.
PutDispProperty
,
null
,
r
equestCert
,
typeValue
);
typeValue
[
0
]
=
validTo
;
typeValue
[
0
]
=
validTo
;
typeRequestCert
.
InvokeMember
(
"NotAfter"
,
BindingFlags
.
PutDispProperty
,
null
,
R
equestCert
,
typeValue
);
typeRequestCert
.
InvokeMember
(
"NotAfter"
,
BindingFlags
.
PutDispProperty
,
null
,
r
equestCert
,
typeValue
);
var
KU
Ext
=
Activator
.
CreateInstance
(
typeKUExt
);
var
ku
Ext
=
Activator
.
CreateInstance
(
typeKUExt
);
typeValue
[
0
]
=
176
;
typeValue
[
0
]
=
176
;
typeKUExt
.
InvokeMember
(
"InitializeEncode"
,
BindingFlags
.
InvokeMethod
,
null
,
KU
Ext
,
typeValue
);
typeKUExt
.
InvokeMember
(
"InitializeEncode"
,
BindingFlags
.
InvokeMethod
,
null
,
ku
Ext
,
typeValue
);
var
certificate
=
typeRequestCert
.
InvokeMember
(
"X509Extensions"
,
BindingFlags
.
GetProperty
,
null
,
R
equestCert
,
null
);
var
certificate
=
typeRequestCert
.
InvokeMember
(
"X509Extensions"
,
BindingFlags
.
GetProperty
,
null
,
r
equestCert
,
null
);
typeValue
=
new
object
[
1
];
typeValue
=
new
object
[
1
];
if
(!
isRoot
)
if
(!
isRoot
)
{
{
typeValue
[
0
]
=
KU
Ext
;
typeValue
[
0
]
=
ku
Ext
;
typeX509Extensions
.
InvokeMember
(
"Add"
,
BindingFlags
.
InvokeMethod
,
null
,
certificate
,
typeValue
);
typeX509Extensions
.
InvokeMember
(
"Add"
,
BindingFlags
.
InvokeMethod
,
null
,
certificate
,
typeValue
);
}
}
typeValue
[
0
]
=
EKU
Ext
;
typeValue
[
0
]
=
eku
Ext
;
typeX509Extensions
.
InvokeMember
(
"Add"
,
BindingFlags
.
InvokeMethod
,
null
,
certificate
,
typeValue
);
typeX509Extensions
.
InvokeMember
(
"Add"
,
BindingFlags
.
InvokeMethod
,
null
,
certificate
,
typeValue
);
if
(!
isRoot
)
if
(!
isRoot
)
...
@@ -203,12 +203,12 @@ namespace Titanium.Web.Proxy.Network.Certificate
...
@@ -203,12 +203,12 @@ namespace Titanium.Web.Proxy.Network.Certificate
if
(!
isRoot
)
if
(!
isRoot
)
{
{
var
S
ignerCertificate
=
Activator
.
CreateInstance
(
typeSignerCertificate
);
var
s
ignerCertificate
=
Activator
.
CreateInstance
(
typeSignerCertificate
);
typeValue
=
new
object
[]
{
0
,
0
,
12
,
signingCertificate
.
Thumbprint
};
typeValue
=
new
object
[]
{
0
,
0
,
12
,
signingCertificate
.
Thumbprint
};
typeSignerCertificate
.
InvokeMember
(
"Initialize"
,
BindingFlags
.
InvokeMethod
,
null
,
S
ignerCertificate
,
typeValue
);
typeSignerCertificate
.
InvokeMember
(
"Initialize"
,
BindingFlags
.
InvokeMethod
,
null
,
s
ignerCertificate
,
typeValue
);
typeValue
=
new
[]
{
S
ignerCertificate
};
typeValue
=
new
[]
{
s
ignerCertificate
};
typeRequestCert
.
InvokeMember
(
"SignerCertificate"
,
BindingFlags
.
PutDispProperty
,
null
,
R
equestCert
,
typeValue
);
typeRequestCert
.
InvokeMember
(
"SignerCertificate"
,
BindingFlags
.
PutDispProperty
,
null
,
r
equestCert
,
typeValue
);
}
}
else
else
{
{
...
@@ -220,24 +220,24 @@ namespace Titanium.Web.Proxy.Network.Certificate
...
@@ -220,24 +220,24 @@ namespace Titanium.Web.Proxy.Network.Certificate
typeX509Extensions
.
InvokeMember
(
"Add"
,
BindingFlags
.
InvokeMethod
,
null
,
certificate
,
typeValue
);
typeX509Extensions
.
InvokeMember
(
"Add"
,
BindingFlags
.
InvokeMethod
,
null
,
certificate
,
typeValue
);
}
}
OID
=
Activator
.
CreateInstance
(
typeOID
);
oid
=
Activator
.
CreateInstance
(
typeOID
);
typeValue
=
new
object
[]
{
1
,
0
,
0
,
hashAlg
};
typeValue
=
new
object
[]
{
1
,
0
,
0
,
hashAlg
};
typeOID
.
InvokeMember
(
"InitializeFromAlgorithmName"
,
BindingFlags
.
InvokeMethod
,
null
,
OID
,
typeValue
);
typeOID
.
InvokeMember
(
"InitializeFromAlgorithmName"
,
BindingFlags
.
InvokeMethod
,
null
,
oid
,
typeValue
);
typeValue
=
new
[]
{
OID
};
typeValue
=
new
[]
{
oid
};
typeRequestCert
.
InvokeMember
(
"HashAlgorithm"
,
BindingFlags
.
PutDispProperty
,
null
,
R
equestCert
,
typeValue
);
typeRequestCert
.
InvokeMember
(
"HashAlgorithm"
,
BindingFlags
.
PutDispProperty
,
null
,
r
equestCert
,
typeValue
);
typeRequestCert
.
InvokeMember
(
"Encode"
,
BindingFlags
.
InvokeMethod
,
null
,
R
equestCert
,
null
);
typeRequestCert
.
InvokeMember
(
"Encode"
,
BindingFlags
.
InvokeMethod
,
null
,
r
equestCert
,
null
);
var
X
509Enrollment
=
Activator
.
CreateInstance
(
typeX509Enrollment
);
var
x
509Enrollment
=
Activator
.
CreateInstance
(
typeX509Enrollment
);
typeValue
[
0
]
=
R
equestCert
;
typeValue
[
0
]
=
r
equestCert
;
typeX509Enrollment
.
InvokeMember
(
"InitializeFromRequest"
,
BindingFlags
.
InvokeMethod
,
null
,
X
509Enrollment
,
typeValue
);
typeX509Enrollment
.
InvokeMember
(
"InitializeFromRequest"
,
BindingFlags
.
InvokeMethod
,
null
,
x
509Enrollment
,
typeValue
);
if
(
isRoot
)
if
(
isRoot
)
{
{
typeValue
[
0
]
=
fullSubject
;
typeValue
[
0
]
=
fullSubject
;
typeX509Enrollment
.
InvokeMember
(
"CertificateFriendlyName"
,
BindingFlags
.
PutDispProperty
,
null
,
X
509Enrollment
,
typeValue
);
typeX509Enrollment
.
InvokeMember
(
"CertificateFriendlyName"
,
BindingFlags
.
PutDispProperty
,
null
,
x
509Enrollment
,
typeValue
);
}
}
...
@@ -245,15 +245,15 @@ namespace Titanium.Web.Proxy.Network.Certificate
...
@@ -245,15 +245,15 @@ namespace Titanium.Web.Proxy.Network.Certificate
typeValue
[
0
]
=
0
;
typeValue
[
0
]
=
0
;
var
createCertRequest
=
typeX509Enrollment
.
InvokeMember
(
"CreateRequest"
,
BindingFlags
.
InvokeMethod
,
null
,
X
509Enrollment
,
typeValue
);
var
createCertRequest
=
typeX509Enrollment
.
InvokeMember
(
"CreateRequest"
,
BindingFlags
.
InvokeMethod
,
null
,
x
509Enrollment
,
typeValue
);
typeValue
=
new
[]
{
2
,
createCertRequest
,
0
,
string
.
Empty
};
typeValue
=
new
[]
{
2
,
createCertRequest
,
0
,
string
.
Empty
};
typeX509Enrollment
.
InvokeMember
(
"InstallResponse"
,
BindingFlags
.
InvokeMethod
,
null
,
X
509Enrollment
,
typeValue
);
typeX509Enrollment
.
InvokeMember
(
"InstallResponse"
,
BindingFlags
.
InvokeMethod
,
null
,
x
509Enrollment
,
typeValue
);
typeValue
=
new
object
[]
{
null
,
0
,
1
};
typeValue
=
new
object
[]
{
null
,
0
,
1
};
try
try
{
{
var
empty
=
(
string
)
typeX509Enrollment
.
InvokeMember
(
"CreatePFX"
,
BindingFlags
.
InvokeMethod
,
null
,
X
509Enrollment
,
typeValue
);
var
empty
=
(
string
)
typeX509Enrollment
.
InvokeMember
(
"CreatePFX"
,
BindingFlags
.
InvokeMethod
,
null
,
x
509Enrollment
,
typeValue
);
return
new
X509Certificate2
(
Convert
.
FromBase64String
(
empty
),
string
.
Empty
,
X509KeyStorageFlags
.
Exportable
);
return
new
X509Certificate2
(
Convert
.
FromBase64String
(
empty
),
string
.
Empty
,
X509KeyStorageFlags
.
Exportable
);
}
}
catch
(
Exception
)
catch
(
Exception
)
...
...
Titanium.Web.Proxy/Network/CertificateManager.cs
View file @
a0a6e678
...
@@ -31,6 +31,10 @@ namespace Titanium.Web.Proxy.Network
...
@@ -31,6 +31,10 @@ namespace Titanium.Web.Proxy.Network
/// </summary>
/// </summary>
internal
class
CertificateManager
:
IDisposable
internal
class
CertificateManager
:
IDisposable
{
{
private
const
string
DefaultRootCertificateIssuer
=
"Titanium"
;
private
const
string
DefaultRootRootCertificateName
=
"Titanium Root Certificate Authority"
;
private
readonly
ICertificateMaker
certEngine
;
private
readonly
ICertificateMaker
certEngine
;
private
bool
clearCertificates
{
get
;
set
;
}
private
bool
clearCertificates
{
get
;
set
;
}
...
@@ -66,8 +70,8 @@ namespace Titanium.Web.Proxy.Network
...
@@ -66,8 +70,8 @@ namespace Titanium.Web.Proxy.Network
certEngine
=
new
WinCertificateMaker
();
certEngine
=
new
WinCertificateMaker
();
}
}
Issuer
=
issuer
;
Issuer
=
issuer
??
DefaultRootCertificateIssuer
;
RootCertificateName
=
rootCertificateName
;
RootCertificateName
=
rootCertificateName
??
DefaultRootRootCertificateName
;
certificateCache
=
new
ConcurrentDictionary
<
string
,
CachedCertificate
>();
certificateCache
=
new
ConcurrentDictionary
<
string
,
CachedCertificate
>();
}
}
...
@@ -88,7 +92,7 @@ namespace Titanium.Web.Proxy.Network
...
@@ -88,7 +92,7 @@ namespace Titanium.Web.Proxy.Network
return
fileName
;
return
fileName
;
}
}
internal
X509Certificate2
Get
RootCertificate
()
internal
X509Certificate2
Load
RootCertificate
()
{
{
var
fileName
=
GetRootCertificatePath
();
var
fileName
=
GetRootCertificatePath
();
if
(!
File
.
Exists
(
fileName
))
return
null
;
if
(!
File
.
Exists
(
fileName
))
return
null
;
...
@@ -108,11 +112,16 @@ namespace Titanium.Web.Proxy.Network
...
@@ -108,11 +112,16 @@ namespace Titanium.Web.Proxy.Network
/// <returns>true if succeeded, else false</returns>
/// <returns>true if succeeded, else false</returns>
internal
bool
CreateTrustedRootCertificate
()
internal
bool
CreateTrustedRootCertificate
()
{
{
RootCertificate
=
GetRootCertificate
();
if
(
RootCertificate
==
null
)
{
RootCertificate
=
LoadRootCertificate
();
}
if
(
RootCertificate
!=
null
)
if
(
RootCertificate
!=
null
)
{
{
return
true
;
return
true
;
}
}
try
try
{
{
RootCertificate
=
CreateCertificate
(
RootCertificateName
,
true
);
RootCertificate
=
CreateCertificate
(
RootCertificateName
,
true
);
...
@@ -121,6 +130,7 @@ namespace Titanium.Web.Proxy.Network
...
@@ -121,6 +130,7 @@ namespace Titanium.Web.Proxy.Network
{
{
exceptionFunc
(
e
);
exceptionFunc
(
e
);
}
}
if
(
RootCertificate
!=
null
)
if
(
RootCertificate
!=
null
)
{
{
try
try
...
@@ -133,9 +143,23 @@ namespace Titanium.Web.Proxy.Network
...
@@ -133,9 +143,23 @@ namespace Titanium.Web.Proxy.Network
exceptionFunc
(
e
);
exceptionFunc
(
e
);
}
}
}
}
return
RootCertificate
!=
null
;
return
RootCertificate
!=
null
;
}
}
/// <summary>
/// Trusts the root certificate.
/// </summary>
/// <param name="exceptionFunc"></param>
internal
void
TrustRootCertificate
(
Action
<
Exception
>
exceptionFunc
)
{
//current user
TrustRootCertificate
(
StoreLocation
.
CurrentUser
,
exceptionFunc
);
//current system
TrustRootCertificate
(
StoreLocation
.
LocalMachine
,
exceptionFunc
);
}
/// <summary>
/// <summary>
/// Create an SSL certificate
/// Create an SSL certificate
/// </summary>
/// </summary>
...
@@ -144,7 +168,6 @@ namespace Titanium.Web.Proxy.Network
...
@@ -144,7 +168,6 @@ namespace Titanium.Web.Proxy.Network
/// <returns></returns>
/// <returns></returns>
internal
virtual
X509Certificate2
CreateCertificate
(
string
certificateName
,
bool
isRootCertificate
)
internal
virtual
X509Certificate2
CreateCertificate
(
string
certificateName
,
bool
isRootCertificate
)
{
{
if
(
certificateCache
.
ContainsKey
(
certificateName
))
if
(
certificateCache
.
ContainsKey
(
certificateName
))
{
{
var
cached
=
certificateCache
[
certificateName
];
var
cached
=
certificateCache
[
certificateName
];
...
@@ -152,7 +175,6 @@ namespace Titanium.Web.Proxy.Network
...
@@ -152,7 +175,6 @@ namespace Titanium.Web.Proxy.Network
return
cached
.
Certificate
;
return
cached
.
Certificate
;
}
}
X509Certificate2
certificate
=
null
;
X509Certificate2
certificate
=
null
;
lock
(
string
.
Intern
(
certificateName
))
lock
(
string
.
Intern
(
certificateName
))
{
{
...
@@ -160,6 +182,11 @@ namespace Titanium.Web.Proxy.Network
...
@@ -160,6 +182,11 @@ namespace Titanium.Web.Proxy.Network
{
{
try
try
{
{
if
(!
isRootCertificate
&&
RootCertificate
==
null
)
{
CreateTrustedRootCertificate
();
}
certificate
=
certEngine
.
MakeCertificate
(
certificateName
,
isRootCertificate
,
RootCertificate
);
certificate
=
certEngine
.
MakeCertificate
(
certificateName
,
isRootCertificate
,
RootCertificate
);
}
}
catch
(
Exception
e
)
catch
(
Exception
e
)
...
@@ -168,7 +195,7 @@ namespace Titanium.Web.Proxy.Network
...
@@ -168,7 +195,7 @@ namespace Titanium.Web.Proxy.Network
}
}
if
(
certificate
!=
null
&&
!
certificateCache
.
ContainsKey
(
certificateName
))
if
(
certificate
!=
null
&&
!
certificateCache
.
ContainsKey
(
certificateName
))
{
{
certificateCache
.
Add
(
certificateName
,
new
CachedCertificate
()
{
Certificate
=
certificate
});
certificateCache
.
Add
(
certificateName
,
new
CachedCertificate
{
Certificate
=
certificate
});
}
}
}
}
else
else
...
@@ -182,10 +209,7 @@ namespace Titanium.Web.Proxy.Network
...
@@ -182,10 +209,7 @@ namespace Titanium.Web.Proxy.Network
}
}
}
}
return
certificate
;
return
certificate
;
}
}
/// <summary>
/// <summary>
...
...
Titanium.Web.Proxy/ProxyServer.cs
View file @
a0a6e678
...
@@ -19,11 +19,10 @@ namespace Titanium.Web.Proxy
...
@@ -19,11 +19,10 @@ namespace Titanium.Web.Proxy
/// </summary>
/// </summary>
public
partial
class
ProxyServer
:
IDisposable
public
partial
class
ProxyServer
:
IDisposable
{
{
/// <summary>
/// <summary>
/// Is the root certificate used by this proxy is valid?
/// Is the root certificate used by this proxy is valid?
/// </summary>
/// </summary>
private
bool
certValidated
{
get
;
set
;
}
private
bool
?
certValidated
{
get
;
set
;
}
/// <summary>
/// <summary>
/// Is the proxy currently running
/// Is the proxy currently running
...
@@ -45,6 +44,8 @@ namespace Titanium.Web.Proxy
...
@@ -45,6 +44,8 @@ namespace Titanium.Web.Proxy
/// </summary>
/// </summary>
private
Action
<
Exception
>
exceptionFunc
;
private
Action
<
Exception
>
exceptionFunc
;
private
bool
trustRootCertificate
;
/// <summary>
/// <summary>
/// A object that creates tcp connection to server
/// A object that creates tcp connection to server
/// </summary>
/// </summary>
...
@@ -66,12 +67,29 @@ namespace Titanium.Web.Proxy
...
@@ -66,12 +67,29 @@ namespace Titanium.Web.Proxy
/// <summary>
/// <summary>
/// Buffer size used throughout this proxy
/// Buffer size used throughout this proxy
/// </summary>
/// </summary>
public
int
BUFFER_SIZE
{
get
;
set
;
}
=
8192
;
public
int
BufferSize
{
get
;
set
;
}
=
8192
;
/// <summary>
/// The root certificate
/// </summary>
public
X509Certificate2
RootCertificate
{
get
{
return
certificateCacheManager
.
RootCertificate
;
}
set
{
certificateCacheManager
.
RootCertificate
=
value
;
}
}
/// <summary>
/// <summary>
/// Name of the root certificate issuer
/// Name of the root certificate issuer
/// </summary>
/// </summary>
public
string
RootCertificateIssuerName
{
get
;
set
;
}
public
string
RootCertificateIssuerName
{
get
{
return
certificateCacheManager
.
Issuer
;
}
set
{
CreateCertificateCacheManager
(
certificateCacheManager
.
RootCertificateName
,
value
);
certValidated
=
null
;
}
}
/// <summary>
/// <summary>
/// Name of the root certificate
/// Name of the root certificate
...
@@ -79,14 +97,33 @@ namespace Titanium.Web.Proxy
...
@@ -79,14 +97,33 @@ namespace Titanium.Web.Proxy
/// The provided root certificate has to be in the proxy exe directory with the private key
/// The provided root certificate has to be in the proxy exe directory with the private key
/// The root certificate file should be named as "rootCert.pfx"
/// The root certificate file should be named as "rootCert.pfx"
/// </summary>
/// </summary>
public
string
RootCertificateName
{
get
;
set
;
}
public
string
RootCertificateName
{
get
{
return
certificateCacheManager
.
RootCertificateName
;
}
set
{
CreateCertificateCacheManager
(
value
,
certificateCacheManager
.
Issuer
);
certValidated
=
null
;
}
}
/// <summary>
/// <summary>
/// Trust the RootCertificate used by this proxy server
/// Trust the RootCertificate used by this proxy server
/// Note that this do not make the client trust the certificate!
/// Note that this do not make the client trust the certificate!
/// This would import the root certificate to the certificate store of machine that runs this proxy server
/// This would import the root certificate to the certificate store of machine that runs this proxy server
/// </summary>
/// </summary>
public
bool
TrustRootCertificate
{
get
;
set
;
}
public
bool
TrustRootCertificate
{
get
{
return
trustRootCertificate
;
}
set
{
trustRootCertificate
=
value
;
if
(
value
)
{
EnsureRootCertificate
();
}
}
}
/// <summary>
/// <summary>
/// Select Certificate Engine
/// Select Certificate Engine
...
@@ -211,7 +248,9 @@ namespace Titanium.Web.Proxy
...
@@ -211,7 +248,9 @@ namespace Titanium.Web.Proxy
/// <summary>
/// <summary>
/// Constructor
/// Constructor
/// </summary>
/// </summary>
public
ProxyServer
()
:
this
(
null
,
null
)
{
}
public
ProxyServer
()
:
this
(
null
,
null
)
{
}
/// <summary>
/// <summary>
/// Constructor.
/// Constructor.
...
@@ -220,9 +259,6 @@ namespace Titanium.Web.Proxy
...
@@ -220,9 +259,6 @@ namespace Titanium.Web.Proxy
/// <param name="rootCertificateIssuerName">Name of root certificate issuer.</param>
/// <param name="rootCertificateIssuerName">Name of root certificate issuer.</param>
public
ProxyServer
(
string
rootCertificateName
,
string
rootCertificateIssuerName
)
public
ProxyServer
(
string
rootCertificateName
,
string
rootCertificateIssuerName
)
{
{
RootCertificateName
=
rootCertificateName
;
RootCertificateIssuerName
=
rootCertificateIssuerName
;
//default values
//default values
ConnectionTimeOutSeconds
=
120
;
ConnectionTimeOutSeconds
=
120
;
CertificateCacheTimeOutMinutes
=
60
;
CertificateCacheTimeOutMinutes
=
60
;
...
@@ -233,8 +269,8 @@ namespace Titanium.Web.Proxy
...
@@ -233,8 +269,8 @@ namespace Titanium.Web.Proxy
#if !DEBUG
#if !DEBUG
new
FireFoxProxySettingsManager
();
new
FireFoxProxySettingsManager
();
#endif
#endif
RootCertificateName
=
RootCertificateName
??
"Titanium Root Certificate Authority"
;
RootCertificateIssuerName
=
RootCertificateIssuerName
??
"Titanium"
;
CreateCertificateCacheManager
(
rootCertificateName
,
rootCertificateIssuerName
)
;
}
}
/// <summary>
/// <summary>
...
@@ -328,8 +364,10 @@ namespace Titanium.Web.Proxy
...
@@ -328,8 +364,10 @@ namespace Titanium.Web.Proxy
.
ToList
()
.
ToList
()
.
ForEach
(
x
=>
x
.
IsSystemHttpsProxy
=
false
);
.
ForEach
(
x
=>
x
.
IsSystemHttpsProxy
=
false
);
EnsureRootCertificate
();
//If certificate was trusted by the machine
//If certificate was trusted by the machine
if
(
certValidated
)
if
(
certValidated
==
true
)
{
{
systemProxySettingsManager
.
SetHttpsProxy
(
systemProxySettingsManager
.
SetHttpsProxy
(
Equals
(
endPoint
.
IpAddress
,
IPAddress
.
Any
)
|
Equals
(
endPoint
.
IpAddress
,
IPAddress
.
Any
)
|
...
@@ -397,23 +435,6 @@ namespace Titanium.Web.Proxy
...
@@ -397,23 +435,6 @@ namespace Titanium.Web.Proxy
throw
new
Exception
(
"Proxy is already running."
);
throw
new
Exception
(
"Proxy is already running."
);
}
}
certificateCacheManager
=
new
CertificateManager
(
CertificateEngine
,
RootCertificateIssuerName
,
RootCertificateName
,
ExceptionFunc
);
certValidated
=
certificateCacheManager
.
CreateTrustedRootCertificate
();
if
(
TrustRootCertificate
)
{
//current user
certificateCacheManager
.
TrustRootCertificate
(
StoreLocation
.
CurrentUser
,
ExceptionFunc
);
//current system
certificateCacheManager
.
TrustRootCertificate
(
StoreLocation
.
LocalMachine
,
ExceptionFunc
);
}
if
(
ForwardToUpstreamGateway
&&
GetCustomUpStreamHttpProxyFunc
==
null
if
(
ForwardToUpstreamGateway
&&
GetCustomUpStreamHttpProxyFunc
==
null
&&
GetCustomUpStreamHttpsProxyFunc
==
null
)
&&
GetCustomUpStreamHttpsProxyFunc
==
null
)
{
{
...
@@ -431,6 +452,25 @@ namespace Titanium.Web.Proxy
...
@@ -431,6 +452,25 @@ namespace Titanium.Web.Proxy
proxyRunning
=
true
;
proxyRunning
=
true
;
}
}
private
void
CreateCertificateCacheManager
(
string
rootCertificateName
,
string
rootCertificateIssuerName
)
{
certificateCacheManager
=
new
CertificateManager
(
CertificateEngine
,
rootCertificateIssuerName
,
rootCertificateName
,
ExceptionFunc
);
}
private
void
EnsureRootCertificate
()
{
if
(!
certValidated
.
HasValue
)
{
certValidated
=
certificateCacheManager
.
CreateTrustedRootCertificate
();
if
(
TrustRootCertificate
)
{
certificateCacheManager
.
TrustRootCertificate
(
ExceptionFunc
);
}
}
}
/// <summary>
/// <summary>
/// Gets the system up stream proxy.
/// Gets the system up stream proxy.
/// </summary>
/// </summary>
...
...
Titanium.Web.Proxy/RequestHandler.cs
View file @
a0a6e678
...
@@ -147,7 +147,7 @@ namespace Titanium.Web.Proxy
...
@@ -147,7 +147,7 @@ namespace Titanium.Web.Proxy
//write back successfull CONNECT response
//write back successfull CONNECT response
await
WriteConnectResponse
(
clientStreamWriter
,
version
);
await
WriteConnectResponse
(
clientStreamWriter
,
version
);
await
TcpHelper
.
SendRaw
(
B
UFFER_SIZE
,
ConnectionTimeOutSeconds
,
httpRemoteUri
.
Host
,
httpRemoteUri
.
Port
,
await
TcpHelper
.
SendRaw
(
B
ufferSize
,
ConnectionTimeOutSeconds
,
httpRemoteUri
.
Host
,
httpRemoteUri
.
Port
,
null
,
version
,
null
,
null
,
version
,
null
,
false
,
SupportedSslProtocols
,
false
,
SupportedSslProtocols
,
ValidateServerCertificate
,
ValidateServerCertificate
,
...
@@ -245,7 +245,7 @@ namespace Titanium.Web.Proxy
...
@@ -245,7 +245,7 @@ namespace Titanium.Web.Proxy
args
.
CustomUpStreamHttpProxyUsed
=
customUpStreamHttpProxy
;
args
.
CustomUpStreamHttpProxyUsed
=
customUpStreamHttpProxy
;
args
.
CustomUpStreamHttpsProxyUsed
=
customUpStreamHttpsProxy
;
args
.
CustomUpStreamHttpsProxyUsed
=
customUpStreamHttpsProxy
;
connection
=
await
tcpConnectionFactory
.
CreateClient
(
B
UFFER_SIZE
,
ConnectionTimeOutSeconds
,
connection
=
await
tcpConnectionFactory
.
CreateClient
(
B
ufferSize
,
ConnectionTimeOutSeconds
,
args
.
WebSession
.
Request
.
RequestUri
.
Host
,
args
.
WebSession
.
Request
.
RequestUri
.
Port
,
args
.
WebSession
.
Request
.
HttpVersion
,
args
.
WebSession
.
Request
.
RequestUri
.
Host
,
args
.
WebSession
.
Request
.
RequestUri
.
Port
,
args
.
WebSession
.
Request
.
HttpVersion
,
args
.
IsHttps
,
SupportedSslProtocols
,
args
.
IsHttps
,
SupportedSslProtocols
,
ValidateServerCertificate
,
ValidateServerCertificate
,
...
@@ -378,7 +378,7 @@ namespace Titanium.Web.Proxy
...
@@ -378,7 +378,7 @@ namespace Titanium.Web.Proxy
}
}
var
args
=
var
args
=
new
SessionEventArgs
(
B
UFFER_SIZE
,
HandleHttpSessionResponse
)
new
SessionEventArgs
(
B
ufferSize
,
HandleHttpSessionResponse
)
{
{
ProxyClient
=
{
TcpClient
=
client
},
ProxyClient
=
{
TcpClient
=
client
},
WebSession
=
{
ConnectHeaders
=
connectHeaders
}
WebSession
=
{
ConnectHeaders
=
connectHeaders
}
...
@@ -487,7 +487,7 @@ namespace Titanium.Web.Proxy
...
@@ -487,7 +487,7 @@ namespace Titanium.Web.Proxy
//if upgrading to websocket then relay the requet without reading the contents
//if upgrading to websocket then relay the requet without reading the contents
if
(
args
.
WebSession
.
Request
.
UpgradeToWebSocket
)
if
(
args
.
WebSession
.
Request
.
UpgradeToWebSocket
)
{
{
await
TcpHelper
.
SendRaw
(
B
UFFER_SIZE
,
ConnectionTimeOutSeconds
,
httpRemoteUri
.
Host
,
httpRemoteUri
.
Port
,
await
TcpHelper
.
SendRaw
(
B
ufferSize
,
ConnectionTimeOutSeconds
,
httpRemoteUri
.
Host
,
httpRemoteUri
.
Port
,
httpCmd
,
httpVersion
,
args
.
WebSession
.
Request
.
RequestHeaders
,
args
.
IsHttps
,
httpCmd
,
httpVersion
,
args
.
WebSession
.
Request
.
RequestHeaders
,
args
.
IsHttps
,
SupportedSslProtocols
,
ValidateServerCertificate
,
SupportedSslProtocols
,
ValidateServerCertificate
,
SelectClientCertificate
,
SelectClientCertificate
,
...
@@ -581,14 +581,14 @@ namespace Titanium.Web.Proxy
...
@@ -581,14 +581,14 @@ namespace Titanium.Web.Proxy
//send the request body bytes to server
//send the request body bytes to server
if
(
args
.
WebSession
.
Request
.
ContentLength
>
0
)
if
(
args
.
WebSession
.
Request
.
ContentLength
>
0
)
{
{
await
args
.
ProxyClient
.
ClientStreamReader
.
CopyBytesToStream
(
B
UFFER_SIZE
,
postStream
,
args
.
WebSession
.
Request
.
ContentLength
);
await
args
.
ProxyClient
.
ClientStreamReader
.
CopyBytesToStream
(
B
ufferSize
,
postStream
,
args
.
WebSession
.
Request
.
ContentLength
);
}
}
//Need to revist, find any potential bugs
//Need to revist, find any potential bugs
//send the request body bytes to server in chunks
//send the request body bytes to server in chunks
else
if
(
args
.
WebSession
.
Request
.
IsChunked
)
else
if
(
args
.
WebSession
.
Request
.
IsChunked
)
{
{
await
args
.
ProxyClient
.
ClientStreamReader
.
CopyBytesToStreamChunked
(
B
UFFER_SIZE
,
postStream
);
await
args
.
ProxyClient
.
ClientStreamReader
.
CopyBytesToStreamChunked
(
B
ufferSize
,
postStream
);
}
}
}
}
}
}
...
...
Titanium.Web.Proxy/ResponseHandler.cs
View file @
a0a6e678
...
@@ -108,7 +108,7 @@ namespace Titanium.Web.Proxy
...
@@ -108,7 +108,7 @@ namespace Titanium.Web.Proxy
||
!
args
.
WebSession
.
Response
.
ResponseKeepAlive
)
||
!
args
.
WebSession
.
Response
.
ResponseKeepAlive
)
{
{
await
args
.
WebSession
.
ServerConnection
.
StreamReader
await
args
.
WebSession
.
ServerConnection
.
StreamReader
.
WriteResponseBody
(
B
UFFER_SIZE
,
args
.
ProxyClient
.
ClientStream
,
args
.
WebSession
.
Response
.
IsChunked
,
.
WriteResponseBody
(
B
ufferSize
,
args
.
ProxyClient
.
ClientStream
,
args
.
WebSession
.
Response
.
IsChunked
,
args
.
WebSession
.
Response
.
ContentLength
);
args
.
WebSession
.
Response
.
ContentLength
);
}
}
//write response if connection:keep-alive header exist and when version is http/1.0
//write response if connection:keep-alive header exist and when version is http/1.0
...
@@ -116,7 +116,7 @@ namespace Titanium.Web.Proxy
...
@@ -116,7 +116,7 @@ namespace Titanium.Web.Proxy
else
if
(
args
.
WebSession
.
Response
.
ResponseKeepAlive
&&
args
.
WebSession
.
Response
.
HttpVersion
.
Minor
==
0
)
else
if
(
args
.
WebSession
.
Response
.
ResponseKeepAlive
&&
args
.
WebSession
.
Response
.
HttpVersion
.
Minor
==
0
)
{
{
await
args
.
WebSession
.
ServerConnection
.
StreamReader
await
args
.
WebSession
.
ServerConnection
.
StreamReader
.
WriteResponseBody
(
B
UFFER_SIZE
,
args
.
ProxyClient
.
ClientStream
,
args
.
WebSession
.
Response
.
IsChunked
,
.
WriteResponseBody
(
B
ufferSize
,
args
.
ProxyClient
.
ClientStream
,
args
.
WebSession
.
Response
.
IsChunked
,
args
.
WebSession
.
Response
.
ContentLength
);
args
.
WebSession
.
Response
.
ContentLength
);
}
}
}
}
...
...
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