xref: /OpenGrok/opengrok-indexer/src/test/resources/analysis/vb/sample.cls (revision eeb7e5b33d1bcc524fcc9d1d560447b044e286a4)
1' The MIT License (MIT)
2'
3' Copyright (c) 2016 Tim Hall
4'
5' Permission is hereby granted, free of charge, to any person obtaining a copy
6' of this software and associated documentation files (the "Software"), to deal
7' in the Software without restriction, including without limitation the rights
8' to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9' copies of the Software, and to permit persons to whom the Software is
10' furnished to do so, subject to the following conditions:
11'
12' The above copyright notice and this permission notice shall be included in all
13' copies or substantial portions of the Software.
14'
15' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16' IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17' FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18' AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19' LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20' OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21' SOFTWARE.
22
23VERSION 1.0 CLASS
24BEGIN
25  MultiUse = -1  'True
26END
27Attribute VB_Name = "WebResponse"
28Attribute VB_GlobalNameSpace = False
29Attribute VB_Creatable = False
30Attribute VB_PredeclaredId = False
31Attribute VB_Exposed = True
32''
33' WebResponse v4.1.3
34' (c) Tim Hall - https://github.com/VBA-tools/VBA-Web
35'
36' Wrapper for http/cURL responses that includes parsed Data based on WebRequest.ResponseFormat.
37'
38' Usage:
39' ```VB.net
40' Dim Response As WebResponse
41' Set Response = Client.Execute(Request)
42'
43' If Response.StatusCode = WebStatusCode.Ok Then
44'   ' Response.Headers, Response.Cookies
45'   ' Response.Data -> Parsed Response.Content based on Request.ResponseFormat
46'   ' Response.Body -> Raw response bytes
47' Else
48'   Debug.Print "Error: " & Response.StatusCode & " - " & Response.Content
49' End If
50' ```
51'
52' Errors:
53' 11030 / 80042b16 / -2147210474 - Error creating from http
54' 11031 / 80042b17 / -2147210473 - Error creating from cURL
55' 11032 / 80042b18 / -2147210472 - Error extracting headers
56'
57' @class WebResponse
58' @author tim.hall.engr@gmail.com
59' @license MIT (http://www.opensource.org/licenses/mit-license.php)
60'' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ '
61Option Explicit
62
63Private web_CrLf As String
64
65' --------------------------------------------- '
66' Properties
67' --------------------------------------------- '
68
69''
70' Status code that the server returned (e.g. 200).
71'
72' @property StatusCode
73' @type WebStatusCode
74''
75Public StatusCode As WebStatusCode
76
77''
78' Status string that the server returned (e.g. `404 -> "Not Found"`)
79'
80' @property StatusDescription
81' @type String
82''
83Public StatusDescription As String
84
85''
86' Content string that the server returned.
87'
88' @property Content
89' @type String
90''
91Public Content As String
92
93''
94' Raw bytes for the response.
95'
96' @property Body
97' @type Byte()
98''
99Public Body As Variant
100
101''
102' Parsed `Content` or `Body` based on the `WebRequest.ResponseFormat`.
103'
104' @property Data
105' @type Dictionary|Collection
106''
107Public Data As Object
108
109''
110' Headers that were included with the response.
111' (`Collection` of `KeyValue`)
112'
113' @property Headers
114' @type Collection
115''
116Public Headers As Collection
117
118''
119' Cookies that were included with the response.
120' (`Collection` of `KeyValue`)
121'
122' @property Cookies
123' @type Collection
124''
125Public Cookies As Collection
126
127' ============================================= '
128' Public Methods
129' ============================================= '
130
131''
132' Helper for updating the response with the given updated response values.
133' Useful for `ByRef` cases to update response in place.
134'
135' @method Update
136' @param Updated {WebResponse} Updated `WebResponse` to pull updated values from
137''
138Public Sub Update(Updated As WebResponse)
139    Me.StatusCode = Updated.StatusCode
140    Me.StatusDescription = Updated.StatusDescription
141    Me.Content = Updated.Content
142    Me.Body = Updated.Body
143    Set Me.Headers = Updated.Headers
144    Set Me.Cookies = Updated.Cookies
145    Set Me.Data = Updated.Data
146End Sub
147
148''
149' Create response from http
150'
151' @internal
152' @method CreateFromHttp
153' @param {WebClient} Client
154' @param {WebRequest} Request
155' @param {WinHttpRequest} Http
156' @throws 11030 / 80042b16 / -2147210474 - Error creating from http
157''
158Public Sub CreateFromHttp(Client As WebClient, Request As WebRequest, Http As Object)
159    On Error GoTo web_ErrorHandling
160
161    Me.StatusCode = Http.Status
162    Me.StatusDescription = Http.StatusText
163    Me.Content = Http.ResponseText
164    Me.Body = Http.ResponseBody
165
166    web_LoadValues Http.GetAllResponseHeaders, Me.Content, Me.Body, Request
167
168    Exit Sub
169
170web_ErrorHandling:
171
172    Dim web_ErrorDescription As String
173    web_ErrorDescription = "An error occurred while creating response from http" & vbNewLine & _
174        Err.Number & VBA.IIf(Err.Number < 0, " (" & VBA.LCase$(VBA.Hex$(Err.Number)) & ")", "") & ": " & Err.Description
175
176    WebHelpers.LogError web_ErrorDescription, "WebResponse.CreateFromHttp", 11030 + vbObjectError
177    Err.Raise 11030 + vbObjectError, "WebResponse.CreateFromHttp", web_ErrorDescription
178End Sub
179
180''
181' Create response from cURL
182'
183' @internal
184' @method CreateFromCurl
185' @param {WebClient} Client
186' @param {WebRequest} Request
187' @param {String} Result
188' @throws 11031 / 80042b17 / -2147210473 - Error creating from cURL
189''
190Public Sub CreateFromCurl(Client As WebClient, Request As WebRequest, Result As String)
191    On Error GoTo web_ErrorHandling
192
193    Dim web_Lines() As String
194
195    web_Lines = VBA.Split(Result, web_CrLf)
196
197    Me.StatusCode = web_ExtractStatusFromCurlResponse(web_Lines)
198    Me.StatusDescription = web_ExtractStatusTextFromCurlResponse(web_Lines)
199    Me.Content = web_ExtractResponseTextFromCurlResponse(web_Lines)
200    Me.Body = WebHelpers.StringToAnsiBytes(Me.Content)
201
202    web_LoadValues web_ExtractHeadersFromCurlResponse(web_Lines), Me.Content, Me.Body, Request
203
204    Exit Sub
205
206web_ErrorHandling:
207
208    Dim web_ErrorDescription As String
209    web_ErrorDescription = "An error occurred while creating response from cURL" & vbNewLine & _
210        Err.Number & VBA.IIf(Err.Number < 0, " (" & VBA.LCase$(VBA.Hex$(Err.Number)) & ")", "") & ": " & Err.Description
211
212    WebHelpers.LogError web_ErrorDescription, "WebResponse.CreateFromCurl", 11031 + vbObjectError
213    Err.Raise 11031 + vbObjectError, "WebResponse.CreateFromCurl", web_ErrorDescription
214End Sub
215
216''
217' Extract headers from response headers
218'
219' @internal
220' @method ExtractHeaders
221' @param {String} ResponseHeaders
222' @return {Collection} Headers
223' @throws 11032 / 80042b18 / -2147210472 - Error extracting headers
224''
225Public Function ExtractHeaders(ResponseHeaders As String) As Collection
226    On Error GoTo web_ErrorHandling
227
228    Dim web_Lines As Variant
229    Dim web_i As Integer
230    Dim web_Headers As New Collection
231    Dim web_Header As Dictionary
232    Dim web_ColonPosition As Long
233    Dim web_Multiline As Boolean
234
235    web_Lines = VBA.Split(ResponseHeaders, web_CrLf)
236
237    For web_i = LBound(web_Lines) To (UBound(web_Lines) + 1)
238        If web_i > UBound(web_Lines) Then
239            web_Headers.Add web_Header
240        ElseIf web_Lines(web_i) <> "" Then
241            web_ColonPosition = VBA.InStr(1, web_Lines(web_i), ":")
242            If web_ColonPosition = 0 And Not web_Header Is Nothing Then
243                ' Assume part of multi-line header
244                web_Multiline = True
245            ElseIf web_Multiline Then
246                ' Close out multi-line string
247                web_Multiline = False
248                web_Headers.Add web_Header
249            ElseIf Not web_Header Is Nothing Then
250                ' Add previous header
251                web_Headers.Add web_Header
252            End If
253
254            If Not web_Multiline Then
255                Set web_Header = WebHelpers.CreateKeyValue( _
256                    Key:=VBA.Trim(VBA.Mid$(web_Lines(web_i), 1, web_ColonPosition - 1)), _
257                    Value:=VBA.Trim(VBA.Mid$(web_Lines(web_i), web_ColonPosition + 1, VBA.Len(web_Lines(web_i)))) _
258                )
259            Else
260                web_Header("Value") = web_Header("Value") & web_CrLf & web_Lines(web_i)
261            End If
262        End If
263    Next web_i
264
265    Set ExtractHeaders = web_Headers
266    Exit Function
267
268web_ErrorHandling:
269
270    Dim web_ErrorDescription As String
271    web_ErrorDescription = "An error occurred while extracting headers" & vbNewLine & _
272        Err.Number & VBA.IIf(Err.Number < 0, " (" & VBA.LCase$(VBA.Hex$(Err.Number)) & ")", "") & ": " & Err.Description
273
274    WebHelpers.LogError web_ErrorDescription, "WebResponse.CreateFromCurl", 11032 + vbObjectError
275    Err.Raise 11032 + vbObjectError, "WebResponse.CreateFromCurl", web_ErrorDescription
276End Function
277
278''
279' Extract cookies from response headers
280'
281' @internal
282' @method ExtractCookies
283' @param {Collection} Headers
284' @return {Collection} Cookies
285''
286Public Function ExtractCookies(Headers As Collection) As Collection
287    Dim web_Header As Dictionary
288    Dim web_Cookie As String
289    Dim web_Key As String
290    Dim web_Value As String
291    Dim web_Cookies As New Collection
292
293    For Each web_Header In Headers
294        If web_Header("Key") = "Set-Cookie" Then
295            web_Cookie = web_Header("Value")
296            If VBA.InStr(1, web_Cookie, "=") > 0 Then
297                web_Key = VBA.Mid$(web_Cookie, 1, VBA.InStr(1, web_Cookie, "=") - 1)
298                web_Value = VBA.Mid$(web_Cookie, VBA.InStr(1, web_Cookie, "=") + 1, VBA.Len(web_Cookie))
299
300                ' Ignore text after semi-colon
301                If VBA.InStr(1, web_Value, ";") > 0 Then
302                    web_Value = VBA.Mid$(web_Value, 1, VBA.InStr(1, web_Value, ";") - 1)
303                End If
304
305                ' Ignore surrounding quotes
306                If VBA.Left$(web_Value, 1) = """" Then
307                    web_Value = VBA.Mid$(web_Value, 2, VBA.Len(web_Value) - 2)
308                End If
309
310                web_Cookies.Add WebHelpers.CreateKeyValue(web_Key, WebHelpers.UrlDecode(web_Value, PlusAsSpace:=False, EncodingMode:=UrlEncodingMode.CookieUrlEncoding))
311            Else
312                WebHelpers.LogWarning _
313                    "Unrecognized cookie format: " & web_Cookie, "WebResponse.ExtractCookies"
314            End If
315        End If
316    Next web_Header
317
318    Set ExtractCookies = web_Cookies
319End Function
320
321' ============================================= '
322' Private Functions
323' ============================================= '
324
325Private Sub web_LoadValues(web_Headers As String, web_Content As String, web_Body As Variant, web_Request As WebRequest)
326    ' Convert content to data by format
327    If web_Request.ResponseFormat <> WebFormat.PlainText Then
328        On Error Resume Next
329        Set Me.Data = _
330            WebHelpers.ParseByFormat(web_Content, web_Request.ResponseFormat, web_Request.CustomResponseFormat, web_Body)
331
332        If Err.Number <> 0 Then
333            WebHelpers.LogError Err.Description, Err.Source, Err.Number
334            Err.Clear
335        End If
336        On Error GoTo 0
337    End If
338
339    ' Extract headers
340    Set Me.Headers = ExtractHeaders(web_Headers)
341
342    ' Extract cookies
343    Set Me.Cookies = ExtractCookies(Me.Headers)
344End Sub
345
346Private Function web_ExtractStatusFromCurlResponse(web_CurlResponseLines() As String) As Long
347    Dim web_StatusLineParts() As String
348
349    web_StatusLineParts = VBA.Split(web_CurlResponseLines(web_FindStatusLine(web_CurlResponseLines)), " ")
350    web_ExtractStatusFromCurlResponse = VBA.CLng(web_StatusLineParts(1))
351End Function
352
353Private Function web_ExtractStatusTextFromCurlResponse(web_CurlResponseLines() As String) As String
354    Dim web_StatusLineParts() As String
355    Dim web_i As Long
356    Dim web_StatusText As String
357
358    web_StatusLineParts = VBA.Split(web_CurlResponseLines(web_FindStatusLine(web_CurlResponseLines)), " ", 3)
359    web_ExtractStatusTextFromCurlResponse = web_StatusLineParts(2)
360End Function
361
362Private Function web_ExtractHeadersFromCurlResponse(web_CurlResponseLines() As String) As String
363    Dim web_StatusLineIndex As Long
364    Dim web_BlankLineIndex As Long
365    Dim web_HeaderLines() As String
366    Dim web_WriteIndex As Long
367    Dim web_ReadIndex As Long
368
369    ' Find status line and blank line before body
370    web_StatusLineIndex = web_FindStatusLine(web_CurlResponseLines)
371    web_BlankLineIndex = web_FindBlankLine(web_CurlResponseLines)
372
373    ' Extract headers string
374    ReDim web_HeaderLines(0 To web_BlankLineIndex - 2 - web_StatusLineIndex)
375
376    web_WriteIndex = 0
377    For web_ReadIndex = (web_StatusLineIndex + 1) To web_BlankLineIndex - 1
378        web_HeaderLines(web_WriteIndex) = web_CurlResponseLines(web_ReadIndex)
379        web_WriteIndex = web_WriteIndex + 1
380    Next web_ReadIndex
381
382    web_ExtractHeadersFromCurlResponse = VBA.Join$(web_HeaderLines, web_CrLf)
383End Function
384
385Private Function web_ExtractResponseTextFromCurlResponse(web_CurlResponseLines() As String) As String
386    Dim web_BlankLineIndex As Long
387    Dim web_BodyLines() As String
388    Dim web_WriteIndex As Long
389    Dim web_ReadIndex As Long
390
391    ' Find blank line before body
392    web_BlankLineIndex = web_FindBlankLine(web_CurlResponseLines)
393
394    ' Extract body string
395    ReDim web_BodyLines(0 To UBound(web_CurlResponseLines) - web_BlankLineIndex - 1)
396
397    web_WriteIndex = 0
398    For web_ReadIndex = web_BlankLineIndex + 1 To UBound(web_CurlResponseLines)
399        web_BodyLines(web_WriteIndex) = web_CurlResponseLines(web_ReadIndex)
400        web_WriteIndex = web_WriteIndex + 1
401    Next web_ReadIndex
402
403    web_ExtractResponseTextFromCurlResponse = VBA.Join$(web_BodyLines, web_CrLf)
404End Function
405
406Private Function web_FindStatusLine(web_CurlResponseLines() As String) As Long
407    ' Special case for cURL: 100 Continue is included before final status code
408    ' -> ignore 100 and find final status code (next non-100 status code)
409    For web_FindStatusLine = LBound(web_CurlResponseLines) To UBound(web_CurlResponseLines)
410        If VBA.Trim$(web_CurlResponseLines(web_FindStatusLine)) <> "" Then
411            If VBA.Split(web_CurlResponseLines(web_FindStatusLine), " ")(1) <> "100" Then
412                Exit Function
413            End If
414        End If
415    Next web_FindStatusLine
416End Function
417
418Private Function web_FindBlankLine(web_CurlResponseLines() As String) As Long
419    For web_FindBlankLine = (web_FindStatusLine(web_CurlResponseLines) + 1) To UBound(web_CurlResponseLines)
420        If VBA.Trim$(web_CurlResponseLines(web_FindBlankLine)) = "" Then
421            Exit Function
422        End If
423    Next web_FindBlankLine
424End Function
425
426Private Sub Class_Initialize()
427    web_CrLf = VBA.Chr$(&HA) & VBA.Chr$(&o12)
428
429    Set Headers = New Collection
430    Set Cookies = New Collection
431End Sub
432
433Private Sub Test_strings()
434    Dim foo1() As String
435    Set foo1 = " testing
436    1-2-3"
437End Sub
438