python-pycurl: Import fixes from upstream.

Also fix the library requirement, which makes
sure that a recent enough version of libcurl is
available.
This commit is contained in:
Michael Tremer 2013-03-01 12:19:32 +00:00
parent 91d1c8a920
commit 883c26f392
10 changed files with 619 additions and 45 deletions

View File

@ -0,0 +1,200 @@
From 05433632fb1ccdabc1d29d78f32bc35de0a8638b Mon Sep 17 00:00:00 2001
From: kjetilja <kjetilja>
Date: Mon, 29 Sep 2008 10:56:57 +0000
Subject: [PATCH 1/5] No longer keep copies of string options since this is managed by libcurl
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
ChangeLog | 12 +++++++++-
src/pycurl.c | 60 +--------------------------------------------------------
2 files changed, 12 insertions(+), 60 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 0fb7f8c..618654d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,15 @@
-Version 7.19.0 [requires libcurl-7.19.0 or better]
+Version 7.19.1 [requires libcurl-7.19.0 or better]
--------------
- * Added CURLFILE, ADDRESS_SCOPE and ISSUERCERT options,
+ * No longer keep string options copies in the
+ Curl Python objects, since string options are
+ now managed by libcurl.
+
+
+Version 7.19.0
+--------------
+
+ * Added CURLFILE, ADDRESS_SCOPE and ISSUERCERT options,
as well as the APPCONNECT_TIME info.
* Added PRIMARY_IP info (patch by
diff --git a/src/pycurl.c b/src/pycurl.c
index a17a23b..6de1514 100644
--- a/src/pycurl.c
+++ b/src/pycurl.c
@@ -1,4 +1,4 @@
-/* $Id: pycurl.c,v 1.147 2008/09/09 17:40:34 kjetilja Exp $ */
+/* $Id: pycurl.c,v 1.148 2008/09/29 10:56:57 kjetilja Exp $ */
/* PycURL -- cURL Python module
*
@@ -97,12 +97,6 @@ static void pycurl_ssl_cleanup(void);
/* Calculate the number of OBJECTPOINT options we need to store */
#define OPTIONS_SIZE ((int)CURLOPT_LASTENTRY % 10000)
#define MOPTIONS_SIZE ((int)CURLMOPT_LASTENTRY % 10000)
-static int OPT_INDEX(int o)
-{
- assert(o >= CURLOPTTYPE_OBJECTPOINT);
- assert(o < CURLOPTTYPE_OBJECTPOINT + OPTIONS_SIZE);
- return o - CURLOPTTYPE_OBJECTPOINT;
-}
/* Type objects */
static PyObject *ErrorObject = NULL;
@@ -161,7 +155,6 @@ typedef struct {
PyObject *writedata_fp;
PyObject *writeheader_fp;
/* misc */
- void *options[OPTIONS_SIZE]; /* for OBJECTPOINT options */
char error[CURL_ERROR_SIZE+1];
} CurlObject;
@@ -741,7 +734,6 @@ util_curl_new(void)
self->writeheader_fp = NULL;
/* Zero string pointer memory buffer used by setopt */
- memset(self->options, 0, sizeof(self->options));
memset(self->error, 0, sizeof(self->error));
return self;
@@ -804,7 +796,6 @@ do_curl_new(PyObject *dummy)
free(s);
goto error;
}
- self->options[ OPT_INDEX(CURLOPT_USERAGENT) ] = s; s = NULL;
/* Success - return new object */
return self;
@@ -872,7 +863,6 @@ static void
util_curl_close(CurlObject *self)
{
CURL *handle;
- int i;
/* Zero handle and thread-state to disallow any operations to be run
* from now on */
@@ -916,16 +906,6 @@ util_curl_close(CurlObject *self)
SFREE(self->postquote);
SFREE(self->prequote);
#undef SFREE
-
- /* Last, free the options. This must be done after the curl handle
- * is closed since libcurl assumes that some options are valid when
- * invoking curl_easy_cleanup(). */
- for (i = 0; i < OPTIONS_SIZE; i++) {
- if (self->options[i] != NULL) {
- free(self->options[i]);
- self->options[i] = NULL;
- }
- }
}
@@ -1424,8 +1404,6 @@ verbose_error:
static PyObject*
do_curl_reset(CurlObject *self)
{
- unsigned int i;
-
curl_easy_reset(self->handle);
/* Decref callbacks and file handles */
@@ -1443,15 +1421,6 @@ do_curl_reset(CurlObject *self)
SFREE(self->postquote);
SFREE(self->prequote);
#undef SFREE
-
- /* Last, free the options */
- for (i = 0; i < OPTIONS_SIZE; i++) {
- if (self->options[i] != NULL) {
- free(self->options[i]);
- self->options[i] = NULL;
- }
- }
-
return Py_None;
}
@@ -1461,7 +1430,6 @@ static PyObject *
util_curl_unsetopt(CurlObject *self, int option)
{
int res;
- int opt_index = -1;
#define SETOPT2(o,x) \
if ((res = curl_easy_setopt(self->handle, (o), (x))) != CURLE_OK) goto error
@@ -1502,7 +1470,6 @@ util_curl_unsetopt(CurlObject *self, int option)
case CURLOPT_SSL_CIPHER_LIST:
case CURLOPT_USERPWD:
SETOPT((char *) 0);
- opt_index = OPT_INDEX(option);
break;
/* info: we explicitly list unsupported options here */
@@ -1512,11 +1479,6 @@ util_curl_unsetopt(CurlObject *self, int option)
return NULL;
}
- if (opt_index >= 0 && self->options[opt_index] != NULL) {
- free(self->options[opt_index]);
- self->options[opt_index] = NULL;
- }
-
Py_INCREF(Py_None);
return Py_None;
@@ -1587,8 +1549,6 @@ do_curl_setopt(CurlObject *self, PyObject *args)
if (PyString_Check(obj)) {
char *str = NULL;
Py_ssize_t len = -1;
- char *buf;
- int opt_index;
/* Check that the option specified a string as well as the input */
switch (option) {
@@ -1651,28 +1611,12 @@ do_curl_setopt(CurlObject *self, PyObject *args)
}
/* Allocate memory to hold the string */
assert(str != NULL);
- if (len <= 0)
- buf = strdup(str);
- else {
- buf = (char *) malloc(len);
- if (buf) memcpy(buf, str, len);
- }
- if (buf == NULL)
- return PyErr_NoMemory();
/* Call setopt */
- res = curl_easy_setopt(self->handle, (CURLoption)option, buf);
+ res = curl_easy_setopt(self->handle, (CURLoption)option, str);
/* Check for errors */
if (res != CURLE_OK) {
- free(buf);
CURLERROR_RETVAL();
}
- /* Save allocated option buffer */
- opt_index = OPT_INDEX(option);
- if (self->options[opt_index] != NULL) {
- free(self->options[opt_index]);
- self->options[opt_index] = NULL;
- }
- self->options[opt_index] = buf;
Py_INCREF(Py_None);
return Py_None;
}
--
1.7.1

