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
0786662d
Commit
0786662d
authored
May 15, 2017
by
Jehonathan Thomas
Committed by
GitHub
May 15, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #228 from honfika/develop
- Create less TcpRow objects
parents
a49370d6
81d32f79
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
207 additions
and
172 deletions
+207
-172
ProxyTestController.cs
.../Titanium.Web.Proxy.Examples.Basic/ProxyTestController.cs
+4
-3
SessionEventArgs.cs
Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
+2
-1
TcpExtensions.cs
Titanium.Web.Proxy/Extensions/TcpExtensions.cs
+21
-0
CustomBinaryReader.cs
Titanium.Web.Proxy/Helpers/CustomBinaryReader.cs
+7
-17
CustomBufferedStream.cs
Titanium.Web.Proxy/Helpers/CustomBufferedStream.cs
+2
-0
Network.cs
Titanium.Web.Proxy/Helpers/Network.cs
+1
-2
Tcp.cs
Titanium.Web.Proxy/Helpers/Tcp.cs
+46
-0
HeaderParser.cs
Titanium.Web.Proxy/Http/HeaderParser.cs
+45
-0
HttpWebClient.cs
Titanium.Web.Proxy/Http/HttpWebClient.cs
+7
-34
Request.cs
Titanium.Web.Proxy/Http/Request.cs
+2
-2
HttpHeader.cs
Titanium.Web.Proxy/Models/HttpHeader.cs
+4
-0
TcpRow.cs
Titanium.Web.Proxy/Network/Tcp/TcpRow.cs
+27
-8
ProxyAuthorizationHandler.cs
Titanium.Web.Proxy/ProxyAuthorizationHandler.cs
+26
-63
RequestHandler.cs
Titanium.Web.Proxy/RequestHandler.cs
+12
-41
ResponseHandler.cs
Titanium.Web.Proxy/ResponseHandler.cs
+0
-1
Titanium.Web.Proxy.csproj
Titanium.Web.Proxy/Titanium.Web.Proxy.csproj
+1
-0
No files found.
Examples/Titanium.Web.Proxy.Examples.Basic/ProxyTestController.cs
View file @
0786662d
using
System
;
using
System.Collections.Generic
;
using
System.IO
;
using
System.Net
;
using
System.Threading.Tasks
;
using
Titanium.Web.Proxy.EventArguments
;
...
...
@@ -106,14 +107,14 @@ namespace Titanium.Web.Proxy.Examples.Basic
//intecept & cancel redirect or update requests
public
async
Task
OnRequest
(
object
sender
,
SessionEventArgs
e
)
{
Console
.
WriteLine
(
"Active Client Connections:"
+
(
sender
as
ProxyServ
er
).
ClientConnectionCount
);
Console
.
WriteLine
(
"Active Client Connections:"
+
(
(
ProxyServer
)
send
er
).
ClientConnectionCount
);
Console
.
WriteLine
(
e
.
WebSession
.
Request
.
Url
);
//read request headers
var
requestHeaders
=
e
.
WebSession
.
Request
.
RequestHeaders
;
var
method
=
e
.
WebSession
.
Request
.
Method
.
ToUpper
();
if
(
(
method
==
"POST"
||
method
==
"PUT"
||
method
==
"PATCH"
)
)
if
(
method
==
"POST"
||
method
==
"PUT"
||
method
==
"PATCH"
)
{
//Get/Set request body bytes
byte
[]
bodyBytes
=
await
e
.
GetRequestBody
();
...
...
@@ -168,7 +169,7 @@ namespace Titanium.Web.Proxy.Examples.Basic
{
if
(
e
.
WebSession
.
Response
.
ResponseStatusCode
==
"200"
)
{
if
(
e
.
WebSession
.
Response
.
ContentType
!=
null
&&
e
.
WebSession
.
Response
.
ContentType
.
Trim
().
ToLower
().
Contains
(
"text/html"
))
if
(
e
.
WebSession
.
Response
.
ContentType
!=
null
&&
e
.
WebSession
.
Response
.
ContentType
.
Trim
().
ToLower
().
Contains
(
"text/html"
))
{
byte
[]
bodyBytes
=
await
e
.
GetResponseBody
();
await
e
.
SetResponseBody
(
bodyBytes
);
...
...
Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
View file @
0786662d
...
...
@@ -93,7 +93,7 @@ namespace Titanium.Web.Proxy.EventArguments
{
//GET request don't have a request body to read
var
method
=
WebSession
.
Request
.
Method
.
ToUpper
();
if
(
(
method
!=
"POST"
&&
method
!=
"PUT"
&&
method
!=
"PATCH"
)
)
if
(
method
!=
"POST"
&&
method
!=
"PUT"
&&
method
!=
"PATCH"
)
{
throw
new
BodyNotFoundException
(
"Request don't have a body. "
+
"Please verify that this request is a Http POST/PUT/PATCH and request "
+
...
...
@@ -411,6 +411,7 @@ namespace Titanium.Web.Proxy.EventArguments
{
response
.
ResponseHeaders
=
headers
;
}
response
.
HttpVersion
=
WebSession
.
Request
.
HttpVersion
;
response
.
ResponseBody
=
result
;
...
...
Titanium.Web.Proxy/Extensions/TcpExtensions.cs
View file @
0786662d
using
System.Net.Sockets
;
using
Titanium.Web.Proxy.Helpers
;
namespace
Titanium.Web.Proxy.Extensions
{
...
...
@@ -32,5 +33,25 @@ namespace Titanium.Web.Proxy.Extensions
client
.
Blocking
=
blockingState
;
}
}
/// <summary>
/// Gets the local port from a native TCP row object.
/// </summary>
/// <param name="tcpRow">The TCP row.</param>
/// <returns>The local port</returns>
internal
static
int
GetLocalPort
(
this
NativeMethods
.
TcpRow
tcpRow
)
{
return
(
tcpRow
.
localPort1
<<
8
)
+
tcpRow
.
localPort2
+
(
tcpRow
.
localPort3
<<
24
)
+
(
tcpRow
.
localPort4
<<
16
);
}
/// <summary>
/// Gets the remote port from a native TCP row object.
/// </summary>
/// <param name="tcpRow">The TCP row.</param>
/// <returns>The remote port</returns>
internal
static
int
GetRemotePort
(
this
NativeMethods
.
TcpRow
tcpRow
)
{
return
(
tcpRow
.
remotePort1
<<
8
)
+
tcpRow
.
remotePort2
+
(
tcpRow
.
remotePort3
<<
24
)
+
(
tcpRow
.
remotePort4
<<
16
);
}
}
}
Titanium.Web.Proxy/Helpers/CustomBinaryReader.cs
View file @
0786662d
...
...
@@ -15,27 +15,14 @@ namespace Titanium.Web.Proxy.Helpers
{
private
readonly
CustomBufferedStream
stream
;
private
readonly
int
bufferSize
;
private
readonly
byte
[]
staticBuffer
;
private
readonly
Encoding
encoding
;
[
ThreadStatic
]
private
static
byte
[]
staticBufferField
;
private
byte
[]
staticBuffer
{
get
{
if
(
staticBufferField
==
null
||
staticBufferField
.
Length
!=
bufferSize
)
{
staticBufferField
=
new
byte
[
bufferSize
];
}
return
staticBufferField
;
}
}
internal
CustomBinaryReader
(
CustomBufferedStream
stream
,
int
bufferSize
)
{
this
.
stream
=
stream
;
staticBuffer
=
new
byte
[
bufferSize
];
this
.
bufferSize
=
bufferSize
;
//default to UTF-8
...
...
@@ -122,10 +109,13 @@ namespace Titanium.Web.Proxy.Helpers
{
int
bytesToRead
=
bufferSize
;
var
buffer
=
staticBuffer
;
if
(
totalBytesToRead
<
bufferSize
)
{
bytesToRead
=
(
int
)
totalBytesToRead
;
buffer
=
new
byte
[
bytesToRead
];
}
var
buffer
=
staticBuffer
;
int
bytesRead
;
var
totalBytesRead
=
0
;
...
...
Titanium.Web.Proxy/Helpers/CustomBufferedStream.cs
View file @
0786662d
...
...
@@ -168,6 +168,7 @@ namespace Titanium.Web.Proxy.Helpers
if
(
bufferLength
>
0
)
{
await
destination
.
WriteAsync
(
streamBuffer
,
bufferPos
,
bufferLength
,
cancellationToken
);
bufferLength
=
0
;
}
await
baseStream
.
CopyToAsync
(
destination
,
bufferSize
,
cancellationToken
);
...
...
@@ -307,6 +308,7 @@ namespace Titanium.Web.Proxy.Helpers
/// <returns>
/// A task that represents the asynchronous write operation.
/// </returns>
[
DebuggerStepThrough
]
public
override
Task
WriteAsync
(
byte
[]
buffer
,
int
offset
,
int
count
,
CancellationToken
cancellationToken
)
{
return
baseStream
.
WriteAsync
(
buffer
,
offset
,
count
,
cancellationToken
);
...
...
Titanium.Web.Proxy/Helpers/Network.cs
View file @
0786662d
...
...
@@ -8,8 +8,7 @@ namespace Titanium.Web.Proxy.Helpers
{
private
static
int
FindProcessIdFromLocalPort
(
int
port
,
IpVersion
ipVersion
)
{
var
tcpRow
=
TcpHelper
.
GetExtendedTcpTable
(
ipVersion
).
FirstOrDefault
(
row
=>
row
.
LocalEndPoint
.
Port
==
port
);
var
tcpRow
=
TcpHelper
.
GetTcpRowByLocalPort
(
ipVersion
,
port
);
return
tcpRow
?.
ProcessId
??
0
;
}
...
...
Titanium.Web.Proxy/Helpers/Tcp.cs
View file @
0786662d
...
...
@@ -123,6 +123,52 @@ namespace Titanium.Web.Proxy.Helpers
return
new
TcpTable
(
tcpRows
);
}
/// <summary>
/// Gets the TCP row by local port number.
/// </summary>
/// <returns><see cref="TcpRow"/>.</returns>
internal
static
TcpRow
GetTcpRowByLocalPort
(
IpVersion
ipVersion
,
int
localPort
)
{
IntPtr
tcpTable
=
IntPtr
.
Zero
;
int
tcpTableLength
=
0
;
var
ipVersionValue
=
ipVersion
==
IpVersion
.
Ipv4
?
NativeMethods
.
AfInet
:
NativeMethods
.
AfInet6
;
if
(
NativeMethods
.
GetExtendedTcpTable
(
tcpTable
,
ref
tcpTableLength
,
false
,
ipVersionValue
,
(
int
)
NativeMethods
.
TcpTableType
.
OwnerPidAll
,
0
)
!=
0
)
{
try
{
tcpTable
=
Marshal
.
AllocHGlobal
(
tcpTableLength
);
if
(
NativeMethods
.
GetExtendedTcpTable
(
tcpTable
,
ref
tcpTableLength
,
true
,
ipVersionValue
,
(
int
)
NativeMethods
.
TcpTableType
.
OwnerPidAll
,
0
)
==
0
)
{
NativeMethods
.
TcpTable
table
=
(
NativeMethods
.
TcpTable
)
Marshal
.
PtrToStructure
(
tcpTable
,
typeof
(
NativeMethods
.
TcpTable
));
IntPtr
rowPtr
=
(
IntPtr
)((
long
)
tcpTable
+
Marshal
.
SizeOf
(
table
.
length
));
for
(
int
i
=
0
;
i
<
table
.
length
;
++
i
)
{
var
tcpRow
=
(
NativeMethods
.
TcpRow
)
Marshal
.
PtrToStructure
(
rowPtr
,
typeof
(
NativeMethods
.
TcpRow
));
if
(
tcpRow
.
GetLocalPort
()
==
localPort
)
{
return
new
TcpRow
(
tcpRow
);
}
rowPtr
=
(
IntPtr
)((
long
)
rowPtr
+
Marshal
.
SizeOf
(
typeof
(
NativeMethods
.
TcpRow
)));
}
}
}
finally
{
if
(
tcpTable
!=
IntPtr
.
Zero
)
{
Marshal
.
FreeHGlobal
(
tcpTable
);
}
}
}
return
null
;
}
/// <summary>
/// relays the input clientStream to the server at the specified host name and port with the given httpCmd and headers as prefix
/// Usefull for websocket requests
...
...
Titanium.Web.Proxy/Http/HeaderParser.cs
0 → 100644
View file @
0786662d
using
System.Collections.Generic
;
using
System.Threading.Tasks
;
using
Titanium.Web.Proxy.Helpers
;
using
Titanium.Web.Proxy.Models
;
using
Titanium.Web.Proxy.Shared
;
namespace
Titanium.Web.Proxy.Http
{
internal
static
class
HeaderParser
{
internal
static
async
Task
ReadHeaders
(
CustomBinaryReader
reader
,
Dictionary
<
string
,
List
<
HttpHeader
>>
nonUniqueResponseHeaders
,
Dictionary
<
string
,
HttpHeader
>
headers
)
{
string
tmpLine
;
while
(!
string
.
IsNullOrEmpty
(
tmpLine
=
await
reader
.
ReadLineAsync
()))
{
var
header
=
tmpLine
.
Split
(
ProxyConstants
.
ColonSplit
,
2
);
var
newHeader
=
new
HttpHeader
(
header
[
0
],
header
[
1
]);
//if header exist in non-unique header collection add it there
if
(
nonUniqueResponseHeaders
.
ContainsKey
(
newHeader
.
Name
))
{
nonUniqueResponseHeaders
[
newHeader
.
Name
].
Add
(
newHeader
);
}
//if header is alread in unique header collection then move both to non-unique collection
else
if
(
headers
.
ContainsKey
(
newHeader
.
Name
))
{
var
existing
=
headers
[
newHeader
.
Name
];
var
nonUniqueHeaders
=
new
List
<
HttpHeader
>
{
existing
,
newHeader
};
nonUniqueResponseHeaders
.
Add
(
newHeader
.
Name
,
nonUniqueHeaders
);
headers
.
Remove
(
newHeader
.
Name
);
}
//add to unique header collection
else
{
headers
.
Add
(
newHeader
.
Name
,
newHeader
);
}
}
}
}
}
Titanium.Web.Proxy/Http/HttpWebClient.cs
View file @
0786662d
...
...
@@ -170,10 +170,10 @@ namespace Titanium.Web.Proxy.Http
var
httpVersion
=
httpResult
[
0
].
Trim
().
ToLower
();
var
version
=
new
Version
(
1
,
1
)
;
if
(
0
==
string
.
CompareOrdinal
(
httpVersion
,
"http/1.0"
))
var
version
=
HttpHeader
.
Version11
;
if
(
string
.
Equals
(
httpVersion
,
"HTTP/1.0"
,
StringComparison
.
OrdinalIgnoreCase
))
{
version
=
new
Version
(
1
,
0
)
;
version
=
HttpHeader
.
Version10
;
}
Response
.
HttpVersion
=
version
;
...
...
@@ -192,8 +192,9 @@ namespace Titanium.Web.Proxy.Http
await
ReceiveResponse
();
return
;
}
else
if
(
Response
.
ResponseStatusCode
.
Equals
(
"417"
)
&&
Response
.
ResponseStatusDescription
.
Equals
(
"expectation failed"
,
StringComparison
.
CurrentCultureIgnoreCase
))
if
(
Response
.
ResponseStatusCode
.
Equals
(
"417"
)
&&
Response
.
ResponseStatusDescription
.
Equals
(
"expectation failed"
,
StringComparison
.
CurrentCultureIgnoreCase
))
{
//read next line after expectation failed response
Response
.
ExpectationFailed
=
true
;
...
...
@@ -204,36 +205,8 @@ namespace Titanium.Web.Proxy.Http
return
;
}
//Read the Response headers
//Read the response headers in to unique and non-unique header collections
string
tmpLine
;
while
(!
string
.
IsNullOrEmpty
(
tmpLine
=
await
ServerConnection
.
StreamReader
.
ReadLineAsync
()))
{
var
header
=
tmpLine
.
Split
(
ProxyConstants
.
ColonSplit
,
2
);
var
newHeader
=
new
HttpHeader
(
header
[
0
],
header
[
1
]);
//if header exist in non-unique header collection add it there
if
(
Response
.
NonUniqueResponseHeaders
.
ContainsKey
(
newHeader
.
Name
))
{
Response
.
NonUniqueResponseHeaders
[
newHeader
.
Name
].
Add
(
newHeader
);
}
//if header is alread in unique header collection then move both to non-unique collection
else
if
(
Response
.
ResponseHeaders
.
ContainsKey
(
newHeader
.
Name
))
{
var
existing
=
Response
.
ResponseHeaders
[
newHeader
.
Name
];
var
nonUniqueHeaders
=
new
List
<
HttpHeader
>
{
existing
,
newHeader
};
Response
.
NonUniqueResponseHeaders
.
Add
(
newHeader
.
Name
,
nonUniqueHeaders
);
Response
.
ResponseHeaders
.
Remove
(
newHeader
.
Name
);
}
//add to unique header collection
else
{
Response
.
ResponseHeaders
.
Add
(
newHeader
.
Name
,
newHeader
);
}
}
await
HeaderParser
.
ReadHeaders
(
ServerConnection
.
StreamReader
,
Response
.
NonUniqueResponseHeaders
,
Response
.
ResponseHeaders
);
}
}
}
Titanium.Web.Proxy/Http/Request.cs
View file @
0786662d
...
...
@@ -241,9 +241,9 @@ namespace Titanium.Web.Proxy.Http
/// request body as string
/// </summary>
internal
string
RequestBodyString
{
get
;
set
;
}
internal
bool
RequestBodyRead
{
get
;
set
;
}
internal
bool
RequestLocked
{
get
;
set
;
}
/// <summary>
...
...
Titanium.Web.Proxy/Models/HttpHeader.cs
View file @
0786662d
...
...
@@ -9,6 +9,10 @@ namespace Titanium.Web.Proxy.Models
/// </summary>
public
class
HttpHeader
{
internal
static
Version
Version10
=
new
Version
(
1
,
0
);
internal
static
Version
Version11
=
new
Version
(
1
,
1
);
/// <summary>
/// Constructor.
/// </summary>
...
...
Titanium.Web.Proxy/Network/Tcp/TcpRow.cs
View file @
0786662d
using
System.Net
;
using
Titanium.Web.Proxy.Extensions
;
using
Titanium.Web.Proxy.Helpers
;
namespace
Titanium.Web.Proxy.Network.Tcp
...
...
@@ -17,24 +18,42 @@ namespace Titanium.Web.Proxy.Network.Tcp
{
ProcessId
=
tcpRow
.
owningPid
;
int
localPort
=
(
tcpRow
.
localPort1
<<
8
)
+
(
tcpRow
.
localPort2
)
+
(
tcpRow
.
localPort3
<<
24
)
+
(
tcpRow
.
localPort4
<<
16
);
long
localAddress
=
tcpRow
.
localAddr
;
LocalEndPoint
=
new
IPEndPoint
(
localAddress
,
localPort
);
LocalPort
=
tcpRow
.
GetLocalPort
();
LocalAddress
=
tcpRow
.
localAddr
;
int
remotePort
=
(
tcpRow
.
remotePort1
<<
8
)
+
(
tcpRow
.
remotePort2
)
+
(
tcpRow
.
remotePort3
<<
24
)
+
(
tcpRow
.
remotePort4
<<
16
);
long
remoteAddress
=
tcpRow
.
remoteAddr
;
RemoteEndPoint
=
new
IPEndPoint
(
remoteAddress
,
remotePort
);
RemotePort
=
tcpRow
.
GetRemotePort
();
RemoteAddress
=
tcpRow
.
remoteAddr
;
}
/// <summary>
/// Gets the local end point address.
/// </summary>
internal
long
LocalAddress
{
get
;
}
/// <summary>
/// Gets the local end point port.
/// </summary>
internal
int
LocalPort
{
get
;
}
/// <summary>
/// Gets the local end point.
/// </summary>
internal
IPEndPoint
LocalEndPoint
{
get
;
}
internal
IPEndPoint
LocalEndPoint
=>
new
IPEndPoint
(
LocalAddress
,
LocalPort
);
/// <summary>
/// Gets the remote end point address.
/// </summary>
internal
long
RemoteAddress
{
get
;
}
/// <summary>
/// Gets the remote end point port.
/// </summary>
internal
int
RemotePort
{
get
;
}
/// <summary>
/// Gets the remote end point.
/// </summary>
internal
IPEndPoint
RemoteEndPoint
{
get
;
}
internal
IPEndPoint
RemoteEndPoint
=>
new
IPEndPoint
(
RemoteAddress
,
RemotePort
);
/// <summary>
/// Gets the process identifier.
...
...
Titanium.Web.Proxy/ProxyAuthorizationHandler.cs
View file @
0786662d
...
...
@@ -19,78 +19,36 @@ namespace Titanium.Web.Proxy
return
true
;
}
var
httpHeaders
=
headers
as
HttpHeader
[]
??
headers
.
ToArray
();
var
httpHeaders
=
headers
as
ICollection
<
HttpHeader
>
??
headers
.
ToArray
();
try
{
if
(
httpHeaders
.
All
(
t
=>
t
.
Name
!=
"Proxy-Authorization"
))
{
await
WriteResponseStatus
(
new
Version
(
1
,
1
),
"407"
,
"Proxy Authentication Required"
,
clientStreamWriter
);
var
response
=
new
Response
{
ResponseHeaders
=
new
Dictionary
<
string
,
HttpHeader
>
{
{
"Proxy-Authenticate"
,
new
HttpHeader
(
"Proxy-Authenticate"
,
"Basic realm=\"TitaniumProxy\""
)
},
{
"Proxy-Connection"
,
new
HttpHeader
(
"Proxy-Connection"
,
"close"
)}
}
};
await
WriteResponseHeaders
(
clientStreamWriter
,
response
);
await
clientStreamWriter
.
WriteLineAsync
();
await
SendAuthentication407Response
(
clientStreamWriter
,
"Proxy Authentication Required"
);
return
false
;
}
var
header
=
httpHeaders
.
FirstOrDefault
(
t
=>
t
.
Name
==
"Proxy-Authorization"
);
if
(
null
==
header
)
throw
new
NullReferenceException
();
if
(
header
==
null
)
throw
new
NullReferenceException
();
var
headerValue
=
header
.
Value
.
Trim
();
if
(!
headerValue
.
StartsWith
(
"basic"
,
StringComparison
.
CurrentCultureIgnoreCase
))
{
//Return not authorized
await
WriteResponseStatus
(
new
Version
(
1
,
1
),
"407"
,
"Proxy Authentication Invalid"
,
clientStreamWriter
);
var
response
=
new
Response
{
ResponseHeaders
=
new
Dictionary
<
string
,
HttpHeader
>
{
{
"Proxy-Authenticate"
,
new
HttpHeader
(
"Proxy-Authenticate"
,
"Basic realm=\"TitaniumProxy\""
)
},
{
"Proxy-Connection"
,
new
HttpHeader
(
"Proxy-Connection"
,
"close"
)}
}
};
await
WriteResponseHeaders
(
clientStreamWriter
,
response
);
await
clientStreamWriter
.
WriteLineAsync
();
await
SendAuthentication407Response
(
clientStreamWriter
,
"Proxy Authentication Invalid"
);
return
false
;
}
headerValue
=
headerValue
.
Substring
(
5
).
Trim
();
var
decoded
=
Encoding
.
UTF8
.
GetString
(
Convert
.
FromBase64String
(
headerValue
));
if
(
decoded
.
Contains
(
":"
)
==
false
)
{
//Return not authorized
await
WriteResponseStatus
(
new
Version
(
1
,
1
),
"407"
,
"Proxy Authentication Invalid"
,
clientStreamWriter
);
var
response
=
new
Response
{
ResponseHeaders
=
new
Dictionary
<
string
,
HttpHeader
>
{
{
"Proxy-Authenticate"
,
new
HttpHeader
(
"Proxy-Authenticate"
,
"Basic realm=\"TitaniumProxy\""
)
},
{
"Proxy-Connection"
,
new
HttpHeader
(
"Proxy-Connection"
,
"close"
)}
}
};
await
WriteResponseHeaders
(
clientStreamWriter
,
response
);
await
clientStreamWriter
.
WriteLineAsync
();
await
SendAuthentication407Response
(
clientStreamWriter
,
"Proxy Authentication Invalid"
);
return
false
;
}
var
username
=
decoded
.
Substring
(
0
,
decoded
.
IndexOf
(
':'
));
var
password
=
decoded
.
Substring
(
decoded
.
IndexOf
(
':'
)
+
1
);
return
await
AuthenticateUserFunc
(
username
,
password
);
...
...
@@ -98,22 +56,27 @@ namespace Titanium.Web.Proxy
catch
(
Exception
e
)
{
ExceptionFunc
(
new
ProxyAuthorizationException
(
"Error whilst authorizing request"
,
e
,
httpHeaders
));
//Return not authorized
await
WriteResponseStatus
(
new
Version
(
1
,
1
),
"407"
,
"Proxy Authentication Invalid"
,
clientStreamWriter
);
var
response
=
new
Response
{
ResponseHeaders
=
new
Dictionary
<
string
,
HttpHeader
>
{
{
"Proxy-Authenticate"
,
new
HttpHeader
(
"Proxy-Authenticate"
,
"Basic realm=\"TitaniumProxy\""
)},
{
"Proxy-Connection"
,
new
HttpHeader
(
"Proxy-Connection"
,
"close"
)}
}
};
await
WriteResponseHeaders
(
clientStreamWriter
,
response
);
await
clientStreamWriter
.
WriteLineAsync
();
//Return not authorized
await
SendAuthentication407Response
(
clientStreamWriter
,
"Proxy Authentication Invalid"
);
return
false
;
}
}
private
async
Task
SendAuthentication407Response
(
StreamWriter
clientStreamWriter
,
string
description
)
{
await
WriteResponseStatus
(
HttpHeader
.
Version11
,
"407"
,
description
,
clientStreamWriter
);
var
response
=
new
Response
{
ResponseHeaders
=
new
Dictionary
<
string
,
HttpHeader
>
{
{
"Proxy-Authenticate"
,
new
HttpHeader
(
"Proxy-Authenticate"
,
"Basic realm=\"TitaniumProxy\""
)},
{
"Proxy-Connection"
,
new
HttpHeader
(
"Proxy-Connection"
,
"close"
)}
}
};
await
WriteResponseHeaders
(
clientStreamWriter
,
response
);
await
clientStreamWriter
.
WriteLineAsync
();
}
}
}
Titanium.Web.Proxy/RequestHandler.cs
View file @
0786662d
...
...
@@ -57,14 +57,14 @@ namespace Titanium.Web.Proxy
httpRemoteUri
=
httpVerb
==
"CONNECT"
?
new
Uri
(
"http://"
+
httpCmdSplit
[
1
])
:
new
Uri
(
httpCmdSplit
[
1
]);
//parse the HTTP version
var
version
=
new
Version
(
1
,
1
)
;
var
version
=
HttpHeader
.
Version11
;
if
(
httpCmdSplit
.
Length
==
3
)
{
var
httpVersion
=
httpCmdSplit
[
2
].
Trim
();
if
(
0
==
string
.
CompareOrdinal
(
httpVersion
,
"http/1.0"
))
if
(
string
.
Equals
(
httpVersion
,
"HTTP/1.0"
,
StringComparison
.
OrdinalIgnoreCase
))
{
version
=
new
Version
(
1
,
0
)
;
version
=
HttpHeader
.
Version10
;
}
}
...
...
@@ -87,8 +87,8 @@ namespace Titanium.Web.Proxy
if
(
httpVerb
==
"CONNECT"
&&
!
excluded
&&
httpRemoteUri
.
Port
!=
80
)
{
httpRemoteUri
=
new
Uri
(
"https://"
+
httpCmdSplit
[
1
]);
string
tmpLine
;
connectRequestHeaders
=
new
List
<
HttpHeader
>();
string
tmpLine
;
while
(!
string
.
IsNullOrEmpty
(
tmpLine
=
await
clientStreamReader
.
ReadLineAsync
()))
{
var
header
=
tmpLine
.
Split
(
ProxyConstants
.
ColonSplit
,
2
);
...
...
@@ -432,50 +432,22 @@ namespace Titanium.Web.Proxy
var
httpMethod
=
httpCmdSplit
[
0
];
//find the request HTTP version
var
httpVersion
=
new
Version
(
1
,
1
)
;
var
httpVersion
=
HttpHeader
.
Version11
;
if
(
httpCmdSplit
.
Length
==
3
)
{
var
httpVersionString
=
httpCmdSplit
[
2
].
T
oLower
().
T
rim
();
var
httpVersionString
=
httpCmdSplit
[
2
].
Trim
();
if
(
0
==
string
.
CompareOrdinal
(
httpVersionString
,
"http/1.0"
))
if
(
string
.
Equals
(
httpVersionString
,
"HTTP/1.0"
,
StringComparison
.
OrdinalIgnoreCase
))
{
httpVersion
=
new
Version
(
1
,
0
)
;
httpVersion
=
HttpHeader
.
Version10
;
}
}
//Read the request headers in to unique and non-unique header collections
string
tmpLine
;
while
(!
string
.
IsNullOrEmpty
(
tmpLine
=
await
clientStreamReader
.
ReadLineAsync
()))
{
var
header
=
tmpLine
.
Split
(
ProxyConstants
.
ColonSplit
,
2
);
var
newHeader
=
new
HttpHeader
(
header
[
0
],
header
[
1
]);
//if header exist in non-unique header collection add it there
if
(
args
.
WebSession
.
Request
.
NonUniqueRequestHeaders
.
ContainsKey
(
newHeader
.
Name
))
{
args
.
WebSession
.
Request
.
NonUniqueRequestHeaders
[
newHeader
.
Name
].
Add
(
newHeader
);
}
//if header is alread in unique header collection then move both to non-unique collection
else
if
(
args
.
WebSession
.
Request
.
RequestHeaders
.
ContainsKey
(
newHeader
.
Name
))
{
var
existing
=
args
.
WebSession
.
Request
.
RequestHeaders
[
newHeader
.
Name
];
var
nonUniqueHeaders
=
new
List
<
HttpHeader
>
{
existing
,
newHeader
};
args
.
WebSession
.
Request
.
NonUniqueRequestHeaders
.
Add
(
newHeader
.
Name
,
nonUniqueHeaders
);
args
.
WebSession
.
Request
.
RequestHeaders
.
Remove
(
newHeader
.
Name
);
}
//add to unique header collection
else
{
args
.
WebSession
.
Request
.
RequestHeaders
.
Add
(
newHeader
.
Name
,
newHeader
);
}
}
await
HeaderParser
.
ReadHeaders
(
clientStreamReader
,
args
.
WebSession
.
Request
.
NonUniqueRequestHeaders
,
args
.
WebSession
.
Request
.
RequestHeaders
);
var
httpRemoteUri
=
new
Uri
(
httpsHostName
==
null
?
httpCmdSplit
[
1
]
:
(
string
.
Concat
(
"https://"
,
args
.
WebSession
.
Request
.
Host
??
httpsHostName
,
httpCmdSplit
[
1
])
));
:
string
.
Concat
(
"https://"
,
args
.
WebSession
.
Request
.
Host
??
httpsHostName
,
httpCmdSplit
[
1
]
));
args
.
WebSession
.
Request
.
RequestUri
=
httpRemoteUri
;
...
...
@@ -483,10 +455,9 @@ namespace Titanium.Web.Proxy
args
.
WebSession
.
Request
.
HttpVersion
=
httpVersion
;
args
.
ProxyClient
.
ClientStream
=
clientStream
;
args
.
ProxyClient
.
ClientStreamReader
=
clientStreamReader
;
args
.
ProxyClient
.
ClientStreamWriter
=
clientStreamWriter
;
args
.
ProxyClient
.
ClientStreamWriter
=
clientStreamWriter
;
if
(
httpsHostName
==
null
&&
(
await
CheckAuthorization
(
clientStreamWriter
,
args
.
WebSession
.
Request
.
RequestHeaders
.
Values
)
==
false
))
if
(
httpsHostName
==
null
&&
await
CheckAuthorization
(
clientStreamWriter
,
args
.
WebSession
.
Request
.
RequestHeaders
.
Values
)
==
false
)
{
Dispose
(
clientStream
,
clientStreamReader
,
...
...
Titanium.Web.Proxy/ResponseHandler.cs
View file @
0786662d
...
...
@@ -9,7 +9,6 @@ using Titanium.Web.Proxy.Exceptions;
using
Titanium.Web.Proxy.Extensions
;
using
Titanium.Web.Proxy.Http
;
using
Titanium.Web.Proxy.Helpers
;
using
System.Net.Sockets
;
using
Titanium.Web.Proxy.Network.Tcp
;
namespace
Titanium.Web.Proxy
...
...
Titanium.Web.Proxy/Titanium.Web.Proxy.csproj
View file @
0786662d
...
...
@@ -77,6 +77,7 @@
<Compile
Include=
"Helpers\CustomBufferedStream.cs"
/>
<Compile
Include=
"Helpers\Network.cs"
/>
<Compile
Include=
"Helpers\RunTime.cs"
/>
<Compile
Include=
"Http\HeaderParser.cs"
/>
<Compile
Include=
"Http\Responses\GenericResponse.cs"
/>
<Compile
Include=
"Network\CachedCertificate.cs"
/>
<Compile
Include=
"Network\Certificate\WinCertificateMaker.cs"
/>
...
...
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