about summary refs log tree commit diff stats
path: root/src/bindings/curl.nim
blob: 07395b6503996e2245f627ab5bf1c5a8a2f5540e (plain) (blame)
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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
const curllib = (func(): string =
  when defined(windows): return "libcurl.dll"
  elif defined(macos): return "libcurl(|.4|.4.8.0).dylib"
  else: return "libcurl.so(|.4|.4.8.0)" # assume posix
)()

const
  CURL_GLOBAL_SSL* = 1 shl 0 # no purpose since 7.57.0
  CURL_GLOBAL_WIN32* = 1 shl 1
  CURL_GLOBAL_ALL* = CURL_GLOBAL_SSL or CURL_GLOBAL_WIN32
  CURL_GLOBAL_NOTHING* = 0
  CURL_GLOBAL_DEFAULT* = CURL_GLOBAL_ALL
  CURL_GLOBAL_ACK_EINTR* = 1 shl 2

const
  CURLOPTTYPE_LONG = 0
  CURLOPTTYPE_OBJECTPOINT = 10000
  CURLOPTTYPE_FUNCTIONPOINT = 20000
  CURLOPTTYPE_OFF_T = 30000
  CURLOPTTYPE_BLOB = 40000

const
  CURLOPTTYPE_STRINGPOINT = CURLOPTTYPE_OBJECTPOINT
  CURLOPTTYPE_SLISTPOINT = CURLOPTTYPE_OBJECTPOINT
  CURLOPTTYPE_CBPOINT = CURLOPTTYPE_OBJECTPOINT
  CURLOPTTYPE_VALUES = CURLOPTTYPE_LONG

const
  CURLINFO_STRING = 0x100000
  CURLINFO_LONG = 0x200000
  CURLINFO_DOUBLE = 0x300000
  CURLINFO_SLIST = 0x400000
  CURLINFO_PTR = 0x400000 # same as SLIST
  CURLINFO_SOCKET = 0x500000
  CURLINFO_OFF_T = 0x600000
  CURLINFO_MASK {.used.} = 0x0fffff
  CURLINFO_TYPEMASK {.used.} = 0xf00000

const
  CURL_WAIT_POLLIN* = 0x0001
  CURL_WAIT_POLLPRI* = 0x0002
  CURL_WAIT_POLLOUT* = 0x0004

{.push cdecl, dynlib: curllib.}

