tdrpa.tdworker 1.1.9.3__py310-none-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. tdrpa/_tdxlwings/__init__.py +193 -0
  2. tdrpa/_tdxlwings/__pycache__/__init__.cpython-311.pyc +0 -0
  3. tdrpa/_tdxlwings/__pycache__/__init__.cpython-38.pyc +0 -0
  4. tdrpa/_tdxlwings/__pycache__/_win32patch.cpython-311.pyc +0 -0
  5. tdrpa/_tdxlwings/__pycache__/_win32patch.cpython-38.pyc +0 -0
  6. tdrpa/_tdxlwings/__pycache__/_xlwindows.cpython-311.pyc +0 -0
  7. tdrpa/_tdxlwings/__pycache__/_xlwindows.cpython-38.pyc +0 -0
  8. tdrpa/_tdxlwings/__pycache__/apps.cpython-311.pyc +0 -0
  9. tdrpa/_tdxlwings/__pycache__/apps.cpython-38.pyc +0 -0
  10. tdrpa/_tdxlwings/__pycache__/base_classes.cpython-311.pyc +0 -0
  11. tdrpa/_tdxlwings/__pycache__/base_classes.cpython-38.pyc +0 -0
  12. tdrpa/_tdxlwings/__pycache__/com_server.cpython-311.pyc +0 -0
  13. tdrpa/_tdxlwings/__pycache__/com_server.cpython-38.pyc +0 -0
  14. tdrpa/_tdxlwings/__pycache__/constants.cpython-311.pyc +0 -0
  15. tdrpa/_tdxlwings/__pycache__/constants.cpython-38.pyc +0 -0
  16. tdrpa/_tdxlwings/__pycache__/expansion.cpython-311.pyc +0 -0
  17. tdrpa/_tdxlwings/__pycache__/expansion.cpython-38.pyc +0 -0
  18. tdrpa/_tdxlwings/__pycache__/main.cpython-311.pyc +0 -0
  19. tdrpa/_tdxlwings/__pycache__/main.cpython-38.pyc +0 -0
  20. tdrpa/_tdxlwings/__pycache__/udfs.cpython-311.pyc +0 -0
  21. tdrpa/_tdxlwings/__pycache__/udfs.cpython-38.pyc +0 -0
  22. tdrpa/_tdxlwings/__pycache__/utils.cpython-311.pyc +0 -0
  23. tdrpa/_tdxlwings/__pycache__/utils.cpython-38.pyc +0 -0
  24. tdrpa/_tdxlwings/_win32patch.py +90 -0
  25. tdrpa/_tdxlwings/_xlmac.py +2240 -0
  26. tdrpa/_tdxlwings/_xlwindows.py +2518 -0
  27. tdrpa/_tdxlwings/addin/Dictionary.cls +474 -0
  28. tdrpa/_tdxlwings/addin/IWebAuthenticator.cls +71 -0
  29. tdrpa/_tdxlwings/addin/WebClient.cls +772 -0
  30. tdrpa/_tdxlwings/addin/WebHelpers.bas +3203 -0
  31. tdrpa/_tdxlwings/addin/WebRequest.cls +875 -0
  32. tdrpa/_tdxlwings/addin/WebResponse.cls +453 -0
  33. tdrpa/_tdxlwings/addin/xlwings.xlam +0 -0
  34. tdrpa/_tdxlwings/apps.py +35 -0
  35. tdrpa/_tdxlwings/base_classes.py +1092 -0
  36. tdrpa/_tdxlwings/cli.py +1306 -0
  37. tdrpa/_tdxlwings/com_server.py +385 -0
  38. tdrpa/_tdxlwings/constants.py +3080 -0
  39. tdrpa/_tdxlwings/conversion/__init__.py +103 -0
  40. tdrpa/_tdxlwings/conversion/framework.py +147 -0
  41. tdrpa/_tdxlwings/conversion/numpy_conv.py +34 -0
  42. tdrpa/_tdxlwings/conversion/pandas_conv.py +184 -0
  43. tdrpa/_tdxlwings/conversion/standard.py +321 -0
  44. tdrpa/_tdxlwings/expansion.py +83 -0
  45. tdrpa/_tdxlwings/ext/__init__.py +3 -0
  46. tdrpa/_tdxlwings/ext/sql.py +73 -0
  47. tdrpa/_tdxlwings/html/xlwings-alert.html +71 -0
  48. tdrpa/_tdxlwings/js/xlwings.js +577 -0
  49. tdrpa/_tdxlwings/js/xlwings.ts +729 -0
  50. tdrpa/_tdxlwings/mac_dict.py +6399 -0
  51. tdrpa/_tdxlwings/main.py +5205 -0
  52. tdrpa/_tdxlwings/mistune/__init__.py +63 -0
  53. tdrpa/_tdxlwings/mistune/block_parser.py +366 -0
  54. tdrpa/_tdxlwings/mistune/inline_parser.py +216 -0
  55. tdrpa/_tdxlwings/mistune/markdown.py +84 -0
  56. tdrpa/_tdxlwings/mistune/renderers.py +220 -0
  57. tdrpa/_tdxlwings/mistune/scanner.py +121 -0
  58. tdrpa/_tdxlwings/mistune/util.py +41 -0
  59. tdrpa/_tdxlwings/pro/__init__.py +40 -0
  60. tdrpa/_tdxlwings/pro/_xlcalamine.py +536 -0
  61. tdrpa/_tdxlwings/pro/_xlofficejs.py +146 -0
  62. tdrpa/_tdxlwings/pro/_xlremote.py +1293 -0
  63. tdrpa/_tdxlwings/pro/custom_functions_code.js +150 -0
  64. tdrpa/_tdxlwings/pro/embedded_code.py +60 -0
  65. tdrpa/_tdxlwings/pro/udfs_officejs.py +549 -0
  66. tdrpa/_tdxlwings/pro/utils.py +199 -0
  67. tdrpa/_tdxlwings/quickstart.xlsm +0 -0
  68. tdrpa/_tdxlwings/quickstart_addin.xlam +0 -0
  69. tdrpa/_tdxlwings/quickstart_addin_ribbon.xlam +0 -0
  70. tdrpa/_tdxlwings/quickstart_fastapi/main.py +47 -0
  71. tdrpa/_tdxlwings/quickstart_fastapi/requirements.txt +3 -0
  72. tdrpa/_tdxlwings/quickstart_standalone.xlsm +0 -0
  73. tdrpa/_tdxlwings/reports.py +12 -0
  74. tdrpa/_tdxlwings/rest/__init__.py +1 -0
  75. tdrpa/_tdxlwings/rest/api.py +368 -0
  76. tdrpa/_tdxlwings/rest/serializers.py +103 -0
  77. tdrpa/_tdxlwings/server.py +14 -0
  78. tdrpa/_tdxlwings/udfs.py +775 -0
  79. tdrpa/_tdxlwings/utils.py +777 -0
  80. tdrpa/_tdxlwings/xlwings-0.31.6.applescript +30 -0
  81. tdrpa/_tdxlwings/xlwings.bas +2061 -0
  82. tdrpa/_tdxlwings/xlwings_custom_addin.bas +2042 -0
  83. tdrpa/_tdxlwings/xlwingslib.cp38-win_amd64.pyd +0 -0
  84. tdrpa/tdworker/__init__.pyi +8 -0
  85. tdrpa/tdworker/_excel.pyi +703 -0
  86. tdrpa/tdworker/_img.pyi +173 -0
  87. tdrpa/tdworker/_os.pyi +46 -0
  88. tdrpa/tdworker/_w.pyi +129 -0
  89. tdrpa/tdworker/_web.pyi +248 -0
  90. tdrpa/tdworker/_winE.pyi +246 -0
  91. tdrpa/tdworker/_winK.pyi +74 -0
  92. tdrpa/tdworker/_winM.pyi +117 -0
  93. tdrpa/tdworker.cp310-win_amd64.pyd +0 -0
  94. tdrpa.tdworker-1.1.9.3.dist-info/METADATA +25 -0
  95. tdrpa.tdworker-1.1.9.3.dist-info/RECORD +97 -0
  96. tdrpa.tdworker-1.1.9.3.dist-info/WHEEL +5 -0
  97. tdrpa.tdworker-1.1.9.3.dist-info/top_level.txt +1 -0
