OSDN Git Service

HttpConnectionクラスにある通信設定の初期化などの処理をNetworkingクラスに移動
[opentween/open-tween.git] / OpenTween / Connection / Networking.cs
1 // OpenTween - Client of Twitter
2 // Copyright (c) 2014 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
3 // All rights reserved.
4 //
5 // This file is part of OpenTween.
6 //
7 // This program is free software; you can redistribute it and/or modify it
8 // under the terms of the GNU General Public License as published by the Free
9 // Software Foundation; either version 3 of the License, or (at your option)
10 // any later version.
11 //
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 // for more details.
16 //
17 // You should have received a copy of the GNU General Public License along
18 // with this program. If not, see <http://www.gnu.org/licenses/>, or write to
19 // the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
20 // Boston, MA 02110-1301, USA.
21
22 using System;
23 using System.Collections.Generic;
24 using System.Linq;
25 using System.Net;
26 using System.Net.Http;
27 using System.Text;
28 using System.Threading;
29 using System.Threading.Tasks;
30
31 namespace OpenTween.Connection
32 {
33     public static class Networking
34     {
35         public static TimeSpan DefaultTimeout { get; set; }
36
37         /// <summary>
38         /// 通信に使用するプロキシの種類
39         /// </summary>
40         public static ProxyType ProxyType
41         {
42             get { return proxyType; }
43         }
44
45         /// <summary>
46         /// 通信に使用するプロキシ
47         /// </summary>
48         public static IWebProxy Proxy
49         {
50             get { return proxy; }
51         }
52
53         /// <summary>
54         /// OpenTween 内で共通して使用する HttpClient インスタンス
55         /// </summary>
56         public static HttpClient Http
57         {
58             get { return globalHttpClient; }
59         }
60
61         /// <summary>
62         /// Webプロキシの設定が変更された場合に発生します
63         /// </summary>
64         public static event EventHandler WebProxyChanged;
65
66         private static bool initialized = false;
67         private static HttpClient globalHttpClient;
68         private static ProxyType proxyType = ProxyType.IE;
69         private static IWebProxy proxy = null;
70
71         static Networking()
72         {
73             DefaultTimeout = TimeSpan.FromSeconds(20);
74             globalHttpClient = CreateHttpClient(new HttpClientHandler());
75         }
76
77         /// <summary>
78         /// ネットワーク接続前に行う処理。起動時に一回だけ実行する必要があります。
79         /// </summary>
80         public static void Initialize()
81         {
82             Networking.initialized = true;
83
84             ServicePointManager.Expect100Continue = false;
85         }
86
87         public static void SetWebProxy(ProxyType proxyType, string proxyAddress, int proxyPort,
88             string proxyUser, string proxyPassword)
89         {
90             IWebProxy proxy;
91             switch (proxyType)
92             {
93                 case ProxyType.None:
94                     proxy = null;
95                     break;
96                 case ProxyType.Specified:
97                     proxy = new WebProxy(proxyAddress, proxyPort);
98                     if (!string.IsNullOrEmpty(proxyUser) || !string.IsNullOrEmpty(proxyPassword))
99                         proxy.Credentials = new NetworkCredential(proxyUser, proxyPassword);
100                     break;
101                 case ProxyType.IE:
102                 default:
103                     proxy = WebRequest.GetSystemWebProxy();
104                     break;
105             }
106
107             Networking.proxyType = proxyType;
108             Networking.proxy = proxy;
109
110             Win32Api.SetProxy(proxyType, proxyAddress, proxyPort, proxyUser, proxyPassword);
111
112             OnWebProxyChanged(EventArgs.Empty);
113         }
114
115         /// <summary>
116         /// プロキシ等の設定を施した HttpClient インスタンスを生成します
117         /// </summary>
118         /// <remarks>
119         /// 通常は Networking.Http を使用すべきです。
120         /// このメソッドを使用する場合は、WebProxyChanged イベントが発生する度に HttpClient を生成し直すように実装してください。
121         /// </remarks>
122         public static HttpClient CreateHttpClient(HttpClientHandler handler)
123         {
124             if (Networking.Proxy != null)
125             {
126                 handler.UseProxy = true;
127                 handler.Proxy = Networking.Proxy;
128             }
129             else
130             {
131                 handler.UseProxy = false;
132             }
133
134             var client = new HttpClient(handler);
135             client.Timeout = Networking.DefaultTimeout;
136             client.DefaultRequestHeaders.Add("User-Agent", Networking.GetUserAgentString());
137
138             return client;
139         }
140
141         public static string GetUserAgentString(bool fakeMSIE = false)
142         {
143             if (fakeMSIE)
144                 return MyCommon.GetAssemblyName() + "/" + MyCommon.FileVersion + " (compatible; MSIE 10.0)";
145             else
146                 return MyCommon.GetAssemblyName() + "/" + MyCommon.FileVersion;
147         }
148
149         /// <summary>
150         /// Initialize() メソッドが事前に呼ばれているか確認します
151         /// </summary>
152         internal static void CheckInitialized()
153         {
154             if (!Networking.initialized)
155                 throw new InvalidOperationException("Sequence error.(not initialized)");
156         }
157
158         private static void OnWebProxyChanged(EventArgs e)
159         {
160             var newClient = Networking.CreateHttpClient(new HttpClientHandler());
161             var oldClient = Interlocked.Exchange(ref globalHttpClient, newClient);
162             oldClient.Dispose();
163
164             if (WebProxyChanged != null)
165                 WebProxyChanged(null, e);
166         }
167     }
168
169     public enum ProxyType
170     {
171         None,
172         IE,
173         Specified,
174     }
175 }