OSDN Git Service

未読ジャンプで中途半端な位置にジャンプする問題に対処したつもり
[opentween/open-tween.git] / Tween / Connection / HttpConnectionBasic.vb
1 ' Tween - Client of Twitter
2 ' Copyright (c) 2007-2011 kiri_feather (@kiri_feather) <kiri.feather@gmail.com>
3 '           (c) 2008-2011 Moz (@syo68k)
4 '           (c) 2008-2011 takeshik (@takeshik) <http://www.takeshik.org/>
5 '           (c) 2010-2011 anis774 (@anis774) <http://d.hatena.ne.jp/anis774/>
6 '           (c) 2010-2011 fantasticswallow (@f_swallow) <http://twitter.com/f_swallow>
7 ' All rights reserved.
8
9 ' This file is part of Tween.
10
11 ' This program is free software; you can redistribute it and/or modify it
12 ' under the terms of the GNU General Public License as published by the Free
13 ' Software Foundation; either version 3 of the License, or (at your option)
14 ' any later version.
15
16 ' This program is distributed in the hope that it will be useful, but
17 ' WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18 ' or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 ' for more details. 
20
21 ' You should have received a copy of the GNU General Public License along
22 ' with this program. If not, see <http://www.gnu.org/licenses/>, or write to
23 ' the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
24 ' Boston, MA 02110-1301, USA.
25
26 Imports System.Text
27 Imports System.Net
28 Imports System.IO
29 Imports System.Diagnostics
30
31 '''<summary>
32 '''BASIC認証を使用するHTTP通信
33 '''</summary>
34 '''<remarks>
35 '''使用前にユーザー/パスワードを設定する。認証確認を伴う場合はAuthenticateを、認証不要な場合はInitializeを呼ぶこと。
36 '''</remarks>
37 Public Class HttpConnectionBasic
38     Inherits HttpConnection
39     Implements IHttpConnection
40
41     '''<summary>
42     '''認証用ユーザー名
43     '''</summary>
44     Private _userName As String = ""
45     '''<summary>
46     '''認証用パスワード
47     '''</summary>
48     Private _password As String = ""
49     '''<summary>
50     '''Authorizationヘッダに設定するエンコード済み文字列
51     '''</summary>
52     Private credential As String = ""
53
54
55     '''<summary>
56     '''認証完了時の応答からuserIdentKey情報に基づいて取得するユーザー情報
57     '''</summary>
58     Private streamReq As HttpWebRequest = Nothing
59
60     '''<summary>
61     '''BASIC認証で指定のURLとHTTP通信を行い、結果を返す
62     '''</summary>
63     '''<param name="method">HTTP通信メソッド(GET/HEAD/POST/PUT/DELETE)</param>
64     '''<param name="requestUri">通信先URI</param>
65     '''<param name="param">GET時のクエリ、またはPOST時のエンティティボディ</param>
66     '''<param name="content">[OUT]HTTP応答のボディデータ</param>
67     '''<param name="headerInfo">[IN/OUT]HTTP応答のヘッダ情報。必要なヘッダ名を事前に設定しておくこと</param>
68     '''<param name="callback">処理終了直前に呼ばれるコールバック関数のデリゲート 不要な場合はNothingを渡すこと</param>
69     '''<returns>HTTP応答のステータスコード</returns>
70     Public Function GetContent(ByVal method As String, _
71             ByVal requestUri As Uri, _
72             ByVal param As Dictionary(Of String, String), _
73             ByRef content As String, _
74             ByVal headerInfo As Dictionary(Of String, String), _
75             ByVal callback As IHttpConnection.CallbackDelegate) As HttpStatusCode Implements IHttpConnection.GetContent
76
77         '認証済かチェック
78         If String.IsNullOrEmpty(Me.credential) Then Return HttpStatusCode.Unauthorized
79
80         Dim webReq As HttpWebRequest = CreateRequest(method, _
81                                                     requestUri, _
82                                                     param, _
83                                                     False)
84         'BASIC認証用ヘッダを付加
85         AppendApiInfo(webReq)
86
87         Dim code As HttpStatusCode
88         If content Is Nothing Then
89             code = GetResponse(webReq, headerInfo, False)
90         Else
91             code = GetResponse(webReq, content, headerInfo, False)
92         End If
93         If callback IsNot Nothing Then
94             Dim frame As New StackFrame(1)
95             callback(frame.GetMethod.Name, code, content)
96         End If
97         Return code
98     End Function
99
100     Public Function GetContent(ByVal method As String, _
101             ByVal requestUri As Uri, _
102             ByVal param As Dictionary(Of String, String), _
103             ByVal binary As List(Of KeyValuePair(Of String, FileInfo)), _
104             ByRef content As String, _
105             ByVal headerInfo As Dictionary(Of String, String), _
106             ByVal callback As IHttpConnection.CallbackDelegate) As HttpStatusCode Implements IHttpConnection.GetContent
107
108         '認証済かチェック
109         If String.IsNullOrEmpty(Me.credential) Then Return HttpStatusCode.Unauthorized
110
111         Dim webReq As HttpWebRequest = CreateRequest(method, _
112                                                     requestUri, _
113                                                     param, _
114                                                     binary, _
115                                                     False)
116         'BASIC認証用ヘッダを付加
117         AppendApiInfo(webReq)
118
119         Dim code As HttpStatusCode
120         If content Is Nothing Then
121             code = GetResponse(webReq, headerInfo, False)
122         Else
123             code = GetResponse(webReq, content, headerInfo, False)
124         End If
125         If callback IsNot Nothing Then
126             Dim frame As New StackFrame(1)
127             callback(frame.GetMethod.Name, code, content)
128         End If
129         Return code
130     End Function
131
132     '''<summary>
133     '''OAuth認証で指定のURLとHTTP通信を行い、ストリームを返す
134     '''</summary>
135     '''<param name="method">HTTP通信メソッド(GET/HEAD/POST/PUT/DELETE)</param>
136     '''<param name="requestUri">通信先URI</param>
137     '''<param name="param">GET時のクエリ、またはPOST時のエンティティボディ</param>
138     '''<param name="content">[OUT]HTTP応答のボディストリーム</param>
139     '''<param name="headerInfo">[IN/OUT]HTTP応答のヘッダ情報。必要なヘッダ名を事前に設定しておくこと</param>
140     '''<returns>HTTP応答のステータスコード</returns>
141     Public Function GetContent(ByVal method As String, _
142             ByVal requestUri As Uri, _
143             ByVal param As Dictionary(Of String, String), _
144             ByRef content As Stream,
145             ByVal userAgent As String) As HttpStatusCode Implements IHttpConnection.GetContent
146         '認証済かチェック
147         If String.IsNullOrEmpty(Me.credential) Then Return HttpStatusCode.Unauthorized
148
149         streamReq = CreateRequest(method, requestUri, param, False)
150         'User-Agent指定がある場合は付加
151         If Not String.IsNullOrEmpty(userAgent) Then streamReq.UserAgent = userAgent
152
153         'BASIC認証用ヘッダを付加
154         AppendApiInfo(streamReq)
155
156         Try
157             Dim webRes As HttpWebResponse = CType(streamReq.GetResponse(), HttpWebResponse)
158             content = webRes.GetResponseStream()
159             Return webRes.StatusCode
160         Catch ex As WebException
161             If ex.Status = WebExceptionStatus.ProtocolError Then
162                 Dim res As HttpWebResponse = DirectCast(ex.Response, HttpWebResponse)
163                 Return res.StatusCode
164             End If
165             Throw
166         End Try
167
168     End Function
169
170     Public Sub RequestAbort() Implements IHttpConnection.RequestAbort
171         Try
172             If streamReq IsNot Nothing Then
173                 streamReq.Abort()
174             End If
175         Catch ex As Exception
176         End Try
177     End Sub
178
179     '''<summary>
180     '''BASIC認証とREST APIで必要なヘッダを付加
181     '''</summary>
182     '''<param name="webRequest">付加対象となるHTTPリクエストオブジェクト</param>
183     Private Sub AppendApiInfo(ByVal webRequest As HttpWebRequest)
184         webRequest.ContentType = "application/x-www-form-urlencoded"
185         webRequest.Accept = "text/html, */*"
186         webRequest.Headers.Add(HttpRequestHeader.Authorization, credential)
187     End Sub
188
189     '''<summary>
190     '''BASIC認証で使用するユーザー名とパスワードを設定。
191     '''</summary>
192     '''<param name="userName">認証で使用するユーザー名</param>
193     '''<param name="password">認証で使用するパスワード</param>
194     Public Sub Initialize(ByVal userName As String, ByVal password As String)
195         Me._userName = userName
196         Me._password = password
197         Me.credential = "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(userName + ":" + password))
198     End Sub
199
200     '''<summary>
201     '''設定されているユーザー名
202     '''</summary>
203     Public ReadOnly Property AuthUsername() As String Implements IHttpConnection.AuthUsername
204         Get
205             Return _userName
206         End Get
207     End Property
208
209     '''<summary>
210     '''パスワード
211     '''</summary>
212     Public ReadOnly Property Password() As String
213         Get
214             Return Me._password
215         End Get
216     End Property
217
218     '''<summary>
219     '''BASIC認証で使用するユーザー名とパスワードを設定。指定のURLにGETリクエストを投げて、OK応答なら認証OKとみなして認証情報を保存する
220     '''</summary>
221     '''<param name="url">認証先のURL</param>
222     '''<param name="userName">認証で使用するユーザー名</param>
223     '''<param name="password">認証で使用するパスワード</param>
224     Public Function Authenticate(ByVal url As Uri, ByVal username As String, ByVal password As String, ByRef content As String) As HttpStatusCode Implements IHttpConnection.Authenticate
225         'urlは認証必要なGETメソッドとする
226         Dim orgCre As String = Me.credential
227         Me.credential = "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(username + ":" + password))
228         Try
229             Dim httpCode As HttpStatusCode = Me.GetContent("GET", url, Nothing, Nothing, Nothing, Nothing)
230             If httpCode = HttpStatusCode.OK Then
231                 Me._userName = username
232                 Me._password = password
233             Else
234                 Me.credential = orgCre
235             End If
236             Return httpCode
237         Catch ex As Exception
238             Me.credential = orgCre
239             Throw
240         End Try
241     End Function
242
243 End Class