[Python-modules-commits] [pycurl] 09/140: Import pycurl_7.13.1.orig.tar.gz

Barry Warsaw barry at moszumanska.debian.org
Wed Oct 1 21:45:00 UTC 2014


This is an automated email from the git hooks/post-receive script.

barry pushed a commit to branch master
in repository pycurl.

commit b401d0dc66c1b82e8420352d99bc27d68a2b1977
Author: Barry Warsaw <barry at python.org>
Date:   Wed Oct 1 16:43:21 2014 -0400

    Import pycurl_7.13.1.orig.tar.gz
---
 ChangeLog                   |  30 ++++-
 PKG-INFO                    |   2 +-
 TODO                        |   7 +-
 doc/curlobject.html         |   4 +-
 doc/pycurl.html             |   5 +-
 examples/basicfirst.py      |   4 +-
 examples/file_upload.py     |  30 ++---
 examples/retriever-multi.py |  23 ++--
 examples/retriever.py       |  74 +++++++----
 examples/xmlrpc_curl.py     |   4 +-
 setup.py                    |   6 +-
 setup_win32_ssl.py          |   4 +-
 src/pycurl.c                | 294 +++++++++++++++++++++++++++++---------------
 tests/test_post2.py         |   8 +-
 14 files changed, 312 insertions(+), 183 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index f02bd3c..0e5ae7e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,32 @@
-Version 7.13.0 [requires libcurl-7.13.0 or better]
+Version 7.13.1 [requires libcurl-7.13.1 or better]
+--------------
+
+2005-03-04  Kjetil Jacobsen  <kjetilja>
+
+        * Use METH_NOARGS where appropriate.
+
+2005-03-03  Kjetil Jacobsen  <kjetilja>
+
+        * Added support for CURLFORM API with HTTPPOST: Supports a
+          a tuple with pairs of options and values instead of just
+          supporting string contents.  See tests/test_post2.py
+          for example usage.  Options are FORM_CONTENTS, FORM_FILE and
+          FORM_CONTENTTYPE, corresponding to the CURLFORM_* options,
+          and values are strings.
+
+2005-02-13  Markus F.X.J. Oberhumer <mfx>
+
+        * Read callbacks (pycurl.READFUNCTION) can now return
+          pycurl.READFUNC_ABORT to immediately abort the current transfer.
+
+        * The INFILESIZE, MAXFILESIZE, POSTFIELDSIZE and RESUME_FROM
+          options now automatically use the largefile version to handle
+          files > 2GB.
+
+        * Added missing pycurl.PORT constant.
+
+
+Version 7.13.0
 --------------
 
 2005-02-10  Kjetil Jacobsen  <kjetilja>
diff --git a/PKG-INFO b/PKG-INFO
index 7012c4e..f0c0e97 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.0
 Name: pycurl
-Version: 7.13.0
+Version: 7.13.1
 Summary: PycURL -- cURL library module for Python
 Home-page: http://pycurl.sourceforge.net/
 Author: Kjetil Jacobsen, Markus F.X.J. Oberhumer
diff --git a/TODO b/TODO
index 8696e58..0ed534a 100644
--- a/TODO
+++ b/TODO
@@ -1,4 +1,4 @@
-# $Id: TODO,v 1.92 2005/02/08 11:46:05 kjetilja Exp $
+# $Id: TODO,v 1.95 2005/03/04 14:43:04 kjetilja Exp $
 # vi:ts=4:et
 
 If you want to hack on pycurl, here's our list of unresolved issues:
@@ -6,8 +6,6 @@ If you want to hack on pycurl, here's our list of unresolved issues:
 
 NEW FEATURES/IMPROVEMENTS:
 
-    * Support more of the CURLFORM_* API in HTTPPOST?
-
     * Add docs to the high-level interface.
 
     * Add more options to the undocumented and currently mostly useless
@@ -18,8 +16,6 @@ NEW FEATURES/IMPROVEMENTS:
       careful since curl_easy_reset() e.g. modifies callbacks and other
       pointers which could leave pycurl and libcurl out of sync.
 
-    * Use METH_O and METH_NOARGS where appropriate instead of METH_VARAGS.
-
 
 DEFICIENICES:
 
@@ -29,4 +25,3 @@ DEFICIENICES:
       There _are_ quite a number of internal error checks, but tracking and
       catching all possible (deliberate) misuses is not a goal (and probably
       impossible anyway, due to the complexity of libcurl).
-
diff --git a/doc/curlobject.html b/doc/curlobject.html
index 281ba2e..4a6fe78 100644
--- a/doc/curlobject.html
+++ b/doc/curlobject.html
@@ -45,7 +45,7 @@ integer, long integer, file objects, lists, or functions.</p>
 import pycurl
 c = pycurl.Curl()
 c.setopt(pycurl.URL, "http://www.python.org/")
-c.setopt(pycurl.HTTPHEADER, ["User-Agent: PycURL test", "Accept:"])
+c.setopt(pycurl.HTTPHEADER, ["Accept:"])
 import StringIO
 b = StringIO.StringIO()
 c.setopt(pycurl.WRITEFUNCTION, b.write)
@@ -95,7 +95,7 @@ print c.getinfo(pycurl.HTTP_CODE), c.getinfo(pycurl.EFFECTIVE_URL)
   <a href="http://validator.w3.org/check/referer"><img align="right"
      src="http://www.w3.org/Icons/valid-xhtml10"
      alt="Valid XHTML 1.0!" height="31" width="88" border="0" /></a>
-  $Id: curlobject.html,v 1.13 2004/03/15 10:57:04 kjetilja Exp $
+  $Id: curlobject.html,v 1.14 2005/02/11 11:09:09 mfx Exp $
 </p>
 
 </body>
diff --git a/doc/pycurl.html b/doc/pycurl.html
index bdbcc10..39c34fb 100644
--- a/doc/pycurl.html
+++ b/doc/pycurl.html
@@ -85,7 +85,8 @@ Returns a tuple of information which is similar to the
 <p>This function creates a new
 <a href="curlobject.html">Curl object</a> which corresponds to a
 <code>CURL</code> handle in libcurl. Curl objects automatically
