Skip to content

Commit 0068c2b

Browse files
committed
Merge pull request #14 from timhall/content-length
Content length
2 parents 5313b64 + e932760 commit 0068c2b

9 files changed

+155
-55
lines changed

.gitattributes

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Auto detect text files and perform LF normalization
2+
* text=auto
3+
4+
# Custom for Visual Studio
5+
*.cs diff=csharp
6+
*.sln merge=union
7+
*.csproj merge=union
8+
*.vbproj merge=union
9+
*.fsproj merge=union
10+
*.dbproj merge=union
11+
12+
# Standard to msysgit
13+
*.doc diff=astextplain
14+
*.DOC diff=astextplain
15+
*.docx diff=astextplain
16+
*.DOCX diff=astextplain
17+
*.dot diff=astextplain
18+
*.DOT diff=astextplain
19+
*.pdf diff=astextplain
20+
*.PDF diff=astextplain
21+
*.rtf diff=astextplain
22+
*.RTF diff=astextplain

specs/Excel-REST - Specs.xlsm

5.81 KB
Binary file not shown.

specs/RestClientAsyncSpecs.bas

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ Public Function Specs() As SpecSuite
8686
.Expect(AsyncResponse.StatusDescription).ToEqual "Internal Server Error"
8787
End With
8888

89-
With Specs.It("should return 504 and close request on request timeout")
89+
With Specs.It("should return 408 and close request on request timeout")
9090
Set Request = New RestRequest
9191
Request.Resource = "timeout"
9292
Request.AddQuerystringParam "ms", 2000
@@ -96,8 +96,8 @@ Public Function Specs() As SpecSuite
9696
Wait WaitTime
9797
.Expect(AsyncResponse).ToBeDefined
9898
If Not AsyncResponse Is Nothing Then
99-
.Expect(AsyncResponse.StatusCode).ToEqual 504
100-
.Expect(AsyncResponse.StatusDescription).ToEqual "Gateway Timeout"
99+
.Expect(AsyncResponse.StatusCode).ToEqual 408
100+
.Expect(AsyncResponse.StatusDescription).ToEqual "Request Timeout"
101101
End If
102102
.Expect(Request.HttpRequest).ToBeUndefined
103103
End With

specs/RestClientSpecs.bas

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Public Function Specs() As SpecSuite
1717
Dim Client As New RestClient
1818
Dim Request As RestRequest
1919
Dim Response As RestResponse
20+
Dim Body As Object
2021

2122
Client.BaseUrl = "localhost:3000/"
2223

@@ -90,7 +91,6 @@ Public Function Specs() As SpecSuite
9091

9192
.Expect(Client.Execute(Request).Data("body")).ToEqual "Howdy!"
9293

93-
Dim Body As Object
9494
Set Body = CreateObject("Scripting.Dictionary")
9595
Body.Add "a", 3.14
9696

@@ -116,17 +116,47 @@ Public Function Specs() As SpecSuite
116116
.Expect(Response.Data("query")("d")).ToEqual "False"
117117
End With
118118

119-
With Specs.It("should return 504 on request timeout")
119+
With Specs.It("should return 408 on request timeout")
120120
Set Request = New RestRequest
121121
Request.Resource = "timeout"
122122
Request.AddQuerystringParam "ms", 2000
123123

