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
36be993a
Commit
36be993a
authored
Apr 14, 2018
by
Honfika
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
more cancellationtokens
parent
3aa4f2fd
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
163 additions
and
142 deletions
+163
-142
SessionEventArgs.cs
Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
+28
-28
ExplicitClientHandler.cs
Titanium.Web.Proxy/ExplicitClientHandler.cs
+1
-1
HttpWriter.cs
Titanium.Web.Proxy/Helpers/HttpWriter.cs
+42
-36
HeaderParser.cs
Titanium.Web.Proxy/Http/HeaderParser.cs
+3
-2
HttpWebClient.cs
Titanium.Web.Proxy/Http/HttpWebClient.cs
+15
-14
GenericResponse.cs
Titanium.Web.Proxy/Http/Responses/GenericResponse.cs
+5
-0
TcpConnectionFactory.cs
Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs
+5
-5
RequestHandler.cs
Titanium.Web.Proxy/RequestHandler.cs
+17
-14
ResponseHandler.cs
Titanium.Web.Proxy/ResponseHandler.cs
+8
-7
Titanium.Web.Proxy.csproj
Titanium.Web.Proxy/Titanium.Web.Proxy.csproj
+39
-35
No files found.
Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
View file @
36be993a
...
...
@@ -86,7 +86,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// <summary>
/// Read request body content as bytes[] for current session
/// </summary>
private
async
Task
ReadRequestBodyAsync
()
private
async
Task
ReadRequestBodyAsync
(
CancellationToken
cancellationToken
)
{
WebSession
.
Request
.
EnsureBodyAvailable
(
false
);
...
...
@@ -95,7 +95,7 @@ namespace Titanium.Web.Proxy.EventArguments
//If not already read (not cached yet)
if
(!
request
.
IsBodyRead
)
{
var
body
=
await
ReadBodyAsync
(
true
);
var
body
=
await
ReadBodyAsync
(
true
,
cancellationToken
);
request
.
Body
=
body
;
//Now set the flag to true
...
...
@@ -108,10 +108,10 @@ namespace Titanium.Web.Proxy.EventArguments
/// <summary>
/// reinit response object
/// </summary>
internal
async
Task
ClearResponse
()
internal
async
Task
ClearResponse
(
CancellationToken
cancellationToken
)
{
//syphon out the response body from server
await
SyphonOutBodyAsync
(
false
);
await
SyphonOutBodyAsync
(
false
,
cancellationToken
);
WebSession
.
Response
=
new
Response
();
}
...
...
@@ -130,7 +130,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// <summary>
/// Read response body as byte[] for current response
/// </summary>
private
async
Task
ReadResponseBodyAsync
()
private
async
Task
ReadResponseBodyAsync
(
CancellationToken
cancellationToken
)
{
if
(!
WebSession
.
Request
.
Locked
)
{
...
...
@@ -146,7 +146,7 @@ namespace Titanium.Web.Proxy.EventArguments
//If not already read (not cached yet)
if
(!
response
.
IsBodyRead
)
{
var
body
=
await
ReadBodyAsync
(
false
);
var
body
=
await
ReadBodyAsync
(
false
,
cancellationToken
);
response
.
Body
=
body
;
//Now set the flag to true
...
...
@@ -156,7 +156,7 @@ namespace Titanium.Web.Proxy.EventArguments
}
}
private
async
Task
<
byte
[
]>
ReadBodyAsync
(
bool
isRequest
)
private
async
Task
<
byte
[
]>
ReadBodyAsync
(
bool
isRequest
,
CancellationToken
cancellationToken
)
{
using
(
var
bodyStream
=
new
MemoryStream
())
{
...
...
@@ -164,18 +164,18 @@ namespace Titanium.Web.Proxy.EventArguments
if
(
isRequest
)
{
await
CopyRequestBodyAsync
(
writer
,
TransformationMode
.
Uncompress
);
await
CopyRequestBodyAsync
(
writer
,
TransformationMode
.
Uncompress
,
cancellationToken
);
}
else
{
await
CopyResponseBodyAsync
(
writer
,
TransformationMode
.
Uncompress
);
await
CopyResponseBodyAsync
(
writer
,
TransformationMode
.
Uncompress
,
cancellationToken
);
}
return
bodyStream
.
ToArray
();
}
}
internal
async
Task
SyphonOutBodyAsync
(
bool
isRequest
)
internal
async
Task
SyphonOutBodyAsync
(
bool
isRequest
,
CancellationToken
cancellationToken
)
{
var
requestResponse
=
isRequest
?
(
RequestResponseBase
)
WebSession
.
Request
:
WebSession
.
Response
;
if
(
requestResponse
.
IsBodyRead
||
!
requestResponse
.
OriginalHasBody
)
...
...
@@ -186,7 +186,7 @@ namespace Titanium.Web.Proxy.EventArguments
using
(
var
bodyStream
=
new
MemoryStream
())
{
var
writer
=
new
HttpWriter
(
bodyStream
,
BufferSize
);
await
CopyBodyAsync
(
isRequest
,
writer
,
TransformationMode
.
None
,
null
);
await
CopyBodyAsync
(
isRequest
,
writer
,
TransformationMode
.
None
,
null
,
cancellationToken
);
}
}
...
...
@@ -194,7 +194,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// This is called when the request is PUT/POST/PATCH to read the body
/// </summary>
/// <returns></returns>
internal
async
Task
CopyRequestBodyAsync
(
HttpWriter
writer
,
TransformationMode
transformation
)
internal
async
Task
CopyRequestBodyAsync
(
HttpWriter
writer
,
TransformationMode
transformation
,
CancellationToken
cancellationToken
)
{
var
request
=
WebSession
.
Request
;
...
...
@@ -220,26 +220,26 @@ namespace Titanium.Web.Proxy.EventArguments
if
(
contentLength
>
copyStream
.
ReadBytes
)
{
var
headers
=
new
HeaderCollection
();
await
HeaderParser
.
ReadHeaders
(
copyStreamReader
,
headers
);
await
HeaderParser
.
ReadHeaders
(
copyStreamReader
,
headers
,
cancellationToken
);
OnMultipartRequestPartSent
(
boundary
,
headers
);
}
}
await
copyStream
.
FlushAsync
();
await
copyStream
.
FlushAsync
(
cancellationToken
);
}
}
else
{
await
CopyBodyAsync
(
true
,
writer
,
transformation
,
OnDataSent
);
await
CopyBodyAsync
(
true
,
writer
,
transformation
,
OnDataSent
,
cancellationToken
);
}
}
internal
async
Task
CopyResponseBodyAsync
(
HttpWriter
writer
,
TransformationMode
transformation
)
internal
async
Task
CopyResponseBodyAsync
(
HttpWriter
writer
,
TransformationMode
transformation
,
CancellationToken
cancellationToken
)
{
await
CopyBodyAsync
(
false
,
writer
,
transformation
,
OnDataReceived
);
await
CopyBodyAsync
(
false
,
writer
,
transformation
,
OnDataReceived
,
cancellationToken
);
}
private
async
Task
CopyBodyAsync
(
bool
isRequest
,
HttpWriter
writer
,
TransformationMode
transformation
,
Action
<
byte
[],
int
,
int
>
onCopy
)
private
async
Task
CopyBodyAsync
(
bool
isRequest
,
HttpWriter
writer
,
TransformationMode
transformation
,
Action
<
byte
[],
int
,
int
>
onCopy
,
CancellationToken
cancellationToken
)
{
var
stream
=
GetStream
(
isRequest
);
var
reader
=
GetStreamReader
(
isRequest
);
...
...
@@ -250,7 +250,7 @@ namespace Titanium.Web.Proxy.EventArguments
long
contentLength
=
requestResponse
.
ContentLength
;
if
(
transformation
==
TransformationMode
.
None
)
{
await
writer
.
CopyBodyAsync
(
reader
,
isChunked
,
contentLength
,
onCopy
);
await
writer
.
CopyBodyAsync
(
reader
,
isChunked
,
contentLength
,
onCopy
,
cancellationToken
);
return
;
}
...
...
@@ -271,7 +271,7 @@ namespace Titanium.Web.Proxy.EventArguments
var
bufStream
=
new
CustomBufferedStream
(
s
,
BufferSize
,
true
);
reader
=
new
CustomBinaryReader
(
bufStream
,
BufferSize
);
await
writer
.
CopyBodyAsync
(
reader
,
false
,
-
1
,
onCopy
);
await
writer
.
CopyBodyAsync
(
reader
,
false
,
-
1
,
onCopy
,
cancellationToken
);
}
finally
{
...
...
@@ -349,11 +349,11 @@ namespace Titanium.Web.Proxy.EventArguments
/// Gets the request body as bytes
/// </summary>
/// <returns></returns>
public
async
Task
<
byte
[
]>
GetRequestBody
()
public
async
Task
<
byte
[
]>
GetRequestBody
(
CancellationToken
cancellationToken
=
default
(
CancellationToken
)
)
{
if
(!
WebSession
.
Request
.
IsBodyRead
)
{
await
ReadRequestBodyAsync
();
await
ReadRequestBodyAsync
(
cancellationToken
);
}
return
WebSession
.
Request
.
Body
;
...
...
@@ -363,11 +363,11 @@ namespace Titanium.Web.Proxy.EventArguments
/// Gets the request body as string
/// </summary>
/// <returns></returns>
public
async
Task
<
string
>
GetRequestBodyAsString
()
public
async
Task
<
string
>
GetRequestBodyAsString
(
CancellationToken
cancellationToken
=
default
(
CancellationToken
)
)
{
if
(!
WebSession
.
Request
.
IsBodyRead
)
{
await
ReadRequestBodyAsync
();
await
ReadRequestBodyAsync
(
cancellationToken
);
}
return
WebSession
.
Request
.
BodyString
;
...
...
@@ -406,11 +406,11 @@ namespace Titanium.Web.Proxy.EventArguments
/// Gets the response body as byte array
/// </summary>
/// <returns></returns>
public
async
Task
<
byte
[
]>
GetResponseBody
()
public
async
Task
<
byte
[
]>
GetResponseBody
(
CancellationToken
cancellationToken
=
default
(
CancellationToken
)
)
{
if
(!
WebSession
.
Response
.
IsBodyRead
)
{
await
ReadResponseBodyAsync
();
await
ReadResponseBodyAsync
(
cancellationToken
);
}
return
WebSession
.
Response
.
Body
;
...
...
@@ -420,11 +420,11 @@ namespace Titanium.Web.Proxy.EventArguments
/// Gets the response body as string
/// </summary>
/// <returns></returns>
public
async
Task
<
string
>
GetResponseBodyAsString
()
public
async
Task
<
string
>
GetResponseBodyAsString
(
CancellationToken
cancellationToken
=
default
(
CancellationToken
)
)
{
if
(!
WebSession
.
Response
.
IsBodyRead
)
{
await
ReadResponseBodyAsync
();
await
ReadResponseBodyAsync
(
cancellationToken
);
}
return
WebSession
.
Response
.
BodyString
;
...
...
Titanium.Web.Proxy/ExplicitClientHandler.cs
View file @
36be993a
...
...
@@ -62,7 +62,7 @@ namespace Titanium.Web.Proxy
HttpVersion
=
version
};
await
HeaderParser
.
ReadHeaders
(
clientStreamReader
,
connectRequest
.
Headers
);
await
HeaderParser
.
ReadHeaders
(
clientStreamReader
,
connectRequest
.
Headers
,
cancellationTokenSource
.
Token
);
var
connectArgs
=
new
TunnelConnectSessionEventArgs
(
BufferSize
,
endPoint
,
connectRequest
,
cancellationTokenSource
,
ExceptionFunc
);
...
...
Titanium.Web.Proxy/Helpers/HttpWriter.cs
View file @
36be993a
...
...
@@ -29,17 +29,17 @@ namespace Titanium.Web.Proxy.Helpers
public
int
BufferSize
{
get
;
}
public
Task
WriteLineAsync
()
public
Task
WriteLineAsync
(
CancellationToken
cancellationToken
=
default
(
CancellationToken
)
)
{
return
WriteAsync
(
newLine
);
return
WriteAsync
(
newLine
,
cancellationToken
:
cancellationToken
);
}
public
Task
WriteAsync
(
string
value
)
public
Task
WriteAsync
(
string
value
,
CancellationToken
cancellationToken
=
default
(
CancellationToken
)
)
{
return
WriteAsyncInternal
(
value
,
false
);
return
WriteAsyncInternal
(
value
,
false
,
cancellationToken
);
}
private
Task
WriteAsyncInternal
(
string
value
,
bool
addNewLine
)
private
Task
WriteAsyncInternal
(
string
value
,
bool
addNewLine
,
CancellationToken
cancellationToken
)
{
int
newLineChars
=
addNewLine
?
newLine
.
Length
:
0
;
int
charCount
=
value
.
Length
;
...
...
@@ -57,7 +57,7 @@ namespace Titanium.Web.Proxy.Helpers
idx
+=
newLineChars
;
}
return
WriteAsync
(
buffer
,
0
,
idx
);
return
WriteAsync
(
buffer
,
0
,
idx
,
cancellationToken
);
}
finally
{
...
...
@@ -77,13 +77,13 @@ namespace Titanium.Web.Proxy.Helpers
idx
+=
newLineChars
;
}
return
WriteAsync
(
buffer
,
0
,
idx
);
return
WriteAsync
(
buffer
,
0
,
idx
,
cancellationToken
);
}
}
public
Task
WriteLineAsync
(
string
value
)
public
Task
WriteLineAsync
(
string
value
,
CancellationToken
cancellationToken
=
default
(
CancellationToken
)
)
{
return
WriteAsyncInternal
(
value
,
true
);
return
WriteAsyncInternal
(
value
,
true
,
cancellationToken
);
}
/// <summary>
...
...
@@ -91,31 +91,32 @@ namespace Titanium.Web.Proxy.Helpers
/// </summary>
/// <param name="headers"></param>
/// <param name="flush"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public
async
Task
WriteHeadersAsync
(
HeaderCollection
headers
,
bool
flush
=
true
)
public
async
Task
WriteHeadersAsync
(
HeaderCollection
headers
,
bool
flush
=
true
,
CancellationToken
cancellationToken
=
default
(
CancellationToken
)
)
{
foreach
(
var
header
in
headers
)
{
await
header
.
WriteToStreamAsync
(
this
);
}
await
WriteLineAsync
();
await
WriteLineAsync
(
cancellationToken
);
if
(
flush
)
{
await
FlushAsync
();
await
FlushAsync
(
cancellationToken
);
}
}
public
async
Task
WriteAsync
(
byte
[]
data
,
bool
flush
=
false
)
public
async
Task
WriteAsync
(
byte
[]
data
,
bool
flush
=
false
,
CancellationToken
cancellationToken
=
default
(
CancellationToken
)
)
{
await
WriteAsync
(
data
,
0
,
data
.
Length
);
await
WriteAsync
(
data
,
0
,
data
.
Length
,
cancellationToken
);
if
(
flush
)
{
await
FlushAsync
();
await
FlushAsync
(
cancellationToken
);
}
}
public
async
Task
WriteAsync
(
byte
[]
data
,
int
offset
,
int
count
,
bool
flush
,
CancellationToken
cancellationToken
)
public
async
Task
WriteAsync
(
byte
[]
data
,
int
offset
,
int
count
,
bool
flush
,
CancellationToken
cancellationToken
=
default
(
CancellationToken
)
)
{
await
WriteAsync
(
data
,
offset
,
count
,
cancellationToken
);
if
(
flush
)
...
...
@@ -129,15 +130,16 @@ namespace Titanium.Web.Proxy.Helpers
/// </summary>
/// <param name="data"></param>
/// <param name="isChunked"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
internal
Task
WriteBodyAsync
(
byte
[]
data
,
bool
isChunked
)
internal
Task
WriteBodyAsync
(
byte
[]
data
,
bool
isChunked
,
CancellationToken
cancellationToken
)
{
if
(
isChunked
)
{
return
WriteBodyChunkedAsync
(
data
);
return
WriteBodyChunkedAsync
(
data
,
cancellationToken
);
}
return
WriteAsync
(
data
);
return
WriteAsync
(
data
,
cancellationToken
:
cancellationToken
);
}
/// <summary>
...
...
@@ -148,14 +150,15 @@ namespace Titanium.Web.Proxy.Helpers
/// <param name="isChunked"></param>
/// <param name="contentLength"></param>
/// <param name="onCopy"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
internal
Task
CopyBodyAsync
(
CustomBinaryReader
streamReader
,
bool
isChunked
,
long
contentLength
,
Action
<
byte
[],
int
,
int
>
onCopy
)
Action
<
byte
[],
int
,
int
>
onCopy
,
CancellationToken
cancellationToken
)
{
//For chunked request we need to read data as they arrive, until we reach a chunk end symbol
if
(
isChunked
)
{
return
CopyBodyChunkedAsync
(
streamReader
,
onCopy
);
return
CopyBodyChunkedAsync
(
streamReader
,
onCopy
,
cancellationToken
);
}
//http 1.0 or the stream reader limits the stream
...
...
@@ -172,18 +175,19 @@ namespace Titanium.Web.Proxy.Helpers
/// Copies the given input bytes to output stream chunked
/// </summary>
/// <param name="data"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
private
async
Task
WriteBodyChunkedAsync
(
byte
[]
data
)
private
async
Task
WriteBodyChunkedAsync
(
byte
[]
data
,
CancellationToken
cancellationToken
)
{
var
chunkHead
=
Encoding
.
ASCII
.
GetBytes
(
data
.
Length
.
ToString
(
"x2"
));
await
WriteAsync
(
chunkHead
);
await
WriteLineAsync
();
await
WriteAsync
(
data
);
await
WriteLineAsync
();
await
WriteAsync
(
chunkHead
,
cancellationToken
:
cancellationToken
);
await
WriteLineAsync
(
cancellationToken
);
await
WriteAsync
(
data
,
cancellationToken
:
cancellationToken
);
await
WriteLineAsync
(
cancellationToken
);
await
WriteLineAsync
(
"0"
);
await
WriteLineAsync
();
await
WriteLineAsync
(
"0"
,
cancellationToken
);
await
WriteLineAsync
(
cancellationToken
);
}
/// <summary>
...
...
@@ -191,12 +195,13 @@ namespace Titanium.Web.Proxy.Helpers
/// </summary>
/// <param name="reader"></param>
/// <param name="onCopy"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
private
async
Task
CopyBodyChunkedAsync
(
CustomBinaryReader
reader
,
Action
<
byte
[],
int
,
int
>
onCopy
)
private
async
Task
CopyBodyChunkedAsync
(
CustomBinaryReader
reader
,
Action
<
byte
[],
int
,
int
>
onCopy
,
CancellationToken
cancellationToken
)
{
while
(
true
)
{
string
chunkHead
=
await
reader
.
ReadLineAsync
();
string
chunkHead
=
await
reader
.
ReadLineAsync
(
cancellationToken
);
int
idx
=
chunkHead
.
IndexOf
(
";"
);
if
(
idx
>=
0
)
{
...
...
@@ -205,17 +210,17 @@ namespace Titanium.Web.Proxy.Helpers
int
chunkSize
=
int
.
Parse
(
chunkHead
,
NumberStyles
.
HexNumber
);
await
WriteLineAsync
(
chunkHead
);
await
WriteLineAsync
(
chunkHead
,
cancellationToken
);
if
(
chunkSize
!=
0
)
{
await
CopyBytesFromStream
(
reader
,
chunkSize
,
onCopy
);
}
await
WriteLineAsync
();
await
WriteLineAsync
(
cancellationToken
);
//chunk trail
await
reader
.
ReadLineAsync
();
await
reader
.
ReadLineAsync
(
cancellationToken
);
if
(
chunkSize
==
0
)
{
...
...
@@ -263,15 +268,16 @@ namespace Titanium.Web.Proxy.Helpers
/// </summary>
/// <param name="requestResponse"></param>
/// <param name="flush"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
protected
async
Task
WriteAsync
(
RequestResponseBase
requestResponse
,
bool
flush
=
true
)
protected
async
Task
WriteAsync
(
RequestResponseBase
requestResponse
,
bool
flush
=
true
,
CancellationToken
cancellationToken
=
default
(
CancellationToken
)
)
{
var
body
=
requestResponse
.
CompressBodyAndUpdateContentLength
();
await
WriteHeadersAsync
(
requestResponse
.
Headers
,
flush
);
await
WriteHeadersAsync
(
requestResponse
.
Headers
,
flush
,
cancellationToken
);
if
(
body
!=
null
)
{
await
WriteBodyAsync
(
body
,
requestResponse
.
IsChunked
);
await
WriteBodyAsync
(
body
,
requestResponse
.
IsChunked
,
cancellationToken
);
}
}
}
...
...
Titanium.Web.Proxy/Http/HeaderParser.cs
View file @
36be993a
using
System
;
using
System.Threading
;
using
System.Threading.Tasks
;
using
StreamExtended.Network
;
using
Titanium.Web.Proxy.Shared
;
...
...
@@ -7,10 +8,10 @@ namespace Titanium.Web.Proxy.Http
{
internal
static
class
HeaderParser
{
internal
static
async
Task
ReadHeaders
(
CustomBinaryReader
reader
,
HeaderCollection
headerCollection
)
internal
static
async
Task
ReadHeaders
(
CustomBinaryReader
reader
,
HeaderCollection
headerCollection
,
CancellationToken
cancellationToken
)
{
string
tmpLine
;
while
(!
string
.
IsNullOrEmpty
(
tmpLine
=
await
reader
.
ReadLineAsync
()))
while
(!
string
.
IsNullOrEmpty
(
tmpLine
=
await
reader
.
ReadLineAsync
(
cancellationToken
)))
{
var
header
=
tmpLine
.
Split
(
ProxyConstants
.
ColonSplit
,
2
);
headerCollection
.
AddHeader
(
header
[
0
],
header
[
1
]);
...
...
Titanium.Web.Proxy/Http/HttpWebClient.cs
View file @
36be993a
using
System
;
using
System.IO
;
using
System.Net
;
using
System.Threading
;
using
System.Threading.Tasks
;
using
Titanium.Web.Proxy.Extensions
;
using
Titanium.Web.Proxy.Models
;
...
...
@@ -79,7 +80,7 @@ namespace Titanium.Web.Proxy.Http
/// Prepare and send the http(s) request
/// </summary>
/// <returns></returns>
internal
async
Task
SendRequest
(
bool
enable100ContinueBehaviour
,
bool
isTransparent
)
internal
async
Task
SendRequest
(
bool
enable100ContinueBehaviour
,
bool
isTransparent
,
CancellationToken
cancellationToken
)
{
var
upstreamProxy
=
ServerConnection
.
UpStreamProxy
;
...
...
@@ -90,7 +91,7 @@ namespace Titanium.Web.Proxy.Http
//prepare the request & headers
await
writer
.
WriteLineAsync
(
Request
.
CreateRequestLine
(
Request
.
Method
,
useUpstreamProxy
||
isTransparent
?
Request
.
OriginalUrl
:
Request
.
RequestUri
.
PathAndQuery
,
Request
.
HttpVersion
));
Request
.
HttpVersion
)
,
cancellationToken
);
//Send Authentication to Upstream proxy if needed
...
...
@@ -113,13 +114,13 @@ namespace Titanium.Web.Proxy.Http
}
}
await
writer
.
WriteLineAsync
();
await
writer
.
WriteLineAsync
(
cancellationToken
);
if
(
enable100ContinueBehaviour
)
{
if
(
Request
.
ExpectContinue
)
{
string
httpStatus
=
await
ServerConnection
.
StreamReader
.
ReadLineAsync
();
string
httpStatus
=
await
ServerConnection
.
StreamReader
.
ReadLineAsync
(
cancellationToken
);
Response
.
ParseResponseLine
(
httpStatus
,
out
_
,
out
int
responseStatusCode
,
out
string
responseStatusDescription
);
...
...
@@ -129,13 +130,13 @@ namespace Titanium.Web.Proxy.Http
&&
responseStatusDescription
.
EqualsIgnoreCase
(
"continue"
))
{
Request
.
Is100Continue
=
true
;
await
ServerConnection
.
StreamReader
.
ReadLineAsync
();
await
ServerConnection
.
StreamReader
.
ReadLineAsync
(
cancellationToken
);
}
else
if
(
responseStatusCode
==
(
int
)
HttpStatusCode
.
ExpectationFailed
&&
responseStatusDescription
.
EqualsIgnoreCase
(
"expectation failed"
))
{
Request
.
ExpectationFailed
=
true
;
await
ServerConnection
.
StreamReader
.
ReadLineAsync
();
await
ServerConnection
.
StreamReader
.
ReadLineAsync
(
cancellationToken
);
}
}
}
...
...
@@ -145,7 +146,7 @@ namespace Titanium.Web.Proxy.Http
/// Receive and parse the http response from server
/// </summary>
/// <returns></returns>
internal
async
Task
ReceiveResponse
()
internal
async
Task
ReceiveResponse
(
CancellationToken
cancellationToken
)
{
//return if this is already read
if
(
Response
.
StatusCode
!=
0
)
...
...
@@ -153,7 +154,7 @@ namespace Titanium.Web.Proxy.Http
return
;
}
string
httpStatus
=
await
ServerConnection
.
StreamReader
.
ReadLineAsync
();
string
httpStatus
=
await
ServerConnection
.
StreamReader
.
ReadLineAsync
(
cancellationToken
);
if
(
httpStatus
==
null
)
{
throw
new
IOException
();
...
...
@@ -161,7 +162,7 @@ namespace Titanium.Web.Proxy.Http
if
(
httpStatus
==
string
.
Empty
)
{
httpStatus
=
await
ServerConnection
.
StreamReader
.
ReadLineAsync
();
httpStatus
=
await
ServerConnection
.
StreamReader
.
ReadLineAsync
(
cancellationToken
);
}
Response
.
ParseResponseLine
(
httpStatus
,
out
var
version
,
out
int
statusCode
,
out
string
statusDescription
);
...
...
@@ -177,10 +178,10 @@ namespace Titanium.Web.Proxy.Http
//Read the next line after 100-continue
Response
.
Is100Continue
=
true
;
Response
.
StatusCode
=
0
;
await
ServerConnection
.
StreamReader
.
ReadLineAsync
();
await
ServerConnection
.
StreamReader
.
ReadLineAsync
(
cancellationToken
);
//now receive response
await
ReceiveResponse
();
await
ReceiveResponse
(
cancellationToken
);
return
;
}
...
...
@@ -190,15 +191,15 @@ namespace Titanium.Web.Proxy.Http
//read next line after expectation failed response
Response
.
ExpectationFailed
=
true
;
Response
.
StatusCode
=
0
;
await
ServerConnection
.
StreamReader
.
ReadLineAsync
();
await
ServerConnection
.
StreamReader
.
ReadLineAsync
(
cancellationToken
);
//now receive response
await
ReceiveResponse
();
await
ReceiveResponse
(
cancellationToken
);
return
;
}
//Read the response headers in to unique and non-unique header collections
await
HeaderParser
.
ReadHeaders
(
ServerConnection
.
StreamReader
,
Response
.
Headers
);
await
HeaderParser
.
ReadHeaders
(
ServerConnection
.
StreamReader
,
Response
.
Headers
,
cancellationToken
);
}
/// <summary>
...
...
Titanium.Web.Proxy/Http/Responses/GenericResponse.cs
View file @
36be993a
using
System.Net
;
using
System.Web
;
namespace
Titanium.Web.Proxy.Http.Responses
{
...
...
@@ -15,9 +16,13 @@ namespace Titanium.Web.Proxy.Http.Responses
{
StatusCode
=
(
int
)
status
;
#if NET45
StatusDescription
=
HttpWorkerRequest
.
GetStatusDescription
(
StatusCode
);
#else
//todo: this is not really correct, status description should contain spaces, too
//see: https://tools.ietf.org/html/rfc7231#section-6.1
StatusDescription
=
status
.
ToString
();
#endif
}
/// <summary>
...
...
Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs
View file @
36be993a
...
...
@@ -74,19 +74,19 @@ namespace Titanium.Web.Proxy.Network.Tcp
if
(
useUpstreamProxy
&&
(
isConnect
||
isHttps
))
{
var
writer
=
new
HttpRequestWriter
(
stream
,
proxyServer
.
BufferSize
);
await
writer
.
WriteLineAsync
(
$"CONNECT
{
remoteHostName
}
:
{
remotePort
}
HTTP/
{
httpVersion
}
"
);
await
writer
.
WriteLineAsync
(
$"Host:
{
remoteHostName
}
:
{
remotePort
}
"
);
await
writer
.
WriteLineAsync
(
$"
{
KnownHeaders
.
Connection
}
:
{
KnownHeaders
.
ConnectionKeepAlive
}
"
);
await
writer
.
WriteLineAsync
(
$"CONNECT
{
remoteHostName
}
:
{
remotePort
}
HTTP/
{
httpVersion
}
"
,
cancellationToken
);
await
writer
.
WriteLineAsync
(
$"Host:
{
remoteHostName
}
:
{
remotePort
}
"
,
cancellationToken
);
await
writer
.
WriteLineAsync
(
$"
{
KnownHeaders
.
Connection
}
:
{
KnownHeaders
.
ConnectionKeepAlive
}
"
,
cancellationToken
);
if
(!
string
.
IsNullOrEmpty
(
externalProxy
.
UserName
)
&&
externalProxy
.
Password
!=
null
)
{
await
HttpHeader
.
ProxyConnectionKeepAlive
.
WriteToStreamAsync
(
writer
);
await
writer
.
WriteLineAsync
(
KnownHeaders
.
ProxyAuthorization
+
": Basic "
+
Convert
.
ToBase64String
(
Encoding
.
UTF8
.
GetBytes
(
externalProxy
.
UserName
+
":"
+
externalProxy
.
Password
)));
externalProxy
.
UserName
+
":"
+
externalProxy
.
Password
))
,
cancellationToken
);
}
await
writer
.
WriteLineAsync
();
await
writer
.
WriteLineAsync
(
cancellationToken
);
using
(
var
reader
=
new
CustomBinaryReader
(
stream
,
proxyServer
.
BufferSize
))
{
...
...
Titanium.Web.Proxy/RequestHandler.cs
View file @
36be993a
...
...
@@ -56,20 +56,22 @@ namespace Titanium.Web.Proxy
while
(
true
)
{
// read the request line
string
httpCmd
=
await
clientStreamReader
.
ReadLineAsync
();
string
httpCmd
=
await
clientStreamReader
.
ReadLineAsync
(
cancellationTokenSource
.
Token
);
if
(
httpCmd
==
"PRI * HTTP/2.0"
)
{
// HTTP/2 Connection Preface
string
line
=
await
clientStreamReader
.
ReadLineAsync
();
string
line
=
await
clientStreamReader
.
ReadLineAsync
(
cancellationTokenSource
.
Token
);
if
(
line
!=
string
.
Empty
)
throw
new
Exception
(
$"HTTP/2 Protocol violation. Empty string expected, '
{
line
}
' received"
);
line
=
await
clientStreamReader
.
ReadLineAsync
();
line
=
await
clientStreamReader
.
ReadLineAsync
(
cancellationTokenSource
.
Token
);
if
(
line
!=
"SM"
)
throw
new
Exception
(
$"HTTP/2 Protocol violation. 'SM' expected, '
{
line
}
' received"
);
line
=
await
clientStreamReader
.
ReadLineAsync
();
line
=
await
clientStreamReader
.
ReadLineAsync
(
cancellationTokenSource
.
Token
);
if
(
line
!=
string
.
Empty
)
throw
new
Exception
(
$"HTTP/2 Protocol violation. Empty string expected, '
{
line
}
' received"
);
// todo
var
buffer
=
new
byte
[
1024
];
await
clientStreamReader
.
ReadBytesAsync
(
buffer
,
0
,
3
,
cancellationTokenSource
.
Token
);
}
if
(
string
.
IsNullOrEmpty
(
httpCmd
))
...
...
@@ -91,7 +93,7 @@ namespace Titanium.Web.Proxy
out
var
version
);
//Read the request headers in to unique and non-unique header collections
await
HeaderParser
.
ReadHeaders
(
clientStreamReader
,
args
.
WebSession
.
Request
.
Headers
);
await
HeaderParser
.
ReadHeaders
(
clientStreamReader
,
args
.
WebSession
.
Request
.
Headers
,
cancellationTokenSource
.
Token
);
Uri
httpRemoteUri
;
if
(
uriSchemeRegex
.
IsMatch
(
httpUrl
))
...
...
@@ -171,7 +173,7 @@ namespace Titanium.Web.Proxy
if
(
request
.
CancelRequest
)
{
//syphon out the request body from client before setting the new body
await
args
.
SyphonOutBodyAsync
(
true
);
await
args
.
SyphonOutBodyAsync
(
true
,
cancellationTokenSource
.
Token
);
await
HandleHttpSessionResponse
(
args
);
...
...
@@ -205,7 +207,7 @@ namespace Titanium.Web.Proxy
//prepare the prefix content
await
connection
.
StreamWriter
.
WriteLineAsync
(
httpCmd
);
await
connection
.
StreamWriter
.
WriteHeadersAsync
(
request
.
Headers
);
string
httpStatus
=
await
connection
.
StreamReader
.
ReadLineAsync
();
string
httpStatus
=
await
connection
.
StreamReader
.
ReadLineAsync
(
cancellationTokenSource
.
Token
);
Response
.
ParseResponseLine
(
httpStatus
,
out
var
responseVersion
,
out
int
responseStatusCode
,
...
...
@@ -214,7 +216,7 @@ namespace Titanium.Web.Proxy
response
.
StatusCode
=
responseStatusCode
;
response
.
StatusDescription
=
responseStatusDescription
;
await
HeaderParser
.
ReadHeaders
(
connection
.
StreamReader
,
response
.
Headers
);
await
HeaderParser
.
ReadHeaders
(
connection
.
StreamReader
,
response
.
Headers
,
cancellationTokenSource
.
Token
);
if
(!
args
.
IsTransparent
)
{
...
...
@@ -287,6 +289,7 @@ namespace Titanium.Web.Proxy
{
try
{
var
cancellationToken
=
args
.
CancellationTokenSource
.
Token
;
var
request
=
args
.
WebSession
.
Request
;
request
.
Locked
=
true
;
...
...
@@ -297,7 +300,7 @@ namespace Titanium.Web.Proxy
if
(
request
.
ExpectContinue
)
{
args
.
WebSession
.
SetConnection
(
connection
);
await
args
.
WebSession
.
SendRequest
(
Enable100ContinueBehaviour
,
args
.
IsTransparent
);
await
args
.
WebSession
.
SendRequest
(
Enable100ContinueBehaviour
,
args
.
IsTransparent
,
cancellationToken
);
}
//If 100 continue was the response inform that to the client
...
...
@@ -309,13 +312,13 @@ namespace Titanium.Web.Proxy
{
await
clientStreamWriter
.
WriteResponseStatusAsync
(
args
.
WebSession
.
Response
.
HttpVersion
,
(
int
)
HttpStatusCode
.
Continue
,
"Continue"
);
await
clientStreamWriter
.
WriteLineAsync
();
await
clientStreamWriter
.
WriteLineAsync
(
cancellationToken
);
}
else
if
(
request
.
ExpectationFailed
)
{
await
clientStreamWriter
.
WriteResponseStatusAsync
(
args
.
WebSession
.
Response
.
HttpVersion
,
(
int
)
HttpStatusCode
.
ExpectationFailed
,
"Expectation Failed"
);
await
clientStreamWriter
.
WriteLineAsync
();
await
clientStreamWriter
.
WriteLineAsync
(
cancellationToken
);
}
}
...
...
@@ -323,7 +326,7 @@ namespace Titanium.Web.Proxy
if
(!
request
.
ExpectContinue
)
{
args
.
WebSession
.
SetConnection
(
connection
);
await
args
.
WebSession
.
SendRequest
(
Enable100ContinueBehaviour
,
args
.
IsTransparent
);
await
args
.
WebSession
.
SendRequest
(
Enable100ContinueBehaviour
,
args
.
IsTransparent
,
cancellationToken
);
}
//check if content-length is > 0
...
...
@@ -332,7 +335,7 @@ namespace Titanium.Web.Proxy
if
(
request
.
IsBodyRead
)
{
var
writer
=
args
.
WebSession
.
ServerConnection
.
StreamWriter
;
await
writer
.
WriteBodyAsync
(
body
,
request
.
IsChunked
);
await
writer
.
WriteBodyAsync
(
body
,
request
.
IsChunked
,
cancellationToken
);
}
else
{
...
...
@@ -341,7 +344,7 @@ namespace Titanium.Web.Proxy
if
(
request
.
HasBody
)
{
HttpWriter
writer
=
args
.
WebSession
.
ServerConnection
.
StreamWriter
;
await
args
.
CopyRequestBodyAsync
(
writer
,
TransformationMode
.
None
);
await
args
.
CopyRequestBodyAsync
(
writer
,
TransformationMode
.
None
,
cancellationToken
);
}
}
}
...
...
Titanium.Web.Proxy/ResponseHandler.cs
View file @
36be993a
...
...
@@ -22,8 +22,9 @@ namespace Titanium.Web.Proxy
{
try
{
var
cancellationToken
=
args
.
CancellationTokenSource
.
Token
;
//read response & headers from server
await
args
.
WebSession
.
ReceiveResponse
();
await
args
.
WebSession
.
ReceiveResponse
(
cancellationToken
);
var
response
=
args
.
WebSession
.
Response
;
args
.
ReRequest
=
false
;
...
...
@@ -61,7 +62,7 @@ namespace Titanium.Web.Proxy
if
(!
response
.
TerminateResponse
)
{
//syphon out the response body from server before setting the new body
await
args
.
SyphonOutBodyAsync
(
false
);
await
args
.
SyphonOutBodyAsync
(
false
,
cancellationToken
);
}
else
{
...
...
@@ -77,7 +78,7 @@ namespace Titanium.Web.Proxy
if
(
args
.
ReRequest
)
{
//clear current response
await
args
.
ClearResponse
();
await
args
.
ClearResponse
(
cancellationToken
);
await
HandleHttpSessionRequestInternal
(
args
.
WebSession
.
ServerConnection
,
args
);
return
;
}
...
...
@@ -89,13 +90,13 @@ namespace Titanium.Web.Proxy
{
await
clientStreamWriter
.
WriteResponseStatusAsync
(
response
.
HttpVersion
,
(
int
)
HttpStatusCode
.
Continue
,
"Continue"
);
await
clientStreamWriter
.
WriteLineAsync
();
await
clientStreamWriter
.
WriteLineAsync
(
cancellationToken
);
}
else
if
(
response
.
ExpectationFailed
)
{
await
clientStreamWriter
.
WriteResponseStatusAsync
(
response
.
HttpVersion
,
(
int
)
HttpStatusCode
.
ExpectationFailed
,
"Expectation Failed"
);
await
clientStreamWriter
.
WriteLineAsync
();
await
clientStreamWriter
.
WriteLineAsync
(
cancellationToken
);
}
if
(!
args
.
IsTransparent
)
...
...
@@ -112,12 +113,12 @@ namespace Titanium.Web.Proxy
//Write back response status to client
await
clientStreamWriter
.
WriteResponseStatusAsync
(
response
.
HttpVersion
,
response
.
StatusCode
,
response
.
StatusDescription
);
await
clientStreamWriter
.
WriteHeadersAsync
(
response
.
Headers
);
await
clientStreamWriter
.
WriteHeadersAsync
(
response
.
Headers
,
cancellationToken
:
cancellationToken
);
//Write body if exists
if
(
response
.
HasBody
)
{
await
args
.
CopyResponseBodyAsync
(
clientStreamWriter
,
TransformationMode
.
None
);
await
args
.
CopyResponseBodyAsync
(
clientStreamWriter
,
TransformationMode
.
None
,
cancellationToken
);
}
}
}
...
...
Titanium.Web.Proxy/Titanium.Web.Proxy.csproj
View file @
36be993a
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net45;netstandard2.0</TargetFrameworks>
<RootNamespace>Titanium.Web.Proxy</RootNamespace>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net45;netstandard2.0</TargetFrameworks>
<RootNamespace>Titanium.Web.Proxy</RootNamespace>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<SignAssembly>True</SignAssembly>
<AssemblyOriginatorKeyFile>StrongNameKey.snk</AssemblyOriginatorKeyFile>
<DelaySign>False</DelaySign>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<LangVersion>7.1</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Portable.BouncyCastle" Version="1.8.2" />
<PackageReference Include="StreamExtended" Version="1.0.147-beta" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="Microsoft.Win32.Registry">
<Version>4.4.0</Version>
</PackageReference>
<PackageReference Include="System.Security.Principal.Windows">
<Version>4.4.1</Version>
</PackageReference>
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp2.1'">
<PackageReference Include="Microsoft.Win32.Registry">
<Version>4.4.0</Version>
</PackageReference>
<PackageReference Include="System.Security.Principal.Windows">
<Version>4.4.1</Version>
</PackageReference>
</ItemGroup>
<AssemblyOriginatorKeyFile>StrongNameKey.snk</AssemblyOriginatorKeyFile>
<DelaySign>False</DelaySign>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<LangVersion>7.1</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Portable.BouncyCastle" Version="1.8.2" />
<PackageReference Include="StreamExtended" Version="1.0.147-beta" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="Microsoft.Win32.Registry">
<Version>4.4.0</Version>
</PackageReference>
<PackageReference Include="System.Security.Principal.Windows">
<Version>4.4.1</Version>
</PackageReference>
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp2.1'">
<PackageReference Include="Microsoft.Win32.Registry">
<Version>4.4.0</Version>
</PackageReference>
<PackageReference Include="System.Security.Principal.Windows">
<Version>4.4.1</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>
<Reference Include="System.Web" />
</ItemGroup>
</Project>
\ No newline at end of file
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