-set CURLOPT_VERBOSE to 0, CURLOPT_NOPROGRESS to 1 and
+set CURLOPT_VERBOSE to 0, CURLOPT_NOPROGRESS to 1,
+provide a default CURLOPT_USERAGENT and setup
 CURLOPT_ERRORBUFFER to point to a private error buffer.</p>
 </dd>
 
@@ -112,7 +113,7 @@ a <code>CURLM</code> handle in libcurl.</p>
   <a href="http://validator.w3.org/check/referer"><img align="right"
      src="http://www.w3.org/Icons/valid-xhtml10"
      alt="Valid XHTML 1.0!" height="31" width="88" border="0" /></a>
-  $Id: pycurl.html,v 1.27 2004/12/22 14:27:16 mfx Exp $
+  $Id: pycurl.html,v 1.28 2005/02/11 11:09:10 mfx Exp $
 </p>
 
 </body>
diff --git a/examples/basicfirst.py b/examples/basicfirst.py
index a63c4be..4e49465 100644
--- a/examples/basicfirst.py
+++ b/examples/basicfirst.py
@@ -1,7 +1,7 @@
 #! /usr/bin/env python
 # -*- coding: iso-8859-1 -*-
 # vi:ts=4:et
-# $Id: basicfirst.py,v 1.4 2003/05/07 17:46:58 esr Exp $
+# $Id: basicfirst.py,v 1.5 2005/02/11 11:09:11 mfx Exp $
 
 import sys
 import pycurl
@@ -19,8 +19,6 @@ t = Test()
 c = pycurl.Curl()
 c.setopt(c.URL, 'http://curl.haxx.se/dev/')
 c.setopt(c.WRITEFUNCTION, t.body_callback)
-c.setopt(c.HTTPHEADER, ["I-am-a-silly-programmer: yes indeed you are",
-                        "User-Agent: Python interface for libcURL"])
 c.perform()
 c.close()
 
diff --git a/examples/file_upload.py b/examples/file_upload.py
index ad690cb..e513e7d 100644
--- a/examples/file_upload.py
+++ b/examples/file_upload.py
@@ -1,28 +1,24 @@
 #! /usr/bin/env python
 # -*- coding: iso-8859-1 -*-
 # vi:ts=4:et
-# $Id: file_upload.py,v 1.3 2005/02/10 11:26:23 kjetilja Exp $
+# $Id: file_upload.py,v 1.5 2005/02/13 08:53:13 mfx Exp $
 
+import os, sys
 import pycurl
-import sys
-import os.path
 
 # Class which holds a file reference and the read callback
-class filereader:
-
-    def __init__(self, f):
-        self.f = f
-
+class FileReader:
+    def __init__(self, fp):
+        self.fp = fp
     def read_callback(self, size):
-        return self.f.read(size)
+        return self.fp.read(size)
 
 # Check commandline arguments
 if len(sys.argv) < 3:
     print "Usage: %s <url> <file to upload>" % sys.argv[0]
     raise SystemExit
-else:
-    url = sys.argv[1]
-    filename = sys.argv[2]
+url = sys.argv[1]
+filename = sys.argv[2]
 
 if not os.path.exists(filename):
     print "Error: the file '%s' does not exist" % filename
@@ -36,17 +32,13 @@ c.setopt(pycurl.UPLOAD, 1)
 # Two versions with the same semantics here, but the filereader version
 # is useful when you have to process the data which is read before returning
 if 1:
-    c.setopt(pycurl.READFUNCTION, filereader(open(filename, 'rb')).read_callback)
+    c.setopt(pycurl.READFUNCTION, FileReader(open(filename, 'rb')).read_callback)
 else:
     c.setopt(pycurl.READFUNCTION, open(filename, 'rb').read)
 
-# Set size of file to be uploaded, use LARGE option if file size is
-# greater than 2GB
+# Set size of file to be uploaded.
 filesize = os.path.getsize(filename)
-if filesize > 2**31:
-    c.setopt(pycurl.INFILESIZE_LARGE, filesize)
-else:
-    c.setopt(pycurl.INFILESIZE, filesize)
+c.setopt(pycurl.INFILESIZE, filesize)
 
 # Start transfer
 print 'Uploading file %s to url %s' % (filename, url)
diff --git a/examples/retriever-multi.py b/examples/retriever-multi.py
index 549810e..488d0f7 100644
--- a/examples/retriever-multi.py
+++ b/examples/retriever-multi.py
@@ -1,15 +1,16 @@
 #! /usr/bin/env python
 # -*- coding: iso-8859-1 -*-
 # vi:ts=4:et
-# $Id: retriever-multi.py,v 1.23 2005/01/08 19:15:42 mfx Exp $
+# $Id: retriever-multi.py,v 1.25 2005/02/13 08:28:01 mfx Exp $
 
 #
 # Usage: python retriever-multi.py <file with URLs to fetch> [<# of
 #          concurrent connections>]
 #
 
-import string, sys
+import sys
 import pycurl
+
 # We should ignore SIGPIPE when using pycurl.NOSIGNAL - see
 # the libcurl tutorial for more info.
 try:
@@ -23,7 +24,10 @@ except ImportError:
 # Get args
 num_conn = 10
 try:
-    urls = open(sys.argv[1]).readlines()
+    if sys.argv[1] == "-":
+        urls = sys.stdin.readlines()
+    else:
+        urls = open(sys.argv[1]).readlines()
     if len(sys.argv) >= 3:
         num_conn = int(sys.argv[2])
 except:
@@ -33,15 +37,12 @@ except:
 
 # Make a queue with (url, filename) tuples
 queue = []
-fileno = 1
 for url in urls:
-    url = string.strip(url)
+    url = url.strip()
     if not url or url[0] == "#":
         continue
-    filename = "doc_%d" % (fileno)
+    filename = "doc_%03d.dat" % (len(queue) + 1)
     queue.append((url, filename))
-    fileno = fileno + 1
-del fileno, url, urls
 
 
 # Check args