124124
Client.TimeoutMS = 500
125125
Set Response = Client.Execute(Request)
126-
.Expect(Response.StatusCode).ToEqual 504
127-
.Expect(Response.StatusDescription).ToEqual "Gateway Timeout"
126+
.Expect(Response.StatusCode).ToEqual 408
127+
.Expect(Response.StatusDescription).ToEqual "Request Timeout"
128128
Debug.Print Response.Content
129129
End With
130+
131+
With Specs.It("should add content-length header (if enabled)")
132+
Set Request = New RestRequest
133+
Request.Resource = "text"
134+
Request.Method = httpPOST
135+
Request.ContentType = "text/plain"
136+
Request.AddBodyString "Howdy!"
137+
138+
Set Response = Client.Execute(Request)
139+
.Expect(Request.Headers("Content-Length")).ToEqual "6"
140+
141+
Request.IncludeContentLength = False
142+
Set Response = Client.Execute(Request)
143+
.Expect(Request.Headers.Exists("Content-Length")).ToEqual False
144+
145+
Set Request = New RestRequest
146+
Request.Resource = "post"
147+
Request.Method = httpPOST
148+
149+
Set Body = CreateObject("Scripting.Dictionary")
150+
Body.Add "a", 3.14
151+
Request.AddBody Body
152+
153+
Set Response = Client.Execute(Request)
154+
.Expect(Request.Headers("Content-Length")).ToEqual "10"
155+
156+
Request.IncludeContentLength = False
157+
Set Response = Client.Execute(Request)
158+
.Expect(Request.Headers.Exists("Content-Length")).ToEqual False
159+
End With
130160

131161
Set Client = Nothing
132162

specs/RestRequestSpecs.bas

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Attribute VB_Name = "RestRequestSpecs"
1313
Public Function Specs() As SpecSuite
1414
Set Specs = New SpecSuite
1515
Dim Request As RestRequest
16+
Dim Body As Object
1617

1718
Specs.Description = "RestRequest"
1819

@@ -132,8 +133,7 @@ Public Function Specs() As SpecSuite
132133

133134
With Specs.It("should only combine body and parameters if not GET Request")
134135
Set Request = New RestRequest
135-
136-
Dim Body As Object
136+
137137
Set Body = CreateObject("Scripting.Dictionary")
138138
Body.Add "A", 123
139139

@@ -243,5 +243,23 @@ Public Function Specs() As SpecSuite
243243
.Expect(Request.FormattedResource).ToEqual "?A=20&B=3.14&C=True"
244244
End With
245245

246+
With Specs.It("should allow body or body string for GET requests")
247+
Set Request = New RestRequest
248+
Request.Method = httpGET
249+
250+
Set Body = CreateObject("Scripting.Dictionary")
251+
Body.Add "A", 123
252+
253+
Request.AddBody Body
254+
.Expect(Request.Body).ToEqual "{""A"":123}"
255+
256+
Set Request = New RestRequest
257+
Request.Method = httpGET
258+
259+
Request.AddBodyString "Howdy!"
260+
.Expect(Request.Body).ToEqual "Howdy!"
261+
End With
262+
246263
InlineRunner.RunSuite Specs
247264
End Function
265+

src/RestClient.cls

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ Attribute VB_Exposed = True
1919
' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ '
2020
Option Explicit
2121

22-
Private Const UserAgent As String = "Excel Client v2.0.1 (https://github.com/timhall/Excel-REST)"
2322
Private Const DefaultTimeoutMS As Integer = 5000
2423

2524

@@ -48,7 +47,7 @@ Public Function Execute(Request As RestRequest) As RestResponse
4847
Dim HeaderKey As Variant
4948

5049
On Error GoTo ErrorHandling
51-
Set Http = CreateObject("MSXML2.ServerXMLHTTP")
50+
Set Http = CreateObject("MSXML2.ServerXMLHTTP.6.0")
5251
HttpSetup Http, Request, False
5352

5453
' Send the request
@@ -63,8 +62,8 @@ ErrorHandling:
6362

