OSDN Git Service

Dispose不要のメソッドにSuppressMessage属性を追加 (CA2000)
[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.Diagnostics.CodeAnalysis;
25 using System.Linq;
26 using System.Net;
27 using System.Net.Http;
28 using System.Text;
29 using System.Threading;
30 using System.Threading.Tasks;
31
32 namespace OpenTween.Connection
33 {
34     public static class Networking
35     {
36         public static TimeSpan DefaultTimeout { get; set; }
37
38         /// <summary>
39         /// 通信に使用するプロキシの種類
40         /// </summary>
41         public static ProxyType ProxyType
42         {
43             get { return proxyType; }
44         }
45
46         /// <summary>
47         /// 通信に使用するプロキシ
48         /// </summary>
49         public static IWebProxy Proxy
50         {
51             get { return proxy; }
52         }
53
54         /// <summary>
55         /// OpenTween 内で共通して使用する HttpClient インスタンス
56         /// </summary>
57         public static HttpClient Http
58         {
59             get { return globalHttpClient; }
60         }
61
62         /// <summary>
63         /// Webプロキシの設定が変更された場合に発生します
64         /// </summary>
65         public static event EventHandler WebProxyChanged;
66
67         private static bool initialized = false;
68         private static HttpClient globalHttpClient;
69         private static ProxyType proxyType = ProxyType.IE;
70         private static IWebProxy proxy = null;
71
72         [SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope")]
73         static Networking()
74         {
75             DefaultTimeout = TimeSpan.FromSeconds(20);
76             globalHttpClient = CreateHttpClient(new HttpClientHandler());
77         }
78
79         /// <summary>
80         /// ネットワーク接続前に行う処理。起動時に一回だけ実行する必要があります。
81         /// </summary>
82         public static void Initialize()
83         {
84             Networking.initialized = true;
85
86             ServicePointManager.Expect100Continue = false;
87         }
88
89         public static void SetWebProxy(ProxyType proxyType, string proxyAddress, int proxyPort,
90             string proxyUser, string proxyPassword)
91         {
92             IWebProxy proxy;
93             switch (proxyType)
94             {
95                 case ProxyType.None:
96                     proxy = null;
97                     break;
98                 case ProxyType.Specified:
99                     proxy = new WebProxy(proxyAddress, proxyPort);
100                     if (!string.IsNullOrEmpty(proxyUser) || !string.IsNullOrEmpty(proxyPassword))
101                         proxy.Credentials = new NetworkCredential(proxyUser, proxyPassword);
102                     break;
103                 case ProxyType.IE:
104                 default:
105                     proxy = WebRequest.GetSystemWebProxy();
106                     break;
107             }
108
109             Networking.proxyType = proxyType;
110             Networking.proxy = proxy;
111
112             NativeMethods.SetProxy(proxyType, proxyAddress, proxyPort, proxyUser, proxyPassword);
113
114             OnWebProxyChanged(EventArgs.Empty);
115         }
116
117         /// <summary>
118         /// プロキシ等の設定を施した HttpClient インスタンスを生成します
119         /// </summary>
120         /// <remarks>
121         /// 通常は Networking.Http を使用すべきです。
122         /// このメソッドを使用する場合は、WebProxyChanged イベントが発生する度に HttpClient を生成し直すように実装してください。
123         /// </remarks>
124         [SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope")]
125         public static HttpClient CreateHttpClient(HttpClientHandler handler)
126         {
127             if (Networking.Proxy != null)
128             {
129                 handler.UseProxy = true;
130                 handler.Proxy = Networking.Proxy;
131             }
132             else
133             {
134                 handler.UseProxy = false;
135             }
136
137             var client = new HttpClient(handler);
138             client.Timeout = Networking.DefaultTimeout;
139             client.DefaultRequestHeaders.Add("User-Agent", Networking.GetUserAgentString());
140
141             return client;
142         }
143
144         public static string GetUserAgentString(bool fakeMSIE = false)
145         {
146             if (fakeMSIE)
147                 return MyCommon.GetAssemblyName() + "/" + MyCommon.FileVersion + " (compatible; MSIE 10.0)";
148             else
149                 return MyCommon.GetAssemblyName() + "/" + MyCommon.FileVersion;
150         }
151
152         /// <summary>
153         /// Initialize() メソッドが事前に呼ばれているか確認します
154         /// </summary>
155         internal static void CheckInitialized()
156         {
157             if (!Networking.initialized)
158                 throw new InvalidOperationException("Sequence error.(not initialized)");
159         }
160
161         [SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope")]
162         private static void OnWebProxyChanged(EventArgs e)
163         {
164             var newClient = Networking.CreateHttpClient(new HttpClientHandler());
165             var oldClient = Interlocked.Exchange(ref globalHttpClient, newClient);
166             oldClient.Dispose();
167
168             if (WebProxyChanged != null)
169                 WebProxyChanged(null, e);
170         }
171     }
172
173     public enum ProxyType
174     {
175         None,
176         IE,
177         Specified,
178     }
179 }