-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcurl.bqn
159 lines (139 loc) · 4.91 KB
/
curl.bqn
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
⟨
# Simple API
Get,Post,
# Advanced API
OpenSession,ResetSession,CloseSession, # session management
SetURL,SetHeaders,SetVerbose,SetTimeout,SetTimeoutms,SetData, # request parameters
Perform, # perform request
⟩⇐
⟨
easyInit,
easyCleanup,
easyReset,
easySetoptStr,
easySetoptPtr,
easySetoptLong,
easyPerform,
easyGetinfoStr,
easyGetinfoLong,
easyGetinfoDouble,
slistAppend,
slistFreeAll,
fopen,
fclose,
curlOptions,
curlInfo
⟩←•Import"ffi.bqn"
⟨RandID⟩←•Import"utils.bqn"
# Simple GET request, with optional headers as left argument
Get←{
𝕊 url: ⟨⟩ 𝕊 url ;
headers 𝕊 url:
session←OpenSession @
r←Perform headers SetHeaders url SetURL session
CloseSession session
r
}
# Simple POST request, with optional headers as left argument
Post←{
𝕊 url‿data: ⟨⟩ 𝕊 url‿data ;
headers 𝕊 url‿data:
session←OpenSession @
r←Perform data SetData headers SetHeaders url SetURL session
CloseSession session
r
}
# Raise an error if the return code 𝕩 is not 0, with custom message 𝕨
Check←{
msg←"Curl: "∾𝕨∾" ("∾(•Fmt 𝕩)∾")"
msg ! 𝕩=0
}
# Create a libcurl session, with default values for user-agent and redirects
OpenSession←{𝕊𝕩:
sessionPtr←EasyInit⟨⟩
"setting user agent"Check EasySetoptStr⟨sessionPtr,curlOptions.useragent,"curl/bqn"∾@⟩
"setting redirect option"Check EasySetoptLong⟨sessionPtr,curlOptions.followlocation,1⟩
slist←SlistAppend⟨8↑0,""⟩
"creating slist" ! slist≢8↑0
{sessionPtr⇐sessionPtr,headersSlist⇐slist}
}
# Reset a libcurl session to default parameters, as if just created by
# OpenSession, but preserving open connections and caches
ResetSession←{𝕊 session:
SlistFreeAll session.headersSlist
EasyReset session.sessionPtr
"setting user agent"Check EasySetoptStr⟨session.sessionPtr,curlOptions.useragent,"curl/bqn"∾@⟩
"setting redirect option"Check EasySetoptLong⟨session.sessionPtr,curlOptions.followlocation,1⟩
slist←SlistAppend⟨8↑0,""⟩
"creating slist" ! slist≢8↑0
{sessionPtr⇐session.sessionPtr,headersSlist⇐slist}
}
# Close a libcurl session, freeing memory
CloseSession←{𝕊 session:
SlistFreeAll session.headersSlist
EasyCleanup session.sessionPtr
@
}
# Set URL for the next request
SetURL←{url 𝕊 session:
"setting URL"Check EasySetoptStr⟨session.sessionPtr,curlOptions.url,url∾@⟩
session
}
# Set headers for the next request, as a list of strings
SetHeaders←{headers 𝕊 session:
slist←session.headersSlist{SlistAppend⟨𝕩,𝕨∾@⟩}´headers
"setting headers"Check rheaders←EasySetoptPtr⟨session.sessionPtr,curlOptions.httpHeader,slist⟩
session
}
# Set the next request as verbose (logging to standard output)
SetVerbose←{𝕊 session:
"setting verbose option"Check EasySetoptLong⟨session.sessionPtr,curlOptions.verbose,1⟩
session
}
# Set timeout in seconds for the next request
SetTimeout←{timeout 𝕊 session:
"setting timeout"Check EasySetoptLong⟨session.sessionPtr,curlOptions.timeout,timeout⟩
session
}
# Set timeout in milliseconds for the next request
SetTimeoutms←{timeoutms 𝕊 session:
"setting timeout (ms)"Check EasySetoptLong⟨session.sessionPtr,curlOptions.timeoutms,timeoutms⟩
session
}
# Use a POST method and set data to post
SetData←{data 𝕊 session:
"setting up POST request"Check EasySetoptLong⟨session.sessionPtr,curlOptions.post,1⟩
"setting POST data"Check EasySetoptStr⟨session.sessionPtr,curlOptions.postfields,data⟩
"setting POST data size"Check EasySetoptLong⟨session.sessionPtr,curlOptions.postfieldsize,≠data⟩
session
}
# Perform a request and get response in a namespace
Perform←{𝕊 session:
id←RandID 32
filename←"/tmp/bqncurl."∾id
filePtr←Fopen⟨filename∾@,"w+"⟩
headerFilename←"/tmp/bqncurl.header."∾id
headerFilePtr←Fopen⟨headerFilename∾@,"w+"⟩
"setting response file target"Check EasySetoptPtr⟨session.sessionPtr,curlOptions.writedata,filePtr⟩
"setting header file target"Check EasySetoptPtr⟨session.sessionPtr,curlOptions.headerdata,headerFilePtr⟩
"performing request"Check EasyPerform⟨session.sessionPtr⟩
rcode‿⟨code⟩←EasyGetinfoLong⟨session.sessionPtr,curlInfo.responseCode,⟨0⟩⟩
"retrieving response code"Check rcode
rredirectcount‿⟨redirectCount⟩←EasyGetinfoLong⟨session.sessionPtr,curlInfo.redirectCount,⟨0⟩⟩
"retrieving redirect count"Check rredirectcount
rtime‿⟨time⟩←EasyGetinfoDouble⟨session.sessionPtr,curlInfo.totalTime,⟨0.0⟩⟩
"retrieving request time"Check rtime
Fclose filePtr
Fclose headerFilePtr
content←•file.Bytes filename
responseHeaders←•file.Chars headerFilename
•file.Remove filename
•file.Remove headerFilename
{
code⇐code,
headers⇐responseHeaders,
content⇐content,
time⇐time,
redirectCount⇐redirectCount,
}
}