type
  CURL* = distinct pointer
  CURLM* = distinct pointer

  curl_mime_struct = object
  curl_mime* = ptr curl_mime_struct
  curl_mimepart_struct = object
  curl_mimepart* = ptr curl_mimepart_struct
  curl_slist_struct = object
  curl_slist* = ptr curl_slist_struct
  curl_socket_t = cint
  curl_waitfd* = object
    fd*: curl_socket_t
    events*: cshort
    revents*: cshort # this is, in fact, supported.
  CURLMsg_data {.union.} = object
    whatever: pointer
    result*: CURLcode
  CURLMsg_struct = object
    msg*: CURLMSG_E
    easy_handle*: CURL
    data*: CURLMsg_data
  CURLMsg* = ptr CURLMsg_struct

  CURLoption* {.size: sizeof(cint).} = enum
    # Long
    CURLOPT_PORT = CURLOPTTYPE_LONG + 3
    CURLOPT_SSLVERSION = CURLOPTTYPE_VALUES + 32
    CURLOPT_TIMECONDITION = CURLOPTTYPE_VALUES + 33
    CURLOPT_POST = CURLOPTTYPE_LONG + 47
    CURLOPT_FOLLOWLOCATION = CURLOPTTYPE_LONG + 52
    CURLOPT_POSTFIELDSIZE = CURLOPTTYPE_LONG + 60
    CURLOPT_HTTPGET = CURLOPTTYPE_LONG + 80
    CURLOPT_CONNECT_ONLY = CURLOPTTYPE_LONG + 141

    # Objectpoint
    CURLOPT_WRITEDATA = CURLOPTTYPE_CBPOINT + 1
    CURLOPT_URL = CURLOPTTYPE_STRINGPOINT + 2
    CURLOPT_PROXY = CURLOPTTYPE_STRINGPOINT + 4
    CURLOPT_POSTFIELDS = CURLOPTTYPE_OBJECTPOINT + 15
    CURLOPT_HTTPHEADER = CURLOPTTYPE_SLISTPOINT + 23
    CURLOPT_HEADERDATA = CURLOPTTYPE_CBPOINT + 29
    CURLOPT_MIMEPOST = CURLOPTTYPE_OBJECTPOINT + 269

    # Functionpoint
    CURLOPT_WRITEFUNCTION = CURLOPTTYPE_FUNCTIONPOINT + 11
    CURLOPT_READFUNCTION = CURLOPTTYPE_FUNCTIONPOINT + 12
    CURLOPT_HEADERFUNCTION = CURLOPTTYPE_FUNCTIONPOINT + 79

    # Off-t
    CURLOPT_INFILESIZE_LARGE = CURLOPTTYPE_OFF_T + 115
    CURLOPT_RESUME_FROM_LARGE = CURLOPTTYPE_OFF_T + 116

    # Blob
    CURLOPT_SSLCERT_BLOB = CURLOPTTYPE_BLOB + 291
    CURLOPT_SSLKEY_BLOB = CURLOPTTYPE_BLOB + 292
    CURLOPT_PROXY_SSLCERT_BLOB = CURLOPTTYPE_BLOB + 293
    CURLOPT_PROXY_SSLKEY_BLOB = CURLOPTTYPE_BLOB + 294
    CURLOPT_ISSUECERT_BLOB = CURLOPTTYPE_BLOB + 295

  CURLINFO* {.size: sizeof(cint).} = enum
    CURLINFO_NONE # first, never use this

    # String
    CURLINFO_REDIRECT_URL = CURLINFO_STRING + 31

    # Long
    CURLINFO_RESPONSE_CODE = CURLINFO_LONG + 2

    # Double
    CURLINFO_TOTAL_TIME = CURLINFO_DOUBLE + 3

    # S-list
    CURLINFO_SSL_ENGINES = CURLINFO_SLIST + 27
    CURLINFO_COOKIELIST = CURLINFO_SLIST + 28

    # Pointer
    CURLINFO_CERTINFO = CURLINFO_PTR + 34
    CURLINFO_TLS_SESSION = CURLINFO_PTR + 43
    CURLINFO_TLS_SSL_PTR = CURLINFO_PTR + 45

    # Socket
    CURLINFO_ACTIVESOCKET = CURLINFO_SOCKET + 44

    # Off_t
    CURLINFO_SIZE_UPLOAD_T = CURLINFO_OFF_T + 7
    CURLINFO_SIZE_DOWNLOAD_T = CURLINFO_OFF_T + 9

  CURLcode* {.size: sizeof(cint).} = enum
    CURLE_OK = 0,
    CURLE_UNSUPPORTED_PROTOCOL,    # 1 
    CURLE_FAILED_INIT,             # 2 
    CURLE_URL_MALFORMAT,           # 3 
    CURLE_NOT_BUILT_IN,            # 4 - [was obsoleted in August 2007 for
                                   # 7.17.0, reused in April 2011 for 7.21.5]
    CURLE_COULDNT_RESOLVE_PROXY,   # 5 
    CURLE_COULDNT_RESOLVE_HOST,    # 6 
    CURLE_COULDNT_CONNECT,         # 7 
    CURLE_WEIRD_SERVER_REPLY,      # 8 
    CURLE_REMOTE_ACCESS_DENIED,    # 9 a service was denied by the server
                                   # due to lack of access - when login fails
                                   # this is not returned.
    CURLE_FTP_ACCEPT_FAILED,       # 10 - [was obsoleted in April 2006 for
                                   # 7.15.4, reused in Dec 2011 for 7.24.0]
    CURLE_FTP_WEIRD_PASS_REPLY,    # 11 
    CURLE_FTP_ACCEPT_TIMEOUT,      # 12 - timeout occurred accepting server
                                   # [was obsoleted in August 2007 for 7.17.0,
                                   # reused in Dec 2011 for 7.24.0]
    CURLE_FTP_WEIRD_PASV_REPLY,    # 13 
    CURLE_FTP_WEIRD_227_FORMAT,    # 14 
    CURLE_FTP_CANT_GET_HOST,       # 15 
    CURLE_HTTP2,                   # 16 - A problem in the http2 framing layer.
                                   # [was obsoleted in August 2007 for 7.17.0,
                                   # reused in July 2014 for 7.38.0]
    CURLE_FTP_COULDNT_SET_TYPE,    # 17 
    CURLE_PARTIAL_FILE,            # 18 
    CURLE_FTP_COULDNT_RETR_FILE,   # 19 
    CURLE_OBSOLETE20,              # 20 - NOT USED 
    CURLE_QUOTE_ERROR,             # 21 - quote command failure 
    CURLE_HTTP_RETURNED_ERROR,     # 22 
    CURLE_WRITE_ERROR,             # 23 
    CURLE_OBSOLETE24,              # 24 - NOT USED 
    CURLE_UPLOAD_FAILED,           # 25 - failed upload "command" 
    CURLE_READ_ERROR,              # 26 - couldn't open/read from file 
    CURLE_OUT_OF_MEMORY,           # 27 
    CURLE_OPERATION_TIMEDOUT,      # 28 - the timeout time was reached 
    CURLE_OBSOLETE29,              # 29 - NOT USED 
    CURLE_FTP_PORT_FAILED,         # 30 - FTP PORT operation failed 
    CURLE_FTP_COULDNT_USE_REST,    # 31 - the REST command failed 
    CURLE_OBSOLETE32,              # 32 - NOT USED 
    CURLE_RANGE_ERROR,             # 33 - RANGE "command" didn't work 
    CURLE_HTTP_POST_ERROR,         # 34 
    CURLE_SSL_CONNECT_ERROR,       # 35 - wrong when connecting with SSL 
    CURLE_BAD_DOWNLOAD_RESUME,     # 36 - couldn't resume download 
    CURLE_FILE_COULDNT_READ_FILE,  # 37 
    CURLE_LDAP_CANNOT_BIND,        # 38 
    CURLE_LDAP_SEARCH_FAILED,      # 39 
    CURLE_OBSOLETE40,              # 40 - NOT USED 
    CURLE_FUNCTION_NOT_FOUND,      # 41 - NOT USED starting with 7.53.0 
    CURLE_ABORTED_BY_CALLBACK,     # 42 
    CURLE_BAD_FUNCTION_ARGUMENT,   # 43 
    CURLE_OBSOLETE44,              # 44 - NOT USED 
    CURLE_INTERFACE_FAILED,        # 45 - CURLOPT_INTERFACE failed 
    CURLE_OBSOLETE46,              # 46 - NOT USED 
    CURLE_TOO_MANY_REDIRECTS,      # 47 - catch endless re-direct loops 
    CURLE_UNKNOWN_OPTION,          # 48 - User specified an unknown option 
    CURLE_SETOPT_OPTION_SYNTAX,    # 49 - Malformed setopt option 
    CURLE_OBSOLETE50,              # 50 - NOT USED 
    CURLE_OBSOLETE51,              # 51 - NOT USED 
    CURLE_GOT_NOTHING,             # 52 - when this is a specific error 
    CURLE_SSL_ENGINE_NOTFOUND,     # 53 - SSL crypto engine not found 
    CURLE_SSL_ENGINE_SETFAILED,    # 54 - can not set SSL crypto engine as
                                   # default
    CURLE_SEND_ERROR,              # 55 - failed sending network data 
    CURLE_RECV_ERROR,              # 56 - failure in receiving network data 
    CURLE_OBSOLETE57,              # 57 - NOT IN USE 
    CURLE_SSL_CERTPROBLEM,         # 58 - problem with the local certificate 
    CURLE_SSL_CIPHER,              # 59 - couldn't use specified cipher 
    CURLE_PEER_FAILED_VERIFICATION, # 60 - peer's certificate or fingerprint
                                   # wasn't verified fine
    CURLE_BAD_CONTENT_ENCODING,    # 61 - Unrecognized/bad encoding 
    CURLE_OBSOLETE62,              # 62 - NOT IN USE since 7.82.0 
    CURLE_FILESIZE_EXCEEDED,       # 63 - Maximum file size exceeded 
    CURLE_USE_SSL_FAILED,          # 64 - Requested FTP SSL level failed 
    CURLE_SEND_FAIL_REWIND,        # 65 - Sending the data requires a rewind
                                   # that failed
    CURLE_SSL_ENGINE_INITFAILED,   # 66 - failed to initialise ENGINE 
    CURLE_LOGIN_DENIED,            # 67 - user, password or similar was not
                                   # accepted and we failed to login
    CURLE_TFTP_NOTFOUND,           # 68 - file not found on server 
    CURLE_TFTP_PERM,               # 69 - permission problem on server 
    CURLE_REMOTE_DISK_FULL,        # 70 - out of disk space on server 
    CURLE_TFTP_ILLEGAL,            # 71 - Illegal TFTP operation 
    CURLE_TFTP_UNKNOWNID,          # 72 - Unknown transfer ID 
    CURLE_REMOTE_FILE_EXISTS,      # 73 - File already exists 
    CURLE_TFTP_NOSUCHUSER,         # 74 - No such user 
    CURLE_CONV_FAILED,             # 75 - conversion failed 
    CURLE_OBSOLETE76,              # 76 - NOT IN USE since 7.82.0 
    CURLE_SSL_CACERT_BADFILE,      # 77 - could not load CACERT file, missing
                                   # or wrong format
    CURLE_REMOTE_FILE_NOT_FOUND,   # 78 - remote file not found 
    CURLE_SSH,                     # 79 - error from the SSH layer, somewhat
                                   # generic so the error message will be of
                                   # interest when this has happened

    CURLE_SSL_SHUTDOWN_FAILED,     # 80 - Failed to shut down the SSL
                                   # connection
    CURLE_AGAIN,                   # 81 - socket is not ready for send/recv,
                                   # wait till it's ready and try again (Added
                                   # in 7.18.2)
    CURLE_SSL_CRL_BADFILE,         # 82 - could not load CRL file, missing or
                                   # wrong format (Added in 7.19.0)
    CURLE_SSL_ISSUER_ERROR,        # 83 - Issuer check failed.  (Added in
                                   # 7.19.0)
    CURLE_FTP_PRET_FAILED,         # 84 - a PRET command failed 
    CURLE_RTSP_CSEQ_ERROR,         # 85 - mismatch of RTSP CSeq numbers 
    CURLE_RTSP_SESSION_ERROR,      # 86 - mismatch of RTSP Session Ids 
    CURLE_FTP_BAD_FILE_LIST,       # 87 - unable to parse FTP file list 
    CURLE_CHUNK_FAILED,            # 88 - chunk callback reported error 
    CURLE_NO_CONNECTION_AVAILABLE, # 89 - No connection available, the
                                   # session will be queued
    CURLE_SSL_PINNEDPUBKEYNOTMATCH, # 90 - specified pinned public key did not
                                   #  match
    CURLE_SSL_INVALIDCERTSTATUS,   # 91 - invalid certificate status 
    CURLE_HTTP2_STREAM,            # 92 - stream error in HTTP/2 framing layer
    CURLE_RECURSIVE_API_CALL,      # 93 - an api function was called from
                                   # inside a callback
    CURLE_AUTH_ERROR,              # 94 - an authentication function returned an
                                   # error
    CURLE_HTTP3,                   # 95 - An HTTP/3 layer problem 
    CURLE_QUIC_CONNECT_ERROR,      # 96 - QUIC connection error 
    CURLE_PROXY,                   # 97 - proxy handshake error 
    CURLE_SSL_CLIENTCERT,          # 98 - client-side certificate required 
    CURLE_UNRECOVERABLE_POLL,      # 99 - poll/select returned fatal error 
    CURL_LAST # never use! 

  CURLMcode* {.size: sizeof(cint).} = enum
    CURLM_CALL_MULTI_PERFORM = -1, # please call curl_multi_perform() or
                                   #   curl_multi_socket*() soon
    CURLM_OK,
    CURLM_BAD_HANDLE,      # the passed-in handle is not a valid CURLM handle
    CURLM_BAD_EASY_HANDLE, # an easy handle was not good/valid
    CURLM_OUT_OF_MEMORY,   # if you ever get this, you're in deep sh*t
    CURLM_INTERNAL_ERROR,  # this is a libcurl bug
    CURLM_BAD_SOCKET,      # the passed in socket argument did not match
    CURLM_UNKNOWN_OPTION,  # curl_multi_setopt() with unsupported option
    CURLM_ADDED_ALREADY,   # an easy handle already added to a multi handle was
                           #   attempted to get added - again
    CURLM_RECURSIVE_API_CALL, # an api function was called from inside a
                              #   callback
    CURLM_WAKEUP_FAILURE,  # wakeup is unavailable or failed
    CURLM_BAD_FUNCTION_ARGUMENT, # function called with a bad parameter
    CURLM_ABORTED_BY_CALLBACK,
    CURLM_UNRECOVERABLE_POLL,
    CURLM_LAST

  CURLMSG_E* {.size: sizeof(cint).} = enum
    CURLMSG_NONE # first, not used
    CURLMSG_DONE # This easy handle has completed. 'result' contains
                 # the CURLcode of the transfer
    CURLMSG_LAST # last, not used

