1 // Copyright (C) 2017 Kazuhiro Fujieda <fujieda@users.osdn.me>
\r
3 // Licensed under the Apache License, Version 2.0 (the "License");
\r
4 // you may not use this file except in compliance with the License.
\r
5 // You may obtain a copy of the License at
\r
7 // http://www.apache.org/licenses/LICENSE-2.0
\r
9 // Unless required by applicable law or agreed to in writing, software
\r
10 // distributed under the License is distributed on an "AS IS" BASIS,
\r
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
12 // See the License for the specific language governing permissions and
\r
13 // limitations under the License.
\r
18 using System.Net.Sockets;
\r
19 using System.Threading;
\r
20 using System.Threading.Tasks;
\r
21 using System.Windows.Forms;
\r
22 using Microsoft.Win32;
\r
24 namespace KancolleSniffer
\r
26 public class ProxyManager
\r
28 private readonly Config _config;
\r
29 private readonly Control _parent;
\r
30 private readonly SystemProxy _systemProxy = new SystemProxy();
\r
31 private int _prevProxyPort;
\r
33 public ProxyManager(Config config, Control parent)
\r
37 SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
\r
40 public bool ApplyConfig()
\r
42 if (!_config.Proxy.Auto)
\r
43 RestoreSystemProxy();
\r
44 if (_config.Proxy.UseUpstream)
\r
46 HttpProxy.UpstreamProxyHost = "127.0.0.1";
\r
47 HttpProxy.UpstreamProxyPort = _config.Proxy.UpstreamPort;
\r
49 HttpProxy.IsEnableUpstreamProxy = _config.Proxy.UseUpstream;
\r
51 if (!HttpProxy.IsInListening || _config.Proxy.Listen != _prevProxyPort)
\r
54 result = StartProxy();
\r
56 if (_config.Proxy.Auto && result)
\r
60 _prevProxyPort = _config.Proxy.Listen;
\r
64 private bool StartProxy()
\r
68 HttpProxy.Startup(_config.Proxy.Listen, false, false);
\r
70 catch (SocketException e)
\r
72 if (e.SocketErrorCode != SocketError.AddressAlreadyInUse &&
\r
73 e.SocketErrorCode != SocketError.AccessDenied)
\r
77 if (WarnConflictPortNumber("プロキシサーバー", _config.Proxy.Listen, _config.Proxy.Auto) == DialogResult.No ||
\r
78 !_config.Proxy.Auto)
\r
80 RestoreSystemProxy();
\r
83 HttpProxy.Startup(0, false, false);
\r
84 _config.Proxy.Listen = HttpProxy.LocalPort;
\r
89 private DialogResult WarnConflictPortNumber(string name, int port, bool auto)
\r
91 var msg = $"{name}のポート番号{port}は他のアプリケーションが使用中です。";
\r
92 var cap = "ポート番号の衝突";
\r
94 ? MessageBox.Show(_parent, msg + "自動的に別の番号を割り当てますか?", cap,
\r
95 MessageBoxButtons.YesNo, MessageBoxIcon.Question)
\r
96 : MessageBox.Show(_parent, msg + "設定ダイアログでポート番号を変更してください。", cap,
\r
97 MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
\r
100 private void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)
\r
102 if (e.Mode != PowerModes.Resume || !_config.Proxy.Auto)
\r
106 for (var i = 0; i < 5; i++, Thread.Sleep(15000))
\r
107 SystemProxy.Refresh();
\r
111 public void Shutdown()
\r
113 Task.Run(() => ShutdownProxy());
\r
114 if (_config.Proxy.Auto)
\r
115 RestoreSystemProxy();
\r
116 SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged;
\r
119 private void ShutdownProxy()
\r
121 HttpProxy.Shutdown();
\r
124 private readonly AutoResetEvent _stopEvent = new AutoResetEvent(false);
\r
125 private Task _checkerTask;
\r
127 private void SetAutoProxyUrl()
\r
129 var url = $"http://localhost:{_config.Proxy.Listen}/proxy.pac";
\r
130 _systemProxy.SetAutoProxyUrl(url);
\r
131 if (_checkerTask != null && !_checkerTask.IsCompleted)
\r
133 _checkerTask = Task.Run(() =>
\r
135 // Windows 10でプロキシ設定がいつの間にか消えるのに対応するために、
\r
136 // 設定が消えていないか毎秒確認して、消えていたら再設定する。
\r
139 var proxy = WebRequest.GetSystemWebProxy().GetProxy(new Uri("http://125.6.184.16/"));
\r
140 if (!proxy.IsLoopback)
\r
142 File.AppendAllText("proxy.log", $"[{DateTime.Now:g}] proxy setting vanished.\r\n");
\r
143 _systemProxy.SetAutoProxyUrl(url);
\r
145 } while (!_stopEvent.WaitOne(1000));
\r
149 private void RestoreSystemProxy()
\r
151 if (_checkerTask != null && !_checkerTask.IsCompleted)
\r
154 _checkerTask.Wait();
\r
156 _systemProxy.RestoreSettings();
\r