Skip to content

Commit db6b29a

Browse files
committed
Merge pull request #20 from timhall/execute-refactor
Refactor Execute and ExecuteAsync
2 parents 4ee85ea + a363143 commit db6b29a

File tree

5 files changed

+132
-110
lines changed

5 files changed

+132
-110
lines changed

build/export.vbs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ Set Args = Wscript.Arguments
1818
If Args.Length > 0 Then
1919
WBPath = Args(0)
2020
OutputPath = Args(1)
21+
Else
22+
WBPath = "specs\Excel-REST - Specs.xlsm"
23+
OutputPath = "src\"
2124
End If
2225

2326
' Setup modules to export

specs/Excel-REST - Specs.xlsm

-870 Bytes
Binary file not shown.

src/RestClient.cls

Lines changed: 17 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -46,37 +46,19 @@ Public ProxyBypassList As Variant
4646
' --------------------------------------------- '
4747

4848
Public Function Execute(Request As RestRequest) As RestResponse
49-
Dim Response As RestResponse
50-
Dim Http As Object
51-
Dim HeaderKey As Variant
52-
5349
On Error GoTo ErrorHandling
54-
Set Http = CreateObject("MSXML2.ServerXMLHTTP.6.0")
55-
HttpSetup Http, Request, False
56-
57-
' Send the request
58-
Http.send Request.Body
50+
Dim Http As Object
5951

60-
' Handle response
61-
Set Response = Request.CreateResponseFromHttp(Http)
52+
Set Http = HttpSetup(Request, False)
53+
Set Execute = RestHelpers.ExecuteRequest(Http, Request)
6254

6355
ErrorHandling:
6456

6557
If Not Http Is Nothing Then Set Http = Nothing
66-
6758
If Err.Number <> 0 Then
68-
If InStr(Err.Description, "The operation timed out") > 0 Then
69-
' Return 408
70-
Set Response = Request.CreateResponse(StatusCodes.RequestTimeout, "Request Timeout")
71-
Err.Clear
72-
Else
73-
' Rethrow error
74-
Err.Raise Err.Number, Description:=Err.Description
75-
End If
59+
' Rethrow error
60+
Err.Raise Err.Number, Description:=Err.Description
7661
End If
77-
78-
Set Execute = Response
79-
8062
End Function
8163

8264
''
@@ -89,35 +71,20 @@ End Function
8971
' --------------------------------------------- '
9072

9173
Public Function ExecuteAsync(Request As RestRequest, Callback As String, Optional ByVal CallbackArgs As Variant) As Boolean
92-
Dim Response As New RestResponse
93-
Dim Http As Object
94-
9574
On Error GoTo ErrorHandling
75+
Dim Http As Object
9676

9777
' Setup the request
98-
Set Http = CreateObject("MSXML2.ServerXMLHTTP.6.0")
99-
HttpSetup Http, Request, True
100-
Request.Callback = Callback
101-
Request.CallbackArgs = CallbackArgs
102-
103-
' Send the request
104-
Request.StartTimeoutTimer Me.TimeoutMS
105-
Http.send Request.Body
106-
107-
' Clean up and return
78+
Set Http = HttpSetup(Request, True)
79+
RestHelpers.ExecuteRequestAsync Http, Request, TimeoutMS, Callback, CallbackArgs
10880
ExecuteAsync = True
10981
Exit Function
11082

11183
ErrorHandling:
11284

85+
' Close Http and rethrow error
11386
If Not Http Is Nothing Then Set Http = Nothing
114-
If Not Response Is Nothing Then Set Response = Nothing
115-
116-
If Err.Number <> 0 Then
117-
' Rethrow error
118-
Err.Raise Err.Number, Description:=Err.Description
119-
End If
120-
87+
Err.Raise Err.Number, Description:=Err.Description
12188
End Function
12289

12390
''
@@ -142,24 +109,24 @@ End Sub
142109
' Private Methods
143110
' ============================================= '
144111

