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
990b7412
Commit
990b7412
authored
Oct 11, 2015
by
justcoding121
Committed by
justcoding121
Oct 11, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cleanup
parent
6b42b1b4
Hide whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
590 additions
and
685 deletions
+590
-685
NuGet.Config
.nuget/NuGet.Config
+1
-0
App.config
Titanium.Web.Proxy.Test/App.config
+2
-1
Program.cs
Titanium.Web.Proxy.Test/Program.cs
+23
-30
AssemblyInfo.cs
Titanium.Web.Proxy.Test/Properties/AssemblyInfo.cs
+5
-2
ProxyTestController.cs
Titanium.Web.Proxy.Test/ProxyTestController.cs
+7
-26
SessionEventArgs.cs
Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
+135
-160
BodyNotFoundException.cs
Titanium.Web.Proxy/Exceptions/BodyNotFoundException.cs
+2
-7
HttpWebRequestExtensions.cs
Titanium.Web.Proxy/Extensions/HttpWebRequestExtensions.cs
+6
-6
HttpWebResponseExtensions.cs
Titanium.Web.Proxy/Extensions/HttpWebResponseExtensions.cs
+3
-7
StreamExtensions.cs
Titanium.Web.Proxy/Extensions/StreamExtensions.cs
+12
-16
CertificateManager.cs
Titanium.Web.Proxy/Helpers/CertificateManager.cs
+12
-11
Compression.cs
Titanium.Web.Proxy/Helpers/Compression.cs
+28
-33
CustomBinaryReader.cs
Titanium.Web.Proxy/Helpers/CustomBinaryReader.cs
+15
-27
Firefox.cs
Titanium.Web.Proxy/Helpers/Firefox.cs
+20
-18
NetFramework.cs
Titanium.Web.Proxy/Helpers/NetFramework.cs
+14
-17
SystemProxy.cs
Titanium.Web.Proxy/Helpers/SystemProxy.cs
+44
-32
Tcp.cs
Titanium.Web.Proxy/Helpers/Tcp.cs
+21
-22
HttpHeader.cs
Titanium.Web.Proxy/Models/HttpHeader.cs
+8
-10
AssemblyInfo.cs
Titanium.Web.Proxy/Properties/AssemblyInfo.cs
+5
-2
ProxyServer.cs
Titanium.Web.Proxy/ProxyServer.cs
+56
-58
RequestHandler.cs
Titanium.Web.Proxy/RequestHandler.cs
+106
-124
ResponseHandler.cs
Titanium.Web.Proxy/ResponseHandler.cs
+64
-76
packages.config
Titanium.Web.Proxy/packages.config
+1
-0
No files found.
.nuget/NuGet.Config
View file @
990b7412
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<
configuration
>
<
configuration
>
<
solution
>
<
solution
>
<
add
key
=
"disableSourceControlIntegration"
value
=
"true"
/>
<
add
key
=
"disableSourceControlIntegration"
value
=
"true"
/>
...
...
Titanium.Web.Proxy.Test/App.config
View file @
990b7412
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<
configuration
>
<
configuration
>
<
startup
>
<
startup
>
<
supportedRuntime
version
=
"v4.0"
sku
=
".NETFramework,Version=v4.0,Profile=Client"
/>
<
supportedRuntime
version
=
"v4.0"
sku
=
".NETFramework,Version=v4.0,Profile=Client"
/>
</
startup
>
</
startup
>
</
configuration
>
</
configuration
>
\ No newline at end of file
Titanium.Web.Proxy.Test/Program.cs
View file @
990b7412
using
System
;
using
System
;
using
System.Collections.Generic
;
using
System.IO
;
using
System.Linq
;
using
System.Reflection
;
using
System.Runtime.InteropServices
;
using
System.Runtime.InteropServices
;
using
System.Security.Cryptography.X509Certificates
;
using
System.Text
;
using
Titanium.Web.Proxy.Helpers
;
namespace
Titanium.Web.Proxy.Test
namespace
Titanium.Web.Proxy.Test
{
{
public
class
Program
public
class
Program
{
{
static
ProxyTestController
controller
=
new
ProxyTestController
();
private
static
readonly
ProxyTestController
Controller
=
new
ProxyTestController
();
public
static
void
Main
(
string
[]
args
)
public
static
void
Main
(
string
[]
args
)
{
{
//On Console exit make sure we also exit the proxy
//On Console exit make sure we also exit the proxy
NativeMethods
.
handler
=
new
NativeMethods
.
ConsoleEventDelegate
(
ConsoleEventCallback
);
NativeMethods
.
Handler
=
ConsoleEventCallback
;
NativeMethods
.
SetConsoleCtrlHandler
(
NativeMethods
.
handler
,
true
);
NativeMethods
.
SetConsoleCtrlHandler
(
NativeMethods
.
Handler
,
true
);
Console
.
Write
(
"Do you want to monitor HTTPS? (Y/N):"
);
Console
.
Write
(
"Do you want to monitor HTTPS? (Y/N):"
);
if
(
Console
.
ReadLine
().
Trim
().
ToLower
()
==
"y"
)
var
readLine
=
Console
.
ReadLine
();
if
(
readLine
!=
null
&&
readLine
.
Trim
().
ToLower
()
==
"y"
)
{
{
controller
.
EnableSSL
=
true
;
Controller
.
EnableSsl
=
true
;
}
}
Console
.
Write
(
"Do you want to set this as a System Proxy? (Y/N):"
);
Console
.
Write
(
"Do you want to set this as a System Proxy? (Y/N):"
);
if
(
Console
.
ReadLine
().
Trim
().
ToLower
()
==
"y"
)
var
line
=
Console
.
ReadLine
();
if
(
line
!=
null
&&
line
.
Trim
().
ToLower
()
==
"y"
)
{
{
controller
.
SetAsSystemProxy
=
true
;
Controller
.
SetAsSystemProxy
=
true
;
}
}
//Start proxy controller
//Start proxy controller
c
ontroller
.
StartProxy
();
C
ontroller
.
StartProxy
();
Console
.
WriteLine
(
"Hit any key to exit.."
);
Console
.
WriteLine
(
"Hit any key to exit.."
);
Console
.
WriteLine
();
Console
.
WriteLine
();
Console
.
Read
();
Console
.
Read
();
c
ontroller
.
Stop
();
C
ontroller
.
Stop
();
}
}
static
bool
ConsoleEventCallback
(
int
eventType
)
private
static
bool
ConsoleEventCallback
(
int
eventType
)
{
{
if
(
eventType
==
2
)
if
(
eventType
==
2
)
{
{
try
try
{
{
controller
.
Stop
();
Controller
.
Stop
();
}
catch
{
// ignored
}
}
catch
{
}
}
}
return
false
;
return
false
;
}
}
}
}
internal
static
class
NativeMethods
internal
static
class
NativeMethods
{
{
// Keeps it from getting garbage collected
internal
static
ConsoleEventDelegate
Handler
;
[
DllImport
(
"kernel32.dll"
,
SetLastError
=
true
)]
[
DllImport
(
"kernel32.dll"
,
SetLastError
=
true
)]
internal
static
extern
bool
SetConsoleCtrlHandler
(
ConsoleEventDelegate
callback
,
bool
add
);
internal
static
extern
bool
SetConsoleCtrlHandler
(
ConsoleEventDelegate
callback
,
bool
add
);
// Pinvoke
// Pinvoke
internal
delegate
bool
ConsoleEventDelegate
(
int
eventType
);
internal
delegate
bool
ConsoleEventDelegate
(
int
eventType
);
// Keeps it from getting garbage collected
internal
static
ConsoleEventDelegate
handler
;
}
}
}
}
\ No newline at end of file
Titanium.Web.Proxy.Test/Properties/AssemblyInfo.cs
View file @
990b7412
using
System.Reflection
;
using
System.Reflection
;
using
System.Runtime.CompilerServices
;
using
System.Runtime.InteropServices
;
using
System.Runtime.InteropServices
;
// General Information about an assembly is controlled through the following
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
// associated with an assembly.
[assembly: AssemblyTitle("Demo")]
[assembly: AssemblyTitle("Demo")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyConfiguration("")]
...
@@ -17,9 +17,11 @@ using System.Runtime.InteropServices;
...
@@ -17,9 +17,11 @@ using System.Runtime.InteropServices;
// Setting ComVisible to false makes the types in this assembly not visible
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("33a2109d-0312-4c94-aa51-fbb2a83e63ab")]
[assembly: Guid("33a2109d-0312-4c94-aa51-fbb2a83e63ab")]
// Version information for an assembly consists of the following four values:
// Version information for an assembly consists of the following four values:
...
@@ -32,5 +34,6 @@ using System.Runtime.InteropServices;
...
@@ -32,5 +34,6 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
\ No newline at end of file
Titanium.Web.Proxy.Test/ProxyTestController.cs
View file @
990b7412
using
System
;
using
System
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Text
;
using
System.Net
;
using
System.Text.RegularExpressions
;
using
System.DirectoryServices.AccountManagement
;
using
System.DirectoryServices.ActiveDirectory
;
using
Titanium.Web.Proxy.EventArguments
;
using
Titanium.Web.Proxy.EventArguments
;
using
Titanium.Web.Proxy
;
using
Titanium.Web.Proxy.Helpers
;
namespace
Titanium.Web.Proxy.Test
namespace
Titanium.Web.Proxy.Test
{
{
public
partial
class
ProxyTestController
public
class
ProxyTestController
{
{
public
int
ListeningPort
{
get
;
set
;
}
public
int
ListeningPort
{
get
;
set
;
}
public
bool
EnableS
SL
{
get
;
set
;
}
public
bool
EnableS
sl
{
get
;
set
;
}
public
bool
SetAsSystemProxy
{
get
;
set
;
}
public
bool
SetAsSystemProxy
{
get
;
set
;
}
public
void
StartProxy
()
public
void
StartProxy
()
{
{
ProxyServer
.
BeforeRequest
+=
OnRequest
;
ProxyServer
.
BeforeRequest
+=
OnRequest
;
ProxyServer
.
BeforeResponse
+=
OnResponse
;
ProxyServer
.
BeforeResponse
+=
OnResponse
;
ProxyServer
.
EnableS
SL
=
EnableSSL
;
ProxyServer
.
EnableS
sl
=
EnableSsl
;
ProxyServer
.
SetAsSystemProxy
=
SetAsSystemProxy
;
ProxyServer
.
SetAsSystemProxy
=
SetAsSystemProxy
;
...
@@ -40,9 +27,9 @@ namespace Titanium.Web.Proxy.Test
...
@@ -40,9 +27,9 @@ namespace Titanium.Web.Proxy.Test
ProxyServer
.
ListeningPort
=
ProxyServer
.
ListeningPort
;
ProxyServer
.
ListeningPort
=
ProxyServer
.
ListeningPort
;
Console
.
WriteLine
(
String
.
Format
(
"Proxy listening on local machine port: {0} "
,
ProxyServer
.
ListeningPort
));
Console
.
WriteLine
(
"Proxy listening on local machine port: {0} "
,
ProxyServer
.
ListeningPort
);
}
}
public
void
Stop
()
public
void
Stop
()
{
{
ProxyServer
.
BeforeRequest
-=
OnRequest
;
ProxyServer
.
BeforeRequest
-=
OnRequest
;
...
@@ -52,13 +39,11 @@ namespace Titanium.Web.Proxy.Test
...
@@ -52,13 +39,11 @@ namespace Titanium.Web.Proxy.Test
}
}
//Test On Request, intecept requests
//Test On Request, intecept requests
//Read browser URL send back to proxy by the injection script in OnResponse event
//Read browser URL send back to proxy by the injection script in OnResponse event
public
void
OnRequest
(
object
sender
,
SessionEventArgs
e
)
public
void
OnRequest
(
object
sender
,
SessionEventArgs
e
)
{
{
Console
.
WriteLine
(
e
.
RequestUrl
);
Console
.
WriteLine
(
e
.
RequestURL
);
////read request headers
////read request headers
//var requestHeaders = e.RequestHeaders;
//var requestHeaders = e.RequestHeaders;
...
@@ -82,7 +67,6 @@ namespace Titanium.Web.Proxy.Test
...
@@ -82,7 +67,6 @@ namespace Titanium.Web.Proxy.Test
//{
//{
// e.Ok("<!DOCTYPE html><html><body><h1>Website Blocked</h1><p>Blocked by titanium web proxy.</p></body></html>");
// e.Ok("<!DOCTYPE html><html><body><h1>Website Blocked</h1><p>Blocked by titanium web proxy.</p></body></html>");
//}
//}
}
}
//Test script injection
//Test script injection
...
@@ -112,9 +96,6 @@ namespace Titanium.Web.Proxy.Test
...
@@ -112,9 +96,6 @@ namespace Titanium.Web.Proxy.Test
// e.SetResponseBodyString(modified);
// e.SetResponseBodyString(modified);
// }
// }
//}
//}
}
}
}
}
}
}
\ No newline at end of file
Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
View file @
990b7412
using
System
;
using
System
;
using
System.Text
;
using
System.Collections.Generic
;
using
System.Globalization
;
using
System.IO
;
using
System.IO
;
using
System.Linq
;
using
System.Net
;
using
System.Net
;
using
Titanium.Web.Proxy.Helpers
;
using
System.Net.Sockets
;
using
System.Net.Sockets
;
using
System.Text
;
using
Titanium.Web.Proxy.Exceptions
;
using
Titanium.Web.Proxy.Exceptions
;
using
System.Linq
;
using
Titanium.Web.Proxy.Helpers
;
using
System.Collections.Generic
;
using
Titanium.Web.Proxy.Models
;
using
Titanium.Web.Proxy.Models
;
namespace
Titanium.Web.Proxy.EventArguments
namespace
Titanium.Web.Proxy.EventArguments
{
{
public
class
SessionEventArgs
:
EventArgs
,
IDisposable
public
class
SessionEventArgs
:
EventArgs
,
IDisposable
{
{
readonly
int
_bufferSize
;
internal
int
BUFFER_SIZE
;
internal
SessionEventArgs
(
int
bufferSize
)
{
_bufferSize
=
bufferSize
;
}
internal
TcpClient
c
lient
{
get
;
set
;
}
internal
TcpClient
C
lient
{
get
;
set
;
}
internal
Stream
c
lientStream
{
get
;
set
;
}
internal
Stream
C
lientStream
{
get
;
set
;
}
internal
CustomBinaryReader
c
lientStreamReader
{
get
;
set
;
}
internal
CustomBinaryReader
C
lientStreamReader
{
get
;
set
;
}
internal
StreamWriter
c
lientStreamWriter
{
get
;
set
;
}
internal
StreamWriter
C
lientStreamWriter
{
get
;
set
;
}
internal
bool
isHttps
{
get
;
set
;
}
public
bool
IsHttps
{
get
;
internal
set
;
}
internal
string
requestURL
{
get
;
set
;
}
public
string
RequestUrl
{
get
;
internal
set
;
}
internal
string
requestHostname
{
get
;
set
;
}
public
string
RequestHostname
{
get
;
internal
set
;
}
internal
int
clientPort
{
get
;
set
;
}
public
int
ClientPort
{
get
;
internal
set
;
}
internal
IPAddress
clientIpAddress
{
get
;
set
;
}
public
IPAddress
ClientIpAddress
{
get
;
internal
set
;
}
internal
Encoding
r
equestEncoding
{
get
;
set
;
}
internal
Encoding
R
equestEncoding
{
get
;
set
;
}
internal
Version
r
equestHttpVersion
{
get
;
set
;
}
internal
Version
R
equestHttpVersion
{
get
;
set
;
}
internal
bool
r
equestIsAlive
{
get
;
set
;
}
internal
bool
R
equestIsAlive
{
get
;
set
;
}
internal
bool
c
ancelRequest
{
get
;
set
;
}
internal
bool
C
ancelRequest
{
get
;
set
;
}
internal
byte
[]
r
equestBody
{
get
;
set
;
}
internal
byte
[]
R
equestBody
{
get
;
set
;
}
internal
string
r
equestBodyString
{
get
;
set
;
}
internal
string
R
equestBodyString
{
get
;
set
;
}
internal
bool
r
equestBodyRead
{
get
;
set
;
}
internal
bool
R
equestBodyRead
{
get
;
set
;
}
internal
List
<
HttpHeader
>
requestHeaders
{
get
;
set
;
}
public
List
<
HttpHeader
>
RequestHeaders
{
get
;
internal
set
;
}
internal
bool
RequestLocked
{
get
;
set
;
}
internal
bool
RequestLocked
{
get
;
set
;
}
internal
HttpWebRequest
p
roxyRequest
{
get
;
set
;
}
internal
HttpWebRequest
P
roxyRequest
{
get
;
set
;
}
internal
Encoding
r
esponseEncoding
{
get
;
set
;
}
internal
Encoding
R
esponseEncoding
{
get
;
set
;
}
internal
Stream
r
esponseStream
{
get
;
set
;
}
internal
Stream
R
esponseStream
{
get
;
set
;
}
internal
byte
[]
r
esponseBody
{
get
;
set
;
}
internal
byte
[]
R
esponseBody
{
get
;
set
;
}
internal
string
r
esponseBodyString
{
get
;
set
;
}
internal
string
R
esponseBodyString
{
get
;
set
;
}
internal
bool
r
esponseBodyRead
{
get
;
set
;
}
internal
bool
R
esponseBodyRead
{
get
;
set
;
}
internal
List
<
HttpHeader
>
responseHeaders
{
get
;
set
;
}
public
List
<
HttpHeader
>
ResponseHeaders
{
get
;
internal
set
;
}
internal
bool
ResponseLocked
{
get
;
set
;
}
internal
bool
ResponseLocked
{
get
;
set
;
}
internal
HttpWebResponse
serverResponse
{
get
;
set
;
}
internal
HttpWebResponse
ServerResponse
{
get
;
set
;
}
public
int
ClientPort
{
get
{
return
this
.
clientPort
;
}
}
public
IPAddress
ClientIpAddress
{
get
{
return
this
.
clientIpAddress
;
}
}
public
bool
IsHttps
{
get
{
return
this
.
isHttps
;
}
}
public
string
RequestURL
{
get
{
return
this
.
requestURL
;
}
}
public
string
RequestHostname
{
get
{
return
this
.
requestHostname
;
}
}
public
List
<
HttpHeader
>
RequestHeaders
{
get
{
return
this
.
requestHeaders
;
}
}
public
List
<
HttpHeader
>
ResponseHeaders
{
get
{
return
this
.
responseHeaders
;
}
}
public
int
RequestContentLength
public
int
RequestContentLength
{
{
get
get
{
{
if
(
this
.
requestHeaders
.
Any
(
x
=>
x
.
Name
.
ToLower
()
==
"content-length"
))
if
(
RequestHeaders
.
All
(
x
=>
x
.
Name
.
ToLower
()
!=
"content-length"
))
return
-
1
;
{
int
contentLen
;
int
contentLen
;
int
.
TryParse
(
RequestHeaders
.
First
(
x
=>
x
.
Name
.
ToLower
()
==
"content-length"
).
Value
,
out
contentLen
);
int
.
TryParse
(
this
.
requestHeaders
.
First
(
x
=>
x
.
Name
.
ToLower
()
==
"content-length"
).
Value
,
out
contentLen
);
if
(
contentLen
!=
0
)
if
(
contentLen
!=
0
)
return
contentLen
;
return
contentLen
;
}
return
-
1
;
return
-
1
;
}
}
}
}
public
string
RequestMethod
{
get
{
return
this
.
proxyRequest
.
Method
;
}
}
public
string
RequestMethod
{
get
{
return
ProxyRequest
.
Method
;
}
}
public
HttpStatusCode
ResponseStatusCode
{
get
{
return
this
.
serverResponse
.
StatusCode
;
}
}
public
HttpStatusCode
ResponseStatusCode
public
string
ResponseContentType
{
get
{
return
this
.
responseHeaders
.
Any
(
x
=>
x
.
Name
.
ToLower
()
==
"content-type"
)
?
this
.
responseHeaders
.
First
(
x
=>
x
.
Name
.
ToLower
()
==
"content-type"
).
Value
:
null
;
}
}
{
get
{
return
ServerResponse
.
StatusCode
;
}
}
public
string
ResponseContentType
{
get
{
return
ResponseHeaders
.
Any
(
x
=>
x
.
Name
.
ToLower
()
==
"content-type"
)
?
ResponseHeaders
.
First
(
x
=>
x
.
Name
.
ToLower
()
==
"content-type"
).
Value
:
null
;
}
}
internal
SessionEventArgs
(
int
bufferSize
)
public
void
Dispose
(
)
{
{
BUFFER_SIZE
=
bufferSize
;
if
(
ProxyRequest
!=
null
)
ProxyRequest
.
Abort
();
if
(
ResponseStream
!=
null
)
ResponseStream
.
Dispose
();
if
(
ServerResponse
!=
null
)
ServerResponse
.
Close
();
}
}
private
void
r
eadRequestBody
()
private
void
R
eadRequestBody
()
{
{
if
((
proxyRequest
.
Method
.
ToUpper
()
!=
"POST"
&&
p
roxyRequest
.
Method
.
ToUpper
()
!=
"PUT"
))
if
((
ProxyRequest
.
Method
.
ToUpper
()
!=
"POST"
&&
P
roxyRequest
.
Method
.
ToUpper
()
!=
"PUT"
))
{
{
throw
new
BodyNotFoundException
(
"Request don't have a body."
+
throw
new
BodyNotFoundException
(
"Request don't have a body."
+
"Please verify that this request is a Http POST/PUT and request content length is greater than zero before accessing the body."
);
"Please verify that this request is a Http POST/PUT and request content length is greater than zero before accessing the body."
);
}
}
if
(
r
equestBody
==
null
)
if
(
R
equestBody
==
null
)
{
{
bool
isChunked
=
false
;
var
isChunked
=
false
;
string
requestContentEncoding
=
null
;
string
requestContentEncoding
=
null
;
if
(
r
equestHeaders
.
Any
(
x
=>
x
.
Name
.
ToLower
()
==
"content-encoding"
))
if
(
R
equestHeaders
.
Any
(
x
=>
x
.
Name
.
ToLower
()
==
"content-encoding"
))
{
{
requestContentEncoding
=
r
equestHeaders
.
First
(
x
=>
x
.
Name
.
ToLower
()
==
"content-encoding"
).
Value
;
requestContentEncoding
=
R
equestHeaders
.
First
(
x
=>
x
.
Name
.
ToLower
()
==
"content-encoding"
).
Value
;
}
}
if
(
r
equestHeaders
.
Any
(
x
=>
x
.
Name
.
ToLower
()
==
"transfer-encoding"
))
if
(
R
equestHeaders
.
Any
(
x
=>
x
.
Name
.
ToLower
()
==
"transfer-encoding"
))
{
{
var
transferEncoding
=
requestHeaders
.
First
(
x
=>
x
.
Name
.
ToLower
()
==
"transfer-encoding"
).
Value
.
ToLower
();
var
transferEncoding
=
RequestHeaders
.
First
(
x
=>
x
.
Name
.
ToLower
()
==
"transfer-encoding"
).
Value
.
ToLower
();
if
(
transferEncoding
.
Contains
(
"chunked"
))
if
(
transferEncoding
.
Contains
(
"chunked"
))
{
{
isChunked
=
true
;
isChunked
=
true
;
}
}
}
}
if
(
requestContentEncoding
==
null
&&
!
isChunked
)
if
(
requestContentEncoding
==
null
&&
!
isChunked
)
requestBody
=
c
lientStreamReader
.
ReadBytes
(
RequestContentLength
);
RequestBody
=
C
lientStreamReader
.
ReadBytes
(
RequestContentLength
);
else
else
{
{
using
(
var
requestBodyStream
=
new
MemoryStream
())
using
(
var
requestBodyStream
=
new
MemoryStream
())
...
@@ -128,76 +140,72 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -128,76 +140,72 @@ namespace Titanium.Web.Proxy.EventArguments
{
{
while
(
true
)
while
(
true
)
{
{
var
chuchkHead
=
c
lientStreamReader
.
ReadLine
();
var
chuchkHead
=
C
lientStreamReader
.
ReadLine
();
var
chunkSize
=
int
.
Parse
(
chuchkHead
,
System
.
Globalization
.
NumberStyles
.
HexNumber
);
var
chunkSize
=
int
.
Parse
(
chuchkHead
,
NumberStyles
.
HexNumber
);
if
(
chunkSize
!=
0
)
if
(
chunkSize
!=
0
)
{
{
var
buffer
=
c
lientStreamReader
.
ReadBytes
(
chunkSize
);
var
buffer
=
C
lientStreamReader
.
ReadBytes
(
chunkSize
);
requestBodyStream
.
Write
(
buffer
,
0
,
buffer
.
Length
);
requestBodyStream
.
Write
(
buffer
,
0
,
buffer
.
Length
);
//chunk trail
var
chunkTrail
=
c
lientStreamReader
.
ReadLine
();
C
lientStreamReader
.
ReadLine
();
}
}
else
else
{
{
c
lientStreamReader
.
ReadLine
();
C
lientStreamReader
.
ReadLine
();
break
;
break
;
}
}
}
}
}
}
try
try
{
{
switch
(
requestContentEncoding
)
switch
(
requestContentEncoding
)
{
{
case
"gzip"
:
case
"gzip"
:
r
equestBody
=
CompressionHelper
.
DecompressGzip
(
requestBodyStream
);
R
equestBody
=
CompressionHelper
.
DecompressGzip
(
requestBodyStream
);
break
;
break
;
case
"deflate"
:
case
"deflate"
:
r
equestBody
=
CompressionHelper
.
DecompressDeflate
(
requestBodyStream
);
R
equestBody
=
CompressionHelper
.
DecompressDeflate
(
requestBodyStream
);
break
;
break
;
case
"zlib"
:
case
"zlib"
:
r
equestBody
=
CompressionHelper
.
DecompressGzip
(
requestBodyStream
);
R
equestBody
=
CompressionHelper
.
DecompressGzip
(
requestBodyStream
);
break
;
break
;
default
:
default
:
r
equestBody
=
requestBodyStream
.
ToArray
();
R
equestBody
=
requestBodyStream
.
ToArray
();
break
;
break
;
}
}
}
}
catch
{
catch
requestBody
=
requestBodyStream
.
ToArray
();
{
RequestBody
=
requestBodyStream
.
ToArray
();
}
}
}
}
}
}
}
}
r
equestBodyRead
=
true
;
R
equestBodyRead
=
true
;
}
}
private
void
readResponseBody
()
private
void
ReadResponseBody
()
{
{
if
(
r
esponseBody
==
null
)
if
(
R
esponseBody
==
null
)
{
{
switch
(
ServerResponse
.
ContentEncoding
)
switch
(
serverResponse
.
ContentEncoding
)
{
{
case
"gzip"
:
case
"gzip"
:
responseBody
=
CompressionHelper
.
DecompressGzip
(
r
esponseStream
);
ResponseBody
=
CompressionHelper
.
DecompressGzip
(
R
esponseStream
);
break
;
break
;
case
"deflate"
:
case
"deflate"
:
responseBody
=
CompressionHelper
.
DecompressDeflate
(
r
esponseStream
);
ResponseBody
=
CompressionHelper
.
DecompressDeflate
(
R
esponseStream
);
break
;
break
;
case
"zlib"
:
case
"zlib"
:
responseBody
=
CompressionHelper
.
DecompressZlib
(
r
esponseStream
);
ResponseBody
=
CompressionHelper
.
DecompressZlib
(
R
esponseStream
);
break
;
break
;
default
:
default
:
responseBody
=
DecodeData
(
r
esponseStream
);
ResponseBody
=
DecodeData
(
R
esponseStream
);
break
;
break
;
}
}
responseBodyRead
=
true
;
ResponseBodyRead
=
true
;
}
}
}
}
...
@@ -205,8 +213,8 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -205,8 +213,8 @@ namespace Titanium.Web.Proxy.EventArguments
//stream reader not recomended for images
//stream reader not recomended for images
private
byte
[]
DecodeData
(
Stream
responseStream
)
private
byte
[]
DecodeData
(
Stream
responseStream
)
{
{
byte
[]
buffer
=
new
byte
[
BUFFER_SIZE
];
var
buffer
=
new
byte
[
_bufferSize
];
using
(
MemoryStream
ms
=
new
MemoryStream
())
using
(
var
ms
=
new
MemoryStream
())
{
{
int
read
;
int
read
;
while
((
read
=
responseStream
.
Read
(
buffer
,
0
,
buffer
.
Length
))
>
0
)
while
((
read
=
responseStream
.
Read
(
buffer
,
0
,
buffer
.
Length
))
>
0
)
...
@@ -215,117 +223,105 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -215,117 +223,105 @@ namespace Titanium.Web.Proxy.EventArguments
}
}
return
ms
.
ToArray
();
return
ms
.
ToArray
();
}
}
}
}
public
Encoding
GetRequestBodyEncoding
()
public
Encoding
GetRequestBodyEncoding
()
{
{
if
(
RequestLocked
)
throw
new
Exception
(
"You cannot call this function after request is made to server."
);
if
(
RequestLocked
)
throw
new
Exception
(
"You cannot call this function after request is made to server."
);
return
r
equestEncoding
;
return
R
equestEncoding
;
}
}
public
byte
[]
GetRequestBody
()
public
byte
[]
GetRequestBody
()
{
{
if
(
RequestLocked
)
throw
new
Exception
(
"You cannot call this function after request is made to server."
);
if
(
RequestLocked
)
throw
new
Exception
(
"You cannot call this function after request is made to server."
);
readRequestBody
();
ReadRequestBody
();
return
requestBody
;
return
RequestBody
;
}
}
public
string
GetRequestBodyAsString
()
public
string
GetRequestBodyAsString
()
{
{
if
(
RequestLocked
)
throw
new
Exception
(
"You cannot call this function after request is made to server."
);
if
(
RequestLocked
)
throw
new
Exception
(
"You cannot call this function after request is made to server."
);
readRequestBody
();
ReadRequestBody
();
if
(
requestBodyString
==
null
)
{
requestBodyString
=
requestEncoding
.
GetString
(
requestBody
);
}
return
requestBodyString
;
return
RequestBodyString
??
(
RequestBodyString
=
RequestEncoding
.
GetString
(
RequestBody
));
}
}
public
void
SetRequestBody
(
byte
[]
body
)
public
void
SetRequestBody
(
byte
[]
body
)
{
{
if
(
RequestLocked
)
throw
new
Exception
(
"You cannot call this function after request is made to server."
);
if
(
RequestLocked
)
throw
new
Exception
(
"You cannot call this function after request is made to server."
);
if
(!
r
equestBodyRead
)
if
(!
R
equestBodyRead
)
{
{
r
eadRequestBody
();
R
eadRequestBody
();
}
}
r
equestBody
=
body
;
R
equestBody
=
body
;
r
equestBodyRead
=
true
;
R
equestBodyRead
=
true
;
}
}
public
void
SetRequestBodyString
(
string
body
)
public
void
SetRequestBodyString
(
string
body
)
{
{
if
(
RequestLocked
)
throw
new
Exception
(
"Youcannot call this function after request is made to server."
);
if
(
RequestLocked
)
throw
new
Exception
(
"Youcannot call this function after request is made to server."
);
if
(!
r
equestBodyRead
)
if
(!
R
equestBodyRead
)
{
{
r
eadRequestBody
();
R
eadRequestBody
();
}
}
this
.
requestBody
=
r
equestEncoding
.
GetBytes
(
body
);
RequestBody
=
R
equestEncoding
.
GetBytes
(
body
);
r
equestBodyRead
=
true
;
R
equestBodyRead
=
true
;
}
}
public
Encoding
GetResponseBodyEncoding
()
public
Encoding
GetResponseBodyEncoding
()
{
{
if
(!
RequestLocked
)
throw
new
Exception
(
"You cannot call this function before request is made to server."
);
if
(!
RequestLocked
)
throw
new
Exception
(
"You cannot call this function before request is made to server."
);
return
r
esponseEncoding
;
return
R
esponseEncoding
;
}
}
public
byte
[]
GetResponseBody
()
public
byte
[]
GetResponseBody
()
{
{
if
(!
RequestLocked
)
throw
new
Exception
(
"You cannot call this function before request is made to server."
);
if
(!
RequestLocked
)
throw
new
Exception
(
"You cannot call this function before request is made to server."
);
r
eadResponseBody
();
R
eadResponseBody
();
return
r
esponseBody
;
return
R
esponseBody
;
}
}
public
string
GetResponseBodyAsString
()
public
string
GetResponseBodyAsString
()
{
{
if
(!
RequestLocked
)
throw
new
Exception
(
"You cannot call this function before request is made to server."
);
if
(!
RequestLocked
)
throw
new
Exception
(
"You cannot call this function before request is made to server."
);
GetResponseBody
();
GetResponseBody
();
if
(
responseBodyString
==
null
)
return
ResponseBodyString
??
(
ResponseBodyString
=
ResponseEncoding
.
GetString
(
ResponseBody
));
{
responseBodyString
=
responseEncoding
.
GetString
(
responseBody
);
}
return
responseBodyString
;
}
}
public
void
SetResponseBody
(
byte
[]
body
)
public
void
SetResponseBody
(
byte
[]
body
)
{
{
if
(!
RequestLocked
)
throw
new
Exception
(
"You cannot call this function before request is made to server."
);
if
(!
RequestLocked
)
throw
new
Exception
(
"You cannot call this function before request is made to server."
);
if
(
r
esponseBody
==
null
)
if
(
R
esponseBody
==
null
)
{
{
GetResponseBody
();
GetResponseBody
();
}
}
responseBody
=
body
;
ResponseBody
=
body
;
}
}
public
void
SetResponseBodyString
(
string
body
)
public
void
SetResponseBodyString
(
string
body
)
{
{
if
(!
RequestLocked
)
throw
new
Exception
(
"You cannot call this function before request is made to server."
);
if
(!
RequestLocked
)
throw
new
Exception
(
"You cannot call this function before request is made to server."
);
if
(
r
esponseBody
==
null
)
if
(
R
esponseBody
==
null
)
{
{
GetResponseBody
();
GetResponseBody
();
}
}
var
bodyBytes
=
r
esponseEncoding
.
GetBytes
(
body
);
var
bodyBytes
=
R
esponseEncoding
.
GetBytes
(
body
);
SetResponseBody
(
bodyBytes
);
SetResponseBody
(
bodyBytes
);
}
}
...
@@ -339,45 +335,24 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -339,45 +335,24 @@ namespace Titanium.Web.Proxy.EventArguments
var
result
=
Encoding
.
Default
.
GetBytes
(
html
);
var
result
=
Encoding
.
Default
.
GetBytes
(
html
);
StreamWriter
connectStreamWriter
=
new
StreamWriter
(
c
lientStream
);
var
connectStreamWriter
=
new
StreamWriter
(
C
lientStream
);
var
s
=
String
.
Format
(
"HTTP/{0}.{1} {2} {3}"
,
requestHttpVersion
.
Major
,
r
equestHttpVersion
.
Minor
,
200
,
"Ok"
);
var
s
=
string
.
Format
(
"HTTP/{0}.{1} {2} {3}"
,
RequestHttpVersion
.
Major
,
R
equestHttpVersion
.
Minor
,
200
,
"Ok"
);
connectStreamWriter
.
WriteLine
(
s
);
connectStreamWriter
.
WriteLine
(
s
);
connectStreamWriter
.
WriteLine
(
String
.
Format
(
"Timestamp: {0}"
,
DateTime
.
Now
.
ToString
())
);
connectStreamWriter
.
WriteLine
(
"Timestamp: {0}"
,
DateTime
.
Now
);
connectStreamWriter
.
WriteLine
(
"content-length: "
+
result
.
Length
);
connectStreamWriter
.
WriteLine
(
"content-length: "
+
result
.
Length
);
connectStreamWriter
.
WriteLine
(
"Cache-Control: no-cache, no-store, must-revalidate"
);
connectStreamWriter
.
WriteLine
(
"Cache-Control: no-cache, no-store, must-revalidate"
);
connectStreamWriter
.
WriteLine
(
"Pragma: no-cache"
);
connectStreamWriter
.
WriteLine
(
"Pragma: no-cache"
);
connectStreamWriter
.
WriteLine
(
"Expires: 0"
);
connectStreamWriter
.
WriteLine
(
"Expires: 0"
);
if
(
requestIsAlive
)
connectStreamWriter
.
WriteLine
(
RequestIsAlive
?
"Connection: Keep-Alive"
:
"Connection: close"
);
{
connectStreamWriter
.
WriteLine
(
"Connection: Keep-Alive"
);
}
else
connectStreamWriter
.
WriteLine
(
"Connection: close"
);
connectStreamWriter
.
WriteLine
();
connectStreamWriter
.
WriteLine
();
connectStreamWriter
.
Flush
();
connectStreamWriter
.
Flush
();
c
lientStream
.
Write
(
result
,
0
,
result
.
Length
);
C
lientStream
.
Write
(
result
,
0
,
result
.
Length
);
cancelRequest
=
true
;
CancelRequest
=
true
;
}
}
public
void
Dispose
()
{
if
(
this
.
proxyRequest
!=
null
)
this
.
proxyRequest
.
Abort
();
if
(
this
.
responseStream
!=
null
)
this
.
responseStream
.
Dispose
();
if
(
this
.
serverResponse
!=
null
)
this
.
serverResponse
.
Close
();
}
}
}
}
}
\ No newline at end of file
Titanium.Web.Proxy/Exceptions/BodyNotFoundException.cs
View file @
990b7412
using
System
;
using
System
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Text
;
namespace
Titanium.Web.Proxy.Exceptions
namespace
Titanium.Web.Proxy.Exceptions
{
{
public
class
BodyNotFoundException
:
Exception
public
class
BodyNotFoundException
:
Exception
{
{
public
BodyNotFoundException
(
string
message
)
public
BodyNotFoundException
(
string
message
)
:
base
(
message
)
:
base
(
message
)
{
{
}
}
}
}
}
}
\ No newline at end of file
Titanium.Web.Proxy/Extensions/HttpWebRequestExtensions.cs
View file @
990b7412
using
System
;
using
System.Net
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Net
;
using
System.Text
;
using
System.Text
;
namespace
Titanium.Web.Proxy.Extensions
namespace
Titanium.Web.Proxy.Extensions
...
@@ -24,9 +21,12 @@ namespace Titanium.Web.Proxy.Extensions
...
@@ -24,9 +21,12 @@ namespace Titanium.Web.Proxy.Extensions
}
}
}
}
}
}
catch
{
}
catch
{
// ignored
}
return
Encoding
.
GetEncoding
(
"ISO-8859-1"
);
return
Encoding
.
GetEncoding
(
"ISO-8859-1"
);
}
}
}
}
}
}
\ No newline at end of file
Titanium.Web.Proxy/Extensions/HttpWebResponseExtensions.cs
View file @
990b7412
using
System
;
using
System.Net
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Net
;
using
System.Text
;
using
System.Text
;
namespace
Titanium.Web.Proxy.Extensions
namespace
Titanium.Web.Proxy.Extensions
...
@@ -11,8 +8,7 @@ namespace Titanium.Web.Proxy.Extensions
...
@@ -11,8 +8,7 @@ namespace Titanium.Web.Proxy.Extensions
public
static
Encoding
GetEncoding
(
this
HttpWebResponse
response
)
public
static
Encoding
GetEncoding
(
this
HttpWebResponse
response
)
{
{
if
(
string
.
IsNullOrEmpty
(
response
.
CharacterSet
))
return
Encoding
.
GetEncoding
(
"ISO-8859-1"
);
if
(
string
.
IsNullOrEmpty
(
response
.
CharacterSet
))
return
Encoding
.
GetEncoding
(
"ISO-8859-1"
);
else
return
Encoding
.
GetEncoding
(
response
.
CharacterSet
);
return
Encoding
.
GetEncoding
(
response
.
CharacterSet
);
}
}
}
}
}
}
\ No newline at end of file
Titanium.Web.Proxy/Extensions/StreamExtensions.cs
View file @
990b7412
using
System
;
using
System
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Text
;
using
System.IO
;
using
System.IO
;
using
System.Text
;
namespace
Titanium.Web.Proxy.Extensions
namespace
Titanium.Web.Proxy.Extensions
{
{
public
static
class
StreamHelper
public
static
class
StreamHelper
{
{
private
const
int
DEFAULT_BUFFER_SIZE
=
8192
;
// +32767
public
static
void
CopyToAsync
(
this
Stream
input
,
string
initialData
,
Stream
output
,
int
bufferSize
)
public
static
void
CopyToAsync
(
this
Stream
input
,
string
initialData
,
Stream
output
,
int
bufferSize
)
{
{
var
bytes
=
Encoding
.
ASCII
.
GetBytes
(
initialData
);
var
bytes
=
Encoding
.
ASCII
.
GetBytes
(
initialData
);
output
.
Write
(
bytes
,
0
,
bytes
.
Length
);
output
.
Write
(
bytes
,
0
,
bytes
.
Length
);
CopyToAsync
(
input
,
output
,
bufferSize
);
CopyToAsync
(
input
,
output
,
bufferSize
);
}
}
//http://stackoverflow.com/questions/1540658/net-asynchronous-stream-read-write
//http://stackoverflow.com/questions/1540658/net-asynchronous-stream-read-write
...
@@ -25,15 +21,14 @@ namespace Titanium.Web.Proxy.Extensions
...
@@ -25,15 +21,14 @@ namespace Titanium.Web.Proxy.Extensions
if
(!
input
.
CanRead
)
throw
new
InvalidOperationException
(
"input must be open for reading"
);
if
(!
input
.
CanRead
)
throw
new
InvalidOperationException
(
"input must be open for reading"
);
if
(!
output
.
CanWrite
)
throw
new
InvalidOperationException
(
"output must be open for writing"
);
if
(!
output
.
CanWrite
)
throw
new
InvalidOperationException
(
"output must be open for writing"
);
byte
[][]
buf
=
{
new
byte
[
bufferSize
],
new
byte
[
bufferSize
]
};
byte
[][]
buf
=
{
new
byte
[
bufferSize
],
new
byte
[
bufferSize
]
};
int
[]
bufl
=
{
0
,
0
};
int
[]
bufl
=
{
0
,
0
};
int
bufno
=
0
;
var
bufno
=
0
;
IAsyncResult
read
=
input
.
BeginRead
(
buf
[
bufno
],
0
,
buf
[
bufno
].
Length
,
null
,
null
);
var
read
=
input
.
BeginRead
(
buf
[
bufno
],
0
,
buf
[
bufno
].
Length
,
null
,
null
);
IAsyncResult
write
=
null
;
IAsyncResult
write
=
null
;
while
(
true
)
while
(
true
)
{
{
// wait for the read operation to complete
// wait for the read operation to complete
read
.
AsyncWaitHandle
.
WaitOne
();
read
.
AsyncWaitHandle
.
WaitOne
();
bufl
[
bufno
]
=
input
.
EndRead
(
read
);
bufl
[
bufno
]
=
input
.
EndRead
(
read
);
...
@@ -62,7 +57,6 @@ namespace Titanium.Web.Proxy.Extensions
...
@@ -62,7 +57,6 @@ namespace Titanium.Web.Proxy.Extensions
// A little speedier than using a ternary expression.
// A little speedier than using a ternary expression.
bufno
^=
1
;
// bufno = ( bufno == 0 ? 1 : 0 ) ;
bufno
^=
1
;
// bufno = ( bufno == 0 ? 1 : 0 ) ;
read
=
input
.
BeginRead
(
buf
[
bufno
],
0
,
buf
[
bufno
].
Length
,
null
,
null
);
read
=
input
.
BeginRead
(
buf
[
bufno
],
0
,
buf
[
bufno
].
Length
,
null
,
null
);
}
}
// wait for the final in-flight write operation, if one exists, to complete
// wait for the final in-flight write operation, if one exists, to complete
...
@@ -75,9 +69,11 @@ namespace Titanium.Web.Proxy.Extensions
...
@@ -75,9 +69,11 @@ namespace Titanium.Web.Proxy.Extensions
output
.
Flush
();
output
.
Flush
();
}
}
catch
{
}
catch
{
// ignored
}
// return to the caller ;
// return to the caller ;
return
;
}
}
}
}
}
}
\ No newline at end of file
Titanium.Web.Proxy/Helpers/CertificateManager.cs
View file @
990b7412
...
@@ -8,10 +8,10 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -8,10 +8,10 @@ namespace Titanium.Web.Proxy.Helpers
{
{
public
class
CertificateManager
:
IDisposable
public
class
CertificateManager
:
IDisposable
{
{
private
const
string
C
ERT_CREATE_FORMAT
=
private
const
string
C
ertCreateFormat
=
"-ss {0} -n \"CN={1}, O={2}\" -sky {3} -cy {4} -m 120 -a sha256 -eku 1.3.6.1.5.5.7.3.1 -b {5:MM/dd/yyyy} {6}"
;
"-ss {0} -n \"CN={1}, O={2}\" -sky {3} -cy {4} -m 120 -a sha256 -eku 1.3.6.1.5.5.7.3.1 -b {5:MM/dd/yyyy} {6}"
;
private
readonly
IDictionary
<
string
,
X509Certificate2
>
certificateCache
;
private
readonly
IDictionary
<
string
,
X509Certificate2
>
_
certificateCache
;
public
string
Issuer
{
get
;
private
set
;
}
public
string
Issuer
{
get
;
private
set
;
}
public
string
RootCertificateName
{
get
;
private
set
;
}
public
string
RootCertificateName
{
get
;
private
set
;
}
...
@@ -27,7 +27,7 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -27,7 +27,7 @@ namespace Titanium.Web.Proxy.Helpers
MyStore
=
new
X509Store
(
StoreName
.
My
,
StoreLocation
.
CurrentUser
);
MyStore
=
new
X509Store
(
StoreName
.
My
,
StoreLocation
.
CurrentUser
);
RootStore
=
new
X509Store
(
StoreName
.
Root
,
StoreLocation
.
CurrentUser
);
RootStore
=
new
X509Store
(
StoreName
.
Root
,
StoreLocation
.
CurrentUser
);
certificateCache
=
new
Dictionary
<
string
,
X509Certificate2
>();
_
certificateCache
=
new
Dictionary
<
string
,
X509Certificate2
>();
}
}
/// <summary>
/// <summary>
...
@@ -69,8 +69,9 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -69,8 +69,9 @@ namespace Titanium.Web.Proxy.Helpers
}
}
protected
virtual
X509Certificate2
CreateCertificate
(
X509Store
store
,
string
certificateName
)
protected
virtual
X509Certificate2
CreateCertificate
(
X509Store
store
,
string
certificateName
)
{
{
if
(
certificateCache
.
ContainsKey
(
certificateName
))
return
certificateCache
[
certificateName
];
if
(
_certificateCache
.
ContainsKey
(
certificateName
))
return
_certificateCache
[
certificateName
];
lock
(
store
)
lock
(
store
)
{
{
...
@@ -80,7 +81,7 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -80,7 +81,7 @@ namespace Titanium.Web.Proxy.Helpers
store
.
Open
(
OpenFlags
.
ReadWrite
);
store
.
Open
(
OpenFlags
.
ReadWrite
);
string
certificateSubject
=
string
.
Format
(
"CN={0}, O={1}"
,
certificateName
,
Issuer
);
string
certificateSubject
=
string
.
Format
(
"CN={0}, O={1}"
,
certificateName
,
Issuer
);
X509Certificate2Collection
certificates
=
var
certificates
=
FindCertificates
(
store
,
certificateSubject
);
FindCertificates
(
store
,
certificateSubject
);
if
(
certificates
!=
null
)
if
(
certificates
!=
null
)
...
@@ -102,8 +103,8 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -102,8 +103,8 @@ namespace Titanium.Web.Proxy.Helpers
finally
finally
{
{
store
.
Close
();
store
.
Close
();
if
(
certificate
!=
null
&&
!
certificateCache
.
ContainsKey
(
certificateName
))
if
(
certificate
!=
null
&&
!
_
certificateCache
.
ContainsKey
(
certificateName
))
certificateCache
.
Add
(
certificateName
,
certificate
);
_
certificateCache
.
Add
(
certificateName
,
certificate
);
}
}
}
}
}
}
...
@@ -151,9 +152,9 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -151,9 +152,9 @@ namespace Titanium.Web.Proxy.Helpers
{
{
store
.
Close
();
store
.
Close
();
if
(
certificates
==
null
&&
if
(
certificates
==
null
&&
certificateCache
.
ContainsKey
(
certificateName
))
_
certificateCache
.
ContainsKey
(
certificateName
))
{
{
certificateCache
.
Remove
(
certificateName
);
_
certificateCache
.
Remove
(
certificateName
);
}
}
}
}
}
}
...
@@ -164,7 +165,7 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -164,7 +165,7 @@ namespace Titanium.Web.Proxy.Helpers
bool
isRootCertificate
=
bool
isRootCertificate
=
(
certificateName
==
RootCertificateName
);
(
certificateName
==
RootCertificateName
);
string
certCreatArgs
=
string
.
Format
(
C
ERT_CREATE_FORMAT
,
string
certCreatArgs
=
string
.
Format
(
C
ertCreateFormat
,
store
.
Name
,
certificateName
,
Issuer
,
store
.
Name
,
certificateName
,
Issuer
,
isRootCertificate
?
"signature"
:
"exchange"
,
isRootCertificate
?
"signature"
:
"exchange"
,
isRootCertificate
?
"authority"
:
"end"
,
DateTime
.
Now
,
isRootCertificate
?
"authority"
:
"end"
,
DateTime
.
Now
,
...
...
Titanium.Web.Proxy/Helpers/Compression.cs
View file @
990b7412
using
System
;
using
System.Diagnostics.CodeAnalysis
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Text
;
using
System.IO
;
using
System.IO
;
using
System.Diagnostics.CodeAnalysis
;
using
Ionic.Zlib
;
namespace
Titanium.Web.Proxy.Helpers
namespace
Titanium.Web.Proxy.Helpers
{
{
public
class
CompressionHelper
public
class
CompressionHelper
{
{
private
static
readonly
int
BUFFER_SIZE
=
8192
;
private
const
int
BufferSize
=
8192
;
[
S
ystem
.
Diagnostics
.
CodeAnalysis
.
S
uppressMessage
(
"Microsoft.Usage"
,
"CA2202:Do not dispose objects multiple times"
)]
[
SuppressMessage
(
"Microsoft.Usage"
,
"CA2202:Do not dispose objects multiple times"
)]
public
static
byte
[]
CompressZlib
(
byte
[]
bytes
)
public
static
byte
[]
CompressZlib
(
byte
[]
bytes
)
{
{
using
(
var
ms
=
new
MemoryStream
())
using
(
MemoryStream
ms
=
new
MemoryStream
())
{
{
using
(
Ionic
.
Zlib
.
ZlibStream
zip
=
new
Ionic
.
Zlib
.
ZlibStream
(
ms
,
Ionic
.
Zlib
.
CompressionMode
.
Compress
,
true
))
using
(
var
zip
=
new
ZlibStream
(
ms
,
CompressionMode
.
Compress
,
true
))
{
{
zip
.
Write
(
bytes
,
0
,
bytes
.
Length
);
zip
.
Write
(
bytes
,
0
,
bytes
.
Length
);
}
}
...
@@ -26,13 +22,12 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -26,13 +22,12 @@ namespace Titanium.Web.Proxy.Helpers
}
}
}
}
[
S
ystem
.
Diagnostics
.
CodeAnalysis
.
S
uppressMessage
(
"Microsoft.Usage"
,
"CA2202:Do not dispose objects multiple times"
)]
[
SuppressMessage
(
"Microsoft.Usage"
,
"CA2202:Do not dispose objects multiple times"
)]
public
static
byte
[]
CompressDeflate
(
byte
[]
bytes
)
public
static
byte
[]
CompressDeflate
(
byte
[]
bytes
)
{
{
using
(
var
ms
=
new
MemoryStream
())
using
(
MemoryStream
ms
=
new
MemoryStream
())
{
{
using
(
Ionic
.
Zlib
.
DeflateStream
zip
=
new
Ionic
.
Zlib
.
DeflateStream
(
ms
,
Ionic
.
Zlib
.
CompressionMode
.
Compress
,
true
))
using
(
var
zip
=
new
DeflateStream
(
ms
,
CompressionMode
.
Compress
,
true
))
{
{
zip
.
Write
(
bytes
,
0
,
bytes
.
Length
);
zip
.
Write
(
bytes
,
0
,
bytes
.
Length
);
}
}
...
@@ -41,32 +36,31 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -41,32 +36,31 @@ namespace Titanium.Web.Proxy.Helpers
}
}
}
}
[
S
ystem
.
Diagnostics
.
CodeAnalysis
.
S
uppressMessage
(
"Microsoft.Usage"
,
"CA2202:Do not dispose objects multiple times"
)]
[
SuppressMessage
(
"Microsoft.Usage"
,
"CA2202:Do not dispose objects multiple times"
)]
public
static
byte
[]
CompressGzip
(
byte
[]
bytes
)
public
static
byte
[]
CompressGzip
(
byte
[]
bytes
)
{
{
using
(
var
ms
=
new
MemoryStream
())
using
(
MemoryStream
ms
=
new
MemoryStream
())
{
{
using
(
Ionic
.
Zlib
.
GZipStream
zip
=
new
Ionic
.
Zlib
.
GZipStream
(
ms
,
Ionic
.
Zlib
.
CompressionMode
.
Compress
,
true
))
using
(
var
zip
=
new
GZipStream
(
ms
,
CompressionMode
.
Compress
,
true
))
{
{
zip
.
Write
(
bytes
,
0
,
bytes
.
Length
);
zip
.
Write
(
bytes
,
0
,
bytes
.
Length
);
}
}
return
ms
.
ToArray
();
return
ms
.
ToArray
();
}
}
}
}
public
static
byte
[]
DecompressGzip
(
Stream
input
)
public
static
byte
[]
DecompressGzip
(
Stream
input
)
{
{
using
(
var
decompressor
=
new
System
.
IO
.
Compression
.
GZipStream
(
input
,
System
.
IO
.
Compression
.
CompressionMode
.
Decompress
))
using
(
var
decompressor
=
new
System
.
IO
.
Compression
.
GZipStream
(
input
,
System
.
IO
.
Compression
.
CompressionMode
.
Decompress
))
{
{
var
buffer
=
new
byte
[
BufferSize
];
int
read
=
0
;
using
(
var
output
=
new
MemoryStream
())
var
buffer
=
new
byte
[
BUFFER_SIZE
];
using
(
MemoryStream
output
=
new
MemoryStream
())
{
{
int
read
;
while
((
read
=
decompressor
.
Read
(
buffer
,
0
,
buffer
.
Length
))
>
0
)
while
((
read
=
decompressor
.
Read
(
buffer
,
0
,
buffer
.
Length
))
>
0
)
{
{
output
.
Write
(
buffer
,
0
,
read
);
output
.
Write
(
buffer
,
0
,
read
);
...
@@ -78,13 +72,13 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -78,13 +72,13 @@ namespace Titanium.Web.Proxy.Helpers
public
static
byte
[]
DecompressDeflate
(
Stream
input
)
public
static
byte
[]
DecompressDeflate
(
Stream
input
)
{
{
using
(
Ionic
.
Zlib
.
DeflateStream
decompressor
=
new
Ionic
.
Zlib
.
DeflateStream
(
input
,
Ionic
.
Zlib
.
CompressionMode
.
Decompress
))
using
(
var
decompressor
=
new
DeflateStream
(
input
,
CompressionMode
.
Decompress
))
{
{
int
read
=
0
;
var
buffer
=
new
byte
[
BufferSize
];
var
buffer
=
new
byte
[
BUFFER_SIZE
];
using
(
MemoryStream
output
=
new
MemoryStream
())
using
(
var
output
=
new
MemoryStream
())
{
{
int
read
;
while
((
read
=
decompressor
.
Read
(
buffer
,
0
,
buffer
.
Length
))
>
0
)
while
((
read
=
decompressor
.
Read
(
buffer
,
0
,
buffer
.
Length
))
>
0
)
{
{
output
.
Write
(
buffer
,
0
,
read
);
output
.
Write
(
buffer
,
0
,
read
);
...
@@ -93,15 +87,16 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -93,15 +87,16 @@ namespace Titanium.Web.Proxy.Helpers
}
}
}
}
}
}
public
static
byte
[]
DecompressZlib
(
Stream
input
)
public
static
byte
[]
DecompressZlib
(
Stream
input
)
{
{
using
(
Ionic
.
Zlib
.
ZlibStream
decompressor
=
new
Ionic
.
Zlib
.
ZlibStream
(
input
,
Ionic
.
Zlib
.
CompressionMode
.
Decompress
))
using
(
var
decompressor
=
new
ZlibStream
(
input
,
CompressionMode
.
Decompress
))
{
{
int
read
=
0
;
var
buffer
=
new
byte
[
BufferSize
];
var
buffer
=
new
byte
[
BUFFER_SIZE
];
using
(
MemoryStream
output
=
new
MemoryStream
())
using
(
var
output
=
new
MemoryStream
())
{
{
int
read
;
while
((
read
=
decompressor
.
Read
(
buffer
,
0
,
buffer
.
Length
))
>
0
)
while
((
read
=
decompressor
.
Read
(
buffer
,
0
,
buffer
.
Length
))
>
0
)
{
{
output
.
Write
(
buffer
,
0
,
read
);
output
.
Write
(
buffer
,
0
,
read
);
...
@@ -111,4 +106,4 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -111,4 +106,4 @@ namespace Titanium.Web.Proxy.Helpers
}
}
}
}
}
}
}
}
\ No newline at end of file
Titanium.Web.Proxy/Helpers/CustomBinaryReader.cs
View file @
990b7412
using
System
;
using
System
;
using
System.Collections.Generic
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Text
;
using
System.IO
;
using
System.IO
;
using
System.
Diagnostics
;
using
System.
Text
;
namespace
Titanium.Web.Proxy.Helpers
namespace
Titanium.Web.Proxy.Helpers
{
{
internal
class
CustomBinaryReader
:
BinaryReader
internal
class
CustomBinaryReader
:
BinaryReader
{
{
internal
CustomBinaryReader
(
Stream
stream
,
Encoding
encoding
)
internal
CustomBinaryReader
(
Stream
stream
,
Encoding
encoding
)
:
base
(
stream
,
encoding
)
:
base
(
stream
,
encoding
)
{
{
}
}
internal
string
ReadLine
()
internal
string
ReadLine
()
{
{
char
[]
buf
=
new
char
[
1
];
var
buf
=
new
char
[
1
];
StringBuilde
r
readBuffer
=
new
StringBuilder
();
va
r
readBuffer
=
new
StringBuilder
();
try
try
{
{
var
charsRead
=
0
;
var
lastChar
=
new
char
();
char
lastChar
=
new
char
();
while
((
charsRead
=
base
.
Read
(
buf
,
0
,
1
))
>
0
)
while
((
Read
(
buf
,
0
,
1
))
>
0
)
{
{
if
(
lastChar
==
'\r'
&&
buf
[
0
]
==
'\n'
)
if
(
lastChar
==
'\r'
&&
buf
[
0
]
==
'\n'
)
{
{
return
readBuffer
.
Remove
(
readBuffer
.
Length
-
1
,
1
).
ToString
();
return
readBuffer
.
Remove
(
readBuffer
.
Length
-
1
,
1
).
ToString
();
}
}
else
if
(
buf
[
0
]
==
'\0'
)
if
(
buf
[
0
]
==
'\0'
)
{
{
return
readBuffer
.
ToString
();
return
readBuffer
.
ToString
();
}
}
readBuffer
.
Append
(
buf
[
0
]);
else
readBuffer
.
Append
(
buf
[
0
]);
lastChar
=
buf
[
0
];
lastChar
=
buf
[
0
];
}
}
return
readBuffer
.
ToString
();
return
readBuffer
.
ToString
();
}
}
catch
(
IOException
)
catch
(
IOException
)
{
{
return
readBuffer
.
ToString
();
return
readBuffer
.
ToString
();
}
}
catch
(
Exception
)
{
throw
;
}
}
}
internal
List
<
string
>
ReadAllLines
()
internal
List
<
string
>
ReadAllLines
()
{
{
string
tmpLine
=
null
;
string
tmpLine
;
List
<
string
>
requestLines
=
new
List
<
string
>();
var
requestLines
=
new
List
<
string
>();
while
(!
S
tring
.
IsNullOrEmpty
(
tmpLine
=
ReadLine
()))
while
(!
s
tring
.
IsNullOrEmpty
(
tmpLine
=
ReadLine
()))
{
{
requestLines
.
Add
(
tmpLine
);
requestLines
.
Add
(
tmpLine
);
}
}
return
requestLines
;
return
requestLines
;
}
}
}
}
}
}
\ No newline at end of file
Titanium.Web.Proxy/Helpers/Firefox.cs
View file @
990b7412
using
System
;
using
System
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Text
;
using
System.IO
;
using
System.IO
;
namespace
Titanium.Web.Proxy.Helpers
namespace
Titanium.Web.Proxy.Helpers
...
@@ -12,21 +9,23 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -12,21 +9,23 @@ namespace Titanium.Web.Proxy.Helpers
{
{
try
try
{
{
DirectoryInfo
[]
myProfileDirectory
=
new
DirectoryInfo
(
Environment
.
GetFolderPath
(
Environment
.
SpecialFolder
.
ApplicationData
)
+
"\\Mozilla\\Firefox\\Profiles\\"
).
GetDirectories
(
"*.default"
);
var
myProfileDirectory
=
string
myFFPrefFile
=
myProfileDirectory
[
0
].
FullName
+
"\\prefs.js"
;
new
DirectoryInfo
(
Environment
.
GetFolderPath
(
Environment
.
SpecialFolder
.
ApplicationData
)
+
if
(
File
.
Exists
(
myFFPrefFile
))
"\\Mozilla\\Firefox\\Profiles\\"
).
GetDirectories
(
"*.default"
);
var
myFfPrefFile
=
myProfileDirectory
[
0
].
FullName
+
"\\prefs.js"
;
if
(
File
.
Exists
(
myFfPrefFile
))
{
{
// We have a pref file so let''s make sure it has the proxy setting
// We have a pref file so let''s make sure it has the proxy setting
StreamReader
myReader
=
new
StreamReader
(
myFF
PrefFile
);
var
myReader
=
new
StreamReader
(
myFf
PrefFile
);
string
myPrefContents
=
myReader
.
ReadToEnd
();
var
myPrefContents
=
myReader
.
ReadToEnd
();
myReader
.
Close
();
myReader
.
Close
();
if
(
myPrefContents
.
Contains
(
"user_pref(\"network.proxy.type\", 0);"
))
if
(
myPrefContents
.
Contains
(
"user_pref(\"network.proxy.type\", 0);"
))
{
{
// Add the proxy enable line and write it back to the file
// Add the proxy enable line and write it back to the file
myPrefContents
=
myPrefContents
.
Replace
(
"user_pref(\"network.proxy.type\", 0);"
,
""
);
myPrefContents
=
myPrefContents
.
Replace
(
"user_pref(\"network.proxy.type\", 0);"
,
""
);
File
.
Delete
(
myF
F
PrefFile
);
File
.
Delete
(
myF
f
PrefFile
);
File
.
WriteAllText
(
myF
F
PrefFile
,
myPrefContents
);
File
.
WriteAllText
(
myF
f
PrefFile
,
myPrefContents
);
}
}
}
}
}
}
...
@@ -35,25 +34,28 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -35,25 +34,28 @@ namespace Titanium.Web.Proxy.Helpers
// Only exception should be a read/write error because the user opened up FireFox so they can be ignored.
// Only exception should be a read/write error because the user opened up FireFox so they can be ignored.
}
}
}
}
public
static
void
RemoveFirefox
()
public
static
void
RemoveFirefox
()
{
{
try
try
{
{
DirectoryInfo
[]
myProfileDirectory
=
new
DirectoryInfo
(
Environment
.
GetFolderPath
(
Environment
.
SpecialFolder
.
ApplicationData
)
+
"\\Mozilla\\Firefox\\Profiles\\"
).
GetDirectories
(
"*.default"
);
var
myProfileDirectory
=
string
myFFPrefFile
=
myProfileDirectory
[
0
].
FullName
+
"\\prefs.js"
;
new
DirectoryInfo
(
Environment
.
GetFolderPath
(
Environment
.
SpecialFolder
.
ApplicationData
)
+
if
(
File
.
Exists
(
myFFPrefFile
))
"\\Mozilla\\Firefox\\Profiles\\"
).
GetDirectories
(
"*.default"
);
var
myFfPrefFile
=
myProfileDirectory
[
0
].
FullName
+
"\\prefs.js"
;
if
(
File
.
Exists
(
myFfPrefFile
))
{
{
// We have a pref file so let''s make sure it has the proxy setting
// We have a pref file so let''s make sure it has the proxy setting
StreamReader
myReader
=
new
StreamReader
(
myFF
PrefFile
);
var
myReader
=
new
StreamReader
(
myFf
PrefFile
);
string
myPrefContents
=
myReader
.
ReadToEnd
();
var
myPrefContents
=
myReader
.
ReadToEnd
();
myReader
.
Close
();
myReader
.
Close
();
if
(!
myPrefContents
.
Contains
(
"user_pref(\"network.proxy.type\", 0);"
))
if
(!
myPrefContents
.
Contains
(
"user_pref(\"network.proxy.type\", 0);"
))
{
{
// Add the proxy enable line and write it back to the file
// Add the proxy enable line and write it back to the file
myPrefContents
=
myPrefContents
+
"\n\r"
+
"user_pref(\"network.proxy.type\", 0);"
;
myPrefContents
=
myPrefContents
+
"\n\r"
+
"user_pref(\"network.proxy.type\", 0);"
;
File
.
Delete
(
myF
F
PrefFile
);
File
.
Delete
(
myF
f
PrefFile
);
File
.
WriteAllText
(
myF
F
PrefFile
,
myPrefContents
);
File
.
WriteAllText
(
myF
f
PrefFile
,
myPrefContents
);
}
}
}
}
}
}
...
@@ -63,4 +65,4 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -63,4 +65,4 @@ namespace Titanium.Web.Proxy.Helpers
}
}
}
}
}
}
}
}
\ No newline at end of file
Titanium.Web.Proxy/Helpers/NetFramework.cs
View file @
990b7412
using
System
;
using
System
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Net.Configuration
;
using
System.Net.Configuration
;
using
System.Reflection
;
using
System.Reflection
;
using
System.Text
;
namespace
Titanium.Web.Proxy.Helpers
namespace
Titanium.Web.Proxy.Helpers
{
{
...
@@ -11,25 +8,24 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -11,25 +8,24 @@ namespace Titanium.Web.Proxy.Helpers
{
{
//Fix bug in .Net 4.0 HttpWebRequest (don't use this for 4.5 and above)
//Fix bug in .Net 4.0 HttpWebRequest (don't use this for 4.5 and above)
//http://stackoverflow.com/questions/856885/httpwebrequest-to-url-with-dot-at-the-end
//http://stackoverflow.com/questions/856885/httpwebrequest-to-url-with-dot-at-the-end
public
static
void
U
RL
PeriodFix
()
public
static
void
U
rl
PeriodFix
()
{
{
MethodInfo
getSyntax
=
typeof
(
UriParser
).
GetMethod
(
"GetSyntax"
,
System
.
Reflection
.
BindingFlags
.
Static
|
System
.
Reflection
.
BindingFlags
.
NonPublic
);
var
getSyntax
=
typeof
(
UriParser
).
GetMethod
(
"GetSyntax"
,
BindingFlags
.
Static
|
BindingFlags
.
NonPublic
);
FieldInfo
flagsField
=
typeof
(
UriParser
).
GetField
(
"m_Flags"
,
System
.
Reflection
.
BindingFlags
.
Instance
|
System
.
Reflection
.
BindingFlags
.
NonPublic
);
var
flagsField
=
typeof
(
UriParser
).
GetField
(
"m_Flags"
,
BindingFlags
.
Instance
|
BindingFlags
.
NonPublic
);
if
(
getSyntax
!=
null
&&
flagsField
!=
null
)
if
(
getSyntax
!=
null
&&
flagsField
!=
null
)
{
{
foreach
(
string
scheme
in
new
[]
{
"http"
,
"https"
})
foreach
(
var
scheme
in
new
[]
{
"http"
,
"https"
})
{
{
UriParser
parser
=
(
UriParser
)
getSyntax
.
Invoke
(
null
,
new
object
[]
{
scheme
});
var
parser
=
(
UriParser
)
getSyntax
.
Invoke
(
null
,
new
object
[]
{
scheme
});
if
(
parser
!=
null
)
if
(
parser
!=
null
)
{
{
int
flagsValue
=
(
int
)
flagsField
.
GetValue
(
parser
);
var
flagsValue
=
(
int
)
flagsField
.
GetValue
(
parser
);
if
((
flagsValue
&
0x1000000
)
!=
0
)
if
((
flagsValue
&
0x1000000
)
!=
0
)
flagsField
.
SetValue
(
parser
,
flagsValue
&
~
0x1000000
);
flagsField
.
SetValue
(
parser
,
flagsValue
&
~
0x1000000
);
}
}
}
}
}
}
}
}
// Enable/disable useUnsafeHeaderParsing.
// Enable/disable useUnsafeHeaderParsing.
...
@@ -37,31 +33,32 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -37,31 +33,32 @@ namespace Titanium.Web.Proxy.Helpers
public
static
bool
ToggleAllowUnsafeHeaderParsing
(
bool
enable
)
public
static
bool
ToggleAllowUnsafeHeaderParsing
(
bool
enable
)
{
{
//Get the assembly that contains the internal class
//Get the assembly that contains the internal class
Assembly
assembly
=
Assembly
.
GetAssembly
(
typeof
(
SettingsSection
));
var
assembly
=
Assembly
.
GetAssembly
(
typeof
(
SettingsSection
));
if
(
assembly
!=
null
)
if
(
assembly
!=
null
)
{
{
//Use the assembly in order to get the internal type for the internal class
//Use the assembly in order to get the internal type for the internal class
Type
settingsSectionType
=
assembly
.
GetType
(
"System.Net.Configuration.SettingsSectionInternal"
);
var
settingsSectionType
=
assembly
.
GetType
(
"System.Net.Configuration.SettingsSectionInternal"
);
if
(
settingsSectionType
!=
null
)
if
(
settingsSectionType
!=
null
)
{
{
//Use the internal static property to get an instance of the internal settings class.
//Use the internal static property to get an instance of the internal settings class.
//If the static instance isn't created already invoking the property will create it for us.
//If the static instance isn't created already invoking the property will create it for us.
object
anInstance
=
settingsSectionType
.
InvokeMember
(
"Section"
,
var
anInstance
=
settingsSectionType
.
InvokeMember
(
"Section"
,
BindingFlags
.
Static
|
BindingFlags
.
GetProperty
|
BindingFlags
.
NonPublic
,
null
,
null
,
new
object
[]
{
});
BindingFlags
.
Static
|
BindingFlags
.
GetProperty
|
BindingFlags
.
NonPublic
,
null
,
null
,
new
object
[]
{});
if
(
anInstance
!=
null
)
if
(
anInstance
!=
null
)
{
{
//Locate the private bool field that tells the framework if unsafe header parsing is allowed
//Locate the private bool field that tells the framework if unsafe header parsing is allowed
FieldInfo
aUseUnsafeHeaderParsing
=
settingsSectionType
.
GetField
(
"useUnsafeHeaderParsing"
,
BindingFlags
.
NonPublic
|
BindingFlags
.
Instance
);
var
aUseUnsafeHeaderParsing
=
settingsSectionType
.
GetField
(
"useUnsafeHeaderParsing"
,
BindingFlags
.
NonPublic
|
BindingFlags
.
Instance
);
if
(
aUseUnsafeHeaderParsing
!=
null
)
if
(
aUseUnsafeHeaderParsing
!=
null
)
{
{
aUseUnsafeHeaderParsing
.
SetValue
(
anInstance
,
enable
);
aUseUnsafeHeaderParsing
.
SetValue
(
anInstance
,
enable
);
return
true
;
return
true
;
}
}
}
}
}
}
}
}
return
false
;
return
false
;
}
}
}
}
}
}
\ No newline at end of file
Titanium.Web.Proxy/Helpers/SystemProxy.cs
View file @
990b7412
using
System
;
using
System
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Text
;
using
Microsoft.Win32
;
using
System.Runtime.InteropServices
;
using
System.Runtime.InteropServices
;
using
Microsoft.Win32
;
namespace
Titanium.Web.Proxy.Helpers
namespace
Titanium.Web.Proxy.Helpers
{
{
internal
static
class
NativeMethods
internal
static
class
NativeMethods
{
{
[
DllImport
(
"wininet.dll"
)]
[
DllImport
(
"wininet.dll"
)]
internal
static
extern
bool
InternetSetOption
(
IntPtr
hInternet
,
int
dwOption
,
IntPtr
lpBuffer
,
int
dwBufferLength
);
internal
static
extern
bool
InternetSetOption
(
IntPtr
hInternet
,
int
dwOption
,
IntPtr
lpBuffer
,
int
dwBufferLength
);
}
}
public
static
class
SystemProxyHelper
public
static
class
SystemProxyHelper
{
{
public
const
int
InternetOptionSettingsChanged
=
39
;
public
const
int
InternetOptionRefresh
=
37
;
private
static
object
_prevProxyServer
;
private
static
object
_prevProxyEnable
;
public
const
int
INTERNET_OPTION_SETTINGS_CHANGED
=
39
;
public
static
void
EnableProxyHttp
(
string
hostname
,
int
port
)
public
const
int
INTERNET_OPTION_REFRESH
=
37
;
static
bool
settingsReturn
,
refreshReturn
;
static
object
prevProxyServer
;
static
object
prevProxyEnable
;
public
static
void
EnableProxyHTTP
(
string
hostname
,
int
port
)
{
{
RegistryKey
reg
=
Registry
.
CurrentUser
.
OpenSubKey
(
"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"
,
true
);
var
reg
=
Registry
.
CurrentUser
.
OpenSubKey
(
prevProxyEnable
=
reg
.
GetValue
(
"ProxyEnable"
);
"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"
,
true
);
prevProxyServer
=
reg
.
GetValue
(
"ProxyServer"
);
if
(
reg
!=
null
)
reg
.
SetValue
(
"ProxyEnable"
,
1
);
{
reg
.
SetValue
(
"ProxyServer"
,
"http="
+
hostname
+
":"
+
port
+
";"
);
_prevProxyEnable
=
reg
.
GetValue
(
"ProxyEnable"
);
refresh
();
_prevProxyServer
=
reg
.
GetValue
(
"ProxyServer"
);
reg
.
SetValue
(
"ProxyEnable"
,
1
);
reg
.
SetValue
(
"ProxyServer"
,
"http="
+
hostname
+
":"
+
port
+
";"
);
}
Refresh
();
}
}
public
static
void
EnableProxyHTTPS
(
string
hostname
,
int
port
)
public
static
void
EnableProxyHttps
(
string
hostname
,
int
port
)
{
{
RegistryKey
reg
=
Registry
.
CurrentUser
.
OpenSubKey
(
"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"
,
true
);
var
reg
=
Registry
.
CurrentUser
.
OpenSubKey
(
reg
.
SetValue
(
"ProxyEnable"
,
1
);
"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"
,
true
);
reg
.
SetValue
(
"ProxyServer"
,
"http="
+
hostname
+
":"
+
port
+
";https="
+
hostname
+
":"
+
port
);
if
(
reg
!=
null
)
refresh
();
{
reg
.
SetValue
(
"ProxyEnable"
,
1
);
reg
.
SetValue
(
"ProxyServer"
,
"http="
+
hostname
+
":"
+
port
+
";https="
+
hostname
+
":"
+
port
);
}
Refresh
();
}
}
public
static
void
DisableAllProxy
()
public
static
void
DisableAllProxy
()
{
{
RegistryKey
reg
=
Registry
.
CurrentUser
.
OpenSubKey
(
"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"
,
true
);
var
reg
=
Registry
.
CurrentUser
.
OpenSubKey
(
reg
.
SetValue
(
"ProxyEnable"
,
prevProxyEnable
);
"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"
,
true
);
if
(
prevProxyServer
!=
null
)
if
(
reg
!=
null
)
reg
.
SetValue
(
"ProxyServer"
,
prevProxyServer
);
{
refresh
();
reg
.
SetValue
(
"ProxyEnable"
,
_prevProxyEnable
);
if
(
_prevProxyServer
!=
null
)
reg
.
SetValue
(
"ProxyServer"
,
_prevProxyServer
);
}
Refresh
();
}
}
private
static
void
refresh
()
private
static
void
Refresh
()
{
{
settingsReturn
=
NativeMethods
.
InternetSetOption
(
IntPtr
.
Zero
,
INTERNET_OPTION_SETTINGS_CHANGED
,
IntPtr
.
Zero
,
0
);
NativeMethods
.
InternetSetOption
(
IntPtr
.
Zero
,
InternetOptionSettingsChanged
,
IntPtr
.
Zero
,
0
);
refreshReturn
=
NativeMethods
.
InternetSetOption
(
IntPtr
.
Zero
,
INTERNET_OPTION_REFRESH
,
IntPtr
.
Zero
,
0
);
NativeMethods
.
InternetSetOption
(
IntPtr
.
Zero
,
InternetOptionRefresh
,
IntPtr
.
Zero
,
0
);
}
}
}
}
}
}
\ No newline at end of file
Titanium.Web.Proxy/Helpers/Tcp.cs
View file @
990b7412
using
System
;
using
System
;
using
System.Collections.Generic
;
using
System.Collections.Generic
;
using
System.IO
;
using
System.Linq
;
using
System.Linq
;
using
System.Text
;
using
System.Net.Security
;
using
System.Net.Security
;
using
System.IO
;
using
System.Net
;
using
System.Threading.Tasks
;
using
System.Net.Sockets
;
using
System.Net.Sockets
;
using
System.Text
;
using
System.Threading.Tasks
;
using
Titanium.Web.Proxy.Extensions
;
using
Titanium.Web.Proxy.Extensions
;
using
Titanium.Web.Proxy.Models
;
using
Titanium.Web.Proxy.Models
;
...
@@ -15,9 +14,9 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -15,9 +14,9 @@ namespace Titanium.Web.Proxy.Helpers
public
class
TcpHelper
public
class
TcpHelper
{
{
private
static
readonly
int
BUFFER_SIZE
=
8192
;
private
static
readonly
int
BUFFER_SIZE
=
8192
;
private
static
readonly
String
[]
colonSpaceSplit
=
new
string
[]
{
": "
};
public
static
void
SendRaw
(
Stream
clientStream
,
string
httpCmd
,
List
<
HttpHeader
>
requestHeaders
,
string
hostName
,
public
static
void
SendRaw
(
Stream
clientStream
,
string
httpCmd
,
List
<
HttpHeader
>
requestHeaders
,
string
hostName
,
int
tunnelPort
,
bool
isHttps
)
int
tunnelPort
,
bool
isHttps
)
{
{
StringBuilder
sb
=
null
;
StringBuilder
sb
=
null
;
if
(
httpCmd
!=
null
||
requestHeaders
!=
null
)
if
(
httpCmd
!=
null
||
requestHeaders
!=
null
)
...
@@ -29,23 +28,22 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -29,23 +28,22 @@ namespace Titanium.Web.Proxy.Helpers
sb
.
Append
(
Environment
.
NewLine
);
sb
.
Append
(
Environment
.
NewLine
);
}
}
if
(
requestHeaders
!=
null
)
if
(
requestHeaders
!=
null
)
for
(
int
i
=
0
;
i
<
requestHeaders
.
Count
;
i
++)
foreach
(
var
header
in
requestHeaders
.
Select
(
t
=>
t
.
ToString
()))
{
{
var
header
=
requestHeaders
[
i
].
ToString
();
sb
.
Append
(
header
);
sb
.
Append
(
header
);
sb
.
Append
(
Environment
.
NewLine
);
sb
.
Append
(
Environment
.
NewLine
);
}
}
sb
.
Append
(
Environment
.
NewLine
);
sb
.
Append
(
Environment
.
NewLine
);
}
}
System
.
Net
.
Sockets
.
TcpClient
tunnelClient
=
null
;
TcpClient
tunnelClient
=
null
;
Stream
tunnelStream
=
null
;
Stream
tunnelStream
=
null
;
try
try
{
{
tunnelClient
=
new
System
.
Net
.
Sockets
.
TcpClient
(
hostName
,
tunnelPort
);
tunnelClient
=
new
TcpClient
(
hostName
,
tunnelPort
);
tunnelStream
=
tunnelClient
.
GetStream
()
as
Stream
;
tunnelStream
=
tunnelClient
.
GetStream
();
if
(
isHttps
)
if
(
isHttps
)
{
{
...
@@ -60,12 +58,15 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -60,12 +58,15 @@ namespace Titanium.Web.Proxy.Helpers
{
{
if
(
sslStream
!=
null
)
if
(
sslStream
!=
null
)
sslStream
.
Dispose
();
sslStream
.
Dispose
();
throw
;
}
}
}
}
var
sendRelay
=
Task
.
Factory
.
StartNew
(()
=>
{
var
sendRelay
=
Task
.
Factory
.
StartNew
(()
=>
if
(
sb
!=
null
)
{
if
(
sb
!=
null
)
clientStream
.
CopyToAsync
(
sb
.
ToString
(),
tunnelStream
,
BUFFER_SIZE
);
clientStream
.
CopyToAsync
(
sb
.
ToString
(),
tunnelStream
,
BUFFER_SIZE
);
else
else
clientStream
.
CopyToAsync
(
tunnelStream
,
BUFFER_SIZE
);
clientStream
.
CopyToAsync
(
tunnelStream
,
BUFFER_SIZE
);
...
@@ -89,7 +90,5 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -89,7 +90,5 @@ namespace Titanium.Web.Proxy.Helpers
throw
;
throw
;
}
}
}
}
}
}
}
}
\ No newline at end of file
Titanium.Web.Proxy/Models/HttpHeader.cs
View file @
990b7412
using
System
;
using
System
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Text
;
namespace
Titanium.Web.Proxy.Models
namespace
Titanium.Web.Proxy.Models
{
{
public
class
HttpHeader
public
class
HttpHeader
{
{
public
string
Name
{
get
;
set
;
}
public
string
Value
{
get
;
set
;
}
public
HttpHeader
(
string
name
,
string
value
)
public
HttpHeader
(
string
name
,
string
value
)
{
{
if
(
string
.
IsNullOrEmpty
(
name
))
throw
new
Exception
(
"Name cannot be null"
);
if
(
string
.
IsNullOrEmpty
(
name
))
throw
new
Exception
(
"Name cannot be null"
);
this
.
Name
=
name
.
Trim
();
Name
=
name
.
Trim
();
this
.
Value
=
value
.
Trim
();
Value
=
value
.
Trim
();
}
}
public
string
Name
{
get
;
set
;
}
public
string
Value
{
get
;
set
;
}
public
override
string
ToString
()
public
override
string
ToString
()
{
{
return
String
.
Format
(
"{0}: {1}"
,
this
.
Name
,
this
.
Value
);
return
string
.
Format
(
"{0}: {1}"
,
Name
,
Value
);
}
}
}
}
}
}
\ No newline at end of file
Titanium.Web.Proxy/Properties/AssemblyInfo.cs
View file @
990b7412
using
System.Reflection
;
using
System.Reflection
;
using
System.Runtime.CompilerServices
;
using
System.Runtime.InteropServices
;
using
System.Runtime.InteropServices
;
// General Information about an assembly is controlled through the following
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
// associated with an assembly.
[assembly: AssemblyTitle("Titanium.Web.Proxy.Properties")]
[assembly: AssemblyTitle("Titanium.Web.Proxy.Properties")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyConfiguration("")]
...
@@ -17,9 +17,11 @@ using System.Runtime.InteropServices;
...
@@ -17,9 +17,11 @@ using System.Runtime.InteropServices;
// Setting ComVisible to false makes the types in this assembly not visible
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("5036e0b7-a0d0-4070-8eb0-72c129dee9b3")]
[assembly: Guid("5036e0b7-a0d0-4070-8eb0-72c129dee9b3")]
// Version information for an assembly consists of the following four values:
// Version information for an assembly consists of the following four values:
...
@@ -29,5 +31,6 @@ using System.Runtime.InteropServices;
...
@@ -29,5 +31,6 @@ using System.Runtime.InteropServices;
// Build Number
// Build Number
// Revision
// Revision
//
//
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
\ No newline at end of file
Titanium.Web.Proxy/ProxyServer.cs
View file @
990b7412
using
System
;
using
System
;
using
System.Collections.Generic
;
using
System.Collections.Generic
;
using
System.Text.RegularExpressions
;
using
System.Threading
;
using
System.IO
;
using
System.Net
;
using
System.Net
;
using
System.Net.Sockets
;
using
System.Net.Security
;
using
System.Net.Security
;
using
System.
Security.Authentication
;
using
System.
Net.Sockets
;
using
System.Security.Cryptography.X509Certificates
;
using
System.Security.Cryptography.X509Certificates
;
using
System.Diagnostics
;
using
System.Text
;
using
System.Text.RegularExpressions
;
using
System.Threading.Tasks
;
using
System.Threading.Tasks
;
using
Titanium.Web.Proxy.EventArguments
;
using
Titanium.Web.Proxy.EventArguments
;
using
Titanium.Web.Proxy.Helpers
;
using
Titanium.Web.Proxy.Helpers
;
using
System.Text
;
namespace
Titanium.Web.Proxy
namespace
Titanium.Web.Proxy
{
{
/// <summary>
/// <summary>
/// Proxy Server Main class
///
Proxy Server Main class
/// </summary>
/// </summary>
public
partial
class
ProxyServer
public
partial
class
ProxyServer
{
{
private
static
readonly
int
BUFFER_SIZE
=
8192
;
private
static
readonly
int
BUFFER_SIZE
=
8192
;
private
static
readonly
char
[]
semiSplit
=
new
char
[]
{
';'
};
private
static
readonly
char
[]
SemiSplit
=
{
';'
};
private
static
readonly
String
[]
colonSpaceSplit
=
new
string
[]
{
": "
};
private
static
readonly
string
[]
ColonSpaceSplit
=
{
": "
};
private
static
readonly
char
[]
spaceSplit
=
new
char
[]
{
' '
};
private
static
readonly
char
[]
SpaceSplit
=
{
' '
};
private
static
readonly
Regex
c
ookieSplitRegEx
=
new
Regex
(
@",(?! )"
);
private
static
readonly
Regex
C
ookieSplitRegEx
=
new
Regex
(
@",(?! )"
);
private
static
readonly
byte
[]
chunkTrail
=
Encoding
.
ASCII
.
GetBytes
(
Environment
.
NewLine
);
private
static
readonly
byte
[]
ChunkTrail
=
Encoding
.
ASCII
.
GetBytes
(
Environment
.
NewLine
);
private
static
readonly
byte
[]
ChunkEnd
=
Encoding
.
ASCII
.
GetBytes
(
0.
ToString
(
"x2"
)
+
Environment
.
NewLine
+
Environment
.
NewLine
);
private
static
object
certificateAccessLock
=
new
object
();
private
static
readonly
byte
[]
ChunkEnd
=
Encoding
.
ASCII
.
GetBytes
(
0.
ToString
(
"x2"
)
+
Environment
.
NewLine
+
Environment
.
NewLine
);
private
static
TcpListener
listener
;
private
static
TcpListener
_listener
;
private
static
CertificateManager
CertManager
{
get
;
set
;
}
public
static
List
<
string
>
ExcludedHttpsHostNameRegex
=
new
List
<
string
>();
public
static
List
<
string
>
ExcludedHttpsHostNameRegex
=
new
List
<
string
>();
public
static
event
EventHandler
<
SessionEventArgs
>
BeforeRequest
;
public
static
event
EventHandler
<
SessionEventArgs
>
BeforeResponse
;
public
static
string
RootCertificateName
{
get
;
set
;
}
public
static
bool
EnableSSL
{
get
;
set
;
}
public
static
bool
SetAsSystemProxy
{
get
;
set
;
}
public
static
Int32
ListeningPort
{
get
;
set
;
}
public
static
IPAddress
ListeningIpAddress
{
get
;
set
;
}
static
ProxyServer
()
static
ProxyServer
()
{
{
CertManager
=
new
CertificateManager
(
"Titanium"
,
CertManager
=
new
CertificateManager
(
"Titanium"
,
...
@@ -61,74 +45,89 @@ namespace Titanium.Web.Proxy
...
@@ -61,74 +45,89 @@ namespace Titanium.Web.Proxy
Initialize
();
Initialize
();
}
}
private
static
CertificateManager
CertManager
{
get
;
set
;
}
public
static
string
RootCertificateName
{
get
;
set
;
}
public
static
bool
EnableSsl
{
get
;
set
;
}
public
static
bool
SetAsSystemProxy
{
get
;
set
;
}
public
static
int
ListeningPort
{
get
;
set
;
}
public
static
IPAddress
ListeningIpAddress
{
get
;
set
;
}
public
static
event
EventHandler
<
SessionEventArgs
>
BeforeRequest
;
public
static
event
EventHandler
<
SessionEventArgs
>
BeforeResponse
;
public
static
void
Initialize
()
public
static
void
Initialize
()
{
{
ServicePointManager
.
Expect100Continue
=
false
;
System
.
Net
.
ServicePointManager
.
Expect100Continue
=
false
;
WebRequest
.
DefaultWebProxy
=
null
;
System
.
Net
.
WebRequest
.
DefaultWebProxy
=
null
;
ServicePointManager
.
DefaultConnectionLimit
=
10
;
System
.
Net
.
ServicePointManager
.
DefaultConnectionLimit
=
10
;
ServicePointManager
.
DnsRefreshTimeout
=
3
*
60
*
1000
;
//3 minutes
ServicePointManager
.
DnsRefreshTimeout
=
3
*
60
*
1000
;
//3 minutes
ServicePointManager
.
MaxServicePointIdleTime
=
3
*
60
*
1000
;
ServicePointManager
.
MaxServicePointIdleTime
=
3
*
60
*
1000
;
//HttpWebRequest certificate validation callback
//HttpWebRequest certificate validation callback
ServicePointManager
.
ServerCertificateValidationCallback
=
delegate
(
object
s
,
X509Certificate
certificate
,
X509Chain
chain
,
SslPolicyErrors
sslPolicyErrors
)
ServicePointManager
.
ServerCertificateValidationCallback
=
{
delegate
(
object
s
,
X509Certificate
certificate
,
X509Chain
chain
,
SslPolicyErrors
sslPolicyErrors
)
if
(
sslPolicyErrors
==
SslPolicyErrors
.
None
)
return
true
;
{
else
if
(
sslPolicyErrors
==
SslPolicyErrors
.
None
)
return
true
;
return
false
;
return
false
;
};
};
//Fix a bug in .NET 4.0
//Fix a bug in .NET 4.0
NetFrameworkHelper
.
U
RL
PeriodFix
();
NetFrameworkHelper
.
U
rl
PeriodFix
();
//useUnsafeHeaderParsing
//useUnsafeHeaderParsing
NetFrameworkHelper
.
ToggleAllowUnsafeHeaderParsing
(
true
);
NetFrameworkHelper
.
ToggleAllowUnsafeHeaderParsing
(
true
);
}
}
public
static
bool
Start
()
public
static
bool
Start
()
{
{
listener
=
new
TcpListener
(
ListeningIpAddress
,
ListeningPort
);
_
listener
=
new
TcpListener
(
ListeningIpAddress
,
ListeningPort
);
listener
.
Start
();
_
listener
.
Start
();
ListeningPort
=
((
IPEndPoint
)
listener
.
LocalEndpoint
).
Port
;
ListeningPort
=
((
IPEndPoint
)
_
listener
.
LocalEndpoint
).
Port
;
// accept clients asynchronously
// accept clients asynchronously
listener
.
BeginAcceptTcpClient
(
OnAcceptConnection
,
listener
);
_listener
.
BeginAcceptTcpClient
(
OnAcceptConnection
,
_
listener
);
if
(
SetAsSystemProxy
)
if
(
SetAsSystemProxy
)
{
{
SystemProxyHelper
.
EnableProxyHTTP
(
ListeningIpAddress
==
IPAddress
.
Any
?
"127.0.0.1"
:
ListeningIpAddress
.
ToString
(),
ListeningPort
);
SystemProxyHelper
.
EnableProxyHttp
(
Equals
(
ListeningIpAddress
,
IPAddress
.
Any
)
?
"127.0.0.1"
:
ListeningIpAddress
.
ToString
(),
ListeningPort
);
FireFoxHelper
.
AddFirefox
();
FireFoxHelper
.
AddFirefox
();
if
(
EnableS
SL
)
if
(
EnableS
sl
)
{
{
RootCertificateName
=
RootCertificateName
==
null
?
"Titanium_Proxy_Test_Root"
:
RootCertificateName
;
RootCertificateName
=
RootCertificateName
??
"Titanium_Proxy_Test_Root"
;
bool
certTrusted
=
CertManager
.
CreateTrustedRootCertificate
();
var
certTrusted
=
CertManager
.
CreateTrustedRootCertificate
();
//If certificate was trusted by the machine
//If certificate was trusted by the machine
if
(
certTrusted
)
if
(
certTrusted
)
{
{
SystemProxyHelper
.
EnableProxyHTTPS
(
ListeningIpAddress
==
IPAddress
.
Any
?
"127.0.0.1"
:
ListeningIpAddress
.
ToString
(),
ListeningPort
);
SystemProxyHelper
.
EnableProxyHttps
(
Equals
(
ListeningIpAddress
,
IPAddress
.
Any
)
?
"127.0.0.1"
:
ListeningIpAddress
.
ToString
(),
ListeningPort
);
}
}
}
}
}
}
return
true
;
return
true
;
}
}
private
static
void
OnAcceptConnection
(
IAsyncResult
asyn
)
private
static
void
OnAcceptConnection
(
IAsyncResult
asyn
)
{
{
try
try
{
{
// Get the listener that handles the client request.
// Get the listener that handles the client request.
listener
.
BeginAcceptTcpClient
(
OnAcceptConnection
,
listener
);
_listener
.
BeginAcceptTcpClient
(
OnAcceptConnection
,
_
listener
);
TcpClient
client
=
listener
.
EndAcceptTcpClient
(
asyn
);
var
client
=
_
listener
.
EndAcceptTcpClient
(
asyn
);
Task
.
Factory
.
StartNew
(()
=>
HandleClient
(
client
));
Task
.
Factory
.
StartNew
(()
=>
HandleClient
(
client
));
}
}
catch
{
}
catch
{
// ignored
}
}
}
...
@@ -140,9 +139,8 @@ namespace Titanium.Web.Proxy
...
@@ -140,9 +139,8 @@ namespace Titanium.Web.Proxy
FireFoxHelper
.
RemoveFirefox
();
FireFoxHelper
.
RemoveFirefox
();
}
}
listener
.
Stop
();
_
listener
.
Stop
();
CertManager
.
Dispose
();
CertManager
.
Dispose
();
}
}
}
}
}
}
\ No newline at end of file
Titanium.Web.Proxy/RequestHandler.cs
View file @
990b7412
using
System
;
using
System
;
using
System.Collections.Generic
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Globalization
;
using
System.Text
;
using
System.Threading
;
using
System.IO
;
using
System.IO
;
using
System.Linq
;
using
System.Net
;
using
System.Net
;
using
System.Net.Security
;
using
System.Net.Security
;
using
System.Security.Authentication
;
using
System.Net.Sockets
;
using
System.Net.Sockets
;
using
System.Diagnostics
;
using
System.Security.Authentication
;
using
System.Security.Cryptography.X509Certificates
;
using
System.Text
;
using
System.Reflection
;
using
System.Text.RegularExpressions
;
using
Titanium.Web.Proxy.Helpers
;
using
Titanium.Web.Proxy.EventArguments
;
using
System.Threading.Tasks
;
using
System.Threading.Tasks
;
using
Titanium.Web.Proxy.EventArguments
;
using
Titanium.Web.Proxy.Extensions
;
using
Titanium.Web.Proxy.Extensions
;
using
System.Text.RegularExpression
s
;
using
Titanium.Web.Proxy.Helper
s
;
using
Titanium.Web.Proxy.Models
;
using
Titanium.Web.Proxy.Models
;
namespace
Titanium.Web.Proxy
namespace
Titanium.Web.Proxy
...
@@ -25,22 +22,22 @@ namespace Titanium.Web.Proxy
...
@@ -25,22 +22,22 @@ namespace Titanium.Web.Proxy
private
static
void
HandleClient
(
TcpClient
client
)
private
static
void
HandleClient
(
TcpClient
client
)
{
{
Stream
clientStream
=
client
.
GetStream
();
Stream
clientStream
=
client
.
GetStream
();
CustomBinaryReade
r
clientStreamReader
=
new
CustomBinaryReader
(
clientStream
,
Encoding
.
ASCII
);
va
r
clientStreamReader
=
new
CustomBinaryReader
(
clientStream
,
Encoding
.
ASCII
);
StreamWrite
r
clientStreamWriter
=
new
StreamWriter
(
clientStream
);
va
r
clientStreamWriter
=
new
StreamWriter
(
clientStream
);
Uri
httpRemoteUri
;
Uri
httpRemoteUri
;
try
try
{
{
//read the first line HTTP command
//read the first line HTTP command
String
httpCmd
=
clientStreamReader
.
ReadLine
();
var
httpCmd
=
clientStreamReader
.
ReadLine
();
if
(
S
tring
.
IsNullOrEmpty
(
httpCmd
))
if
(
s
tring
.
IsNullOrEmpty
(
httpCmd
))
{
{
throw
new
EndOfStreamException
();
throw
new
EndOfStreamException
();
}
}
//break up the line into three components (method, remote URL & Http Version)
//break up the line into three components (method, remote URL & Http Version)
String
[]
httpCmdSplit
=
httpCmd
.
Split
(
s
paceSplit
,
3
);
var
httpCmdSplit
=
httpCmd
.
Split
(
S
paceSplit
,
3
);
var
httpVerb
=
httpCmdSplit
[
0
];
var
httpVerb
=
httpCmdSplit
[
0
];
...
@@ -56,13 +53,12 @@ namespace Titanium.Web.Proxy
...
@@ -56,13 +53,12 @@ namespace Titanium.Web.Proxy
//Client wants to create a secure tcp tunnel (its a HTTPS request)
//Client wants to create a secure tcp tunnel (its a HTTPS request)
if
(
httpVerb
.
ToUpper
()
==
"CONNECT"
&&
!
excluded
&&
httpRemoteUri
.
Port
==
443
)
if
(
httpVerb
.
ToUpper
()
==
"CONNECT"
&&
!
excluded
&&
httpRemoteUri
.
Port
==
443
)
{
{
httpRemoteUri
=
new
Uri
(
"https://"
+
httpCmdSplit
[
1
]);
httpRemoteUri
=
new
Uri
(
"https://"
+
httpCmdSplit
[
1
]);
clientStreamReader
.
ReadAllLines
();
clientStreamReader
.
ReadAllLines
();
WriteConnectResponse
(
clientStreamWriter
,
httpVersion
);
WriteConnectResponse
(
clientStreamWriter
,
httpVersion
);
var
certificate
=
ProxyServer
.
CertManager
.
CreateCertificate
(
httpRemoteUri
.
Host
);
var
certificate
=
CertManager
.
CreateCertificate
(
httpRemoteUri
.
Host
);
SslStream
sslStream
=
null
;
SslStream
sslStream
=
null
;
...
@@ -70,7 +66,8 @@ namespace Titanium.Web.Proxy
...
@@ -70,7 +66,8 @@ namespace Titanium.Web.Proxy
{
{
sslStream
=
new
SslStream
(
clientStream
,
true
);
sslStream
=
new
SslStream
(
clientStream
,
true
);
//Successfully managed to authenticate the client using the fake certificate
//Successfully managed to authenticate the client using the fake certificate
sslStream
.
AuthenticateAsServer
(
certificate
,
false
,
SslProtocols
.
Tls
|
SslProtocols
.
Ssl3
|
SslProtocols
.
Ssl2
,
false
);
sslStream
.
AuthenticateAsServer
(
certificate
,
false
,
SslProtocols
.
Tls
|
SslProtocols
.
Ssl3
|
SslProtocols
.
Ssl2
,
false
);
clientStreamReader
=
new
CustomBinaryReader
(
sslStream
,
Encoding
.
ASCII
);
clientStreamReader
=
new
CustomBinaryReader
(
sslStream
,
Encoding
.
ASCII
);
clientStreamWriter
=
new
StreamWriter
(
sslStream
);
clientStreamWriter
=
new
StreamWriter
(
sslStream
);
...
@@ -87,52 +84,52 @@ namespace Titanium.Web.Proxy
...
@@ -87,52 +84,52 @@ namespace Titanium.Web.Proxy
}
}
httpCmd
=
clientStreamReader
.
ReadLine
();
httpCmd
=
clientStreamReader
.
ReadLine
();
}
}
else
if
(
httpVerb
.
ToUpper
()
==
"CONNECT"
)
else
if
(
httpVerb
.
ToUpper
()
==
"CONNECT"
)
{
{
clientStreamReader
.
ReadAllLines
();
clientStreamReader
.
ReadAllLines
();
WriteConnectResponse
(
clientStreamWriter
,
httpVersion
);
WriteConnectResponse
(
clientStreamWriter
,
httpVersion
);
TcpHelper
.
SendRaw
(
clientStreamReader
.
BaseStream
,
null
,
null
,
httpRemoteUri
.
Host
,
httpRemoteUri
.
Port
,
false
);
TcpHelper
.
SendRaw
(
clientStreamReader
.
BaseStream
,
null
,
null
,
httpRemoteUri
.
Host
,
httpRemoteUri
.
Port
,
false
);
Dispose
(
client
,
clientStream
,
clientStreamReader
,
clientStreamWriter
,
null
);
Dispose
(
client
,
clientStream
,
clientStreamReader
,
clientStreamWriter
,
null
);
return
;
return
;
}
}
//Now create the request
//Now create the request
Task
.
Factory
.
StartNew
(()
=>
HandleHttpSessionRequest
(
client
,
httpCmd
,
clientStream
,
clientStreamReader
,
clientStreamWriter
,
httpRemoteUri
.
Scheme
==
Uri
.
UriSchemeHttps
?
httpRemoteUri
.
OriginalString
:
null
));
Task
.
Factory
.
StartNew
(
()
=>
HandleHttpSessionRequest
(
client
,
httpCmd
,
clientStream
,
clientStreamReader
,
clientStreamWriter
,
httpRemoteUri
.
Scheme
==
Uri
.
UriSchemeHttps
?
httpRemoteUri
.
OriginalString
:
null
));
}
}
catch
catch
{
{
Dispose
(
client
,
clientStream
,
clientStreamReader
,
clientStreamWriter
,
null
);
Dispose
(
client
,
clientStream
,
clientStreamReader
,
clientStreamWriter
,
null
);
}
}
}
}
private
static
void
HandleHttpSessionRequest
(
TcpClient
client
,
string
httpCmd
,
Stream
clientStream
,
CustomBinaryReader
clientStreamReader
,
StreamWriter
clientStreamWriter
,
string
secureTunnelHostName
)
private
static
void
HandleHttpSessionRequest
(
TcpClient
client
,
string
httpCmd
,
Stream
clientStream
,
CustomBinaryReader
clientStreamReader
,
StreamWriter
clientStreamWriter
,
string
secureTunnelHostName
)
{
{
if
(
string
.
IsNullOrEmpty
(
httpCmd
))
if
(
String
.
IsNullOrEmpty
(
httpCmd
))
{
{
Dispose
(
client
,
clientStream
,
clientStreamReader
,
clientStreamWriter
,
null
);
Dispose
(
client
,
clientStream
,
clientStreamReader
,
clientStreamWriter
,
null
);
return
;
return
;
}
}
var
args
=
new
SessionEventArgs
(
BUFFER_SIZE
);
var
args
=
new
SessionEventArgs
(
BUFFER_SIZE
);
args
.
c
lient
=
client
;
args
.
C
lient
=
client
;
try
try
{
{
//break up the line into three components (method, remote URL & Http Version)
//break up the line into three components (method, remote URL & Http Version)
String
[]
httpCmdSplit
=
httpCmd
.
Split
(
s
paceSplit
,
3
);
var
httpCmdSplit
=
httpCmd
.
Split
(
S
paceSplit
,
3
);
var
httpMethod
=
httpCmdSplit
[
0
];
var
httpMethod
=
httpCmdSplit
[
0
];
var
httpRemoteUri
=
new
Uri
(
secureTunnelHostName
==
null
?
httpCmdSplit
[
1
]
:
(
secureTunnelHostName
+
httpCmdSplit
[
1
]));
var
httpRemoteUri
=
new
Uri
(
secureTunnelHostName
==
null
?
httpCmdSplit
[
1
]
:
(
secureTunnelHostName
+
httpCmdSplit
[
1
]));
var
httpVersion
=
httpCmdSplit
[
2
];
var
httpVersion
=
httpCmdSplit
[
2
];
Version
version
;
Version
version
;
...
@@ -147,29 +144,29 @@ namespace Titanium.Web.Proxy
...
@@ -147,29 +144,29 @@ namespace Titanium.Web.Proxy
if
(
httpRemoteUri
.
Scheme
==
Uri
.
UriSchemeHttps
)
if
(
httpRemoteUri
.
Scheme
==
Uri
.
UriSchemeHttps
)
{
{
args
.
i
sHttps
=
true
;
args
.
I
sHttps
=
true
;
}
}
args
.
r
equestHeaders
=
new
List
<
HttpHeader
>();
args
.
R
equestHeaders
=
new
List
<
HttpHeader
>();
string
tmpLine
=
null
;
string
tmpLine
;
while
(!
S
tring
.
IsNullOrEmpty
(
tmpLine
=
clientStreamReader
.
ReadLine
()))
while
(!
s
tring
.
IsNullOrEmpty
(
tmpLine
=
clientStreamReader
.
ReadLine
()))
{
{
String
[]
header
=
tmpLine
.
Split
(
c
olonSpaceSplit
,
2
,
StringSplitOptions
.
None
);
var
header
=
tmpLine
.
Split
(
C
olonSpaceSplit
,
2
,
StringSplitOptions
.
None
);
args
.
r
equestHeaders
.
Add
(
new
HttpHeader
(
header
[
0
],
header
[
1
]));
args
.
R
equestHeaders
.
Add
(
new
HttpHeader
(
header
[
0
],
header
[
1
]));
}
}
for
(
int
i
=
0
;
i
<
args
.
r
equestHeaders
.
Count
;
i
++)
for
(
var
i
=
0
;
i
<
args
.
R
equestHeaders
.
Count
;
i
++)
{
{
var
rawHeader
=
args
.
r
equestHeaders
[
i
];
var
rawHeader
=
args
.
R
equestHeaders
[
i
];
//if request was upgrade to web-socket protocol then relay the request without proxying
//if request was upgrade to web-socket protocol then relay the request without proxying
if
((
rawHeader
.
Name
.
ToLower
()
==
"upgrade"
)
&&
(
rawHeader
.
Value
.
ToLower
()
==
"websocket"
))
if
((
rawHeader
.
Name
.
ToLower
()
==
"upgrade"
)
&&
(
rawHeader
.
Value
.
ToLower
()
==
"websocket"
))
{
{
TcpHelper
.
SendRaw
(
clientStreamReader
.
BaseStream
,
httpCmd
,
args
.
RequestHeaders
,
TcpHelper
.
SendRaw
(
clientStreamReader
.
BaseStream
,
httpCmd
,
args
.
requestHeaders
,
httpRemoteUri
.
Host
,
httpRemoteUri
.
Port
,
httpRemoteUri
.
Scheme
==
Uri
.
UriSchemeHttps
);
httpRemoteUri
.
Host
,
httpRemoteUri
.
Port
,
httpRemoteUri
.
Scheme
==
Uri
.
UriSchemeHttps
);
Dispose
(
client
,
clientStream
,
clientStreamReader
,
clientStreamWriter
,
args
);
Dispose
(
client
,
clientStream
,
clientStreamReader
,
clientStreamWriter
,
args
);
return
;
return
;
}
}
...
@@ -177,52 +174,51 @@ namespace Titanium.Web.Proxy
...
@@ -177,52 +174,51 @@ namespace Titanium.Web.Proxy
//construct the web request that we are going to issue on behalf of the client.
//construct the web request that we are going to issue on behalf of the client.
args
.
proxyRequest
=
(
HttpWebRequest
)
Http
WebRequest
.
Create
(
httpRemoteUri
);
args
.
ProxyRequest
=
(
HttpWebRequest
)
WebRequest
.
Create
(
httpRemoteUri
);
args
.
p
roxyRequest
.
Proxy
=
null
;
args
.
P
roxyRequest
.
Proxy
=
null
;
args
.
p
roxyRequest
.
UseDefaultCredentials
=
true
;
args
.
P
roxyRequest
.
UseDefaultCredentials
=
true
;
args
.
p
roxyRequest
.
Method
=
httpMethod
;
args
.
P
roxyRequest
.
Method
=
httpMethod
;
args
.
p
roxyRequest
.
ProtocolVersion
=
version
;
args
.
P
roxyRequest
.
ProtocolVersion
=
version
;
args
.
c
lientStream
=
clientStream
;
args
.
C
lientStream
=
clientStream
;
args
.
c
lientStreamReader
=
clientStreamReader
;
args
.
C
lientStreamReader
=
clientStreamReader
;
args
.
c
lientStreamWriter
=
clientStreamWriter
;
args
.
C
lientStreamWriter
=
clientStreamWriter
;
args
.
p
roxyRequest
.
AllowAutoRedirect
=
false
;
args
.
P
roxyRequest
.
AllowAutoRedirect
=
false
;
args
.
p
roxyRequest
.
AutomaticDecompression
=
DecompressionMethods
.
None
;
args
.
P
roxyRequest
.
AutomaticDecompression
=
DecompressionMethods
.
None
;
args
.
requestHostname
=
args
.
p
roxyRequest
.
RequestUri
.
Host
;
args
.
RequestHostname
=
args
.
P
roxyRequest
.
RequestUri
.
Host
;
args
.
requestURL
=
args
.
p
roxyRequest
.
RequestUri
.
OriginalString
;
args
.
RequestUrl
=
args
.
P
roxyRequest
.
RequestUri
.
OriginalString
;
args
.
clientPort
=
((
IPEndPoint
)
client
.
Client
.
RemoteEndPoint
).
Port
;
args
.
ClientPort
=
((
IPEndPoint
)
client
.
Client
.
RemoteEndPoint
).
Port
;
args
.
clientIpAddress
=
((
IPEndPoint
)
client
.
Client
.
RemoteEndPoint
).
Address
;
args
.
ClientIpAddress
=
((
IPEndPoint
)
client
.
Client
.
RemoteEndPoint
).
Address
;
args
.
r
equestHttpVersion
=
version
;
args
.
R
equestHttpVersion
=
version
;
args
.
requestIsAlive
=
args
.
p
roxyRequest
.
KeepAlive
;
args
.
RequestIsAlive
=
args
.
P
roxyRequest
.
KeepAlive
;
args
.
proxyRequest
.
ConnectionGroupName
=
args
.
r
equestHostname
;
args
.
ProxyRequest
.
ConnectionGroupName
=
args
.
R
equestHostname
;
args
.
p
roxyRequest
.
AllowWriteStreamBuffering
=
true
;
args
.
P
roxyRequest
.
AllowWriteStreamBuffering
=
true
;
//If requested interception
//If requested interception
if
(
BeforeRequest
!=
null
)
if
(
BeforeRequest
!=
null
)
{
{
args
.
requestEncoding
=
args
.
p
roxyRequest
.
GetEncoding
();
args
.
RequestEncoding
=
args
.
P
roxyRequest
.
GetEncoding
();
BeforeRequest
(
null
,
args
);
BeforeRequest
(
null
,
args
);
}
}
args
.
RequestLocked
=
true
;
args
.
RequestLocked
=
true
;
if
(
args
.
c
ancelRequest
)
if
(
args
.
C
ancelRequest
)
{
{
Dispose
(
client
,
clientStream
,
clientStreamReader
,
clientStreamWriter
,
args
);
Dispose
(
client
,
clientStream
,
clientStreamReader
,
clientStreamWriter
,
args
);
return
;
return
;
}
}
SetRequestHeaders
(
args
.
requestHeaders
,
args
.
p
roxyRequest
);
SetRequestHeaders
(
args
.
RequestHeaders
,
args
.
P
roxyRequest
);
//If request was modified by user
//If request was modified by user
if
(
args
.
r
equestBodyRead
)
if
(
args
.
R
equestBodyRead
)
{
{
args
.
proxyRequest
.
ContentLength
=
args
.
requestBody
.
Length
;
args
.
ProxyRequest
.
ContentLength
=
args
.
RequestBody
.
Length
;
Stream
newStream
=
args
.
proxyRequest
.
GetRequestStream
();
var
newStream
=
args
.
ProxyRequest
.
GetRequestStream
();
newStream
.
Write
(
args
.
requestBody
,
0
,
args
.
requestBody
.
Length
);
newStream
.
Write
(
args
.
RequestBody
,
0
,
args
.
RequestBody
.
Length
);
args
.
proxyRequest
.
BeginGetResponse
(
new
AsyncCallback
(
HandleHttpSessionResponse
),
args
);
args
.
ProxyRequest
.
BeginGetResponse
(
HandleHttpSessionResponse
,
args
);
}
}
else
else
{
{
...
@@ -232,38 +228,36 @@ namespace Titanium.Web.Proxy
...
@@ -232,38 +228,36 @@ namespace Titanium.Web.Proxy
SendClientRequestBody
(
args
);
SendClientRequestBody
(
args
);
}
}
//Http request body sent, now wait asynchronously for response
//Http request body sent, now wait asynchronously for response
args
.
proxyRequest
.
BeginGetResponse
(
new
AsyncCallback
(
HandleHttpSessionResponse
),
args
);
args
.
ProxyRequest
.
BeginGetResponse
(
HandleHttpSessionResponse
,
args
);
}
}
//Now read the next request (if keep-Alive is enabled, otherwise exit this thread)
//Now read the next request (if keep-Alive is enabled, otherwise exit this thread)
//If client is pipeling the request, this will be immediately hit before response for previous request was made
//If client is pipeling the request, this will be immediately hit before response for previous request was made
httpCmd
=
clientStreamReader
.
ReadLine
();
httpCmd
=
clientStreamReader
.
ReadLine
();
//Http request body sent, now wait for next request
//Http request body sent, now wait for next request
Task
.
Factory
.
StartNew
(()
=>
HandleHttpSessionRequest
(
args
.
client
,
httpCmd
,
args
.
clientStream
,
args
.
clientStreamReader
,
args
.
clientStreamWriter
,
secureTunnelHostName
));
Task
.
Factory
.
StartNew
(
()
=>
HandleHttpSessionRequest
(
args
.
Client
,
httpCmd
,
args
.
ClientStream
,
args
.
ClientStreamReader
,
args
.
ClientStreamWriter
,
secureTunnelHostName
));
}
}
catch
catch
{
{
Dispose
(
client
,
clientStream
,
clientStreamReader
,
clientStreamWriter
,
args
);
Dispose
(
client
,
clientStream
,
clientStreamReader
,
clientStreamWriter
,
args
);
}
}
}
}
private
static
void
WriteConnectResponse
(
StreamWriter
clientStreamWriter
,
string
httpVersion
)
private
static
void
WriteConnectResponse
(
StreamWriter
clientStreamWriter
,
string
httpVersion
)
{
{
clientStreamWriter
.
WriteLine
(
httpVersion
+
" 200 Connection established"
);
clientStreamWriter
.
WriteLine
(
httpVersion
+
" 200 Connection established"
);
clientStreamWriter
.
WriteLine
(
String
.
Format
(
"Timestamp: {0}"
,
DateTime
.
Now
.
ToString
())
);
clientStreamWriter
.
WriteLine
(
"Timestamp: {0}"
,
DateTime
.
Now
);
clientStreamWriter
.
WriteLine
(
String
.
Format
(
"connection:close"
)
);
clientStreamWriter
.
WriteLine
(
"connection:close"
);
clientStreamWriter
.
WriteLine
();
clientStreamWriter
.
WriteLine
();
clientStreamWriter
.
Flush
();
clientStreamWriter
.
Flush
();
}
}
private
static
void
SetRequestHeaders
(
List
<
HttpHeader
>
requestHeaders
,
HttpWebRequest
webRequest
)
private
static
void
SetRequestHeaders
(
List
<
HttpHeader
>
requestHeaders
,
HttpWebRequest
webRequest
)
{
{
for
(
var
i
=
0
;
i
<
requestHeaders
.
Count
;
i
++)
for
(
int
i
=
0
;
i
<
requestHeaders
.
Count
;
i
++)
{
{
switch
(
requestHeaders
[
i
].
Name
.
ToLower
())
switch
(
requestHeaders
[
i
].
Name
.
ToLower
())
{
{
...
@@ -300,7 +294,7 @@ namespace Titanium.Web.Proxy
...
@@ -300,7 +294,7 @@ namespace Titanium.Web.Proxy
webRequest
.
Host
=
requestHeaders
[
i
].
Value
;
webRequest
.
Host
=
requestHeaders
[
i
].
Value
;
break
;
break
;
case
"if-modified-since"
:
case
"if-modified-since"
:
String
[]
sb
=
requestHeaders
[
i
].
Value
.
Trim
().
Split
(
s
emiSplit
);
var
sb
=
requestHeaders
[
i
].
Value
.
Trim
().
Split
(
S
emiSplit
);
DateTime
d
;
DateTime
d
;
if
(
DateTime
.
TryParse
(
sb
[
0
],
out
d
))
if
(
DateTime
.
TryParse
(
sb
[
0
],
out
d
))
webRequest
.
IfModifiedSince
=
d
;
webRequest
.
IfModifiedSince
=
d
;
...
@@ -311,7 +305,12 @@ namespace Titanium.Web.Proxy
...
@@ -311,7 +305,12 @@ namespace Titanium.Web.Proxy
break
;
break
;
case
"range"
:
case
"range"
:
var
startEnd
=
requestHeaders
[
i
].
Value
.
Replace
(
Environment
.
NewLine
,
""
).
Remove
(
0
,
6
).
Split
(
'-'
);
var
startEnd
=
requestHeaders
[
i
].
Value
.
Replace
(
Environment
.
NewLine
,
""
).
Remove
(
0
,
6
).
Split
(
'-'
);
if
(
startEnd
.
Length
>
1
)
{
if
(!
String
.
IsNullOrEmpty
(
startEnd
[
1
]))
webRequest
.
AddRange
(
int
.
Parse
(
startEnd
[
0
]),
int
.
Parse
(
startEnd
[
1
]));
else
webRequest
.
AddRange
(
int
.
Parse
(
startEnd
[
0
]));
}
if
(
startEnd
.
Length
>
1
)
{
if
(!
string
.
IsNullOrEmpty
(
startEnd
[
1
]))
webRequest
.
AddRange
(
int
.
Parse
(
startEnd
[
0
]),
int
.
Parse
(
startEnd
[
1
]));
else
webRequest
.
AddRange
(
int
.
Parse
(
startEnd
[
0
]));
}
else
else
webRequest
.
AddRange
(
int
.
Parse
(
startEnd
[
0
]));
webRequest
.
AddRange
(
int
.
Parse
(
startEnd
[
0
]));
break
;
break
;
...
@@ -340,109 +339,92 @@ namespace Titanium.Web.Proxy
...
@@ -340,109 +339,92 @@ namespace Titanium.Web.Proxy
break
;
break
;
}
}
}
}
}
}
//This is called when the request is PUT/POST to read the body
//This is called when the request is PUT/POST to read the body
private
static
void
SendClientRequestBody
(
SessionEventArgs
args
)
private
static
void
SendClientRequestBody
(
SessionEventArgs
args
)
{
{
// End the operation
// End the operation
Stream
postStream
=
args
.
p
roxyRequest
.
GetRequestStream
();
var
postStream
=
args
.
P
roxyRequest
.
GetRequestStream
();
if
(
args
.
p
roxyRequest
.
ContentLength
>
0
)
if
(
args
.
P
roxyRequest
.
ContentLength
>
0
)
{
{
args
.
p
roxyRequest
.
AllowWriteStreamBuffering
=
true
;
args
.
P
roxyRequest
.
AllowWriteStreamBuffering
=
true
;
try
try
{
{
var
totalbytesRead
=
0
;
int
totalbytesRead
=
0
;
int
bytesToRead
;
int
bytesToRead
;
if
(
args
.
p
roxyRequest
.
ContentLength
<
BUFFER_SIZE
)
if
(
args
.
P
roxyRequest
.
ContentLength
<
BUFFER_SIZE
)
{
{
bytesToRead
=
(
int
)
args
.
p
roxyRequest
.
ContentLength
;
bytesToRead
=
(
int
)
args
.
P
roxyRequest
.
ContentLength
;
}
}
else
else
bytesToRead
=
BUFFER_SIZE
;
bytesToRead
=
BUFFER_SIZE
;
while
(
totalbytesRead
<
(
int
)
args
.
p
roxyRequest
.
ContentLength
)
while
(
totalbytesRead
<
(
int
)
args
.
P
roxyRequest
.
ContentLength
)
{
{
var
buffer
=
args
.
c
lientStreamReader
.
ReadBytes
(
bytesToRead
);
var
buffer
=
args
.
C
lientStreamReader
.
ReadBytes
(
bytesToRead
);
totalbytesRead
+=
buffer
.
Length
;
totalbytesRead
+=
buffer
.
Length
;
int
RemainingBytes
=
(
int
)
args
.
p
roxyRequest
.
ContentLength
-
totalbytesRead
;
var
remainingBytes
=
(
int
)
args
.
P
roxyRequest
.
ContentLength
-
totalbytesRead
;
if
(
R
emainingBytes
<
bytesToRead
)
if
(
r
emainingBytes
<
bytesToRead
)
{
{
bytesToRead
=
R
emainingBytes
;
bytesToRead
=
r
emainingBytes
;
}
}
postStream
.
Write
(
buffer
,
0
,
buffer
.
Length
);
postStream
.
Write
(
buffer
,
0
,
buffer
.
Length
);
}
}
postStream
.
Close
();
postStream
.
Close
();
}
}
catch
catch
{
{
if
(
postStream
!=
null
)
postStream
.
Close
();
{
postStream
.
Dispose
();
postStream
.
Close
();
postStream
.
Dispose
();
}
throw
;
throw
;
}
}
}
}
//Need to revist, find any potential bugs
//Need to revist, find any potential bugs
else
if
(
args
.
p
roxyRequest
.
SendChunked
)
else
if
(
args
.
P
roxyRequest
.
SendChunked
)
{
{
args
.
p
roxyRequest
.
AllowWriteStreamBuffering
=
true
;
args
.
P
roxyRequest
.
AllowWriteStreamBuffering
=
true
;
try
try
{
{
while
(
true
)
while
(
true
)
{
{
var
chuchkHead
=
args
.
c
lientStreamReader
.
ReadLine
();
var
chuchkHead
=
args
.
C
lientStreamReader
.
ReadLine
();
var
chunkSize
=
int
.
Parse
(
chuchkHead
,
System
.
Globalization
.
NumberStyles
.
HexNumber
);
var
chunkSize
=
int
.
Parse
(
chuchkHead
,
NumberStyles
.
HexNumber
);
if
(
chunkSize
!=
0
)
if
(
chunkSize
!=
0
)
{
{
var
buffer
=
args
.
c
lientStreamReader
.
ReadBytes
(
chunkSize
);
var
buffer
=
args
.
C
lientStreamReader
.
ReadBytes
(
chunkSize
);
postStream
.
Write
(
buffer
,
0
,
buffer
.
Length
);
postStream
.
Write
(
buffer
,
0
,
buffer
.
Length
);
//chunk trail
var
chunkTrail
=
args
.
c
lientStreamReader
.
ReadLine
();
args
.
C
lientStreamReader
.
ReadLine
();
}
}
else
else
{
{
args
.
c
lientStreamReader
.
ReadLine
();
args
.
C
lientStreamReader
.
ReadLine
();
break
;
break
;
}
}
}
}
postStream
.
Close
();
postStream
.
Close
();
}
}
catch
catch
{
{
if
(
postStream
!=
null
)
postStream
.
Close
();
{
postStream
.
Dispose
();
postStream
.
Close
();
postStream
.
Dispose
();
}
throw
;
throw
;
}
}
}
}
}
}
}
}
}
}
\ No newline at end of file
Titanium.Web.Proxy/ResponseHandler.cs
View file @
990b7412
using
System
;
using
System
;
using
System.Collections.Generic
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Text
;
using
System.Net.Sockets
;
using
System.IO
;
using
System.IO
;
using
System.Linq
;
using
System.Net
;
using
System.Net
;
using
System.Net.Security
;
using
System.Net.Sockets
;
using
System.Threading
;
using
System.Text
;
using
System.Security.Authentication
;
using
System.Diagnostics
;
using
Titanium.Web.Proxy.EventArguments
;
using
Titanium.Web.Proxy.EventArguments
;
using
Titanium.Web.Proxy.Helpers
;
using
System.Threading.Tasks
;
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
;
namespace
Titanium.Web.Proxy
namespace
Titanium.Web.Proxy
...
@@ -22,94 +17,89 @@ namespace Titanium.Web.Proxy
...
@@ -22,94 +17,89 @@ namespace Titanium.Web.Proxy
//Called asynchronously when a request was successfully and we received the response
//Called asynchronously when a request was successfully and we received the response
private
static
void
HandleHttpSessionResponse
(
IAsyncResult
asynchronousResult
)
private
static
void
HandleHttpSessionResponse
(
IAsyncResult
asynchronousResult
)
{
{
SessionEventArgs
args
=
(
SessionEventArgs
)
asynchronousResult
.
AsyncState
;
var
args
=
(
SessionEventArgs
)
asynchronousResult
.
AsyncState
;
try
try
{
{
args
.
serverResponse
=
(
HttpWebResponse
)
args
.
p
roxyRequest
.
EndGetResponse
(
asynchronousResult
);
args
.
ServerResponse
=
(
HttpWebResponse
)
args
.
P
roxyRequest
.
EndGetResponse
(
asynchronousResult
);
}
}
catch
(
WebException
webEx
)
catch
(
WebException
webEx
)
{
{
//Things line 404, 500 etc
//Things line 404, 500 etc
args
.
s
erverResponse
=
webEx
.
Response
as
HttpWebResponse
;
args
.
S
erverResponse
=
webEx
.
Response
as
HttpWebResponse
;
}
}
try
try
{
{
if
(
args
.
s
erverResponse
!=
null
)
if
(
args
.
S
erverResponse
!=
null
)
{
{
args
.
responseHeaders
=
ReadResponseHeaders
(
args
.
s
erverResponse
);
args
.
ResponseHeaders
=
ReadResponseHeaders
(
args
.
S
erverResponse
);
args
.
responseStream
=
args
.
s
erverResponse
.
GetResponseStream
();
args
.
ResponseStream
=
args
.
S
erverResponse
.
GetResponseStream
();
if
(
BeforeResponse
!=
null
)
if
(
BeforeResponse
!=
null
)
{
{
args
.
responseEncoding
=
args
.
s
erverResponse
.
GetEncoding
();
args
.
ResponseEncoding
=
args
.
S
erverResponse
.
GetEncoding
();
BeforeResponse
(
null
,
args
);
BeforeResponse
(
null
,
args
);
}
}
args
.
ResponseLocked
=
true
;
args
.
ResponseLocked
=
true
;
if
(
args
.
r
esponseBodyRead
)
if
(
args
.
R
esponseBodyRead
)
{
{
bool
isChunked
=
args
.
serverResponse
.
GetResponseHeader
(
"transfer-encoding"
)
==
null
?
false
:
args
.
serverResponse
.
GetResponseHeader
(
"transfer-encoding"
).
ToLower
().
Contains
(
"chunked"
)
?
true
:
false
;
var
isChunked
=
args
.
ServerResponse
.
GetResponseHeader
(
"transfer-encoding"
).
ToLower
().
Contains
(
"chunked"
);
var
contentEncoding
=
args
.
serverResponse
.
ContentEncoding
;
var
contentEncoding
=
args
.
ServerResponse
.
ContentEncoding
;
if
(
contentEncoding
!=
null
)
switch
(
contentEncoding
.
ToLower
())
switch
(
contentEncoding
.
ToLower
())
{
{
case
"gzip"
:
case
"gzip"
:
args
.
ResponseBody
=
CompressionHelper
.
CompressGzip
(
args
.
ResponseBody
);
args
.
responseBody
=
CompressionHelper
.
CompressGzip
(
args
.
responseBody
);
break
;
break
;
case
"deflate"
:
case
"deflate"
:
args
.
ResponseBody
=
CompressionHelper
.
CompressDeflate
(
args
.
ResponseBody
);
args
.
responseBody
=
CompressionHelper
.
CompressDeflate
(
args
.
responseBody
);
break
;
break
;
case
"zlib"
:
case
"zlib"
:
args
.
ResponseBody
=
CompressionHelper
.
CompressZlib
(
args
.
ResponseBody
);
args
.
responseBody
=
CompressionHelper
.
CompressZlib
(
args
.
responseBody
);
break
;
break
;
}
default
:
break
;
WriteResponseStatus
(
args
.
ServerResponse
.
ProtocolVersion
,
args
.
ServerResponse
.
StatusCode
,
}
args
.
ServerResponse
.
StatusDescription
,
args
.
ClientStreamWriter
);
WriteResponseHeaders
(
args
.
ClientStreamWriter
,
args
.
ResponseHeaders
,
args
.
ResponseBody
.
Length
,
WriteResponseStatus
(
args
.
serverResponse
.
ProtocolVersion
,
args
.
serverResponse
.
StatusCode
,
args
.
serverResponse
.
StatusDescription
,
args
.
clientStreamWriter
);
isChunked
);
WriteResponseHeaders
(
args
.
clientStreamWriter
,
args
.
responseHeaders
,
args
.
responseBody
.
Length
,
isChunked
);
WriteResponseBody
(
args
.
ClientStream
,
args
.
ResponseBody
,
isChunked
);
WriteResponseBody
(
args
.
clientStream
,
args
.
responseBody
,
isChunked
);
}
}
else
else
{
{
bool
isChunked
=
args
.
serverResponse
.
GetResponseHeader
(
"transfer-encoding"
)
==
null
?
false
:
args
.
serverResponse
.
GetResponseHeader
(
"transfer-encoding"
).
ToLower
().
Contains
(
"chunked"
)
?
true
:
false
;
var
isChunked
=
args
.
ServerResponse
.
GetResponseHeader
(
"transfer-encoding"
).
ToLower
().
Contains
(
"chunked"
);
WriteResponseStatus
(
args
.
serverResponse
.
ProtocolVersion
,
args
.
serverResponse
.
StatusCode
,
args
.
serverResponse
.
StatusDescription
,
args
.
clientStreamWriter
);
WriteResponseHeaders
(
args
.
clientStreamWriter
,
args
.
responseHeaders
);
WriteResponseBody
(
args
.
responseStream
,
args
.
clientStream
,
isChunked
);
WriteResponseStatus
(
args
.
ServerResponse
.
ProtocolVersion
,
args
.
ServerResponse
.
StatusCode
,
args
.
ServerResponse
.
StatusDescription
,
args
.
ClientStreamWriter
);
WriteResponseHeaders
(
args
.
ClientStreamWriter
,
args
.
ResponseHeaders
);
WriteResponseBody
(
args
.
ResponseStream
,
args
.
ClientStream
,
isChunked
);
}
}
args
.
clientStream
.
Flush
();
args
.
ClientStream
.
Flush
();
}
}
}
}
catch
catch
{
{
Dispose
(
args
.
client
,
args
.
clientStream
,
args
.
clientStreamReader
,
args
.
c
lientStreamWriter
,
args
);
Dispose
(
args
.
Client
,
args
.
ClientStream
,
args
.
ClientStreamReader
,
args
.
C
lientStreamWriter
,
args
);
}
}
finally
finally
{
{
if
(
args
!=
null
)
args
.
Dispose
();
args
.
Dispose
();
}
}
}
}
private
static
List
<
HttpHeader
>
ReadResponseHeaders
(
HttpWebResponse
response
)
private
static
List
<
HttpHeader
>
ReadResponseHeaders
(
HttpWebResponse
response
)
{
{
var
returnHeaders
=
new
List
<
HttpHeader
>();
var
returnHeaders
=
new
List
<
HttpHeader
>();
S
tring
cookieHeaderName
=
null
;
s
tring
cookieHeaderName
=
null
;
S
tring
cookieHeaderValue
=
null
;
s
tring
cookieHeaderValue
=
null
;
foreach
(
S
tring
headerKey
in
response
.
Headers
.
Keys
)
foreach
(
s
tring
headerKey
in
response
.
Headers
.
Keys
)
{
{
if
(
headerKey
.
ToLower
()
==
"set-cookie"
)
if
(
headerKey
.
ToLower
()
==
"set-cookie"
)
{
{
...
@@ -120,21 +110,21 @@ namespace Titanium.Web.Proxy
...
@@ -120,21 +110,21 @@ namespace Titanium.Web.Proxy
returnHeaders
.
Add
(
new
HttpHeader
(
headerKey
,
response
.
Headers
[
headerKey
]));
returnHeaders
.
Add
(
new
HttpHeader
(
headerKey
,
response
.
Headers
[
headerKey
]));
}
}
if
(!
S
tring
.
IsNullOrWhiteSpace
(
cookieHeaderValue
))
if
(!
s
tring
.
IsNullOrWhiteSpace
(
cookieHeaderValue
))
{
{
response
.
Headers
.
Remove
(
cookieHeaderName
);
response
.
Headers
.
Remove
(
cookieHeaderName
);
String
[]
cookies
=
c
ookieSplitRegEx
.
Split
(
cookieHeaderValue
);
var
cookies
=
C
ookieSplitRegEx
.
Split
(
cookieHeaderValue
);
foreach
(
String
cookie
in
cookies
)
foreach
(
var
cookie
in
cookies
)
returnHeaders
.
Add
(
new
HttpHeader
(
"Set-Cookie"
,
cookie
));
returnHeaders
.
Add
(
new
HttpHeader
(
"Set-Cookie"
,
cookie
));
}
}
return
returnHeaders
;
return
returnHeaders
;
}
}
private
static
void
WriteResponseStatus
(
Version
version
,
HttpStatusCode
code
,
String
description
,
StreamWriter
responseWriter
)
private
static
void
WriteResponseStatus
(
Version
version
,
HttpStatusCode
code
,
string
description
,
StreamWriter
responseWriter
)
{
{
String
s
=
String
.
Format
(
"HTTP/{0}.{1} {2} {3}"
,
version
.
Major
,
version
.
Minor
,
(
Int32
)
code
,
description
);
var
s
=
string
.
Format
(
"HTTP/{0}.{1} {2} {3}"
,
version
.
Major
,
version
.
Minor
,
(
int
)
code
,
description
);
responseWriter
.
WriteLine
(
s
);
responseWriter
.
WriteLine
(
s
);
}
}
...
@@ -150,9 +140,10 @@ namespace Titanium.Web.Proxy
...
@@ -150,9 +140,10 @@ namespace Titanium.Web.Proxy
responseWriter
.
WriteLine
();
responseWriter
.
WriteLine
();
responseWriter
.
Flush
();
responseWriter
.
Flush
();
}
}
private
static
void
WriteResponseHeaders
(
StreamWriter
responseWriter
,
List
<
HttpHeader
>
headers
,
int
length
,
bool
isChunked
)
private
static
void
WriteResponseHeaders
(
StreamWriter
responseWriter
,
List
<
HttpHeader
>
headers
,
int
length
,
bool
isChunked
)
{
{
if
(!
isChunked
)
if
(!
isChunked
)
{
{
...
@@ -175,7 +166,6 @@ namespace Titanium.Web.Proxy
...
@@ -175,7 +166,6 @@ namespace Titanium.Web.Proxy
responseWriter
.
WriteLine
();
responseWriter
.
WriteLine
();
responseWriter
.
Flush
();
responseWriter
.
Flush
();
}
}
private
static
void
WriteResponseBody
(
Stream
clientStream
,
byte
[]
data
,
bool
isChunked
)
private
static
void
WriteResponseBody
(
Stream
clientStream
,
byte
[]
data
,
bool
isChunked
)
...
@@ -192,7 +182,7 @@ namespace Titanium.Web.Proxy
...
@@ -192,7 +182,7 @@ namespace Titanium.Web.Proxy
{
{
if
(!
isChunked
)
if
(!
isChunked
)
{
{
Byte
[]
buffer
=
new
B
yte
[
BUFFER_SIZE
];
var
buffer
=
new
b
yte
[
BUFFER_SIZE
];
int
bytesRead
;
int
bytesRead
;
while
((
bytesRead
=
inStream
.
Read
(
buffer
,
0
,
buffer
.
Length
))
>
0
)
while
((
bytesRead
=
inStream
.
Read
(
buffer
,
0
,
buffer
.
Length
))
>
0
)
...
@@ -203,11 +193,11 @@ namespace Titanium.Web.Proxy
...
@@ -203,11 +193,11 @@ namespace Titanium.Web.Proxy
else
else
WriteResponseBodyChunked
(
inStream
,
outStream
);
WriteResponseBodyChunked
(
inStream
,
outStream
);
}
}
//Send chunked response
//Send chunked response
private
static
void
WriteResponseBodyChunked
(
Stream
inStream
,
Stream
outStream
)
private
static
void
WriteResponseBodyChunked
(
Stream
inStream
,
Stream
outStream
)
{
{
var
buffer
=
new
byte
[
BUFFER_SIZE
];
Byte
[]
buffer
=
new
Byte
[
BUFFER_SIZE
];
int
bytesRead
;
int
bytesRead
;
while
((
bytesRead
=
inStream
.
Read
(
buffer
,
0
,
buffer
.
Length
))
>
0
)
while
((
bytesRead
=
inStream
.
Read
(
buffer
,
0
,
buffer
.
Length
))
>
0
)
...
@@ -215,31 +205,29 @@ namespace Titanium.Web.Proxy
...
@@ -215,31 +205,29 @@ namespace Titanium.Web.Proxy
var
chunkHead
=
Encoding
.
ASCII
.
GetBytes
(
bytesRead
.
ToString
(
"x2"
));
var
chunkHead
=
Encoding
.
ASCII
.
GetBytes
(
bytesRead
.
ToString
(
"x2"
));
outStream
.
Write
(
chunkHead
,
0
,
chunkHead
.
Length
);
outStream
.
Write
(
chunkHead
,
0
,
chunkHead
.
Length
);
outStream
.
Write
(
chunkTrail
,
0
,
c
hunkTrail
.
Length
);
outStream
.
Write
(
ChunkTrail
,
0
,
C
hunkTrail
.
Length
);
outStream
.
Write
(
buffer
,
0
,
bytesRead
);
outStream
.
Write
(
buffer
,
0
,
bytesRead
);
outStream
.
Write
(
chunkTrail
,
0
,
chunkTrail
.
Length
);
outStream
.
Write
(
ChunkTrail
,
0
,
ChunkTrail
.
Length
);
}
}
outStream
.
Write
(
ChunkEnd
,
0
,
ChunkEnd
.
Length
);
outStream
.
Write
(
ChunkEnd
,
0
,
ChunkEnd
.
Length
);
}
}
private
static
void
WriteResponseBodyChunked
(
byte
[]
data
,
Stream
outStream
)
private
static
void
WriteResponseBodyChunked
(
byte
[]
data
,
Stream
outStream
)
{
{
Byte
[]
buffer
=
new
Byte
[
BUFFER_SIZE
];
var
chunkHead
=
Encoding
.
ASCII
.
GetBytes
(
data
.
Length
.
ToString
(
"x2"
));
var
chunkHead
=
Encoding
.
ASCII
.
GetBytes
(
data
.
Length
.
ToString
(
"x2"
));
outStream
.
Write
(
chunkHead
,
0
,
chunkHead
.
Length
);
outStream
.
Write
(
chunkHead
,
0
,
chunkHead
.
Length
);
outStream
.
Write
(
chunkTrail
,
0
,
c
hunkTrail
.
Length
);
outStream
.
Write
(
ChunkTrail
,
0
,
C
hunkTrail
.
Length
);
outStream
.
Write
(
data
,
0
,
data
.
Length
);
outStream
.
Write
(
data
,
0
,
data
.
Length
);
outStream
.
Write
(
chunkTrail
,
0
,
c
hunkTrail
.
Length
);
outStream
.
Write
(
ChunkTrail
,
0
,
C
hunkTrail
.
Length
);
outStream
.
Write
(
ChunkEnd
,
0
,
ChunkEnd
.
Length
);
outStream
.
Write
(
ChunkEnd
,
0
,
ChunkEnd
.
Length
);
}
}
private
static
void
Dispose
(
TcpClient
client
,
Stream
clientStream
,
CustomBinaryReader
clientStreamReader
,
StreamWriter
clientStreamWriter
,
SessionEventArgs
args
)
private
static
void
Dispose
(
TcpClient
client
,
IDisposable
clientStream
,
IDisposable
clientStreamReader
,
IDisposable
clientStreamWriter
,
IDisposable
args
)
{
{
if
(
args
!=
null
)
if
(
args
!=
null
)
args
.
Dispose
();
args
.
Dispose
();
...
...
Titanium.Web.Proxy/packages.config
View file @
990b7412
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<
packages
>
<
packages
>
<
package
id
=
"DotNetZip"
version
=
"1.9.3"
targetFramework
=
"net40-Client"
/>
<
package
id
=
"DotNetZip"
version
=
"1.9.3"
targetFramework
=
"net40-Client"
/>
</
packages
>
</
packages
>
\ 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