
/* curl.q: libcurl interface
   $Id: curl.q,v 1.2 2006/04/25 17:40:42 agraef Exp $ */

/* This file is part of the Q programming system.

   The Q programming system is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option) any
   later version.

   The Q programming system is distributed in the hope that it will be
   useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */

import clib;

/* This module gives access to libcurl's "easy" API functions, which enables
   you to transfer files with URL syntax in a uniform and convenient way. The
   interface closely follows the C API. For a closer description of the
   operations provided by this module please refer to the libcurl manual
   pages. */

/* Manifest constants. The libcurl operations are controlled by a bunch of
   symbolic constants which are used to set transfer options and retrieve
   information about a completed transfer with the curl_setopt and
   curl_getinfo functions. NOTE: Currently the options and infos from libcurl
   versions up to 7.10.2 are supported. Also note the absence of
   CURLOPT_ERRORBUFFER; this option is only used internally to return error
   messages with curl_error (see below) when available. */

public var const

  /* Error codes. */

  CURLE_OK, CURLE_UNSUPPORTED_PROTOCOL, CURLE_FAILED_INIT,
  CURLE_URL_MALFORMAT, CURLE_URL_MALFORMAT_USER,
  CURLE_COULDNT_RESOLVE_PROXY, CURLE_COULDNT_RESOLVE_HOST,
  CURLE_COULDNT_CONNECT,
  CURLE_FTP_WEIRD_SERVER_REPLY, CURLE_FTP_ACCESS_DENIED,
  CURLE_FTP_USER_PASSWORD_INCORRECT, CURLE_FTP_WEIRD_PASS_REPLY,
  CURLE_FTP_WEIRD_USER_REPLY, CURLE_FTP_WEIRD_PASV_REPLY,
  CURLE_FTP_WEIRD_227_FORMAT, CURLE_FTP_CANT_GET_HOST,
  CURLE_FTP_CANT_RECONNECT, CURLE_FTP_COULDNT_SET_BINARY,
  CURLE_PARTIAL_FILE, CURLE_FTP_COULDNT_RETR_FILE,
  CURLE_FTP_WRITE_ERROR, CURLE_FTP_QUOTE_ERROR,
  CURLE_HTTP_NOT_FOUND, CURLE_WRITE_ERROR,
  CURLE_MALFORMAT_USER, CURLE_FTP_COULDNT_STOR_FILE,
  CURLE_READ_ERROR, CURLE_OUT_OF_MEMORY,
  CURLE_OPERATION_TIMEOUTED,
  CURLE_FTP_COULDNT_SET_ASCII, CURLE_FTP_PORT_FAILED,
  CURLE_FTP_COULDNT_USE_REST, CURLE_FTP_COULDNT_GET_SIZE,
  CURLE_HTTP_RANGE_ERROR, CURLE_HTTP_POST_ERROR,
  CURLE_SSL_CONNECT_ERROR, CURLE_BAD_DOWNLOAD_RESUME,
  CURLE_FILE_COULDNT_READ_FILE, CURLE_LDAP_CANNOT_BIND,
  CURLE_LDAP_SEARCH_FAILED, CURLE_LIBRARY_NOT_FOUND,
  CURLE_FUNCTION_NOT_FOUND, CURLE_ABORTED_BY_CALLBACK,
  CURLE_BAD_FUNCTION_ARGUMENT, CURLE_BAD_CALLING_ORDER,
  CURLE_HTTP_PORT_FAILED, CURLE_BAD_PASSWORD_ENTERED,
  CURLE_TOO_MANY_REDIRECTS, CURLE_UNKNOWN_TELNET_OPTION,
  CURLE_TELNET_OPTION_SYNTAX, CURLE_OBSOLETE,
  CURLE_SSL_PEER_CERTIFICATE, CURLE_GOT_NOTHING,
  CURLE_SSL_ENGINE_NOTFOUND, CURLE_SSL_ENGINE_SETFAILED,
  CURLE_SEND_ERROR, CURLE_RECV_ERROR,
  CURLE_SHARE_IN_USE, CURLE_SSL_CERTPROBLEM,
  CURLE_SSL_CIPHER, CURLE_SSL_CACERT,
  CURLE_BAD_CONTENT_ENCODING,

  /* Information types passed to the CURLOPT_DEBUGFUNCTION callback. */

  CURLINFO_TEXT, CURLINFO_HEADER_IN, CURLINFO_HEADER_OUT,
  CURLINFO_DATA_IN, CURLINFO_DATA_OUT,

  /* Tags used to describe the sections of multipart/formdata posts issued
     with the CURLOPT_HTTPPOST option. */

  CURLFORM_CONTENT, CURLFORM_FILECONTENT, CURLFORM_FILE, CURLFORM_BUFFER,

  /* Values for the CURLOPT_NETRC option. */

  CURL_NETRC_OPTIONAL, CURL_NETRC_IGNORED, CURL_NETRC_REQUIRED,

  /* Values for the CURLOPT_TIMECONDITION option. */

  CURL_TIMECOND_IFMODSINCE, CURL_TIMECOND_IFUNMODSINCE,

  /* Values for the CURLOPT_HTTP_VERSION option. */

  CURL_HTTP_VERSION_NONE, CURL_HTTP_VERSION_1_0, CURL_HTTP_VERSION_1_1,

  /* Values for the CURLOPT_CLOSEPOLICY option. */

  CURLCLOSEPOLICY_LEAST_RECENTLY_USED, CURLCLOSEPOLICY_OLDEST,

  /* Symbolic option values. */

  CURLOPT_VERBOSE, CURLOPT_HEADER, CURLOPT_NOPROGRESS, CURLOPT_NOSIGNAL,

  CURLOPT_WRITEFUNCTION, CURLOPT_READFUNCTION, CURLOPT_PROGRESSFUNCTION,
  CURLOPT_PASSWDFUNCTION, CURLOPT_HEADERFUNCTION, CURLOPT_DEBUGFUNCTION,

  CURLOPT_FAILONERROR,

  CURLOPT_URL, CURLOPT_PROXY, CURLOPT_PROXYPORT, CURLOPT_PROXYTYPE,
  CURLOPT_HTTPPROXYTUNNEL, CURLOPT_INTERFACE, CURLOPT_DNS_CACHE_TIMEOUT,
  CURLOPT_DNS_USE_GLOBAL_CACHE, CURLOPT_BUFFERSIZE,

  CURLOPT_NETRC, CURLOPT_USERPWD, CURLOPT_PROXYUSERPWD,

  CURLOPT_ENCODING, CURLOPT_FOLLOWLOCATION, CURLOPT_MAXREDIRS,
  CURLOPT_PUT, CURLOPT_POST, CURLOPT_POSTFIELDS, CURLOPT_POSTFIELDSIZE,
  CURLOPT_HTTPPOST, CURLOPT_REFERER, CURLOPT_USERAGENT, CURLOPT_HTTPHEADER,
  CURLOPT_COOKIE, CURLOPT_COOKIEFILE, CURLOPT_COOKIEJAR,
  CURLOPT_TIMECONDITION, CURLOPT_TIMEVALUE, CURLOPT_HTTPGET,
  CURLOPT_HTTP_VERSION,

  CURLOPT_FTPPORT, CURLOPT_QUOTE, CURLOPT_POSTQUOTE, CURLOPT_PREQUOTE,
  CURLOPT_FTPLISTONLY, CURLOPT_FTPAPPEND, CURLOPT_FTP_USE_EPSV,

  CURLOPT_TRANSFERTEXT, CURLOPT_CRLF, CURLOPT_RANGE, CURLOPT_RESUME_FROM,
  CURLOPT_CUSTOMREQUEST, CURLOPT_FILETIME, CURLOPT_NOBODY, CURLOPT_INFILESIZE,
  CURLOPT_UPLOAD,

  CURLOPT_TIMEOUT, CURLOPT_LOW_SPEED_LIMIT, CURLOPT_LOW_SPEED_TIME,
  CURLOPT_MAXCONNECTS, CURLOPT_CLOSEPOLICY, CURLOPT_FRESH_CONNECT,
  CURLOPT_FORBID_REUSE, CURLOPT_CONNECTTIMEOUT,

  CURLOPT_SSLCERT, CURLOPT_SSLCERTTYPE, CURLOPT_SSLCERTPASSWD,
  CURLOPT_SSLKEY, CURLOPT_SSLKEYTYPE,CURLOPT_SSLKEYPASSWD,
  CURLOPT_SSLENGINE, CURLOPT_SSLENGINE_DEFAULT, CURLOPT_SSLVERSION,
  CURLOPT_SSL_VERIFYPEER, CURLOPT_CAINFO, CURLOPT_CAPATH,
  CURLOPT_RANDOM_FILE, CURLOPT_EGDSOCKET, CURLOPT_SSL_VERIFYHOST,
  CURLOPT_SSL_CIPHER_LIST, CURLOPT_KRB4LEVEL,

  /* Symbolic info values. */

  CURLINFO_EFFECTIVE_URL, CURLINFO_HTTP_CODE, CURLINFO_FILETIME,
  CURLINFO_TOTAL_TIME, CURLINFO_NAMELOOKUP_TIME, CURLINFO_CONNECT_TIME,
  CURLINFO_PRETRANSFER_TIME, CURLINFO_STARTTRANSFER_TIME,
  CURLINFO_REDIRECT_TIME, CURLINFO_REDIRECT_COUNT,
  CURLINFO_SIZE_UPLOAD, CURLINFO_SIZE_DOWNLOAD,
  CURLINFO_SPEED_DOWNLOAD, CURLINFO_SPEED_UPLOAD,
  CURLINFO_HEADER_SIZE, CURLINFO_REQUEST_SIZE,
  CURLINFO_SSL_VERIFYRESULT,
  CURLINFO_CONTENT_LENGTH_DOWNLOAD, CURLINFO_CONTENT_LENGTH_UPLOAD,
  CURLINFO_CONTENT_TYPE;