proc `==`*(a: CURL, b: CURL): bool {.borrow.}
proc `==`*(a: CURLM, b: CURLM): bool {.borrow.}

{.push importc.}

proc curl_global_init*(flags: clong): CURLcode
proc curl_global_cleanup*()

proc curl_easy_init*(): CURL
proc curl_easy_cleanup*(handle: CURL)
proc curl_easy_setopt*(handle: CURL, option: CURLoption): CURLcode {.varargs.}
proc curl_easy_perform*(handle: CURL): CURLcode
proc curl_easy_getinfo*(handle: CURL, info: CURLINFO): CURLcode {.varargs.}
proc curl_easy_strerror*(errornum: CURLcode): cstring

proc curl_mime_init*(handle: CURL): curl_mime
proc curl_mime_free*(mime: curl_mime)
proc curl_mime_addpart*(mime: curl_mime): curl_mimepart
proc curl_mime_name*(part: curl_mimepart, name: cstring)
proc curl_mime_data*(part: curl_mimepart, data: pointer, datasize: csize_t)
proc curl_mime_filename*(part: curl_mimepart, name: cstring)
proc curl_mime_filedata*(part: curl_mimepart, filename: cstring)

proc curl_slist_append*(slist: curl_slist, str: cstring): curl_slist
proc curl_slist_free_all*(slist: curl_slist)

