1 /* $Id: pycurl.c,v 1.86 2005/03/04 08:39:30 kjetilja Exp $ */
3 /* PycURL -- cURL Python module
6 * Copyright (C) 2001-2005 by Kjetil Jacobsen <kjetilja at cs.uit.no>
7 * Copyright (C) 2001-2005 by Markus F.X.J. Oberhumer <markus at oberhumer.com>
10 * Tino Lange <Tino.Lange at gmx.de>
11 * Matt King <matt at gnik.com>
12 * Conrad Steenberg <conrad at hep.caltech.edu>
13 * Amit Mongia <amit_mongia at hotmail.com>
14 * Eric S. Raymond <esr at thyrsus.com>
15 * Martin Muenstermann <mamuema at sourceforge.net>
16 * Domenico Andreoli <cavok at libero.it>
18 * See file COPYING for license information.
20 * Some quick info on Python's refcount:
21 * Py_BuildValue does incref the item(s)
22 * PyArg_ParseTuple does NOT incref the item
23 * PyList_Append does incref the item
24 * PyTuple_SET_ITEM does NOT incref the item
25 * PyTuple_SetItem does NOT incref the item
26 * PyXXX_GetItem returns a borrowed reference
29 #if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
33 # define CURL_STATICLIB 1
36 #include <sys/types.h>
42 #include <curl/curl.h>
43 #include <curl/multi.h>
47 /* Ensure we have updated versions */
48 #if !defined(PY_VERSION_HEX) || (PY_VERSION_HEX < 0x02020000)
49 # error "Need Python version 2.2 or greater to compile pycurl."
51 #if !defined(LIBCURL_VERSION_NUM) || (LIBCURL_VERSION_NUM < 0x070d01)
52 # error "Need libcurl version 7.13.1 or greater to compile pycurl."
56 #define UNUSED(var) ((void)&var)
58 #undef COMPILE_TIME_ASSERT
59 #define COMPILE_TIME_ASSERT(expr) \
60 { typedef int compile_time_assert_fail__[1 - 2 * !(expr)]; }
63 /* Calculate the number of OBJECTPOINT options we need to store */
64 #define OPTIONS_SIZE ((int)CURLOPT_LASTENTRY % 10000)
65 static int OPT_INDEX(int o)
67 assert(o >= CURLOPTTYPE_OBJECTPOINT);
68 assert(o < CURLOPTTYPE_OBJECTPOINT + OPTIONS_SIZE);
69 return o - CURLOPTTYPE_OBJECTPOINT;
73 static PyObject *ErrorObject = NULL;
74 static PyTypeObject *p_Curl_Type = NULL;
75 static PyTypeObject *p_CurlMulti_Type = NULL;
79 PyObject *dict; /* Python attributes dictionary */
89 PyObject *dict; /* Python attributes dictionary */
92 CurlMultiObject *multi_stack;
93 struct curl_httppost *httppost;
94 struct curl_slist *httpheader;
95 struct curl_slist *http200aliases;
96 struct curl_slist *quote;
97 struct curl_slist *postquote;
98 struct curl_slist *prequote;
99 struct curl_slist *source_prequote;
100 struct curl_slist *source_postquote;
109 PyObject *readdata_fp;
110 PyObject *writedata_fp;
111 PyObject *writeheader_fp;
113 void *options[OPTIONS_SIZE]; /* for OBJECTPOINT options */
114 char error[CURL_ERROR_SIZE+1];
117 /* Throw exception based on return value `res' and `self->error' */
118 #define CURLERROR_RETVAL() do {\
120 self->error[sizeof(self->error) - 1] = 0; \
121 v = Py_BuildValue("(is)", (int) (res), self->error); \
122 if (v != NULL) { PyErr_SetObject(ErrorObject, v); Py_DECREF(v); } \
126 /* Throw exception based on return value `res' and custom message */
127 #define CURLERROR_MSG(msg) do {\
128 PyObject *v; const char *m = (msg); \
129 v = Py_BuildValue("(is)", (int) (res), (m)); \
130 if (v != NULL) { PyErr_SetObject(ErrorObject, v); Py_DECREF(v); } \
135 /* Safe XDECREF for object states that handles nested deallocations */
137 PyObject *tmp = (PyObject *)(v); \
143 /*************************************************************************
144 // python utility functions
145 **************************************************************************/
147 #if (PY_VERSION_HEX < 0x02030000) && !defined(PY_LONG_LONG)
148 # define PY_LONG_LONG LONG_LONG
151 /* Like PyString_AsString(), but set an exception if the string contains
152 * embedded NULs. Actually PyString_AsStringAndSize() already does that for
153 * us if the `len' parameter is NULL - see Objects/stringobject.c.
156 static char *PyString_AsString_NoNUL(PyObject *obj)
160 r = PyString_AsStringAndSize(obj, &s, NULL);
162 return NULL; /* exception already set */
168 /* Convert a curl slist (a list of strings) to a Python list.
169 * In case of error return NULL with an exception set.
171 static PyObject *convert_slist(struct curl_slist *slist, int free_flags)
173 PyObject *ret = NULL;
176 if (ret == NULL) goto error;
178 for ( ; slist != NULL; slist = slist->next) {
181 if (slist->data != NULL) {
182 v = PyString_FromString(slist->data);
183 if (v == NULL || PyList_Append(ret, v) != 0) {
191 if ((free_flags & 1) && slist)
192 curl_slist_free_all(slist);
197 if ((free_flags & 2) && slist)
198 curl_slist_free_all(slist);
203 /*************************************************************************
204 // static utility functions
205 **************************************************************************/
207 static PyThreadState *
208 get_thread_state(const CurlObject *self)
210 /* Get the thread state for callbacks to run in.
211 * This is either `self->state' when running inside perform() or
212 * `self->multi_stack->state' when running inside multi_perform().
213 * When the result is != NULL we also implicitly assert
214 * a valid `self->handle'.
218 assert(self->ob_type == p_Curl_Type);
219 if (self->state != NULL)
221 /* inside perform() */
222 assert(self->handle != NULL);
223 if (self->multi_stack != NULL) {
224 assert(self->multi_stack->state == NULL);
228 if (self->multi_stack != NULL && self->multi_stack->state != NULL)
230 /* inside multi_perform() */
231 assert(self->handle != NULL);
232 assert(self->multi_stack->multi_handle != NULL);
233 assert(self->state == NULL);
234 return self->multi_stack->state;
240 /* assert some CurlObject invariants */
242 assert_curl_state(const CurlObject *self)
244 assert(self != NULL);
245 assert(self->ob_type == p_Curl_Type);
246 (void) get_thread_state(self);
250 /* assert some CurlMultiObject invariants */
252 assert_multi_state(const CurlMultiObject *self)
254 assert(self != NULL);
255 assert(self->ob_type == p_CurlMulti_Type);
256 if (self->state != NULL) {
257 assert(self->multi_handle != NULL);
262 /* check state for methods */
264 check_curl_state(const CurlObject *self, int flags, const char *name)
266 assert_curl_state(self);
267 if ((flags & 1) && self->handle == NULL) {
268 PyErr_Format(ErrorObject, "cannot invoke %s() - no curl handle", name);
271 if ((flags & 2) && get_thread_state(self) != NULL) {
272 PyErr_Format(ErrorObject, "cannot invoke %s() - perform() is currently running", name);
279 check_multi_state(const CurlMultiObject *self, int flags, const char *name)
281 assert_multi_state(self);
282 if ((flags & 1) && self->multi_handle == NULL) {
283 PyErr_Format(ErrorObject, "cannot invoke %s() - no multi handle", name);
286 if ((flags & 2) && self->state != NULL) {
287 PyErr_Format(ErrorObject, "cannot invoke %s() - multi_perform() is currently running", name);
294 /*************************************************************************
296 **************************************************************************/
298 /* --------------- construct/destruct (i.e. open/close) --------------- */
300 /* Allocate a new python curl object */
306 self = (CurlObject *) PyObject_GC_New(CurlObject, p_Curl_Type);
309 PyObject_GC_Track(self);
311 /* Set python curl object initial values */
315 self->multi_stack = NULL;
316 self->httppost = NULL;
317 self->httpheader = NULL;
318 self->http200aliases = NULL;
320 self->postquote = NULL;
321 self->prequote = NULL;
322 self->source_postquote = NULL;
323 self->source_prequote = NULL;
325 /* Set callback pointers to NULL by default */
330 self->debug_cb = NULL;
331 self->ioctl_cb = NULL;
333 /* Set file object pointers to NULL by default */
334 self->readdata_fp = NULL;
335 self->writedata_fp = NULL;
336 self->writeheader_fp = NULL;
338 /* Zero string pointer memory buffer used by setopt */
339 memset(self->options, 0, sizeof(self->options));
340 memset(self->error, 0, sizeof(self->error));
346 /* constructor - this is a module-level function returning a new instance */
348 do_curl_new(PyObject *dummy)
350 CurlObject *self = NULL;
356 /* Allocate python curl object */
357 self = util_curl_new();
361 /* Initialize curl handle */
362 self->handle = curl_easy_init();
363 if (self->handle == NULL)
366 /* Set curl error buffer and zero it */
367 res = curl_easy_setopt(self->handle, CURLOPT_ERRORBUFFER, self->error);
370 memset(self->error, 0, sizeof(self->error));
372 /* Set backreference */
373 res = curl_easy_setopt(self->handle, CURLOPT_PRIVATE, (char *) self);
377 /* Enable NOPROGRESS by default, i.e. no progress output */
378 res = curl_easy_setopt(self->handle, CURLOPT_NOPROGRESS, (long)1);
382 /* Disable VERBOSE by default, i.e. no verbose output */
383 res = curl_easy_setopt(self->handle, CURLOPT_VERBOSE, (long)0);
387 /* Set FTP_ACCOUNT to NULL by default */
388 res = curl_easy_setopt(self->handle, CURLOPT_FTP_ACCOUNT, NULL);
392 /* Set default USERAGENT */
393 s = (char *) malloc(7 + strlen(LIBCURL_VERSION) + 1);
396 strcpy(s, "PycURL/"); strcpy(s+7, LIBCURL_VERSION);
397 res = curl_easy_setopt(self->handle, CURLOPT_USERAGENT, (char *) s);
398 if (res != CURLE_OK) {
402 self->options[ OPT_INDEX(CURLOPT_USERAGENT) ] = s; s = NULL;
404 /* Success - return new object */
408 Py_DECREF(self); /* this also closes self->handle */
409 PyErr_SetString(ErrorObject, "initializing curl failed");
414 /* util function shared by close() and clear() */
416 util_curl_xdecref(CurlObject *self, int flags, CURL *handle)
419 /* Decrement refcount for attributes dictionary. */
424 /* Decrement refcount for multi_stack. */
425 if (self->multi_stack != NULL) {
426 CurlMultiObject *multi_stack = self->multi_stack;
427 self->multi_stack = NULL;
428 if (multi_stack->multi_handle != NULL && handle != NULL) {
429 (void) curl_multi_remove_handle(multi_stack->multi_handle, handle);
431 Py_DECREF(multi_stack);
436 /* Decrement refcount for python callbacks. */
446 /* Decrement refcount for python file objects. */
447 ZAP(self->readdata_fp);
448 ZAP(self->writedata_fp);
449 ZAP(self->writeheader_fp);
455 util_curl_close(CurlObject *self)
460 /* Zero handle and thread-state to disallow any operations to be run
462 assert(self != NULL);
463 assert(self->ob_type == p_Curl_Type);
464 handle = self->handle;
466 if (handle == NULL) {
467 /* Some paranoia assertions just to make sure the object
468 * deallocation problem is finally really fixed... */
469 assert(self->state == NULL);
470 assert(self->multi_stack == NULL);
471 return; /* already closed */
475 /* Decref multi stuff which uses this handle */
476 util_curl_xdecref(self, 2, handle);
478 /* Cleanup curl handle - must be done without the gil */
479 Py_BEGIN_ALLOW_THREADS
480 curl_easy_cleanup(handle);
484 /* Decref callbacks and file handles */
485 util_curl_xdecref(self, 4 | 8, handle);
487 /* Free all variables allocated by setopt */
489 #define SFREE(v) if ((v) != NULL) (curl_formfree(v), (v) = NULL)
490 SFREE(self->httppost);
492 #define SFREE(v) if ((v) != NULL) (curl_slist_free_all(v), (v) = NULL)
493 SFREE(self->httpheader);
494 SFREE(self->http200aliases);
496 SFREE(self->postquote);
497 SFREE(self->prequote);
498 SFREE(self->source_postquote);
499 SFREE(self->source_prequote);
502 /* Last, free the options. This must be done after the curl handle
503 * is closed since libcurl assumes that some options are valid when
504 * invoking curl_easy_cleanup(). */
505 for (i = 0; i < OPTIONS_SIZE; i++) {
506 if (self->options[i] != NULL) {
507 free(self->options[i]);
508 self->options[i] = NULL;
515 do_curl_dealloc(CurlObject *self)
517 PyObject_GC_UnTrack(self);
518 Py_TRASHCAN_SAFE_BEGIN(self)
521 util_curl_close(self);
523 PyObject_GC_Del(self);
524 Py_TRASHCAN_SAFE_END(self)
529 do_curl_close(CurlObject *self)
531 if (check_curl_state(self, 2, "close") != 0) {
534 util_curl_close(self);
541 do_curl_errstr(CurlObject *self)
543 if (check_curl_state(self, 1 | 2, "errstr") != 0) {
546 self->error[sizeof(self->error) - 1] = 0;
547 return PyString_FromString(self->error);
551 /* --------------- GC support --------------- */
553 /* Drop references that may have created reference cycles. */
555 do_curl_clear(CurlObject *self)
557 assert(get_thread_state(self) == NULL);
558 util_curl_xdecref(self, 1 | 2 | 4 | 8, self->handle);
562 /* Traverse all refcounted objects. */
564 do_curl_traverse(CurlObject *self, visitproc visit, void *arg)
568 #define VISIT(v) if ((v) != NULL && ((err = visit(v, arg)) != 0)) return err
571 VISIT((PyObject *) self->multi_stack);
577 VISIT(self->debug_cb);
578 VISIT(self->ioctl_cb);
580 VISIT(self->readdata_fp);
581 VISIT(self->writedata_fp);
582 VISIT(self->writeheader_fp);
589 /* --------------- perform --------------- */
592 do_curl_perform(CurlObject *self)
596 if (check_curl_state(self, 1 | 2, "perform") != 0) {
600 /* Save handle to current thread (used as context for python callbacks) */
601 self->state = PyThreadState_Get();
602 assert(self->state != NULL);
604 /* Release global lock and start */
605 Py_BEGIN_ALLOW_THREADS
606 res = curl_easy_perform(self->handle);
609 /* Zero thread-state to disallow callbacks to be run from now on */
612 if (res != CURLE_OK) {
620 /* --------------- callback handlers --------------- */
622 /* IMPORTANT NOTE: due to threading issues, we cannot call _any_ Python
623 * function without acquiring the thread state in the callback handlers.
627 util_write_callback(int flags, char *ptr, size_t size, size_t nmemb, void *stream)
630 PyThreadState *tmp_state;
632 PyObject *result = NULL;
633 size_t ret = 0; /* assume error */
638 self = (CurlObject *)stream;
639 tmp_state = get_thread_state(self);
640 if (tmp_state == NULL)
642 PyEval_AcquireThread(tmp_state);
645 cb = flags ? self->h_cb : self->w_cb;
648 if (size <= 0 || nmemb <= 0)
650 total_size = (int)(size * nmemb);
651 if (total_size < 0 || (size_t)total_size / size != nmemb) {
652 PyErr_SetString(ErrorObject, "integer overflow in write callback");
657 arglist = Py_BuildValue("(s#)", ptr, total_size);
660 result = PyEval_CallObject(cb, arglist);
666 if (result == Py_None) {
667 ret = total_size; /* None means success */
669 else if (PyInt_Check(result)) {
670 long obj_size = PyInt_AsLong(result);
671 if (obj_size < 0 || obj_size > total_size) {
672 PyErr_Format(ErrorObject, "invalid return value for write callback %ld %ld", (long)obj_size, (long)total_size);
675 ret = (size_t) obj_size; /* success */
677 else if (PyLong_Check(result)) {
678 long obj_size = PyLong_AsLong(result);
679 if (obj_size < 0 || obj_size > total_size) {
680 PyErr_Format(ErrorObject, "invalid return value for write callback %ld %ld", (long)obj_size, (long)total_size);
683 ret = (size_t) obj_size; /* success */
686 PyErr_SetString(ErrorObject, "write callback must return int or None");
693 PyEval_ReleaseThread(tmp_state);
702 write_callback(char *ptr, size_t size, size_t nmemb, void *stream)
704 return util_write_callback(0, ptr, size, nmemb, stream);
708 header_callback(char *ptr, size_t size, size_t nmemb, void *stream)
710 return util_write_callback(1, ptr, size, nmemb, stream);
715 read_callback(char *ptr, size_t size, size_t nmemb, void *stream)
718 PyThreadState *tmp_state;
720 PyObject *result = NULL;
722 size_t ret = CURL_READFUNC_ABORT; /* assume error, this actually works */
726 self = (CurlObject *)stream;
727 tmp_state = get_thread_state(self);
728 if (tmp_state == NULL)
730 PyEval_AcquireThread(tmp_state);
733 if (self->r_cb == NULL)
735 if (size <= 0 || nmemb <= 0)
737 total_size = (int)(size * nmemb);
738 if (total_size < 0 || (size_t)total_size / size != nmemb) {
739 PyErr_SetString(ErrorObject, "integer overflow in read callback");
744 arglist = Py_BuildValue("(i)", total_size);
747 result = PyEval_CallObject(self->r_cb, arglist);
753 if (PyString_Check(result)) {
757 r = PyString_AsStringAndSize(result, &buf, &obj_size);
758 if (r != 0 || obj_size < 0 || obj_size > total_size) {
759 PyErr_Format(ErrorObject, "invalid return value for read callback %ld %ld", (long)obj_size, (long)total_size);
762 memcpy(ptr, buf, obj_size);
763 ret = obj_size; /* success */
765 else if (PyInt_Check(result)) {
766 long r = PyInt_AsLong(result);
767 if (r != CURL_READFUNC_ABORT) {
770 /* ret is CURL_READUNC_ABORT */
772 else if (PyLong_Check(result)) {
773 long r = PyLong_AsLong(result);
774 if (r != CURL_READFUNC_ABORT) {
777 /* ret is CURL_READUNC_ABORT */
781 PyErr_SetString(ErrorObject, "read callback must return string");
788 PyEval_ReleaseThread(tmp_state);
797 progress_callback(void *stream,
798 double dltotal, double dlnow, double ultotal, double ulnow)
801 PyThreadState *tmp_state;
803 PyObject *result = NULL;
804 int ret = 1; /* assume error */
807 self = (CurlObject *)stream;
808 tmp_state = get_thread_state(self);
809 if (tmp_state == NULL)
811 PyEval_AcquireThread(tmp_state);
814 if (self->pro_cb == NULL)
818 arglist = Py_BuildValue("(dddd)", dltotal, dlnow, ultotal, ulnow);
821 result = PyEval_CallObject(self->pro_cb, arglist);
827 if (result == Py_None) {
828 ret = 0; /* None means success */
830 else if (PyInt_Check(result)) {
831 ret = (int) PyInt_AsLong(result);
834 ret = PyObject_IsTrue(result); /* FIXME ??? */
839 PyEval_ReleaseThread(tmp_state);
848 debug_callback(CURL *curlobj, curl_infotype type,
849 char *buffer, size_t total_size, void *stream)
852 PyThreadState *tmp_state;
854 PyObject *result = NULL;
855 int ret = 0; /* always success */
860 self = (CurlObject *)stream;
861 tmp_state = get_thread_state(self);
862 if (tmp_state == NULL)
864 PyEval_AcquireThread(tmp_state);
867 if (self->debug_cb == NULL)
869 if ((int)total_size < 0 || (size_t)((int)total_size) != total_size) {
870 PyErr_SetString(ErrorObject, "integer overflow in debug callback");
875 arglist = Py_BuildValue("(is#)", (int)type, buffer, (int)total_size);
878 result = PyEval_CallObject(self->debug_cb, arglist);
883 /* return values from debug callbacks should be ignored */
887 PyEval_ReleaseThread(tmp_state);
896 ioctl_callback(CURL *curlobj, int cmd, void *stream)
899 PyThreadState *tmp_state;
901 PyObject *result = NULL;
902 int ret = CURLIOE_FAILRESTART; /* assume error */
907 self = (CurlObject *)stream;
908 tmp_state = get_thread_state(self);
909 if (tmp_state == NULL)
910 return (curlioerr) ret;
911 PyEval_AcquireThread(tmp_state);
914 if (self->ioctl_cb == NULL)
918 arglist = Py_BuildValue("(i)", (int)cmd);
921 result = PyEval_CallObject(self->ioctl_cb, arglist);
927 if (result == Py_None) {
928 ret = CURLIOE_OK; /* None means success */
930 else if (PyInt_Check(result)) {
931 ret = (int) PyInt_AsLong(result);
932 if (ret >= CURLIOE_LAST || ret < 0) {
933 PyErr_SetString(ErrorObject, "ioctl callback returned invalid value");
940 PyEval_ReleaseThread(tmp_state);
941 return (curlioerr) ret;
948 /* --------------- unsetopt/setopt/getinfo --------------- */
951 util_curl_unsetopt(CurlObject *self, int option)
956 #define SETOPT2(o,x) \
957 if ((res = curl_easy_setopt(self->handle, (o), (x))) != CURLE_OK) goto error
958 #define SETOPT(x) SETOPT2((CURLoption)option, (x))
960 /* FIXME: implement more options. Have to carefully check lib/url.c in the
961 * libcurl source code to see if it's actually safe to simply
962 * unset the option. */
965 case CURLOPT_HTTPPOST:
967 curl_formfree(self->httppost);
968 self->httppost = NULL;
969 /* FIXME: what about data->set.httpreq ?? */
971 case CURLOPT_INFILESIZE:
974 case CURLOPT_WRITEHEADER:
976 ZAP(self->writeheader_fp);
981 case CURLOPT_COOKIEJAR:
982 case CURLOPT_CUSTOMREQUEST:
983 case CURLOPT_EGDSOCKET:
984 case CURLOPT_FTPPORT:
985 case CURLOPT_PROXYUSERPWD:
986 case CURLOPT_RANDOM_FILE:
987 case CURLOPT_SSL_CIPHER_LIST:
988 case CURLOPT_USERPWD:
990 opt_index = OPT_INDEX(option);
993 /* info: we explicitly list unsupported options here */
994 case CURLOPT_COOKIEFILE:
996 PyErr_SetString(PyExc_TypeError, "unsetopt() is not supported for this option");
1000 if (opt_index >= 0 && self->options[opt_index] != NULL) {
1001 free(self->options[opt_index]);
1002 self->options[opt_index] = NULL;
1017 do_curl_unsetopt(CurlObject *self, PyObject *args)
1021 if (!PyArg_ParseTuple(args, "i:unsetopt", &option)) {
1024 if (check_curl_state(self, 1 | 2, "unsetopt") != 0) {
1028 /* early checks of option value */
1031 if (option >= (int)CURLOPTTYPE_OFF_T + OPTIONS_SIZE)
1033 if (option % 10000 >= OPTIONS_SIZE)
1036 return util_curl_unsetopt(self, option);
1039 PyErr_SetString(PyExc_TypeError, "invalid arguments to unsetopt");
1045 do_curl_setopt(CurlObject *self, PyObject *args)
1051 if (!PyArg_ParseTuple(args, "iO:setopt", &option, &obj))
1053 if (check_curl_state(self, 1 | 2, "setopt") != 0)
1056 /* early checks of option value */
1059 if (option >= (int)CURLOPTTYPE_OFF_T + OPTIONS_SIZE)
1061 if (option % 10000 >= OPTIONS_SIZE)
1064 #if 0 /* XXX - should we ??? */
1065 /* Handle the case of None */
1066 if (obj == Py_None) {
1067 return util_curl_unsetopt(self, option);
1071 /* Handle the case of string arguments */
1072 if (PyString_Check(obj)) {
1078 /* Check that the option specified a string as well as the input */
1080 case CURLOPT_CAINFO:
1081 case CURLOPT_CAPATH:
1082 case CURLOPT_COOKIE:
1083 case CURLOPT_COOKIEFILE:
1084 case CURLOPT_COOKIEJAR:
1085 case CURLOPT_CUSTOMREQUEST:
1086 case CURLOPT_EGDSOCKET:
1087 case CURLOPT_ENCODING:
1088 case CURLOPT_FTPPORT:
1089 case CURLOPT_INTERFACE:
1090 case CURLOPT_KRB4LEVEL:
1091 case CURLOPT_NETRC_FILE:
1093 case CURLOPT_PROXYUSERPWD:
1094 case CURLOPT_RANDOM_FILE:
1096 case CURLOPT_REFERER:
1097 case CURLOPT_SSLCERT:
1098 case CURLOPT_SSLCERTTYPE:
1099 case CURLOPT_SSLENGINE:
1100 case CURLOPT_SSLKEY:
1101 case CURLOPT_SSLKEYPASSWD:
1102 case CURLOPT_SSLKEYTYPE:
1103 case CURLOPT_SSL_CIPHER_LIST:
1105 case CURLOPT_USERAGENT:
1106 case CURLOPT_USERPWD:
1107 case CURLOPT_SOURCE_HOST:
1108 case CURLOPT_SOURCE_USERPWD:
1109 case CURLOPT_SOURCE_PATH:
1110 /* FIXME: check if more of these options allow binary data */
1111 str = PyString_AsString_NoNUL(obj);
1115 case CURLOPT_POSTFIELDS:
1116 if (PyString_AsStringAndSize(obj, &str, &len) != 0)
1118 /* automatically set POSTFIELDSIZE */
1119 res = curl_easy_setopt(self->handle, CURLOPT_POSTFIELDSIZE, (long)len);
1120 if (res != CURLE_OK) {
1125 PyErr_SetString(PyExc_TypeError, "strings are not supported for this option");
1128 /* Allocate memory to hold the string */
1129 assert(str != NULL);
1133 buf = (char *) malloc(len);
1134 if (buf) memcpy(buf, str, len);
1137 return PyErr_NoMemory();
1139 res = curl_easy_setopt(self->handle, (CURLoption)option, buf);
1140 /* Check for errors */
1141 if (res != CURLE_OK) {
1145 /* Save allocated option buffer */
1146 opt_index = OPT_INDEX(option);
1147 if (self->options[opt_index] != NULL) {
1148 free(self->options[opt_index]);
1149 self->options[opt_index] = NULL;
1151 self->options[opt_index] = buf;
1156 #define IS_LONG_OPTION(o) (o < CURLOPTTYPE_OBJECTPOINT)
1157 #define IS_OFF_T_OPTION(o) (o >= CURLOPTTYPE_OFF_T)
1159 /* Handle the case of integer arguments */
1160 if (PyInt_Check(obj)) {
1161 long d = PyInt_AsLong(obj);
1163 if (IS_LONG_OPTION(option))
1164 res = curl_easy_setopt(self->handle, (CURLoption)option, (long)d);
1165 else if (IS_OFF_T_OPTION(option))
1166 res = curl_easy_setopt(self->handle, (CURLoption)option, (curl_off_t)d);
1168 PyErr_SetString(PyExc_TypeError, "integers are not supported for this option");
1171 if (res != CURLE_OK) {
1178 /* Handle the case of long arguments (used by *_LARGE options) */
1179 if (PyLong_Check(obj)) {
1180 PY_LONG_LONG d = PyLong_AsLongLong(obj);
1181 if (d == -1 && PyErr_Occurred())
1184 if (IS_LONG_OPTION(option) && (long)d == d)
1185 res = curl_easy_setopt(self->handle, (CURLoption)option, (long)d);
1186 else if (IS_OFF_T_OPTION(option) && (curl_off_t)d == d)
1187 res = curl_easy_setopt(self->handle, (CURLoption)option, (curl_off_t)d);
1189 PyErr_SetString(PyExc_TypeError, "longs are not supported for this option");
1192 if (res != CURLE_OK) {
1199 #undef IS_LONG_OPTION
1200 #undef IS_OFF_T_OPTION
1202 /* Handle the case of file objects */
1203 if (PyFile_Check(obj)) {
1206 /* Ensure the option specified a file as well as the input */
1208 case CURLOPT_READDATA:
1209 case CURLOPT_WRITEDATA:
1211 case CURLOPT_WRITEHEADER:
1212 if (self->w_cb != NULL) {
1213 PyErr_SetString(ErrorObject, "cannot combine WRITEHEADER with WRITEFUNCTION.");
1218 PyErr_SetString(PyExc_TypeError, "files are not supported for this option");
1222 fp = PyFile_AsFile(obj);
1224 PyErr_SetString(PyExc_TypeError, "second argument must be open file");
1227 res = curl_easy_setopt(self->handle, (CURLoption)option, fp);
1228 if (res != CURLE_OK) {
1234 case CURLOPT_READDATA:
1235 ZAP(self->readdata_fp);
1236 self->readdata_fp = obj;
1238 case CURLOPT_WRITEDATA:
1239 ZAP(self->writedata_fp);
1240 self->writedata_fp = obj;
1242 case CURLOPT_WRITEHEADER:
1243 ZAP(self->writeheader_fp);
1244 self->writeheader_fp = obj;
1250 /* Return success */
1255 /* Handle the case of list objects */
1256 if (PyList_Check(obj)) {
1257 struct curl_slist **old_slist = NULL;
1258 struct curl_slist *slist = NULL;
1262 case CURLOPT_HTTP200ALIASES:
1263 old_slist = &self->http200aliases;
1265 case CURLOPT_HTTPHEADER:
1266 old_slist = &self->httpheader;
1269 old_slist = &self->quote;
1271 case CURLOPT_POSTQUOTE:
1272 old_slist = &self->postquote;
1274 case CURLOPT_PREQUOTE:
1275 old_slist = &self->prequote;
1277 case CURLOPT_SOURCE_PREQUOTE:
1278 old_slist = &self->source_prequote;
1280 case CURLOPT_SOURCE_POSTQUOTE:
1281 old_slist = &self->source_postquote;
1283 case CURLOPT_HTTPPOST:
1286 /* None of the list options were recognized, throw exception */
1287 PyErr_SetString(PyExc_TypeError, "lists are not supported for this option");
1291 len = PyList_Size(obj);
1293 /* Empty list - do nothing */
1298 /* Handle HTTPPOST different since we construct a HttpPost form struct */
1299 if (option == CURLOPT_HTTPPOST) {
1300 struct curl_httppost *post = NULL;
1301 struct curl_httppost *last = NULL;
1303 for (i = 0; i < len; i++) {
1304 char *nstr = NULL, *cstr = NULL;
1305 int nlen = -1, clen = -1;
1306 PyObject *listitem = PyList_GetItem(obj, i);
1308 if (!PyTuple_Check(listitem)) {
1309 curl_formfree(post);
1310 PyErr_SetString(PyExc_TypeError, "list items must be tuple objects");
1313 if (PyTuple_GET_SIZE(listitem) != 2) {
1314 curl_formfree(post);
1315 PyErr_SetString(PyExc_TypeError, "tuple must contain two elements (name, value)");
1318 if (PyString_AsStringAndSize(PyTuple_GET_ITEM(listitem, 0), &nstr, &nlen) != 0) {
1319 curl_formfree(post);
1320 PyErr_SetString(PyExc_TypeError, "tuple must contain string as first element");
1323 if (PyString_Check(PyTuple_GET_ITEM(listitem, 1))) {
1324 /* Handle strings as second argument for backwards compatibility */
1325 PyString_AsStringAndSize(PyTuple_GET_ITEM(listitem, 1), &cstr, &clen);
1326 /* INFO: curl_formadd() internally does memdup() the data, so
1327 * embedded NUL characters _are_ allowed here. */
1328 res = curl_formadd(&post, &last,
1329 CURLFORM_COPYNAME, nstr,
1330 CURLFORM_NAMELENGTH, (long) nlen,
1331 CURLFORM_COPYCONTENTS, cstr,
1332 CURLFORM_CONTENTSLENGTH, (long) clen,
1334 if (res != CURLE_OK) {
1335 curl_formfree(post);
1339 else if (PyTuple_Check(PyTuple_GET_ITEM(listitem, 1))) {
1340 /* Supports content, file and content-type */
1341 PyObject *t = PyTuple_GET_ITEM(listitem, 1);
1342 int tlen = PyTuple_Size(t);
1344 struct curl_forms *forms = NULL;
1346 /* Sanity check that there are at least two tuple items */
1348 curl_formfree(post);
1349 PyErr_SetString(PyExc_TypeError, "tuple must contain at least one option and one value");
1353 /* Allocate enough space to accommodate length options for content */
1354 forms = PyMem_Malloc(sizeof(struct curl_forms) * ((tlen*2) + 1));
1355 if (forms == NULL) {
1356 curl_formfree(post);
1361 /* Iterate all the tuple members pairwise */
1362 for (j = 0, k = 0, l = 0; j < tlen; j += 2, l++) {
1366 if (j == (tlen-1)) {
1367 PyErr_SetString(PyExc_TypeError, "expected value");
1369 curl_formfree(post);
1372 if (!PyInt_Check(PyTuple_GET_ITEM(t, j))) {
1373 PyErr_SetString(PyExc_TypeError, "option must be long");
1375 curl_formfree(post);
1378 if (!PyString_Check(PyTuple_GET_ITEM(t, j+1))) {
1379 PyErr_SetString(PyExc_TypeError, "value must be string");
1381 curl_formfree(post);
1385 val = PyLong_AsLong(PyTuple_GET_ITEM(t, j));
1386 if (val != CURLFORM_COPYCONTENTS &&
1387 val != CURLFORM_FILE &&
1388 val != CURLFORM_CONTENTTYPE)
1390 PyErr_SetString(PyExc_TypeError, "unsupported option");
1392 curl_formfree(post);
1395 PyString_AsStringAndSize(PyTuple_GET_ITEM(t, j+1), &ostr, &olen);
1396 forms[k].option = val;
1397 forms[k].value = ostr;
1399 if (val == CURLFORM_COPYCONTENTS) {
1400 /* Contents can contain \0 bytes so we specify the length */
1401 forms[k].option = CURLFORM_CONTENTSLENGTH;
1402 forms[k].value = (char *)olen;
1406 forms[k].option = CURLFORM_END;
1407 res = curl_formadd(&post, &last,
1408 CURLFORM_COPYNAME, nstr,
1409 CURLFORM_NAMELENGTH, (long) nlen,
1410 CURLFORM_ARRAY, forms,
1413 if (res != CURLE_OK) {
1414 curl_formfree(post);
1418 /* Some other type was given, ignore */
1419 curl_formfree(post);
1420 PyErr_SetString(PyExc_TypeError, "unsupported second type in tuple");
1424 res = curl_easy_setopt(self->handle, CURLOPT_HTTPPOST, post);
1425 /* Check for errors */
1426 if (res != CURLE_OK) {
1427 curl_formfree(post);
1430 /* Finally, free previously allocated httppost and update */
1431 curl_formfree(self->httppost);
1432 self->httppost = post;
1438 /* Just to be sure we do not bug off here */
1439 assert(old_slist != NULL && slist == NULL);
1441 /* Handle regular list operations on the other options */
1442 for (i = 0; i < len; i++) {
1443 PyObject *listitem = PyList_GetItem(obj, i);
1444 struct curl_slist *nlist;
1447 if (!PyString_Check(listitem)) {
1448 curl_slist_free_all(slist);
1449 PyErr_SetString(PyExc_TypeError, "list items must be string objects");
1452 /* INFO: curl_slist_append() internally does strdup() the data, so
1453 * no embedded NUL characters allowed here. */
1454 str = PyString_AsString_NoNUL(listitem);
1456 curl_slist_free_all(slist);
1459 nlist = curl_slist_append(slist, str);
1460 if (nlist == NULL || nlist->data == NULL) {
1461 curl_slist_free_all(slist);
1462 return PyErr_NoMemory();
1466 res = curl_easy_setopt(self->handle, (CURLoption)option, slist);
1467 /* Check for errors */
1468 if (res != CURLE_OK) {
1469 curl_slist_free_all(slist);
1472 /* Finally, free previously allocated list and update */
1473 curl_slist_free_all(*old_slist);
1480 /* Handle the case of function objects for callbacks */
1481 if (PyFunction_Check(obj) || PyCFunction_Check(obj) || PyMethod_Check(obj)) {
1482 /* We use function types here to make sure that our callback
1483 * definitions exactly match the <curl/curl.h> interface.
1485 const curl_write_callback w_cb = write_callback;
1486 const curl_write_callback h_cb = header_callback;
1487 const curl_read_callback r_cb = read_callback;
1488 const curl_progress_callback pro_cb = progress_callback;
1489 const curl_debug_callback debug_cb = debug_callback;
1490 const curl_ioctl_callback ioctl_cb = ioctl_callback;
1493 case CURLOPT_WRITEFUNCTION:
1494 if (self->writeheader_fp != NULL) {
1495 PyErr_SetString(ErrorObject, "cannot combine WRITEFUNCTION with WRITEHEADER option.");
1499 ZAP(self->writedata_fp);
1502 curl_easy_setopt(self->handle, CURLOPT_WRITEFUNCTION, w_cb);
1503 curl_easy_setopt(self->handle, CURLOPT_WRITEDATA, self);
1505 case CURLOPT_HEADERFUNCTION:
1509 curl_easy_setopt(self->handle, CURLOPT_HEADERFUNCTION, h_cb);
1510 curl_easy_setopt(self->handle, CURLOPT_WRITEHEADER, self);
1512 case CURLOPT_READFUNCTION:
1514 ZAP(self->readdata_fp);
1517 curl_easy_setopt(self->handle, CURLOPT_READFUNCTION, r_cb);
1518 curl_easy_setopt(self->handle, CURLOPT_READDATA, self);
1520 case CURLOPT_PROGRESSFUNCTION:
1524 curl_easy_setopt(self->handle, CURLOPT_PROGRESSFUNCTION, pro_cb);
1525 curl_easy_setopt(self->handle, CURLOPT_PROGRESSDATA, self);
1527 case CURLOPT_DEBUGFUNCTION:
1529 ZAP(self->debug_cb);
1530 self->debug_cb = obj;
1531 curl_easy_setopt(self->handle, CURLOPT_DEBUGFUNCTION, debug_cb);
1532 curl_easy_setopt(self->handle, CURLOPT_DEBUGDATA, self);
1534 case CURLOPT_IOCTLFUNCTION:
1536 ZAP(self->ioctl_cb);
1537 self->ioctl_cb = obj;
1538 curl_easy_setopt(self->handle, CURLOPT_IOCTLFUNCTION, ioctl_cb);
1539 curl_easy_setopt(self->handle, CURLOPT_IOCTLDATA, self);
1543 /* None of the function options were recognized, throw exception */
1544 PyErr_SetString(PyExc_TypeError, "functions are not supported for this option");
1551 /* Failed to match any of the function signatures -- return error */
1553 PyErr_SetString(PyExc_TypeError, "invalid arguments to setopt");
1559 do_curl_getinfo(CurlObject *self, PyObject *args)
1564 if (!PyArg_ParseTuple(args, "i:getinfo", &option)) {
1567 if (check_curl_state(self, 1 | 2, "getinfo") != 0) {
1572 case CURLINFO_FILETIME:
1573 case CURLINFO_HEADER_SIZE:
1574 case CURLINFO_HTTP_CODE:
1575 case CURLINFO_REDIRECT_COUNT:
1576 case CURLINFO_REQUEST_SIZE:
1577 case CURLINFO_SSL_VERIFYRESULT:
1578 case CURLINFO_HTTP_CONNECTCODE:
1579 case CURLINFO_HTTPAUTH_AVAIL:
1580 case CURLINFO_PROXYAUTH_AVAIL:
1581 case CURLINFO_OS_ERRNO:
1582 case CURLINFO_NUM_CONNECTS:
1584 /* Return PyInt as result */
1587 res = curl_easy_getinfo(self->handle, (CURLINFO)option, &l_res);
1588 /* Check for errors and return result */
1589 if (res != CURLE_OK) {
1592 return PyInt_FromLong(l_res);
1595 case CURLINFO_CONTENT_TYPE:
1596 case CURLINFO_EFFECTIVE_URL:
1598 /* Return PyString as result */
1601 res = curl_easy_getinfo(self->handle, (CURLINFO)option, &s_res);
1602 if (res != CURLE_OK) {
1605 /* If the resulting string is NULL, return None */
1606 if (s_res == NULL) {
1610 return PyString_FromString(s_res);
1613 case CURLINFO_CONNECT_TIME:
1614 case CURLINFO_CONTENT_LENGTH_DOWNLOAD:
1615 case CURLINFO_CONTENT_LENGTH_UPLOAD:
1616 case CURLINFO_NAMELOOKUP_TIME:
1617 case CURLINFO_PRETRANSFER_TIME:
1618 case CURLINFO_REDIRECT_TIME:
1619 case CURLINFO_SIZE_DOWNLOAD:
1620 case CURLINFO_SIZE_UPLOAD:
1621 case CURLINFO_SPEED_DOWNLOAD:
1622 case CURLINFO_SPEED_UPLOAD:
1623 case CURLINFO_STARTTRANSFER_TIME:
1624 case CURLINFO_TOTAL_TIME:
1626 /* Return PyFloat as result */
1629 res = curl_easy_getinfo(self->handle, (CURLINFO)option, &d_res);
1630 if (res != CURLE_OK) {
1633 return PyFloat_FromDouble(d_res);
1636 case CURLINFO_SSL_ENGINES:
1638 /* Return a list of strings */
1639 struct curl_slist *slist = NULL;
1641 res = curl_easy_getinfo(self->handle, (CURLINFO)option, &slist);
1642 if (res != CURLE_OK) {
1645 return convert_slist(slist, 1 | 2);
1649 /* Got wrong option on the method call */
1650 PyErr_SetString(PyExc_ValueError, "invalid argument to getinfo");
1655 /*************************************************************************
1657 **************************************************************************/
1659 /* --------------- construct/destruct (i.e. open/close) --------------- */
1661 /* constructor - this is a module-level function returning a new instance */
1662 static CurlMultiObject *
1663 do_multi_new(PyObject *dummy)
1665 CurlMultiObject *self;
1669 /* Allocate python curl-multi object */
1670 self = (CurlMultiObject *) PyObject_GC_New(CurlMultiObject, p_CurlMulti_Type);
1672 PyObject_GC_Track(self);
1678 /* Initialize object attributes */
1682 /* Allocate libcurl multi handle */
1683 self->multi_handle = curl_multi_init();
1684 if (self->multi_handle == NULL) {
1686 PyErr_SetString(ErrorObject, "initializing curl-multi failed");
1694 util_multi_close(CurlMultiObject *self)
1696 assert(self != NULL);
1698 if (self->multi_handle != NULL) {
1699 CURLM *multi_handle = self->multi_handle;
1700 self->multi_handle = NULL;
1701 curl_multi_cleanup(multi_handle);
1707 do_multi_dealloc(CurlMultiObject *self)
1709 PyObject_GC_UnTrack(self);
1710 Py_TRASHCAN_SAFE_BEGIN(self)
1713 util_multi_close(self);
1715 PyObject_GC_Del(self);
1716 Py_TRASHCAN_SAFE_END(self)
1721 do_multi_close(CurlMultiObject *self)
1723 if (check_multi_state(self, 2, "close") != 0) {
1726 util_multi_close(self);
1732 /* --------------- GC support --------------- */
1734 /* Drop references that may have created reference cycles. */
1736 do_multi_clear(CurlMultiObject *self)
1743 do_multi_traverse(CurlMultiObject *self, visitproc visit, void *arg)
1747 #define VISIT(v) if ((v) != NULL && ((err = visit(v, arg)) != 0)) return err
1755 /* --------------- perform --------------- */
1759 do_multi_perform(CurlMultiObject *self)
1764 if (check_multi_state(self, 1 | 2, "perform") != 0) {
1768 /* Release global lock and start */
1769 self->state = PyThreadState_Get();
1770 assert(self->state != NULL);
1771 Py_BEGIN_ALLOW_THREADS
1772 res = curl_multi_perform(self->multi_handle, &running);
1773 Py_END_ALLOW_THREADS
1776 /* We assume these errors are ok, otherwise throw exception */
1777 if (res != CURLM_OK && res != CURLM_CALL_MULTI_PERFORM) {
1778 CURLERROR_MSG("perform failed");
1781 /* Return a tuple with the result and the number of running handles */
1782 return Py_BuildValue("(ii)", (int)res, running);
1786 /* --------------- add_handle/remove_handle --------------- */
1788 /* static utility function */
1790 check_multi_add_remove(const CurlMultiObject *self, const CurlObject *obj)
1792 /* check CurlMultiObject status */
1793 assert_multi_state(self);
1794 if (self->multi_handle == NULL) {
1795 PyErr_SetString(ErrorObject, "cannot add/remove handle - multi-stack is closed");
1798 if (self->state != NULL) {
1799 PyErr_SetString(ErrorObject, "cannot add/remove handle - multi_perform() already running");
1802 /* check CurlObject status */
1803 assert_curl_state(obj);
1804 if (obj->state != NULL) {
1805 PyErr_SetString(ErrorObject, "cannot add/remove handle - perform() of curl object already running");
1808 if (obj->multi_stack != NULL && obj->multi_stack != self) {
1809 PyErr_SetString(ErrorObject, "cannot add/remove handle - curl object already on another multi-stack");
1817 do_multi_add_handle(CurlMultiObject *self, PyObject *args)
1822 if (!PyArg_ParseTuple(args, "O!:add_handle", p_Curl_Type, &obj)) {
1825 if (check_multi_add_remove(self, obj) != 0) {
1828 if (obj->handle == NULL) {
1829 PyErr_SetString(ErrorObject, "curl object already closed");
1832 if (obj->multi_stack == self) {
1833 PyErr_SetString(ErrorObject, "curl object already on this multi-stack");
1836 assert(obj->multi_stack == NULL);
1837 res = curl_multi_add_handle(self->multi_handle, obj->handle);
1838 if (res != CURLM_OK) {
1839 CURLERROR_MSG("curl_multi_add_handle() failed due to internal errors");
1841 obj->multi_stack = self;
1849 do_multi_remove_handle(CurlMultiObject *self, PyObject *args)
1854 if (!PyArg_ParseTuple(args, "O!:remove_handle", p_Curl_Type, &obj)) {
1857 if (check_multi_add_remove(self, obj) != 0) {
1860 if (obj->handle == NULL) {
1861 /* CurlObject handle already closed -- ignore */
1864 if (obj->multi_stack != self) {
1865 PyErr_SetString(ErrorObject, "curl object not on this multi-stack");
1868 res = curl_multi_remove_handle(self->multi_handle, obj->handle);
1869 if (res != CURLM_OK) {
1870 CURLERROR_MSG("curl_multi_remove_handle() failed due to internal errors");
1872 assert(obj->multi_stack == self);
1873 obj->multi_stack = NULL;
1881 /* --------------- fdset ---------------------- */
1884 do_multi_fdset(CurlMultiObject *self)
1887 int max_fd = -1, fd;
1888 PyObject *ret = NULL;
1889 PyObject *read_list = NULL, *write_list = NULL, *except_list = NULL;
1890 PyObject *py_fd = NULL;
1892 if (check_multi_state(self, 1 | 2, "fdset") != 0) {
1896 /* Clear file descriptor sets */
1897 FD_ZERO(&self->read_fd_set);
1898 FD_ZERO(&self->write_fd_set);
1899 FD_ZERO(&self->exc_fd_set);
1901 /* Don't bother releasing the gil as this is just a data structure operation */
1902 res = curl_multi_fdset(self->multi_handle, &self->read_fd_set,
1903 &self->write_fd_set, &self->exc_fd_set, &max_fd);
1904 if (res != CURLM_OK || max_fd < 0) {
1905 CURLERROR_MSG("curl_multi_fdset() failed due to internal errors");
1908 /* Allocate lists. */
1909 if ((read_list = PyList_New(0)) == NULL) goto error;
1910 if ((write_list = PyList_New(0)) == NULL) goto error;
1911 if ((except_list = PyList_New(0)) == NULL) goto error;
1913 /* Populate lists */
1914 for (fd = 0; fd < max_fd + 1; fd++) {
1915 if (FD_ISSET(fd, &self->read_fd_set)) {
1916 if ((py_fd = PyInt_FromLong((long)fd)) == NULL) goto error;
1917 if (PyList_Append(read_list, py_fd) != 0) goto error;
1921 if (FD_ISSET(fd, &self->write_fd_set)) {
1922 if ((py_fd = PyInt_FromLong((long)fd)) == NULL) goto error;
1923 if (PyList_Append(write_list, py_fd) != 0) goto error;
1927 if (FD_ISSET(fd, &self->exc_fd_set)) {
1928 if ((py_fd = PyInt_FromLong((long)fd)) == NULL) goto error;
1929 if (PyList_Append(except_list, py_fd) != 0) goto error;
1935 /* Return a tuple with the 3 lists */
1936 ret = Py_BuildValue("(OOO)", read_list, write_list, except_list);
1939 Py_XDECREF(except_list);
1940 Py_XDECREF(write_list);
1941 Py_XDECREF(read_list);
1946 /* --------------- info_read --------------- */
1949 do_multi_info_read(CurlMultiObject *self, PyObject *args)
1951 PyObject *ret = NULL;
1952 PyObject *ok_list = NULL, *err_list = NULL;
1954 int in_queue = 0, num_results = INT_MAX;
1957 if (!PyArg_ParseTuple(args, "|i:info_read", &num_results)) {
1960 if (num_results <= 0) {
1961 PyErr_SetString(ErrorObject, "argument to info_read must be greater than zero");
1964 if (check_multi_state(self, 1 | 2, "info_read") != 0) {
1968 if ((ok_list = PyList_New(0)) == NULL) goto error;
1969 if ((err_list = PyList_New(0)) == NULL) goto error;
1971 /* Loop through all messages */
1972 while ((msg = curl_multi_info_read(self->multi_handle, &in_queue)) != NULL) {
1974 CurlObject *co = NULL;
1976 /* Check for termination as specified by the user */
1977 if (num_results-- <= 0) {
1981 /* Fetch the curl object that corresponds to the curl handle in the message */
1982 res = curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &co);
1983 if (res != CURLE_OK || co == NULL) {
1984 Py_DECREF(err_list);
1986 CURLERROR_MSG("Unable to fetch curl handle from curl object");
1988 assert(co->ob_type == p_Curl_Type);
1989 if (msg->msg != CURLMSG_DONE) {
1990 /* FIXME: what does this mean ??? */
1992 if (msg->data.result == CURLE_OK) {
1993 /* Append curl object to list of objects which succeeded */
1994 if (PyList_Append(ok_list, (PyObject *)co) != 0) {
1999 /* Create a result tuple that will get added to err_list. */
2000 PyObject *v = Py_BuildValue("(Ois)", (PyObject *)co, (int)msg->data.result, co->error);
2001 /* Append curl object to list of objects which failed */
2002 if (v == NULL || PyList_Append(err_list, v) != 0) {
2009 /* Return (number of queued messages, [ok_objects], [error_objects]) */
2010 ret = Py_BuildValue("(iOO)", in_queue, ok_list, err_list);
2012 Py_XDECREF(err_list);
2013 Py_XDECREF(ok_list);
2018 /* --------------- select --------------- */
2021 do_multi_select(CurlMultiObject *self, PyObject *args)
2024 double timeout = -1.0;
2025 struct timeval tv, *tvp;
2028 if (!PyArg_ParseTuple(args, "|d:select", &timeout)) {
2031 if (check_multi_state(self, 1 | 2, "select") != 0) {
2035 if (timeout == -1.0) {
2036 /* no timeout given - wait forever */
2038 } else if (timeout < 0 || timeout >= 365 * 24 * 60 * 60) {
2039 PyErr_SetString(PyExc_OverflowError, "invalid timeout period");
2042 long seconds = (long)timeout;
2043 timeout = timeout - (double)seconds;
2044 assert(timeout >= 0.0); assert(timeout < 1.0);
2045 tv.tv_sec = seconds;
2046 tv.tv_usec = (long)(timeout*1000000.0);
2050 FD_ZERO(&self->read_fd_set);
2051 FD_ZERO(&self->write_fd_set);
2052 FD_ZERO(&self->exc_fd_set);
2054 res = curl_multi_fdset(self->multi_handle, &self->read_fd_set,
2055 &self->write_fd_set, &self->exc_fd_set, &max_fd);
2056 if (res != CURLM_OK) {
2057 CURLERROR_MSG("multi_fdset failed");
2064 Py_BEGIN_ALLOW_THREADS
2065 n = select(max_fd + 1, &self->read_fd_set, &self->write_fd_set, &self->exc_fd_set, tvp);
2066 Py_END_ALLOW_THREADS
2067 /* info: like Python's socketmodule.c we do not raise an exception
2068 * if select() fails - we'll leave it to the actual libcurl
2069 * socket code to report any errors.
2073 return PyInt_FromLong(n);
2077 /*************************************************************************
2079 **************************************************************************/
2081 /* --------------- methods --------------- */
2083 static char co_close_doc [] = "close() -> None. Close handle and end curl session.\n";
2084 static char co_errstr_doc [] = "errstr() -> String. Return the internal libcurl error buffer string.\n";
2085 static char co_getinfo_doc [] = "getinfo(info) -> Res. Extract and return information from a curl session. Throws pycurl.error exception upon failure.\n";
2086 static char co_perform_doc [] = "perform() -> None. Perform a file transfer. Throws pycurl.error exception upon failure.\n";
2087 static char co_setopt_doc [] = "setopt(option, parameter) -> None. Set curl session option. Throws pycurl.error exception upon failure.\n";
2088 static char co_unsetopt_doc [] = "unsetopt(option) -> None. Reset curl session option to default value. Throws pycurl.error exception upon failure.\n";
2090 static char co_multi_fdset_doc [] = "fdset() -> Tuple. Returns a tuple of three lists that can be passed to the select.select() method .\n";
2091 static char co_multi_info_read_doc [] = "info_read([max_objects]) -> Tuple. Returns a tuple (number of queued handles, [curl objects]).\n";
2092 static char co_multi_select_doc [] = "select([timeout]) -> Int. Returns result from doing a select() on the curl multi file descriptor with the given timeout.\n";
2094 static PyMethodDef curlobject_methods[] = {
2095 {"close", (PyCFunction)do_curl_close, METH_NOARGS, co_close_doc},
2096 {"errstr", (PyCFunction)do_curl_errstr, METH_NOARGS, co_errstr_doc},
2097 {"getinfo", (PyCFunction)do_curl_getinfo, METH_VARARGS, co_getinfo_doc},
2098 {"perform", (PyCFunction)do_curl_perform, METH_NOARGS, co_perform_doc},
2099 {"setopt", (PyCFunction)do_curl_setopt, METH_VARARGS, co_setopt_doc},
2100 {"unsetopt", (PyCFunction)do_curl_unsetopt, METH_VARARGS, co_unsetopt_doc},
2101 {NULL, NULL, 0, NULL}
2104 static PyMethodDef curlmultiobject_methods[] = {
2105 {"add_handle", (PyCFunction)do_multi_add_handle, METH_VARARGS, NULL},
2106 {"close", (PyCFunction)do_multi_close, METH_NOARGS, NULL},
2107 {"fdset", (PyCFunction)do_multi_fdset, METH_NOARGS, co_multi_fdset_doc},
2108 {"info_read", (PyCFunction)do_multi_info_read, METH_VARARGS, co_multi_info_read_doc},
2109 {"perform", (PyCFunction)do_multi_perform, METH_NOARGS, NULL},
2110 {"remove_handle", (PyCFunction)do_multi_remove_handle, METH_VARARGS, NULL},
2111 {"select", (PyCFunction)do_multi_select, METH_VARARGS, co_multi_select_doc},
2112 {NULL, NULL, 0, NULL}
2116 /* --------------- setattr/getattr --------------- */
2118 static PyObject *curlobject_constants = NULL;
2119 static PyObject *curlmultiobject_constants = NULL;
2122 my_setattr(PyObject **dict, char *name, PyObject *v)
2127 rv = PyDict_DelItemString(*dict, name);
2129 PyErr_SetString(PyExc_AttributeError, "delete non-existing attribute");
2132 if (*dict == NULL) {
2133 *dict = PyDict_New();
2137 return PyDict_SetItemString(*dict, name, v);
2141 my_getattr(PyObject *co, char *name, PyObject *dict1, PyObject *dict2, PyMethodDef *m)
2144 if (v == NULL && dict1 != NULL)
2145 v = PyDict_GetItemString(dict1, name);
2146 if (v == NULL && dict2 != NULL)
2147 v = PyDict_GetItemString(dict2, name);
2152 return Py_FindMethod(m, co, name);
2156 do_curl_setattr(CurlObject *co, char *name, PyObject *v)
2158 assert_curl_state(co);
2159 return my_setattr(&co->dict, name, v);
2163 do_multi_setattr(CurlMultiObject *co, char *name, PyObject *v)
2165 assert_multi_state(co);
2166 return my_setattr(&co->dict, name, v);
2170 do_curl_getattr(CurlObject *co, char *name)
2172 assert_curl_state(co);
2173 return my_getattr((PyObject *)co, name, co->dict,
2174 curlobject_constants, curlobject_methods);
2178 do_multi_getattr(CurlMultiObject *co, char *name)
2180 assert_multi_state(co);
2181 return my_getattr((PyObject *)co, name, co->dict,
2182 curlmultiobject_constants, curlmultiobject_methods);
2186 /* --------------- actual type definitions --------------- */
2188 static PyTypeObject Curl_Type = {
2189 PyObject_HEAD_INIT(NULL)
2191 "pycurl.Curl", /* tp_name */
2192 sizeof(CurlObject), /* tp_basicsize */
2193 0, /* tp_itemsize */
2195 (destructor)do_curl_dealloc, /* tp_dealloc */
2197 (getattrfunc)do_curl_getattr, /* tp_getattr */
2198 (setattrfunc)do_curl_setattr, /* tp_setattr */
2201 0, /* tp_as_number */
2202 0, /* tp_as_sequence */
2203 0, /* tp_as_mapping */
2207 0, /* tp_getattro */
2208 0, /* tp_setattro */
2209 0, /* tp_as_buffer */
2210 Py_TPFLAGS_HAVE_GC, /* tp_flags */
2212 (traverseproc)do_curl_traverse, /* tp_traverse */
2213 (inquiry)do_curl_clear /* tp_clear */
2214 /* More fields follow here, depending on your Python version. You can
2215 * safely ignore any compiler warnings about missing initializers.
2219 static PyTypeObject CurlMulti_Type = {
2220 PyObject_HEAD_INIT(NULL)
2222 "pycurl.CurlMulti", /* tp_name */
2223 sizeof(CurlMultiObject), /* tp_basicsize */
2224 0, /* tp_itemsize */
2226 (destructor)do_multi_dealloc, /* tp_dealloc */
2228 (getattrfunc)do_multi_getattr, /* tp_getattr */
2229 (setattrfunc)do_multi_setattr, /* tp_setattr */
2232 0, /* tp_as_number */
2233 0, /* tp_as_sequence */
2234 0, /* tp_as_mapping */
2238 0, /* tp_getattro */
2239 0, /* tp_setattro */
2240 0, /* tp_as_buffer */
2241 Py_TPFLAGS_HAVE_GC, /* tp_flags */
2243 (traverseproc)do_multi_traverse, /* tp_traverse */
2244 (inquiry)do_multi_clear /* tp_clear */
2245 /* More fields follow here, depending on your Python version. You can
2246 * safely ignore any compiler warnings about missing initializers.
2251 /*************************************************************************
2253 // Note that the object constructors (do_curl_new, do_multi_new)
2254 // are module-level functions as well.
2255 **************************************************************************/
2258 do_global_init(PyObject *dummy, PyObject *args)
2263 if (!PyArg_ParseTuple(args, "i:global_init", &option)) {
2267 if (!(option == CURL_GLOBAL_SSL ||
2268 option == CURL_GLOBAL_WIN32 ||
2269 option == CURL_GLOBAL_ALL ||
2270 option == CURL_GLOBAL_NOTHING)) {
2271 PyErr_SetString(PyExc_ValueError, "invalid option to global_init");
2275 res = curl_global_init(option);
2276 if (res != CURLE_OK) {
2277 PyErr_SetString(ErrorObject, "unable to set global option");
2287 do_global_cleanup(PyObject *dummy)
2290 curl_global_cleanup();
2297 static PyObject *vi_str(const char *s)
2303 while (*s == ' ' || *s == '\t')
2305 return PyString_FromString(s);
2309 do_version_info(PyObject *dummy, PyObject *args)
2311 const curl_version_info_data *vi;
2312 PyObject *ret = NULL;
2313 PyObject *protocols = NULL;
2316 int stamp = CURLVERSION_NOW;
2319 if (!PyArg_ParseTuple(args, "|i:version_info", &stamp)) {
2322 vi = curl_version_info((CURLversion) stamp);
2324 PyErr_SetString(ErrorObject, "unable to get version info");
2328 /* Note: actually libcurl in lib/version.c does ignore
2329 * the "stamp" parm, and so do we */
2331 for (i = 0; vi->protocols[i] != NULL; )
2333 protocols = PyTuple_New(i);
2334 if (protocols == NULL)
2336 for (i = 0; vi->protocols[i] != NULL; i++) {
2337 tmp = vi_str(vi->protocols[i]);
2340 PyTuple_SET_ITEM(protocols, i, tmp);
2342 ret = PyTuple_New(12);
2347 tmp = (v); if (tmp == NULL) goto error; PyTuple_SET_ITEM(ret, i, tmp)
2348 SET(0, PyInt_FromLong((long) vi->age));
2349 SET(1, vi_str(vi->version));
2350 SET(2, PyInt_FromLong(vi->version_num));
2351 SET(3, vi_str(vi->host));
2352 SET(4, PyInt_FromLong(vi->features));
2353 SET(5, vi_str(vi->ssl_version));
2354 SET(6, PyInt_FromLong(vi->ssl_version_num));
2355 SET(7, vi_str(vi->libz_version));
2357 SET(9, vi_str(vi->ares));
2358 SET(10, PyInt_FromLong(vi->ares_num));
2359 SET(11, vi_str(vi->libidn));
2365 Py_XDECREF(protocols);
2370 /* Per function docstrings */
2371 static char pycurl_global_init_doc [] =
2372 "global_init(option) -> None. Initialize curl environment.\n";
2374 static char pycurl_global_cleanup_doc [] =
2375 "global_cleanup() -> None. Cleanup curl environment.\n";
2377 static char pycurl_version_info_doc [] =
2378 "version_info() -> tuple. Returns a 12-tuple with the version info.\n";
2380 static char pycurl_curl_new_doc [] =
2381 "Curl() -> New curl object. Implicitly calls global_init() if not called.\n";
2383 static char pycurl_multi_new_doc [] =
2384 "CurlMulti() -> New curl multi-object.\n";
2387 /* List of functions defined in this module */
2388 static PyMethodDef curl_methods[] = {
2389 {"global_init", (PyCFunction)do_global_init, METH_VARARGS, pycurl_global_init_doc},
2390 {"global_cleanup", (PyCFunction)do_global_cleanup, METH_NOARGS, pycurl_global_cleanup_doc},
2391 {"version_info", (PyCFunction)do_version_info, METH_VARARGS, pycurl_version_info_doc},
2392 {"Curl", (PyCFunction)do_curl_new, METH_NOARGS, pycurl_curl_new_doc},
2393 {"CurlMulti", (PyCFunction)do_multi_new, METH_NOARGS, pycurl_multi_new_doc},
2394 {NULL, NULL, 0, NULL}
2398 /* Module docstring */
2399 static char module_doc [] =
2400 "This module implements an interface to the cURL library.\n"
2404 "Curl() -> New object. Create a new curl object.\n"
2405 "CurlMulti() -> New object. Create a new curl multi-object.\n"
2409 "global_init(option) -> None. Initialize curl environment.\n"
2410 "global_cleanup() -> None. Cleanup curl environment.\n"
2411 "version_info() -> tuple. Return version information.\n"
2415 /* Helper functions for inserting constants into the module namespace */
2418 insobj2(PyObject *dict1, PyObject *dict2, char *name, PyObject *value)
2420 /* Insert an object into one or two dicts. Eats a reference to value.
2421 * See also the implementation of PyDict_SetItemString(). */
2422 PyObject *key = NULL;
2424 if (dict1 == NULL && dict2 == NULL)
2428 key = PyString_FromString(name);
2432 PyString_InternInPlace(&key); /* XXX Should we really? */
2434 if (dict1 != NULL) {
2435 assert(PyDict_GetItem(dict1, key) == NULL);
2436 if (PyDict_SetItem(dict1, key, value) != 0)
2439 if (dict2 != NULL && dict2 != dict1) {
2440 assert(PyDict_GetItem(dict2, key) == NULL);
2441 if (PyDict_SetItem(dict2, key, value) != 0)
2448 Py_FatalError("pycurl: FATAL: insobj2() failed");
2453 insstr(PyObject *d, char *name, char *value)
2455 PyObject *v = PyString_FromString(value);
2456 insobj2(d, NULL, name, v);
2460 insint(PyObject *d, char *name, long value)
2462 PyObject *v = PyInt_FromLong(value);
2463 insobj2(d, NULL, name, v);
2467 insint_c(PyObject *d, char *name, long value)
2469 PyObject *v = PyInt_FromLong(value);
2470 insobj2(d, curlobject_constants, name, v);
2474 insint_m(PyObject *d, char *name, long value)
2476 PyObject *v = PyInt_FromLong(value);
2477 insobj2(d, curlmultiobject_constants, name, v);
2481 /* Initialization function for the module */
2482 #if defined(PyMODINIT_FUNC)
2485 #if defined(__cplusplus)
2493 const curl_version_info_data *vi;
2495 /* Initialize the type of the new type objects here; doing it here
2496 * is required for portability to Windows without requiring C++. */
2497 p_Curl_Type = &Curl_Type;
2498 p_CurlMulti_Type = &CurlMulti_Type;
2499 Curl_Type.ob_type = &PyType_Type;
2500 CurlMulti_Type.ob_type = &PyType_Type;
2502 /* Create the module and add the functions */
2503 m = Py_InitModule3("pycurl", curl_methods, module_doc);
2504 assert(m != NULL && PyModule_Check(m));
2506 /* Add error object to the module */
2507 d = PyModule_GetDict(m);
2509 ErrorObject = PyErr_NewException("pycurl.error", NULL, NULL);
2510 assert(ErrorObject != NULL);
2511 PyDict_SetItemString(d, "error", ErrorObject);
2513 curlobject_constants = PyDict_New();
2514 assert(curlobject_constants != NULL);
2516 /* Add version strings to the module */
2517 insstr(d, "version", curl_version());
2518 insstr(d, "COMPILE_DATE", __DATE__ " " __TIME__);
2519 insint(d, "COMPILE_PY_VERSION_HEX", PY_VERSION_HEX);
2520 insint(d, "COMPILE_LIBCURL_VERSION_NUM", LIBCURL_VERSION_NUM);
2523 ** the order of these constants mostly follows <curl/curl.h>
2526 /* Abort curl_read_callback(). */
2527 insint_c(d, "READFUNC_ABORT", CURL_READFUNC_ABORT);
2529 /* constants for ioctl callback return values */
2530 insint_c(d, "IOE_OK", CURLIOE_OK);
2531 insint_c(d, "IOE_UNKNOWNCMD", CURLIOE_UNKNOWNCMD);
2532 insint_c(d, "IOE_FAILRESTART", CURLIOE_FAILRESTART);
2534 /* curl_infotype: the kind of data that is passed to information_callback */
2535 /* XXX do we actually need curl_infotype in pycurl ??? */
2536 insint_c(d, "INFOTYPE_TEXT", CURLINFO_TEXT);
2537 insint_c(d, "INFOTYPE_HEADER_IN", CURLINFO_HEADER_IN);
2538 insint_c(d, "INFOTYPE_HEADER_OUT", CURLINFO_HEADER_OUT);
2539 insint_c(d, "INFOTYPE_DATA_IN", CURLINFO_DATA_IN);
2540 insint_c(d, "INFOTYPE_DATA_OUT", CURLINFO_DATA_OUT);
2541 insint_c(d, "INFOTYPE_SSL_DATA_IN", CURLINFO_SSL_DATA_IN);
2542 insint_c(d, "INFOTYPE_SSL_DATA_OUT", CURLINFO_SSL_DATA_OUT);
2544 /* CURLcode: error codes */
2545 /* FIXME: lots of error codes are missing */
2546 insint_c(d, "E_OK", CURLE_OK);
2547 insint_c(d, "E_UNSUPPORTED_PROTOCOL", CURLE_UNSUPPORTED_PROTOCOL);
2549 /* curl_proxytype: constants for setopt(PROXYTYPE, x) */
2550 insint_c(d, "PROXYTYPE_HTTP", CURLPROXY_HTTP);
2551 insint_c(d, "PROXYTYPE_SOCKS4", CURLPROXY_SOCKS4);
2552 insint_c(d, "PROXYTYPE_SOCKS5", CURLPROXY_SOCKS5);
2554 /* curl_httpauth: constants for setopt(HTTPAUTH, x) */
2555 insint_c(d, "HTTPAUTH_NONE", CURLAUTH_NONE);
2556 insint_c(d, "HTTPAUTH_BASIC", CURLAUTH_BASIC);
2557 insint_c(d, "HTTPAUTH_DIGEST", CURLAUTH_DIGEST);
2558 insint_c(d, "HTTPAUTH_GSSNEGOTIATE", CURLAUTH_GSSNEGOTIATE);
2559 insint_c(d, "HTTPAUTH_NTLM", CURLAUTH_NTLM);
2560 insint_c(d, "HTTPAUTH_ANY", CURLAUTH_ANY);
2561 insint_c(d, "HTTPAUTH_ANYSAFE", CURLAUTH_ANYSAFE);
2563 /* curl_ftpssl: constants for setopt(FTP_SSL, x) */
2564 insint_c(d, "FTPSSL_NONE", CURLFTPSSL_NONE);
2565 insint_c(d, "FTPSSL_TRY", CURLFTPSSL_TRY);
2566 insint_c(d, "FTPSSL_CONTROL", CURLFTPSSL_CONTROL);
2567 insint_c(d, "FTPSSL_ALL", CURLFTPSSL_ALL);
2569 /* curl_ftpauth: constants for setopt(FTPSSLAUTH, x) */
2570 insint_c(d, "FTPAUTH_DEFAULT", CURLFTPAUTH_DEFAULT);
2571 insint_c(d, "FTPAUTH_SSL", CURLFTPAUTH_SSL);
2572 insint_c(d, "FTPAUTH_TLS", CURLFTPAUTH_TLS);
2574 /* curl_ftpauth: constants for setopt(FTPSSLAUTH, x) */
2575 insint_c(d, "FORM_CONTENTS", CURLFORM_COPYCONTENTS);
2576 insint_c(d, "FORM_FILE", CURLFORM_FILE);
2577 insint_c(d, "FORM_CONTENTTYPE", CURLFORM_CONTENTTYPE);
2579 /* CURLoption: symbolic constants for setopt() */
2580 /* FIXME: reorder these to match <curl/curl.h> */
2581 insint_c(d, "FILE", CURLOPT_WRITEDATA);
2582 insint_c(d, "URL", CURLOPT_URL);
2583 insint_c(d, "PORT", CURLOPT_PORT);
2584 insint_c(d, "PROXY", CURLOPT_PROXY);
2585 insint_c(d, "USERPWD", CURLOPT_USERPWD);
2586 insint_c(d, "PROXYUSERPWD", CURLOPT_PROXYUSERPWD);
2587 insint_c(d, "RANGE", CURLOPT_RANGE);
2588 insint_c(d, "INFILE", CURLOPT_READDATA);
2589 /* ERRORBUFFER is not supported */
2590 insint_c(d, "WRITEFUNCTION", CURLOPT_WRITEFUNCTION);
2591 insint_c(d, "READFUNCTION", CURLOPT_READFUNCTION);
2592 insint_c(d, "TIMEOUT", CURLOPT_TIMEOUT);
2593 insint_c(d, "INFILESIZE", CURLOPT_INFILESIZE_LARGE); /* _LARGE ! */
2594 insint_c(d, "POSTFIELDS", CURLOPT_POSTFIELDS);
2595 insint_c(d, "REFERER", CURLOPT_REFERER);
2596 insint_c(d, "FTPPORT", CURLOPT_FTPPORT);
2597 insint_c(d, "USERAGENT", CURLOPT_USERAGENT);
2598 insint_c(d, "LOW_SPEED_LIMIT", CURLOPT_LOW_SPEED_LIMIT);
2599 insint_c(d, "LOW_SPEED_TIME", CURLOPT_LOW_SPEED_TIME);
2600 insint_c(d, "RESUME_FROM", CURLOPT_RESUME_FROM_LARGE); /* _LARGE ! */
2601 insint_c(d, "WRITEDATA", CURLOPT_WRITEDATA);
2602 insint_c(d, "READDATA", CURLOPT_READDATA);
2603 insint_c(d, "PROXYPORT", CURLOPT_PROXYPORT);
2604 insint_c(d, "HTTPPROXYTUNNEL", CURLOPT_HTTPPROXYTUNNEL);
2605 insint_c(d, "VERBOSE", CURLOPT_VERBOSE);
2606 insint_c(d, "HEADER", CURLOPT_HEADER);
2607 insint_c(d, "NOPROGRESS", CURLOPT_NOPROGRESS);
2608 insint_c(d, "NOBODY", CURLOPT_NOBODY);
2609 insint_c(d, "FAILONERROR", CURLOPT_FAILONERROR);
2610 insint_c(d, "UPLOAD", CURLOPT_UPLOAD);
2611 insint_c(d, "POST", CURLOPT_POST);
2612 insint_c(d, "FTPLISTONLY", CURLOPT_FTPLISTONLY);
2613 insint_c(d, "FTPAPPEND", CURLOPT_FTPAPPEND);
2614 insint_c(d, "NETRC", CURLOPT_NETRC);
2615 insint_c(d, "FOLLOWLOCATION", CURLOPT_FOLLOWLOCATION);
2616 insint_c(d, "TRANSFERTEXT", CURLOPT_TRANSFERTEXT);
2617 insint_c(d, "PUT", CURLOPT_PUT);
2618 insint_c(d, "POSTFIELDSIZE", CURLOPT_POSTFIELDSIZE_LARGE); /* _LARGE ! */
2619 insint_c(d, "COOKIE", CURLOPT_COOKIE);
2620 insint_c(d, "HTTPHEADER", CURLOPT_HTTPHEADER);
2621 insint_c(d, "HTTPPOST", CURLOPT_HTTPPOST);
2622 insint_c(d, "SSLCERT", CURLOPT_SSLCERT);
2623 insint_c(d, "SSLCERTPASSWD", CURLOPT_SSLCERTPASSWD);
2624 insint_c(d, "CRLF", CURLOPT_CRLF);
2625 insint_c(d, "QUOTE", CURLOPT_QUOTE);
2626 insint_c(d, "POSTQUOTE", CURLOPT_POSTQUOTE);
2627 insint_c(d, "PREQUOTE", CURLOPT_PREQUOTE);
2628 insint_c(d, "WRITEHEADER", CURLOPT_WRITEHEADER);
2629 insint_c(d, "HEADERFUNCTION", CURLOPT_HEADERFUNCTION);
2630 insint_c(d, "COOKIEFILE", CURLOPT_COOKIEFILE);
2631 insint_c(d, "SSLVERSION", CURLOPT_SSLVERSION);
2632 insint_c(d, "TIMECONDITION", CURLOPT_TIMECONDITION);
2633 insint_c(d, "TIMEVALUE", CURLOPT_TIMEVALUE);
2634 insint_c(d, "CUSTOMREQUEST", CURLOPT_CUSTOMREQUEST);
2635 insint_c(d, "STDERR", CURLOPT_STDERR);
2636 insint_c(d, "INTERFACE", CURLOPT_INTERFACE);
2637 insint_c(d, "KRB4LEVEL", CURLOPT_KRB4LEVEL);
2638 insint_c(d, "PROGRESSFUNCTION", CURLOPT_PROGRESSFUNCTION);
2639 insint_c(d, "SSL_VERIFYPEER", CURLOPT_SSL_VERIFYPEER);
2640 insint_c(d, "CAPATH", CURLOPT_CAPATH);
2641 insint_c(d, "CAINFO", CURLOPT_CAINFO);
2642 insint_c(d, "OPT_FILETIME", CURLOPT_FILETIME);
2643 insint_c(d, "MAXREDIRS", CURLOPT_MAXREDIRS);
2644 insint_c(d, "MAXCONNECTS", CURLOPT_MAXCONNECTS);
2645 insint_c(d, "CLOSEPOLICY", CURLOPT_CLOSEPOLICY);
2646 insint_c(d, "FRESH_CONNECT", CURLOPT_FRESH_CONNECT);
2647 insint_c(d, "FORBID_REUSE", CURLOPT_FORBID_REUSE);
2648 insint_c(d, "RANDOM_FILE", CURLOPT_RANDOM_FILE);
2649 insint_c(d, "EGDSOCKET", CURLOPT_EGDSOCKET);
2650 insint_c(d, "CONNECTTIMEOUT", CURLOPT_CONNECTTIMEOUT);
2651 insint_c(d, "HTTPGET", CURLOPT_HTTPGET);
2652 insint_c(d, "SSL_VERIFYHOST", CURLOPT_SSL_VERIFYHOST);
2653 insint_c(d, "COOKIEJAR", CURLOPT_COOKIEJAR);
2654 insint_c(d, "SSL_CIPHER_LIST", CURLOPT_SSL_CIPHER_LIST);
2655 insint_c(d, "HTTP_VERSION", CURLOPT_HTTP_VERSION);
2656 insint_c(d, "FTP_USE_EPSV", CURLOPT_FTP_USE_EPSV);
2657 insint_c(d, "SSLCERTTYPE", CURLOPT_SSLCERTTYPE);
2658 insint_c(d, "SSLKEY", CURLOPT_SSLKEY);
2659 insint_c(d, "SSLKEYTYPE", CURLOPT_SSLKEYTYPE);
2660 insint_c(d, "SSLKEYPASSWD", CURLOPT_SSLKEYPASSWD);
2661 insint_c(d, "SSLENGINE", CURLOPT_SSLENGINE);
2662 insint_c(d, "SSLENGINE_DEFAULT", CURLOPT_SSLENGINE_DEFAULT);
2663 insint_c(d, "DNS_CACHE_TIMEOUT", CURLOPT_DNS_CACHE_TIMEOUT);
2664 insint_c(d, "DNS_USE_GLOBAL_CACHE", CURLOPT_DNS_USE_GLOBAL_CACHE);
2665 insint_c(d, "DEBUGFUNCTION", CURLOPT_DEBUGFUNCTION);
2666 insint_c(d, "BUFFERSIZE", CURLOPT_BUFFERSIZE);
2667 insint_c(d, "NOSIGNAL", CURLOPT_NOSIGNAL);
2668 insint_c(d, "SHARE", CURLOPT_SHARE);
2669 insint_c(d, "PROXYTYPE", CURLOPT_PROXYTYPE);
2670 insint_c(d, "ENCODING", CURLOPT_ENCODING);
2671 insint_c(d, "HTTP200ALIASES", CURLOPT_HTTP200ALIASES);
2672 insint_c(d, "UNRESTRICTED_AUTH", CURLOPT_UNRESTRICTED_AUTH);
2673 insint_c(d, "FTP_USE_EPRT", CURLOPT_FTP_USE_EPRT);
2674 insint_c(d, "HTTPAUTH", CURLOPT_HTTPAUTH);
2675 insint_c(d, "FTP_CREATE_MISSING_DIRS", CURLOPT_FTP_CREATE_MISSING_DIRS);
2676 insint_c(d, "PROXYAUTH", CURLOPT_PROXYAUTH);
2677 insint_c(d, "FTP_RESPONSE_TIMEOUT", CURLOPT_FTP_RESPONSE_TIMEOUT);
2678 insint_c(d, "IPRESOLVE", CURLOPT_IPRESOLVE);
2679 insint_c(d, "MAXFILESIZE", CURLOPT_MAXFILESIZE_LARGE); /* _LARGE ! */
2680 insint_c(d, "INFILESIZE_LARGE", CURLOPT_INFILESIZE_LARGE);
2681 insint_c(d, "RESUME_FROM_LARGE", CURLOPT_RESUME_FROM_LARGE);
2682 insint_c(d, "MAXFILESIZE_LARGE", CURLOPT_MAXFILESIZE_LARGE);
2683 insint_c(d, "NETRC_FILE", CURLOPT_NETRC_FILE);
2684 insint_c(d, "FTP_SSL", CURLOPT_FTP_SSL);
2685 insint_c(d, "POSTFIELDSIZE_LARGE", CURLOPT_POSTFIELDSIZE_LARGE);
2686 insint_c(d, "TCP_NODELAY", CURLOPT_TCP_NODELAY);
2687 insint_c(d, "SOURCE_USERPWD", CURLOPT_SOURCE_USERPWD);
2688 insint_c(d, "SOURCE_PREQUOTE", CURLOPT_SOURCE_PREQUOTE);
2689 insint_c(d, "SOURCE_POSTQUOTE", CURLOPT_SOURCE_POSTQUOTE);
2690 insint_c(d, "FTPSSLAUTH", CURLOPT_FTPSSLAUTH);
2691 insint_c(d, "IOCTLFUNCTION", CURLOPT_IOCTLFUNCTION);
2692 insint_c(d, "IOCTLDATA", CURLOPT_IOCTLDATA);
2693 insint_c(d, "SOURCE_URL", CURLOPT_SOURCE_URL);
2694 insint_c(d, "SOURCE_QUOTE", CURLOPT_SOURCE_QUOTE);
2695 insint_c(d, "FTP_ACCOUNT", CURLOPT_FTP_ACCOUNT);
2697 /* constants for setopt(IPRESOLVE, x) */
2698 insint_c(d, "IPRESOLVE_WHATEVER", CURL_IPRESOLVE_WHATEVER);
2699 insint_c(d, "IPRESOLVE_V4", CURL_IPRESOLVE_V4);
2700 insint_c(d, "IPRESOLVE_V6", CURL_IPRESOLVE_V6);
2702 /* constants for setopt(HTTP_VERSION, x) */
2703 insint_c(d, "CURL_HTTP_VERSION_NONE", CURL_HTTP_VERSION_NONE);
2704 insint_c(d, "CURL_HTTP_VERSION_1_0", CURL_HTTP_VERSION_1_0);
2705 insint_c(d, "CURL_HTTP_VERSION_1_1", CURL_HTTP_VERSION_1_1);
2706 insint_c(d, "CURL_HTTP_VERSION_LAST", CURL_HTTP_VERSION_LAST);
2708 /* CURL_NETRC_OPTION: constants for setopt(NETRC, x) */
2709 insint_c(d, "NETRC_OPTIONAL", CURL_NETRC_OPTIONAL);
2710 insint_c(d, "NETRC_IGNORED", CURL_NETRC_IGNORED);
2711 insint_c(d, "NETRC_REQUIRED", CURL_NETRC_REQUIRED);
2713 /* constants for setopt(SSLVERSION, x) */
2714 insint_c(d, "SSLVERSION_DEFAULT", CURL_SSLVERSION_DEFAULT);
2715 insint_c(d, "SSLVERSION_TLSv1", CURL_SSLVERSION_TLSv1);
2716 insint_c(d, "SSLVERSION_SSLv2", CURL_SSLVERSION_SSLv2);
2717 insint_c(d, "SSLVERSION_SSLv3", CURL_SSLVERSION_SSLv3);
2719 /* curl_TimeCond: constants for setopt(TIMECONDITION, x) */
2720 insint_c(d, "TIMECONDITION_NONE", CURL_TIMECOND_NONE);
2721 insint_c(d, "TIMECONDITION_IFMODSINCE", CURL_TIMECOND_IFMODSINCE);
2722 insint_c(d, "TIMECONDITION_IFUNMODSINCE", CURL_TIMECOND_IFUNMODSINCE);
2723 insint_c(d, "TIMECONDITION_LASTMOD", CURL_TIMECOND_LASTMOD);
2725 /* CURLINFO: symbolic constants for getinfo(x) */
2726 insint_c(d, "EFFECTIVE_URL", CURLINFO_EFFECTIVE_URL);
2727 insint_c(d, "HTTP_CODE", CURLINFO_HTTP_CODE);
2728 insint_c(d, "RESPONSE_CODE", CURLINFO_HTTP_CODE);
2729 insint_c(d, "TOTAL_TIME", CURLINFO_TOTAL_TIME);
2730 insint_c(d, "NAMELOOKUP_TIME", CURLINFO_NAMELOOKUP_TIME);
2731 insint_c(d, "CONNECT_TIME", CURLINFO_CONNECT_TIME);
2732 insint_c(d, "PRETRANSFER_TIME", CURLINFO_PRETRANSFER_TIME);
2733 insint_c(d, "SIZE_UPLOAD", CURLINFO_SIZE_UPLOAD);
2734 insint_c(d, "SIZE_DOWNLOAD", CURLINFO_SIZE_DOWNLOAD);
2735 insint_c(d, "SPEED_DOWNLOAD", CURLINFO_SPEED_DOWNLOAD);
2736 insint_c(d, "SPEED_UPLOAD", CURLINFO_SPEED_UPLOAD);
2737 insint_c(d, "HEADER_SIZE", CURLINFO_HEADER_SIZE);
2738 insint_c(d, "REQUEST_SIZE", CURLINFO_REQUEST_SIZE);
2739 insint_c(d, "SSL_VERIFYRESULT", CURLINFO_SSL_VERIFYRESULT);
2740 insint_c(d, "INFO_FILETIME", CURLINFO_FILETIME);
2741 insint_c(d, "CONTENT_LENGTH_DOWNLOAD", CURLINFO_CONTENT_LENGTH_DOWNLOAD);
2742 insint_c(d, "CONTENT_LENGTH_UPLOAD", CURLINFO_CONTENT_LENGTH_UPLOAD);
2743 insint_c(d, "STARTTRANSFER_TIME", CURLINFO_STARTTRANSFER_TIME);
2744 insint_c(d, "CONTENT_TYPE", CURLINFO_CONTENT_TYPE);
2745 insint_c(d, "REDIRECT_TIME", CURLINFO_REDIRECT_TIME);
2746 insint_c(d, "REDIRECT_COUNT", CURLINFO_REDIRECT_COUNT);
2747 insint_c(d, "HTTP_CONNECTCODE", CURLINFO_HTTP_CONNECTCODE);
2748 insint_c(d, "HTTPAUTH_AVAIL", CURLINFO_HTTPAUTH_AVAIL);
2749 insint_c(d, "PROXYAUTH_AVAIL", CURLINFO_PROXYAUTH_AVAIL);
2750 insint_c(d, "OS_ERRNO", CURLINFO_OS_ERRNO);
2751 insint_c(d, "NUM_CONNECTS", CURLINFO_NUM_CONNECTS);
2752 insint_c(d, "SSL_ENGINES", CURLINFO_SSL_ENGINES);
2754 /* curl_closepolicy: constants for setopt(CLOSEPOLICY, x) */
2755 insint_c(d, "CLOSEPOLICY_OLDEST", CURLCLOSEPOLICY_OLDEST);
2756 insint_c(d, "CLOSEPOLICY_LEAST_RECENTLY_USED", CURLCLOSEPOLICY_LEAST_RECENTLY_USED);
2757 insint_c(d, "CLOSEPOLICY_LEAST_TRAFFIC", CURLCLOSEPOLICY_LEAST_TRAFFIC);
2758 insint_c(d, "CLOSEPOLICY_SLOWEST", CURLCLOSEPOLICY_SLOWEST);
2759 insint_c(d, "CLOSEPOLICY_CALLBACK", CURLCLOSEPOLICY_CALLBACK);
2761 /* options for global_init() */
2762 insint(d, "GLOBAL_SSL", CURL_GLOBAL_SSL);
2763 insint(d, "GLOBAL_WIN32", CURL_GLOBAL_WIN32);
2764 insint(d, "GLOBAL_ALL", CURL_GLOBAL_ALL);
2765 insint(d, "GLOBAL_NOTHING", CURL_GLOBAL_NOTHING);
2766 insint(d, "GLOBAL_DEFAULT", CURL_GLOBAL_DEFAULT);
2768 /* curl_lock_data: XXX do we need this in pycurl ??? */
2769 /* curl_lock_access: XXX do we need this in pycurl ??? */
2770 /* CURLSHcode: XXX do we need this in pycurl ??? */
2771 /* CURLSHoption: XXX do we need this in pycurl ??? */
2773 /* CURLversion: constants for curl_version_info(x) */
2775 /* XXX - do we need these ?? */
2776 insint(d, "VERSION_FIRST", CURLVERSION_FIRST);
2777 insint(d, "VERSION_SECOND", CURLVERSION_SECOND);
2778 insint(d, "VERSION_THIRD", CURLVERSION_THIRD);
2779 insint(d, "VERSION_NOW", CURLVERSION_NOW);
2782 /* version features - bitmasks for curl_version_info_data.features */
2784 /* XXX - do we need these ?? */
2785 /* XXX - should we really rename these ?? */
2786 insint(d, "VERSION_FEATURE_IPV6", CURL_VERSION_IPV6);
2787 insint(d, "VERSION_FEATURE_KERBEROS4", CURL_VERSION_KERBEROS4);
2788 insint(d, "VERSION_FEATURE_SSL", CURL_VERSION_SSL);
2789 insint(d, "VERSION_FEATURE_LIBZ", CURL_VERSION_LIBZ);
2790 insint(d, "VERSION_FEATURE_NTLM", CURL_VERSION_NTLM);
2791 insint(d, "VERSION_FEATURE_GSSNEGOTIATE", CURL_VERSION_GSSNEGOTIATE);
2792 insint(d, "VERSION_FEATURE_DEBUG", CURL_VERSION_DEBUG);
2793 insint(d, "VERSION_FEATURE_ASYNCHDNS", CURL_VERSION_ASYNCHDNS);
2794 insint(d, "VERSION_FEATURE_SPNEGO", CURL_VERSION_SPNEGO);
2795 insint(d, "VERSION_FEATURE_LARGEFILE", CURL_VERSION_LARGEFILE);
2796 insint(d, "VERSION_FEATURE_IDN", CURL_VERSION_IDN);
2800 ** the order of these constants mostly follows <curl/multi.h>
2803 /* CURLMcode: multi error codes */
2804 insint_m(d, "E_CALL_MULTI_PERFORM", CURLM_CALL_MULTI_PERFORM);
2805 insint_m(d, "E_MULTI_OK", CURLM_OK);
2806 insint_m(d, "E_MULTI_BAD_HANDLE", CURLM_BAD_HANDLE);
2807 insint_m(d, "E_MULTI_BAD_EASY_HANDLE", CURLM_BAD_EASY_HANDLE);
2808 insint_m(d, "E_MULTI_OUT_OF_MEMORY", CURLM_OUT_OF_MEMORY);
2809 insint_m(d, "E_MULTI_INTERNAL_ERROR", CURLM_INTERNAL_ERROR);
2811 /* Check the version, as this has caused nasty problems in
2813 vi = curl_version_info(CURLVERSION_NOW);
2815 Py_FatalError("pycurl: FATAL: curl_version_info() failed");
2818 if (vi->version_num < LIBCURL_VERSION_NUM) {
2819 Py_FatalError("pycurl: FATAL: libcurl link-time version is older than compile-time version");
2823 /* Finally initialize global interpreter lock */
2824 PyEval_InitThreads();
2827 /* vi:ts=4:et:nowrap