private extern curl_vars;

def
 (CURLE_OK, CURLE_UNSUPPORTED_PROTOCOL, CURLE_FAILED_INIT,
  CURLE_URL_MALFORMAT, CURLE_URL_MALFORMAT_USER,
  CURLE_COULDNT_RESOLVE_PROXY, CURLE_COULDNT_RESOLVE_HOST,
  CURLE_COULDNT_CONNECT,
  CURLE_FTP_WEIRD_SERVER_REPLY, CURLE_FTP_ACCESS_DENIED,
  CURLE_FTP_USER_PASSWORD_INCORRECT, CURLE_FTP_WEIRD_PASS_REPLY,
  CURLE_FTP_WEIRD_USER_REPLY, CURLE_FTP_WEIRD_PASV_REPLY,
  CURLE_FTP_WEIRD_227_FORMAT, CURLE_FTP_CANT_GET_HOST,
  CURLE_FTP_CANT_RECONNECT, CURLE_FTP_COULDNT_SET_BINARY,
  CURLE_PARTIAL_FILE, CURLE_FTP_COULDNT_RETR_FILE,
  CURLE_FTP_WRITE_ERROR, CURLE_FTP_QUOTE_ERROR,
  CURLE_HTTP_NOT_FOUND, CURLE_WRITE_ERROR,
  CURLE_MALFORMAT_USER, CURLE_FTP_COULDNT_STOR_FILE,
  CURLE_READ_ERROR, CURLE_OUT_OF_MEMORY,
  CURLE_OPERATION_TIMEOUTED,
  CURLE_FTP_COULDNT_SET_ASCII, CURLE_FTP_PORT_FAILED,
  CURLE_FTP_COULDNT_USE_REST, CURLE_FTP_COULDNT_GET_SIZE,
  CURLE_HTTP_RANGE_ERROR, CURLE_HTTP_POST_ERROR,
  CURLE_SSL_CONNECT_ERROR, CURLE_BAD_DOWNLOAD_RESUME,
  CURLE_FILE_COULDNT_READ_FILE, CURLE_LDAP_CANNOT_BIND,
  CURLE_LDAP_SEARCH_FAILED, CURLE_LIBRARY_NOT_FOUND,
  CURLE_FUNCTION_NOT_FOUND, CURLE_ABORTED_BY_CALLBACK,
  CURLE_BAD_FUNCTION_ARGUMENT, CURLE_BAD_CALLING_ORDER,
  CURLE_HTTP_PORT_FAILED, CURLE_BAD_PASSWORD_ENTERED,
  CURLE_TOO_MANY_REDIRECTS, CURLE_UNKNOWN_TELNET_OPTION,
  CURLE_TELNET_OPTION_SYNTAX, CURLE_OBSOLETE,
  CURLE_SSL_PEER_CERTIFICATE, CURLE_GOT_NOTHING,
  CURLE_SSL_ENGINE_NOTFOUND, CURLE_SSL_ENGINE_SETFAILED,
  CURLE_SEND_ERROR, CURLE_RECV_ERROR,
  CURLE_SHARE_IN_USE, CURLE_SSL_CERTPROBLEM,
  CURLE_SSL_CIPHER, CURLE_SSL_CACERT,
  CURLE_BAD_CONTENT_ENCODING,

  CURLINFO_TEXT, CURLINFO_HEADER_IN, CURLINFO_HEADER_OUT,
  CURLINFO_DATA_IN, CURLINFO_DATA_OUT,

  CURLFORM_CONTENT, CURLFORM_FILECONTENT, CURLFORM_FILE, CURLFORM_BUFFER,

  CURL_NETRC_OPTIONAL, CURL_NETRC_IGNORED, CURL_NETRC_REQUIRED,

  CURL_TIMECOND_IFMODSINCE, CURL_TIMECOND_IFUNMODSINCE,

  CURL_HTTP_VERSION_NONE, CURL_HTTP_VERSION_1_0, CURL_HTTP_VERSION_1_1,

  CURLCLOSEPOLICY_LEAST_RECENTLY_USED, CURLCLOSEPOLICY_OLDEST,

  CURLOPT_VERBOSE, CURLOPT_HEADER, CURLOPT_NOPROGRESS, CURLOPT_NOSIGNAL,

  CURLOPT_WRITEFUNCTION, CURLOPT_READFUNCTION, CURLOPT_PROGRESSFUNCTION,
  CURLOPT_PASSWDFUNCTION, CURLOPT_HEADERFUNCTION, CURLOPT_DEBUGFUNCTION,

  CURLOPT_FAILONERROR,

  CURLOPT_URL, CURLOPT_PROXY, CURLOPT_PROXYPORT, CURLOPT_PROXYTYPE,
  CURLOPT_HTTPPROXYTUNNEL, CURLOPT_INTERFACE, CURLOPT_DNS_CACHE_TIMEOUT,
  CURLOPT_DNS_USE_GLOBAL_CACHE, CURLOPT_BUFFERSIZE,

  CURLOPT_NETRC, CURLOPT_USERPWD, CURLOPT_PROXYUSERPWD,

  CURLOPT_ENCODING, CURLOPT_FOLLOWLOCATION, CURLOPT_MAXREDIRS,
  CURLOPT_PUT, CURLOPT_POST, CURLOPT_POSTFIELDS, CURLOPT_POSTFIELDSIZE,
  CURLOPT_HTTPPOST, CURLOPT_REFERER, CURLOPT_USERAGENT, CURLOPT_HTTPHEADER,
  CURLOPT_COOKIE, CURLOPT_COOKIEFILE, CURLOPT_COOKIEJAR,
  CURLOPT_TIMECONDITION, CURLOPT_TIMEVALUE, CURLOPT_HTTPGET,
  CURLOPT_HTTP_VERSION,

  CURLOPT_FTPPORT, CURLOPT_QUOTE, CURLOPT_POSTQUOTE, CURLOPT_PREQUOTE,
  CURLOPT_FTPLISTONLY, CURLOPT_FTPAPPEND, CURLOPT_FTP_USE_EPSV,

  CURLOPT_TRANSFERTEXT, CURLOPT_CRLF, CURLOPT_RANGE, CURLOPT_RESUME_FROM,
  CURLOPT_CUSTOMREQUEST, CURLOPT_FILETIME, CURLOPT_NOBODY, CURLOPT_INFILESIZE,
  CURLOPT_UPLOAD,

  CURLOPT_TIMEOUT, CURLOPT_LOW_SPEED_LIMIT, CURLOPT_LOW_SPEED_TIME,
  CURLOPT_MAXCONNECTS, CURLOPT_CLOSEPOLICY, CURLOPT_FRESH_CONNECT,
  CURLOPT_FORBID_REUSE, CURLOPT_CONNECTTIMEOUT,

  CURLOPT_SSLCERT, CURLOPT_SSLCERTTYPE, CURLOPT_SSLCERTPASSWD,
  CURLOPT_SSLKEY, CURLOPT_SSLKEYTYPE,CURLOPT_SSLKEYPASSWD,
  CURLOPT_SSLENGINE, CURLOPT_SSLENGINE_DEFAULT, CURLOPT_SSLVERSION,
  CURLOPT_SSL_VERIFYPEER, CURLOPT_CAINFO, CURLOPT_CAPATH,
  CURLOPT_RANDOM_FILE, CURLOPT_EGDSOCKET, CURLOPT_SSL_VERIFYHOST,
  CURLOPT_SSL_CIPHER_LIST, CURLOPT_KRB4LEVEL,

  CURLINFO_EFFECTIVE_URL, CURLINFO_HTTP_CODE, CURLINFO_FILETIME,
  CURLINFO_TOTAL_TIME, CURLINFO_NAMELOOKUP_TIME, CURLINFO_CONNECT_TIME,
  CURLINFO_PRETRANSFER_TIME, CURLINFO_STARTTRANSFER_TIME,
  CURLINFO_REDIRECT_TIME, CURLINFO_REDIRECT_COUNT,
  CURLINFO_SIZE_UPLOAD, CURLINFO_SIZE_DOWNLOAD,
  CURLINFO_SPEED_DOWNLOAD, CURLINFO_SPEED_UPLOAD,
  CURLINFO_HEADER_SIZE, CURLINFO_REQUEST_SIZE,
  CURLINFO_SSL_VERIFYRESULT,
  CURLINFO_CONTENT_LENGTH_DOWNLOAD, CURLINFO_CONTENT_LENGTH_UPLOAD,
  CURLINFO_CONTENT_TYPE) = curl_vars;

