OSDN Git Service

HTTPプロキシでHTTPSをサポートする
authorKazuhiro Fujieda <fujieda@users.osdn.me>
Sat, 2 Jan 2016 11:18:11 +0000 (20:18 +0900)
committerKazuhiro Fujieda <fujieda@users.osdn.me>
Mon, 4 Jan 2016 13:31:25 +0000 (22:31 +0900)
KancolleSniffer/HttpProxy.cs

index 7a0f4eb..26647b4 100644 (file)
@@ -103,6 +103,11 @@ namespace KancolleSniffer
                 try\r
                 {\r
                     ReceiveRequest();\r
+                    if (_session.Request.Method == "CONNECT")\r
+                    {\r
+                        HandleConnect();\r
+                        return;\r
+                    }\r
                     SendRequest();\r
                     ReceiveResponse();\r
                     SendResponse();\r
@@ -165,6 +170,44 @@ namespace KancolleSniffer
                     .Write(_session.Response.Body);\r
             }\r
 \r
+            private void HandleConnect()\r
+            {\r
+                var host = "";\r
+                var port = 443;\r
+                if (!ParseAuthority(_session.Request.PathAndQuery, ref host, ref port))\r
+                    return;\r
+                _server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);\r
+                _server.Connect(host, port);\r
+                _clientStream.WriteLines("HTTP/1.0 200 Connection established\r\n\r\n");\r
+                Task[] tasks =\r
+                {\r
+                    Task.Run(() => { TunnnelSockets(_client, _server); }),\r
+                    Task.Run(() => { TunnnelSockets(_server, _client); })\r
+                };\r
+                Task.WaitAll(tasks);\r
+            }\r
+\r
+            private void TunnnelSockets(Socket from, Socket to)\r
+            {\r
+                try\r
+                {\r
+                    var buf = new byte[8192];\r
+                    while (true)\r
+                    {\r
+                        var n = from.Receive(buf);\r
+                        if (n == 0)\r
+                            break;\r
+                        var sent = to.Send(buf, n, SocketFlags.None);\r
+                        if (sent < n)\r
+                            break;\r
+                    }\r
+                    to.Shutdown(SocketShutdown.Send);\r
+                }\r
+                catch (SocketException)\r
+                {\r
+                }\r
+            }\r
+\r
             private static readonly Regex HostAndPortRegex =\r
                 new Regex("http://([^:/]+)(?::(\\d+))?/", RegexOptions.Compiled);\r
 \r
@@ -376,7 +419,8 @@ namespace KancolleSniffer
             private string _statusLine;\r
 \r
             public override string ModifiedHeaders =>\r
-                InsertContentLength(RemoveHeaders(base.ModifiedHeaders, new [] {"transfer-encoding", "content-encoding", "content-length"}));\r
+                InsertContentLength(RemoveHeaders(base.ModifiedHeaders,\r
+                    new[] {"transfer-encoding", "content-encoding", "content-length"}));\r
 \r
             private string InsertContentLength(string headers)\r
             {\r