6463
If Err.Number <> 0 Then
6564
If InStr(Err.Description, "The operation timed out") > 0 Then
66-
' Return 504
67-
Set Response = Request.CreateResponse(StatusCodes.GatewayTimeout, "Gateway Timeout")
65+
' Return 408
66+
Set Response = Request.CreateResponse(StatusCodes.RequestTimeout, "Request Timeout")
6867
Err.Clear
6968
Else
7069
' Rethrow error
@@ -92,7 +91,7 @@ Public Function ExecuteAsync(Request As RestRequest, Callback As String, Optiona
9291
On Error GoTo ErrorHandling
9392

9493
' Setup the request
95-
Set Http = CreateObject("MSXML2.ServerXMLHTTP")
94+
Set Http = CreateObject("MSXML2.ServerXMLHTTP.6.0")
9695
HttpSetup Http, Request, True
9796
Request.Callback = Callback
9897
Request.CallbackArgs = CallbackArgs
@@ -122,18 +121,7 @@ End Function
122121
' ============================================= '
123122

124123
Private Sub HttpSetup(ByRef Http As Object, ByRef Request As RestRequest, Optional UseAsync As Boolean = False)
125-
' Set timeouts
126-
Http.setTimeouts Me.TimeoutMS, Me.TimeoutMS, Me.TimeoutMS, Me.TimeoutMS
127-
128-
' Add general headers to request
129-
Request.AddHeader "User-Agent", UserAgent
130-
Request.AddHeader "Content-Type", Request.ContentType()
131-
132-
' Pass http to request and setup onreadystatechange
133-
If UseAsync Then
134-
Set Request.HttpRequest = Http
135-
Http.onreadystatechange = Request
136-
End If
124+
RestHelpers.PrepareHttpRequest Http, Request, Me.TimeoutMS, UseAsync
137125

138126
' Before execute and http open hooks for authenticator
139127
If Not Me.Authenticator Is Nothing Then
@@ -144,11 +132,7 @@ Private Sub HttpSetup(ByRef Http As Object, ByRef Request As RestRequest, Option
144132
Http.Open Request.MethodName(), Request.FullUrl(Me.BaseUrl), UseAsync
145133
End If
146134

147-
' Set request headers
148-
Dim HeaderKey As Variant
149-
For Each HeaderKey In Request.Headers.keys()
150-
Http.setRequestHeader HeaderKey, Request.Headers(HeaderKey)
151-
Next HeaderKey
135+
RestHelpers.SetHeaders Http, Request
152136
End Sub
153137

154138
Private Sub Class_Initialize()

src/RestClientBase.bas

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

18-
Private Const UserAgent As String = "Excel Client v2.0.1 (https://github.com/timhall/Excel-REST)"
1918
Private Const TimeoutMS As Integer = 5000
2019
Private Initialized As Boolean
2120

@@ -69,7 +68,7 @@ Public Function Execute(Request As RestRequest) As RestResponse
6968
Dim HeaderKey As Variant
7069

7170
On Error GoTo ErrorHandling
72-
Set Http = CreateObject("MSXML2.ServerXMLHTTP")
71+
Set Http = CreateObject("MSXML2.ServerXMLHTTP.6.0")
7372
HttpSetup Http, Request, False
7473

7574
' Send the request
@@ -84,8 +83,8 @@ ErrorHandling:
8483

8584
If Err.Number <> 0 Then
8685
If InStr(Err.Description, "The operation timed out") > 0 Then
87-
' Return 504
88-
Set Response = Request.CreateResponse(StatusCodes.GatewayTimeout, "Gateway Timeout")
86+
' Return 408
87+
Set Response = Request.CreateResponse(StatusCodes.RequestTimeout, "Request Timeout")
8988
Err.Clear
9089
Else
9190
' Rethrow error
@@ -112,7 +111,7 @@ Public Function ExecuteAsync(Request As RestRequest, Callback As String, Optiona
112111
On Error GoTo ErrorHandling
113112

114113
' Setup the request
115-
Set Http = CreateObject("MSXML2.ServerXMLHTTP")
114+
Set Http = CreateObject("MSXML2.ServerXMLHTTP.6.0")
116115
HttpSetup Http, Request, True
117116
Request.Callback = Callback
118117
Request.CallbackArgs = CallbackArgs
@@ -138,28 +137,13 @@ End Function
138137

139138
Private Sub HttpSetup(ByRef Http As Object, ByRef Request As RestRequest, Optional UseAsync As Boolean = False)
140139
If Not Initialized Then: Initialize
141-
142-
' Set timeouts
143-
Http.setTimeouts TimeoutMS, TimeoutMS, TimeoutMS, TimeoutMS
144-
145-
' Add general headers to request
146-
Request.AddHeader "User-Agent", UserAgent
147-
Request.AddHeader "Content-Type", Request.ContentType()
148140

149-
' Pass http to request and setup onreadystatechange
150-
If UseAsync Then
151-
Set Request.HttpRequest = Http
152-
Http.onreadystatechange = Request
153-
End If
141+
RestHelpers.PrepareHttpRequest Http, Request, TimeoutMS, UseAsync
154142

155-
' Before execute and http open hooks for authenticator
143+
' Before execute and http open hooks for authentication
156144
BeforeExecute Request
157145
HttpOpen Http, Request, BaseUrl, UseAsync
158146

159-
' Set request headers
160-
Dim HeaderKey As Variant
161-
For Each HeaderKey In Request.Headers.keys()
162-
Http.setRequestHeader HeaderKey, Request.Headers(HeaderKey)
163-
Next HeaderKey
147+
RestHelpers.SetHeaders Http, Request
164148
End Sub
165149

src/RestHelpers.bas

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ Attribute VB_Name = "RestHelpers"
3939

4040
#End If
4141

42+
Private Const UserAgent As String = "Excel Client v2.0.1 (https://github.com/timhall/Excel-REST)"
43+
4244
' Moved to top from JSONLib
4345
Private Const INVALID_JSON As Long = 1
4446
Private Const INVALID_OBJECT As Long = 2
@@ -56,6 +58,7 @@ Public Enum StatusCodes
5658
Unauthorized = 401
5759
Forbidden = 403
5860
NotFound = 404
61+
RequestTimeout = 408
5962
UnsupportedMediaType = 415
6063
InternalServerError = 500
6164
BadGateway = 502
@@ -226,6 +229,51 @@ Public Function FilterObject(ByVal Original As Object, Whitelist As Variant) As
226229
Set FilterObject = Filtered
227230
End Function
228231

232+
''
233+
' Prepare http request for execution
234+
'
235+
' @param {Object} Http request
236+
' @param {RestRequest} Request
237+
' @param {Integer} TimeoutMS
238+
' @param {Boolean} [UseAsync=False]
239+
' --------------------------------------------- '
240+
241+
Public Sub PrepareHttpRequest(ByRef Http As Object, Request As RestRequest, TimeoutMS As Integer, Optional UseAsync As Boolean = False)
242+
' Set timeouts
243+
Http.setTimeouts TimeoutMS, TimeoutMS, TimeoutMS, TimeoutMS
244+
245+
' Add general headers to request
246+
Request.AddHeader "User-Agent", UserAgent
247+
Request.AddHeader "Content-Type", Request.ContentType
248+
249+
If Request.IncludeContentLength Then
250+
Request.AddHeader "Content-Length", Request.ContentLength
251+
Else
252+
If Request.Headers.Exists("Content-Length") Then
253+
Request.Headers.Remove "Content-Length"
254+
End If
255+
End If
256+
257+
' Pass http to request and setup onreadystatechange
258+
If UseAsync Then
259+
Set Request.HttpRequest = Http
260+
Http.onreadystatechange = Request
261+
End If
262+
End Sub
263+
264+
''
265+
' Set headers to http object for given request
266+
'
267+
' @param {Object} Http request
268+
' @param {RestRequest} Request
269+
' --------------------------------------------- '
270+
271+
Public Sub SetHeaders(ByRef Http As Object, Request As RestRequest)
272+
Dim HeaderKey As Variant
273+
For Each HeaderKey In Request.Headers.keys()
274+
Http.setRequestHeader HeaderKey, Request.Headers(HeaderKey)
275+
Next HeaderKey
276+
End Sub
229277

230278

231279
' ======================================================================================== '

0 commit comments

Comments
 (0)