/* Curl connection handles. Handle objects are returned by the curl_init
   function. To initiate a transfer after the handle has been created, you
   first have to set the transfer options (at least the target URL, maybe also
   local files, callbacks, other input data, etc.) with curl_setopt, then call
   curl_perform on the connection handle. After curl_perform returns, the
   transfer is finished and you can set new options as needed and call
   curl_perform again for the next transfer. When done, the handle can be
   closed with curl_cleanup; this also happens automatically when a connection
   handle is garbage-collected. */

public extern type Curl;

public iscurl X;

iscurl H:Curl		= true;
iscurl _		= false otherwise;

/* The curl_init function is used to open a new connection handle. An existing
   handle can be closed with curl_cleanup; after that all operations on this
   handle will fail. */

public extern curl_init, curl_cleanup H;

/* The curl_setopt operation is used with the symbolic option values
   (CURLOPT_*) in the manifest constants section to set various options for
   the transfer.

   Most options take either Bool, Int or String values (a zero resp. nonzero
   Int value can be used interchangeably with false resp. true for options
   requiring a truth value). Note that all passed values (except Bool or Int
   which are copied) will be cached as long as the handle is open, so you
   should call curl_cleanup as soon as possible to free the cached resources.

   The CURLOPT_HTTPHEADER, CURLOPT_QUOTE and CURLOPT_POSTQUOTE options each
   expect a list of String values. The CURLOPT_HTTPPOST option needs a list of
   multipart/formdata HTTP POST sections encoded as tuples. Each section
   starts with the name of the field (a string) and a symbolic tag describing
   the type of section, followed by additional string data as detailed
   below. The CONTENT_TYPE field is always optional; if present, it specifies
   the MIME type of the posted data, such as "text/html".

   - (NAME, CURLFORM_CONTENT, DATA[, CONTENT_TYPE]): Specifies a simple
     content section with the given name and data. The data can either be
     given as an ordinary (character) string or as a byte string.     

   - (NAME, CURLFORM_FILECONTENT, DATAFILE[, CONTENT_TYPE]): Like above, but
     the data is taken from the file named DATAFILE (a string).

   - (NAME, CURLFORM_FILE, DATAFILE[, FILENAME[, CONTENT_TYPE]]): Specifies a
     file upload section. If present, the FILENAME field (a string) specifies
     the filename to be used in the upload part instead of the actual filename
     in DATAFILE.

   - (NAME, CURLFORM_BUFFER, DATA, FILENAME[, CONTENT_TYPE]): Like above, but
     the file contents is taken from the given DATA string (or byte string)
     instead of a file. Note that here the FILENAME field is mandatory.

   File uploads may actually involve multiple parts, by repeating the
   CURLFORM_FILE/BUFFER, DATA/DATAFILE, FILENAME, CONTENT_TYPE fields
   accordingly.

   The callback options each take a Q expression CB as their value which will
   be applied to some parameters and evaluated when the callback is invoked
   during execution of curl_perform. The different callbacks are invoked as
   follows:

   - CURLOPT_WRITEFUNCTION: CB DATA, where DATA denotes the byte string to be
     written; return the number of bytes actually written (which should equal
     #DATA unless you want the transfer to abort with an error message)

   - CURLOPT_READFUNCTION: CB SIZE, where SIZE denotes the maximum number of
     bytes to be read; return the read data as a byte string (an empty byte
     string signals end of file and terminates the current transfer)

   - CURLOPT_PROGRESSFUNCTION: CB (DLTOTAL,DLNOW,ULTOTAL,ULNOW), where
     DLTOTAL/DLNOW denote the current progress in a download, and ULTOTAL/
     ULNOW the current progress in an upload operation (all parameters are
     floating point values); return () unless the transfer is to be aborted
     with an error message

   - CURLOPT_PASSWDFUNCTION: CB PROMPT SIZE, where PROMPT is a prompt string,
     and SIZE the maximum length of the password; return the password read
     from the user as a string (which will be truncated to the given SIZE if
     necessary) or any other value to abort the process with an error message

   - CURLOPT_HEADERFUNCTION: CB DATA, where DATA is the header data (a byte
     string) that needs to be recorded; return either the number of bytes
     actually written or -1 to signal an error condition

   - CURLOPT_DEBUGFUNCTION: CB H INFO DATA, where H is the connection handle,
     INFO the type of information passed to the callback (one of the CURLINFO
     constants) and DATA the corresponding informational text, header or other
     data as a byte string; return ()  */

public extern curl_setopt H OPT VAL;

/* The following operation actually starts the transfer. It returns when the
   transfer is finished. The function also calls the callbacks set up with
   curl_setopt when appropriate. */

public extern curl_perform H;

/* After the transfer is finished you can obtain various information about it
   with the following operation, which is used with the symbolic CURLINFO_*
   values in the manifest constants section. */

public extern curl_getinfo H INFO;

/* Error handling. If any of the libcurl functions returns an error code, the
   following symbol is used to return that code along with a readable error
   message (if available). You can redefine this function as appropriate for
   the application. */

public curl_error CODE MSG;

/* Utility functions. The curl_version function returns the libcurl version as
   a string, curl_escape and curl_unescape are used to quote resp. unquote
   special characters in URL strings. */

public extern curl_version;

public extern curl_escape S, curl_unescape S;
