Commit 3499ed64 authored by justcoding121's avatar justcoding121 Committed by justcoding121

Refactor

parent a08acc1b
...@@ -3,7 +3,7 @@ Titanium ...@@ -3,7 +3,7 @@ Titanium
A light weight http(s) proxy server written in C# A light weight http(s) proxy server written in C#
![alt tag](https://raw.githubusercontent.com/titanium007/Titanium/master/Titanium.ProxyTest/Capture.PNG) ![alt tag](https://raw.githubusercontent.com/titanium007/Titanium/master/Titanium.Web.Proxy.Test/Capture.PNG)
Features Features
======== ========
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Diagnostics;
using System.Net;
namespace Titanium.HTTPProxyServer
{
public partial class ProxyServer
{
private static void GetRequestStreamCallback(IAsyncResult asynchronousResult)
{
var Args = (SessionEventArgs)asynchronousResult.AsyncState;
// End the operation
Stream postStream = Args.proxyRequest.EndGetRequestStream(asynchronousResult);
if (Args.proxyRequest.ContentLength > 0)
{
Args.proxyRequest.AllowWriteStreamBuffering = true;
try
{
int totalbytesRead = 0;
int bytesToRead;
if (Args.proxyRequest.ContentLength < BUFFER_SIZE)
{
bytesToRead = (int)Args.proxyRequest.ContentLength;
}
else
bytesToRead = BUFFER_SIZE;
while (totalbytesRead < (int)Args.proxyRequest.ContentLength)
{
var buffer = Args.clientStreamReader.ReadBytes(bytesToRead);
totalbytesRead += buffer.Length;
int RemainingBytes = (int)Args.proxyRequest.ContentLength - totalbytesRead;
if (RemainingBytes < bytesToRead)
{
bytesToRead = RemainingBytes;
}
postStream.Write(buffer, 0, buffer.Length);
}
postStream.Close();
}
catch (IOException ex)
{
Args.proxyRequest.KeepAlive = false;
Args.finishedRequestEvent.Set();
Debug.WriteLine(ex.Message);
return;
}
catch (WebException ex)
{
Args.proxyRequest.KeepAlive = false;
Args.finishedRequestEvent.Set();
Debug.WriteLine(ex.Message);
return;
}
}
else if (Args.proxyRequest.SendChunked)
{
Args.proxyRequest.AllowWriteStreamBuffering = true;
try
{
StringBuilder sb = new StringBuilder();
byte[] byteRead = new byte[1];
while (true)
{
Args.clientStream.Read(byteRead, 0, 1);
sb.Append(Encoding.ASCII.GetString(byteRead));
if (sb.ToString().EndsWith(Environment.NewLine))
{
var chunkSizeInHex = sb.ToString().Replace(Environment.NewLine, String.Empty);
var chunckSize = int.Parse(chunkSizeInHex, System.Globalization.NumberStyles.HexNumber);
if (chunckSize == 0)
{
for (int i = 0; i < Encoding.ASCII.GetByteCount(Environment.NewLine); i++)
{
Args.clientStream.ReadByte();
}
break;
}
var totalbytesRead = 0;
int bytesToRead;
if (chunckSize < BUFFER_SIZE)
{
bytesToRead = chunckSize;
}
else
bytesToRead = BUFFER_SIZE;
while (totalbytesRead < chunckSize)
{
var buffer = Args.clientStreamReader.ReadBytes(bytesToRead);
totalbytesRead += buffer.Length;
int RemainingBytes = chunckSize - totalbytesRead;
if (RemainingBytes < bytesToRead)
{
bytesToRead = RemainingBytes;
}
postStream.Write(buffer, 0, buffer.Length);
}
for (int i = 0; i < Encoding.ASCII.GetByteCount(Environment.NewLine); i++)
{
Args.clientStream.ReadByte();
}
sb.Clear();
}
}
postStream.Close();
}
catch (IOException ex)
{
if (postStream != null)
postStream.Close();
Args.proxyRequest.KeepAlive = false;
Args.finishedRequestEvent.Set();
Debug.WriteLine(ex.Message);
return;
}
catch (WebException ex)
{
if (postStream != null)
postStream.Close();
Args.proxyRequest.KeepAlive = false;
Args.finishedRequestEvent.Set();
Debug.WriteLine(ex.Message);
return;
}
}
Args.proxyRequest.BeginGetResponse(new AsyncCallback(GetResponseCallback), Args);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Threading;
using System.Security.Authentication;
using System.Diagnostics;
namespace Titanium.HTTPProxyServer
{
partial class ProxyServer
{
private static void GetResponseCallback(IAsyncResult asynchronousResult)
{
SessionEventArgs Args = (SessionEventArgs)asynchronousResult.AsyncState;
try
{
Args.serverResponse = (HttpWebResponse)Args.proxyRequest.EndGetResponse(asynchronousResult);
}
catch (WebException webEx)
{
Args.proxyRequest.KeepAlive = false;
Args.serverResponse = webEx.Response as HttpWebResponse;
}
Stream serverResponseStream = null;
Stream clientWriteStream = Args.clientStream;
StreamWriter myResponseWriter = null;
try
{
myResponseWriter = new StreamWriter(clientWriteStream);
if (Args.serverResponse != null)
{
List<Tuple<String, String>> responseHeaders = ProcessResponse(Args.serverResponse);
serverResponseStream = Args.serverResponse.GetResponseStream();
Args.serverResponseStream = serverResponseStream;
if (Args.serverResponse.Headers.Count == 0 && Args.serverResponse.ContentLength == -1)
Args.proxyRequest.KeepAlive = false;
bool isChunked = Args.serverResponse.GetResponseHeader("transfer-encoding") == null ? false : Args.serverResponse.GetResponseHeader("transfer-encoding").ToLower() == "chunked" ? true : false;
Args.proxyRequest.KeepAlive = Args.serverResponse.GetResponseHeader("connection") == null ? Args.proxyRequest.KeepAlive : (Args.serverResponse.GetResponseHeader("connection") == "close" ? false : Args.proxyRequest.KeepAlive);
Args.upgradeProtocol = Args.serverResponse.GetResponseHeader("upgrade") == null ? null : Args.serverResponse.GetResponseHeader("upgrade");
if (BeforeResponse != null)
BeforeResponse(null, Args);
if (Args.wasModified)
{
byte[] data;
switch (Args.serverResponse.ContentEncoding)
{
case "gzip":
data = CompressGzip(Args.responseString, Args.encoding);
WriteResponseStatus(Args.serverResponse.ProtocolVersion, Args.serverResponse.StatusCode, Args.serverResponse.StatusDescription, myResponseWriter);
WriteResponseHeaders(myResponseWriter, responseHeaders, data.Length);
sendData(clientWriteStream, data, isChunked);
break;
case "deflate":
data = CompressDeflate(Args.responseString, Args.encoding);
WriteResponseStatus(Args.serverResponse.ProtocolVersion, Args.serverResponse.StatusCode, Args.serverResponse.StatusDescription, myResponseWriter);
WriteResponseHeaders(myResponseWriter, responseHeaders, data.Length);
sendData(clientWriteStream, data, isChunked);
break;
case "zlib":
data = CompressZlib(Args.responseString, Args.encoding);
WriteResponseStatus(Args.serverResponse.ProtocolVersion, Args.serverResponse.StatusCode, Args.serverResponse.StatusDescription, myResponseWriter);
WriteResponseHeaders(myResponseWriter, responseHeaders, data.Length);
sendData(clientWriteStream, data, isChunked);
break;
default:
data = EncodeData(Args.responseString, Args.encoding);
WriteResponseStatus(Args.serverResponse.ProtocolVersion, Args.serverResponse.StatusCode, Args.serverResponse.StatusDescription, myResponseWriter);
WriteResponseHeaders(myResponseWriter, responseHeaders, data.Length);
sendData(clientWriteStream, data, isChunked);
break;
}
}
else
{
WriteResponseStatus(Args.serverResponse.ProtocolVersion, Args.serverResponse.StatusCode, Args.serverResponse.StatusDescription, myResponseWriter);
WriteResponseHeaders(myResponseWriter, responseHeaders);
if (isChunked)
SendChunked(serverResponseStream, clientWriteStream);
else
SendNormal(serverResponseStream, clientWriteStream);
}
clientWriteStream.Flush();
}
else
Args.proxyRequest.KeepAlive = false;
}
catch (IOException ex)
{
Args.proxyRequest.KeepAlive = false;
Debug.WriteLine(ex.Message);
}
catch (SocketException ex)
{
Args.proxyRequest.KeepAlive = false;
Debug.WriteLine(ex.Message);
}
catch (ArgumentException ex)
{
Args.proxyRequest.KeepAlive = false;
Debug.WriteLine(ex.Message);
}
catch (WebException ex)
{
Args.proxyRequest.KeepAlive = false;
Debug.WriteLine(ex.Message);
}
finally
{
if (Args.proxyRequest.KeepAlive == false)
{
if (myResponseWriter != null)
myResponseWriter.Close();
if (clientWriteStream != null)
clientWriteStream.Close();
}
//if (serverResponseStream != null)
// serverResponseStream.Close();
if (Args.serverResponse != null)
Args.serverResponse.Close();
Args.finishedRequestEvent.Set();
}
}
}
}
using System;
using System.Collections.Generic;
using System.Net;
using System.IO;
using System.Reflection;
using System.Linq;
namespace Titanium.HTTPProxyServer
{
public partial class ProxyServer
{
private static void URLPeriodFix()
{
MethodInfo getSyntax = typeof(UriParser).GetMethod("GetSyntax", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
FieldInfo flagsField = typeof(UriParser).GetField("m_Flags", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
if (getSyntax != null && flagsField != null)
{
foreach (string scheme in new[] { "http", "https" })
{
UriParser parser = (UriParser)getSyntax.Invoke(null, new object[] { scheme });
if (parser != null)
{
int flagsValue = (int)flagsField.GetValue(parser);
if ((flagsValue & 0x1000000) != 0)
flagsField.SetValue(parser, flagsValue & ~0x1000000);
}
}
}
}
private static List<Tuple<String, String>> ProcessResponse(HttpWebResponse response)
{
String value = null;
String header = null;
List<Tuple<String, String>> returnHeaders = new List<Tuple<String, String>>();
foreach (String s in response.Headers.Keys)
{
if (s.ToLower() == "set-cookie")
{
header = s;
value = response.Headers[s];
}
else
returnHeaders.Add(new Tuple<String, String>(s, response.Headers[s]));
}
if (!String.IsNullOrWhiteSpace(value))
{
response.Headers.Remove(header);
String[] cookies = cookieSplitRegEx.Split(value);
foreach (String cookie in cookies)
returnHeaders.Add(new Tuple<String, String>("Set-Cookie", cookie));
}
return returnHeaders;
}
private static void WriteResponseStatus(Version version, HttpStatusCode code, String description, StreamWriter myResponseWriter)
{
String s = String.Format("HTTP/{0}.{1} {2} {3}", version.Major, version.Minor, (Int32)code, description);
myResponseWriter.WriteLine(s);
}
private static void WriteResponseHeaders(StreamWriter myResponseWriter, List<Tuple<String, String>> headers)
{
if (headers != null)
{
foreach (Tuple<String, String> header in headers)
{
myResponseWriter.WriteLine(String.Format("{0}: {1}", header.Item1, header.Item2));
}
}
myResponseWriter.WriteLine();
myResponseWriter.Flush();
}
private static void WriteResponseHeaders(StreamWriter myResponseWriter, List<Tuple<String, String>> headers, int length)
{
if (headers != null)
{
foreach (Tuple<String, String> header in headers)
{
if (header.Item1.ToLower() != "content-length")
myResponseWriter.WriteLine(String.Format("{0}: {1}", header.Item1, header.Item2));
else
myResponseWriter.WriteLine(String.Format("{0}: {1}", "content-length", length.ToString()));
}
}
myResponseWriter.WriteLine();
myResponseWriter.Flush();
}
//NEED to optimize this call later
private static string getHostName(ref Queue<string> requestLines)
{
String httpCmd = requestLines.Dequeue();
while (!String.IsNullOrWhiteSpace(httpCmd))
{
String[] header = httpCmd.Split(colonSpaceSplit, 2, StringSplitOptions.None);
switch (header[0].ToLower())
{
case "host":
var hostdetail = header[1];
if (hostdetail.Contains(":"))
return hostdetail.Split(':')[0].Trim();
else
return hostdetail.Trim();
default:
break;
}
httpCmd = requestLines.Dequeue();
}
return null;
}
private static void ReadRequestHeaders(ref List<string> requestLines, HttpWebRequest webReq)
{
for(int i=1; i<requestLines.Count; i++)
{
String httpCmd = requestLines[i];
String[] header = httpCmd.Split(colonSpaceSplit, 2, StringSplitOptions.None);
if(!String.IsNullOrEmpty(header[0].Trim()))
switch (header[0].ToLower())
{
case "accept":
webReq.Accept = header[1];
break;
case "accept-encoding":
webReq.Headers.Add(header[0], "gzip,deflate,zlib");
break;
case "cookie":
webReq.Headers["Cookie"] = header[1];
break;
case "connection":
if (header[1].ToLower() == "keep-alive")
webReq.KeepAlive = true;
break;
case "content-length":
int contentLen;
int.TryParse(header[1], out contentLen);
if (contentLen != 0)
webReq.ContentLength = contentLen;
break;
case "content-type":
webReq.ContentType = header[1];
break;
case "expect":
if (header[1].ToLower() == "100-continue")
webReq.ServicePoint.Expect100Continue = true;
else
webReq.Expect = header[1];
break;
case "host":
webReq.Host = header[1];
break;
case "if-modified-since":
String[] sb = header[1].Trim().Split(semiSplit);
DateTime d;
if (DateTime.TryParse(sb[0], out d))
webReq.IfModifiedSince = d;
break;
case "proxy-connection":
break;
case "range":
var startEnd = header[1].Replace(Environment.NewLine, "").Remove(0, 6).Split('-');
if (startEnd.Length > 1) { if (!String.IsNullOrEmpty(startEnd[1])) webReq.AddRange(int.Parse(startEnd[0]), int.Parse(startEnd[1])); else webReq.AddRange(int.Parse(startEnd[0])); }
else
webReq.AddRange(int.Parse(startEnd[0]));
break;
case "referer":
webReq.Referer = header[1];
break;
case "user-agent":
webReq.UserAgent = header[1];
break;
case "transfer-encoding":
if (header[1].ToLower() == "chunked")
webReq.SendChunked = true;
else
webReq.SendChunked = false;
break;
case "upgrade":
if (header[1].ToLower() == "http/1.1")
webReq.Headers.Add(header[0], header[1]);
break;
default:
if(header.Length>0)
webReq.Headers.Add(header[0], header[1]);
else
webReq.Headers.Add(header[0], "");
break;
}
}
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<connectionStrings>
<add name="SqlCELogConnectionString" providerName="System.Data.SqlServerCe.4.0" connectionString="Data Source=Log.sdf" />
<add name="SqlCEEventsConnectionString" providerName="System.Data.SqlServerCe.4.0" connectionString="Data Source=Events.sdf" />
<add name="SqlCEFilesConnectionString" providerName="System.Data.SqlServerCe.4.0" connectionString="Data Source=Files.sdf" />
<add name="SqlServerLogConnectionString" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=ASXLog;Integrated Security=True;Enlist=False;" providerName="System.Data.SqlClient" />
<add name="SqlServerEventsConnectionString" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=ASXEvents;Integrated Security=True;Enlist=False;" providerName="System.Data.SqlClient" />
<add name="SqlServerFilesConnectionString" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=ASXFiles;Integrated Security=True;Enlist=False;" providerName="System.Data.SqlClient" />
<add name="SqlServerSettingsConnectionString" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=ASXSettings;Integrated Security=True;Enlist=False;" providerName="System.Data.SqlClient" />
</connectionStrings>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlCeConnectionFactory, EntityFramework">
<parameters>
<parameter value="System.Data.SqlServerCe.4.0" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
<provider invariantName="System.Data.SqlServerCe.4.0" type="System.Data.Entity.SqlServerCompact.SqlCeProviderServices, EntityFramework.SqlServerCompact" />
</providers>
</entityFramework>
<unity configSource="unity.debug.xml" />
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0,Profile=Client" /></startup></configuration>
C:\CodeRepository\Titanium\Titanium.ProxyTest\bin\Debug\Titanium.ProxyManager.exe.config
C:\CodeRepository\Titanium\Titanium.ProxyTest\bin\Debug\makecert.exe
C:\CodeRepository\Titanium\Titanium.ProxyTest\bin\Debug\unity.debug.xml
C:\CodeRepository\Titanium\Titanium.ProxyTest\bin\Debug\Titanium.ProxyManager.exe
C:\CodeRepository\Titanium\Titanium.ProxyTest\bin\Debug\Titanium.ProxyManager.pdb
C:\CodeRepository\Titanium\Titanium.ProxyTest\bin\Debug\Titanium.HTTPProxyServer.dll
C:\CodeRepository\Titanium\Titanium.ProxyTest\bin\Debug\Ionic.Zip.dll
C:\CodeRepository\Titanium\Titanium.ProxyTest\bin\Debug\Titanium.HTTPProxyServer.pdb
C:\CodeRepository\Titanium\Titanium.ProxyTest\bin\Debug\Ionic.Zip.xml
C:\CodeRepository\Titanium\Titanium.ProxyTest\obj\Debug\Titanium.ProxyTest.csprojResolveAssemblyReference.cache
C:\CodeRepository\Titanium\Titanium.ProxyTest\obj\Debug\Titanium.ProxyManager.exe
C:\CodeRepository\Titanium\Titanium.ProxyTest\obj\Debug\Titanium.ProxyManager.pdb
...@@ -4,9 +4,9 @@ using System.Linq; ...@@ -4,9 +4,9 @@ using System.Linq;
using System.Text; using System.Text;
using System.IO; using System.IO;
namespace Titanium.HTTPProxyServer.Test namespace Titanium.Web.Proxy.Test.Helpers
{ {
public class FireFoxUtility public class FireFoxHelper
{ {
public static void AddFirefox() public static void AddFirefox()
{ {
......
...@@ -5,9 +5,9 @@ using System.Text; ...@@ -5,9 +5,9 @@ using System.Text;
using Microsoft.Win32; using Microsoft.Win32;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace Titanium.HTTPProxyServer.Test namespace Titanium.Web.Proxy.Test.Helpers
{ {
public static class SystemProxyUtility public static class SystemProxyHelper
{ {
[DllImport("wininet.dll")] [DllImport("wininet.dll")]
public static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer, int dwBufferLength); public static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer, int dwBufferLength);
......
...@@ -6,8 +6,9 @@ using System.Reflection; ...@@ -6,8 +6,9 @@ using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
using System.Text; using System.Text;
using Titanium.Web.Proxy.Test.Helpers;
namespace Titanium.HTTPProxyServer.Test namespace Titanium.Web.Proxy.Test
{ {
public class Program public class Program
{ {
...@@ -28,20 +29,20 @@ namespace Titanium.HTTPProxyServer.Test ...@@ -28,20 +29,20 @@ namespace Titanium.HTTPProxyServer.Test
if(Console.ReadLine().Trim().ToLower()=="y" ) if(Console.ReadLine().Trim().ToLower()=="y" )
{ {
InstallCertificate(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)); InstallCertificate(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location));
SystemProxyUtility.EnableProxyHTTPS("localhost", controller.ListeningPort); SystemProxyHelper.EnableProxyHTTPS("localhost", controller.ListeningPort);
} }
Console.WriteLine("Hit any key to exit.."); Console.WriteLine("Hit any key to exit..");
Console.WriteLine(); Console.WriteLine();
Console.Read(); Console.Read();
//Reset System Proxy on exit //Reset System Proxy on exit
SystemProxyUtility.DisableAllProxy(); SystemProxyHelper.DisableAllProxy();
FireFoxUtility.RemoveFirefox(); FireFoxHelper.RemoveFirefox();
controller.Stop(); controller.Stop();
} }
private static void InstallCertificate(string cerDirectory) private static void InstallCertificate(string CertificateDirectory)
{ {
X509Certificate2 certificate = new X509Certificate2(Path.Combine(cerDirectory , "Titanium Proxy Test Root Certificate.cer")); X509Certificate2 certificate = new X509Certificate2(Path.Combine(CertificateDirectory , "Titanium Proxy Test Root Certificate.cer"));
X509Store store = new X509Store(StoreName.Root, StoreLocation.CurrentUser); X509Store store = new X509Store(StoreName.Root, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadWrite); store.Open(OpenFlags.ReadWrite);
...@@ -64,8 +65,8 @@ namespace Titanium.HTTPProxyServer.Test ...@@ -64,8 +65,8 @@ namespace Titanium.HTTPProxyServer.Test
{ {
try try
{ {
SystemProxyUtility.DisableAllProxy(); SystemProxyHelper.DisableAllProxy();
FireFoxUtility.RemoveFirefox(); FireFoxHelper.RemoveFirefox();
} }
catch { } catch { }
...@@ -73,7 +74,7 @@ namespace Titanium.HTTPProxyServer.Test ...@@ -73,7 +74,7 @@ namespace Titanium.HTTPProxyServer.Test
return false; return false;
} }
// Keeps it from getting garbage collected // Keeps it from getting garbage collected
static ConsoleEventDelegate handler; private static ConsoleEventDelegate handler;
// Pinvoke // Pinvoke
private delegate bool ConsoleEventDelegate(int eventType); private delegate bool ConsoleEventDelegate(int eventType);
[DllImport("kernel32.dll", SetLastError = true)] [DllImport("kernel32.dll", SetLastError = true)]
......
...@@ -6,12 +6,13 @@ using System.Net; ...@@ -6,12 +6,13 @@ using System.Net;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.DirectoryServices.AccountManagement; using System.DirectoryServices.AccountManagement;
using System.DirectoryServices.ActiveDirectory; using System.DirectoryServices.ActiveDirectory;
using Titanium; using Titanium.Web.Proxy.Models;
using Titanium.HTTPProxyServer; using Titanium.Web.Proxy;
using Titanium.Web.Proxy.Test.Helpers;
namespace Titanium.HTTPProxyServer.Test namespace Titanium.Web.Proxy.Test
{ {
public partial class ProxyTestController public partial class ProxyTestController
{ {
...@@ -32,8 +33,8 @@ namespace Titanium.HTTPProxyServer.Test ...@@ -32,8 +33,8 @@ namespace Titanium.HTTPProxyServer.Test
ProxyServer.Start(); ProxyServer.Start();
SystemProxyUtility.EnableProxyHTTP("localhost", ProxyServer.ListeningPort); SystemProxyHelper.EnableProxyHTTP("localhost", ProxyServer.ListeningPort);
FireFoxUtility.AddFirefox(); FireFoxHelper.AddFirefox();
ListeningPort = ProxyServer.ListeningPort; ListeningPort = ProxyServer.ListeningPort;
...@@ -66,16 +67,16 @@ namespace Titanium.HTTPProxyServer.Test ...@@ -66,16 +67,16 @@ namespace Titanium.HTTPProxyServer.Test
//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)
{ {
string Random = e.requestURL.Substring(e.requestURL.LastIndexOf(@"/") + 1); string Random = e.RequestURL.Substring(e.RequestURL.LastIndexOf(@"/") + 1);
int index = _URLList.IndexOf(Random); int index = _URLList.IndexOf(Random);
if (index >= 0) if (index >= 0)
{ {
string URL = e.decode(); string URL = e.Decode();
if (_lastURL != URL) if (_lastURL != URL)
{ {
OnChanged(new VisitedEventArgs() { hostname = e.hostName, URL = URL, remoteIP = e.ipAddress, remotePort = e.port }); OnChanged(new VisitedEventArgs() { hostname = e.Hostname, URL = URL, remoteIP = e.ipAddress, remotePort = e.Port });
} }
...@@ -92,16 +93,16 @@ namespace Titanium.HTTPProxyServer.Test ...@@ -92,16 +93,16 @@ namespace Titanium.HTTPProxyServer.Test
{ {
if (e.proxyRequest.Method == "GET" || e.proxyRequest.Method == "POST") if (e.ProxyRequest.Method == "GET" || e.ProxyRequest.Method == "POST")
{ {
if (e.serverResponse.StatusCode == HttpStatusCode.OK) if (e.ServerResponse.StatusCode == HttpStatusCode.OK)
{ {
if (e.serverResponse.ContentType.Trim().ToLower().Contains("text/html")) if (e.ServerResponse.ContentType.Trim().ToLower().Contains("text/html"))
{ {
string c = e.serverResponse.GetResponseHeader("X-Requested-With"); string c = e.ServerResponse.GetResponseHeader("X-Requested-With");
if (e.serverResponse.GetResponseHeader("X-Requested-With") == "") if (e.ServerResponse.GetResponseHeader("X-Requested-With") == "")
{ {
e.getResponseBody(); e.GetResponseBody();
string functioname = "fr" + RandomString(10); string functioname = "fr" + RandomString(10);
string VisitedURL = RandomString(5); string VisitedURL = RandomString(5);
...@@ -111,10 +112,10 @@ namespace Titanium.HTTPProxyServer.Test ...@@ -111,10 +112,10 @@ namespace Titanium.HTTPProxyServer.Test
string RandomLastRequest = RandomString(10); string RandomLastRequest = RandomString(10);
string LocalRequest; string LocalRequest;
if (e.isSecure) if (e.IsSecure)
LocalRequest = "https://" + e.hostName + "/" + RandomURLEnding; LocalRequest = "https://" + e.Hostname + "/" + RandomURLEnding;
else else
LocalRequest = "http://" + e.hostName + "/" + RandomURLEnding; LocalRequest = "http://" + e.Hostname + "/" + RandomURLEnding;
string script = "var " + RandomLastRequest + " = null;" + string script = "var " + RandomLastRequest + " = null;" +
"if(window.top==self) { " + "\n" + "if(window.top==self) { " + "\n" +
...@@ -130,13 +131,13 @@ namespace Titanium.HTTPProxyServer.Test ...@@ -130,13 +131,13 @@ namespace Titanium.HTTPProxyServer.Test
RequestVariable + ".open(\"POST\",\"" + LocalRequest + "\", true); " + "\n" + RequestVariable + ".open(\"POST\",\"" + LocalRequest + "\", true); " + "\n" +
RequestVariable + ".send(" + VisitedURL + ");} " + RandomLastRequest + " = " + VisitedURL + "}"; RequestVariable + ".send(" + VisitedURL + ");} " + RandomLastRequest + " = " + VisitedURL + "}";
string response = e.responseString; string response = e.ResponseString;
Regex RE = new Regex("</body>", RegexOptions.RightToLeft | RegexOptions.IgnoreCase | RegexOptions.Multiline); Regex RE = new Regex("</body>", RegexOptions.RightToLeft | RegexOptions.IgnoreCase | RegexOptions.Multiline);
string replaced = RE.Replace(response, "<script type =\"text/javascript\">" + script + "</script></body>", 1); string replaced = RE.Replace(response, "<script type =\"text/javascript\">" + script + "</script></body>", 1);
if (replaced.Length != response.Length) if (replaced.Length != response.Length)
{ {
e.responseString = replaced; e.ResponseString = replaced;
_URLList.Add(RandomURLEnding); _URLList.Add(RandomURLEnding);
} }
......
...@@ -8,8 +8,8 @@ ...@@ -8,8 +8,8 @@
<ProjectGuid>{F3B7E553-1904-4E80-BDC7-212342B5C952}</ProjectGuid> <ProjectGuid>{F3B7E553-1904-4E80-BDC7-212342B5C952}</ProjectGuid>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Titanium.ProxyManager</RootNamespace> <RootNamespace>Titanium.Web.Proxy.Test</RootNamespace>
<AssemblyName>Titanium.ProxyManager</AssemblyName> <AssemblyName>Titanium.Web.Proxy.Test</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion> <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<TargetFrameworkProfile>Client</TargetFrameworkProfile> <TargetFrameworkProfile>Client</TargetFrameworkProfile>
...@@ -54,8 +54,8 @@ ...@@ -54,8 +54,8 @@
<Compile Include="Program.cs" /> <Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ProxyTestController.cs" /> <Compile Include="ProxyTestController.cs" />
<Compile Include="Utility\Firefox.cs" /> <Compile Include="Helpers\Firefox.cs" />
<Compile Include="Utility\SystemProxyUtility.cs" /> <Compile Include="Helpers\SystemProxy.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="Capture.PNG" /> <Content Include="Capture.PNG" />
...@@ -70,9 +70,9 @@ ...@@ -70,9 +70,9 @@
</None> </None>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Titanium.HTTPProxyServer\Titanium.HTTPProxyServer.csproj"> <ProjectReference Include="..\Titanium.Web.Proxy\Titanium.Web.Proxy.csproj">
<Project>{8d73a1be-868c-42d2-9ece-f32cc1a02906}</Project> <Project>{8d73a1be-868c-42d2-9ece-f32cc1a02906}</Project>
<Name>Titanium.HTTPProxyServer</Name> <Name>Titanium.Web.Proxy</Name>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
......
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013 # Visual Studio 2013
VisualStudioVersion = 12.0.21005.1 VisualStudioVersion = 12.0.31101.0
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{B6DBABDC-C985-4872-9C38-B4E5079CBC4B}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{B6DBABDC-C985-4872-9C38-B4E5079CBC4B}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Titanium.HTTPProxyServer", "Titanium.HTTPProxyServer\Titanium.HTTPProxyServer.csproj", "{8D73A1BE-868C-42D2-9ECE-F32CC1A02906}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Titanium.Web.Proxy", "Titanium.Web.Proxy\Titanium.Web.Proxy.csproj", "{8D73A1BE-868C-42D2-9ECE-F32CC1A02906}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Titanium.Proxy.Test", "Titanium.ProxyTest\Titanium.Proxy.Test.csproj", "{F3B7E553-1904-4E80-BDC7-212342B5C952}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Titanium.Web.Proxy.Test", "Titanium.Web.Proxy.Test\Titanium.Web.Proxy.Test.csproj", "{F3B7E553-1904-4E80-BDC7-212342B5C952}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
...@@ -17,9 +17,6 @@ Global ...@@ -17,9 +17,6 @@ Global
Release|Any CPU = Release|Any CPU Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64 Release|x64 = Release|x64
Release|x86 = Release|x86 Release|x86 = Release|x86
Release-Plus|Any CPU = Release-Plus|Any CPU
Release-Plus|x64 = Release-Plus|x64
Release-Plus|x86 = Release-Plus|x86
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{8D73A1BE-868C-42D2-9ECE-F32CC1A02906}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8D73A1BE-868C-42D2-9ECE-F32CC1A02906}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
...@@ -34,12 +31,6 @@ Global ...@@ -34,12 +31,6 @@ Global
{8D73A1BE-868C-42D2-9ECE-F32CC1A02906}.Release|x64.Build.0 = Release|x64 {8D73A1BE-868C-42D2-9ECE-F32CC1A02906}.Release|x64.Build.0 = Release|x64
{8D73A1BE-868C-42D2-9ECE-F32CC1A02906}.Release|x86.ActiveCfg = Release|x86 {8D73A1BE-868C-42D2-9ECE-F32CC1A02906}.Release|x86.ActiveCfg = Release|x86
{8D73A1BE-868C-42D2-9ECE-F32CC1A02906}.Release|x86.Build.0 = Release|x86 {8D73A1BE-868C-42D2-9ECE-F32CC1A02906}.Release|x86.Build.0 = Release|x86
{8D73A1BE-868C-42D2-9ECE-F32CC1A02906}.Release-Plus|Any CPU.ActiveCfg = Release|Any CPU
{8D73A1BE-868C-42D2-9ECE-F32CC1A02906}.Release-Plus|Any CPU.Build.0 = Release|Any CPU
{8D73A1BE-868C-42D2-9ECE-F32CC1A02906}.Release-Plus|x64.ActiveCfg = Release|x64
{8D73A1BE-868C-42D2-9ECE-F32CC1A02906}.Release-Plus|x64.Build.0 = Release|x64
{8D73A1BE-868C-42D2-9ECE-F32CC1A02906}.Release-Plus|x86.ActiveCfg = Release|x86
{8D73A1BE-868C-42D2-9ECE-F32CC1A02906}.Release-Plus|x86.Build.0 = Release|x86
{F3B7E553-1904-4E80-BDC7-212342B5C952}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F3B7E553-1904-4E80-BDC7-212342B5C952}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F3B7E553-1904-4E80-BDC7-212342B5C952}.Debug|Any CPU.Build.0 = Debug|Any CPU {F3B7E553-1904-4E80-BDC7-212342B5C952}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F3B7E553-1904-4E80-BDC7-212342B5C952}.Debug|x64.ActiveCfg = Debug|Any CPU {F3B7E553-1904-4E80-BDC7-212342B5C952}.Debug|x64.ActiveCfg = Debug|Any CPU
...@@ -48,10 +39,6 @@ Global ...@@ -48,10 +39,6 @@ Global
{F3B7E553-1904-4E80-BDC7-212342B5C952}.Release|Any CPU.Build.0 = Release|Any CPU {F3B7E553-1904-4E80-BDC7-212342B5C952}.Release|Any CPU.Build.0 = Release|Any CPU
{F3B7E553-1904-4E80-BDC7-212342B5C952}.Release|x64.ActiveCfg = Release|Any CPU {F3B7E553-1904-4E80-BDC7-212342B5C952}.Release|x64.ActiveCfg = Release|Any CPU
{F3B7E553-1904-4E80-BDC7-212342B5C952}.Release|x86.ActiveCfg = Release|Any CPU {F3B7E553-1904-4E80-BDC7-212342B5C952}.Release|x86.ActiveCfg = Release|Any CPU
{F3B7E553-1904-4E80-BDC7-212342B5C952}.Release-Plus|Any CPU.ActiveCfg = Release|Any CPU
{F3B7E553-1904-4E80-BDC7-212342B5C952}.Release-Plus|Any CPU.Build.0 = Release|Any CPU
{F3B7E553-1904-4E80-BDC7-212342B5C952}.Release-Plus|x64.ActiveCfg = Release|Any CPU
{F3B7E553-1904-4E80-BDC7-212342B5C952}.Release-Plus|x86.ActiveCfg = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
......
...@@ -3,44 +3,44 @@ using System.Security.Cryptography.X509Certificates; ...@@ -3,44 +3,44 @@ using System.Security.Cryptography.X509Certificates;
using System.Diagnostics; using System.Diagnostics;
using System.Threading; using System.Threading;
namespace Titanium.HTTPProxyServer namespace Titanium.Web.Proxy.Helpers
{ {
public partial class ProxyServer public class CertificateHelper
{ {
static X509Store store; private static X509Store store;
private static X509Certificate2 getCertificate(string hostname) public static X509Certificate2 GetCertificate(string Hostname)
{ {
if (store == null) if (store == null)
{ {
store = new X509Store(StoreName.My, StoreLocation.CurrentUser); store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly); store.Open(OpenFlags.ReadOnly);
} }
var CachedCertificate = getCertifiateFromStore(hostname); var CachedCertificate = GetCertifiateFromStore(Hostname);
if(CachedCertificate==null) if (CachedCertificate == null)
CreateClientCertificate(hostname); CreateClientCertificate(Hostname);
return getCertifiateFromStore(hostname); return GetCertifiateFromStore(Hostname);
} }
public static X509Certificate2 getCertifiateFromStore(string hostname) private static X509Certificate2 GetCertifiateFromStore(string Hostname)
{ {
X509Certificate2Collection certificateCollection = store.Certificates.Find(X509FindType.FindBySubjectName, hostname, true); X509Certificate2Collection certificateCollection = store.Certificates.Find(X509FindType.FindBySubjectName, Hostname, true);
foreach(var certificate in certificateCollection) foreach (var certificate in certificateCollection)
{ {
if (certificate.SubjectName.Name.StartsWith("CN=" + hostname) && certificate.IssuerName.Name.StartsWith("CN=Titanium_Proxy_Test_Root")) if (certificate.SubjectName.Name.StartsWith("CN=" + Hostname) && certificate.IssuerName.Name.StartsWith("CN=Titanium_Proxy_Test_Root"))
return certificate; return certificate;
} }
return null; return null;
} }
public static void CreateClientCertificate(string hostname) private static void CreateClientCertificate(string Hostname)
{ {
Process process = new Process(); Process process = new Process();
// Stop the process from opening a new window // Stop the process from opening a new window
...@@ -50,12 +50,12 @@ namespace Titanium.HTTPProxyServer ...@@ -50,12 +50,12 @@ namespace Titanium.HTTPProxyServer
// Setup executable and parameters // Setup executable and parameters
process.StartInfo.FileName = @"makecert.exe"; process.StartInfo.FileName = @"makecert.exe";
process.StartInfo.Arguments = @"-pe -ss my -n ""CN=" + hostname + @""" -sky exchange -in Titanium_Proxy_Test_Root -is my -eku 1.3.6.1.5.5.7.3.1 -cy end -a sha1 -m 132 -b 10/07/2012"; process.StartInfo.Arguments = @"-pe -ss my -n ""CN=" + Hostname + @""" -sky exchange -in Titanium_Proxy_Test_Root -is my -eku 1.3.6.1.5.5.7.3.1 -cy end -a sha1 -m 132 -b 10/07/2012";
// Go // Go
process.Start(); process.Start();
process.WaitForExit(); process.WaitForExit();
} }
......
...@@ -4,77 +4,35 @@ using System.Linq; ...@@ -4,77 +4,35 @@ using System.Linq;
using System.Text; using System.Text;
using System.IO; using System.IO;
namespace Titanium.HTTPProxyServer namespace Titanium.Web.Proxy.Helpers
{ {
public partial class ProxyServer public class CompressionHelper
{ {
private static readonly int BUFFER_SIZE = 8192;
private static void SendNormal(Stream inStream, Stream outStream)
{
Byte[] buffer = new Byte[BUFFER_SIZE];
int bytesRead;
while ((bytesRead = inStream.Read(buffer, 0, buffer.Length)) > 0)
{
outStream.Write(buffer, 0, bytesRead);
} public static string DecompressGzip(Stream input, Encoding e)
}
private static void SendChunked(Stream inStream, Stream outStream)
{ {
using (System.IO.Compression.GZipStream decompressor = new System.IO.Compression.GZipStream(input, System.IO.Compression.CompressionMode.Decompress))
Byte[] buffer = new Byte[BUFFER_SIZE];
var ChunkTrail = Encoding.ASCII.GetBytes(Environment.NewLine);
int bytesRead;
while ((bytesRead = inStream.Read(buffer, 0, buffer.Length)) > 0)
{ {
var ChunkHead = Encoding.ASCII.GetBytes(bytesRead.ToString("x2")); int read = 0;
outStream.Write(ChunkHead, 0, ChunkHead.Length); var buffer = new byte[BUFFER_SIZE];
outStream.Write(ChunkTrail, 0, ChunkTrail.Length);
outStream.Write(buffer, 0, bytesRead);
outStream.Write(ChunkTrail, 0, ChunkTrail.Length);
}
var ChunkEnd = Encoding.ASCII.GetBytes(0.ToString("x2") + Environment.NewLine + Environment.NewLine);
outStream.Write(ChunkEnd, 0, ChunkEnd.Length);
}
private static void SendChunked(byte[] data, Stream outStream)
{
Byte[] buffer = new Byte[BUFFER_SIZE];
var ChunkTrail = Encoding.ASCII.GetBytes(Environment.NewLine);
var ChunkHead = Encoding.ASCII.GetBytes(data.Length.ToString("x2"));
outStream.Write(ChunkHead, 0, ChunkHead.Length);
outStream.Write(ChunkTrail, 0, ChunkTrail.Length);
outStream.Write(data, 0, data.Length);
outStream.Write(ChunkTrail, 0, ChunkTrail.Length);
using (MemoryStream output = new MemoryStream())
{
while ((read = decompressor.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, read);
}
return e.GetString(output.ToArray());
}
var ChunkEnd = Encoding.ASCII.GetBytes(0.ToString("x2") + Environment.NewLine + Environment.NewLine); }
outStream.Write(ChunkEnd, 0, ChunkEnd.Length);
} }
public static byte[] CompressZlib(string ResponseData, Encoding e)
private static byte[] EncodeData(string ResponseData, Encoding e)
{
return e.GetBytes(ResponseData);
}
private static byte[] CompressZlib(string ResponseData, Encoding e)
{ {
Byte[] bytes = e.GetBytes(ResponseData); Byte[] bytes = e.GetBytes(ResponseData);
...@@ -89,13 +47,13 @@ namespace Titanium.HTTPProxyServer ...@@ -89,13 +47,13 @@ namespace Titanium.HTTPProxyServer
return ms.ToArray(); return ms.ToArray();
} }
} }
private static byte[] CompressDeflate(string ResponseData, Encoding e) public static byte[] CompressDeflate(string ResponseData, Encoding e)
{ {
Byte[] bytes = e.GetBytes(ResponseData); Byte[] bytes = e.GetBytes(ResponseData);
...@@ -108,39 +66,66 @@ namespace Titanium.HTTPProxyServer ...@@ -108,39 +66,66 @@ namespace Titanium.HTTPProxyServer
} }
return ms.ToArray(); return ms.ToArray();
} }
} }
private static byte[] CompressGzip(string ResponseData, Encoding e) public static byte[] CompressGzip(string ResponseData, Encoding e)
{ {
Byte[] bytes = e.GetBytes(ResponseData); Byte[] bytes = e.GetBytes(ResponseData);
using (MemoryStream ms = new MemoryStream()) using (MemoryStream ms = new MemoryStream())
{ {
using (Ionic.Zlib.GZipStream zip = new Ionic.Zlib.GZipStream(ms, Ionic.Zlib.CompressionMode.Compress, true)) using (Ionic.Zlib.GZipStream zip = new Ionic.Zlib.GZipStream(ms, Ionic.Zlib.CompressionMode.Compress, true))
{ {
zip.Write(bytes, 0, bytes.Length); zip.Write(bytes, 0, bytes.Length);
} }
return ms.ToArray(); return ms.ToArray();
} }
} }
private static void sendData(Stream outStream, byte[] data, bool isChunked) public static string DecompressDeflate(Stream input, Encoding e)
{ {
if (!isChunked)
using (Ionic.Zlib.DeflateStream decompressor = new Ionic.Zlib.DeflateStream(input, Ionic.Zlib.CompressionMode.Decompress))
{ {
outStream.Write(data, 0, data.Length); int read = 0;
var buffer = new byte[BUFFER_SIZE];
using (MemoryStream output = new MemoryStream())
{
while ((read = decompressor.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, read);
}
return e.GetString(output.ToArray());
}
} }
else
SendChunked(data, outStream);
} }
public static string DecompressZlib(Stream input, Encoding e)
{
using (Ionic.Zlib.ZlibStream decompressor = new Ionic.Zlib.ZlibStream(input, Ionic.Zlib.CompressionMode.Decompress))
{
int read = 0;
var buffer = new byte[BUFFER_SIZE];
using (MemoryStream output = new MemoryStream())
{
while ((read = decompressor.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, read);
}
return e.GetString(output.ToArray());
}
}
}
} }
} }
...@@ -5,13 +5,11 @@ using System.Text; ...@@ -5,13 +5,11 @@ using System.Text;
using System.IO; using System.IO;
using System.Diagnostics; using System.Diagnostics;
namespace Titanium.HTTPProxyServer namespace Titanium.Web.Proxy.Helpers
{ {
public class CustomBinaryReader : BinaryReader public class CustomBinaryReader : BinaryReader
{ {
public CustomBinaryReader(Stream stream, Encoding encoding) public CustomBinaryReader(Stream stream, Encoding encoding)
: base(stream, encoding) : base(stream, encoding)
{ {
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
namespace Titanium.Web.Proxy.Helpers
{
public class NetFrameworkHelper
{
public static void URLPeriodFix()
{
MethodInfo getSyntax = typeof(UriParser).GetMethod("GetSyntax", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
FieldInfo flagsField = typeof(UriParser).GetField("m_Flags", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
if (getSyntax != null && flagsField != null)
{
foreach (string scheme in new[] { "http", "https" })
{
UriParser parser = (UriParser)getSyntax.Invoke(null, new object[] { scheme });
if (parser != null)
{
int flagsValue = (int)flagsField.GetValue(parser);
if ((flagsValue & 0x1000000) != 0)
flagsField.SetValue(parser, flagsValue & ~0x1000000);
}
}
}
}
}
}
...@@ -4,9 +4,9 @@ using System.Linq; ...@@ -4,9 +4,9 @@ using System.Linq;
using System.Text; using System.Text;
using System.IO; using System.IO;
namespace Titanium.HTTPProxyServer namespace Titanium.Web.Proxy.Helpers
{ {
public static class StreamUtilities public static class StreamHelper
{ {
private const int DEFAULT_BUFFER_SIZE = 8192; // +32767 private const int DEFAULT_BUFFER_SIZE = 8192; // +32767
public static void CopyTo(this Stream input, Stream output) public static void CopyTo(this Stream input, Stream output)
......
...@@ -7,20 +7,22 @@ using System.IO; ...@@ -7,20 +7,22 @@ using System.IO;
using System.Net; using System.Net;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Titanium.HTTPProxyServer namespace Titanium.Web.Proxy.Helpers
{ {
public partial class ProxyServer public class TcpHelper
{ {
public static void sendRaw(string hostname, int tunnelPort, System.IO.Stream clientStream) private static readonly int BUFFER_SIZE = 8192;
private static readonly String[] colonSpaceSplit = new string[] { ": " };
public static void SendRaw(string Hostname, int TunnelPort, System.IO.Stream ClientStream)
{ {
System.Net.Sockets.TcpClient tunnelClient = new System.Net.Sockets.TcpClient(hostname, tunnelPort); System.Net.Sockets.TcpClient tunnelClient = new System.Net.Sockets.TcpClient(Hostname, TunnelPort);
var tunnelStream = tunnelClient.GetStream(); var tunnelStream = tunnelClient.GetStream();
var tunnelReadBuffer = new byte[BUFFER_SIZE]; var tunnelReadBuffer = new byte[BUFFER_SIZE];
Task sendRelay = new Task(() => StreamUtilities.CopyTo(clientStream, tunnelStream, BUFFER_SIZE)); Task sendRelay = new Task(() => StreamHelper.CopyTo(ClientStream, tunnelStream, BUFFER_SIZE));
Task receiveRelay = new Task(() => StreamUtilities.CopyTo(tunnelStream, clientStream, BUFFER_SIZE)); Task receiveRelay = new Task(() => StreamHelper.CopyTo(tunnelStream, ClientStream, BUFFER_SIZE));
sendRelay.Start(); sendRelay.Start();
receiveRelay.Start(); receiveRelay.Start();
...@@ -33,21 +35,21 @@ namespace Titanium.HTTPProxyServer ...@@ -33,21 +35,21 @@ namespace Titanium.HTTPProxyServer
if (tunnelClient != null) if (tunnelClient != null)
tunnelClient.Close(); tunnelClient.Close();
} }
private static void sendRaw(string httpCmd, string secureHostName, ref List<string> requestLines, bool isSecure, Stream clientStream) public static void SendRaw(string HttpCmd, string SecureHostName, ref List<string> RequestLines, bool IsHttps, Stream ClientStream)
{ {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.Append(httpCmd); sb.Append(HttpCmd);
sb.Append(Environment.NewLine); sb.Append(Environment.NewLine);
string hostname= secureHostName; string hostname= SecureHostName;
for(int i = 1; i < requestLines.Count;i++) for(int i = 1; i < RequestLines.Count;i++)
{ {
var header = requestLines[i]; var header = RequestLines[i];
if (secureHostName == null) if (SecureHostName == null)
{ {
String[] headerParsed = httpCmd.Split(colonSpaceSplit, 2, StringSplitOptions.None); String[] headerParsed = HttpCmd.Split(colonSpaceSplit, 2, StringSplitOptions.None);
switch (headerParsed[0].ToLower()) switch (headerParsed[0].ToLower())
{ {
case "host": case "host":
...@@ -66,13 +68,8 @@ namespace Titanium.HTTPProxyServer ...@@ -66,13 +68,8 @@ namespace Titanium.HTTPProxyServer
} }
sb.Append(Environment.NewLine); sb.Append(Environment.NewLine);
if (hostname == null)
{
// Dns.geth
}
int tunnelPort = 80; int tunnelPort = 80;
if (isSecure) if (IsHttps)
{ {
tunnelPort = 443; tunnelPort = 443;
...@@ -82,7 +79,7 @@ namespace Titanium.HTTPProxyServer ...@@ -82,7 +79,7 @@ namespace Titanium.HTTPProxyServer
System.Net.Sockets.TcpClient tunnelClient = new System.Net.Sockets.TcpClient(hostname, tunnelPort); System.Net.Sockets.TcpClient tunnelClient = new System.Net.Sockets.TcpClient(hostname, tunnelPort);
var tunnelStream = tunnelClient.GetStream() as System.IO.Stream; var tunnelStream = tunnelClient.GetStream() as System.IO.Stream;
if (isSecure) if (IsHttps)
{ {
var sslStream = new SslStream(tunnelStream); var sslStream = new SslStream(tunnelStream);
sslStream.AuthenticateAsClient(hostname); sslStream.AuthenticateAsClient(hostname);
...@@ -90,8 +87,8 @@ namespace Titanium.HTTPProxyServer ...@@ -90,8 +87,8 @@ namespace Titanium.HTTPProxyServer
} }
var sendRelay = new Task(() => StreamUtilities.CopyTo(sb.ToString(), clientStream, tunnelStream, BUFFER_SIZE)); var sendRelay = new Task(() => StreamHelper.CopyTo(sb.ToString(), ClientStream, tunnelStream, BUFFER_SIZE));
var receiveRelay = new Task(() => StreamUtilities.CopyTo(tunnelStream, clientStream, BUFFER_SIZE)); var receiveRelay = new Task(() => StreamHelper.CopyTo(tunnelStream, ClientStream, BUFFER_SIZE));
sendRelay.Start(); sendRelay.Start();
receiveRelay.Start(); receiveRelay.Start();
......
...@@ -2,45 +2,46 @@ ...@@ -2,45 +2,46 @@
using System.Text; using System.Text;
using System.IO; using System.IO;
using System.Net; using System.Net;
using Titanium.Web.Proxy.Helpers;
namespace Titanium.HTTPProxyServer namespace Titanium.Web.Proxy.Models
{ {
public class SessionEventArgs : EventArgs public class SessionEventArgs : EventArgs
{ {
public string requestURL { get; set; } public string RequestURL { get; set; }
public string hostName { get; set; } public string Hostname { get; set; }
public CustomBinaryReader clientStreamReader { get; set; } public CustomBinaryReader ClientStreamReader { get; set; }
public string responseString { get; set; } public string ResponseString { get; set; }
public int requestLength { get; set; } public int RequestLength { get; set; }
public Stream clientStream { get; set; } public Stream ClientStream { get; set; }
public Version httpVersion { get; set; } public Version HttpVersion { get; set; }
public bool isAlive { get; set; } public bool IsAlive { get; set; }
public bool cancel { get; set; } public bool Cancel { get; set; }
public bool isSecure { get; set; } public bool IsSecure { get; set; }
public int port { get; set; } public int Port { get; set; }
private int BUFFER_SIZE; private int BUFFER_SIZE;
public HttpWebResponse serverResponse { get; set; } public HttpWebResponse ServerResponse { get; set; }
public Stream serverResponseStream { get; set; } public Stream ServerResponseStream { get; set; }
public HttpWebRequest proxyRequest { get; set; } public HttpWebRequest ProxyRequest { get; set; }
public Encoding encoding { get; set; } public Encoding Encoding { get; set; }
public bool wasModified { get; set; } public bool WasModified { get; set; }
public System.Threading.ManualResetEvent finishedRequestEvent { get; set; } public System.Threading.ManualResetEvent FinishedRequestEvent { get; set; }
public string upgradeProtocol { get; set; } public string UpgradeProtocol { get; set; }
public SessionEventArgs(int BufferSize) public SessionEventArgs(int BufferSize)
{ {
BUFFER_SIZE = BufferSize; BUFFER_SIZE = BufferSize;
} }
public string decode() public string Decode()
{ {
int bytesRead; int bytesRead;
int totalBytesRead = 0; int totalBytesRead = 0;
MemoryStream mw = new MemoryStream(); MemoryStream mw = new MemoryStream();
var buffer = clientStreamReader.ReadBytes(requestLength); var buffer = ClientStreamReader.ReadBytes(RequestLength);
while (totalBytesRead < requestLength && (bytesRead = buffer.Length) > 0) while (totalBytesRead < RequestLength && (bytesRead = buffer.Length) > 0)
{ {
totalBytesRead += bytesRead; totalBytesRead += bytesRead;
mw.Write(buffer, 0, bytesRead); mw.Write(buffer, 0, bytesRead);
...@@ -52,8 +53,8 @@ namespace Titanium.HTTPProxyServer ...@@ -52,8 +53,8 @@ namespace Titanium.HTTPProxyServer
} }
public void Ok() public void Ok()
{ {
StreamWriter connectStreamWriter = new StreamWriter(clientStream); StreamWriter connectStreamWriter = new StreamWriter(ClientStream);
var s = String.Format("HTTP/{0}.{1} {2} {3}", httpVersion.Major, httpVersion.Minor, 200, "Ok"); var s = String.Format("HTTP/{0}.{1} {2} {3}", HttpVersion.Major, HttpVersion.Minor, 200, "Ok");
connectStreamWriter.WriteLine(s); connectStreamWriter.WriteLine(s);
connectStreamWriter.WriteLine(String.Format("Timestamp: {0}", DateTime.Now.ToString())); connectStreamWriter.WriteLine(String.Format("Timestamp: {0}", DateTime.Now.ToString()));
connectStreamWriter.WriteLine("content-length: 0"); connectStreamWriter.WriteLine("content-length: 0");
...@@ -61,7 +62,7 @@ namespace Titanium.HTTPProxyServer ...@@ -61,7 +62,7 @@ namespace Titanium.HTTPProxyServer
connectStreamWriter.WriteLine("Pragma: no-cache"); connectStreamWriter.WriteLine("Pragma: no-cache");
connectStreamWriter.WriteLine("Expires: 0"); connectStreamWriter.WriteLine("Expires: 0");
if (isAlive) if (IsAlive)
{ {
connectStreamWriter.WriteLine("Connection: Keep-Alive"); connectStreamWriter.WriteLine("Connection: Keep-Alive");
} }
...@@ -70,106 +71,48 @@ namespace Titanium.HTTPProxyServer ...@@ -70,106 +71,48 @@ namespace Titanium.HTTPProxyServer
connectStreamWriter.WriteLine(); connectStreamWriter.WriteLine();
connectStreamWriter.Flush(); connectStreamWriter.Flush();
cancel = true; Cancel = true;
} }
public void getResponseBody() public void GetResponseBody()
{ {
if (responseString == null) if (ResponseString == null)
{ {
encoding = Encoding.GetEncoding(serverResponse.CharacterSet);
if (encoding == null) encoding = Encoding.Default; Encoding = Encoding.GetEncoding(ServerResponse.CharacterSet);
if (Encoding == null) Encoding = Encoding.Default;
string ResponseData = ""; string ResponseData = "";
switch (serverResponse.ContentEncoding) switch (ServerResponse.ContentEncoding)
{ {
case "gzip": case "gzip":
ResponseData = DecompressGzip(serverResponseStream, encoding); ResponseData = CompressionHelper.DecompressGzip(ServerResponseStream, Encoding);
break; break;
case "deflate": case "deflate":
ResponseData = DecompressDeflate(serverResponseStream, encoding); ResponseData = CompressionHelper.DecompressDeflate(ServerResponseStream, Encoding);
break; break;
case "zlib": case "zlib":
ResponseData = DecompressZlib(serverResponseStream, encoding); ResponseData = CompressionHelper.DecompressZlib(ServerResponseStream, Encoding);
break; break;
default: default:
ResponseData = DecodeData(serverResponseStream, encoding); ResponseData = DecodeData(ServerResponseStream, Encoding);
break; break;
} }
responseString = ResponseData; ResponseString = ResponseData;
wasModified = true; WasModified = true;
} }
} }
//stream reader not recomended for images //stream reader not recomended for images
private string DecodeData(Stream responseStream, Encoding e) private string DecodeData(Stream ResponseStream, Encoding e)
{ {
StreamReader reader = new StreamReader(responseStream, e); StreamReader reader = new StreamReader(ResponseStream, e);
return reader.ReadToEnd(); return reader.ReadToEnd();
} }
private string DecompressGzip(Stream input, Encoding e)
{
using (System.IO.Compression.GZipStream decompressor = new System.IO.Compression.GZipStream(input,System.IO.Compression.CompressionMode.Decompress))
{
int read = 0;
var buffer = new byte[BUFFER_SIZE];
using (MemoryStream output = new MemoryStream())
{
while ((read = decompressor.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, read);
}
return e.GetString(output.ToArray());
}
}
}
private string DecompressDeflate(Stream input, Encoding e)
{
using (Ionic.Zlib.DeflateStream decompressor = new Ionic.Zlib.DeflateStream(input, Ionic.Zlib.CompressionMode.Decompress))
{
int read = 0;
var buffer = new byte[BUFFER_SIZE];
using (MemoryStream output = new MemoryStream())
{
while ((read = decompressor.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, read);
}
return e.GetString(output.ToArray());
}
}
}
private string DecompressZlib(Stream input, Encoding e)
{
using (Ionic.Zlib.ZlibStream decompressor = new Ionic.Zlib.ZlibStream(input, Ionic.Zlib.CompressionMode.Decompress))
{
int read = 0;
var buffer = new byte[BUFFER_SIZE];
using (MemoryStream output = new MemoryStream())
{
while ((read = decompressor.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, read);
}
return e.GetString(output.ToArray());
}
}
}
...@@ -177,5 +120,5 @@ namespace Titanium.HTTPProxyServer ...@@ -177,5 +120,5 @@ namespace Titanium.HTTPProxyServer
public IPAddress ipAddress { get; set; } public IPAddress ipAddress { get; set; }
} }
} }
...@@ -9,9 +9,12 @@ using System.Net.Security; ...@@ -9,9 +9,12 @@ using System.Net.Security;
using System.Security.Authentication; using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
using System.Diagnostics; using System.Diagnostics;
using System.Threading.Tasks;
using Titanium.Web.Proxy.Models;
using Titanium.Web.Proxy.Helpers;
namespace Titanium.HTTPProxyServer namespace Titanium.Web.Proxy
{ {
/// <summary> /// <summary>
/// Proxy Server Main class /// Proxy Server Main class
...@@ -21,19 +24,19 @@ namespace Titanium.HTTPProxyServer ...@@ -21,19 +24,19 @@ namespace Titanium.HTTPProxyServer
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 = new char[] { ';' };
private static readonly char[] equalSplit = new char[] { '=' };
private static readonly String[] colonSpaceSplit = new string[] { ": " }; private static readonly String[] colonSpaceSplit = new string[] { ": " };
private static readonly char[] spaceSplit = new char[] { ' ' }; private static readonly char[] spaceSplit = new char[] { ' ' };
private static readonly char[] commaSplit = new char[] { ',' };
private static readonly Regex cookieSplitRegEx = new Regex(@",(?! )"); private static readonly Regex cookieSplitRegEx = new Regex(@",(?! )");
private static object _outputLockObj = new object(); private static object certificateAccessLock = new object();
private static List<string> _pinnedCertificateClients = new List<string>(); private static List<string> pinnedCertificateClients = new List<string>();
private static Dictionary<string, X509Certificate2> certificateCache = new Dictionary<string, X509Certificate2>();
private static X509Store _store = new X509Store(StoreName.My, StoreLocation.CurrentUser); private static ManualResetEvent tcpClientConnected = new ManualResetEvent(false);
private static TcpListener _listener; private static TcpListener listener;
private static Thread _listenerThread; private static Thread listenerThread;
public static event EventHandler<SessionEventArgs> BeforeRequest; public static event EventHandler<SessionEventArgs> BeforeRequest;
public static event EventHandler<SessionEventArgs> BeforeResponse; public static event EventHandler<SessionEventArgs> BeforeResponse;
...@@ -47,7 +50,7 @@ namespace Titanium.HTTPProxyServer ...@@ -47,7 +50,7 @@ namespace Titanium.HTTPProxyServer
{ {
get get
{ {
return ((IPEndPoint)_listener.LocalEndpoint).Port; return ((IPEndPoint)listener.LocalEndpoint).Port;
} }
} }
...@@ -65,21 +68,22 @@ namespace Titanium.HTTPProxyServer ...@@ -65,21 +68,22 @@ namespace Titanium.HTTPProxyServer
{ {
if (sslPolicyErrors == SslPolicyErrors.None) return true; if (sslPolicyErrors == SslPolicyErrors.None) return true;
else else
return false; return false;
}; };
URLPeriodFix(); NetFrameworkHelper.URLPeriodFix();
} }
private static bool ShouldListen { get; set; }
public static bool Start() public static bool Start()
{ {
_listener = new TcpListener(IPAddress.Any, 0); listener = new TcpListener(IPAddress.Any, 0);
_listener.Start(); listener.Start();
_listenerThread = new Thread(new ParameterizedThreadStart(Listen)); listenerThread = new Thread(new ParameterizedThreadStart(Listen));
_listenerThread.Start(_listener); listenerThread.IsBackground = true;
_listenerThread.IsBackground = true; ShouldListen = true;
listenerThread.Start(listener);
return true; return true;
} }
...@@ -87,60 +91,62 @@ namespace Titanium.HTTPProxyServer ...@@ -87,60 +91,62 @@ namespace Titanium.HTTPProxyServer
public static void Stop() public static void Stop()
{ {
_listener.Stop(); ShouldListen = false;
_listenerThread.Abort(); listener.Stop();
_listenerThread.Join(); listenerThread.Interrupt();
} }
// Thread signal.
public static ManualResetEvent tcpClientConnected =
new ManualResetEvent(false);
private static void Listen(Object obj) private static void Listen(Object obj)
{ {
TcpListener listener = (TcpListener)obj; TcpListener listener = (TcpListener)obj;
try try
{ {
while (true) while (ShouldListen)
{ {
// Set the event to nonsignaled state. // Set the event to nonsignaled state.
tcpClientConnected.Reset(); tcpClientConnected.Reset();
listener.BeginAcceptTcpClient(new AsyncCallback(DoAcceptTcpClientCallback), listener); listener.BeginAcceptTcpClient(new AsyncCallback(AcceptTcpClientCallback), listener);
// Wait until a connection is made and processed before // Wait until a connection is made and processed before
// continuing. // continuing.
tcpClientConnected.WaitOne(); tcpClientConnected.WaitOne();
} }
} }
catch (ThreadAbortException ex) { Debug.WriteLine(ex.Message); } catch (ThreadInterruptedException) { }
catch (SocketException ex) catch (SocketException ex)
{ {
Debug.WriteLine(ex.Message); Debug.WriteLine(ex.Message);
} }
} }
public static void DoAcceptTcpClientCallback(IAsyncResult ar) public static void AcceptTcpClientCallback(IAsyncResult ar)
{ {
// Get the listener that handles the client request. // Get the listener that handles the client request.
TcpListener listener = (TcpListener)ar.AsyncState; TcpListener listener = (TcpListener)ar.AsyncState;
TcpClient client = null;
// End the operation and display the received data on // End the operation and display the received data on
// the console. // the console.
TcpClient client = listener.EndAcceptTcpClient(ar); client = listener.EndAcceptTcpClient(ar);
while (!ThreadPool.UnsafeQueueUserWorkItem(new WaitCallback(ProcessClient), client)) ; Task.Factory.StartNew(() => ProcessClient(client));
// Signal the calling thread to continue. // Signal the calling thread to continue.
tcpClientConnected.Set(); tcpClientConnected.Set();
} }
private static int pending = 0;
private static void ProcessClient(Object param) private static void ProcessClient(Object param)
{ {
try try
{ {
TcpClient client = param as TcpClient; TcpClient client = param as TcpClient;
DoHttpProcessing(client); HandleClientRequest(client);
client.Close(); client.Close();
} }
catch (Exception ex) catch (Exception ex)
......
This diff is collapsed.
...@@ -8,8 +8,8 @@ ...@@ -8,8 +8,8 @@
<ProjectGuid>{8D73A1BE-868C-42D2-9ECE-F32CC1A02906}</ProjectGuid> <ProjectGuid>{8D73A1BE-868C-42D2-9ECE-F32CC1A02906}</ProjectGuid>
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Titanium.HTTPProxyServer</RootNamespace> <RootNamespace>Titanium.Web.Proxy</RootNamespace>
<AssemblyName>Titanium.HTTPProxyServer</AssemblyName> <AssemblyName>Titanium.Web.Proxy</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion> <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkProfile>Client</TargetFrameworkProfile> <TargetFrameworkProfile>Client</TargetFrameworkProfile>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
...@@ -74,17 +74,16 @@ ...@@ -74,17 +74,16 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Request\RequestHandler.cs" /> <Compile Include="RequestHandler.cs" />
<Compile Include="Request\RequestManager.cs" /> <Compile Include="ResponseHandler.cs" />
<Compile Include="Response\ResponseManager.cs" /> <Compile Include="Helpers\Certificate.cs" />
<Compile Include="Utility\CertificateUtility.cs" /> <Compile Include="Helpers\CustomBinaryReader.cs" />
<Compile Include="Utility\CustomBinaryReader.cs" /> <Compile Include="Helpers\NetFramework.cs" />
<Compile Include="Utility\GeneralUtility.cs" /> <Compile Include="Helpers\Compression.cs" />
<Compile Include="Utility\CompressionUtility.cs" />
<Compile Include="ProxyServer.cs" /> <Compile Include="ProxyServer.cs" />
<Compile Include="EventArgs\SessionEventArgs.cs" /> <Compile Include="Models\SessionEventArgs.cs" />
<Compile Include="Utility\RawTCPRelay.cs" /> <Compile Include="Helpers\Tcp.cs" />
<Compile Include="Extensions\StreamExtensions.cs" /> <Compile Include="Helpers\Stream.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="Properties\" /> <Folder Include="Properties\" />
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment