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
05ed651f
Unverified
Commit
05ed651f
authored
Apr 25, 2019
by
Jehonathan Thomas
Committed by
GitHub
Apr 25, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #583 from honfika/master
Basic HTTP/2 support. Disabled by default. Warning added to the enabl…
parents
a8a822a4
2d4dc4e0
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
342 additions
and
163 deletions
+342
-163
MainWindow.xaml.cs
examples/Titanium.Web.Proxy.Examples.Wpf/MainWindow.xaml.cs
+39
-0
SessionListItem.cs
examples/Titanium.Web.Proxy.Examples.Wpf/SessionListItem.cs
+30
-18
Titanium.Web.Proxy.Examples.Wpf.NetCore.csproj
...amples.Wpf/Titanium.Web.Proxy.Examples.Wpf.NetCore.csproj
+17
-0
SessionEventArgsBase.cs
...Titanium.Web.Proxy/EventArguments/SessionEventArgsBase.cs
+1
-1
ExplicitClientHandler.cs
src/Titanium.Web.Proxy/ExplicitClientHandler.cs
+18
-3
HttpHelper.cs
src/Titanium.Web.Proxy/Helpers/HttpHelper.cs
+2
-2
Ref.cs
src/Titanium.Web.Proxy/Helpers/Ref.cs
+0
-32
ConnectRequest.cs
src/Titanium.Web.Proxy/Http/ConnectRequest.cs
+2
-0
KnownHeaders.cs
src/Titanium.Web.Proxy/Http/KnownHeaders.cs
+9
-9
TunnelType.cs
src/Titanium.Web.Proxy/Http/TunnelType.cs
+10
-0
StaticTable.cs
src/Titanium.Web.Proxy/Http2/Hpack/StaticTable.cs
+48
-48
Http2Helper.cs
src/Titanium.Web.Proxy/Http2/Http2Helper.cs
+156
-45
HttpHeader.cs
src/Titanium.Web.Proxy/Models/HttpHeader.cs
+1
-1
TcpConnectionFactory.cs
src/Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs
+1
-1
ProxyServer.cs
src/Titanium.Web.Proxy/ProxyServer.cs
+6
-3
RequestHandler.cs
src/Titanium.Web.Proxy/RequestHandler.cs
+2
-0
No files found.
examples/Titanium.Web.Proxy.Examples.Wpf/MainWindow.xaml.cs
View file @
05ed651f
...
@@ -150,6 +150,12 @@ namespace Titanium.Web.Proxy.Examples.Wpf
...
@@ -150,6 +150,12 @@ namespace Titanium.Web.Proxy.Examples.Wpf
SessionListItem
item
=
null
;
SessionListItem
item
=
null
;
await
Dispatcher
.
InvokeAsync
(()
=>
{
item
=
addSession
(
e
);
});
await
Dispatcher
.
InvokeAsync
(()
=>
{
item
=
addSession
(
e
);
});
if
(
e
.
HttpClient
.
ConnectRequest
?.
TunnelType
==
TunnelType
.
Http2
)
{
// GetRequestBody for HTTP/2 currently not supported
return
;
}
if
(
e
.
HttpClient
.
Request
.
HasBody
)
if
(
e
.
HttpClient
.
Request
.
HasBody
)
{
{
e
.
HttpClient
.
Request
.
KeepBody
=
true
;
e
.
HttpClient
.
Request
.
KeepBody
=
true
;
...
@@ -168,6 +174,12 @@ namespace Titanium.Web.Proxy.Examples.Wpf
...
@@ -168,6 +174,12 @@ namespace Titanium.Web.Proxy.Examples.Wpf
}
}
});
});
if
(
e
.
HttpClient
.
ConnectRequest
?.
TunnelType
==
TunnelType
.
Http2
)
{
// GetRequestBody for HTTP/2 currently not supported
return
;
}
if
(
item
!=
null
)
if
(
item
!=
null
)
{
{
if
(
e
.
HttpClient
.
Response
.
HasBody
)
if
(
e
.
HttpClient
.
Response
.
HasBody
)
...
@@ -217,6 +229,12 @@ namespace Titanium.Web.Proxy.Examples.Wpf
...
@@ -217,6 +229,12 @@ namespace Titanium.Web.Proxy.Examples.Wpf
var
session
=
(
SessionEventArgsBase
)
sender
;
var
session
=
(
SessionEventArgsBase
)
sender
;
if
(
sessionDictionary
.
TryGetValue
(
session
.
HttpClient
,
out
var
li
))
if
(
sessionDictionary
.
TryGetValue
(
session
.
HttpClient
,
out
var
li
))
{
{
var
tunnelType
=
session
.
HttpClient
.
ConnectRequest
?.
TunnelType
??
TunnelType
.
Unknown
;
if
(
tunnelType
!=
TunnelType
.
Unknown
)
{
li
.
Protocol
=
TunnelTypeToString
(
tunnelType
);
}
li
.
ReceivedDataCount
+=
args
.
Count
;
li
.
ReceivedDataCount
+=
args
.
Count
;
}
}
};
};
...
@@ -226,6 +244,12 @@ namespace Titanium.Web.Proxy.Examples.Wpf
...
@@ -226,6 +244,12 @@ namespace Titanium.Web.Proxy.Examples.Wpf
var
session
=
(
SessionEventArgsBase
)
sender
;
var
session
=
(
SessionEventArgsBase
)
sender
;
if
(
sessionDictionary
.
TryGetValue
(
session
.
HttpClient
,
out
var
li
))
if
(
sessionDictionary
.
TryGetValue
(
session
.
HttpClient
,
out
var
li
))
{
{
var
tunnelType
=
session
.
HttpClient
.
ConnectRequest
?.
TunnelType
??
TunnelType
.
Unknown
;
if
(
tunnelType
!=
TunnelType
.
Unknown
)
{
li
.
Protocol
=
TunnelTypeToString
(
tunnelType
);
}
li
.
SentDataCount
+=
args
.
Count
;
li
.
SentDataCount
+=
args
.
Count
;
}
}
};
};
...
@@ -235,6 +259,21 @@ namespace Titanium.Web.Proxy.Examples.Wpf
...
@@ -235,6 +259,21 @@ namespace Titanium.Web.Proxy.Examples.Wpf
return
item
;
return
item
;
}
}
private
string
TunnelTypeToString
(
TunnelType
tunnelType
)
{
switch
(
tunnelType
)
{
case
TunnelType
.
Https
:
return
"https"
;
case
TunnelType
.
Websocket
:
return
"websocket"
;
case
TunnelType
.
Http2
:
return
"http2"
;
}
return
null
;
}
private
void
ListViewSessions_OnKeyDown
(
object
sender
,
KeyEventArgs
e
)
private
void
ListViewSessions_OnKeyDown
(
object
sender
,
KeyEventArgs
e
)
{
{
if
(
e
.
Key
==
Key
.
Delete
)
if
(
e
.
Key
==
Key
.
Delete
)
...
...
examples/Titanium.Web.Proxy.Examples.Wpf/SessionListItem.cs
View file @
05ed651f
...
@@ -11,7 +11,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf
...
@@ -11,7 +11,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf
private
long
?
bodySize
;
private
long
?
bodySize
;
private
Exception
exception
;
private
Exception
exception
;
private
string
host
;
private
string
host
;
private
string
process
;
private
int
processId
;
private
string
protocol
;
private
string
protocol
;
private
long
receivedDataCount
;
private
long
receivedDataCount
;
private
long
sentDataCount
;
private
long
sentDataCount
;
...
@@ -54,10 +54,32 @@ namespace Titanium.Web.Proxy.Examples.Wpf
...
@@ -54,10 +54,32 @@ namespace Titanium.Web.Proxy.Examples.Wpf
set
=>
SetField
(
ref
bodySize
,
value
);
set
=>
SetField
(
ref
bodySize
,
value
);
}
}
public
int
ProcessId
{
get
=>
processId
;
set
{
if
(
SetField
(
ref
processId
,
value
))
{
OnPropertyChanged
(
nameof
(
Process
));
}
}
}
public
string
Process
public
string
Process
{
{
get
=>
process
;
get
set
=>
SetField
(
ref
process
,
value
);
{
try
{
var
process
=
System
.
Diagnostics
.
Process
.
GetProcessById
(
processId
);
return
process
.
ProcessName
+
":"
+
processId
;
}
catch
(
Exception
)
{
return
string
.
Empty
;
}
}
}
}
public
long
ReceivedDataCount
public
long
ReceivedDataCount
...
@@ -80,13 +102,16 @@ namespace Titanium.Web.Proxy.Examples.Wpf
...
@@ -80,13 +102,16 @@ namespace Titanium.Web.Proxy.Examples.Wpf
public
event
PropertyChangedEventHandler
PropertyChanged
;
public
event
PropertyChangedEventHandler
PropertyChanged
;
protected
void
SetField
<
T
>(
ref
T
field
,
T
value
,
[
CallerMemberName
]
string
propertyName
=
null
)
protected
bool
SetField
<
T
>(
ref
T
field
,
T
value
,
[
CallerMemberName
]
string
propertyName
=
null
)
{
{
if
(!
Equals
(
field
,
value
))
if
(!
Equals
(
field
,
value
))
{
{
field
=
value
;
field
=
value
;
OnPropertyChanged
(
propertyName
);
OnPropertyChanged
(
propertyName
);
return
true
;
}
}
return
false
;
}
}
[
NotifyPropertyChangedInvocator
]
[
NotifyPropertyChangedInvocator
]
...
@@ -132,20 +157,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf
...
@@ -132,20 +157,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf
BodySize
=
responseSize
;
BodySize
=
responseSize
;
}
}
Process
=
GetProcessDescription
(
HttpClient
.
ProcessId
.
Value
);
ProcessId
=
HttpClient
.
ProcessId
.
Value
;
}
private
string
GetProcessDescription
(
int
processId
)
{
try
{
var
process
=
System
.
Diagnostics
.
Process
.
GetProcessById
(
processId
);
return
process
.
ProcessName
+
":"
+
processId
;
}
catch
(
Exception
)
{
return
string
.
Empty
;
}
}
}
}
}
}
}
examples/Titanium.Web.Proxy.Examples.Wpf/Titanium.Web.Proxy.Examples.Wpf.NetCore.csproj
0 → 100644
View file @
05ed651f
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
<UseWPF>true</UseWPF>
</PropertyGroup>
<ItemGroup>
<Compile Remove="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Titanium.Web.Proxy\Titanium.Web.Proxy.csproj" />
</ItemGroup>
</Project>
\ No newline at end of file
src/Titanium.Web.Proxy/EventArguments/SessionEventArgsBase.cs
View file @
05ed651f
...
@@ -31,7 +31,7 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -31,7 +31,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// <summary>
/// <summary>
/// Relative milliseconds for various events.
/// Relative milliseconds for various events.
/// </summary>
/// </summary>
public
Dictionary
<
string
,
DateTime
>
TimeLine
{
get
;
set
;
}
=
new
Dictionary
<
string
,
DateTime
>();
public
Dictionary
<
string
,
DateTime
>
TimeLine
{
get
;
}
=
new
Dictionary
<
string
,
DateTime
>();
/// <summary>
/// <summary>
/// Initializes a new instance of the <see cref="SessionEventArgsBase" /> class.
/// Initializes a new instance of the <see cref="SessionEventArgsBase" /> class.
...
...
src/Titanium.Web.Proxy/ExplicitClientHandler.cs
View file @
05ed651f
...
@@ -126,6 +126,7 @@ namespace Titanium.Web.Proxy
...
@@ -126,6 +126,7 @@ namespace Titanium.Web.Proxy
bool
isClientHello
=
clientHelloInfo
!=
null
;
bool
isClientHello
=
clientHelloInfo
!=
null
;
if
(
isClientHello
)
if
(
isClientHello
)
{
{
connectRequest
.
TunnelType
=
TunnelType
.
Https
;
connectRequest
.
ClientHelloInfo
=
clientHelloInfo
;
connectRequest
.
ClientHelloInfo
=
clientHelloInfo
;
}
}
...
@@ -208,9 +209,9 @@ namespace Titanium.Web.Proxy
...
@@ -208,9 +209,9 @@ namespace Titanium.Web.Proxy
}
}
catch
(
Exception
e
)
catch
(
Exception
e
)
{
{
var
cert
n
ame
=
certificate
?.
GetNameInfo
(
X509NameType
.
SimpleName
,
false
);
var
cert
N
ame
=
certificate
?.
GetNameInfo
(
X509NameType
.
SimpleName
,
false
);
throw
new
ProxyConnectException
(
throw
new
ProxyConnectException
(
$"Couldn't authenticate host '
{
connectHostname
}
' with certificate '
{
cert
n
ame
}
'."
,
e
,
connectArgs
);
$"Couldn't authenticate host '
{
connectHostname
}
' with certificate '
{
cert
N
ame
}
'."
,
e
,
connectArgs
);
}
}
if
(
await
HttpHelper
.
IsConnectMethod
(
clientStream
)
==
-
1
)
if
(
await
HttpHelper
.
IsConnectMethod
(
clientStream
)
==
-
1
)
...
@@ -233,6 +234,11 @@ namespace Titanium.Web.Proxy
...
@@ -233,6 +234,11 @@ namespace Titanium.Web.Proxy
// Hostname is excluded or it is not an HTTPS connect
// Hostname is excluded or it is not an HTTPS connect
if
(!
decryptSsl
||
!
isClientHello
)
if
(!
decryptSsl
||
!
isClientHello
)
{
{
if
(!
isClientHello
)
{
connectRequest
.
TunnelType
=
TunnelType
.
Websocket
;
}
// create new connection to server.
// create new connection to server.
// If we detected that client tunnel CONNECTs without SSL by checking for empty client hello then
// If we detected that client tunnel CONNECTs without SSL by checking for empty client hello then
// this connection should not be HTTPS.
// this connection should not be HTTPS.
...
@@ -286,6 +292,8 @@ namespace Titanium.Web.Proxy
...
@@ -286,6 +292,8 @@ 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
;
// HTTP/2 Connection Preface
// HTTP/2 Connection Preface
string
line
=
await
clientStream
.
ReadLineAsync
(
cancellationToken
);
string
line
=
await
clientStream
.
ReadLineAsync
(
cancellationToken
);
if
(
line
!=
string
.
Empty
)
if
(
line
!=
string
.
Empty
)
...
@@ -318,9 +326,16 @@ namespace Titanium.Web.Proxy
...
@@ -318,9 +326,16 @@ namespace Titanium.Web.Proxy
await
Http2Helper
.
SendHttp2
(
clientStream
,
connection
.
Stream
,
BufferSize
,
await
Http2Helper
.
SendHttp2
(
clientStream
,
connection
.
Stream
,
BufferSize
,
(
buffer
,
offset
,
count
)
=>
{
connectArgs
.
OnDataSent
(
buffer
,
offset
,
count
);
},
(
buffer
,
offset
,
count
)
=>
{
connectArgs
.
OnDataSent
(
buffer
,
offset
,
count
);
},
(
buffer
,
offset
,
count
)
=>
{
connectArgs
.
OnDataReceived
(
buffer
,
offset
,
count
);
},
(
buffer
,
offset
,
count
)
=>
{
connectArgs
.
OnDataReceived
(
buffer
,
offset
,
count
);
},
()
=>
new
SessionEventArgs
(
this
,
endPoint
,
cancellationTokenSource
)
{
ProxyClient
=
{
Connection
=
clientConnection
},
HttpClient
=
{
ConnectRequest
=
connectArgs
?.
HttpClient
.
ConnectRequest
},
UserData
=
connectArgs
?.
UserData
},
async
args
=>
{
await
invokeBeforeRequest
(
args
);
},
async
args
=>
{
await
invokeBeforeResponse
(
args
);
},
connectArgs
.
CancellationTokenSource
,
clientConnection
.
Id
,
ExceptionFunc
);
connectArgs
.
CancellationTokenSource
,
clientConnection
.
Id
,
ExceptionFunc
);
#endif
#endif
}
}
finally
finally
{
{
...
...
src/Titanium.Web.Proxy/Helpers/HttpHelper.cs
View file @
05ed651f
...
@@ -146,8 +146,8 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -146,8 +146,8 @@ namespace Titanium.Web.Proxy.Helpers
private
static
async
Task
<
int
>
startsWith
(
ICustomStreamReader
clientStreamReader
,
string
expectedStart
)
private
static
async
Task
<
int
>
startsWith
(
ICustomStreamReader
clientStreamReader
,
string
expectedStart
)
{
{
bool
isExpected
=
true
;
bool
isExpected
=
true
;
int
legthToCheck
=
10
;
int
le
n
gthToCheck
=
10
;
for
(
int
i
=
0
;
i
<
legthToCheck
;
i
++)
for
(
int
i
=
0
;
i
<
le
n
gthToCheck
;
i
++)
{
{
int
b
=
await
clientStreamReader
.
PeekByteAsync
(
i
);
int
b
=
await
clientStreamReader
.
PeekByteAsync
(
i
);
if
(
b
==
-
1
)
if
(
b
==
-
1
)
...
...
src/Titanium.Web.Proxy/Helpers/Ref.cs
deleted
100644 → 0
View file @
a8a822a4
namespace
Titanium.Web.Proxy.Helpers
{
internal
class
Ref
<
T
>
{
internal
Ref
()
{
}
internal
Ref
(
T
value
)
{
Value
=
value
;
}
internal
T
Value
{
get
;
set
;
}
public
override
string
ToString
()
{
var
value
=
Value
;
return
value
==
null
?
string
.
Empty
:
value
.
ToString
();
}
public
static
implicit
operator
T
(
Ref
<
T
>
r
)
{
return
r
.
Value
;
}
public
static
implicit
operator
Ref
<
T
>(
T
value
)
{
return
new
Ref
<
T
>(
value
);
}
}
}
src/Titanium.Web.Proxy/Http/ConnectRequest.cs
View file @
05ed651f
...
@@ -12,6 +12,8 @@ namespace Titanium.Web.Proxy.Http
...
@@ -12,6 +12,8 @@ namespace Titanium.Web.Proxy.Http
Method
=
"CONNECT"
;
Method
=
"CONNECT"
;
}
}
public
TunnelType
TunnelType
{
get
;
internal
set
;
}
public
ClientHelloInfo
ClientHelloInfo
{
get
;
set
;
}
public
ClientHelloInfo
ClientHelloInfo
{
get
;
set
;
}
}
}
}
}
src/Titanium.Web.Proxy/Http/KnownHeaders.cs
View file @
05ed651f
...
@@ -6,28 +6,28 @@
...
@@ -6,28 +6,28 @@
public
static
class
KnownHeaders
public
static
class
KnownHeaders
{
{
// Both
// Both
public
const
string
Connection
=
"
c
onnection"
;
public
const
string
Connection
=
"
C
onnection"
;
public
const
string
ConnectionClose
=
"close"
;
public
const
string
ConnectionClose
=
"close"
;
public
const
string
ConnectionKeepAlive
=
"keep-alive"
;
public
const
string
ConnectionKeepAlive
=
"keep-alive"
;
public
const
string
ContentLength
=
"
content-l
ength"
;
public
const
string
ContentLength
=
"
Content-L
ength"
;
public
const
string
ContentType
=
"
content-t
ype"
;
public
const
string
ContentType
=
"
Content-T
ype"
;
public
const
string
ContentTypeCharset
=
"charset"
;
public
const
string
ContentTypeCharset
=
"charset"
;
public
const
string
ContentTypeBoundary
=
"boundary"
;
public
const
string
ContentTypeBoundary
=
"boundary"
;
public
const
string
Upgrade
=
"
u
pgrade"
;
public
const
string
Upgrade
=
"
U
pgrade"
;
public
const
string
UpgradeWebsocket
=
"websocket"
;
public
const
string
UpgradeWebsocket
=
"websocket"
;
// Request headers
// Request headers
public
const
string
AcceptEncoding
=
"
accept-e
ncoding"
;
public
const
string
AcceptEncoding
=
"
Accept-E
ncoding"
;
public
const
string
Authorization
=
"Authorization"
;
public
const
string
Authorization
=
"Authorization"
;
public
const
string
Expect
=
"
e
xpect"
;
public
const
string
Expect
=
"
E
xpect"
;
public
const
string
Expect100Continue
=
"100-continue"
;
public
const
string
Expect100Continue
=
"100-continue"
;
public
const
string
Host
=
"
h
ost"
;
public
const
string
Host
=
"
H
ost"
;
public
const
string
ProxyAuthorization
=
"Proxy-Authorization"
;
public
const
string
ProxyAuthorization
=
"Proxy-Authorization"
;
public
const
string
ProxyAuthorizationBasic
=
"basic"
;
public
const
string
ProxyAuthorizationBasic
=
"basic"
;
...
@@ -36,7 +36,7 @@
...
@@ -36,7 +36,7 @@
public
const
string
ProxyConnectionClose
=
"close"
;
public
const
string
ProxyConnectionClose
=
"close"
;
// Response headers
// Response headers
public
const
string
ContentEncoding
=
"
content-e
ncoding"
;
public
const
string
ContentEncoding
=
"
Content-E
ncoding"
;
public
const
string
ContentEncodingDeflate
=
"deflate"
;
public
const
string
ContentEncodingDeflate
=
"deflate"
;
public
const
string
ContentEncodingGzip
=
"gzip"
;
public
const
string
ContentEncodingGzip
=
"gzip"
;
public
const
string
ContentEncodingBrotli
=
"br"
;
public
const
string
ContentEncodingBrotli
=
"br"
;
...
@@ -45,7 +45,7 @@
...
@@ -45,7 +45,7 @@
public
const
string
ProxyAuthenticate
=
"Proxy-Authenticate"
;
public
const
string
ProxyAuthenticate
=
"Proxy-Authenticate"
;
public
const
string
TransferEncoding
=
"
transfer-e
ncoding"
;
public
const
string
TransferEncoding
=
"
Transfer-E
ncoding"
;
public
const
string
TransferEncodingChunked
=
"chunked"
;
public
const
string
TransferEncodingChunked
=
"chunked"
;
}
}
}
}
src/Titanium.Web.Proxy/Http/TunnelType.cs
0 → 100644
View file @
05ed651f
namespace
Titanium.Web.Proxy.Http
{
public
enum
TunnelType
{
Unknown
,
Https
,
Websocket
,
Http2
,
}
}
src/Titanium.Web.Proxy/Http2/Hpack/StaticTable.cs
View file @
05ed651f
...
@@ -59,99 +59,99 @@ namespace Titanium.Web.Proxy.Http2.Hpack
...
@@ -59,99 +59,99 @@ namespace Titanium.Web.Proxy.Http2.Hpack
/* 14 */
/* 14 */
new
HttpHeader
(
":status"
,
"500"
),
new
HttpHeader
(
":status"
,
"500"
),
/* 15 */
/* 15 */
new
HttpHeader
(
"
accept-c
harset"
,
string
.
Empty
),
new
HttpHeader
(
"
Accept-C
harset"
,
string
.
Empty
),
/* 16 */
/* 16 */
new
HttpHeader
(
"
accept-e
ncoding"
,
"gzip, deflate"
),
new
HttpHeader
(
"
Accept-E
ncoding"
,
"gzip, deflate"
),
/* 17 */
/* 17 */
new
HttpHeader
(
"
accept-l
anguage"
,
string
.
Empty
),
new
HttpHeader
(
"
Accept-L
anguage"
,
string
.
Empty
),
/* 18 */
/* 18 */
new
HttpHeader
(
"
accept-r
anges"
,
string
.
Empty
),
new
HttpHeader
(
"
Accept-R
anges"
,
string
.
Empty
),
/* 19 */
/* 19 */
new
HttpHeader
(
"
a
ccept"
,
string
.
Empty
),
new
HttpHeader
(
"
A
ccept"
,
string
.
Empty
),
/* 20 */
/* 20 */
new
HttpHeader
(
"
access-control-allow-o
rigin"
,
string
.
Empty
),
new
HttpHeader
(
"
Access-Control-Allow-O
rigin"
,
string
.
Empty
),
/* 21 */
/* 21 */
new
HttpHeader
(
"
a
ge"
,
string
.
Empty
),
new
HttpHeader
(
"
A
ge"
,
string
.
Empty
),
/* 22 */
/* 22 */
new
HttpHeader
(
"
a
llow"
,
string
.
Empty
),
new
HttpHeader
(
"
A
llow"
,
string
.
Empty
),
/* 23 */
/* 23 */
new
HttpHeader
(
"
a
uthorization"
,
string
.
Empty
),
new
HttpHeader
(
"
A
uthorization"
,
string
.
Empty
),
/* 24 */
/* 24 */
new
HttpHeader
(
"
cache-c
ontrol"
,
string
.
Empty
),
new
HttpHeader
(
"
Cache-C
ontrol"
,
string
.
Empty
),
/* 25 */
/* 25 */
new
HttpHeader
(
"
content-d
isposition"
,
string
.
Empty
),
new
HttpHeader
(
"
Content-D
isposition"
,
string
.
Empty
),
/* 26 */
/* 26 */
new
HttpHeader
(
"
content-e
ncoding"
,
string
.
Empty
),
new
HttpHeader
(
"
Content-E
ncoding"
,
string
.
Empty
),
/* 27 */
/* 27 */
new
HttpHeader
(
"
content-l
anguage"
,
string
.
Empty
),
new
HttpHeader
(
"
Content-L
anguage"
,
string
.
Empty
),
/* 28 */
/* 28 */
new
HttpHeader
(
"
content-l
ength"
,
string
.
Empty
),
new
HttpHeader
(
"
Content-L
ength"
,
string
.
Empty
),
/* 29 */
/* 29 */
new
HttpHeader
(
"
content-l
ocation"
,
string
.
Empty
),
new
HttpHeader
(
"
Content-L
ocation"
,
string
.
Empty
),
/* 30 */
/* 30 */
new
HttpHeader
(
"
content-r
ange"
,
string
.
Empty
),
new
HttpHeader
(
"
Content-R
ange"
,
string
.
Empty
),
/* 31 */
/* 31 */
new
HttpHeader
(
"
content-t
ype"
,
string
.
Empty
),
new
HttpHeader
(
"
Content-T
ype"
,
string
.
Empty
),
/* 32 */
/* 32 */
new
HttpHeader
(
"
c
ookie"
,
string
.
Empty
),
new
HttpHeader
(
"
C
ookie"
,
string
.
Empty
),
/* 33 */
/* 33 */
new
HttpHeader
(
"
d
ate"
,
string
.
Empty
),
new
HttpHeader
(
"
D
ate"
,
string
.
Empty
),
/* 34 */
/* 34 */
new
HttpHeader
(
"
et
ag"
,
string
.
Empty
),
new
HttpHeader
(
"
ET
ag"
,
string
.
Empty
),
/* 35 */
/* 35 */
new
HttpHeader
(
"
e
xpect"
,
string
.
Empty
),
new
HttpHeader
(
"
E
xpect"
,
string
.
Empty
),
/* 36 */
/* 36 */
new
HttpHeader
(
"
e
xpires"
,
string
.
Empty
),
new
HttpHeader
(
"
E
xpires"
,
string
.
Empty
),
/* 37 */
/* 37 */
new
HttpHeader
(
"
f
rom"
,
string
.
Empty
),
new
HttpHeader
(
"
F
rom"
,
string
.
Empty
),
/* 38 */
/* 38 */
new
HttpHeader
(
"
h
ost"
,
string
.
Empty
),
new
HttpHeader
(
"
H
ost"
,
string
.
Empty
),
/* 39 */
/* 39 */
new
HttpHeader
(
"
if-m
atch"
,
string
.
Empty
),
new
HttpHeader
(
"
If-M
atch"
,
string
.
Empty
),
/* 40 */
/* 40 */
new
HttpHeader
(
"
if-modified-s
ince"
,
string
.
Empty
),
new
HttpHeader
(
"
If-Modified-S
ince"
,
string
.
Empty
),
/* 41 */
/* 41 */
new
HttpHeader
(
"
if-none-m
atch"
,
string
.
Empty
),
new
HttpHeader
(
"
If-None-M
atch"
,
string
.
Empty
),
/* 42 */
/* 42 */
new
HttpHeader
(
"
if-r
ange"
,
string
.
Empty
),
new
HttpHeader
(
"
If-R
ange"
,
string
.
Empty
),
/* 43 */
/* 43 */
new
HttpHeader
(
"
if-unmodified-s
ince"
,
string
.
Empty
),
new
HttpHeader
(
"
If-Unmodified-S
ince"
,
string
.
Empty
),
/* 44 */
/* 44 */
new
HttpHeader
(
"
last-m
odified"
,
string
.
Empty
),
new
HttpHeader
(
"
Last-M
odified"
,
string
.
Empty
),
/* 45 */
/* 45 */
new
HttpHeader
(
"
l
ink"
,
string
.
Empty
),
new
HttpHeader
(
"
L
ink"
,
string
.
Empty
),
/* 46 */
/* 46 */
new
HttpHeader
(
"
l
ocation"
,
string
.
Empty
),
new
HttpHeader
(
"
L
ocation"
,
string
.
Empty
),
/* 47 */
/* 47 */
new
HttpHeader
(
"
max-f
orwards"
,
string
.
Empty
),
new
HttpHeader
(
"
Max-F
orwards"
,
string
.
Empty
),
/* 48 */
/* 48 */
new
HttpHeader
(
"
proxy-a
uthenticate"
,
string
.
Empty
),
new
HttpHeader
(
"
Proxy-A
uthenticate"
,
string
.
Empty
),
/* 49 */
/* 49 */
new
HttpHeader
(
"
proxy-a
uthorization"
,
string
.
Empty
),
new
HttpHeader
(
"
Proxy-A
uthorization"
,
string
.
Empty
),
/* 50 */
/* 50 */
new
HttpHeader
(
"
r
ange"
,
string
.
Empty
),
new
HttpHeader
(
"
R
ange"
,
string
.
Empty
),
/* 51 */
/* 51 */
new
HttpHeader
(
"
r
eferer"
,
string
.
Empty
),
new
HttpHeader
(
"
R
eferer"
,
string
.
Empty
),
/* 52 */
/* 52 */
new
HttpHeader
(
"
r
efresh"
,
string
.
Empty
),
new
HttpHeader
(
"
R
efresh"
,
string
.
Empty
),
/* 53 */
/* 53 */
new
HttpHeader
(
"
retry-a
fter"
,
string
.
Empty
),
new
HttpHeader
(
"
Retry-A
fter"
,
string
.
Empty
),
/* 54 */
/* 54 */
new
HttpHeader
(
"
s
erver"
,
string
.
Empty
),
new
HttpHeader
(
"
S
erver"
,
string
.
Empty
),
/* 55 */
/* 55 */
new
HttpHeader
(
"
set-c
ookie"
,
string
.
Empty
),
new
HttpHeader
(
"
Set-C
ookie"
,
string
.
Empty
),
/* 56 */
/* 56 */
new
HttpHeader
(
"
strict-transport-s
ecurity"
,
string
.
Empty
),
new
HttpHeader
(
"
Strict-Transport-S
ecurity"
,
string
.
Empty
),
/* 57 */
/* 57 */
new
HttpHeader
(
"
transfer-e
ncoding"
,
string
.
Empty
),
new
HttpHeader
(
"
Transfer-E
ncoding"
,
string
.
Empty
),
/* 58 */
/* 58 */
new
HttpHeader
(
"
user-a
gent"
,
string
.
Empty
),
new
HttpHeader
(
"
User-A
gent"
,
string
.
Empty
),
/* 59 */
/* 59 */
new
HttpHeader
(
"
v
ary"
,
string
.
Empty
),
new
HttpHeader
(
"
V
ary"
,
string
.
Empty
),
/* 60 */
/* 60 */
new
HttpHeader
(
"
v
ia"
,
string
.
Empty
),
new
HttpHeader
(
"
V
ia"
,
string
.
Empty
),
/* 61 */
/* 61 */
new
HttpHeader
(
"
www-a
uthenticate"
,
string
.
Empty
)
new
HttpHeader
(
"
WWW-A
uthenticate"
,
string
.
Empty
)
};
};
private
static
readonly
Dictionary
<
string
,
int
>
staticIndexByName
=
CreateMap
();
private
static
readonly
Dictionary
<
string
,
int
>
staticIndexByName
=
CreateMap
();
...
@@ -244,4 +244,4 @@ namespace Titanium.Web.Proxy.Http2.Hpack
...
@@ -244,4 +244,4 @@ namespace Titanium.Web.Proxy.Http2.Hpack
return
ret
;
return
ret
;
}
}
}
}
}
}
\ No newline at end of file
src/Titanium.Web.Proxy/Http2/Http2Helper.cs
View file @
05ed651f
#
if
NETCOREAPP2_1
#
if
NETCOREAPP2_1
using
System
;
using
System
;
using
System.Collections.Concurrent
;
using
System.Collections.Generic
;
using
System.IO
;
using
System.IO
;
using
System.Net
;
using
System.Threading
;
using
System.Threading
;
using
System.Threading.Tasks
;
using
System.Threading.Tasks
;
using
Titanium.Web.Proxy.EventArguments
;
using
Titanium.Web.Proxy.Exceptions
;
using
Titanium.Web.Proxy.Http
;
using
Titanium.Web.Proxy.Http2.Hpack
;
using
Titanium.Web.Proxy.Http2.Hpack
;
namespace
Titanium.Web.Proxy.Http2
namespace
Titanium.Web.Proxy.Http2
...
@@ -25,27 +31,24 @@ namespace Titanium.Web.Proxy.Http2
...
@@ -25,27 +31,24 @@ namespace Titanium.Web.Proxy.Http2
/// Useful for websocket requests
/// Useful for websocket requests
/// Task-based Asynchronous Pattern
/// Task-based Asynchronous Pattern
/// </summary>
/// </summary>
/// <param name="clientStream"></param>
/// <param name="serverStream"></param>
/// <param name="bufferSize"></param>
/// <param name="onDataSend"></param>
/// <param name="onDataReceive"></param>
/// <param name="cancellationTokenSource"></param>
/// <param name="connectionId"></param>
/// <param name="exceptionFunc"></param>
/// <returns></returns>
/// <returns></returns>
internal
static
async
Task
SendHttp2
(
Stream
clientStream
,
Stream
serverStream
,
int
bufferSize
,
internal
static
async
Task
SendHttp2
(
Stream
clientStream
,
Stream
serverStream
,
int
bufferSize
,
Action
<
byte
[],
int
,
int
>
onDataSend
,
Action
<
byte
[],
int
,
int
>
onDataReceive
,
Action
<
byte
[],
int
,
int
>
onDataSend
,
Action
<
byte
[],
int
,
int
>
onDataReceive
,
Func
<
SessionEventArgs
>
sessionFactory
,
Func
<
SessionEventArgs
,
Task
>
onBeforeRequest
,
Func
<
SessionEventArgs
,
Task
>
onBeforeResponse
,
CancellationTokenSource
cancellationTokenSource
,
Guid
connectionId
,
CancellationTokenSource
cancellationTokenSource
,
Guid
connectionId
,
ExceptionHandler
exceptionFunc
)
ExceptionHandler
exceptionFunc
)
{
{
var
decoder
=
new
Decoder
(
8192
,
4096
*
16
);
var
sessions
=
new
ConcurrentDictionary
<
int
,
SessionEventArgs
>();
// Now async relay all server=>client & client=>server data
// Now async relay all server=>client & client=>server data
var
sendRelay
=
var
sendRelay
=
CopyHttp2FrameAsync
(
clientStream
,
serverStream
,
onDataSend
,
bufferSize
,
connectionId
,
copyHttp2FrameAsync
(
clientStream
,
serverStream
,
onDataSend
,
sessionFactory
,
decoder
,
sessions
,
onBeforeRequest
,
true
,
cancellationTokenSource
.
Token
);
bufferSize
,
connectionId
,
true
,
cancellationTokenSource
.
Token
,
exceptionFunc
);
var
receiveRelay
=
var
receiveRelay
=
CopyHttp2FrameAsync
(
serverStream
,
clientStream
,
onDataReceive
,
bufferSize
,
connectionId
,
copyHttp2FrameAsync
(
serverStream
,
clientStream
,
onDataReceive
,
sessionFactory
,
decoder
,
sessions
,
onBeforeResponse
,
false
,
cancellationTokenSource
.
Token
);
bufferSize
,
connectionId
,
false
,
cancellationTokenSource
.
Token
,
exceptionFunc
);
await
Task
.
WhenAny
(
sendRelay
,
receiveRelay
);
await
Task
.
WhenAny
(
sendRelay
,
receiveRelay
);
cancellationTokenSource
.
Cancel
();
cancellationTokenSource
.
Cancel
();
...
@@ -53,16 +56,17 @@ namespace Titanium.Web.Proxy.Http2
...
@@ -53,16 +56,17 @@ namespace Titanium.Web.Proxy.Http2
await
Task
.
WhenAll
(
sendRelay
,
receiveRelay
);
await
Task
.
WhenAll
(
sendRelay
,
receiveRelay
);
}
}
private
static
async
Task
CopyHttp2FrameAsync
(
Stream
input
,
Stream
output
,
Action
<
byte
[],
int
,
int
>
onCopy
,
private
static
async
Task
copyHttp2FrameAsync
(
Stream
input
,
Stream
output
,
Action
<
byte
[],
int
,
int
>
onCopy
,
int
bufferSize
,
Guid
connectionId
,
bool
isClient
,
CancellationToken
cancellationToken
)
Func
<
SessionEventArgs
>
sessionFactory
,
Decoder
decoder
,
ConcurrentDictionary
<
int
,
SessionEventArgs
>
sessions
,
Func
<
SessionEventArgs
,
Task
>
onBeforeRequestResponse
,
int
bufferSize
,
Guid
connectionId
,
bool
isClient
,
CancellationToken
cancellationToken
,
ExceptionHandler
exceptionFunc
)
{
{
var
decoder
=
new
Decoder
(
8192
,
4096
);
var
headerBuffer
=
new
byte
[
9
];
var
headerBuffer
=
new
byte
[
9
];
var
buffer
=
new
byte
[
32768
];
var
buffer
=
new
byte
[
32768
];
while
(
true
)
while
(
true
)
{
{
int
read
=
await
F
orceRead
(
input
,
headerBuffer
,
0
,
9
,
cancellationToken
);
int
read
=
await
f
orceRead
(
input
,
headerBuffer
,
0
,
9
,
cancellationToken
);
onCopy
(
headerBuffer
,
0
,
read
);
onCopy
(
headerBuffer
,
0
,
read
);
if
(
read
!=
9
)
if
(
read
!=
9
)
{
{
...
@@ -75,55 +79,112 @@ namespace Titanium.Web.Proxy.Http2
...
@@ -75,55 +79,112 @@ namespace Titanium.Web.Proxy.Http2
int
streamId
=
((
headerBuffer
[
5
]
&
0x7f
)
<<
24
)
+
(
headerBuffer
[
6
]
<<
16
)
+
(
headerBuffer
[
7
]
<<
8
)
+
int
streamId
=
((
headerBuffer
[
5
]
&
0x7f
)
<<
24
)
+
(
headerBuffer
[
6
]
<<
16
)
+
(
headerBuffer
[
7
]
<<
8
)
+
headerBuffer
[
8
];
headerBuffer
[
8
];
read
=
await
F
orceRead
(
input
,
buffer
,
0
,
length
,
cancellationToken
);
read
=
await
f
orceRead
(
input
,
buffer
,
0
,
length
,
cancellationToken
);
onCopy
(
buffer
,
0
,
read
);
onCopy
(
buffer
,
0
,
read
);
if
(
read
!=
length
)
if
(
read
!=
length
)
{
{
return
;
return
;
}
}
if
(
isClient
)
bool
endStream
=
false
;
//System.Diagnostics.Debug.WriteLine("CLIENT: " + isClient + ", STREAM: " + streamId + ", TYPE: " + type);
if
(
type
==
0
/* data */
)
{
bool
endStreamFlag
=
(
flags
&
(
int
)
Http2FrameFlag
.
EndStream
)
!=
0
;
if
(
endStreamFlag
)
{
endStream
=
true
;
}
}
else
if
(
type
==
1
/*headers*/
)
{
{
if
(
type
==
1
/*headers*/
)
bool
endHeaders
=
(
flags
&
(
int
)
Http2FrameFlag
.
EndHeaders
)
!=
0
;
bool
padded
=
(
flags
&
(
int
)
Http2FrameFlag
.
Padded
)
!=
0
;
bool
priority
=
(
flags
&
(
int
)
Http2FrameFlag
.
Priority
)
!=
0
;
bool
endStreamFlag
=
(
flags
&
(
int
)
Http2FrameFlag
.
EndStream
)
!=
0
;
if
(
endStreamFlag
)
{
{
bool
endHeaders
=
(
flags
&
(
int
)
Http2FrameFlag
.
EndHeaders
)
!=
0
;
endStream
=
true
;
bool
padded
=
(
flags
&
(
int
)
Http2FrameFlag
.
Padded
)
!=
0
;
}
bool
priority
=
(
flags
&
(
int
)
Http2FrameFlag
.
Priority
)
!=
0
;
System
.
Diagnostics
.
Debug
.
WriteLine
(
"HEADER: "
+
streamId
+
" end: "
+
endHeaders
);
int
offset
=
0
;
if
(
padded
)
{
offset
=
1
;
}
if
(
priority
)
{
offset
+=
5
;
}
int
offset
=
0
;
int
dataLength
=
length
-
offset
;
if
(
padded
)
if
(
padded
)
{
{
offset
=
1
;
dataLength
-=
buffer
[
0
]
;
}
}
if
(
priority
)
if
(!
sessions
.
TryGetValue
(
streamId
,
out
var
args
))
{
{
offset
+=
5
;
// todo: remove sessions when finished, otherwise it will be a "memory leak"
}
args
=
sessionFactory
();
sessions
.
TryAdd
(
streamId
,
args
);
}
int
dataLength
=
length
-
offset
;
var
headerListener
=
new
MyHeaderListener
(
if
(
padded
)
(
name
,
value
)
=>
{
{
dataLength
-=
buffer
[
0
];
var
headers
=
isClient
?
args
.
HttpClient
.
Request
.
Headers
:
args
.
HttpClient
.
Response
.
Headers
;
}
headers
.
AddHeader
(
name
,
value
);
});
var
headerListener
=
new
MyHeaderListener
();
try
try
{
lock
(
decoder
)
{
{
decoder
.
Decode
(
new
BinaryReader
(
new
MemoryStream
(
buffer
,
offset
,
dataLength
)),
decoder
.
Decode
(
new
BinaryReader
(
new
MemoryStream
(
buffer
,
offset
,
dataLength
)),
headerListener
);
headerListener
);
decoder
.
EndHeaderBlock
();
decoder
.
EndHeaderBlock
();
}
}
catch
(
Exception
)
if
(
isClient
)
{
args
.
HttpClient
.
Request
.
HttpVersion
=
HttpVersion
.
Version20
;
args
.
HttpClient
.
Request
.
Method
=
headerListener
.
Method
;
args
.
HttpClient
.
Request
.
OriginalUrl
=
headerListener
.
Status
;
args
.
HttpClient
.
Request
.
RequestUri
=
headerListener
.
GetUri
();
}
else
{
{
args
.
HttpClient
.
Response
.
HttpVersion
=
HttpVersion
.
Version20
;
int
.
TryParse
(
headerListener
.
Status
,
out
int
statusCode
);
args
.
HttpClient
.
Response
.
StatusCode
=
statusCode
;
}
}
}
}
catch
(
Exception
ex
)
{
exceptionFunc
(
new
ProxyHttpException
(
"Failed to decode HTTP/2 headers"
,
ex
,
args
));
}
if
(
endHeaders
)
{
await
onBeforeRequestResponse
(
args
);
}
}
if
(!
isClient
&&
endStream
)
{
sessions
.
TryRemove
(
streamId
,
out
_
);
}
}
await
output
.
WriteAsync
(
headerBuffer
,
0
,
headerBuffer
.
Length
,
cancellationToken
);
// do not cancel the write operation
await
output
.
WriteAsync
(
buffer
,
0
,
length
,
cancellationToken
);
await
output
.
WriteAsync
(
headerBuffer
,
0
,
headerBuffer
.
Length
/*, cancellationToken*/
);
await
output
.
WriteAsync
(
buffer
,
0
,
length
/*, cancellationToken*/
);
if
(
cancellationToken
.
IsCancellationRequested
)
{
return
;
}
/*using (var fs = new System.IO.FileStream($@"c:\11\{connectionId}.{streamId}.dat", FileMode.Append))
/*using (var fs = new System.IO.FileStream($@"c:\11\{connectionId}.{streamId}.dat", FileMode.Append))
{
{
...
@@ -133,7 +194,7 @@ namespace Titanium.Web.Proxy.Http2
...
@@ -133,7 +194,7 @@ namespace Titanium.Web.Proxy.Http2
}
}
}
}
private
static
async
Task
<
int
>
F
orceRead
(
Stream
input
,
byte
[]
buffer
,
int
offset
,
int
bytesToRead
,
private
static
async
Task
<
int
>
f
orceRead
(
Stream
input
,
byte
[]
buffer
,
int
offset
,
int
bytesToRead
,
CancellationToken
cancellationToken
)
CancellationToken
cancellationToken
)
{
{
int
totalRead
=
0
;
int
totalRead
=
0
;
...
@@ -155,9 +216,59 @@ namespace Titanium.Web.Proxy.Http2
...
@@ -155,9 +216,59 @@ namespace Titanium.Web.Proxy.Http2
class
MyHeaderListener
:
IHeaderListener
class
MyHeaderListener
:
IHeaderListener
{
{
private
readonly
Action
<
string
,
string
>
addHeaderFunc
;
public
string
Method
{
get
;
private
set
;
}
public
string
Status
{
get
;
private
set
;
}
private
string
authority
;
private
string
scheme
;
public
string
Path
{
get
;
private
set
;
}
public
MyHeaderListener
(
Action
<
string
,
string
>
addHeaderFunc
)
{
this
.
addHeaderFunc
=
addHeaderFunc
;
}
public
void
AddHeader
(
string
name
,
string
value
,
bool
sensitive
)
public
void
AddHeader
(
string
name
,
string
value
,
bool
sensitive
)
{
{
Console
.
WriteLine
(
name
+
": "
+
value
+
" "
+
sensitive
);
if
(
name
[
0
]
==
':'
)
{
switch
(
name
)
{
case
":method"
:
Method
=
value
;
return
;
case
":authority"
:
authority
=
value
;
return
;
case
":scheme"
:
scheme
=
value
;
return
;
case
":path"
:
Path
=
value
;
return
;
case
":status"
:
Status
=
value
;
return
;
}
}
addHeaderFunc
(
name
,
value
);
}
public
Uri
GetUri
()
{
if
(
authority
==
null
)
{
// todo
authority
=
"abc.abc"
;
}
return
new
Uri
(
scheme
+
"://"
+
authority
+
Path
);
}
}
}
}
}
}
...
...
src/Titanium.Web.Proxy/Models/HttpHeader.cs
View file @
05ed651f
...
@@ -45,7 +45,7 @@ namespace Titanium.Web.Proxy.Models
...
@@ -45,7 +45,7 @@ namespace Titanium.Web.Proxy.Models
/// <summary>
/// <summary>
/// Header Name.
/// Header Name.
/// </summary>
/// </summary>
public
string
Name
{
get
;
set
;
}
public
string
Name
{
get
;
}
/// <summary>
/// <summary>
/// Header Value.
/// Header Value.
...
...
src/Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs
View file @
05ed651f
...
@@ -42,7 +42,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
...
@@ -42,7 +42,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
Task
.
Run
(
async
()
=>
await
clearOutdatedConnections
());
Task
.
Run
(
async
()
=>
await
clearOutdatedConnections
());
}
}
internal
ProxyServer
Server
{
get
;
set
;
}
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
,
...
...
src/Titanium.Web.Proxy/ProxyServer.cs
View file @
05ed651f
...
@@ -146,10 +146,13 @@ namespace Titanium.Web.Proxy
...
@@ -146,10 +146,13 @@ namespace Titanium.Web.Proxy
public
bool
EnableWinAuth
{
get
;
set
;
}
public
bool
EnableWinAuth
{
get
;
set
;
}
/// <summary>
/// <summary>
/// Enable disable HTTP/2 support. This setting is internal,
/// Enable disable HTTP/2 support.
/// because the implementation is not finished
/// Warning: HTTP/2 support is very limited
/// - only enabled when both client and server supports it (no protocol changing in proxy)
/// - GetRequest/ResponseBody(AsString) methods are not supported
/// - cannot modify the request/response (e.g header modifications in BeforeRequest/Response events are ignored)
/// </summary>
/// </summary>
internal
bool
EnableHttp2
{
get
;
set
;
}
=
false
;
public
bool
EnableHttp2
{
get
;
set
;
}
=
false
;
/// <summary>
/// <summary>
/// Should we check for certificate revocation during SSL authentication to servers
/// Should we check for certificate revocation during SSL authentication to servers
...
...
src/Titanium.Web.Proxy/RequestHandler.cs
View file @
05ed651f
...
@@ -312,6 +312,8 @@ namespace Titanium.Web.Proxy
...
@@ -312,6 +312,8 @@ namespace Titanium.Web.Proxy
if
(
args
.
HttpClient
.
Request
.
UpgradeToWebSocket
)
if
(
args
.
HttpClient
.
Request
.
UpgradeToWebSocket
)
{
{
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
(
httpCmd
,
args
,
args
.
HttpClient
.
Request
,
await
handleWebSocketUpgrade
(
httpCmd
,
args
,
args
.
HttpClient
.
Request
,
args
.
HttpClient
.
Response
,
args
.
ProxyClient
.
ClientStream
,
args
.
ProxyClient
.
ClientStreamWriter
,
args
.
HttpClient
.
Response
,
args
.
ProxyClient
.
ClientStream
,
args
.
ProxyClient
.
ClientStreamWriter
,
...
...
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