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", "1.0", "1.1", (char *)NULL
300 CONST static char *netrcTable[] = {
301 "optional", "ignored", "required", (char *)NULL
304 CONST static char *encodingTable[] = {
305 "identity", "deflated", "all", (char *)NULL
308 CONST static char *versionInfoTable[] = {
309 "-version", "-versionnum", "-host", "-features",
310 "-sslversion", "-sslversionnum", "-libzversion",
311 "-protocols", (char *)NULL
314 CONST static char *proxyTypeTable[] = {
315 "http", "http1.0", "socks4", "socks4a", "socks5", "socks5h", (char *)NULL
318 CONST static char *httpAuthMethods[] = {
319 "basic", "digest", "digestie", "gssnegotiate", "ntlm", "any", "anysafe", "ntlmwb",(char *)NULL
322 CONST static char *ipresolve[] = {
323 "whatever", "v4", "v6", (char *)NULL
326 CONST static char *ftpssl[] = {
327 "nope", "try", "control", "all", (char *)NULL
330 CONST static char *shareCmd[] = {
331 "share", "unshare", "cleanup", (char *)NULL
334 CONST static char *lockData[] = {
335 "cookies", "dns", (char *)NULL
338 CONST static char *ftpsslauth[] = {
339 "default", "ssl", "tls", (char *)NULL
342 CONST static char *ftpsslccc[] = {
343 "none", "passive", "active", (char *)NULL
346 CONST static char *sslversion[] = {
347 "default", "tlsv1", "sslv2", "sslv3", (char *)NULL
350 CONST static char *ftpfilemethod[] = {
351 "default", "multicwd", "nocwd", "singlecwd", (char *)NULL
354 CONST static char *sshauthtypes[] = {
355 "publickey", "password", "host", "keyboard", "any", (char *)NULL
358 CONST static char *postredir[] = {
359 "301", "302", "all", (char *)NULL
362 CONST static char *protocolNames[] = {
363 "http", "https", "ftp", "ftps", "scp", "sftp", "telnet", "ldap",
364 "ldaps","dict", "file","tftp", "all", "imap", "imaps", "pop3",
365 "pop3s", "smtp", "smtps", "rtsp", "rtmp", "rtmpt", "rtmpe",
366 "rtmpte", "rtmps", "rtmpts", "gopher", (char*)NULL
369 CONST static char *tlsauth[] = {
370 "none", "srp", (char *)NULL
373 CONST static char *gssapidelegation[] = {
374 "flag", "policyflag", (char *) NULL
377 int curlseek(void *instream, curl_off_t offset, int origin);
379 int Tclcurl_MultiInit (Tcl_Interp *interp);
383 int Tclcurl_Init(Tcl_Interp *interp);
385 char *curlCreateObjCmd(Tcl_Interp *interp,struct curlObjData *curlData);
386 int curlInitObjCmd(ClientData clientData, Tcl_Interp *interp, int objc,
387 Tcl_Obj *CONST objv[]);
388 int curlObjCmd(ClientData clientData, Tcl_Interp *interp, int objc,
389 Tcl_Obj *CONST objv[]);
390 int curlDeleteCmd(ClientData clientData);
392 int curlPerform(Tcl_Interp *interp,CURL *curlHandle,struct curlObjData *curlData);
394 int curlSetOptsTransfer(Tcl_Interp *interp, struct curlObjData *curlData,int objc,
395 Tcl_Obj *CONST objv[]);
397 int curlConfigTransfer(Tcl_Interp *interp, struct curlObjData *curlData,int objc,
398 Tcl_Obj *CONST objv[]);
401 int curlDupHandle(Tcl_Interp *interp, struct curlObjData *curlData,int objc,
402 Tcl_Obj *CONST objv[]);
404 int curlResetHandle(Tcl_Interp *interp, struct curlObjData *curlData);
406 int curlSetOpts(Tcl_Interp *interp, struct curlObjData *curlData,
407 Tcl_Obj *CONST objv,int tableIndex);
409 int SetoptInt(Tcl_Interp *interp,CURL *curlHandle,CURLoption opt,int tableIndex,
411 int SetoptLong(Tcl_Interp *interp,CURL *curlHandle,CURLoption opt,int tableIndex,
413 int SetoptCurlOffT(Tcl_Interp *interp,CURL *curlHandle,CURLoption opt,int tableIndex,
415 int SetoptChar(Tcl_Interp *interp,CURL *curlHandle,CURLoption opt,
416 int tableIndex,Tcl_Obj *tclObj);
417 int SetoptSHandle(Tcl_Interp *interp,CURL *curlHandle,CURLoption opt,
418 int tableIndex,Tcl_Obj *tclObj);
419 int SetoptsList(Tcl_Interp *interp,struct curl_slist **slistPtr,Tcl_Obj *CONST objv);
421 CURLcode curlGetInfo(Tcl_Interp *interp,CURL *curlHandle,int tableIndex);
423 void curlFreeSpace(struct curlObjData *curlData);
425 void curlErrorSetOpt(Tcl_Interp *interp,CONST char **configTable, int option,CONST char *parPtr);
427 size_t curlHeaderReader(void *ptr,size_t size,size_t nmemb,FILE *stream);
429 size_t curlBodyReader(void *ptr,size_t size,size_t nmemb,FILE *curlDataPtr);
431 int curlProgressCallback(void *clientp,double dltotal,double dlnow,
432 double ultotal,double ulnow);
434 size_t curlWriteProcInvoke(void *ptr,size_t size,size_t nmemb,FILE *curlDataPtr);
435 size_t curlReadProcInvoke(void *ptr,size_t size,size_t nmemb,FILE *curlDataPtr);
437 long curlChunkBgnProcInvoke (const void *transfer_info, void *curlDataPtr, int remains);
438 long curlChunkEndProcInvoke (void *curlDataPtr);
439 int curlfnmatchProcInvoke(void *curlDataPtr, const char *pattern, const char *filename);
441 /* Puts a ssh key into a Tcl object */
442 Tcl_Obj *curlsshkeyextract(Tcl_Interp *interp,const struct curl_khkey *key);
444 /* Function that will be invoked by libcurl to see what the user wants to
445 do about the new ssh host */
446 size_t curlsshkeycallback(CURL *easy, /* easy handle */
447 const struct curl_khkey *knownkey, /* known */
448 const struct curl_khkey *foundkey, /* found */
449 enum curl_khmatch, /* libcurl's view on the keys */
452 int curlDebugProcInvoke(CURL *curlHandle, curl_infotype infoType,
453 char * dataPtr, size_t size, void *curlData);
455 int curlVersion (ClientData clientData, Tcl_Interp *interp,
456 int objc,Tcl_Obj *CONST objv[]);
458 int curlEscape(ClientData clientData, Tcl_Interp *interp,
459 int objc,Tcl_Obj *CONST objv[]);
461 int curlUnescape(ClientData clientData, Tcl_Interp *interp,
462 int objc,Tcl_Obj *CONST objv[]);
464 int curlVersionInfo (ClientData clientData, Tcl_Interp *interp,
465 int objc,Tcl_Obj *CONST objv[]);
467 int curlCopyCurlData (struct curlObjData *curlDataOld,
468 struct curlObjData *curlDataNew);
470 int curlOpenFile(Tcl_Interp *interp,char *fileName, FILE **handle, int writing, int text);
472 int curlOpenFiles (Tcl_Interp *interp,struct curlObjData *curlData);
473 void curlCloseFiles(struct curlObjData *curlData);
475 int curlSetPostData(Tcl_Interp *interp,struct curlObjData *curlData);
476 void curlResetPostData(struct curlObjData *curlDataPtr);
477 void curlResetFormArray(struct curl_forms *formArray);
479 void curlSetBodyVarName(Tcl_Interp *interp,struct curlObjData *curlDataPtr);
481 char *curlstrdup (char *old);
484 char *curlCreateShareObjCmd (Tcl_Interp *interp,struct shcurlObjData *shcurlData);
485 int curlShareInitObjCmd (ClientData clientData, Tcl_Interp *interp,
486 int objc,Tcl_Obj *CONST objv[]);
487 int curlShareObjCmd (ClientData clientData, Tcl_Interp *interp,
488 int objc,Tcl_Obj *CONST objv[]);
489 int curlCleanUpShareCmd(ClientData clientData);
492 TCL_DECLARE_MUTEX(cookieLock)
493 TCL_DECLARE_MUTEX(dnsLock)
494 TCL_DECLARE_MUTEX(sslLock)
495 TCL_DECLARE_MUTEX(connectLock)
497 void curlShareLockFunc (CURL *handle, curl_lock_data data
498 , curl_lock_access access, void *userptr);
499 void curlShareUnLockFunc(CURL *handle, curl_lock_data data, void *userptr);
502 int curlErrorStrings (Tcl_Interp *interp, Tcl_Obj *CONST objv,int type);
503 int curlEasyStringError (ClientData clientData, Tcl_Interp *interp,
504 int objc,Tcl_Obj *CONST objv[]);
505 int curlShareStringError (ClientData clientData, Tcl_Interp *interp,
506 int objc,Tcl_Obj *CONST objv[]);
507 int curlMultiStringError (ClientData clientData, Tcl_Interp *interp,
508 int objc,Tcl_Obj *CONST objv[]);