proc curl_multi_init*(): CURLM
proc curl_multi_add_handle*(multi_handle: CURLM, curl_handle: CURL): CURLMcode
proc curl_multi_remove_handle*(multi_handle: CURLM, curl_handle: CURL): CURLMcode
proc curl_multi_fdset*(multi_handle: CURLM, read_fd_set, write_fd_set, exc_fd_set: pointer, max_fd: ptr cint): CURLMcode
proc curl_multi_wait*(multi_handle: CURLM, extra_fds: ptr curl_waitfd, extra_nfds: cuint, timeout_ns: cint, ret: ptr cint): CURLMcode
proc curl_multi_poll*(multi_handle: CURLM, extra_fds: ptr curl_waitfd, extra_nfds: cuint, timeout_ns: cint, ret: ptr cint): CURLMcode
proc curl_multi_wakeup*(multi_handle: CURLM): CURLMcode
proc curl_multi_perform*(multi_handle: CURLM, running_handles: ptr cint): CURLMcode
proc curl_multi_cleanup*(multi_handle: CURLM): CURLMcode
proc curl_multi_info_read*(multi_handle: CURLM, msgs_in_queue: ptr cint): CURLMsg
proc curl_multi_strerror*(code: CURLMcode): cstring
{.pop.}

{.pop.}