145-
Private Sub HttpSetup(ByRef Http As Object, ByRef Request As RestRequest, Optional UseAsync As Boolean = False)
146-
RestHelpers.PrepareHttpRequest Http, Request, Me.TimeoutMS, UseAsync
112+
Private Function HttpSetup(ByRef Request As RestRequest, Optional UseAsync As Boolean = False) As Object
113+
Set HttpSetup = RestHelpers.PrepareHttpRequest(Request, Me.TimeoutMS, UseAsync)
147114

148115
If Me.ProxyServer <> "" Then
149-
RestHelpers.PrepareProxyForHttpRequest Http, Me.ProxyServer, Me.ProxyUsername, Me.ProxyPassword, Me.ProxyBypassList
116+
RestHelpers.PrepareProxyForHttpRequest HttpSetup, Me.ProxyServer, Me.ProxyUsername, Me.ProxyPassword, Me.ProxyBypassList
150117
End If
151118

152119
' Before execute and http open hooks for authenticator
153120
If Not Me.Authenticator Is Nothing Then
154121
Me.Authenticator.BeforeExecute Request
155-
Me.Authenticator.HttpOpen Http, Request, Me.BaseUrl, UseAsync
122+
Me.Authenticator.HttpOpen HttpSetup, Request, Me.BaseUrl, UseAsync
156123
Else
157124
' Nothing hooked in so open http object
158-
Http.Open Request.MethodName(), Request.FullUrl(Me.BaseUrl), UseAsync
125+
HttpSetup.Open Request.MethodName(), Request.FullUrl(Me.BaseUrl), UseAsync
159126
End If
160127

161-
RestHelpers.SetHeaders Http, Request
162-
End Sub
128+
RestHelpers.SetHeaders HttpSetup, Request
129+
End Function
163130

164131
Private Sub Class_Initialize()
165132
Me.TimeoutMS = DefaultTimeoutMS

src/RestClientBase.bas

Lines changed: 43 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ Attribute VB_Name = "RestClientBase"
1515
' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ '
1616
Option Explicit
1717

18+
' > Customize with BaseUrl
19+
Private Const DefaultBaseUrl As String = ""
1820
Private Const TimeoutMS As Integer = 5000
1921
Private Initialized As Boolean
2022

