-
Notifications
You must be signed in to change notification settings - Fork 3
/
Fetch.brs
100 lines (96 loc) · 3.7 KB
/
Fetch.brs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
' options: {
' url: [req] string - http or https url
' timeout: [opt] int - ms to wait before timeout (defaults to 0 (no timeout))
' headers: [opt] assocarray - list of request headers where key=headername and val=headervalue
' method: [opt] string - the HTTP method. GET|POST|PUT|DELETE|etc (defaults to GET)
' if you are doing a normal GET or POST, you can omit this - it is only useful for the other verbs
' body: [opt] string - the preformatted request body (ie: form data).
' if specified, the request method will default to POST unless overridden with options.method
' }
'
' returns Response object: {
' status: int - the HTTP status code (ex: 200); can be negative to indicate transport error
' ok: bool - true if the response is successful (200-299)
' headers: assocarray - where each header name is a key and the value is an object
' text(): string - function that returns the raw string response
' json(): object - function that returns the response parsed as JSON
' xml(): object - function that returns the response parsed as an roXmlElement
' }
'
function fetch(options)
timeout = options.timeout
if timeout = invalid then timeout = 0
response = invalid
port = CreateObject("roMessagePort")
request = CreateObject("roUrlTransfer")
request.SetCertificatesFile("common:/certs/ca-bundle.crt")
request.InitClientCertificates()
request.RetainBodyOnError(true)
request.SetMessagePort(port)
if options.headers <> invalid
for each header in options.headers
val = options.headers[header]
if val <> invalid then request.addHeader(header, val)
end for
end if
if options.method <> invalid
request.setRequest(options.method)
end if
request.SetUrl(options.url)
requestSent = invalid
if options.body <> invalid
requestSent = request.AsyncPostFromString(options.body)
else
requestSent = request.AsyncGetToString()
end if
if (requestSent)
msg = wait(timeout, port)
status = -999
body = "(TIMEOUT)"
headers = {}
if (type(msg) = "roUrlEvent")
status = msg.GetResponseCode()
headersArray = msg.GetResponseHeadersArray()
for each headerObj in headersArray
for each headerName in headerObj
val = {
value: headerObj[headerName]
next: invalid
}
current = headers[headerName]
if current <> invalid
prev = current
while current <> invalid
prev = current
current = current.next
end while
prev.next = val
else
headers[headerName] = val
end if
end for
end for
body = msg.GetString()
if status < 0 then body = msg.GetFailureReason()
end if
response = {
_body: body,
status: status,
ok: (status >= 200 AND status < 300),
headers: headers,
text: function()
return m._body
end function,
json: function()
return ParseJSON(m._body)
end function,
xml: function()
if m._body = invalid then return invalid
xml = CreateObject("roXMLElement") '
if NOT xml.Parse(m._body) then return invalid
return xml
end function
}
end if
return response
end function