about summary refs log blame commit diff stats
path: root/src/bindings/curl.nim
blob: 07395b6503996e2245f627ab5bf1c5a8a2f5540e (plain) (tree)


























                                                         







                                         

                                       
 




                             


                               

                           





                                           
                                     












                                                   



                                           

                                                   



                                                  
                                                 



                                               
                                               




















                                                           








                                                











                                              


                                                



                                                 































































































































                                                                                




























                                                                               









                                                                              
                                                     




                                                        
                                                                           




                                                                    











                                                                                                                                     
       

       
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.}