View File

@ -0,0 +1,61 @@
From 009e170d2838346461ff0b31b0afa44f3d6278f3 Mon Sep 17 00:00:00 2001
From: zanee <zanee>
Date: Fri, 23 Apr 2010 16:06:41 +0000
Subject: [PATCH 2/5] Fixes https://sourceforge.net/tracker/?func=detail&aid=2812016&group_id=28236&atid=392777 with applied patch from sourceforge user dbprice1.
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
setup.py | 23 ++++++++++++++++++-----
1 files changed, 18 insertions(+), 5 deletions(-)
diff --git a/setup.py b/setup.py
index 0ffd9d2..76b9d58 100644
--- a/setup.py
+++ b/setup.py
@@ -1,7 +1,7 @@
#! /usr/bin/env python
# -*- coding: iso-8859-1 -*-
# vi:ts=4:et
-# $Id: setup.py,v 1.150 2008/09/09 17:40:34 kjetilja Exp $
+# $Id: setup.py,v 1.151 2010/04/23 16:06:41 zanee Exp $
"""Setup script for the PycURL module distribution."""
@@ -9,7 +9,7 @@ PACKAGE = "pycurl"
PY_PACKAGE = "curl"
VERSION = "7.19.0"
-import glob, os, re, sys, string
+import glob, os, re, sys, string, subprocess
import distutils
from distutils.core import setup
from distutils.extension import Extension
@@ -96,9 +96,22 @@ else:
include_dirs.append(e[2:])
else:
extra_compile_args.append(e)
- libs = split_quoted(
- os.popen("'%s' --libs" % CURL_CONFIG).read()+\
- os.popen("'%s' --static-libs" % CURL_CONFIG).read())
+
+ # Run curl-config --libs and --static-libs. Some platforms may not
+ # support one or the other of these curl-config options, so gracefully
+ # tolerate failure of either, but not both.
+ optbuf = ""
+ for option in ["--libs", "--static-libs"]:
+ p = subprocess.Popen("'%s' %s" % (CURL_CONFIG, option), shell=True,
+ stdout=subprocess.PIPE)
+ (stdout, stderr) = p.communicate()
+ if p.wait() == 0:
+ optbuf += stdout
+ if optbuf == "":
+ raise Exception, ("Neither of curl-config --libs or --static-libs" +
+ "produced output")
+ libs = split_quoted(optbuf)
+
for e in libs:
if e[:2] == "-l":
libraries.append(e[2:])
--
1.7.1

