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
7f45a971
Commit
7f45a971
authored
Dec 28, 2017
by
Honfika
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Multipart form data event, some streamextended classes added
parent
583695f3
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
114 additions
and
65 deletions
+114
-65
MultipartRequestPartSentEventArgs.cs
...Proxy/EventArguments/MultipartRequestPartSentEventArgs.cs
+18
-0
SessionEventArgs.cs
Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
+12
-0
HttpWebRequestExtensions.cs
Titanium.Web.Proxy/Extensions/HttpWebRequestExtensions.cs
+0
-22
HttpWebResponseExtensions.cs
Titanium.Web.Proxy/Extensions/HttpWebResponseExtensions.cs
+0
-19
StreamExtensions.cs
Titanium.Web.Proxy/Extensions/StreamExtensions.cs
+1
-0
HttpHelper.cs
Titanium.Web.Proxy/Helpers/HttpHelper.cs
+35
-4
HeaderParser.cs
Titanium.Web.Proxy/Http/HeaderParser.cs
+15
-2
Request.cs
Titanium.Web.Proxy/Http/Request.cs
+4
-1
Response.cs
Titanium.Web.Proxy/Http/Response.cs
+2
-1
RequestHandler.cs
Titanium.Web.Proxy/RequestHandler.cs
+27
-16
No files found.
Titanium.Web.Proxy/EventArguments/MultipartRequestPartSentEventArgs.cs
0 → 100644
View file @
7f45a971
using
System
;
using
Titanium.Web.Proxy.Http
;
namespace
Titanium.Web.Proxy.EventArguments
{
public
class
MultipartRequestPartSentEventArgs
:
EventArgs
{
public
string
Boundary
{
get
;
}
public
HeaderCollection
Headers
{
get
;
}
public
MultipartRequestPartSentEventArgs
(
string
boundary
,
HeaderCollection
headers
)
{
Boundary
=
boundary
;
Headers
=
headers
;
}
}
}
\ No newline at end of file
Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
View file @
7f45a971
...
@@ -42,6 +42,8 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -42,6 +42,8 @@ namespace Titanium.Web.Proxy.EventArguments
/// </summary>
/// </summary>
internal
ProxyClient
ProxyClient
{
get
;
set
;
}
internal
ProxyClient
ProxyClient
{
get
;
set
;
}
internal
bool
HasMulipartEventSubscribers
=>
MultipartRequestPartSent
!=
null
;
/// <summary>
/// <summary>
/// Returns a unique Id for this request/response session
/// Returns a unique Id for this request/response session
/// same as RequestId of WebSession
/// same as RequestId of WebSession
...
@@ -90,6 +92,11 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -90,6 +92,11 @@ namespace Titanium.Web.Proxy.EventArguments
public
event
EventHandler
<
DataEventArgs
>
DataReceived
;
public
event
EventHandler
<
DataEventArgs
>
DataReceived
;
/// <summary>
/// Occurs when multipart request part sent.
/// </summary>
public
event
EventHandler
<
MultipartRequestPartSentEventArgs
>
MultipartRequestPartSent
;
public
ProxyEndPoint
LocalEndPoint
;
public
ProxyEndPoint
LocalEndPoint
;
/// <summary>
/// <summary>
...
@@ -189,6 +196,11 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -189,6 +196,11 @@ namespace Titanium.Web.Proxy.EventArguments
DataReceived
?.
Invoke
(
this
,
new
DataEventArgs
(
buffer
,
offset
,
count
));
DataReceived
?.
Invoke
(
this
,
new
DataEventArgs
(
buffer
,
offset
,
count
));
}
}
internal
void
OnMultipartRequestPartSent
(
string
boundary
,
HeaderCollection
headers
)
{
MultipartRequestPartSent
?.
Invoke
(
this
,
new
MultipartRequestPartSentEventArgs
(
boundary
,
headers
));
}
/// <summary>
/// <summary>
/// Read response body as byte[] for current response
/// Read response body as byte[] for current response
/// </summary>
/// </summary>
...
...
Titanium.Web.Proxy/Extensions/HttpWebRequestExtensions.cs
deleted
100644 → 0
View file @
583695f3
using
System.Text
;
using
Titanium.Web.Proxy.Helpers
;
using
Titanium.Web.Proxy.Http
;
namespace
Titanium.Web.Proxy.Extensions
{
/// <summary>
/// Extensions on HttpWebSession object
/// </summary>
internal
static
class
HttpWebRequestExtensions
{
/// <summary>
/// parse the character encoding of request from request headers
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
internal
static
Encoding
GetEncoding
(
this
Request
request
)
{
return
HttpHelper
.
GetEncodingFromContentType
(
request
.
ContentType
);
}
}
}
Titanium.Web.Proxy/Extensions/HttpWebResponseExtensions.cs
deleted
100644 → 0
View file @
583695f3
using
System.Text
;
using
Titanium.Web.Proxy.Helpers
;
using
Titanium.Web.Proxy.Http
;
namespace
Titanium.Web.Proxy.Extensions
{
internal
static
class
HttpWebResponseExtensions
{
/// <summary>
/// Gets the character encoding of response from response headers
/// </summary>
/// <param name="response"></param>
/// <returns></returns>
internal
static
Encoding
GetResponseCharacterEncoding
(
this
Response
response
)
{
return
HttpHelper
.
GetEncodingFromContentType
(
response
.
ContentType
);
}
}
}
Titanium.Web.Proxy/Extensions/StreamExtensions.cs
View file @
7f45a971
...
@@ -17,6 +17,7 @@ namespace Titanium.Web.Proxy.Extensions
...
@@ -17,6 +17,7 @@ namespace Titanium.Web.Proxy.Extensions
/// <param name="input"></param>
/// <param name="input"></param>
/// <param name="output"></param>
/// <param name="output"></param>
/// <param name="onCopy"></param>
/// <param name="onCopy"></param>
/// <param name="bufferSize"></param>
internal
static
async
Task
CopyToAsync
(
this
Stream
input
,
Stream
output
,
Action
<
byte
[],
int
,
int
>
onCopy
,
int
bufferSize
)
internal
static
async
Task
CopyToAsync
(
this
Stream
input
,
Stream
output
,
Action
<
byte
[],
int
,
int
>
onCopy
,
int
bufferSize
)
{
{
byte
[]
buffer
=
new
byte
[
bufferSize
];
byte
[]
buffer
=
new
byte
[
bufferSize
];
...
...
Titanium.Web.Proxy/Helpers/HttpHelper.cs
View file @
7f45a971
...
@@ -8,7 +8,12 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -8,7 +8,12 @@ namespace Titanium.Web.Proxy.Helpers
{
{
private
static
readonly
Encoding
defaultEncoding
=
Encoding
.
GetEncoding
(
"ISO-8859-1"
);
private
static
readonly
Encoding
defaultEncoding
=
Encoding
.
GetEncoding
(
"ISO-8859-1"
);
public
static
Encoding
GetEncodingFromContentType
(
string
contentType
)
/// <summary>
/// Gets the character encoding of request/response from content-type header
/// </summary>
/// <param name="contentType"></param>
/// <returns></returns>
internal
static
Encoding
GetEncodingFromContentType
(
string
contentType
)
{
{
try
try
{
{
...
@@ -22,10 +27,10 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -22,10 +27,10 @@ namespace Titanium.Web.Proxy.Helpers
var
parameters
=
contentType
.
Split
(
ProxyConstants
.
SemiColonSplit
);
var
parameters
=
contentType
.
Split
(
ProxyConstants
.
SemiColonSplit
);
foreach
(
string
parameter
in
parameters
)
foreach
(
string
parameter
in
parameters
)
{
{
var
encodingS
plit
=
parameter
.
Split
(
ProxyConstants
.
EqualSplit
,
2
);
var
s
plit
=
parameter
.
Split
(
ProxyConstants
.
EqualSplit
,
2
);
if
(
encodingSplit
.
Length
==
2
&&
encodingS
plit
[
0
].
Trim
().
Equals
(
"charset"
,
StringComparison
.
CurrentCultureIgnoreCase
))
if
(
split
.
Length
==
2
&&
s
plit
[
0
].
Trim
().
Equals
(
"charset"
,
StringComparison
.
CurrentCultureIgnoreCase
))
{
{
string
value
=
encodingS
plit
[
1
];
string
value
=
s
plit
[
1
];
if
(
value
.
Equals
(
"x-user-defined"
,
StringComparison
.
OrdinalIgnoreCase
))
if
(
value
.
Equals
(
"x-user-defined"
,
StringComparison
.
OrdinalIgnoreCase
))
{
{
//todo: what is this?
//todo: what is this?
...
@@ -51,6 +56,32 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -51,6 +56,32 @@ namespace Titanium.Web.Proxy.Helpers
return
defaultEncoding
;
return
defaultEncoding
;
}
}
internal
static
string
GetBoundaryFromContentType
(
string
contentType
)
{
if
(
contentType
!=
null
)
{
//extract the boundary
var
parameters
=
contentType
.
Split
(
ProxyConstants
.
SemiColonSplit
);
foreach
(
string
parameter
in
parameters
)
{
var
split
=
parameter
.
Split
(
ProxyConstants
.
EqualSplit
,
2
);
if
(
split
.
Length
==
2
&&
split
[
0
].
Trim
().
Equals
(
"boundary"
,
StringComparison
.
CurrentCultureIgnoreCase
))
{
string
value
=
split
[
1
];
if
(
value
.
Length
>
2
&&
value
[
0
]
==
'"'
&&
value
[
value
.
Length
-
1
]
==
'"'
)
{
value
=
value
.
Substring
(
1
,
value
.
Length
-
2
);
}
return
value
;
}
}
}
//return null if not specified
return
null
;
}
/// <summary>
/// <summary>
/// Tries to get root domain from a given hostname
/// Tries to get root domain from a given hostname
/// Adapted from below answer
/// Adapted from below answer
...
...
Titanium.Web.Proxy/Http/HeaderParser.cs
View file @
7f45a971
using
StreamExtended.Network
;
using
System
;
using
StreamExtended.Network
;
using
System.Collections.Generic
;
using
System.Collections.Generic
;
using
System.Threading.Tasks
;
using
System.Threading.Tasks
;
using
Titanium.Web.Proxy.Models
;
using
Titanium.Web.Proxy.Models
;
...
@@ -25,7 +26,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -25,7 +26,7 @@ namespace Titanium.Web.Proxy.Http
{
{
nonUniqueResponseHeaders
[
newHeader
.
Name
].
Add
(
newHeader
);
nonUniqueResponseHeaders
[
newHeader
.
Name
].
Add
(
newHeader
);
}
}
//if header is alread in unique header collection then move both to non-unique collection
//if header is alread
y
in unique header collection then move both to non-unique collection
else
if
(
headers
.
ContainsKey
(
newHeader
.
Name
))
else
if
(
headers
.
ContainsKey
(
newHeader
.
Name
))
{
{
var
existing
=
headers
[
newHeader
.
Name
];
var
existing
=
headers
[
newHeader
.
Name
];
...
@@ -46,5 +47,17 @@ namespace Titanium.Web.Proxy.Http
...
@@ -46,5 +47,17 @@ namespace Titanium.Web.Proxy.Http
}
}
}
}
}
}
/// <summary>
/// Increase size of buffer and copy existing content to new buffer
/// </summary>
/// <param name="buffer"></param>
/// <param name="size"></param>
private
static
void
ResizeBuffer
(
ref
byte
[]
buffer
,
long
size
)
{
var
newBuffer
=
new
byte
[
size
];
Buffer
.
BlockCopy
(
buffer
,
0
,
newBuffer
,
0
,
buffer
.
Length
);
buffer
=
newBuffer
;
}
}
}
}
}
Titanium.Web.Proxy/Http/Request.cs
View file @
7f45a971
...
@@ -3,6 +3,7 @@ using System.ComponentModel;
...
@@ -3,6 +3,7 @@ using System.ComponentModel;
using
System.Text
;
using
System.Text
;
using
Titanium.Web.Proxy.Exceptions
;
using
Titanium.Web.Proxy.Exceptions
;
using
Titanium.Web.Proxy.Extensions
;
using
Titanium.Web.Proxy.Extensions
;
using
Titanium.Web.Proxy.Helpers
;
using
Titanium.Web.Proxy.Models
;
using
Titanium.Web.Proxy.Models
;
using
Titanium.Web.Proxy.Shared
;
using
Titanium.Web.Proxy.Shared
;
...
@@ -156,6 +157,8 @@ namespace Titanium.Web.Proxy.Http
...
@@ -156,6 +157,8 @@ namespace Titanium.Web.Proxy.Http
}
}
}
}
public
bool
IsMultipartFormData
=>
ContentType
?.
StartsWith
(
"multipart/form-data"
)
==
true
;
/// <summary>
/// <summary>
/// Request Url
/// Request Url
/// </summary>
/// </summary>
...
@@ -164,7 +167,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -164,7 +167,7 @@ namespace Titanium.Web.Proxy.Http
/// <summary>
/// <summary>
/// Encoding for this request
/// Encoding for this request
/// </summary>
/// </summary>
public
Encoding
Encoding
=>
this
.
GetEncoding
(
);
public
Encoding
Encoding
=>
HttpHelper
.
GetEncodingFromContentType
(
ContentType
);
/// <summary>
/// <summary>
/// Terminates the underlying Tcp Connection to client after current request
/// Terminates the underlying Tcp Connection to client after current request
...
...
Titanium.Web.Proxy/Http/Response.cs
View file @
7f45a971
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
using
System.ComponentModel
;
using
System.ComponentModel
;
using
System.Text
;
using
System.Text
;
using
Titanium.Web.Proxy.Extensions
;
using
Titanium.Web.Proxy.Extensions
;
using
Titanium.Web.Proxy.Helpers
;
using
Titanium.Web.Proxy.Models
;
using
Titanium.Web.Proxy.Models
;
using
Titanium.Web.Proxy.Shared
;
using
Titanium.Web.Proxy.Shared
;
...
@@ -36,7 +37,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -36,7 +37,7 @@ namespace Titanium.Web.Proxy.Http
/// <summary>
/// <summary>
/// Encoding used in response
/// Encoding used in response
/// </summary>
/// </summary>
public
Encoding
Encoding
=>
this
.
GetResponseCharacterEncoding
(
);
public
Encoding
Encoding
=>
HttpHelper
.
GetEncodingFromContentType
(
ContentType
);
/// <summary>
/// <summary>
/// Content encoding for this response
/// Content encoding for this response
...
...
Titanium.Web.Proxy/RequestHandler.cs
View file @
7f45a971
...
@@ -457,11 +457,12 @@ namespace Titanium.Web.Proxy
...
@@ -457,11 +457,12 @@ namespace Titanium.Web.Proxy
try
try
{
{
args
.
WebSession
.
Request
.
RequestLocked
=
true
;
var
request
=
args
.
WebSession
.
Request
;
request
.
RequestLocked
=
true
;
//if expect continue is enabled then send the headers first
//if expect continue is enabled then send the headers first
//and see if server would return 100 conitinue
//and see if server would return 100 conitinue
if
(
args
.
WebSession
.
R
equest
.
ExpectContinue
)
if
(
r
equest
.
ExpectContinue
)
{
{
args
.
WebSession
.
SetConnection
(
connection
);
args
.
WebSession
.
SetConnection
(
connection
);
await
args
.
WebSession
.
SendRequest
(
Enable100ContinueBehaviour
);
await
args
.
WebSession
.
SendRequest
(
Enable100ContinueBehaviour
);
...
@@ -470,12 +471,12 @@ namespace Titanium.Web.Proxy
...
@@ -470,12 +471,12 @@ namespace Titanium.Web.Proxy
//If 100 continue was the response inform that to the client
//If 100 continue was the response inform that to the client
if
(
Enable100ContinueBehaviour
)
if
(
Enable100ContinueBehaviour
)
{
{
if
(
args
.
WebSession
.
R
equest
.
Is100Continue
)
if
(
r
equest
.
Is100Continue
)
{
{
await
args
.
ProxyClient
.
ClientStreamWriter
.
WriteResponseStatusAsync
(
args
.
WebSession
.
Response
.
HttpVersion
,
(
int
)
HttpStatusCode
.
Continue
,
"Continue"
);
await
args
.
ProxyClient
.
ClientStreamWriter
.
WriteResponseStatusAsync
(
args
.
WebSession
.
Response
.
HttpVersion
,
(
int
)
HttpStatusCode
.
Continue
,
"Continue"
);
await
args
.
ProxyClient
.
ClientStreamWriter
.
WriteLineAsync
();
await
args
.
ProxyClient
.
ClientStreamWriter
.
WriteLineAsync
();
}
}
else
if
(
args
.
WebSession
.
R
equest
.
ExpectationFailed
)
else
if
(
r
equest
.
ExpectationFailed
)
{
{
await
args
.
ProxyClient
.
ClientStreamWriter
.
WriteResponseStatusAsync
(
args
.
WebSession
.
Response
.
HttpVersion
,
(
int
)
HttpStatusCode
.
ExpectationFailed
,
"Expectation Failed"
);
await
args
.
ProxyClient
.
ClientStreamWriter
.
WriteResponseStatusAsync
(
args
.
WebSession
.
Response
.
HttpVersion
,
(
int
)
HttpStatusCode
.
ExpectationFailed
,
"Expectation Failed"
);
await
args
.
ProxyClient
.
ClientStreamWriter
.
WriteLineAsync
();
await
args
.
ProxyClient
.
ClientStreamWriter
.
WriteLineAsync
();
...
@@ -483,38 +484,37 @@ namespace Titanium.Web.Proxy
...
@@ -483,38 +484,37 @@ namespace Titanium.Web.Proxy
}
}
//If expect continue is not enabled then set the connectio and send request headers
//If expect continue is not enabled then set the connectio and send request headers
if
(!
args
.
WebSession
.
R
equest
.
ExpectContinue
)
if
(!
r
equest
.
ExpectContinue
)
{
{
args
.
WebSession
.
SetConnection
(
connection
);
args
.
WebSession
.
SetConnection
(
connection
);
await
args
.
WebSession
.
SendRequest
(
Enable100ContinueBehaviour
);
await
args
.
WebSession
.
SendRequest
(
Enable100ContinueBehaviour
);
}
}
//check if content-length is > 0
//check if content-length is > 0
if
(
args
.
WebSession
.
R
equest
.
ContentLength
>
0
)
if
(
r
equest
.
ContentLength
>
0
)
{
{
//If request was modified by user
//If request was modified by user
if
(
args
.
WebSession
.
R
equest
.
IsBodyRead
)
if
(
r
equest
.
IsBodyRead
)
{
{
if
(
args
.
WebSession
.
R
equest
.
ContentEncoding
!=
null
)
if
(
r
equest
.
ContentEncoding
!=
null
)
{
{
args
.
WebSession
.
Request
.
Body
=
request
.
Body
=
await
GetCompressedResponseBody
(
request
.
ContentEncoding
,
request
.
Body
);
await
GetCompressedResponseBody
(
args
.
WebSession
.
Request
.
ContentEncoding
,
args
.
WebSession
.
Request
.
Body
);
}
}
var
body
=
args
.
WebSession
.
R
equest
.
Body
;
var
body
=
r
equest
.
Body
;
//chunked send is not supported as of now
//chunked send is not supported as of now
args
.
WebSession
.
R
equest
.
ContentLength
=
body
.
Length
;
r
equest
.
ContentLength
=
body
.
Length
;
var
newStream
=
args
.
WebSession
.
ServerConnection
.
Stream
;
var
newStream
=
args
.
WebSession
.
ServerConnection
.
Stream
;
await
newStream
.
WriteAsync
(
body
,
0
,
body
.
Length
);
await
newStream
.
WriteAsync
(
body
,
0
,
body
.
Length
);
}
}
else
else
{
{
if
(!
args
.
WebSession
.
R
equest
.
ExpectationFailed
)
if
(!
r
equest
.
ExpectationFailed
)
{
{
//If its a post/put/patch request, then read the client html body and send it to server
//If its a post/put/patch request, then read the client html body and send it to server
if
(
args
.
WebSession
.
R
equest
.
HasBody
)
if
(
r
equest
.
HasBody
)
{
{
await
SendClientRequestBody
(
args
);
await
SendClientRequestBody
(
args
);
}
}
...
@@ -523,7 +523,7 @@ namespace Titanium.Web.Proxy
...
@@ -523,7 +523,7 @@ namespace Titanium.Web.Proxy
}
}
//If not expectation failed response was returned by server then parse response
//If not expectation failed response was returned by server then parse response
if
(!
args
.
WebSession
.
R
equest
.
ExpectationFailed
)
if
(!
r
equest
.
ExpectationFailed
)
{
{
disposed
=
await
HandleHttpSessionResponse
(
args
);
disposed
=
await
HandleHttpSessionResponse
(
args
);
...
@@ -624,7 +624,18 @@ namespace Titanium.Web.Proxy
...
@@ -624,7 +624,18 @@ namespace Titanium.Web.Proxy
//send the request body bytes to server
//send the request body bytes to server
if
(
args
.
WebSession
.
Request
.
ContentLength
>
0
)
if
(
args
.
WebSession
.
Request
.
ContentLength
>
0
)
{
{
await
args
.
ProxyClient
.
ClientStreamReader
.
CopyBytesToStream
(
postStream
,
args
.
WebSession
.
Request
.
ContentLength
);
var
request
=
args
.
WebSession
.
Request
;
if
(
args
.
HasMulipartEventSubscribers
&&
request
.
IsMultipartFormData
)
{
string
boundary
=
HttpHelper
.
GetBoundaryFromContentType
(
request
.
ContentType
);
args
.
OnMultipartRequestPartSent
(
boundary
);
// todo
await
args
.
ProxyClient
.
ClientStreamReader
.
CopyBytesToStream
(
postStream
,
args
.
WebSession
.
Request
.
ContentLength
);
}
else
{
await
args
.
ProxyClient
.
ClientStreamReader
.
CopyBytesToStream
(
postStream
,
args
.
WebSession
.
Request
.
ContentLength
);
}
}
}
//Need to revist, find any potential bugs
//Need to revist, find any potential bugs
//send the request body bytes to server in chunks
//send the request body bytes to server in chunks
...
...
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