@@ -53,13 +54,12 @@ print "PycURL %s (compiled against 0x%x)" % (pycurl.version, pycurl.COMPILE_LIBC
 print "----- Getting", num_urls, "URLs using", num_conn, "connections -----"
 
 
-# Preallocate a list of curl objects
+# Pre-allocate a list of curl objects
 m = pycurl.CurlMulti()
 m.handles = []
 for i in range(num_conn):
     c = pycurl.Curl()
     c.fp = None
-    c.setopt(pycurl.HTTPHEADER, ["User-Agent: PycURL"])
     c.setopt(pycurl.FOLLOWLOCATION, 1)
     c.setopt(pycurl.MAXREDIRS, 5)
     c.setopt(pycurl.CONNECTTIMEOUT, 30)
@@ -120,6 +120,3 @@ for c in m.handles:
     c.close()
 m.close()
 
-# Delete objects (just for testing the refcounts)
-del c, m, freelist, queue
-
diff --git a/examples/retriever.py b/examples/retriever.py
index 3d6990a..bd20da7 100644
--- a/examples/retriever.py
+++ b/examples/retriever.py
@@ -1,7 +1,12 @@
 #! /usr/bin/env python
 # -*- coding: iso-8859-1 -*-
 # vi:ts=4:et
-# $Id: retriever.py,v 1.15 2004/12/26 17:31:53 mfx Exp $
+# $Id: retriever.py,v 1.17 2005/02/13 08:28:01 mfx Exp $
+
+#
+# Usage: python retriever.py <file with URLs to fetch> [<# of
+#          concurrent connections>]
+#
 
 import sys, threading, Queue
 import pycurl
@@ -16,6 +21,39 @@ except ImportError:
     pass
 
 
+# Get args
+num_conn = 10
+try:
+    if sys.argv[1] == "-":
+        urls = sys.stdin.readlines()
+    else:
+        urls = open(sys.argv[1]).readlines()
+    if len(sys.argv) >= 3:
+        num_conn = int(sys.argv[2])
+except:
+    print "Usage: %s <file with URLs to fetch> [<# of concurrent connections>]" % sys.argv[0]
+    raise SystemExit
+
+
+# Make a queue with (url, filename) tuples
+queue = Queue.Queue()
+for url in urls:
+    url = url.strip()
+    if not url or url[0] == "#":
+        continue
+    filename = "doc_%03d.dat" % (len(queue.queue) + 1)
+    queue.put((url, filename))
+
+
+# Check args
+assert queue.queue, "no URLs given"
+num_urls = len(queue.queue)
+num_conn = min(num_conn, num_urls)
+assert 1 <= num_conn <= 10000, "invalid number of concurrent connections"
+print "PycURL %s (compiled against 0x%x)" % (pycurl.version, pycurl.COMPILE_LIBCURL_VERSION_NUM)
+print "----- Getting", num_urls, "URLs using", num_conn, "connections -----"
+
+
 class WorkerThread(threading.Thread):
     def __init__(self, queue):
         threading.Thread.__init__(self)
@@ -27,16 +65,15 @@ class WorkerThread(threading.Thread):
                 url, filename = self.queue.get_nowait()
             except Queue.Empty:
                 raise SystemExit
-            f = open(filename, "wb")
+            fp = open(filename, "wb")
             curl = pycurl.Curl()
-            curl.setopt(pycurl.HTTPHEADER, ["User-Agent: PycURL"])
+            curl.setopt(pycurl.URL, url)
             curl.setopt(pycurl.FOLLOWLOCATION, 1)
             curl.setopt(pycurl.MAXREDIRS, 5)
-            curl.setopt(pycurl.URL, url)
-            curl.setopt(pycurl.WRITEDATA, f)
-            curl.setopt(pycurl.NOSIGNAL, 1)
             curl.setopt(pycurl.CONNECTTIMEOUT, 30)
             curl.setopt(pycurl.TIMEOUT, 300)
+            curl.setopt(pycurl.NOSIGNAL, 1)
+            curl.setopt(pycurl.WRITEDATA, fp)
             try:
                 curl.perform()
             except:
@@ -44,36 +81,19 @@ class WorkerThread(threading.Thread):
                 traceback.print_exc(file=sys.stderr)
                 sys.stderr.flush()
             curl.close()
-            f.close()
+            fp.close()
             sys.stdout.write(".")
             sys.stdout.flush()
 
-# Read list of URLs from file specified on commandline
-try:
-    urls = open(sys.argv[1]).readlines()
-    num_workers = int(sys.argv[2])
-except:
-    # File or number of workers was not specified, show usage string
-    print "Usage: %s <file with URLs to fetch> <number of worker threads>" % sys.argv[0]
-    raise SystemExit
-
-# Initialize thread array and the file number used to store documents
-threads = []
-fileno = 0
-queue = Queue.Queue()
-
-# Fill the work input queue with URLs
-for url in urls:
-    fileno = fileno + 1
-    filename = "doc_%d" % (fileno,)
-    queue.put((url, filename))
 
 # Start a bunch of threads
-for num_threads in range(num_workers):
+threads = []
+for dummy in range(num_conn):
     t = WorkerThread(queue)
     t.start()
     threads.append(t)
 
+
 # Wait for all threads to finish
 for thread in threads:
     thread.join()
diff --git a/examples/xmlrpc_curl.py b/examples/xmlrpc_curl.py
index 640db0e..a175d23 100644
--- a/examples/xmlrpc_curl.py
+++ b/examples/xmlrpc_curl.py
@@ -1,7 +1,7 @@
 #! /usr/bin/env python
 # -*- coding: iso-8859-1 -*-
 # vi:ts=4:et
-# $Id: xmlrpc_curl.py,v 1.9 2004/12/26 17:31:53 mfx Exp $
+# $Id: xmlrpc_curl.py,v 1.10 2005/02/11 11:09:12 mfx Exp $
 
 # We should ignore SIGPIPE when using pycurl.NOSIGNAL - see
 # the libcurl tutorial for more info.
@@ -21,7 +21,7 @@ import xmlrpclib, pycurl
 class CURLTransport(xmlrpclib.Transport):
     """Handles a cURL HTTP transaction to an XML-RPC server."""
 
-    xmlrpc_h = [ "User-Agent: PycURL XML-RPC", "Content-Type: text/xml" ]
+    xmlrpc_h = [ "Content-Type: text/xml" ]
 
     def __init__(self, username=None, password=None):
         self.c = pycurl.Curl()
diff --git a/setup.py b/setup.py
index 9fe4054..a9799db 100644
--- a/setup.py
+++ b/setup.py
@@ -1,13 +1,13 @@
 #! /usr/bin/env python
 # -*- coding: iso-8859-1 -*-
 # vi:ts=4:et
-# $Id: setup.py,v 1.121 2005/02/04 01:38:20 mfx Exp $
+# $Id: setup.py,v 1.123 2005/02/17 10:13:23 mfx Exp $
 
 """Setup script for the PycURL module distribution."""
 
 PACKAGE = "pycurl"
 PY_PACKAGE = "curl"
-VERSION = "7.13.0"
+VERSION = "7.13.1"
 
 import glob, os, re, sys, string
 import distutils
@@ -63,7 +63,7 @@ if sys.platform == "win32":
     # Windows users have to configure the CURL_DIR path parameter to match
     # their cURL source installation.  The path set here is just an example
     # and thus unlikely to match your installation.
-    CURL_DIR = r"c:\src\build\pycurl\curl-7.12.3"
+    CURL_DIR = r"c:\src\build\pycurl\curl-7.13.1"
     CURL_DIR = scan_argv("--curl-dir=", CURL_DIR)
     print "Using curl directory:", CURL_DIR
     assert os.path.isdir(CURL_DIR), "please check CURL_DIR in setup.py"
diff --git a/setup_win32_ssl.py b/setup_win32_ssl.py
index 18e7e3a..b900874 100644
--- a/setup_win32_ssl.py
+++ b/setup_win32_ssl.py
@@ -1,13 +1,13 @@
 #! /usr/bin/env python
 # -*- coding: iso-8859-1 -*-
 # vi:ts=4:et
-# $Id: setup_win32_ssl.py,v 1.26 2005/02/04 01:38:20 mfx Exp $
+# $Id: setup_win32_ssl.py,v 1.27 2005/02/17 10:13:23 mfx Exp $
 
 import os, sys, string
 assert sys.platform == "win32", "Only for building on Win32 with SSL and zlib"
 
 
-CURL_DIR = r"c:\src\build\pycurl\curl-7.13.0-ssl"
+CURL_DIR = r"c:\src\build\pycurl\curl-7.13.1-ssl"
 OPENSSL_DIR = r"c:\src\build\pycurl\openssl-0.9.7e"
 sys.argv.insert(1, "--curl-dir=" + CURL_DIR)
 
diff --git a/src/pycurl.c b/src/pycurl.c
index 504e0d0..6f5f699 100644
--- a/src/pycurl.c
+++ b/src/pycurl.c
@@ -1,4 +1,4 @@
-/* $Id: pycurl.c,v 1.74 2005/02/10 10:17:15 kjetilja Exp $ */
+/* $Id: pycurl.c,v 1.86 2005/03/04 08:39:30 kjetilja Exp $ */
 
 /* PycURL -- cURL Python module
  *
@@ -48,8 +48,8 @@
 #if !defined(PY_VERSION_HEX) || (PY_VERSION_HEX < 0x02020000)
 #  error "Need Python version 2.2 or greater to compile pycurl."
 #endif
-#if !defined(LIBCURL_VERSION_NUM) || (LIBCURL_VERSION_NUM < 0x070d00)
-#  error "Need libcurl version 7.13.0 or greater to compile pycurl."
+#if !defined(LIBCURL_VERSION_NUM) || (LIBCURL_VERSION_NUM < 0x070d01)
+#  error "Need libcurl version 7.13.1 or greater to compile pycurl."
 #endif
 
 #undef UNUSED
@@ -345,15 +345,13 @@ util_curl_new(void)
 
 /* constructor - this is a module-level function returning a new instance */
 static CurlObject *
-do_curl_new(PyObject *dummy, PyObject *args)
+do_curl_new(PyObject *dummy)
 {
-    CurlObject *self;
+    CurlObject *self = NULL;
     int res;
+    char *s = NULL;
 
     UNUSED(dummy);
-    if (!PyArg_ParseTuple(args, ":Curl")) {
-        return NULL;
-    }
 
     /* Allocate python curl object */
     self = util_curl_new();
@@ -371,6 +369,11 @@ do_curl_new(PyObject *dummy, PyObject *args)
         goto error;
     memset(self->error, 0, sizeof(self->error));
 
+    /* Set backreference */
+    res = curl_easy_setopt(self->handle, CURLOPT_PRIVATE, (char *) self);
+    if (res != CURLE_OK)
+        goto error;
+
     /* Enable NOPROGRESS by default, i.e. no progress output */
     res = curl_easy_setopt(self->handle, CURLOPT_NOPROGRESS, (long)1);
     if (res != CURLE_OK)
@@ -381,16 +384,23 @@ do_curl_new(PyObject *dummy, PyObject *args)
     if (res != CURLE_OK)
         goto error;
 
-    /* Set backreference */
-    res = curl_easy_setopt(self->handle, CURLOPT_PRIVATE, (char *) self);
-    if (res != CURLE_OK)
-        goto error;
-
     /* Set FTP_ACCOUNT to NULL by default */
     res = curl_easy_setopt(self->handle, CURLOPT_FTP_ACCOUNT, NULL);
     if (res != CURLE_OK)
         goto error;
 
+    /* Set default USERAGENT */
+    s = (char *) malloc(7 + strlen(LIBCURL_VERSION) + 1);
+    if (s == NULL)
+        goto error;
+    strcpy(s, "PycURL/"); strcpy(s+7, LIBCURL_VERSION);
+    res = curl_easy_setopt(self->handle, CURLOPT_USERAGENT, (char *) s);
+    if (res != CURLE_OK) {
+        free(s);
+        goto error;
+    }
+    self->options[ OPT_INDEX(CURLOPT_USERAGENT) ] = s; s = NULL;
+
     /* Success - return new object */
     return self;
 
@@ -516,11 +526,8 @@ do_curl_dealloc(CurlObject *self)
 
 
 static PyObject *
-do_curl_close(CurlObject *self, PyObject *args)
+do_curl_close(CurlObject *self)
 {
-    if (!PyArg_ParseTuple(args, ":close")) {
-        return NULL;
-    }
     if (check_curl_state(self, 2, "close") != 0) {
         return NULL;
     }
@@ -531,11 +538,8 @@ do_curl_close(CurlObject *self, PyObject *args)
 
 
 static PyObject *
-do_curl_errstr(CurlObject *self, PyObject *args)
+do_curl_errstr(CurlObject *self)
 {
-    if (!PyArg_ParseTuple(args, ":errstr")) {
-        return NULL;
-    }
     if (check_curl_state(self, 1 | 2, "errstr") != 0) {
         return NULL;
     }
@@ -585,13 +589,10 @@ do_curl_traverse(CurlObject *self, visitproc visit, void *arg)
 /* --------------- perform --------------- */
 
 static PyObject *
-do_curl_perform(CurlObject *self, PyObject *args)
+do_curl_perform(CurlObject *self)
 {
     int res;
 
-    if (!PyArg_ParseTuple(args, ":perform")) {
-        return NULL;
-    }
     if (check_curl_state(self, 1 | 2, "perform") != 0) {
         return NULL;
     }
@@ -761,7 +762,22 @@ read_callback(char *ptr, size_t size, size_t nmemb, void *stream)
         memcpy(ptr, buf, obj_size);
         ret = obj_size;             /* success */
     }
+    else if (PyInt_Check(result)) {
+        long r = PyInt_AsLong(result);
+        if (r != CURL_READFUNC_ABORT) {
+            goto type_error;
+        }
+        /* ret is CURL_READUNC_ABORT */
+    }
+    else if (PyLong_Check(result)) {
+        long r = PyLong_AsLong(result);
+        if (r != CURL_READFUNC_ABORT) {
+            goto type_error;
+        }
+        /* ret is CURL_READUNC_ABORT */
+    }
     else {
+    type_error:
         PyErr_SetString(ErrorObject, "read callback must return string");
         goto verbose_error;
     }
@@ -891,7 +907,7 @@ ioctl_callback(CURL *curlobj, int cmd, void *stream)
     self = (CurlObject *)stream;
     tmp_state = get_thread_state(self);
     if (tmp_state == NULL)
-        return ret;
+        return (curlioerr) ret;
     PyEval_AcquireThread(tmp_state);
 
     /* check args */
@@ -922,7 +938,7 @@ ioctl_callback(CURL *curlobj, int cmd, void *stream)
 silent_error:
     Py_XDECREF(result);
     PyEval_ReleaseThread(tmp_state);
-    return ret;
+    return (curlioerr) ret;
 verbose_error:
     PyErr_Print();
     goto silent_error;
@@ -1159,7 +1175,7 @@ do_curl_setopt(CurlObject *self, PyObject *args)
         return Py_None;
     }
 
-    /* Handle the case of long arguments (used by *LARGE options) */
+    /* Handle the case of long arguments (used by *_LARGE options) */
     if (PyLong_Check(obj)) {
         PY_LONG_LONG d = PyLong_AsLongLong(obj);
         if (d == -1 && PyErr_Occurred())
@@ -1296,27 +1312,113 @@ do_curl_setopt(CurlObject *self, PyObject *args)
                 }
                 if (PyTuple_GET_SIZE(listitem) != 2) {
                     curl_formfree(post);
-                    PyErr_SetString(PyExc_TypeError, "tuple must contain two items (name and value)");
+                    PyErr_SetString(PyExc_TypeError, "tuple must contain two elements (name, value)");
                     return NULL;
                 }
-                /* FIXME: Only support strings as names and values for now */
-                if (PyString_AsStringAndSize(PyTuple_GET_ITEM(listitem, 0), &nstr, &nlen) != 0 ||
-                    PyString_AsStringAndSize(PyTuple_GET_ITEM(listitem, 1), &cstr, &clen) != 0) {
+                if (PyString_AsStringAndSize(PyTuple_GET_ITEM(listitem, 0), &nstr, &nlen) != 0) {
                     curl_formfree(post);
-                    PyErr_SetString(PyExc_TypeError, "tuple items must be strings");
+                    PyErr_SetString(PyExc_TypeError, "tuple must contain string as first element");
                     return NULL;
                 }
-                /* INFO: curl_formadd() internally does memdup() the data, so
-                 * embedded NUL characters _are_ allowed here. */
-                res = curl_formadd(&post, &last,
-                                   CURLFORM_COPYNAME, nstr,
-                                   CURLFORM_NAMELENGTH, (long) nlen,
-                                   CURLFORM_COPYCONTENTS, cstr,
-                                   CURLFORM_CONTENTSLENGTH, (long) clen,
-                                   CURLFORM_END);
-                if (res != CURLE_OK) {
+                if (PyString_Check(PyTuple_GET_ITEM(listitem, 1))) {
+                    /* Handle strings as second argument for backwards compatibility */
+                    PyString_AsStringAndSize(PyTuple_GET_ITEM(listitem, 1), &cstr, &clen);
+                    /* INFO: curl_formadd() internally does memdup() the data, so
+                     * embedded NUL characters _are_ allowed here. */
+                    res = curl_formadd(&post, &last,
+                                       CURLFORM_COPYNAME, nstr,
+                                       CURLFORM_NAMELENGTH, (long) nlen,
+                                       CURLFORM_COPYCONTENTS, cstr,
+                                       CURLFORM_CONTENTSLENGTH, (long) clen,
+                                       CURLFORM_END);
+                    if (res != CURLE_OK) {
+                        curl_formfree(post);
+                        CURLERROR_RETVAL();
+                    }
+                }
+                else if (PyTuple_Check(PyTuple_GET_ITEM(listitem, 1))) {
+                    /* Supports content, file and content-type */
+                    PyObject *t = PyTuple_GET_ITEM(listitem, 1);
+                    int tlen = PyTuple_Size(t);
+                    int j, k, l;
+                    struct curl_forms *forms = NULL;
+
+                    /* Sanity check that there are at least two tuple items */
+                    if (tlen < 2) {
+                        curl_formfree(post);
+                        PyErr_SetString(PyExc_TypeError, "tuple must contain at least one option and one value");
+                        return NULL;
+                    }
+
+                    /* Allocate enough space to accommodate length options for content */
+                    forms = PyMem_Malloc(sizeof(struct curl_forms) * ((tlen*2) + 1));
+                    if (forms == NULL) {
+                        curl_formfree(post);
+                        PyErr_NoMemory();
+                        return NULL;
+                    }
+
+                    /* Iterate all the tuple members pairwise */
+                    for (j = 0, k = 0, l = 0; j < tlen; j += 2, l++) {
+                        char *ostr;
+                        int olen, val;
+
+                        if (j == (tlen-1)) {
+                            PyErr_SetString(PyExc_TypeError, "expected value");
+                            PyMem_Free(forms);
+                            curl_formfree(post);
+                            return NULL;
+                        }
+                        if (!PyInt_Check(PyTuple_GET_ITEM(t, j))) {
+                            PyErr_SetString(PyExc_TypeError, "option must be long");
+                            PyMem_Free(forms);
+                            curl_formfree(post);
+                            return NULL;
+                        }
+                        if (!PyString_Check(PyTuple_GET_ITEM(t, j+1))) {
+                            PyErr_SetString(PyExc_TypeError, "value must be string");
+                            PyMem_Free(forms);
+                            curl_formfree(post);
+                            return NULL;
+                        }
+
+                        val = PyLong_AsLong(PyTuple_GET_ITEM(t, j));
+                        if (val != CURLFORM_COPYCONTENTS &&
+                            val != CURLFORM_FILE &&
+                            val != CURLFORM_CONTENTTYPE)
+                        {
+                            PyErr_SetString(PyExc_TypeError, "unsupported option");
+                            PyMem_Free(forms);
+                            curl_formfree(post);
+                            return NULL;
+                        }
+                        PyString_AsStringAndSize(PyTuple_GET_ITEM(t, j+1), &ostr, &olen);
+                        forms[k].option = val;
+                        forms[k].value = ostr;
+                        ++k;
+                        if (val == CURLFORM_COPYCONTENTS) {
+                            /* Contents can contain \0 bytes so we specify the length */
+                            forms[k].option = CURLFORM_CONTENTSLENGTH;
+                            forms[k].value = (char *)olen;
+                            ++k;
+                        }
+                    }
+                    forms[k].option = CURLFORM_END;
+                    res = curl_formadd(&post, &last,
+                                       CURLFORM_COPYNAME, nstr,
+                                       CURLFORM_NAMELENGTH, (long) nlen,
+                                       CURLFORM_ARRAY, forms,
+                                       CURLFORM_END);
+                    PyMem_Free(forms);
+                    if (res != CURLE_OK) {
+                        curl_formfree(post);
+                        CURLERROR_RETVAL();
+                    }
+                } else {
+                    /* Some other type was given, ignore */
                     curl_formfree(post);
-                    CURLERROR_RETVAL();
+                    PyErr_SetString(PyExc_TypeError, "unsupported second type in tuple");
+                    return NULL;
                 }
             }
             res = curl_easy_setopt(self->handle, CURLOPT_HTTPPOST, post);
@@ -1558,14 +1660,11 @@ do_curl_getinfo(CurlObject *self, PyObject *args)
 
 /* constructor - this is a module-level function returning a new instance */
 static CurlMultiObject *
-do_multi_new(PyObject *dummy, PyObject *args)
+do_multi_new(PyObject *dummy)
 {
     CurlMultiObject *self;
 
     UNUSED(dummy);
-    if (!PyArg_ParseTuple(args, ":CurlMulti")) {
-        return NULL;
-    }
 
     /* Allocate python curl-multi object */
     self = (CurlMultiObject *) PyObject_GC_New(CurlMultiObject, p_CurlMulti_Type);
@@ -1619,11 +1718,8 @@ do_multi_dealloc(CurlMultiObject *self)
 
 
 static PyObject *
-do_multi_close(CurlMultiObject *self, PyObject *args)
+do_multi_close(CurlMultiObject *self)
 {
-    if (!PyArg_ParseTuple(args, ":close")) {
-        return NULL;
-    }
     if (check_multi_state(self, 2, "close") != 0) {
         return NULL;
     }
@@ -1660,14 +1756,11 @@ do_multi_traverse(CurlMultiObject *self, visitproc visit, void *arg)
 
 
 static PyObject *
-do_multi_perform(CurlMultiObject *self, PyObject *args)
+do_multi_perform(CurlMultiObject *self)
 {
     CURLMcode res;
     int running = -1;
 
-    if (!PyArg_ParseTuple(args, ":perform")) {
-        return NULL;
-    }
     if (check_multi_state(self, 1 | 2, "perform") != 0) {
         return NULL;
     }
@@ -1788,7 +1881,7 @@ done:
 /* --------------- fdset ---------------------- */
 
 static PyObject *
-do_multi_fdset(CurlMultiObject *self, PyObject *args)
+do_multi_fdset(CurlMultiObject *self)
 {
     CURLMcode res;
     int max_fd = -1, fd;
@@ -1796,9 +1889,6 @@ do_multi_fdset(CurlMultiObject *self, PyObject *args)
     PyObject *read_list = NULL, *write_list = NULL, *except_list = NULL;
     PyObject *py_fd = NULL;
 
-    if (!PyArg_ParseTuple(args, ":fdset")) {
-        return NULL;
-    }
     if (check_multi_state(self, 1 | 2, "fdset") != 0) {
         return NULL;
     }
@@ -2002,10 +2092,10 @@ static char co_multi_info_read_doc [] = "info_read([max_objects]) -> Tuple. Retu
 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";
 
 static PyMethodDef curlobject_methods[] = {
-    {"close", (PyCFunction)do_curl_close, METH_VARARGS, co_close_doc},
-    {"errstr", (PyCFunction)do_curl_errstr, METH_VARARGS, co_errstr_doc},
+    {"close", (PyCFunction)do_curl_close, METH_NOARGS, co_close_doc},
+    {"errstr", (PyCFunction)do_curl_errstr, METH_NOARGS, co_errstr_doc},
     {"getinfo", (PyCFunction)do_curl_getinfo, METH_VARARGS, co_getinfo_doc},
-    {"perform", (PyCFunction)do_curl_perform, METH_VARARGS, co_perform_doc},
+    {"perform", (PyCFunction)do_curl_perform, METH_NOARGS, co_perform_doc},
     {"setopt", (PyCFunction)do_curl_setopt, METH_VARARGS, co_setopt_doc},
     {"unsetopt", (PyCFunction)do_curl_unsetopt, METH_VARARGS, co_unsetopt_doc},
     {NULL, NULL, 0, NULL}
@@ -2013,10 +2103,10 @@ static PyMethodDef curlobject_methods[] = {
 
 static PyMethodDef curlmultiobject_methods[] = {
     {"add_handle", (PyCFunction)do_multi_add_handle, METH_VARARGS, NULL},
-    {"close", (PyCFunction)do_multi_close, METH_VARARGS, NULL},
-    {"fdset", (PyCFunction)do_multi_fdset, METH_VARARGS, co_multi_fdset_doc},
+    {"close", (PyCFunction)do_multi_close, METH_NOARGS, NULL},
+    {"fdset", (PyCFunction)do_multi_fdset, METH_NOARGS, co_multi_fdset_doc},
     {"info_read", (PyCFunction)do_multi_info_read, METH_VARARGS, co_multi_info_read_doc},
-    {"perform", (PyCFunction)do_multi_perform, METH_VARARGS, NULL},
+    {"perform", (PyCFunction)do_multi_perform, METH_NOARGS, NULL},
     {"remove_handle", (PyCFunction)do_multi_remove_handle, METH_VARARGS, NULL},
     {"select", (PyCFunction)do_multi_select, METH_VARARGS, co_multi_select_doc},
     {NULL, NULL, 0, NULL}
@@ -2194,13 +2284,9 @@ do_global_init(PyObject *dummy, PyObject *args)
 
 
 static PyObject *
-do_global_cleanup(PyObject *dummy, PyObject *args)
+do_global_cleanup(PyObject *dummy)
 {
     UNUSED(dummy);
-    if (!PyArg_ParseTuple(args, ":global_cleanup")) {
-        return NULL;
-    }
-
     curl_global_cleanup();
     Py_INCREF(Py_None);
     return Py_None;
@@ -2301,10 +2387,10 @@ static char pycurl_multi_new_doc [] =
 /* List of functions defined in this module */
 static PyMethodDef curl_methods[] = {
     {"global_init", (PyCFunction)do_global_init, METH_VARARGS, pycurl_global_init_doc},
-    {"global_cleanup", (PyCFunction)do_global_cleanup, METH_VARARGS, pycurl_global_cleanup_doc},
+    {"global_cleanup", (PyCFunction)do_global_cleanup, METH_NOARGS, pycurl_global_cleanup_doc},
     {"version_info", (PyCFunction)do_version_info, METH_VARARGS, pycurl_version_info_doc},
-    {"Curl", (PyCFunction)do_curl_new, METH_VARARGS, pycurl_curl_new_doc},
-    {"CurlMulti", (PyCFunction)do_multi_new, METH_VARARGS, pycurl_multi_new_doc},
+    {"Curl", (PyCFunction)do_curl_new, METH_NOARGS, pycurl_curl_new_doc},
+    {"CurlMulti", (PyCFunction)do_multi_new, METH_NOARGS, pycurl_multi_new_doc},
     {NULL, NULL, 0, NULL}
 };
 
@@ -2437,6 +2523,14 @@ initpycurl(void)
      ** the order of these constants mostly follows <curl/curl.h>
      **/
 
+    /* Abort curl_read_callback(). */
+    insint_c(d, "READFUNC_ABORT", CURL_READFUNC_ABORT);
+
+    /* constants for ioctl callback return values */
+    insint_c(d, "IOE_OK", CURLIOE_OK);
+    insint_c(d, "IOE_UNKNOWNCMD", CURLIOE_UNKNOWNCMD);
+    insint_c(d, "IOE_FAILRESTART", CURLIOE_FAILRESTART);
+
     /* curl_infotype: the kind of data that is passed to information_callback */
 /* XXX do we actually need curl_infotype in pycurl ??? */
     insint_c(d, "INFOTYPE_TEXT", CURLINFO_TEXT);
@@ -2477,17 +2571,35 @@ initpycurl(void)
     insint_c(d, "FTPAUTH_SSL", CURLFTPAUTH_SSL);
     insint_c(d, "FTPAUTH_TLS", CURLFTPAUTH_TLS);
 
+    /* curl_ftpauth: constants for setopt(FTPSSLAUTH, x) */
+    insint_c(d, "FORM_CONTENTS", CURLFORM_COPYCONTENTS);
+    insint_c(d, "FORM_FILE", CURLFORM_FILE);
+    insint_c(d, "FORM_CONTENTTYPE", CURLFORM_CONTENTTYPE);
+
     /* CURLoption: symbolic constants for setopt() */
 /* FIXME: reorder these to match <curl/curl.h> */
     insint_c(d, "FILE", CURLOPT_WRITEDATA);
+    insint_c(d, "URL", CURLOPT_URL);
+    insint_c(d, "PORT", CURLOPT_PORT);
+    insint_c(d, "PROXY", CURLOPT_PROXY);
+    insint_c(d, "USERPWD", CURLOPT_USERPWD);
+    insint_c(d, "PROXYUSERPWD", CURLOPT_PROXYUSERPWD);
+    insint_c(d, "RANGE", CURLOPT_RANGE);
     insint_c(d, "INFILE", CURLOPT_READDATA);
-    insint_c(d, "WRITEDATA", CURLOPT_WRITEDATA);
+    /* ERRORBUFFER is not supported */
     insint_c(d, "WRITEFUNCTION", CURLOPT_WRITEFUNCTION);
-    insint_c(d, "READDATA", CURLOPT_READDATA);
     insint_c(d, "READFUNCTION", CURLOPT_READFUNCTION);
-    insint_c(d, "INFILESIZE", CURLOPT_INFILESIZE);
-    insint_c(d, "URL", CURLOPT_URL);
-    insint_c(d, "PROXY", CURLOPT_PROXY);
+    insint_c(d, "TIMEOUT", CURLOPT_TIMEOUT);
+    insint_c(d, "INFILESIZE", CURLOPT_INFILESIZE_LARGE);    /* _LARGE ! */
+    insint_c(d, "POSTFIELDS", CURLOPT_POSTFIELDS);
+    insint_c(d, "REFERER", CURLOPT_REFERER);
+    insint_c(d, "FTPPORT", CURLOPT_FTPPORT);
+    insint_c(d, "USERAGENT", CURLOPT_USERAGENT);
+    insint_c(d, "LOW_SPEED_LIMIT", CURLOPT_LOW_SPEED_LIMIT);
+    insint_c(d, "LOW_SPEED_TIME", CURLOPT_LOW_SPEED_TIME);
+    insint_c(d, "RESUME_FROM", CURLOPT_RESUME_FROM_LARGE);  /* _LARGE ! */
+    insint_c(d, "WRITEDATA", CURLOPT_WRITEDATA);
+    insint_c(d, "READDATA", CURLOPT_READDATA);
     insint_c(d, "PROXYPORT", CURLOPT_PROXYPORT);
     insint_c(d, "HTTPPROXYTUNNEL", CURLOPT_HTTPPROXYTUNNEL);
     insint_c(d, "VERBOSE", CURLOPT_VERBOSE);
@@ -2503,18 +2615,7 @@ initpycurl(void)
     insint_c(d, "FOLLOWLOCATION", CURLOPT_FOLLOWLOCATION);
     insint_c(d, "TRANSFERTEXT", CURLOPT_TRANSFERTEXT);
     insint_c(d, "PUT", CURLOPT_PUT);
-    insint_c(d, "USERPWD", CURLOPT_USERPWD);
-    insint_c(d, "PROXYUSERPWD", CURLOPT_PROXYUSERPWD);
-    insint_c(d, "RANGE", CURLOPT_RANGE);
-    insint_c(d, "TIMEOUT", CURLOPT_TIMEOUT);
-    insint_c(d, "POSTFIELDS", CURLOPT_POSTFIELDS);
-    insint_c(d, "POSTFIELDSIZE", CURLOPT_POSTFIELDSIZE);
-    insint_c(d, "REFERER", CURLOPT_REFERER);
-    insint_c(d, "USERAGENT", CURLOPT_USERAGENT);
-    insint_c(d, "FTPPORT", CURLOPT_FTPPORT);
-    insint_c(d, "LOW_SPEED_LIMIT", CURLOPT_LOW_SPEED_LIMIT);
-    insint_c(d, "LOW_SPEED_TIME", CURLOPT_LOW_SPEED_TIME);
-    insint_c(d, "CURLOPT_RESUME_FROM", CURLOPT_RESUME_FROM);
+    insint_c(d, "POSTFIELDSIZE", CURLOPT_POSTFIELDSIZE_LARGE);  /* _LARGE ! */
     insint_c(d, "COOKIE", CURLOPT_COOKIE);
     insint_c(d, "HTTPHEADER", CURLOPT_HTTPHEADER);
     insint_c(d, "HTTPPOST", CURLOPT_HTTPPOST);
@@ -2575,7 +2676,7 @@ initpycurl(void)
     insint_c(d, "PROXYAUTH", CURLOPT_PROXYAUTH);
     insint_c(d, "FTP_RESPONSE_TIMEOUT", CURLOPT_FTP_RESPONSE_TIMEOUT);
     insint_c(d, "IPRESOLVE", CURLOPT_IPRESOLVE);
-    insint_c(d, "MAXFILESIZE", CURLOPT_MAXFILESIZE);
+    insint_c(d, "MAXFILESIZE", CURLOPT_MAXFILESIZE_LARGE);  /* _LARGE ! */
     insint_c(d, "INFILESIZE_LARGE", CURLOPT_INFILESIZE_LARGE);
     insint_c(d, "RESUME_FROM_LARGE", CURLOPT_RESUME_FROM_LARGE);
     insint_c(d, "MAXFILESIZE_LARGE", CURLOPT_MAXFILESIZE_LARGE);
@@ -2587,16 +2688,11 @@ initpycurl(void)
     insint_c(d, "SOURCE_PREQUOTE", CURLOPT_SOURCE_PREQUOTE);
     insint_c(d, "SOURCE_POSTQUOTE", CURLOPT_SOURCE_POSTQUOTE);
     insint_c(d, "FTPSSLAUTH", CURLOPT_FTPSSLAUTH);
-    insint_c(d, "FTP_ACCOUNT", CURLOPT_FTP_ACCOUNT);
-    insint_c(d, "SOURCE_URL", CURLOPT_SOURCE_URL);
-    insint_c(d, "SOURCE_QUOTE", CURLOPT_SOURCE_QUOTE);
     insint_c(d, "IOCTLFUNCTION", CURLOPT_IOCTLFUNCTION);
     insint_c(d, "IOCTLDATA", CURLOPT_IOCTLDATA);
-
-    /* constants for ioctl callback return values */
-    insint_c(d, "IOE_OK", CURLIOE_OK);
-    insint_c(d, "IOE_UNKNOWNCMD", CURLIOE_UNKNOWNCMD);
-    insint_c(d, "IOE_FAILRESTART", CURLIOE_FAILRESTART);
+    insint_c(d, "SOURCE_URL", CURLOPT_SOURCE_URL);
+    insint_c(d, "SOURCE_QUOTE", CURLOPT_SOURCE_QUOTE);
+    insint_c(d, "FTP_ACCOUNT", CURLOPT_FTP_ACCOUNT);
 
     /* constants for setopt(IPRESOLVE, x) */
     insint_c(d, "IPRESOLVE_WHATEVER", CURL_IPRESOLVE_WHATEVER);
diff --git a/tests/test_post2.py b/tests/test_post2.py
index b4fd9b0..fd1395a 100644
--- a/tests/test_post2.py
+++ b/tests/test_post2.py
@@ -1,12 +1,14 @@
 #! /usr/bin/env python
 # -*- coding: iso-8859-1 -*-
 # vi:ts=4:et
-# $Id: test_post2.py,v 1.12 2004/04/30 15:12:28 kjetilja Exp $
+# $Id: test_post2.py,v 1.13 2005/03/03 10:00:40 kjetilja Exp $
 
 import pycurl
 
-
-pf = [('field1', 'this is a test using httppost & stuff'), ('field2', 'value2')]
+pf = [('field1', 'this is a test using httppost & stuff'),
+      ('field2', (pycurl.FORM_FILE, 'test_post.py', pycurl.FORM_FILE, 'test_post2.py')),
+      ('field3', (pycurl.FORM_CONTENTS, 'this is wei\000rd, but null-bytes are okay'))
+     ]
 
 c = pycurl.Curl()
 c.setopt(c.URL, 'http://www.contactor.se/~dast/postit.cgi')

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/pycurl.git



More information about the Python-modules-commits mailing list