View File

@ -0,0 +1,160 @@
From 4a377e2d60fb903e91a370595a6ea22cb7ee0e0e Mon Sep 17 00:00:00 2001
From: zanee <zanee>
Date: Wed, 28 Apr 2010 16:02:41 +0000
Subject: [PATCH 3/5 v2] Fixes refcount bug and provides better organization of PyCurl object. Submitted by dbprice1.
https://sourceforge.net/tracker/?func=detail&aid=2893665&group_id=28236&atid=392777
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
src/pycurl.c | 88 +++++++++++++++++++++++++++++++++++++--------------------
1 files changed, 57 insertions(+), 31 deletions(-)
diff --git a/src/pycurl.c b/src/pycurl.c
index 6de1514..32c7ca5 100644
--- a/src/pycurl.c
+++ b/src/pycurl.c
@@ -1,4 +1,4 @@
-/* $Id: pycurl.c,v 1.148 2008/09/29 10:56:57 kjetilja Exp $ */
+/* $Id: pycurl.c,v 1.149 2010/04/28 16:02:41 zanee Exp $ */
/* PycURL -- cURL Python module
*
@@ -739,64 +739,80 @@ util_curl_new(void)
return self;
}
-
-/* constructor - this is a module-level function returning a new instance */
-static CurlObject *
-do_curl_new(PyObject *dummy)
+/* initializer - used to intialize curl easy handles for use with pycurl */
+static int
+util_curl_init(CurlObject *self)
{
- CurlObject *self = NULL;
int res;
char *s = NULL;
- UNUSED(dummy);
-
- /* Allocate python curl object */
- self = util_curl_new();
- if (self == NULL)
- return NULL;
-
- /* Initialize curl handle */
- self->handle = curl_easy_init();
- if (self->handle == NULL)
- goto error;
-
/* Set curl error buffer and zero it */
res = curl_easy_setopt(self->handle, CURLOPT_ERRORBUFFER, self->error);
- if (res != CURLE_OK)
- goto error;
+ if (res != CURLE_OK) {
+ return (-1);
+ }
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;
+ if (res != CURLE_OK) {
+ return (-1);
+ }
/* Enable NOPROGRESS by default, i.e. no progress output */
res = curl_easy_setopt(self->handle, CURLOPT_NOPROGRESS, (long)1);
- if (res != CURLE_OK)
- goto error;
+ if (res != CURLE_OK) {
+ return (-1);
+ }
/* Disable VERBOSE by default, i.e. no verbose output */
res = curl_easy_setopt(self->handle, CURLOPT_VERBOSE, (long)0);
- if (res != CURLE_OK)
- goto error;
+ if (res != CURLE_OK) {
+ return (-1);
+ }
/* Set FTP_ACCOUNT to NULL by default */
res = curl_easy_setopt(self->handle, CURLOPT_FTP_ACCOUNT, NULL);
- if (res != CURLE_OK)
- goto error;
+ if (res != CURLE_OK) {
+ return (-1);
+ }
/* Set default USERAGENT */
s = (char *) malloc(7 + strlen(LIBCURL_VERSION) + 1);
- if (s == NULL)
- goto error;
+ if (s == NULL) {
+ return (-1);
+ }
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;
+ return (-1);
}
+ return (0);
+}
+
+/* constructor - this is a module-level function returning a new instance */
+static CurlObject *
+do_curl_new(PyObject *dummy)
+{
+ CurlObject *self = NULL;
+ int res;
+
+ UNUSED(dummy);
+
+ /* Allocate python curl object */
+ self = util_curl_new();
+ if (self == NULL)
+ return NULL;
+
+ /* Initialize curl handle */
+ self->handle = curl_easy_init();
+ if (self->handle == NULL)
+ goto error;
+ res = util_curl_init(self);
+ if (res < 0)
+ goto error;
/* Success - return new object */
return self;
@@ -1404,6 +1420,8 @@ verbose_error:
static PyObject*
do_curl_reset(CurlObject *self)
{
+ int res;
+
curl_easy_reset(self->handle);
/* Decref callbacks and file handles */
@@ -1421,6 +1439,14 @@ do_curl_reset(CurlObject *self)
SFREE(self->postquote);
SFREE(self->prequote);
#undef SFREE
+ res = util_curl_init(self);
+ if (res < 0) {
+ Py_DECREF(self); /* this also closes self->handle */
+ PyErr_SetString(ErrorObject, "resetting curl failed");
+ return NULL;
+ }
+
+ Py_INCREF(Py_None);
return Py_None;
}
--
1.7.1

View File

@ -0,0 +1,94 @@
From 206c15ea32e05ae98827d00626a101e33a7bec70 Mon Sep 17 00:00:00 2001
From: zanee <zanee>
Date: Wed, 28 Apr 2010 16:03:40 +0000
Subject: [PATCH 4/5] Test for reset fixes refcount bug
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
tests/test_reset.py | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 74 insertions(+), 0 deletions(-)
create mode 100644 tests/test_reset.py
diff --git a/tests/test_reset.py b/tests/test_reset.py
new file mode 100644
index 0000000..c350d17
--- /dev/null
+++ b/tests/test_reset.py
@@ -0,0 +1,74 @@
+#!/usr/bin/python
+
+import sys
+import pycurl
+
+saw_error = 1
+
+def main():
+ global saw_error
+
+ pycurl.global_init(pycurl.GLOBAL_DEFAULT)
+
+ outf = file("/dev/null", "rb+")
+ cm = pycurl.CurlMulti()
+
+ # Set multi handle's options
+ cm.setopt(pycurl.M_PIPELINING, 1)
+
+ eh = pycurl.Curl()
+
+ for x in range(1, 20):
+
+ eh.setopt(pycurl.WRITEDATA, outf)
+ eh.setopt(pycurl.URL, sys.argv[1])
+ cm.add_handle(eh)
+
+ while 1:
+ ret, active_handles = cm.perform()
+ if ret != pycurl.E_CALL_MULTI_PERFORM:
+ break
+
+ while active_handles:
+ ret = cm.select(1.0)
+ if ret == -1:
+ continue
+ while 1:
+ ret, active_handles = cm.perform()
+ if ret != pycurl.E_CALL_MULTI_PERFORM:
+ break
+
+ count, good, bad = cm.info_read()
+
+ for h, en, em in bad:
+ print "Transfer to %s failed with %d, %s\n" % \
+ (h.getinfo(pycurl.EFFECTIVE_URL), en, em)
+ raise RuntimeError
+
+ for h in good:
+ httpcode = h.getinfo(pycurl.RESPONSE_CODE)
+ if httpcode != 200:
+ print "Transfer to %s failed with code %d\n" %\
+ (h.getinfo(pycurl.EFFECTIVE_URL), httpcode)
+ raise RuntimeError
+
+ else:
+ print "Recd %d bytes from %s" % \
+ (h.getinfo(pycurl.SIZE_DOWNLOAD),
+ h.getinfo(pycurl.EFFECTIVE_URL))
+
+ cm.remove_handle(eh)
+ eh.reset()
+
+ eh.close()
+ cm.close()
+ outf.close()
+
+ pycurl.global_cleanup()
+
+
+if __name__ == '__main__':
+ if len(sys.argv) != 2:
+ print "Usage: %s <url>" % sys.argv[0]
+ sys.exit(2)
+ main()
--
1.7.1

View File

@ -0,0 +1,32 @@
From d075bfb8a5207f933a5a704becd7f64e8521dc28 Mon Sep 17 00:00:00 2001
From: zanee <zanee>
Date: Tue, 4 May 2010 18:47:08 +0000
Subject: [PATCH 5/5] Updating ChangeLog with relevant changes
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
ChangeLog | 11 +++++++++++
1 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 618654d..885c8b0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+Version 7.19.2
+--------------
+
+ * Cleaned up website
+
+ * Fix pycurl.reset() (patch by <johansen at sun.com>).
+
+ * Fix install routine in setup.py where
+ certain platforms (Solaris, Mac OSX, etc)
+ would search for a static copy of libcurl (dbp)
+
Version 7.19.1 [requires libcurl-7.19.0 or better]
--------------
--
1.7.1

View File

@ -0,0 +1,34 @@
From 0796c0530648ae0e741a20a78d1fcf315783c178 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Mon, 25 Feb 2013 19:48:22 +0100
Subject: [PATCH 1/2] setup.py: do not use curl-config --static-libs
---
setup.py | 5 ++---
1 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/setup.py b/setup.py
index 76b9d58..86a2951 100644
--- a/setup.py
+++ b/setup.py
@@ -101,15 +101,14 @@ else:
# support one or the other of these curl-config options, so gracefully
# tolerate failure of either, but not both.
optbuf = ""
- for option in ["--libs", "--static-libs"]:
+ for option in ["--libs"]:
p = subprocess.Popen("'%s' %s" % (CURL_CONFIG, option), shell=True,
stdout=subprocess.PIPE)
(stdout, stderr) = p.communicate()
if p.wait() == 0:
optbuf += stdout
if optbuf == "":
- raise Exception, ("Neither of curl-config --libs or --static-libs" +
- "produced output")
+ raise Exception, ("curl-config --libs did not produce output")
libs = split_quoted(optbuf)
for e in libs:
--
1.7.1

View File

@ -0,0 +1,28 @@
From 0bd83ea6c820db26f98936e6e017d39fb214cbd0 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Mon, 25 Feb 2013 19:50:18 +0100
Subject: [PATCH 2/2] test_internals.py: add a test for ref-counting of reset()
---
tests/test_internals.py | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/tests/test_internals.py b/tests/test_internals.py
index afcc53d..d026952 100644
--- a/tests/test_internals.py
+++ b/tests/test_internals.py
@@ -245,6 +245,11 @@ if 1 and gc:
if opts.verbose >= 1:
print "Tracked objects:", len(gc.get_objects())
+if 1:
+ # Ensure that the refcounting error in "reset" is fixed:
+ for i in xrange(100000):
+ c = Curl()
+ c.reset()
# /***********************************************************************
# // done
--
1.7.1

View File

@ -1,24 +0,0 @@
--- a/src/pycurl.c
+++ a/src/pycurl.c
@@ -1452,6 +1452,7 @@ do_curl_reset(CurlObject *self)
}
}
+ Py_INCREF(Py_None);
return Py_None;
}
--- a/tests/test_internals.py
+++ a/tests/test_internals.py
@@ -245,6 +245,11 @@ if 1 and gc:
if opts.verbose >= 1:
print "Tracked objects:", len(gc.get_objects())
+if 1:
+ # Ensure that the refcounting error in "reset" is fixed:
+ for i in xrange(100000):
+ c = Curl()
+ c.reset()
# /***********************************************************************
# // done

