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
51e83bae
Unverified
Commit
51e83bae
authored
Nov 26, 2019
by
honfika
Committed by
GitHub
Nov 26, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #683 from justcoding121/master
beta
parents
35a48908
abf159fc
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
65 additions
and
41 deletions
+65
-41
SessionEventArgs.cs
src/Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
+0
-2
ExplicitClientHandler.cs
src/Titanium.Web.Proxy/ExplicitClientHandler.cs
+9
-9
HttpClientStream.cs
src/Titanium.Web.Proxy/Helpers/HttpClientStream.cs
+14
-0
RequestStatusInfo.cs
src/Titanium.Web.Proxy/Helpers/RequestStatusInfo.cs
+19
-0
TcpHelper.cs
src/Titanium.Web.Proxy/Helpers/TcpHelper.cs
+2
-5
Request.cs
src/Titanium.Web.Proxy/Http/Request.cs
+6
-6
RequestResponseBase.cs
src/Titanium.Web.Proxy/Http/RequestResponseBase.cs
+1
-1
BCCertificateMaker.cs
...anium.Web.Proxy/Network/Certificate/BCCertificateMaker.cs
+1
-4
RequestHandler.cs
src/Titanium.Web.Proxy/RequestHandler.cs
+7
-9
SslTools.cs
src/Titanium.Web.Proxy/StreamExtended/SslTools.cs
+3
-3
TransparentClientHandler.cs
src/Titanium.Web.Proxy/TransparentClientHandler.cs
+3
-2
No files found.
src/Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
View file @
51e83bae
...
@@ -4,12 +4,10 @@ using System.IO;
...
@@ -4,12 +4,10 @@ using System.IO;
using
System.Net
;
using
System.Net
;
using
System.Threading
;
using
System.Threading
;
using
System.Threading.Tasks
;
using
System.Threading.Tasks
;
using
Titanium.Web.Proxy.Compression
;
using
Titanium.Web.Proxy.Helpers
;
using
Titanium.Web.Proxy.Helpers
;
using
Titanium.Web.Proxy.Http
;
using
Titanium.Web.Proxy.Http
;
using
Titanium.Web.Proxy.Http.Responses
;
using
Titanium.Web.Proxy.Http.Responses
;
using
Titanium.Web.Proxy.Models
;
using
Titanium.Web.Proxy.Models
;
using
Titanium.Web.Proxy.Network
;
using
Titanium.Web.Proxy.Network.Tcp
;
using
Titanium.Web.Proxy.Network.Tcp
;
using
Titanium.Web.Proxy.StreamExtended.Network
;
using
Titanium.Web.Proxy.StreamExtended.Network
;
...
...
src/Titanium.Web.Proxy/ExplicitClientHandler.cs
View file @
51e83bae
...
@@ -52,18 +52,16 @@ namespace Titanium.Web.Proxy
...
@@ -52,18 +52,16 @@ namespace Titanium.Web.Proxy
if
(
await
HttpHelper
.
IsConnectMethod
(
clientStream
,
BufferPool
,
cancellationToken
)
==
1
)
if
(
await
HttpHelper
.
IsConnectMethod
(
clientStream
,
BufferPool
,
cancellationToken
)
==
1
)
{
{
// read the first line HTTP command
// read the first line HTTP command
string
?
httpCmd
=
await
clientStream
.
ReadLineAsync
(
cancellationToken
);
var
requestLine
=
await
clientStream
.
ReadRequestLine
(
cancellationToken
);
if
(
string
.
IsNullOrEmpty
(
httpCmd
))
if
(
requestLine
.
IsEmpty
(
))
{
{
return
;
return
;
}
}
Request
.
ParseRequestLine
(
httpCmd
!,
out
string
_
,
out
var
httpUrl
,
out
var
version
);
var
connectRequest
=
new
ConnectRequest
(
requestLine
.
RequestUri
.
GetString
())
var
connectRequest
=
new
ConnectRequest
(
httpUrl
.
GetString
())
{
{
RequestUriString8
=
httpUrl
,
RequestUriString8
=
requestLine
.
RequestUri
,
HttpVersion
=
v
ersion
HttpVersion
=
requestLine
.
V
ersion
};
};
await
HeaderParser
.
ReadHeaders
(
clientStream
,
connectRequest
.
Headers
,
cancellationToken
);
await
HeaderParser
.
ReadHeaders
(
clientStream
,
connectRequest
.
Headers
,
cancellationToken
);
...
@@ -105,7 +103,7 @@ namespace Titanium.Web.Proxy
...
@@ -105,7 +103,7 @@ namespace Titanium.Web.Proxy
}
}
// write back successful CONNECT response
// write back successful CONNECT response
var
response
=
ConnectResponse
.
CreateSuccessfulConnectResponse
(
v
ersion
);
var
response
=
ConnectResponse
.
CreateSuccessfulConnectResponse
(
requestLine
.
V
ersion
);
// Set ContentLength explicitly to properly handle HTTP 1.0
// Set ContentLength explicitly to properly handle HTTP 1.0
response
.
ContentLength
=
0
;
response
.
ContentLength
=
0
;
...
@@ -175,7 +173,7 @@ namespace Titanium.Web.Proxy
...
@@ -175,7 +173,7 @@ namespace Titanium.Web.Proxy
}
}
}
}
string
connectHostname
=
httpUrl
.
GetString
();
string
connectHostname
=
requestLine
.
RequestUri
.
GetString
();
int
idx
=
connectHostname
.
IndexOf
(
":"
);
int
idx
=
connectHostname
.
IndexOf
(
":"
);
if
(
idx
>=
0
)
if
(
idx
>=
0
)
{
{
...
@@ -214,6 +212,8 @@ namespace Titanium.Web.Proxy
...
@@ -214,6 +212,8 @@ namespace Titanium.Web.Proxy
// HTTPS server created - we can now decrypt the client's traffic
// HTTPS server created - we can now decrypt the client's traffic
clientStream
=
new
HttpClientStream
(
sslStream
,
BufferPool
);
clientStream
=
new
HttpClientStream
(
sslStream
,
BufferPool
);
sslStream
=
null
;
// clientStream was created, no need to keep SSL stream reference
clientStream
.
DataRead
+=
(
o
,
args
)
=>
connectArgs
.
OnDecryptedDataSent
(
args
.
Buffer
,
args
.
Offset
,
args
.
Count
);
clientStream
.
DataRead
+=
(
o
,
args
)
=>
connectArgs
.
OnDecryptedDataSent
(
args
.
Buffer
,
args
.
Offset
,
args
.
Count
);
clientStream
.
DataWrite
+=
(
o
,
args
)
=>
connectArgs
.
OnDecryptedDataReceived
(
args
.
Buffer
,
args
.
Offset
,
args
.
Count
);
clientStream
.
DataWrite
+=
(
o
,
args
)
=>
connectArgs
.
OnDecryptedDataReceived
(
args
.
Buffer
,
args
.
Offset
,
args
.
Count
);
}
}
...
...
src/Titanium.Web.Proxy/Helpers/HttpClientStream.cs
View file @
51e83bae
...
@@ -29,5 +29,19 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -29,5 +29,19 @@ namespace Titanium.Web.Proxy.Helpers
await
WriteAsync
(
response
,
headerBuilder
,
cancellationToken
);
await
WriteAsync
(
response
,
headerBuilder
,
cancellationToken
);
}
}
internal
async
ValueTask
<
RequestStatusInfo
>
ReadRequestLine
(
CancellationToken
cancellationToken
=
default
)
{
// read the first line HTTP command
string
?
httpCmd
=
await
ReadLineAsync
(
cancellationToken
);
if
(
string
.
IsNullOrEmpty
(
httpCmd
))
{
return
default
;
}
Request
.
ParseRequestLine
(
httpCmd
!,
out
string
method
,
out
var
requestUri
,
out
var
version
);
return
new
RequestStatusInfo
{
Method
=
method
,
RequestUri
=
requestUri
,
Version
=
version
};
}
}
}
}
}
src/Titanium.Web.Proxy/Helpers/RequestStatusInfo.cs
0 → 100644
View file @
51e83bae
using
System
;
using
Titanium.Web.Proxy.Models
;
namespace
Titanium.Web.Proxy.Helpers
{
struct
RequestStatusInfo
{
public
string
Method
{
get
;
set
;
}
public
ByteString
RequestUri
{
get
;
set
;
}
public
Version
Version
{
get
;
set
;
}
public
bool
IsEmpty
()
{
return
Method
==
null
&&
RequestUri
.
Length
==
0
&&
Version
==
null
;
}
}
}
src/Titanium.Web.Proxy/Helpers/TcpHelper.cs
View file @
51e83bae
...
@@ -100,12 +100,10 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -100,12 +100,10 @@ namespace Titanium.Web.Proxy.Helpers
/// <param name="onDataSend"></param>
/// <param name="onDataSend"></param>
/// <param name="onDataReceive"></param>
/// <param name="onDataReceive"></param>
/// <param name="cancellationTokenSource"></param>
/// <param name="cancellationTokenSource"></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
)
{
{
// Now async relay all server=>client & client=>server data
// Now async relay all server=>client & client=>server data
var
sendRelay
=
var
sendRelay
=
...
@@ -139,8 +137,7 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -139,8 +137,7 @@ namespace Titanium.Web.Proxy.Helpers
{
{
// todo: fix APM mode
// todo: fix APM mode
return
sendRawTap
(
clientStream
,
serverStream
,
bufferPool
,
onDataSend
,
onDataReceive
,
return
sendRawTap
(
clientStream
,
serverStream
,
bufferPool
,
onDataSend
,
onDataReceive
,
cancellationTokenSource
,
cancellationTokenSource
);
exceptionFunc
);
}
}
}
}
}
}
src/Titanium.Web.Proxy/Http/Request.cs
View file @
51e83bae
...
@@ -254,7 +254,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -254,7 +254,7 @@ namespace Titanium.Web.Proxy.Http
}
}
}
}
internal
static
void
ParseRequestLine
(
string
httpCmd
,
out
string
httpMethod
,
out
ByteString
httpUrl
,
internal
static
void
ParseRequestLine
(
string
httpCmd
,
out
string
method
,
out
ByteString
requestUri
,
out
Version
version
)
out
Version
version
)
{
{
int
firstSpace
=
httpCmd
.
IndexOf
(
' '
);
int
firstSpace
=
httpCmd
.
IndexOf
(
' '
);
...
@@ -269,21 +269,21 @@ namespace Titanium.Web.Proxy.Http
...
@@ -269,21 +269,21 @@ namespace Titanium.Web.Proxy.Http
// break up the line into three components (method, remote URL & Http Version)
// break up the line into three components (method, remote URL & Http Version)
// Find the request Verb
// Find the request Verb
httpM
ethod
=
httpCmd
.
Substring
(
0
,
firstSpace
);
m
ethod
=
httpCmd
.
Substring
(
0
,
firstSpace
);
if
(!
isAllUpper
(
httpM
ethod
))
if
(!
isAllUpper
(
m
ethod
))
{
{
httpMethod
=
httpM
ethod
.
ToUpper
();
method
=
m
ethod
.
ToUpper
();
}
}
version
=
HttpHeader
.
Version11
;
version
=
HttpHeader
.
Version11
;
if
(
firstSpace
==
lastSpace
)
if
(
firstSpace
==
lastSpace
)
{
{
httpUrl
=
(
ByteString
)
httpCmd
.
AsSpan
(
firstSpace
+
1
).
ToString
();
requestUri
=
(
ByteString
)
httpCmd
.
AsSpan
(
firstSpace
+
1
).
ToString
();
}
}
else
else
{
{
httpUrl
=
(
ByteString
)
httpCmd
.
AsSpan
(
firstSpace
+
1
,
lastSpace
-
firstSpace
-
1
).
ToString
();
requestUri
=
(
ByteString
)
httpCmd
.
AsSpan
(
firstSpace
+
1
,
lastSpace
-
firstSpace
-
1
).
ToString
();
// parse the HTTP version
// parse the HTTP version
var
httpVersion
=
httpCmd
.
AsSpan
(
lastSpace
+
1
);
var
httpVersion
=
httpCmd
.
AsSpan
(
lastSpace
+
1
);
...
...
src/Titanium.Web.Proxy/Http/RequestResponseBase.cs
View file @
51e83bae
...
@@ -196,7 +196,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -196,7 +196,7 @@ namespace Titanium.Web.Proxy.Http
/// Use the encoding specified to decode the byte[] data to string
/// Use the encoding specified to decode the byte[] data to string
/// </summary>
/// </summary>
[
Browsable
(
false
)]
[
Browsable
(
false
)]
public
string
BodyString
=>
bodyString
??
(
bodyString
=
Encoding
.
GetString
(
Body
)
);
public
string
BodyString
=>
bodyString
??
=
Encoding
.
GetString
(
Body
);
/// <summary>
/// <summary>
/// Was the body read by user?
/// Was the body read by user?
...
...
src/Titanium.Web.Proxy/Network/Certificate/BCCertificateMaker.cs
View file @
51e83bae
using
System
;
using
System
;
using
System.IO
;
using
System.IO
;
using
System.Security.Cryptography.X509Certificates
;
using
System.Security.Cryptography.X509Certificates
;
using
System.Threading
;
using
Org.BouncyCastle.Asn1
;
using
Org.BouncyCastle.Asn1
;
using
Org.BouncyCastle.Asn1.Pkcs
;
using
Org.BouncyCastle.Asn1.Pkcs
;
using
Org.BouncyCastle.Asn1.X509
;
using
Org.BouncyCastle.Asn1.X509
;
...
@@ -219,11 +218,9 @@ namespace Titanium.Web.Proxy.Network.Certificate
...
@@ -219,11 +218,9 @@ namespace Titanium.Web.Proxy.Network.Certificate
/// <param name="subject">The s subject cn.</param>
/// <param name="subject">The s subject cn.</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>
/// <returns>X509Certificate2.</returns>
/// <returns>X509Certificate2.</returns>
private
X509Certificate2
makeCertificateInternal
(
string
subject
,
private
X509Certificate2
makeCertificateInternal
(
string
subject
,
bool
switchToMtaIfNeeded
,
X509Certificate2
?
signingCert
=
null
,
bool
switchToMtaIfNeeded
,
X509Certificate2
?
signingCert
=
null
)
CancellationToken
cancellationToken
=
default
)
{
{
return
makeCertificateInternal
(
subject
,
$"CN=
{
subject
}
"
,
return
makeCertificateInternal
(
subject
,
$"CN=
{
subject
}
"
,
DateTime
.
UtcNow
.
AddDays
(-
certificateGraceDays
),
DateTime
.
UtcNow
.
AddDays
(
certificateValidDays
),
DateTime
.
UtcNow
.
AddDays
(-
certificateGraceDays
),
DateTime
.
UtcNow
.
AddDays
(
certificateValidDays
),
...
...
src/Titanium.Web.Proxy/RequestHandler.cs
View file @
51e83bae
...
@@ -58,8 +58,8 @@ namespace Titanium.Web.Proxy
...
@@ -58,8 +58,8 @@ namespace Titanium.Web.Proxy
}
}
// read the request line
// read the request line
string
?
httpCmd
=
await
clientStream
.
ReadLineAsync
(
cancellationToken
);
var
requestLine
=
await
clientStream
.
ReadRequestLine
(
cancellationToken
);
if
(
string
.
IsNullOrEmpty
(
httpCmd
))
if
(
requestLine
.
IsEmpty
(
))
{
{
return
;
return
;
}
}
...
@@ -73,8 +73,6 @@ namespace Titanium.Web.Proxy
...
@@ -73,8 +73,6 @@ namespace Titanium.Web.Proxy
{
{
try
try
{
{
Request
.
ParseRequestLine
(
httpCmd
!,
out
string
httpMethod
,
out
ByteString
httpUrl
,
out
var
version
);
// Read the request headers in to unique and non-unique header collections
// Read the request headers in to unique and non-unique header collections
await
HeaderParser
.
ReadHeaders
(
clientStream
,
args
.
HttpClient
.
Request
.
Headers
,
await
HeaderParser
.
ReadHeaders
(
clientStream
,
args
.
HttpClient
.
Request
.
Headers
,
cancellationToken
);
cancellationToken
);
...
@@ -86,10 +84,10 @@ namespace Titanium.Web.Proxy
...
@@ -86,10 +84,10 @@ namespace Titanium.Web.Proxy
request
.
Authority
=
connectRequest
.
Authority
;
request
.
Authority
=
connectRequest
.
Authority
;
}
}
request
.
RequestUriString8
=
httpUrl
;
request
.
RequestUriString8
=
requestLine
.
RequestUri
;
request
.
Method
=
http
Method
;
request
.
Method
=
requestLine
.
Method
;
request
.
HttpVersion
=
v
ersion
;
request
.
HttpVersion
=
requestLine
.
V
ersion
;
if
(!
args
.
IsTransparent
)
if
(!
args
.
IsTransparent
)
{
{
...
@@ -293,13 +291,13 @@ namespace Titanium.Web.Proxy
...
@@ -293,13 +291,13 @@ namespace Titanium.Web.Proxy
}
}
// construct the web request that we are going to issue on behalf of the client.
// construct the web request that we are going to issue on behalf of the client.
await
handleHttpSessionRequest
(
connection
,
args
);
await
handleHttpSessionRequest
(
args
);
return
true
;
return
true
;
},
generator
,
serverConnection
);
},
generator
,
serverConnection
);
}
}
private
async
Task
handleHttpSessionRequest
(
TcpServerConnection
connection
,
SessionEventArgs
args
)
private
async
Task
handleHttpSessionRequest
(
SessionEventArgs
args
)
{
{
var
cancellationToken
=
args
.
CancellationTokenSource
.
Token
;
var
cancellationToken
=
args
.
CancellationTokenSource
.
Token
;
var
request
=
args
.
HttpClient
.
Request
;
var
request
=
args
.
HttpClient
.
Request
;
...
...
src/Titanium.Web.Proxy/StreamExtended/SslTools.cs
View file @
51e83bae
...
@@ -154,7 +154,7 @@ namespace Titanium.Web.Proxy.StreamExtended
...
@@ -154,7 +154,7 @@ namespace Titanium.Web.Proxy.StreamExtended
if
(
extensionsStartPosition
<
recordLength
+
5
)
if
(
extensionsStartPosition
<
recordLength
+
5
)
{
{
extensions
=
await
ReadExtensions
(
majorVersion
,
minorVersion
,
peekStream
,
bufferPool
,
cancellationToken
);
extensions
=
await
ReadExtensions
(
majorVersion
,
minorVersion
,
peekStream
,
cancellationToken
);
}
}
var
clientHelloInfo
=
new
ClientHelloInfo
(
3
,
majorVersion
,
minorVersion
,
random
,
sessionId
,
ciphers
,
peekStream
.
Position
)
var
clientHelloInfo
=
new
ClientHelloInfo
(
3
,
majorVersion
,
minorVersion
,
random
,
sessionId
,
ciphers
,
peekStream
.
Position
)
...
@@ -292,7 +292,7 @@ namespace Titanium.Web.Proxy.StreamExtended
...
@@ -292,7 +292,7 @@ namespace Titanium.Web.Proxy.StreamExtended
if
(
extensionsStartPosition
<
recordLength
+
5
)
if
(
extensionsStartPosition
<
recordLength
+
5
)
{
{
extensions
=
await
ReadExtensions
(
majorVersion
,
minorVersion
,
peekStream
,
bufferPool
,
cancellationToken
);
extensions
=
await
ReadExtensions
(
majorVersion
,
minorVersion
,
peekStream
,
cancellationToken
);
}
}
var
serverHelloInfo
=
new
ServerHelloInfo
(
3
,
majorVersion
,
minorVersion
,
random
,
sessionId
,
cipherSuite
,
peekStream
.
Position
)
var
serverHelloInfo
=
new
ServerHelloInfo
(
3
,
majorVersion
,
minorVersion
,
random
,
sessionId
,
cipherSuite
,
peekStream
.
Position
)
...
@@ -308,7 +308,7 @@ namespace Titanium.Web.Proxy.StreamExtended
...
@@ -308,7 +308,7 @@ namespace Titanium.Web.Proxy.StreamExtended
return
null
;
return
null
;
}
}
private
static
async
Task
<
Dictionary
<
string
,
SslExtension
>?>
ReadExtensions
(
int
majorVersion
,
int
minorVersion
,
PeekStreamReader
peekStreamReader
,
IBufferPool
bufferPool
,
CancellationToken
cancellationToken
)
private
static
async
Task
<
Dictionary
<
string
,
SslExtension
>?>
ReadExtensions
(
int
majorVersion
,
int
minorVersion
,
PeekStreamReader
peekStreamReader
,
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
)
...
...
src/Titanium.Web.Proxy/TransparentClientHandler.cs
View file @
51e83bae
...
@@ -75,14 +75,15 @@ namespace Titanium.Web.Proxy
...
@@ -75,14 +75,15 @@ namespace Titanium.Web.Proxy
// HTTPS server created - we can now decrypt the client's traffic
// HTTPS server created - we can now decrypt the client's traffic
clientStream
=
new
HttpClientStream
(
sslStream
,
BufferPool
);
clientStream
=
new
HttpClientStream
(
sslStream
,
BufferPool
);
sslStream
=
null
;
// clientStream was created, no need to keep SSL stream reference
}
}
catch
(
Exception
e
)
catch
(
Exception
e
)
{
{
var
cert
n
ame
=
certificate
?.
GetNameInfo
(
X509NameType
.
SimpleName
,
false
);
var
cert
N
ame
=
certificate
?.
GetNameInfo
(
X509NameType
.
SimpleName
,
false
);
var
session
=
new
SessionEventArgs
(
this
,
endPoint
,
clientConnection
,
clientStream
,
null
,
var
session
=
new
SessionEventArgs
(
this
,
endPoint
,
clientConnection
,
clientStream
,
null
,
cancellationTokenSource
);
cancellationTokenSource
);
throw
new
ProxyConnectException
(
throw
new
ProxyConnectException
(
$"Couldn't authenticate host '
{
httpsHostName
}
' with certificate '
{
cert
n
ame
}
'."
,
e
,
session
);
$"Couldn't authenticate host '
{
httpsHostName
}
' with certificate '
{
cert
N
ame
}
'."
,
e
,
session
);
}
}
}
}
...
...
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