@@ -48,12 +50,13 @@ Private Sub HttpOpen(ByRef Http As Object, ByRef Request As RestRequest, BaseUrl
4850
Http.Open Request.MethodName(), Request.FullUrl(BaseUrl), UseAsync
4951
End Sub
5052

51-
' > Customize with BaseUrl and other properties
53+
5254
Private Sub Initialize()
53-
' BaseUrl = "https://..."
54-
' ProxyServer = "..."
55-
' ProxyUsername = "..."
56-
' ProxyPassword = "..."
55+
If BaseUrl = "" Then
56+
BaseUrl = DefaultBaseUrl
57+
End If
58+
59+
' > Customize with any properties
5760

5861
Initialized = True
5962
End Sub
@@ -70,36 +73,19 @@ End Sub
7073
' --------------------------------------------- '
7174

7275
Public Function Execute(Request As RestRequest) As RestResponse
73-
Dim Response As RestResponse
74-
Dim Http As Object
75-
Dim HeaderKey As Variant
76-
7776
On Error GoTo ErrorHandling
78-
Set Http = CreateObject("MSXML2.ServerXMLHTTP.6.0")
79-
HttpSetup Http, Request, False
80-
81-
' Send the request
82-
Http.send Request.Body
77+
Dim Http As Object
8378

84-
' Handle response
85-
Set Response = Request.CreateResponseFromHttp(Http)
79+
Set Http = HttpSetup(Request, False)
80+
Set Execute = RestHelpers.ExecuteRequest(Http, Request)
8681

8782
ErrorHandling:
8883

8984
If Not Http Is Nothing Then Set Http = Nothing
90-
9185
If Err.Number <> 0 Then
92-
If InStr(Err.Description, "The operation timed out") > 0 Then
93-
' Return 408
94-
Set Response = Request.CreateResponse(StatusCodes.RequestTimeout, "Request Timeout")
95-
Err.Clear
96-
Else
97-
' Rethrow error
98-
Err.Raise Err.Number, Description:=Err.Description
99-
End If
86+
' Rethrow error
87+
Err.Raise Err.Number, Description:=Err.Description
10088
End If
101-
102-
Set Execute = Response
10389
End Function
10490

10591
''
@@ -112,50 +98,52 @@ End Function
11298
' --------------------------------------------- '
11399

114100
Public Function ExecuteAsync(Request As RestRequest, Callback As String, Optional ByVal CallbackArgs As Variant) As Boolean
115-
Dim Response As New RestResponse
116-
Dim Http As Object
117-
118101
On Error GoTo ErrorHandling
102+
Dim Http As Object
119103

120104
' Setup the request
121-
Set Http = CreateObject("MSXML2.ServerXMLHTTP.6.0")
122-
HttpSetup Http, Request, True
123-
Request.Callback = Callback
124-
Request.CallbackArgs = CallbackArgs
125-
126-
' Send the request
127-
Request.StartTimeoutTimer TimeoutMS
128-
Http.send Request.Body
129-
130-
' Clean up and return
105+
Set Http = HttpSetup(Request, True)
106+
RestHelpers.ExecuteRequestAsync Http, Request, TimeoutMS, Callback, CallbackArgs
131107
ExecuteAsync = True
132108
Exit Function
133109

134110
ErrorHandling:
135111

112+
' Close Http and rethrow error
136113
If Not Http Is Nothing Then Set Http = Nothing
137-
If Not Response Is Nothing Then Set Response = Nothing
138-
139-
If Err.Number <> 0 Then
140-
' Rethrow error
141-
Err.Raise Err.Number, Description:=Err.Description
142-
End If
114+
Err.Raise Err.Number, Description:=Err.Description
143115
End Function
144116

145-
Private Sub HttpSetup(ByRef Http As Object, ByRef Request As RestRequest, Optional UseAsync As Boolean = False)
146-
If Not Initialized Then: Initialize
147-
148-
RestHelpers.PrepareHttpRequest Http, Request, TimeoutMS, UseAsync
117+
''
118+
' Setup proxy server
119+
'
120+
' @param {String} ProxyServer
121+
' @param {String} [Username=""]
122+
' @param {String} [Password=""]
123+
' @param {Variant} [BypassList]
124+
' --------------------------------------------- '
125+
126+
Public Sub SetupProxy(ProxyServer As String, _
127+
Optional Username As String = "", Optional Password As String = "", Optional BypassList As Variant)
149128

129+
ProxyServer = ProxyServer
130+
ProxyUsername = ProxyUsername
131+
ProxyPassword = ProxyPassword
132+
BypassList = BypassList
133+
End Sub
134+
135+
Private Function HttpSetup(ByRef Request As RestRequest, Optional UseAsync As Boolean = False) As Object
136+
If Not Initialized Then: Initialize
150137

138+
Set HttpSetup = RestHelpers.PrepareHttpRequest(Request, TimeoutMS, UseAsync)
139+
151140
If ProxyServer <> "" Then
152-
RestHelpers.PrepareProxyForHttpRequest Http, ProxyServer, ProxyUsername, ProxyPassword, ProxyBypassList
141+
RestHelpers.PrepareProxyForHttpRequest HttpSetup, ProxyServer, ProxyUsername, ProxyPassword, ProxyBypassList
153142
End If
154143

155144
' Before execute and http open hooks for authentication
156145
BeforeExecute Request
157-
HttpOpen Http, Request, BaseUrl, UseAsync
146+
HttpOpen HttpSetup, Request, BaseUrl, UseAsync
158147

159-
RestHelpers.SetHeaders Http, Request
160-
End Sub
161-
148+
RestHelpers.SetHeaders HttpSetup, Request
149+
End Function

src/RestHelpers.bas

Lines changed: 69 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -228,14 +228,16 @@ End Function
228228
''
229229
' Prepare http request for execution
230230
'
231-
' @param {Object} Http request
232231
' @param {RestRequest} Request
233232
' @param {Integer} TimeoutMS
234233
' @param {Boolean} [UseAsync=False]
234+
' @return {Object} Setup http object
235235
' --------------------------------------------- '
236236

237-
Public Sub PrepareHttpRequest(ByRef Http As Object, Request As RestRequest, TimeoutMS As Integer, _
238-
Optional UseAsync As Boolean = False)
237+
Public Function PrepareHttpRequest(Request As RestRequest, TimeoutMS As Integer, _
238+
Optional UseAsync As Boolean = False) As Object
239+
Dim Http As Object
240+
Set Http = CreateObject("MSXML2.ServerXMLHTTP.6.0")
239241

240242
' Set timeouts
241243
Http.setTimeouts TimeoutMS, TimeoutMS, TimeoutMS, TimeoutMS
@@ -257,7 +259,9 @@ Public Sub PrepareHttpRequest(ByRef Http As Object, Request As RestRequest, Time
257259
Set Request.HttpRequest = Http
258260
Http.onreadystatechange = Request
259261
End If
260-
End Sub
262+
263+
Set PrepareHttpRequest = Http
264+
End Function
261265

262266
''
263267
' Set headers to http object for given request
@@ -277,9 +281,9 @@ End Sub
277281
' Prepare proxy for http object
278282
'
279283
' @param {String} ProxyServer
280-
' @param {Variant} [BypassList]
281284
' @param {String} [Username=""]
282285
' @param {String} [Password=""]
286+
' @param {Variant} [BypassList]
283287
' --------------------------------------------- '
284288

285289
Public Sub PrepareProxyForHttpRequest(ByRef Http As Object, ProxyServer As String, _
@@ -292,7 +296,67 @@ Public Sub PrepareProxyForHttpRequest(ByRef Http As Object, ProxyServer As Strin
292296
Http.SetProxyCredentials Username, Password
293297
End If
294298
End If
299+
End Sub
300+
301+
''
302+
' Execute request synchronously
303+
'
304+
' @param {Object} Http
305+
' @param {RestRequest} Request The request to execute
306+
' @return {RestResponse} Wrapper of server response for request
307+
' --------------------------------------------- '
308+
309+
Public Function ExecuteRequest(ByRef Http As Object, ByRef Request As RestRequest) As RestResponse
310+
On Error GoTo ErrorHandling
311+
Dim Response As RestResponse
312+
313+
' Send the request and handle response
314+
Http.Send Request.Body
315+
Set Response = Request.CreateResponseFromHttp(Http)
316+
317+
ErrorHandling:
318+
319+
If Not Http Is Nothing Then Set Http = Nothing
320+
If Err.Number <> 0 Then
321+
If InStr(Err.Description, "The operation timed out") > 0 Then
322+
' Return 408
323+
Set Response = Request.CreateResponse(StatusCodes.RequestTimeout, "Request Timeout")
324+
Err.Clear
325+
Else
326+
' Rethrow error
327+
Err.Raise Err.Number, Description:=Err.Description
328+
End If
329+
End If
330+
331+
Set ExecuteRequest = Response
332+
End Function
333+
334+
''
335+
' Execute request asynchronously
336+
'
337+
' @param {Object} Http
338+
' @param {RestRequest} Request The request to execute
339+
' @param {String} Callback Name of function to call when request completes (specify "" if none)
340+
' @param {Variant} [CallbackArgs] Variable array of arguments that get passed directly to callback function
341+
' --------------------------------------------- '
342+
343+
Public Sub ExecuteRequestAsync(ByRef Http As Object, ByRef Request As RestRequest, TimeoutMS As Integer, Callback As String, Optional ByVal CallbackArgs As Variant)
344+
On Error GoTo ErrorHandling
345+
346+
Request.Callback = Callback
347+
Request.CallbackArgs = CallbackArgs
295348

349+
' Send the request
350+
Request.StartTimeoutTimer TimeoutMS
351+
Http.Send Request.Body
352+
353+
Exit Sub
354+
355+
ErrorHandling:
356+
357+
' Close http and rethrow error
358+
If Not Http Is Nothing Then Set Http = Nothing
359+
Err.Raise Err.Number, Description:=Err.Description
296360
End Sub
297361

298362
' ======================================================================================== '

0 commit comments

Comments
 (0)