View File

@ -1,12 +0,0 @@
--- setup.py~ 2008-04-22 17:00:45.000000000 +0300
+++ setup.py 2008-07-03 21:53:36.000000000 +0300
@@ -97,8 +97,7 @@
else:
extra_compile_args.append(e)
libs = split_quoted(
- os.popen("'%s' --libs" % CURL_CONFIG).read()+\
- os.popen("'%s' --static-libs" % CURL_CONFIG).read())
+ os.popen("'%s' --libs" % CURL_CONFIG).read())
for e in libs:
if e[:2] == "-l":
libraries.append(e[2:])

View File

@ -5,7 +5,7 @@
name = python-pycurl
version = 7.19.0
release = 4
release = 5
thisapp = pycurl-%{version}
groups = Development/Languages
@ -13,14 +13,6 @@ url = http://pycurl.sourceforge.net/
license = LGPLv2+ or MIT
summary = A Python interface to libcurl.
# During its initialization, PycURL checks that the actual libcurl version
# is not lower than the one used when PycURL was built.
# Yes, that should be handled by library versioning (which would then get
# automatically reflected).
# For now, we have to reflect that dependency.
LIBCURL_VERSION = $(shell curl-config --version | awk '{ print $NF }')
PKG_DEPS += libcurl>=%{LIBCURL_VERSION}
description
PycURL is a Python interface to libcurl. PycURL can be used to fetch
objects identified by a URL from a Python program, similar to the
@ -56,6 +48,15 @@ end
packages
package %{name}
# During its initialization, PycURL checks that the actual libcurl version
# is not lower than the one used when PycURL was built.
# Yes, that should be handled by library versioning (which would then get
# automatically reflected).
# For now, we have to reflect that dependency.
requires
libcurl >= %(curl-config --version | awk '{ print $NF }')
end
end
package %{name}-debuginfo
template DEBUGINFO