@@ -0,0 +1,772 @@
1
+ VERSION 1.0 CLASS
2
+ BEGIN
3
+ MultiUse = -1 'True
4
+ END
5
+ Attribute VB_Name = "WebClient"
6
+ Attribute VB_GlobalNameSpace = False
7
+ Attribute VB_Creatable = False
8
+ Attribute VB_PredeclaredId = False
9
+ Attribute VB_Exposed = True
10
+ ''
11
+ ' CHANGES:
12
+ ' * PrepareCurlRequest: allow big request body, based on https://github.com/VBA-tools/VBA-Web/pull/397
13
+ '
14
+ ' WebClient v4.1.6
15
+ ' (c) Tim Hall - https://github.com/VBA-tools/VBA-Web
16
+ '
17
+ ' `WebClient` executes requests and handles response and is responsible for functionality shared between requests,
18
+ ' such as authentication, proxy configuration, and security.
19
+ '
20
+ ' Usage:
21
+ '
22
+ ' ```VB.net
23
+ ' Dim Client As New WebClient
24
+ ' Client.BaseUrl = "https://www.example.com/api/"
25
+ '
26
+ ' Dim Auth As New HttpBasicAuthenticator
27
+ ' Auth.Setup Username, Password
28
+ ' Set Client.Authenticator = Auth
29
+ '
30
+ ' Dim Request As New WebRequest
31
+ ' Dim Response As WebResponse
32
+ ' ' Setup WebRequest...
33
+ '
34
+ ' Set Response = Client.Execute(Request)
35
+ ' ' -> Uses Http Basic authentication and appends Request.Resource to BaseUrl
36
+ ' ```
37
+ '
38
+ ' Errors:
39
+ ' 11010 / 80042b02 / -2147210494 - cURL error in Execute
40
+ ' 11011 / 80042b03 / -2147210493 - Error in Execute
41
+ ' 11012 / 80042b04 / -2147210492 - Error preparing http request
42
+ ' 11013 / 80042b05 / -2147210491 - Error preparing cURL request
43
+ '
44
+ ' @class WebClient
45
+ ' @author tim.hall.engr@gmail.com
46
+ ' @license MIT (http://www.opensource.org/licenses/mit-license.php)
47
+ '' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ '
48
+ Option Explicit
49
+
50
+ ' --------------------------------------------- '
51
+ ' Constants and Private Variables
52
+ ' --------------------------------------------- '
53
+
54
+ Private Const web_DefaultTimeoutMs As Long = 5000
55
+
56
+ Private Const web_HttpRequest_SetCredentials_ForServer = 0
57
+ Private Const web_HttpRequest_SetCredentials_ForProxy = 1
58
+
59
+ Private Const web_HttpRequest_ProxySetting_Default = 0
60
+ Private Const web_HttpRequest_ProxySetting_PreConfig = 0
61
+ Private Const web_HttpRequest_ProxySetting_Direct = 1
62
+ Private Const web_HttpRequest_ProxySetting_Proxy = 2
63
+
64
+ Private Enum web_WinHttpRequestOption
65
+ web_WinHttpRequestOption_UserAgentString = 0
66
+ web_WinHttpRequestOption_URL = 1
67
+ web_WinHttpRequestOption_URLCodePage = 2
68
+ web_WinHttpRequestOption_EscapePercentInURL = 3
69
+ web_WinHttpRequestOption_SslErrorIgnoreFlags = 4
70
+ web_WinHttpRequestOption_SelectCertificate = 5
71
+ web_WinHttpRequestOption_EnableRedirects = 6
72
+ web_WinHttpRequestOption_UrlEscapeDisable = 7
73
+ web_WinHttpRequestOption_UrlEscapeDisableQuery = 8
74
+ web_WinHttpRequestOption_SecureProtocols = 9
75
+ web_WinHttpRequestOption_EnableTracing = 10
76
+ web_WinHttpRequestOption_RevertImpersonationOverSsl = 11
77
+ web_WinHttpRequestOption_EnableHttpsToHttpRedirects = 12
78
+ web_WinHttpRequestOption_EnablePassportAuthentication = 13
79
+ web_WinHttpRequestOption_MaxAutomaticRedirects = 14
80
+ web_WinHttpRequestOption_MaxResponseHeaderSize = 15
81
+ web_WinHttpRequestOption_MaxResponseDrainSize = 16
82
+ web_WinHttpRequestOption_EnableHttp1_1 = 17
83
+ web_WinHttpRequestOption_EnableCertificateRevocationCheck = 18
84
+ End Enum
85
+
86
+ Private web_pProxyServer As String
87
+ Private web_pAutoProxyDomain As String
88
+
89
+ ' --------------------------------------------- '
90
+ ' Properties
91
+ ' --------------------------------------------- '
92
+
93
+ ''
94
+ ' Set the base url that is shared by all requests
95
+ ' and that the request `Resource` is appended to.
96
+ '
97
+ ' @example
98
+ ' ```VB.net
99
+ ' ' Desired URLs
100
+ ' ' https://api.example.com/v1/messages
101
+ ' ' https://api.example.com/v1/users/id
102
+ ' ' BaseUrl <- ^ -> Resource
103
+ '
104
+ ' Dim Client As New WebClient
105
+ ' Client.BaseUrl = "https://api.example.com/v1/"
106
+ '
107
+ ' Dim Request As New WebRequest
108
+ ' Request.Resource = "messages"
109
+ ' Request.Resource = "users/{id}"
110
+ ' ```
111
+ '
112
+ ' @property BaseUrl
113
+ ' @type String
114
+ ''
115
+ Public BaseUrl As String
116
+
117
+ ''
118
+ ' Attach an authenticator to the client for authentication requests.
119
+ '
120
+ ' @example
121
+ ' ```VB.net
122
+ ' Dim Client As New WebClient
123
+ ' Dim Auth As New OAuth1Authenticator
124
+ ' Auth.Setup ...
125
+ '
126
+ ' Set Client.Authenticator = Auth
127
+ ' ' -> All requests use Auth to add "Authorization" header
128
+ ' ```
129
+ '
130
+ ' @property Authenticator
131
+ ' @type IWebAuthenticator
132
+ ''
133
+ Public Authenticator As IWebAuthenticator
134
+
135
+ ''
136
+ ' Timeout (in milliseconds) to wait for timeout in each request phase
137
+ ' (Resolve, Connect, Send, Receive).
138
+
139
+ '
140
+ ' @property TimeoutMs
141
+ ' @type Long
142
+ ' @default 5000
143
+ ''
144
+ Public TimeoutMs As Long
145
+
146
+ ''
147
+ ' Comma separated list of domains to bypass the proxy.
148
+ '
149
+ ' @property ProxyBypassList
150
+ ' @type String
151
+ ''
152
+ Public proxyBypassList As String
153
+
154
+ ''
155
+ ' Username for proxy.
156
+ '
157
+ ' @property ProxyUsername
158
+ ' @type String
159
+ ''
160
+ Public proxyUsername As String
161
+
162
+ ''
163
+ ' Password for proxy.
164
+ '
165
+ ' @property ProxyPassword
166
+ ' @type String
167
+ ''
168
+ Public proxyPassword As String
169
+
170
+ ''
171
+ ' Load proxy server and bypass list automatically (`False` by default).
172
+ '
173
+ ' @property EnableAutoProxy
174
+ ' @type Boolean
175
+ ' @default False
176
+ ''
177
+ Public enableAutoProxy As Boolean
178
+
179
+ ''
180
+ ' Turn off SSL validation (`False` by default).
181
+ ' Useful for self-signed certificates and should only be used with trusted servers.
182
+ '
183
+ ' @property Insecure
184
+ ' @type Boolean
185
+ ' @default False
186
+ ''
187
+ Public insecure As Boolean
188
+
189
+ ''
190
+ ' Follow redirects (301, 302, 307) using Location header
191
+ '
192
+ ' @property FollowRedirects
193
+ ' @type Boolean
194
+ ' @default True
195
+ ''
196
+ Public followRedirects As Boolean
197
+
198
+ ''
199
+ ' Proxy server to pass requests through (except for those that match `ProxyBypassList`).
200
+ '
201
+ ' @property ProxyServer
202
+ ' @type String
203
+ ''
204
+ Public Property Get proxyServer() As String
205
+ proxyServer = web_pProxyServer
206
+ End Property
207
+ Public Property Let proxyServer(Value As String)
208
+ Me.enableAutoProxy = False
209
+ web_pProxyServer = Value
210
+ End Property
211
+
212
+ ' ============================================= '
213
+ ' Public Methods
214
+ ' ============================================= '
215
+
216
+ ''
217
+ ' Execute the given request
218
+ ' (append the request's `FormattedResource` to the `BaseUrl`)
219
+ ' and return the response.
220
+ '
221
+ ' @example
222
+ ' ```VB.net
223
+ ' Dim Client As New WebClient
224
+ ' Client.BaseUrl = "https://api.example.com/v1/"
225
+ '
226
+ ' Dim Request As New WebRequest
227
+ ' Request.Resource = "messages/{id}"
228
+ ' Request.AddUrlSegment "id", 123
229
+ '
230
+ ' ' Add querystring, body, headers, cookies, etc. for request
231
+ '
232
+ ' Dim Response As WebResponse
233
+ ' Set Response = Client.Execute(Request)
234
+ '
235
+ ' ' -> GET https://api.example/com/v1/messages/123
236
+ ' ' headers, cookies, and body...
237
+ ' ```
238
+ '
239
+ ' @method Execute
240
+ ' @param {WebRequest} request The request to execute
241
+ ' @return {WebResponse} Wrapper of server response for request
242
+ ' @throws 11010 / 80042b02 / -2147210494 - cURL error in Execute
243
+ ' @throws 11011 / 80042b03 / -2147210493 - Error in Execute
244
+ ''
245
+ Public Function Execute(Request As WebRequest) As WebResponse
246
+ Dim web_Http As Object
247
+ Dim web_Response As New WebResponse
248
+
249
+ On Error GoTo web_ErrorHandling
250
+
251
+ #If Mac Then
252
+ Dim web_Curl As String
253
+ Dim web_Result As ShellResult
254
+
255
+ web_Curl = Me.PrepareCurlRequest(Request)
256
+ web_Result = WebHelpers.ExecuteInShell(web_Curl)
257
+
258
+ ' Handle cURL errors
259
+ '
260
+ ' Map to WinHttp error number, as possible
261
+ ' https://msdn.microsoft.com/en-us/library/aa383770(VS.85).aspx
262
+ If web_Result.ExitCode > 0 Then
263
+ Dim web_ErrorNumber As Long
264
+ Dim web_ErrorMessage As String
265
+ Dim web_ErrorDetails As String
266
+ web_ErrorNumber = web_Result.ExitCode / 256
267
+
268
+ Select Case web_ErrorNumber
269
+ Case 1
270
+ ' 1 = CURLE_UNSUPPORTED_PROTOCOL
271
+ ' 12006 = ERROR_WINHTTP_UNRECOGNIZED_SCHEME
272
+ Err.Raise 12006 + &H30000 + vbObjectError, "The URL does not use a recognized protocol (1: CURLE_UNSUPPORTED_PROTOCOL)" & vbNewLine & _
273
+ "URL: " & Me.GetFullUrl(Request) & vbNewLine & _
274
+ "Protocol: " & WebHelpers.GetUrlParts(Me.GetFullUrl(Request))("Protocol")
275
+ Case 3
276
+ ' 3 = CURLE_URL_MALFORMAT
277
+ ' 12005 = ERROR_WINHTTP_INVALID_URL
278
+ Err.Raise 12005 + &H30000 + vbObjectError, "The URL is invalid (3: CURLE_URL_MALFORMAT)" & _
279
+ "URL: " & Me.GetFullUrl(Request)
280
+ Case 5, 6
281
+ ' 5 = CURLE_COULDNT_RESOLVE_PROXY
282
+ ' 6 = CURLE_COULDNT_RESOLVE_HOST
283
+ ' 12007 = ERROR_WINHTTP_NAME_NOT_RESOLVED
284
+ If web_ErrorNumber = 5 Then
285
+ web_ErrorDetails = "(5: CURLE_COULDNT_RESOLVE_PROXY)"
286
+ Else
287
+ web_ErrorDetails = "(6: CURLE_COULDNT_RESOLVE_HOST)"
288
+ End If
289
+
290
+ Err.Raise 12007 + &H30000 + vbObjectError, "WebClient.Execute", "The server name or address could not be resolved " & web_ErrorDetails
291
+ Case 7
292
+ ' 7 = CURLE_COULDNT_CONNECT
293
+ ' 12029 = ERROR_WINHTTP_CANNOT_CONNECT
294
+ Err.Raise 12029 + &H30000 + vbObjectError, "WebClient.Execute", "A connection with the server could not be established (7: CURLE_COULDNT_CONNECT)"
295
+ Case 12, 28
296
+ ' 12 = CURLE_FTP_ACCEPT_TIMEOUT
297
+ ' 28 = CURLE_OPERATION_TIMEDOUT
298
+ ' 12002 = ERROR_WINHTTP_TIMEOUT
299
+ If web_ErrorNumber = 12 Then
300
+ web_ErrorDetails = "(12: CURLE_FTP_ACCEPT_TIMEOUT)"
301
+ Else
302
+ web_ErrorDetails = "(28: CURLE_OPERATION_TIMEDOUT)"
303
+ End If
304
+
305
+ Err.Raise 12002 + &H30000 + vbObjectError, "WebClient.Execute", "The operation timed out " & web_ErrorDetails
306
+ Case 47
307
+ ' 47 = CURLE_TOO_MANY_REDIRECTS
308
+ ' 12156 = ERROR_WINHTTP_REDIRECT_FAILED
309
+ Err.Raise 12156 + &H30000 + vbObjectError, "WebClient.Execute", "Too many redirects (47: CURLE_TOO_MANY_REDIRECTS)"
310
+ Case Else
311
+ Err.Raise 11010 + vbObjectError, "WebClient.Execute", "An unknown cURL error occured, #" & web_ErrorNumber & vbNewLine & _
312
+ "Find details at http://curl.haxx.se/libcurl/c/libcurl-errors.html"
313
+ End Select
314
+ End If
315
+
316
+ web_Response.CreateFromCurl Me, Request, web_Result.Output
317
+
318
+ #Else
319
+ Set web_Http = Me.PrepareHttpRequest(Request)
320
+
321
+ web_Http.Send Request.Body
322
+ Do While Not web_Http.WaitForResponse(0.025)
323
+ VBA.DoEvents
324
+ Loop
325
+
326
+ web_Response.CreateFromHttp Me, Request, web_Http
327
+
328
+ #End If
329
+
330
+ WebHelpers.LogResponse Me, Request, web_Response
331
+
332
+ If Not Me.Authenticator Is Nothing Then
333
+ Me.Authenticator.AfterExecute Me, Request, web_Response
334
+ End If
335
+
336
+ Set web_Http = Nothing
337
+ Set Execute = web_Response
338
+ Exit Function
339
+
340
+ web_ErrorHandling:
341
+
342
+ Set web_Http = Nothing
343
+ Dim web_ErrorDescription As String
344
+
345
+ ' Check lower 16 bits from error
346
+ ' (e.g. 80072EE2 -> 2EE2 -> 12002)
347
+ Select Case Err.Number And 65535
348
+ Case 12002, 12007, 12029
349
+ ' Treat timeout-related errors as 408: timeout, name not resolved, cannot connect
350
+ web_Response.StatusCode = WebStatusCode.RequestTimeout
351
+ web_Response.StatusDescription = "Request Timeout: " & Err.Description
352
+
353
+ WebHelpers.LogResponse Me, Request, web_Response
354
+ Set Execute = web_Response
355
+ Err.Clear
356
+ Case Else
357
+ ' Error
358
+ web_ErrorDescription = "An error occurred during execute" & vbNewLine & _
359
+ Err.Number & VBA.IIf(Err.Number < 0, " (" & VBA.LCase$(VBA.Hex$(Err.Number)) & ")", "") & ": " & Err.Description
360
+
361
+ WebHelpers.LogError web_ErrorDescription, "WebClient.Execute", 11011 + vbObjectError
362
+ Err.Raise 11011 + vbObjectError, "WebClient.Execute", web_ErrorDescription
363
+ End Select
364
+ End Function
365
+
366
+ ''
367
+ ' Get JSON from the given URL
368
+ ' (with options for Headers, Cookies, QuerystringParams, and UrlSegments).
369
+ '
370
+ ' @example
371
+ ' ```VB.net
372
+ ' Dim Client As New WebClient
373
+ ' Dim Url As String
374
+ ' Url = "https://api.example.com/v1/messages/1"
375
+ '
376
+ ' Dim Response As WebResponse
377
+ ' Set Response = Client.GetJson(Url)
378
+ '
379
+ ' Dim Headers As New Collection
380
+ ' Headers.Add WebHelpers.CreateKeyValue("Authorization", "Bearer ...")
381
+ '
382
+ ' Dim Options As New Dictionary
383
+ ' Options.Add "Headers", Headers
384
+ '
385
+ ' Set Response = Client.GetJson(Url, Options)
386
+ ' ```
387
+ '
388
+ ' @method GetJson
389
+ ' @param {String} Url (appended to `BaseUrl`, if set)
390
+ ' @param {Dictionary} [Options]
391
+ ' @param {Collection} [Options.Headers] Collection of `KeyValue`
392
+ ' @param {Collection} [Options.Cookies] Collection of `KeyValue`
393
+ ' @param {Collection} [Options.QuerystringParams] Collection of `KeyValue`
394
+ ' @param {Dictionary} [Options.UrlSegments]
395
+ ' @return {WebResponse} Response
396
+ ''
397
+ Public Function GetJson(url As String, Optional Options As Dictionary) As WebResponse
398
+ Dim web_Request As New WebRequest
399
+ web_Request.CreateFromOptions Options
400
+ web_Request.Resource = url
401
+ web_Request.Format = WebFormat.Json
402
+ web_Request.Method = WebMethod.HttpGet
403
+
404
+ Set GetJson = Me.Execute(web_Request)
405
+ End Function
406
+
407
+ ''
408
+ ' Post JSON Body (`Array`, `Collection`, `Dictionary`) to the given URL
409
+ ' (with options for Headers, Cookies, QuerystringParams, and UrlSegments).
410
+ '
411
+ ' @example
412
+ ' ```VB.net
413
+ ' Dim Client As New WebClient
414
+ ' Dim Url As String
415
+ ' Url = "https://api.example.com/v1/messages/1"
416
+ '
417
+ ' ' Body
418
+ ' ' Array, Collection, or Dictionary
419
+ ' Dim Body As New Dictionary
420
+ ' Body.Add "message", "Howdy!"
421
+ '
422
+ ' Dim Response As WebResponse
423
+ ' Set Response = Client.PostJson(Url, Body)
424
+ '
425
+ ' Dim Headers As New Collection
426
+ ' Headers.Add WebHelpers.CreateKeyValue("Authorization", "Bearer ...")
427
+ '
428
+ ' Dim Options As New Dictionary
429
+ ' Options.Add "Headers", Headers
430
+ '
431
+ ' Set Response = Client.PostJson(Url, Body, Options)
432
+ ' ```
433
+ '
434
+ ' @method PostJson
435
+ ' @param {String} Url (appended to `BaseUrl`, if set)
436
+ ' @param {Dictionary} Body
437
+ ' @param {Dictionary} [Options]
438
+ ' @param {Collection} [Options.Headers] Collection of `KeyValue`
439
+ ' @param {Collection} [Options.Cookies] Collection of `KeyValue`
440
+ ' @param {Collection} [Options.QuerystringParams] Collection of `KeyValue`
441
+ ' @param {Dictionary} [Options.UrlSegments]
442
+ ' @return {WebResponse} Response
443
+ ''
444
+ Public Function PostJson(url As String, Body As Variant, Optional Options As Dictionary) As WebResponse
445
+ Dim web_Request As New WebRequest
446
+ web_Request.CreateFromOptions Options
447
+ web_Request.Resource = url
448
+ web_Request.Format = WebFormat.Json
449
+ web_Request.Method = WebMethod.HttpPost
450
+ If VBA.IsObject(Body) Then
451
+ Set web_Request.Body = Body
452
+ Else
453
+ web_Request.Body = Body
454
+ End If
455
+
456
+ Set PostJson = Me.Execute(web_Request)
457
+ End Function
458
+
459
+ ''
460
+ ' Set proxy for all requests
461
+ '
462
+ ' @example
463
+ ' ```VB.net
464
+ ' Dim Client As New RestClient
465
+ '
466
+ ' ' Just Server
467
+ ' Client.SetProxy "proxy_server:80"
468
+ '
469
+ ' ' Server + Username and Password
470
+ ' Client.SetProxy "proxy_server:80", "Tim", "Password"
471
+ '
472
+ ' ' Server + Username and Password + BypassList
473
+ ' Client.SetProxy "proxy_server:80", "Tim", "Password", "<local>,*.bypass.com"
474
+ ' ```
475
+ '
476
+ ' @method SetProxy
477
+ ' @param {String} ProxyServer Proxy server to pass requests through
478
+ ' @param {String} [Username=""] Username for proxy
479
+ ' @param {String} [Password=""] Password for proxy
480
+ ' @param {String} [BypassList=""] Comma-separated list of servers that should bypass proxy
481
+ ''
482
+ Public Sub SetProxy(proxyServer As String, _
483
+ Optional Username As String = "", Optional Password As String = "", Optional BypassList As String = "")
484
+
485
+ Me.proxyServer = proxyServer
486
+ Me.proxyUsername = Username
487
+ Me.proxyPassword = Password
488
+ Me.proxyBypassList = BypassList
489
+ End Sub
490
+
491
+ ''
492
+ ' Get full url by joining given `WebRequest.FormattedResource` and `BaseUrl`.
493
+ '
494
+ ' @method GetFullUrl
495
+ ' @param {WebRequest} Request
496
+ ' @return {String}
497
+ ''
498
+ Public Function GetFullUrl(Request As WebRequest) As String
499
+ GetFullUrl = WebHelpers.JoinUrl(Me.BaseUrl, Request.FormattedResource)
500
+ End Function
501
+
502
+ ''
503
+ ' Prepare Http request for given WebRequest
504
+ '
505
+ ' @internal
506
+ ' @method PrepareHttpRequest
507
+ ' @param {WebRequest} Request
508
+ ' @return {WinHttpRequest}
509
+ ' @throws 11012 / 80042b04 / -2147210492 - Error preparing http request
510
+ ''
511
+ Public Function PrepareHttpRequest(Request As WebRequest, Optional Async As Boolean = True) As Object
512
+ Dim web_Http As Object
513
+ Dim web_KeyValue As Dictionary
514
+
515
+ On Error GoTo web_ErrorHandling
516
+
517
+ Set web_Http = CreateObject("WinHttp.WinHttpRequest.5.1")
518
+
519
+ ' Prepare request (before open)
520
+ web_BeforeExecute Request
521
+
522
+ ' Open http request
523
+ web_Http.Open WebHelpers.MethodToName(Request.Method), Me.GetFullUrl(Request), Async
524
+
525
+ ' Set timeouts
526
+ web_Http.SetTimeouts Me.TimeoutMs, Me.TimeoutMs, Me.TimeoutMs, Me.TimeoutMs
527
+
528
+ ' Load auto-proxy (if needed)
529
+ If Me.enableAutoProxy Then
530
+ web_LoadAutoProxy Request
531
+ End If
532
+
533
+ ' Setup proxy
534
+ ' See http://msdn.microsoft.com/en-us/library/windows/desktop/aa384059(v=vs.85).aspx for details
535
+ If Me.proxyServer <> "" Then
536
+ WebHelpers.LogDebug "SetProxy: " & Me.proxyServer, "WebClient.PrepareHttpRequest"
537
+ web_Http.SetProxy web_HttpRequest_ProxySetting_Proxy, Me.proxyServer, Me.proxyBypassList
538
+
539
+ If Me.proxyUsername <> "" Then
540
+ WebHelpers.LogDebug "SetProxyCredentials: " & Me.proxyUsername & ", " & WebHelpers.Obfuscate(Me.proxyPassword), "WebClient.PrepareHttpRequest"
541
+ web_Http.SetCredentials Me.proxyUsername, Me.proxyPassword, web_HttpRequest_SetCredentials_ForProxy
542
+ End If
543
+ Else
544
+ ' Attempt to get proxy setup with Proxycfg.exe, otherwise direct
545
+ web_Http.SetProxy web_HttpRequest_ProxySetting_PreConfig
546
+ End If
547
+
548
+ ' Setup security
549
+ If Me.insecure Then
550
+ ' - Disable certifcate revocation check
551
+ ' - Ignore all SSL errors
552
+ ' Unknown certification authority (CA) or untrusted root, 0x0100
553
+ ' Wrong usage, 0x0200
554
+ ' Invalid common name (CN), 0x1000
555
+ ' Invalid date or certificate expired, 0x2000
556
+ ' = 0x3300 = 13056
557
+ ' - Enable https-to-http redirects
558
+ web_Http.Option(web_WinHttpRequestOption.web_WinHttpRequestOption_EnableCertificateRevocationCheck) = False
559
+ web_Http.Option(web_WinHttpRequestOption.web_WinHttpRequestOption_SslErrorIgnoreFlags) = 13056
560
+ web_Http.Option(web_WinHttpRequestOption.web_WinHttpRequestOption_EnableHttpsToHttpRedirects) = True
561
+ Else
562
+ ' By default:
563
+ ' - Enable certificate revocation check (especially useful after HeartBleed)
564
+ ' - Ignore no SLL erros
565
+ ' - Disable https-to-http redirects
566
+ web_Http.Option(web_WinHttpRequestOption.web_WinHttpRequestOption_EnableCertificateRevocationCheck) = True
567
+ web_Http.Option(web_WinHttpRequestOption.web_WinHttpRequestOption_SslErrorIgnoreFlags) = 0
568
+ web_Http.Option(web_WinHttpRequestOption.web_WinHttpRequestOption_EnableHttpsToHttpRedirects) = False
569
+ End If
570
+
571
+ ' Setup redirects
572
+ web_Http.Option(web_WinHttpRequestOption.web_WinHttpRequestOption_EnableRedirects) = Me.followRedirects
573
+
574
+ ' Set headers on http request (after open)
575
+ For Each web_KeyValue In Request.headers
576
+ web_Http.SetRequestHeader web_KeyValue("Key"), web_KeyValue("Value")
577
+ Next web_KeyValue
578
+
579
+ For Each web_KeyValue In Request.Cookies
580
+ web_Http.SetRequestHeader "Cookie", web_KeyValue("Key") & "=" & web_KeyValue("Value")
581
+ Next web_KeyValue
582
+
583
+ ' Give authenticator opportunity to update Http
584
+ If Not Me.Authenticator Is Nothing Then
585
+ Me.Authenticator.PrepareHttp Me, Request, web_Http
586
+ End If
587
+
588
+ ' Log request and return
589
+ WebHelpers.LogRequest Me, Request
590
+ Set PrepareHttpRequest = web_Http
591
+ Exit Function
592
+
593
+ web_ErrorHandling:
594
+
595
+ Set web_Http = Nothing
596
+ Err.Raise 11012 + vbObjectError, "WebClient.PrepareHttpRequest", _
597
+ "An error occurred while preparing http request" & vbNewLine & _
598
+ Err.Number & VBA.IIf(Err.Number < 0, " (" & VBA.LCase$(VBA.Hex$(Err.Number)) & ")", "") & ": " & Err.Description
599
+ End Function
600
+
601
+ ''
602
+ ' Prepare cURL request for given WebRequest
603
+ '
604
+ ' @internal
605
+ ' @method PrepareCurlRequest
606
+ ' @param {WebRequest} Request
607
+ ' @return {String}
608
+ ' @throws 11013 / 80042b05 / -2147210491 - Error preparing cURL request
609
+ ''
610
+ Public Function PrepareCurlRequest(Request As WebRequest) As String
611
+ Dim web_Curl As String
612
+ Dim web_KeyValue As Dictionary
613
+ Dim web_CookieString As String
614
+
615
+ On Error GoTo web_ErrorHandling
616
+
617
+ web_Curl = "curl -i"
618
+
619
+ ' Setup authenticator
620
+ web_BeforeExecute Request
621
+
622
+ ' Set timeouts
623
+ ' (max time = resolve + sent + receive)
624
+ web_Curl = web_Curl & " --connect-timeout " & Me.TimeoutMs / 1000
625
+ web_Curl = web_Curl & " --max-time " & 3 * Me.TimeoutMs / 1000
626
+
627
+ ' Setup proxy
628
+ If Me.proxyServer <> "" Then
629
+ web_Curl = web_Curl & " --proxy " & Me.proxyServer
630
+
631
+ If Me.proxyBypassList <> "" Then
632
+ web_Curl = web_Curl & " --noproxy " & Me.proxyBypassList
633
+ End If
634
+ If Me.proxyUsername <> "" Then
635
+ web_Curl = web_Curl & " --proxy-user " & Me.proxyUsername & ":" & Me.proxyPassword
636
+ End If
637
+ End If
638
+
639
+ ' Setup security
640
+ If Me.insecure Then
641
+ web_Curl = web_Curl & " --insecure"
642
+ End If
643
+
644
+ ' Setup redirects
645
+ If Me.followRedirects Then
646
+ web_Curl = web_Curl & " --location"
647
+ End If
648
+
649
+ ' Set headers and cookies
650
+ For Each web_KeyValue In Request.headers
651
+ web_Curl = web_Curl & " -H '" & web_KeyValue("Key") & ": " & web_KeyValue("Value") & "'"
652
+ Next web_KeyValue
653
+
654
+ For Each web_KeyValue In Request.Cookies
655
+ web_CookieString = web_CookieString & web_KeyValue("Key") & "=" & web_KeyValue("Value") & ";"
656
+ Next web_KeyValue
657
+ If web_CookieString <> "" Then
658
+ web_Curl = web_Curl & " --cookie '" & web_CookieString & "'"
659
+ End If
660
+
661
+ ' Add method (CHANGED from here to end of function)
662
+ web_Curl = web_Curl & " -X " & WebHelpers.MethodToName(Request.Method)
663
+
664
+ ' Add data
665
+ Dim TempFileName As String
666
+ TempFileName = "xlwings-" & CreateGUID() & ".txt"
667
+ Open TempFileName For Output As #1
668
+ Print #1, Request.Body
669
+ Close #1
670
+ web_Curl = web_Curl & " -d @" & TempFileName
671
+
672
+ ' Add url
673
+ web_Curl = web_Curl & " '" & Me.GetFullUrl(Request) & "'"
674
+
675
+ ' Give authenticator opportunity to update cURL
676
+ If Not Me.Authenticator Is Nothing Then
677
+ Me.Authenticator.PrepareCurl Me, Request, web_Curl
678
+ End If
679
+
680
+ ' Log request
681
+ WebHelpers.LogRequest Me, Request
682
+
683
+ ' Remove data file and return
684
+ PrepareCurlRequest = web_Curl & "&& rm " & TempFileName
685
+ Exit Function
686
+
687
+ web_ErrorHandling:
688
+
689
+ Err.Raise 11013 + vbObjectError, "WebClient.PrepareCURLRequest", _
690
+ "An error occurred while preparing cURL request" & vbNewLine & _
691
+ Err.Number & VBA.IIf(Err.Number < 0, " (" & VBA.LCase$(VBA.Hex$(Err.Number)) & ")", "") & ": " & Err.Description
692
+ End Function
693
+
694
+ ''
695
+ ' Clone client
696
+ '
697
+ ' @internal
698
+ ' @method Clone
699
+ ' @return {WebClient}
700
+ ''
701
+ Public Function Clone() As WebClient
702
+ Set Clone = New WebClient
703
+ Clone.BaseUrl = Me.BaseUrl
704
+ Clone.proxyServer = Me.proxyServer
705
+ Clone.proxyBypassList = Me.proxyBypassList
706
+ Clone.proxyUsername = Me.proxyUsername
707
+ Clone.proxyPassword = Me.proxyPassword
708
+ Clone.enableAutoProxy = Me.enableAutoProxy
709
+ Clone.TimeoutMs = Me.TimeoutMs
710
+ Clone.insecure = Me.insecure
711
+ Set Clone.Authenticator = Me.Authenticator
712
+ End Function
713
+
714
+ ' ============================================= '
715
+ ' Private Methods
716
+ ' ============================================= '
717
+
718
+ Private Sub web_BeforeExecute(web_Request As WebRequest)
719
+ If Not Me.Authenticator Is Nothing Then
720
+ Me.Authenticator.BeforeExecute Me, web_Request
721
+ End If
722
+
723
+ ' Preparing request includes adding headers
724
+ ' -> Needs to happen after BeforeExecute in case headers were changed
725
+ web_Request.Prepare
726
+ End Sub
727
+
728
+ Private Sub web_LoadAutoProxy(web_Request As WebRequest)
729
+ #If Win32 Or Win64 Then
730
+ On Error GoTo web_ErrorHandling
731
+
732
+ Dim web_Parts As Dictionary
733
+ Dim web_Domain As String
734
+ Dim web_ProxyServer As String
735
+ Dim web_ProxyBypassList As String
736
+
737
+ Set web_Parts = WebHelpers.GetUrlParts(Me.GetFullUrl(web_Request))
738
+ web_Domain = VBA.IIf(web_Parts("Protocol") <> "", web_Parts("Protocol") & "://", "") & _
739
+ web_Parts("Host") & ":" & web_Parts("Port")
740
+
741
+ ' Cache auto-proxy by domain
742
+ If web_Domain <> web_pAutoProxyDomain Then
743
+ ' Cache first to store error as no proxy
744
+ web_pAutoProxyDomain = web_Domain
745
+
746
+ WebHelpers.GetAutoProxy web_Domain, web_ProxyServer, web_ProxyBypassList
747
+
748
+ WebHelpers.LogDebug "Loaded auto-proxy for " & web_Domain & ":" & vbNewLine & _
749
+ "Server = " & web_ProxyServer & vbNewLine & _
750
+ "Bypass List = " & web_ProxyBypassList
751
+
752
+ ' Store proxy server in underlying to avoid turning off auto-proxy
753
+ web_pProxyServer = web_ProxyServer
754
+ Me.proxyBypassList = web_ProxyBypassList
755
+ End If
756
+
757
+ Exit Sub
758
+
759
+ web_ErrorHandling:
760
+
761
+ WebHelpers.LogError "An error occurred while loading auto-proxy" & vbNewLine & _
762
+ Err.Number & VBA.IIf(Err.Number < 0, " (" & VBA.LCase$(VBA.Hex$(Err.Number)) & ")", "") & ": " & Err.Description, _
763
+ "WebClient.LoadAutoProxy", Err.Number
764
+ #End If
765
+ End Sub
766
+
767
+ Private Sub Class_Initialize()
768
+ Me.TimeoutMs = web_DefaultTimeoutMs
769
+ Me.enableAutoProxy = False
770
+ Me.insecure = False
771
+ Me.followRedirects = True
772
+ End Sub