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
06afb6fd
Commit
06afb6fd
authored
Apr 25, 2019
by
Honfika
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Allow to read HTTP/2 request/response body
(still not able to modify header or body data)
parent
03cd1e18
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
98 additions
and
32 deletions
+98
-32
MainWindow.xaml.cs
examples/Titanium.Web.Proxy.Examples.Wpf/MainWindow.xaml.cs
+9
-10
SessionEventArgs.cs
src/Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
+40
-12
RequestResponseBase.cs
src/Titanium.Web.Proxy/Http/RequestResponseBase.cs
+5
-0
Http2Helper.cs
src/Titanium.Web.Proxy/Http2/Http2Helper.cs
+44
-9
ProxyServer.cs
src/Titanium.Web.Proxy/ProxyServer.cs
+0
-1
No files found.
examples/Titanium.Web.Proxy.Examples.Wpf/MainWindow.xaml.cs
View file @
06afb6fd
...
@@ -36,6 +36,9 @@ namespace Titanium.Web.Proxy.Examples.Wpf
...
@@ -36,6 +36,9 @@ namespace Titanium.Web.Proxy.Examples.Wpf
public
MainWindow
()
public
MainWindow
()
{
{
proxyServer
=
new
ProxyServer
();
proxyServer
=
new
ProxyServer
();
proxyServer
.
EnableHttp2
=
true
;
//proxyServer.CertificateManager.CertificateEngine = CertificateEngine.DefaultWindows;
//proxyServer.CertificateManager.CertificateEngine = CertificateEngine.DefaultWindows;
////Set a password for the .pfx file
////Set a password for the .pfx file
...
@@ -150,11 +153,9 @@ namespace Titanium.Web.Proxy.Examples.Wpf
...
@@ -150,11 +153,9 @@ 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
)
//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
)
{
{
...
@@ -174,11 +175,9 @@ namespace Titanium.Web.Proxy.Examples.Wpf
...
@@ -174,11 +175,9 @@ namespace Titanium.Web.Proxy.Examples.Wpf
}
}
});
});
if
(
e
.
HttpClient
.
ConnectRequest
?.
TunnelType
==
TunnelType
.
Http2
)
//if (e.HttpClient.ConnectRequest?.TunnelType == TunnelType.Http2)
{
//{
// GetRequestBody for HTTP/2 currently not supported
//}
return
;
}
if
(
item
!=
null
)
if
(
item
!=
null
)
{
{
...
...
src/Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
View file @
06afb6fd
...
@@ -28,6 +28,8 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -28,6 +28,8 @@ namespace Titanium.Web.Proxy.EventArguments
/// </summary>
/// </summary>
private
bool
reRequest
;
private
bool
reRequest
;
internal
TaskCompletionSource
<
bool
>
ReadHttp2BodyTaskCompletionSource
;
/// <summary>
/// <summary>
/// Constructor to initialize the proxy
/// Constructor to initialize the proxy
/// </summary>
/// </summary>
...
@@ -88,6 +90,18 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -88,6 +90,18 @@ namespace Titanium.Web.Proxy.EventArguments
// If not already read (not cached yet)
// If not already read (not cached yet)
if
(!
request
.
IsBodyRead
)
if
(!
request
.
IsBodyRead
)
{
if
(
request
.
HttpVersion
==
HttpVersion
.
Version20
)
{
request
.
Http2BodyData
=
new
MemoryStream
();
request
.
ReadHttp2BodyTaskCompletionSource
=
new
TaskCompletionSource
<
bool
>();
// signal to HTTP/2 copy frame method to continue
ReadHttp2BodyTaskCompletionSource
.
SetResult
(
true
);
await
request
.
ReadHttp2BodyTaskCompletionSource
.
Task
;
}
else
{
{
var
body
=
await
readBodyAsync
(
true
,
cancellationToken
);
var
body
=
await
readBodyAsync
(
true
,
cancellationToken
);
request
.
Body
=
body
;
request
.
Body
=
body
;
...
@@ -98,6 +112,7 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -98,6 +112,7 @@ namespace Titanium.Web.Proxy.EventArguments
OnDataSent
(
body
,
0
,
body
.
Length
);
OnDataSent
(
body
,
0
,
body
.
Length
);
}
}
}
}
}
/// <summary>
/// <summary>
/// reinit response object
/// reinit response object
...
@@ -139,6 +154,18 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -139,6 +154,18 @@ namespace Titanium.Web.Proxy.EventArguments
// If not already read (not cached yet)
// If not already read (not cached yet)
if
(!
response
.
IsBodyRead
)
if
(!
response
.
IsBodyRead
)
{
if
(
response
.
HttpVersion
==
HttpVersion
.
Version20
)
{
response
.
Http2BodyData
=
new
MemoryStream
();
response
.
ReadHttp2BodyTaskCompletionSource
=
new
TaskCompletionSource
<
bool
>();
// signal to HTTP/2 copy frame method to continue
ReadHttp2BodyTaskCompletionSource
.
SetResult
(
true
);
await
response
.
ReadHttp2BodyTaskCompletionSource
.
Task
;
}
else
{
{
var
body
=
await
readBodyAsync
(
false
,
cancellationToken
);
var
body
=
await
readBodyAsync
(
false
,
cancellationToken
);
response
.
Body
=
body
;
response
.
Body
=
body
;
...
@@ -149,6 +176,7 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -149,6 +176,7 @@ namespace Titanium.Web.Proxy.EventArguments
OnDataReceived
(
body
,
0
,
body
.
Length
);
OnDataReceived
(
body
,
0
,
body
.
Length
);
}
}
}
}
}
private
async
Task
<
byte
[
]>
readBodyAsync
(
bool
isRequest
,
CancellationToken
cancellationToken
)
private
async
Task
<
byte
[
]>
readBodyAsync
(
bool
isRequest
,
CancellationToken
cancellationToken
)
{
{
...
...
src/Titanium.Web.Proxy/Http/RequestResponseBase.cs
View file @
06afb6fd
...
@@ -3,6 +3,7 @@ using System.ComponentModel;
...
@@ -3,6 +3,7 @@ using System.ComponentModel;
using
System.Diagnostics.CodeAnalysis
;
using
System.Diagnostics.CodeAnalysis
;
using
System.IO
;
using
System.IO
;
using
System.Text
;
using
System.Text
;
using
System.Threading.Tasks
;
using
Titanium.Web.Proxy.Compression
;
using
Titanium.Web.Proxy.Compression
;
using
Titanium.Web.Proxy.Extensions
;
using
Titanium.Web.Proxy.Extensions
;
using
Titanium.Web.Proxy.Helpers
;
using
Titanium.Web.Proxy.Helpers
;
...
@@ -49,6 +50,10 @@ namespace Titanium.Web.Proxy.Http
...
@@ -49,6 +50,10 @@ namespace Titanium.Web.Proxy.Http
/// </summary>
/// </summary>
internal
string
OriginalContentEncoding
{
get
;
set
;
}
internal
string
OriginalContentEncoding
{
get
;
set
;
}
internal
TaskCompletionSource
<
bool
>
ReadHttp2BodyTaskCompletionSource
;
internal
MemoryStream
Http2BodyData
;
/// <summary>
/// <summary>
/// Keeps the body data after the session is finished.
/// Keeps the body data after the session is finished.
/// </summary>
/// </summary>
...
...
src/Titanium.Web.Proxy/Http2/Http2Helper.cs
View file @
06afb6fd
...
@@ -62,6 +62,8 @@ namespace Titanium.Web.Proxy.Http2
...
@@ -62,6 +62,8 @@ namespace Titanium.Web.Proxy.Http2
int
bufferSize
,
Guid
connectionId
,
bool
isClient
,
CancellationToken
cancellationToken
,
int
bufferSize
,
Guid
connectionId
,
bool
isClient
,
CancellationToken
cancellationToken
,
ExceptionHandler
exceptionFunc
)
ExceptionHandler
exceptionFunc
)
{
{
decoder
=
new
Decoder
(
8192
,
4096
*
16
);
var
headerBuffer
=
new
byte
[
9
];
var
headerBuffer
=
new
byte
[
9
];
var
buffer
=
new
byte
[
32768
];
var
buffer
=
new
byte
[
32768
];
while
(
true
)
while
(
true
)
...
@@ -96,6 +98,27 @@ namespace Titanium.Web.Proxy.Http2
...
@@ -96,6 +98,27 @@ namespace Titanium.Web.Proxy.Http2
{
{
endStream
=
true
;
endStream
=
true
;
}
}
if
(!
sessions
.
TryGetValue
(
streamId
,
out
var
args
))
{
throw
new
ProxyHttpException
(
"HTTP Body data received before any header frame."
,
null
,
args
);
}
var
rr
=
isClient
?
(
RequestResponseBase
)
args
.
HttpClient
.
Request
:
args
.
HttpClient
.
Response
;
if
(
rr
.
ReadHttp2BodyTaskCompletionSource
!=
null
)
{
// Get body method was called in the "before" event handler
var
data
=
rr
.
Http2BodyData
;
data
.
Write
(
buffer
,
0
,
length
);
if
(
endStream
)
{
rr
.
Body
=
data
.
ToArray
();
rr
.
IsBodyRead
=
true
;
rr
.
ReadHttp2BodyTaskCompletionSource
.
SetResult
(
true
);
}
}
}
}
else
if
(
type
==
1
/*headers*/
)
else
if
(
type
==
1
/*headers*/
)
{
{
...
@@ -127,7 +150,6 @@ namespace Titanium.Web.Proxy.Http2
...
@@ -127,7 +150,6 @@ namespace Titanium.Web.Proxy.Http2
if
(!
sessions
.
TryGetValue
(
streamId
,
out
var
args
))
if
(!
sessions
.
TryGetValue
(
streamId
,
out
var
args
))
{
{
// todo: remove sessions when finished, otherwise it will be a "memory leak"
args
=
sessionFactory
();
args
=
sessionFactory
();
sessions
.
TryAdd
(
streamId
,
args
);
sessions
.
TryAdd
(
streamId
,
args
);
}
}
...
@@ -149,16 +171,18 @@ namespace Titanium.Web.Proxy.Http2
...
@@ -149,16 +171,18 @@ namespace Titanium.Web.Proxy.Http2
if
(
isClient
)
if
(
isClient
)
{
{
args
.
HttpClient
.
Request
.
HttpVersion
=
HttpVersion
.
Version20
;
var
request
=
args
.
HttpClient
.
Request
;
args
.
HttpClient
.
Request
.
Method
=
headerListener
.
Method
;
request
.
HttpVersion
=
HttpVersion
.
Version20
;
args
.
HttpClient
.
Request
.
OriginalUrl
=
headerListener
.
Status
;
request
.
Method
=
headerListener
.
Method
;
args
.
HttpClient
.
Request
.
RequestUri
=
headerListener
.
GetUri
();
request
.
OriginalUrl
=
headerListener
.
Status
;
request
.
RequestUri
=
headerListener
.
GetUri
();
}
}
else
else
{
{
args
.
HttpClient
.
Response
.
HttpVersion
=
HttpVersion
.
Version20
;
var
response
=
args
.
HttpClient
.
Response
;
response
.
HttpVersion
=
HttpVersion
.
Version20
;
int
.
TryParse
(
headerListener
.
Status
,
out
int
statusCode
);
int
.
TryParse
(
headerListener
.
Status
,
out
int
statusCode
);
args
.
HttpClient
.
R
esponse
.
StatusCode
=
statusCode
;
r
esponse
.
StatusCode
=
statusCode
;
}
}
}
}
catch
(
Exception
ex
)
catch
(
Exception
ex
)
...
@@ -168,7 +192,18 @@ namespace Titanium.Web.Proxy.Http2
...
@@ -168,7 +192,18 @@ namespace Titanium.Web.Proxy.Http2
if
(
endHeaders
)
if
(
endHeaders
)
{
{
await
onBeforeRequestResponse
(
args
);
var
handler
=
onBeforeRequestResponse
(
args
);
var
tcs
=
new
TaskCompletionSource
<
bool
>();
args
.
ReadHttp2BodyTaskCompletionSource
=
tcs
;
if
(
handler
==
await
Task
.
WhenAny
(
handler
,
tcs
.
Task
))
{
tcs
.
SetResult
(
true
);
}
var
rr
=
isClient
?
(
RequestResponseBase
)
args
.
HttpClient
.
Request
:
args
.
HttpClient
.
Response
;
rr
.
Locked
=
true
;
}
}
}
}
...
@@ -186,7 +221,7 @@ namespace Titanium.Web.Proxy.Http2
...
@@ -186,7 +221,7 @@ namespace Titanium.Web.Proxy.Http2
return
;
return
;
}
}
/*using (var fs = new System.IO.FileStream($@"c:\
11
\{connectionId}.{streamId}.dat", FileMode.Append))
/*using (var fs = new System.IO.FileStream($@"c:\
temp
\{connectionId}.{streamId}.dat", FileMode.Append))
{
{
fs.Write(headerBuffer, 0, headerBuffer.Length);
fs.Write(headerBuffer, 0, headerBuffer.Length);
fs.Write(buffer, 0, length);
fs.Write(buffer, 0, length);
...
...
src/Titanium.Web.Proxy/ProxyServer.cs
View file @
06afb6fd
...
@@ -149,7 +149,6 @@ namespace Titanium.Web.Proxy
...
@@ -149,7 +149,6 @@ namespace Titanium.Web.Proxy
/// Enable disable HTTP/2 support.
/// Enable disable HTTP/2 support.
/// Warning: HTTP/2 support is very limited
/// Warning: HTTP/2 support is very limited
/// - only enabled when both client and server supports it (no protocol changing in proxy)
/// - 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)
/// - cannot modify the request/response (e.g header modifications in BeforeRequest/Response events are ignored)
/// </summary>
/// </summary>
public
bool
EnableHttp2
{
get
;
set
;
}
=
false
;
public
bool
EnableHttp2
{
get
;
set
;
}
=
false
;
...
...
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