4 * Header file for the TclCurl extension to enable Tcl interpreters
7 * Copyright (c) 2001-2011 Andres Garcia Garcia.
9 * See the file "license.terms" for information on usage and redistribution
10 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
14 #if (defined(WIN32) || defined(_WIN32))
15 #define CURL_STATICLIB 1
18 #include <curl/curl.h>
19 #include <curl/easy.h>
25 #define _MPRINTF_REPLACE
26 #include <curl/mprintf.h>
33 * Windows needs to know which symbols to export. Unix does not.
34 * BUILD_tclcurl should be undefined for Unix.
35 * Actually I don't use this, but it was in TEA so I keep in case
36 * I ever understand what it is for.
40 #undef TCL_STORAGE_CLASS
41 #define TCL_STORAGE_CLASS DLLEXPORT
44 #define TclCurlVersion "7.22.0"
47 * This struct will contain the data of a transfer if the user wants
48 * to put the body into a Tcl variable
56 * Struct that will be used for a linked list with all the
59 struct formArrayStruct {
60 struct curl_forms *formArray;
61 struct curl_slist *formHeaderList;
62 struct formArrayStruct *next;
68 Tcl_Command shareToken;
70 struct curl_slist *headerList;
71 struct curl_slist *quote;
72 struct curl_slist *prequote;
73 struct curl_slist *postquote;
74 struct curl_httppost *postListFirst;
75 struct curl_httppost *postListLast;
76 struct formArrayStruct *formArray;
86 char *errorBufferName;
97 struct MemoryStruct bodyVar;
99 char *cancelTransVarName;
104 struct curl_slist *http200aliases;
107 char *sshkeycallProc;
108 struct curl_slist *mailrcpt;
113 struct curl_slist *resolve;
114 struct curl_slist *telnetoptions;
117 struct shcurlObjData {
124 CONST static char *commandTable[] = {
137 CONST static char *optionTable[] = {
138 "CURLOPT_URL", "CURLOPT_FILE", "CURLOPT_READDATA",
139 "CURLOPT_USERAGENT", "CURLOPT_REFERER", "CURLOPT_VERBOSE",
140 "CURLOPT_HEADER", "CURLOPT_NOBODY", "CURLOPT_PROXY",
141 "CURLOPT_PROXYPORT", "CURLOPT_HTTPPROXYTUNNEL", "CURLOPT_FAILONERROR",
142 "CURLOPT_TIMEOUT", "CURLOPT_LOW_SPEED_LIMIT", "CURLOPT_LOW_SPEED_TIME",
143 "CURLOPT_RESUME_FROM", "CURLOPT_INFILESIZE", "CURLOPT_UPLOAD",
144 "CURLOPT_FTPLISTONLY", "CURLOPT_FTPAPPEND", "CURLOPT_NETRC",
145 "CURLOPT_FOLLOWLOCATION","CURLOPT_TRANSFERTEXT", "CURLOPT_PUT",
146 "CURLOPT_MUTE", "CURLOPT_USERPWD", "CURLOPT_PROXYUSERPWD",
147 "CURLOPT_RANGE", "CURLOPT_ERRORBUFFER", "CURLOPT_HTTPGET",
148 "CURLOPT_POST", "CURLOPT_POSTFIELDS", "CURLOPT_POSTFIELDSIZE",
149 "CURLOPT_FTPPORT", "CURLOPT_COOKIE", "CURLOPT_COOKIEFILE",
150 "CURLOPT_HTTPHEADER", "CURLOPT_HTTPPOST", "CURLOPT_SSLCERT",
151 "CURLOPT_SSLCERTPASSWD", "CURLOPT_SSLVERSION", "CURLOPT_CRLF",
152 "CURLOPT_QUOTE", "CURLOPT_POSTQUOTE", "CURLOPT_WRITEHEADER",
153 "CURLOPT_TIMECONDITION", "CURLOPT_TIMEVALUE", "CURLOPT_CUSTOMREQUEST",
154 "CURLOPT_STDERR", "CURLOPT_INTERFACE", "CURLOPT_KRB4LEVEL",
155 "CURLOPT_SSL_VERIFYPEER","CURLOPT_CAINFO", "CURLOPT_FILETIME",
156 "CURLOPT_MAXREDIRS", "CURLOPT_MAXCONNECTS", "CURLOPT_CLOSEPOLICY",
157 "CURLOPT_RANDOM_FILE", "CURLOPT_EGDSOCKET", "CURLOPT_CONNECTTIMEOUT",
158 "CURLOPT_NOPROGRESS", "CURLOPT_HEADERVAR", "CURLOPT_BODYVAR",
159 "CURLOPT_PROGRESSPROC","CURLOPT_CANCELTRANSVARNAME","CURLOPT_WRITEPROC",
160 "CURLOPT_READPROC", "CURLOPT_SSL_VERIFYHOST", "CURLOPT_COOKIEJAR",
161 "CURLOPT_SSL_CIPHER_LIST","CURLOPT_HTTP_VERSION", "CURLOPT_FTP_USE_EPSV",
162 "CURLOPT_SSLCERTTYPE", "CURLOPT_SSLKEY", "CURLOPT_SSLKEYTYPE",
163 "CURLOPT_SSLKEYPASSWD", "CURLOPT_SSL_ENGINE", "CURLOPT_SSL_ENGINEDEFAULT",
164 "CURLOPT_PREQUOTE", "CURLOPT_DEBUGPROC", "CURLOPT_DNS_CACHE_TIMEOUT",
165 "CURLOPT_DNS_USE_GLOBAL_CACHE", "CURLOPT_COOKIESESSION","CURLOPT_CAPATH",
166 "CURLOPT_BUFFERSIZE", "CURLOPT_NOSIGNAL", "CURLOPT_ENCODING",
167 "CURLOPT_PROXYTYPE", "CURLOPT_HTTP200ALIASES", "CURLOPT_UNRESTRICTED_AUTH",
168 "CURLOPT_FTP_USE_EPRT", "CURLOPT_NOSUCHOPTION", "CURLOPT_HTTPAUTH",
169 "CURLOPT_FTP_CREATE_MISSING_DIRS", "CURLOPT_PROXYAUTH",
170 "CURLOPT_FTP_RESPONSE_TIMEOUT", "CURLOPT_IPRESOLVE",
171 "CURLOPT_MAXFILESIZE", "CURLOPT_NETRC_FILE", "CURLOPT_FTP_SSL",
172 "CURLOPT_SHARE", "CURLOPT_PORT", "CURLOPT_TCP_NODELAY",
173 "CURLOPT_AUTOREFERER", "CURLOPT_SOURCE_HOST", "CURLOPT_SOURCE_USERPWD",
174 "CURLOPT_SOURCE_PATH", "CURLOPT_SOURCE_PORT", "CURLOPT_PASV_HOST",
175 "CURLOPT_SOURCE_PREQUOTE","CURLOPT_SOURCE_POSTQUOTE",
176 "CURLOPT_FTPSSLAUTH", "CURLOPT_SOURCE_URL", "CURLOPT_SOURCE_QUOTE",
177 "CURLOPT_FTP_ACCOUNT", "CURLOPT_IGNORE_CONTENT_LENGTH",
178 "CURLOPT_COOKIELIST", "CURLOPT_FTP_SKIP_PASV_IP",
179 "CURLOPT_FTP_FILEMETHOD", "CURLOPT_LOCALPORT", "CURLOPT_LOCALPORTRANGE",
180 "CURLOPT_MAX_SEND_SPEED_LARGE", "CURLOPT_MAX_RECV_SPEED_LARGE",
181 "CURLOPT_FTP_ALTERNATIVE_TO_USER", "CURLOPT_SSL_SESSIONID_CACHE",
182 "CURLOPT_SSH_AUTH_TYPES", "CURLOPT_SSH_PUBLIC_KEYFILE",
183 "CURLOPT_SSH_PRIVATE_KEYFILE", "CURLOPT_TIMEOUT_MS",
184 "CURLOPT_CONNECTTIMEOUT_MS", "CURLOPT_HTTP_CONTENT_DECODING",
185 "CURLOPT_HTTP_TRANSFER_DECODING", "CURLOPT_KRBLEVEL",
186 "CURLOPT_NEW_FILE_PERMS", "CURLOPT_NEW_DIRECTORY_PERMS",
187 "CURLOPT_KEYPASSWD", "CURLOPT_APPEND", "CURLOPT_DIRLISTONLY",
188 "CURLOPT_USE_SSL", "CURLOPT_POST301", "CURLOPT_SSH_HOST_PUBLIC_KEY_MD5",
189 "CURLOPT_PROXY_TRANSFER_MODE", "CURLOPT_CRLFILE",
190 "CURLOPT_ISSUERCERT", "CURLOPT_ADDRESS_SCOPE", "CURLOPT_CERTINFO",
191 "CURLOPT_POSTREDIR", "CURLOPT_USERNAME", "CURLOPT_PASSWORD",
192 "CURLOPT_PROXYUSERNAME", "CURLOPT_PROXYPASSWORD", "CURLOPT_TFTP_BLKSIZE",
193 "CURLOPT_SOCKS5_GSSAPI_SERVICE", "CURLOPT_SOCKS5_GSSAPI_NEC",
194 "CURLOPT_PROTOCOLS", "CURLOPT_REDIR_PROTOCOLS","CURLOPT_FTP_SSL_CC",
195 "CURLOPT_SSH_KNOWNHOSTS", "CURLOPT_SSH_KEYFUNCTION","CURLOPT_MAIL_FROM",
196 "CURLOPT_MAIL_RCPT", "CURLOPT_FTP_USE_PRET", "CURLOPT_WILDCARDMATCH",
197 "CURLOPT_CHUNK_BGN_PROC", "CURLOPT_CHUNK_BGN_VAR", "CURLOPT_CHUNK_END_PROC",
198 "CURLOPT_FNMATCH_PROC", "CURLOPT_RESOLVE", "CURLOPT_TLSAUTH_USERNAME",
199 "CURLOPT_TLSAUTH_PASSWORD","CURLOPT_GSSAPI_DELEGATION", "CURLOPT_NOPROXY",
200 "CURLOPT_TELNETOPTIONS",
204 CONST static char *configTable[] = {
205 "-url", "-file", "-infile",
206 "-useragent", "-referer", "-verbose",
207 "-header", "-nobody", "-proxy",
208 "-proxyport", "-httpproxytunnel", "-failonerror",
209 "-timeout", "-lowspeedlimit", "-lowspeedtime",
210 "-resumefrom", "-infilesize", "-upload",
211 "-ftplistonly", "-ftpappend", "-netrc",
212 "-followlocation", "-transfertext", "-put",
213 "-mute", "-userpwd", "-proxyuserpwd",
214 "-range", "-errorbuffer", "-httpget",
215 "-post", "-postfields", "-postfieldssize",
216 "-ftpport", "-cookie", "-cookiefile",
217 "-httpheader", "-httppost", "-sslcert",
218 "-sslcertpasswd", "-sslversion", "-crlf",
219 "-quote", "-postquote", "-writeheader",
220 "-timecondition", "-timevalue", "-customrequest",
221 "-stderr", "-interface", "-krb4level",
222 "-sslverifypeer", "-cainfo", "-filetime",
223 "-maxredirs", "-maxconnects", "-closepolicy",
224 "-randomfile", "-egdsocket", "-connecttimeout",
225 "-noprogress", "-headervar", "-bodyvar",
226 "-progressproc", "-canceltransvarname", "-writeproc",
227 "-readproc", "-sslverifyhost", "-cookiejar",
228 "-sslcipherlist", "-httpversion", "-ftpuseepsv",
229 "-sslcerttype", "-sslkey", "-sslkeytype",
230 "-sslkeypasswd", "-sslengine", "-sslenginedefault",
231 "-prequote", "-debugproc", "-dnscachetimeout",
232 "-dnsuseglobalcache", "-cookiesession", "-capath",
233 "-buffersize", "-nosignal", "-encoding",
234 "-proxytype", "-http200aliases", "-unrestrictedauth",
235 "-ftpuseeprt", "-command", "-httpauth",
236 "-ftpcreatemissingdirs", "-proxyauth",
237 "-ftpresponsetimeout", "-ipresolve",
238 "-maxfilesize", "-netrcfile", "-ftpssl",
239 "-share", "-port", "-tcpnodelay",
240 "-autoreferer", "-sourcehost", "-sourceuserpwd",
241 "-sourcepath", "-sourceport", "-pasvhost",
242 "-sourceprequote", "-sourcepostquote", "-ftpsslauth",
243 "-sourceurl", "-sourcequote", "-ftpaccount",
244 "-ignorecontentlength", "-cookielist",
245 "-ftpskippasvip", "-ftpfilemethod", "-localport",
247 "-maxsendspeed", "-maxrecvspeed",
248 "-ftpalternativetouser", "-sslsessionidcache",
249 "-sshauthtypes", "-sshpublickeyfile", "-sshprivatekeyfile",
250 "-timeoutms", "-connecttimeoutms", "-contentdecoding",
251 "-transferdecoding", "-krblevel", "-newfileperms",
252 "-newdirectoryperms", "-keypasswd", "-append",
253 "-dirlistonly", "-usessl", "-post301",
254 "-sshhostpublickeymd5", "-proxytransfermode",
255 "-crlfile", "-issuercert", "-addressscope",
256 "-certinfo", "-postredir", "-username",
257 "-password", "-proxyuser", "-proxypassword",
258 "-tftpblksize", "-socks5gssapiservice","-socks5gssapinec",
259 "-protocols", "-redirprotocols", "-ftpsslcc",
260 "-sshknownhosts", "-sshkeyproc", "-mailfrom",
261 "-mailrcpt", "-ftpusepret", "-wildcardmatch",
262 "-chunkbgnproc", "-chunkbgnvar", "-chunkendproc",
263 "-fnmatchproc", "-resolve", "-tlsauthusername",
264 "-tlsauthpassword", "-gssapidelegation", "-noproxy",
269 CONST static char *timeCond[] = {
270 "ifmodsince", "ifunmodsince",
274 CONST static char *getInfoTable[]={
275 "effectiveurl", "httpcode", "responsecode",
276 "filetime", "totaltime", "namelookuptime",
277 "connecttime", "pretransfertime","sizeupload",
278 "sizedownload", "speeddownload", "speedupload",
279 "headersize", "requestsize", "sslverifyresult",
280 "contentlengthdownload", "contentlengthupload",
281 "starttransfertime", "contenttype",
282 "redirecttime", "redirectcount", "httpauthavail",
283 "proxyauthavail", "oserrno", "numconnects",
284 "sslengines", "httpconnectcode","cookielist",
285 "ftpentrypath", "redirecturl", "primaryip",
286 "appconnecttime", "certinfo", "conditionunmet",
287 "primaryport", "localip", "localport",
291 CONST static char *curlFormTable[]={
292 "name", "contents", "file", "contenttype", "contentheader", "filename",
293 "bufferName", "buffer", "filecontent", (char *)NULL
296 CONST static char *httpVersionTable[] = {
297 "none", /* CURL_HTTP_VERSION_NONE */
298 "1.0", /* CURL_HTTP_VERSION_1_0 */
299 "1.1", /* CURL_HTTP_VERSION_1_1 */
300 "2.0", /* CURL_HTTP_VERSION_2_0 */
301 "2TLS", /* CURL_HTTP_VERSION_2TLS */
302 "2_PRIOR_KNOWLEDGE", /* CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE */
306 CONST static char *netrcTable[] = {
307 "optional", "ignored", "required", (char *)NULL
310 CONST static char *encodingTable[] = {
311 "identity", "deflated", "all", (char *)NULL
314 CONST static char *versionInfoTable[] = {
315 "-version", "-versionnum", "-host", "-features",
316 "-sslversion", "-sslversionnum", "-libzversion",
317 "-protocols", (char *)NULL
320 CONST static char *proxyTypeTable[] = {
321 "http", "http1.0", "socks4", "socks4a", "socks5", "socks5h", (char *)NULL
324 CONST static char *httpAuthMethods[] = {
325 "basic", "digest", "digestie", "gssnegotiate", "ntlm", "any", "anysafe", "ntlmwb",(char *)NULL
328 CONST static char *ipresolve[] = {
329 "whatever", "v4", "v6", (char *)NULL
332 CONST static char *ftpssl[] = {
333 "nope", "try", "control", "all", (char *)NULL
336 CONST static char *shareCmd[] = {
337 "share", "unshare", "cleanup", (char *)NULL
340 CONST static char *lockData[] = {
341 "cookies", "dns", (char *)NULL
344 CONST static char *ftpsslauth[] = {
345 "default", "ssl", "tls", (char *)NULL
348 CONST static char *ftpsslccc[] = {
349 "none", "passive", "active", (char *)NULL
352 CONST static char *sslversion[] = {
353 "default", "tlsv1", "sslv2", "sslv3", "tlsv1_0", "tlsv1_1", "tlsv1_2", (char *)NULL
356 CONST static char *ftpfilemethod[] = {
357 "default", "multicwd", "nocwd", "singlecwd", (char *)NULL
360 CONST static char *sshauthtypes[] = {
361 "publickey", "password", "host", "keyboard", "any", (char *)NULL
364 CONST static char *postredir[] = {
365 "301", "302", "all", (char *)NULL
368 CONST static char *protocolNames[] = {
369 "http", "https", "ftp", "ftps", "scp", "sftp", "telnet", "ldap",
370 "ldaps","dict", "file","tftp", "all", "imap", "imaps", "pop3",
371 "pop3s", "smtp", "smtps", "rtsp", "rtmp", "rtmpt", "rtmpe",
372 "rtmpte", "rtmps", "rtmpts", "gopher", (char*)NULL
375 CONST static char *tlsauth[] = {
376 "none", "srp", (char *)NULL
379 CONST static char *gssapidelegation[] = {
380 "flag", "policyflag", (char *) NULL
383 int curlseek(void *instream, curl_off_t offset, int origin);
385 int Tclcurl_MultiInit (Tcl_Interp *interp);
389 int Tclcurl_Init(Tcl_Interp *interp);
391 char *curlCreateObjCmd(Tcl_Interp *interp,struct curlObjData *curlData);
392 int curlInitObjCmd(ClientData clientData, Tcl_Interp *interp, int objc,
393 Tcl_Obj *CONST objv[]);
394 int curlObjCmd(ClientData clientData, Tcl_Interp *interp, int objc,
395 Tcl_Obj *CONST objv[]);
396 int curlDeleteCmd(ClientData clientData);
398 int curlPerform(Tcl_Interp *interp,CURL *curlHandle,struct curlObjData *curlData);
400 int curlSetOptsTransfer(Tcl_Interp *interp, struct curlObjData *curlData,int objc,
401 Tcl_Obj *CONST objv[]);
403 int curlConfigTransfer(Tcl_Interp *interp, struct curlObjData *curlData,int objc,
404 Tcl_Obj *CONST objv[]);
407 int curlDupHandle(Tcl_Interp *interp, struct curlObjData *curlData,int objc,
408 Tcl_Obj *CONST objv[]);
410 int curlResetHandle(Tcl_Interp *interp, struct curlObjData *curlData);
412 int curlSetOpts(Tcl_Interp *interp, struct curlObjData *curlData,
413 Tcl_Obj *CONST objv,int tableIndex);
415 int SetoptInt(Tcl_Interp *interp,CURL *curlHandle,CURLoption opt,int tableIndex,
417 int SetoptLong(Tcl_Interp *interp,CURL *curlHandle,CURLoption opt,int tableIndex,
419 int SetoptCurlOffT(Tcl_Interp *interp,CURL *curlHandle,CURLoption opt,int tableIndex,
421 int SetoptChar(Tcl_Interp *interp,CURL *curlHandle,CURLoption opt,
422 int tableIndex,Tcl_Obj *tclObj);
423 int SetoptSHandle(Tcl_Interp *interp,CURL *curlHandle,CURLoption opt,
424 int tableIndex,Tcl_Obj *tclObj);
425 int SetoptsList(Tcl_Interp *interp,struct curl_slist **slistPtr,Tcl_Obj *CONST objv);
427 CURLcode curlGetInfo(Tcl_Interp *interp,CURL *curlHandle,int tableIndex);
429 void curlFreeSpace(struct curlObjData *curlData);
431 void curlErrorSetOpt(Tcl_Interp *interp,CONST char **configTable, int option,CONST char *parPtr);
433 size_t curlHeaderReader(void *ptr,size_t size,size_t nmemb,FILE *stream);
435 size_t curlBodyReader(void *ptr,size_t size,size_t nmemb,FILE *curlDataPtr);
437 int curlProgressCallback(void *clientp,double dltotal,double dlnow,
438 double ultotal,double ulnow);
440 size_t curlWriteProcInvoke(void *ptr,size_t size,size_t nmemb,FILE *curlDataPtr);
441 size_t curlReadProcInvoke(void *ptr,size_t size,size_t nmemb,FILE *curlDataPtr);
443 long curlChunkBgnProcInvoke (const void *transfer_info, void *curlDataPtr, int remains);
444 long curlChunkEndProcInvoke (void *curlDataPtr);
445 int curlfnmatchProcInvoke(void *curlDataPtr, const char *pattern, const char *filename);
447 /* Puts a ssh key into a Tcl object */
448 Tcl_Obj *curlsshkeyextract(Tcl_Interp *interp,const struct curl_khkey *key);
450 /* Function that will be invoked by libcurl to see what the user wants to
451 do about the new ssh host */
452 size_t curlsshkeycallback(CURL *easy, /* easy handle */
453 const struct curl_khkey *knownkey, /* known */
454 const struct curl_khkey *foundkey, /* found */
455 enum curl_khmatch, /* libcurl's view on the keys */
458 int curlDebugProcInvoke(CURL *curlHandle, curl_infotype infoType,
459 char * dataPtr, size_t size, void *curlData);
461 int curlVersion (ClientData clientData, Tcl_Interp *interp,
462 int objc,Tcl_Obj *CONST objv[]);
464 int curlEscape(ClientData clientData, Tcl_Interp *interp,
465 int objc,Tcl_Obj *CONST objv[]);
467 int curlUnescape(ClientData clientData, Tcl_Interp *interp,
468 int objc,Tcl_Obj *CONST objv[]);
470 int curlVersionInfo (ClientData clientData, Tcl_Interp *interp,
471 int objc,Tcl_Obj *CONST objv[]);
473 int curlCopyCurlData (struct curlObjData *curlDataOld,
474 struct curlObjData *curlDataNew);
476 int curlOpenFile(Tcl_Interp *interp,char *fileName, FILE **handle, int writing, int text);
478 int curlOpenFiles (Tcl_Interp *interp,struct curlObjData *curlData);
479 void curlCloseFiles(struct curlObjData *curlData);
481 int curlSetPostData(Tcl_Interp *interp,struct curlObjData *curlData);
482 void curlResetPostData(struct curlObjData *curlDataPtr);
483 void curlResetFormArray(struct curl_forms *formArray);
485 void curlSetBodyVarName(Tcl_Interp *interp,struct curlObjData *curlDataPtr);
487 char *curlstrdup (char *old);
490 char *curlCreateShareObjCmd (Tcl_Interp *interp,struct shcurlObjData *shcurlData);
491 int curlShareInitObjCmd (ClientData clientData, Tcl_Interp *interp,
492 int objc,Tcl_Obj *CONST objv[]);
493 int curlShareObjCmd (ClientData clientData, Tcl_Interp *interp,
494 int objc,Tcl_Obj *CONST objv[]);
495 int curlCleanUpShareCmd(ClientData clientData);
498 TCL_DECLARE_MUTEX(cookieLock)
499 TCL_DECLARE_MUTEX(dnsLock)
500 TCL_DECLARE_MUTEX(sslLock)
501 TCL_DECLARE_MUTEX(connectLock)
503 void curlShareLockFunc (CURL *handle, curl_lock_data data
504 , curl_lock_access access, void *userptr);
505 void curlShareUnLockFunc(CURL *handle, curl_lock_data data, void *userptr);
508 int curlErrorStrings (Tcl_Interp *interp, Tcl_Obj *CONST objv,int type);
509 int curlEasyStringError (ClientData clientData, Tcl_Interp *interp,
510 int objc,Tcl_Obj *CONST objv[]);
511 int curlShareStringError (ClientData clientData, Tcl_Interp *interp,
512 int objc,Tcl_Obj *CONST objv[]);
513 int curlMultiStringError (ClientData clientData, Tcl_Interp *interp,
514 int objc,Tcl_Obj *CONST objv[]);