├── SharpProxy
├── main.ico
├── app.config
├── Properties
│ ├── Settings.settings
│ ├── Settings.Designer.cs
│ ├── AssemblyInfo.cs
│ ├── Resources.Designer.cs
│ └── Resources.resx
├── Program.cs
├── SharpProxy.csproj
├── ProxyThread.cs
├── frmMain.cs
├── frmMain.Designer.cs
└── frmMain.resx
├── README.txt
├── .gitignore
└── SharpProxy.sln
/SharpProxy/main.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jocull/SharpProxy/HEAD/SharpProxy/main.ico
--------------------------------------------------------------------------------
/SharpProxy/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/SharpProxy/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/README.txt:
--------------------------------------------------------------------------------
1 | SharpProxy is a simple proxy server developed with the intent of being able to open up local ASP.NET development servers.
2 |
3 | This allows you to test, hit breakpoints, and generally do development by using other machines and mobile devices.
4 |
5 | Simply enter the local port number of your .NET development server and map it with an external port to host on.
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | #ignore thumbnails created by windows
3 | Thumbs.db
4 | #Ignore files build by Visual Studio
5 | *.obj
6 | *.exe
7 | *.pdb
8 | *.user
9 | *.aps
10 | *.pch
11 | *.vspscc
12 | *_i.c
13 | *_p.c
14 | *.ncb
15 | *.suo
16 | *.tlb
17 | *.tlh
18 | *.bak
19 | *.cache
20 | *.ilk
21 | *.log
22 | [Bb]in
23 | [Dd]ebug*/
24 | *.lib
25 | *.sbr
26 | obj/
27 | [Rr]elease*/
28 | _ReSharper*/
29 | [Tt]est[Rr]esult*
--------------------------------------------------------------------------------
/SharpProxy/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Windows.Forms;
4 |
5 | namespace SharpProxy
6 | {
7 | static class Program
8 | {
9 | ///
10 | /// The main entry point for the application.
11 | ///
12 | [STAThread]
13 | static void Main()
14 | {
15 | Application.EnableVisualStyles();
16 | Application.SetCompatibleTextRenderingDefault(false);
17 | Application.Run(new frmMain());
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/SharpProxy.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 11.00
3 | # Visual Studio 2010
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpProxy", "SharpProxy\SharpProxy.csproj", "{AED54322-48BB-4587-ADE3-45FE2D2318AC}"
5 | EndProject
6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{AE1ED7D8-B282-4B84-AD12-E5FB1A736314}"
7 | ProjectSection(SolutionItems) = preProject
8 | README.txt = README.txt
9 | EndProjectSection
10 | EndProject
11 | Global
12 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
13 | Debug|x86 = Debug|x86
14 | Release|x86 = Release|x86
15 | EndGlobalSection
16 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
17 | {AED54322-48BB-4587-ADE3-45FE2D2318AC}.Debug|x86.ActiveCfg = Debug|x86
18 | {AED54322-48BB-4587-ADE3-45FE2D2318AC}.Debug|x86.Build.0 = Debug|x86
19 | {AED54322-48BB-4587-ADE3-45FE2D2318AC}.Release|x86.ActiveCfg = Release|x86
20 | {AED54322-48BB-4587-ADE3-45FE2D2318AC}.Release|x86.Build.0 = Release|x86
21 | EndGlobalSection
22 | GlobalSection(SolutionProperties) = preSolution
23 | HideSolutionNode = FALSE
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/SharpProxy/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.18444
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace SharpProxy.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/SharpProxy/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("SharpProxy")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("James O'Cull")]
12 | [assembly: AssemblyProduct("SharpProxy")]
13 | [assembly: AssemblyCopyright("Copyright © James O'Cull 2011")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("04551f25-ff67-480c-9c96-70d56ef1a4aa")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("0.6.*")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/SharpProxy/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.18444
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace SharpProxy.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SharpProxy.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/SharpProxy/SharpProxy.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | x86
6 | 8.0.30703
7 | 2.0
8 | {AED54322-48BB-4587-ADE3-45FE2D2318AC}
9 | WinExe
10 | Properties
11 | SharpProxy
12 | SharpProxy
13 | v4.0
14 |
15 |
16 | 512
17 | publish\
18 | true
19 | Disk
20 | false
21 | Foreground
22 | 7
23 | Days
24 | false
25 | false
26 | true
27 | 0
28 | 1.0.0.%2a
29 | false
30 | false
31 | true
32 |
33 |
34 | x86
35 | true
36 | full
37 | false
38 | bin\Debug\
39 | DEBUG;TRACE
40 | prompt
41 | 4
42 |
43 |
44 | x86
45 | pdbonly
46 | true
47 | bin\Release\
48 | TRACE
49 | prompt
50 | 4
51 |
52 |
53 | main.ico
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | Form
70 |
71 |
72 | frmMain.cs
73 |
74 |
75 |
76 |
77 |
78 | frmMain.cs
79 |
80 |
81 | ResXFileCodeGenerator
82 | Resources.Designer.cs
83 | Designer
84 |
85 |
86 | True
87 | Resources.resx
88 | True
89 |
90 |
91 |
92 | SettingsSingleFileGenerator
93 | Settings.Designer.cs
94 |
95 |
96 | True
97 | Settings.settings
98 | True
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | False
107 | .NET Framework 3.5 SP1 Client Profile
108 | false
109 |
110 |
111 | False
112 | .NET Framework 3.5 SP1
113 | true
114 |
115 |
116 | False
117 | Windows Installer 3.1
118 | true
119 |
120 |
121 |
122 |
129 |
--------------------------------------------------------------------------------
/SharpProxy/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | text/microsoft-resx
107 |
108 |
109 | 2.0
110 |
111 |
112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
113 |
114 |
115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
--------------------------------------------------------------------------------
/SharpProxy/ProxyThread.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Net.Sockets;
5 | using System.Net;
6 | using System.Threading;
7 | using System.IO;
8 | using System.Linq;
9 | using System.Diagnostics;
10 |
11 | namespace SharpProxy
12 | {
13 | public class ProxyThread
14 | {
15 | public int ExternalPort { get; set; }
16 | public int InternalPort { get; set; }
17 | public bool RewriteHostHeaders { get; set; }
18 | public bool Stopped { get; set; }
19 |
20 | private TcpListener Listener { get; set; }
21 |
22 | private readonly long PROXY_TIMEOUT_TICKS = new TimeSpan(0, 1, 0).Ticks;
23 |
24 | private const string HTTP_SEPARATOR = "\r\n";
25 | private const string HTTP_HEADER_BREAK = HTTP_SEPARATOR + HTTP_SEPARATOR;
26 |
27 | private readonly string[] HTTP_SEPARATORS = new string[] { HTTP_SEPARATOR };
28 | private readonly string[] HTTP_HEADER_BREAKS = new string[] { HTTP_HEADER_BREAK };
29 |
30 | public ProxyThread(int extPort, int intPort, bool rewriteHostHeaders)
31 | {
32 | this.ExternalPort = extPort;
33 | this.InternalPort = intPort;
34 | this.RewriteHostHeaders = rewriteHostHeaders;
35 | this.Stopped = false;
36 | this.Listener = null;
37 |
38 | new Thread(new ThreadStart(Listen)).Start();
39 | }
40 |
41 | public void Stop()
42 | {
43 | Stopped = true;
44 | if (Listener != null)
45 | {
46 | Listener.Stop();
47 | }
48 | }
49 |
50 | protected void Listen()
51 | {
52 | Listener = new TcpListener(new IPEndPoint(IPAddress.Any, this.ExternalPort));
53 | Listener.Start();
54 |
55 | while (!Stopped)
56 | {
57 | try
58 | {
59 | TcpClient client = Listener.AcceptTcpClient();
60 | //Dispatch the thread and continue listening...
61 | new Thread(new ThreadStart(() => Proxy(client))).Start();
62 | }
63 | catch (Exception ex)
64 | {
65 | //TODO: Remove this. Only here to catch breakpoints.
66 | bool failed = true;
67 | }
68 | }
69 | }
70 |
71 | protected void Proxy(object arg)
72 | {
73 | byte[] buffer = new byte[16384];
74 | int clientRead = -1;
75 | int hostRead = -1;
76 |
77 | long lastTime = DateTime.Now.Ticks;
78 |
79 | try
80 | {
81 | //Setup connections
82 | using (TcpClient client = (TcpClient)arg)
83 | using (TcpClient host = new TcpClient())
84 | {
85 | host.Connect(new IPEndPoint(IPAddress.Loopback, this.InternalPort));
86 |
87 | //Setup our streams
88 | using (BinaryReader clientIn = new BinaryReader(client.GetStream()))
89 | using (BinaryWriter clientOut = new BinaryWriter(client.GetStream()))
90 | using (BinaryReader hostIn = new BinaryReader(host.GetStream()))
91 | using (BinaryWriter hostOut = new BinaryWriter(host.GetStream()))
92 | {
93 | //Start funneling data!
94 | while (clientRead != 0 || hostRead != 0 || (DateTime.Now.Ticks - lastTime) <= PROXY_TIMEOUT_TICKS)
95 | {
96 | while (client.Connected && (clientRead = client.Available) > 0)
97 | {
98 | clientRead = clientIn.Read(buffer, 0, buffer.Length);
99 |
100 | //Rewrite the host header?
101 | if (this.RewriteHostHeaders && clientRead > 0)
102 | {
103 | string str = Encoding.UTF8.GetString(buffer, 0, clientRead);
104 |
105 | int startIdx = str.IndexOf(HTTP_SEPARATOR + "Host:");
106 | if (startIdx >= 0)
107 | {
108 | int endIdx = str.IndexOf(HTTP_SEPARATOR, startIdx + 1, str.Length - (startIdx + 1));
109 | if (endIdx > 0)
110 | {
111 | string replace = str.Substring(startIdx, endIdx - startIdx);
112 | string replaceWith = HTTP_SEPARATOR + "Host: localhost:" + InternalPort;
113 |
114 | Trace.WriteLine("Incoming HTTP header:\n\n" + str);
115 |
116 | str = str.Replace(replace, replaceWith);
117 |
118 | Trace.WriteLine("Rewritten HTTP header:\n\n" + str);
119 |
120 | byte[] strBytes = Encoding.UTF8.GetBytes(str);
121 | Array.Clear(buffer, 0, buffer.Length);
122 | Array.Copy(strBytes, buffer, strBytes.Length);
123 | clientRead = strBytes.Length;
124 | }
125 | }
126 | }
127 |
128 | hostOut.Write(buffer, 0, clientRead);
129 | lastTime = DateTime.Now.Ticks;
130 | hostOut.Flush();
131 | }
132 | while (host.Connected && (hostRead = host.Available) > 0)
133 | {
134 | hostRead = hostIn.Read(buffer, 0, buffer.Length);
135 | clientOut.Write(buffer, 0, hostRead);
136 | lastTime = DateTime.Now.Ticks;
137 | clientOut.Flush();
138 | }
139 |
140 | //Sleepy time?
141 | if (this.Stopped)
142 | return;
143 | if (clientRead == 0 && hostRead == 0)
144 | {
145 | Thread.Sleep(100);
146 | }
147 | }
148 |
149 | long waitTime = DateTime.Now.Ticks - lastTime;
150 | }
151 | }
152 | }
153 | catch (Exception ex)
154 | {
155 | //TODO: Remove this. Only here to catch breakpoints.
156 | bool failed = true;
157 | }
158 | }
159 | }
160 | }
--------------------------------------------------------------------------------
/SharpProxy/frmMain.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Drawing;
6 | using System.Text;
7 | using System.Windows.Forms;
8 | using System.Net;
9 | using System.Net.NetworkInformation;
10 | using System.Net.Sockets;
11 | using System.Linq;
12 | using System.IO;
13 |
14 | namespace SharpProxy
15 | {
16 | public partial class frmMain : Form
17 | {
18 | private const int MIN_PORT = 1;
19 | private const int MAX_PORT = 65535;
20 |
21 | public static readonly string CommonDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "SharpProxy");
22 | public static readonly string ConfigInfoPath = Path.Combine(CommonDataPath, "config.txt");
23 |
24 | private ProxyThread ProxyThreadListener = null;
25 |
26 | public frmMain()
27 | {
28 | InitializeComponent();
29 | this.Text += " " + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
30 |
31 | var ips = getLocalIPs().OrderBy(x => x);
32 | if (ips.Any())
33 | {
34 | cmbIPAddress.Items.Clear();
35 | foreach (string ip in ips)
36 | {
37 | cmbIPAddress.Items.Add(ip);
38 | }
39 | cmbIPAddress.Text = cmbIPAddress.Items[0].ToString();
40 | }
41 |
42 | int port = 5000;
43 | while (!checkPortAvailability(port))
44 | {
45 | port++;
46 | }
47 | txtExternalPort.Text = port.ToString();
48 | }
49 |
50 | private void frmMain_Shown(object sender, EventArgs e)
51 | {
52 | txtInternalPort.Focus();
53 |
54 | //Try to load config
55 | try
56 | {
57 | using (StreamReader sr = new StreamReader(ConfigInfoPath))
58 | {
59 | var values = sr.ReadToEnd().Split('\n')
60 | .Select(x => x.Trim())
61 | .ToArray();
62 |
63 | txtInternalPort.Text = values[0];
64 | chkRewriteHostHeaders.Checked = bool.Parse(values[1]);
65 | }
66 | }
67 | catch { }
68 | }
69 |
70 | private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
71 | {
72 | if (ProxyThreadListener != null)
73 | {
74 | ProxyThreadListener.Stop();
75 | }
76 |
77 | //Try to save config
78 | try
79 | {
80 | if (!Directory.Exists(CommonDataPath))
81 | {
82 | Directory.CreateDirectory(CommonDataPath);
83 | }
84 | using (StreamWriter sw = new StreamWriter(ConfigInfoPath))
85 | {
86 | sw.WriteLine(txtInternalPort.Text);
87 | sw.WriteLine(chkRewriteHostHeaders.Checked);
88 | }
89 | }
90 | catch { }
91 | }
92 |
93 | private void btnStart_Click(object sender, EventArgs e)
94 | {
95 | int externalPort = 0;
96 | int internalPort = 0;
97 | //Validation
98 | int.TryParse(txtExternalPort.Text, out externalPort);
99 | int.TryParse(txtInternalPort.Text, out internalPort);
100 | if (!checkPortRange(externalPort)
101 | || !checkPortRange(internalPort)
102 | || externalPort == internalPort)
103 | {
104 | showError("Ports must be between " + MIN_PORT + "-" + MAX_PORT + " and must not be the same.");
105 | return;
106 | }
107 | if (!checkPortAvailability(externalPort))
108 | {
109 | showError("Port " + externalPort + " is not available, please select a different port.");
110 | return;
111 | }
112 |
113 | ProxyThreadListener = new ProxyThread(externalPort, internalPort, chkRewriteHostHeaders.Checked);
114 |
115 | toggleButtons();
116 | }
117 |
118 | private void btnStop_Click(object sender, EventArgs e)
119 | {
120 | ProxyThreadListener.Stop();
121 |
122 | toggleButtons();
123 | }
124 |
125 | private void showError(string msg)
126 | {
127 | MessageBox.Show(msg, "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
128 | }
129 |
130 | private bool checkPortRange(int port)
131 | {
132 | if (port < MIN_PORT || port > MAX_PORT)
133 | return false;
134 | return true;
135 | }
136 |
137 | private List getLocalIPs()
138 | {
139 | //Try to find our internal IP address...
140 | string myHost = System.Net.Dns.GetHostName();
141 | IPAddress[] addresses = System.Net.Dns.GetHostEntry(myHost).AddressList;
142 | List myIPs = new List();
143 | string fallbackIP = "";
144 |
145 | for (int i = 0; i < addresses.Length; i++)
146 | {
147 | //Is this a valid IPv4 address?
148 | if (addresses[i].AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
149 | {
150 | string thisAddress = addresses[i].ToString();
151 | //Loopback is not our preference...
152 | if (thisAddress == "127.0.0.1")
153 | continue;
154 | //169.x.x.x addresses are self-assigned "private network" IP by Windows
155 | if (thisAddress.StartsWith("169"))
156 | {
157 | fallbackIP = thisAddress;
158 | continue;
159 | }
160 | myIPs.Add(thisAddress);
161 | }
162 | }
163 | if (myIPs.Count == 0 && !string.IsNullOrEmpty(fallbackIP))
164 | {
165 | myIPs.Add(fallbackIP);
166 | }
167 |
168 | return myIPs;
169 | }
170 |
171 | private void toggleButtons()
172 | {
173 | btnStop.Enabled = !btnStop.Enabled;
174 | btnStart.Enabled = !btnStart.Enabled;
175 | txtExternalPort.Enabled = !txtExternalPort.Enabled;
176 | txtInternalPort.Enabled = !txtInternalPort.Enabled;
177 | chkRewriteHostHeaders.Enabled = !chkRewriteHostHeaders.Enabled;
178 | }
179 |
180 | private bool checkPortAvailability(int port)
181 | {
182 | //http://stackoverflow.com/questions/570098/in-c-how-to-check-if-a-tcp-port-is-available
183 |
184 | // Evaluate current system tcp connections. This is the same information provided
185 | // by the netstat command line application, just in .Net strongly-typed object
186 | // form. We will look through the list, and if our port we would like to use
187 | // in our TcpClient is occupied, we will set isAvailable to false.
188 | IPGlobalProperties ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties();
189 | TcpConnectionInformation[] tcpConnInfoArray = ipGlobalProperties.GetActiveTcpConnections();
190 |
191 | foreach (TcpConnectionInformation tcpi in tcpConnInfoArray)
192 | {
193 | if (tcpi.LocalEndPoint.Port == port)
194 | return false;
195 | }
196 |
197 | try
198 | {
199 | TcpListener listener = new TcpListener(new IPEndPoint(IPAddress.Any, port));
200 | listener.Start();
201 | listener.Stop();
202 | }
203 | catch (Exception)
204 | {
205 | return false;
206 | }
207 |
208 | return true;
209 | }
210 |
211 | private void txtPorts_KeyPress(object sender, KeyPressEventArgs e)
212 | {
213 | if (e.KeyChar == (char)Keys.Enter)
214 | {
215 | btnStart_Click(null, null);
216 | }
217 | }
218 | }
219 | }
220 |
--------------------------------------------------------------------------------
/SharpProxy/frmMain.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace SharpProxy
2 | {
3 | partial class frmMain
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(frmMain));
32 | this.btnStart = new System.Windows.Forms.Button();
33 | this.btnStop = new System.Windows.Forms.Button();
34 | this.label1 = new System.Windows.Forms.Label();
35 | this.txtExternalPort = new System.Windows.Forms.TextBox();
36 | this.txtInternalPort = new System.Windows.Forms.TextBox();
37 | this.label2 = new System.Windows.Forms.Label();
38 | this.label3 = new System.Windows.Forms.Label();
39 | this.cmbIPAddress = new System.Windows.Forms.ComboBox();
40 | this.chkRewriteHostHeaders = new System.Windows.Forms.CheckBox();
41 | this.SuspendLayout();
42 | //
43 | // btnStart
44 | //
45 | this.btnStart.Location = new System.Drawing.Point(11, 154);
46 | this.btnStart.Name = "btnStart";
47 | this.btnStart.Size = new System.Drawing.Size(75, 23);
48 | this.btnStart.TabIndex = 0;
49 | this.btnStart.Text = "&Start";
50 | this.btnStart.UseVisualStyleBackColor = true;
51 | this.btnStart.Click += new System.EventHandler(this.btnStart_Click);
52 | //
53 | // btnStop
54 | //
55 | this.btnStop.Enabled = false;
56 | this.btnStop.Location = new System.Drawing.Point(125, 154);
57 | this.btnStop.Name = "btnStop";
58 | this.btnStop.Size = new System.Drawing.Size(75, 23);
59 | this.btnStop.TabIndex = 1;
60 | this.btnStop.Text = "S&top";
61 | this.btnStop.UseVisualStyleBackColor = true;
62 | this.btnStop.Click += new System.EventHandler(this.btnStop_Click);
63 | //
64 | // label1
65 | //
66 | this.label1.AutoSize = true;
67 | this.label1.Location = new System.Drawing.Point(12, 49);
68 | this.label1.Name = "label1";
69 | this.label1.Size = new System.Drawing.Size(67, 13);
70 | this.label1.TabIndex = 2;
71 | this.label1.Text = "External Port";
72 | //
73 | // txtExternalPort
74 | //
75 | this.txtExternalPort.Location = new System.Drawing.Point(11, 65);
76 | this.txtExternalPort.MaxLength = 7;
77 | this.txtExternalPort.Name = "txtExternalPort";
78 | this.txtExternalPort.Size = new System.Drawing.Size(189, 20);
79 | this.txtExternalPort.TabIndex = 3;
80 | this.txtExternalPort.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.txtPorts_KeyPress);
81 | //
82 | // txtInternalPort
83 | //
84 | this.txtInternalPort.Location = new System.Drawing.Point(11, 104);
85 | this.txtInternalPort.MaxLength = 7;
86 | this.txtInternalPort.Name = "txtInternalPort";
87 | this.txtInternalPort.Size = new System.Drawing.Size(189, 20);
88 | this.txtInternalPort.TabIndex = 5;
89 | this.txtInternalPort.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.txtPorts_KeyPress);
90 | //
91 | // label2
92 | //
93 | this.label2.AutoSize = true;
94 | this.label2.Location = new System.Drawing.Point(12, 88);
95 | this.label2.Name = "label2";
96 | this.label2.Size = new System.Drawing.Size(64, 13);
97 | this.label2.TabIndex = 4;
98 | this.label2.Text = "Internal Port";
99 | //
100 | // label3
101 | //
102 | this.label3.AutoSize = true;
103 | this.label3.Location = new System.Drawing.Point(12, 9);
104 | this.label3.Name = "label3";
105 | this.label3.Size = new System.Drawing.Size(83, 13);
106 | this.label3.TabIndex = 6;
107 | this.label3.Text = "Your IP Address";
108 | //
109 | // cmbIPAddress
110 | //
111 | this.cmbIPAddress.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
112 | this.cmbIPAddress.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
113 | this.cmbIPAddress.FormattingEnabled = true;
114 | this.cmbIPAddress.Location = new System.Drawing.Point(11, 25);
115 | this.cmbIPAddress.Name = "cmbIPAddress";
116 | this.cmbIPAddress.Size = new System.Drawing.Size(189, 21);
117 | this.cmbIPAddress.TabIndex = 8;
118 | //
119 | // chkRewriteHostHeaders
120 | //
121 | this.chkRewriteHostHeaders.AutoSize = true;
122 | this.chkRewriteHostHeaders.Checked = true;
123 | this.chkRewriteHostHeaders.CheckState = System.Windows.Forms.CheckState.Checked;
124 | this.chkRewriteHostHeaders.Location = new System.Drawing.Point(13, 131);
125 | this.chkRewriteHostHeaders.Name = "chkRewriteHostHeaders";
126 | this.chkRewriteHostHeaders.Size = new System.Drawing.Size(188, 17);
127 | this.chkRewriteHostHeaders.TabIndex = 9;
128 | this.chkRewriteHostHeaders.Text = "&Rewrite host headers (IIS Express)";
129 | this.chkRewriteHostHeaders.UseVisualStyleBackColor = true;
130 | //
131 | // frmMain
132 | //
133 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
134 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
135 | this.ClientSize = new System.Drawing.Size(212, 185);
136 | this.Controls.Add(this.chkRewriteHostHeaders);
137 | this.Controls.Add(this.cmbIPAddress);
138 | this.Controls.Add(this.label3);
139 | this.Controls.Add(this.txtInternalPort);
140 | this.Controls.Add(this.label2);
141 | this.Controls.Add(this.txtExternalPort);
142 | this.Controls.Add(this.label1);
143 | this.Controls.Add(this.btnStop);
144 | this.Controls.Add(this.btnStart);
145 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
146 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
147 | this.MaximizeBox = false;
148 | this.Name = "frmMain";
149 | this.Text = "SharpProxy";
150 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.frmMain_FormClosing);
151 | this.Shown += new System.EventHandler(this.frmMain_Shown);
152 | this.ResumeLayout(false);
153 | this.PerformLayout();
154 |
155 | }
156 |
157 | #endregion
158 |
159 | private System.Windows.Forms.Button btnStart;
160 | private System.Windows.Forms.Button btnStop;
161 | private System.Windows.Forms.Label label1;
162 | private System.Windows.Forms.TextBox txtExternalPort;
163 | private System.Windows.Forms.TextBox txtInternalPort;
164 | private System.Windows.Forms.Label label2;
165 | private System.Windows.Forms.Label label3;
166 | private System.Windows.Forms.ComboBox cmbIPAddress;
167 | private System.Windows.Forms.CheckBox chkRewriteHostHeaders;
168 | }
169 | }
170 |
171 |
--------------------------------------------------------------------------------
/SharpProxy/frmMain.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 |
122 |
123 | AAABAAQAEBAQAAEABAAoAQAARgAAACAgEAABAAQA6AIAAG4BAAAwMBAAAQAEAGgGAABWBAAAQEAQAAEA
124 | BABoCgAAvgoAACgAAAAQAAAAIAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA
125 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
126 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEQAAAAAREREREQAAABER
127 | ERERAAAAAAAAEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
128 | AAD+/wAA/v8AAP4/AAD+vwAA/j8AAP//AAD8HwAAAAAAAAAAAAD8HwAA//8AAP4/AAD/vwAA/j8AAP7/
129 | AAD+PwAAKAAAACAAAABAAAAAAQAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAAAAAAA
130 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
131 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
132 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
133 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
134 | AAAAAAAAAAAREQAAAAAAAAAAAAAAAAAAEREAAAAAAAAAABEREREREREREREAAAAAAAARERERERERERER
135 | AAAAAAAAEREREREREREREQAAAAAAABEREREREREREREAAAAAAAAAAAAAAAAREQAAAAAAAAAAAAAAAAAA
136 | EREAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
137 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
138 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
139 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/8/////P////z////8/////A////wP///8z////M////wP///8
140 | D//////////////wA///8AP/AAAAAAAAAAAAAAAAAAAAAP/wA///8AP//////////////A////wP////
141 | z////8////wP///8D////P////z////8D////A//KAAAADAAAABgAAAAAQAEAAAAAAAAAAAAAAAAAAAA
142 | AAAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
143 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
144 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
145 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
146 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
147 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
148 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
149 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
150 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAREREAAAAAAAAAAAAAAAAAAAAAAAAAAAAR
151 | EREAAAAAAAAAAAAAAAAAAAAAAAAAAAAREREAAAAAAAAAAAAAAAAREREREREREREREREREREAAAAAAAAA
152 | AAAREREREREREREREREREREAAAAAAAAAAAAREREREREREREREREREREAAAAAAAAAAAARERERERERERER
153 | EREREREAAAAAAAAAAAAREREREREREREREREREREAAAAAAAAAAAAREREREREREREREREREREAAAAAAAAA
154 | AAAAAAAAAAAAAAAREREAAAAAAAAAAAAAAAAAAAAAAAAAAAAREREAAAAAAAAAAAAAAAAAAAAAAAAAAAAR
155 | EREAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
156 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
157 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
158 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
159 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
160 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
161 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
162 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///j///8AAP//+P///wAA///4////AAD///j///8AAP//
163 | +P///wAA///4////AAD///gD//8AAP//+AP//wAA///4A///AAD///jj//8AAP//+OP//wAA///44///
164 | AAD///gD//8AAP//+AP//wAA///4A///AAD///////8AAP///////wAA////////AAD//8AAf/8AAP//
165 | wAB//wAA///AAH//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
166 | AAD//8AAf/8AAP//wAB//wAA///AAH//AAD///////8AAP///////wAA////////AAD///gD//8AAP//
167 | +AP//wAA///4A///AAD////j//8AAP///+P//wAA////4///AAD///gD//8AAP//+AP//wAA///4A///
168 | AAD///j///8AAP//+P///wAA///4////AAD///gD//8AAP//+AP//wAA///4A///AAAoAAAAQAAAAIAA
169 | AAABAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
170 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
171 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
172 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
173 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
174 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
175 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
176 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
177 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
178 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
179 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
180 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
181 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
182 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
183 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEREREAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
184 | AAAAAAAAEREREQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARERERAAAAAAAAAAAAAAAAAAAAAAAA
185 | AAAAAAAAAAAAABEREREAAAAAAAAAAAAAAAAAAAAAEREREREREREREREREREREREREREAAAAAAAAAAAAA
186 | AAAREREREREREREREREREREREREREQAAAAAAAAAAAAAAABERERERERERERERERERERERERERAAAAAAAA
187 | AAAAAAAAEREREREREREREREREREREREREREAAAAAAAAAAAAAAAAREREREREREREREREREREREREREQAA
188 | AAAAAAAAAAAAABERERERERERERERERERERERERERAAAAAAAAAAAAAAAAERERERERERERERERERERERER
189 | EREAAAAAAAAAAAAAAAAREREREREREREREREREREREREREQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABER
190 | EREAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEREREQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
191 | AAARERERAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEREREAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
192 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
193 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
194 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
195 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
196 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
197 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
198 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
199 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
200 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
201 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
202 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
203 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
204 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////8P/////////w////////
205 | //D/////////8P/////////w//////////D/////////8P/////////w//////////AA////////8AD/
206 | ///////wAP////////AA////////8PD////////w8P////////Dw////////8PD////////wAP//////
207 | //AA////////8AD////////wAP//////////////////////////////////////////////////AAAP
208 | //////8AAA///////wAAD///////AAAP//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
209 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AAAP//////8AAA///////wAAD///////AAAP
210 | //////////////////////////////////////////////////AA////////8AD////////wAP//////
211 | //AA//////////D/////////8P/////////w//////////D////////wAP////////AA////////8AD/
212 | ///////wAP////////D/////////8P/////////w//////////D/////////8AD////////wAP//////
213 | //AA////////8AD///8=
214 |
215 |
216 |
--------------------------------------------------------------------------------