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

Barry Warsaw barry at moszumanska.debian.org
Mon Apr 27 20:26:59 UTC 2015


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

barry pushed a commit to branch master
in repository pycurl.

commit 4d69da98db3a3dfb2b4e3a7a9edb2b9fd0469013
Author: Barry Warsaw <barry at python.org>
Date:   Mon Apr 27 16:11:47 2015 -0400

    Import pycurl_7.19.5.1.orig.tar.gz
---
 AUTHORS                                            |   1 +
 ChangeLog                                          |  22 +-
 MANIFEST.in                                        |   9 +
 PKG-INFO                                           |   2 +-
 RELEASE-NOTES.rst                                  |   7 +
 doc/conf.py                                        |   4 +-
 examples/linksys.py                                |   0
 examples/smtp.py                                   |  39 +++
 requirements-dev-2.4.txt                           |   2 +
 requirements-dev-2.5.txt                           |   2 +
 requirements-dev.txt                               |   4 +
 setup.py                                           |   4 +-
 src/easy.c                                         |  17 +
 src/module.c                                       |  17 +
 src/pycurl.h                                       |  16 +
 tests/__init__.py                                  |   8 +
 tests/app.py                                       | 113 ++++++
 tests/appmanager.py                                |  56 +++
 tests/certinfo_test.py                             |  67 ++++
 tests/certs/server.crt                             |  14 +
 tests/certs/server.key                             |  15 +
 tests/curl_object_test.py                          |  27 ++
 tests/debug_test.py                                |  52 +++
 tests/default_write_function_test.py               |  84 +++++
 tests/error_constants_test.py                      |  21 ++
 tests/error_test.py                                |  82 +++++
 tests/ext/test-lib.sh                              |  69 ++++
 tests/ext/test-suite.sh                            |  25 ++
 tests/fake-curl/curl-config-empty                  |  15 +
 tests/fake-curl/curl-config-libs-and-static-libs   |  17 +
 tests/fake-curl/curl-config-ssl-feature-only       |  18 +
 tests/fake-curl/curl-config-ssl-in-libs            |  14 +
 tests/fake-curl/curl-config-ssl-in-static-libs     |  17 +
 tests/fixtures/form_submission.txt                 |   1 +
 tests/ftp_test.py                                  |  53 +++
 tests/functools_backport.py                        |  58 ++++
 tests/getinfo_test.py                              |  52 +++
 tests/global_init_test.py                          |  31 ++
 tests/header_function_test.py                      |  49 +++
 tests/header_test.py                               |  49 +++
 tests/info_constants_test.py                       |  16 +
 tests/internals_test.py                            | 225 ++++++++++++
 tests/matrix.py                                    | 214 ++++++++++++
 tests/matrix/curl-7.19.0-sslv2-2b0e09b0f98.patch   |  40 +++
 .../curl-7.19.0-sslv2-c66b0b32fba-modified.patch   |  29 ++
 tests/matrix/python25.patch                        |  67 ++++
 tests/matrix/python30.patch                        |  19 ++
 tests/memory_mgmt_test.py                          | 261 ++++++++++++++
 tests/multi_memory_mgmt_test.py                    |  35 ++
 tests/multi_option_constants_test.py               |  24 ++
 tests/multi_socket_select_test.py                  | 120 +++++++
 tests/multi_socket_test.py                         |  97 ++++++
 tests/multi_test.py                                | 379 +++++++++++++++++++++
 tests/multi_timer_test.py                          |  90 +++++
 tests/option_constants_test.py                     | 149 ++++++++
 tests/pause_test.py                                |  93 +++++
 tests/post_test.py                                 | 125 +++++++
 tests/procmgr.py                                   | 101 ++++++
 tests/protocol_constants_test.py                   |  48 +++
 tests/pycurl_object_test.py                        | 125 +++++++
 tests/read_callback_test.py                        | 126 +++++++
 tests/readdata_test.py                             | 160 +++++++++
 tests/relative_url_test.py                         |  22 ++
 tests/reload_test.py                               |  20 ++
 tests/reset_test.py                                |  88 +++++
 tests/resolve_test.py                              |  26 ++
 tests/runwsgi.py                                   | 129 +++++++
 tests/seek_function_constants_test.py              |  31 ++
 tests/seek_function_test.py                        |  77 +++++
 tests/setopt_lifecycle_test.py                     |  58 ++++
 tests/setopt_test.py                               |  42 +++
 tests/setopt_unicode_test.py                       |  41 +++
 tests/setup_test.py                                | 103 ++++++
 tests/share_test.py                                |  71 ++++
 tests/socket_open_test.py                          |  48 +++
 tests/unset_range_test.py                          |  51 +++
 tests/user_agent_string_test.py                    |  27 ++
 tests/util.py                                      | 183 ++++++++++
 tests/version_comparison_test.py                   |  15 +
 tests/version_test.py                              |  13 +
 tests/vsftpd.conf                                  |  13 +
 tests/write_abort_test.py                          |  40 +++
 tests/write_cb_bogus_test.py                       |  47 +++
 tests/write_test.py                                |  94 +++++
 tests/write_to_stringio_test.py                    |  41 +++
 winbuild.py                                        |   2 +-
 86 files changed, 4971 insertions(+), 7 deletions(-)

diff --git a/AUTHORS b/AUTHORS
index 6586f7b..b27c1ba 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -22,6 +22,7 @@ Eric S. Raymond <esr at thyrsus.com>
 Gisle Vanem <gvanem at yahoo.no>
 Jakob Truelsen <jakob at scalgo.com>
 Jayne <corvine at gmail.com>
+JiCiT
 Jim Patterson
 K.S.Sreeram <sreeram at tachyontech.net>
 Kamil Dudka <kdudka at redhat.com>
diff --git a/ChangeLog b/ChangeLog
index 8f956b0..4cd24c0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,26 @@
-Version 7.19.5 [requires libcurl-7.19.0 or better] - 2014-07-12
+Version 7.19.5.1 [requires libcurl-7.19.0 or better] - 2015-01-06
+-----------------------------------------------------------------
+
+        * Added CURLPROXY_SOCKS4A and CURLPROXY_SOCKS5_HOSTNAME.
+
+        * setup.py now prints PycURL-specific option help when -h is used.
+
+        * LibreSSL is now supported (patch by JiCiT.)
+
+        * Fixed an oversight that broke PycURL building against libcurl 7.19.4
+          through 7.21.1. The bug was introduced in PycURL 7.19.5.
+
+        * Tests are now included in source distributions again, thanks to
+          Kamil Dudka and Johan Bergstroem.
+
+        * Added CURLOPT_MAIL_FROM and CURLOPT_MAIL_RCPT (libcurl 7.20.0+)
+          and CURLOPT_MAIL_AUTH (libcurl 7.25.0+).
+
+Version 7.19.5 [requires libcurl-7.21.2 or better] - 2014-07-12
 ---------------------------------------------------------------
 
+        * Tests removed from source and binary distributions.
+
         * Documentation greatly improved. Quickstart guide added.
 
         * pycurl.Curl, pycurl.CurlMulti and pycurl.CurlShare are now classes
diff --git a/MANIFEST.in b/MANIFEST.in
index e6a78c5..97730e6 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -32,4 +32,13 @@ include src/share.c
 include src/stringcompat.c
 include src/threadsupport.c
 include python/curl/*.py
+include requirements*.txt
+include tests/*.py
+include tests/certs/*.crt
+include tests/certs/*.key
+include tests/ext/*.sh
+include tests/fake-curl/*
+include tests/fixtures/form_submission.txt
+include tests/matrix/*.patch
+include tests/vsftpd.conf
 include winbuild.py
diff --git a/PKG-INFO b/PKG-INFO
index 24e3a5e..3998554 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: pycurl
-Version: 7.19.5
+Version: 7.19.5.1
 Summary: PycURL -- cURL library module for Python
 Home-page: http://pycurl.sourceforge.net/
 Author: Oleg Pudeyev
diff --git a/RELEASE-NOTES.rst b/RELEASE-NOTES.rst
index 79a59a5..3027e95 100644
--- a/RELEASE-NOTES.rst
+++ b/RELEASE-NOTES.rst
@@ -1,6 +1,13 @@
 Release Notes
 =============
 
+PycURL 7.19.5.1 - 2015-01-06
+----------------------------
+
+This release primarily fixes build breakage against libcurl 7.19.4 through
+7.21.1, such as versions shipped with CentOS.
+
+
 PycURL 7.19.5 - 2014-07-12
 --------------------------
 
diff --git a/doc/conf.py b/doc/conf.py
index e88066d..a6b8d22 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -54,9 +54,9 @@ copyright = u'2001-2014 Kjetil Jacobsen, Markus F.X.J. Oberhumer, Oleg Pudeyev'
 # built documents.
 #
 # The short X.Y version.
-version = '7.19.5'
+version = '7.19.5.1'
 # The full version, including alpha/beta/rc tags.
-release = '7.19.5'
+release = '7.19.5.1'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
diff --git a/examples/linksys.py b/examples/linksys.py
old mode 100755
new mode 100644
diff --git a/examples/smtp.py b/examples/smtp.py
new file mode 100644
index 0000000..2b7ce77
--- /dev/null
+++ b/examples/smtp.py
@@ -0,0 +1,39 @@
+# Based on the simple libcurl SMTP example:
+# https://github.com/bagder/curl/blob/master/docs/examples/smtp-mail.c
+# There are other SMTP examples in that directory that you may find helpful.
+
+import pycurl
+try:
+    from io import BytesIO
+except ImportError:
+    from StringIO import StringIO as BytesIO
+
+mail_server = 'smtp://localhost'
+mail_from = 'sender at example.org'
+mail_to = 'addressee at example.net'
+
+c = pycurl.Curl()
+c.setopt(c.URL, mail_server)
+c.setopt(c.MAIL_FROM, mail_from)
+c.setopt(c.MAIL_RCPT, [mail_to])
+
+message = '''\
+From: %s
+To: %s
+Subject: PycURL SMTP example
+
+SMTP example via PycURL
+''' % (mail_from, mail_to)
+
+# libcurl does not perform buffering, therefore
+# we need to wrap the message string into a BytesIO or StringIO.
+io = BytesIO(message)
+c.setopt(c.READDATA, io)
+
+# If UPLOAD is not set, libcurl performs SMTP VRFY.
+# Setting UPLOAD to True sends a message.
+c.setopt(c.UPLOAD, True)
+
+# Observe SMTP conversation.
+c.setopt(c.VERBOSE, True)
+c.perform()
diff --git a/requirements-dev-2.4.txt b/requirements-dev-2.4.txt
new file mode 100644
index 0000000..76411a0
--- /dev/null
+++ b/requirements-dev-2.4.txt
@@ -0,0 +1,2 @@
+nose
+simplejson==2.1.0
diff --git a/requirements-dev-2.5.txt b/requirements-dev-2.5.txt
new file mode 100644
index 0000000..52e3460
--- /dev/null
+++ b/requirements-dev-2.5.txt
@@ -0,0 +1,2 @@
+-r requirements-dev.txt
+simplejson
diff --git a/requirements-dev.txt b/requirements-dev.txt
new file mode 100644
index 0000000..e3c80c0
--- /dev/null
+++ b/requirements-dev.txt
@@ -0,0 +1,4 @@
+bottle
+# nose 1.3.1 is broken on python 3:
+# https://github.com/nose-devs/nose/issues/780
+nose>=1.3.2
diff --git a/setup.py b/setup.py
index 6215dfa..9cb0667 100644
--- a/setup.py
+++ b/setup.py
@@ -6,7 +6,7 @@
 
 PACKAGE = "pycurl"
 PY_PACKAGE = "curl"
-VERSION = "7.19.5"
+VERSION = "7.19.5.1"
 
 import glob, os, re, sys, string, subprocess
 import distutils
@@ -606,7 +606,7 @@ PycURL Windows options:
 '''
 
 if __name__ == "__main__":
-    if '--help' in sys.argv:
+    if '--help' in sys.argv or '-h' in sys.argv:
         # unfortunately this help precedes distutils help
         if sys.platform == "win32":
             print(windows_help)
diff --git a/src/easy.c b/src/easy.c
index 6f1ba1d..e521de4 100644
--- a/src/easy.c
+++ b/src/easy.c
@@ -351,6 +351,9 @@ util_curl_close(CurlObject *self)
 #ifdef HAVE_CURLOPT_RESOLVE
     SFREE(self->resolve);
 #endif
+#ifdef HAVE_CURL_7_20_0_OPTS
+    SFREE(self->mail_rcpt);
+#endif
 #undef SFREE
 }
 
@@ -1023,6 +1026,9 @@ do_curl_reset(CurlObject *self)
 #ifdef HAVE_CURLOPT_RESOLVE
     SFREE(self->resolve);
 #endif
+#ifdef HAVE_CURL_7_20_0_OPTS
+    SFREE(self->mail_rcpt);
+#endif
 #undef SFREE
     res = util_curl_init(self);
     if (res < 0) {
@@ -1232,6 +1238,12 @@ do_curl_setopt(CurlObject *self, PyObject *args)
 #ifdef HAVE_CURL_7_19_6_OPTS
         case CURLOPT_SSH_KNOWNHOSTS:
 #endif
+#ifdef HAVE_CURL_7_20_0_OPTS
+        case CURLOPT_MAIL_FROM:
+#endif
+#ifdef HAVE_CURL_7_25_0_OPTS
+        case CURLOPT_MAIL_AUTH:
+#endif
 /* FIXME: check if more of these options allow binary data */
             str = PyText_AsString_NoNUL(obj, &encoded_obj);
             if (str == NULL)
@@ -1414,6 +1426,11 @@ do_curl_setopt(CurlObject *self, PyObject *args)
             old_slist = &self->resolve;
             break;
 #endif
+#ifdef HAVE_CURL_7_20_0_OPTS
+        case CURLOPT_MAIL_RCPT:
+            old_slist = &self->mail_rcpt;
+            break;
+#endif
         case CURLOPT_HTTPPOST:
             break;
         default:
diff --git a/src/module.c b/src/module.c
index be00f2a..d7c776f 100644
--- a/src/module.c
+++ b/src/module.c
@@ -299,6 +299,8 @@ initpycurl(void)
         runtime_ssl_lib = "none/other";
     } else if (!strncmp(vi->ssl_version, "OpenSSL/", 8)) {
         runtime_ssl_lib = "openssl";
+    } else if (!strncmp(vi->ssl_version, "LibreSSL/", 9)) {
+        runtime_ssl_lib = "openssl";
     } else if (!strncmp(vi->ssl_version, "GnuTLS/", 7)) {
         runtime_ssl_lib = "gnutls";
     } else if (!strncmp(vi->ssl_version, "NSS/", 4)) {
@@ -501,7 +503,9 @@ initpycurl(void)
     insint_c(d, "PROXYTYPE_HTTP_1_0", CURLPROXY_HTTP_1_0);
 #endif
     insint_c(d, "PROXYTYPE_SOCKS4", CURLPROXY_SOCKS4);
+    insint_c(d, "PROXYTYPE_SOCKS4A", CURLPROXY_SOCKS4A);
     insint_c(d, "PROXYTYPE_SOCKS5", CURLPROXY_SOCKS5);
+    insint_c(d, "PROXYTYPE_SOCKS5_HOSTNAME", CURLPROXY_SOCKS5_HOSTNAME);
 
     /* curl_httpauth: constants for setopt(HTTPAUTH, x) */
     insint_c(d, "HTTPAUTH_NONE", CURLAUTH_NONE);
@@ -720,12 +724,15 @@ initpycurl(void)
     insint_c(d, "PROTO_DICT", CURLPROTO_DICT);
     insint_c(d, "PROTO_FILE", CURLPROTO_FILE);
     insint_c(d, "PROTO_TFTP", CURLPROTO_TFTP);
+#ifdef HAVE_CURL_7_20_0_OPTS
     insint_c(d, "PROTO_IMAP", CURLPROTO_IMAP);
     insint_c(d, "PROTO_IMAPS", CURLPROTO_IMAPS);
     insint_c(d, "PROTO_POP3", CURLPROTO_POP3);
     insint_c(d, "PROTO_POP3S", CURLPROTO_POP3S);
     insint_c(d, "PROTO_SMTP", CURLPROTO_SMTP);
     insint_c(d, "PROTO_SMTPS", CURLPROTO_SMTPS);
+#endif
+#ifdef HAVE_CURL_7_21_0_OPTS
     insint_c(d, "PROTO_RTSP", CURLPROTO_RTSP);
     insint_c(d, "PROTO_RTMP", CURLPROTO_RTMP);
     insint_c(d, "PROTO_RTMPT", CURLPROTO_RTMPT);
@@ -733,7 +740,10 @@ initpycurl(void)
     insint_c(d, "PROTO_RTMPTE", CURLPROTO_RTMPTE);
     insint_c(d, "PROTO_RTMPS", CURLPROTO_RTMPS);
     insint_c(d, "PROTO_RTMPTS", CURLPROTO_RTMPTS);
+#endif
+#ifdef HAVE_CURL_7_21_2_OPTS
     insint_c(d, "PROTO_GOPHER", CURLPROTO_GOPHER);
+#endif
     insint_c(d, "PROTO_ALL", CURLPROTO_ALL);
 #endif
 #ifdef HAVE_CURL_7_19_4_OPTS
@@ -741,6 +751,13 @@ initpycurl(void)
     insint_c(d, "SOCKS5_GSSAPI_SERVICE", CURLOPT_SOCKS5_GSSAPI_SERVICE);
     insint_c(d, "SOCKS5_GSSAPI_NEC", CURLOPT_SOCKS5_GSSAPI_NEC);
 #endif
+#ifdef HAVE_CURL_7_20_0_OPTS
+    insint_c(d, "MAIL_FROM", CURLOPT_MAIL_FROM);
+    insint_c(d, "MAIL_RCPT", CURLOPT_MAIL_RCPT);
+#endif
+#ifdef HAVE_CURL_7_25_0_OPTS
+    insint_c(d, "MAIL_AUTH", CURLOPT_MAIL_AUTH);
+#endif
 
     insint_c(d, "M_TIMERFUNCTION", CURLMOPT_TIMERFUNCTION);
     insint_c(d, "M_SOCKETFUNCTION", CURLMOPT_SOCKETFUNCTION);
diff --git a/src/pycurl.h b/src/pycurl.h
index 249d962..6a5fc1a 100644
--- a/src/pycurl.h
+++ b/src/pycurl.h
@@ -84,10 +84,19 @@ pycurl_inet_ntop (int family, void *addr, char *string, size_t string_size);
 #define HAVE_CURL_7_19_6_OPTS
 #endif
 
+#if LIBCURL_VERSION_NUM >= 0x071400 /* check for 7.20.0 or greater */
+#define HAVE_CURL_7_20_0_OPTS
+#endif
+
 #if LIBCURL_VERSION_NUM >= 0x071500 /* check for 7.21.0 or greater */
 #define HAVE_CURLINFO_LOCAL_PORT
 #define HAVE_CURLINFO_PRIMARY_PORT
 #define HAVE_CURLINFO_LOCAL_IP
+#define HAVE_CURL_7_21_0_OPTS
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x071502 /* check for 7.21.2 or greater */
+#define HAVE_CURL_7_21_2_OPTS
 #endif
 
 #if LIBCURL_VERSION_NUM >= 0x071503 /* check for 7.21.3 or greater */
@@ -103,6 +112,10 @@ pycurl_inet_ntop (int family, void *addr, char *string, size_t string_size);
 #define HAVE_CURL_7_24_0
 #endif
 
+#if LIBCURL_VERSION_NUM >= 0x071900 /* check for 7.25.0 or greater */
+#define HAVE_CURL_7_25_0_OPTS
+#endif
+
 #if LIBCURL_VERSION_NUM >= 0x071A00 /* check for 7.26.0 or greater */
 #define HAVE_CURL_REDIR_POST_303
 #endif
@@ -289,6 +302,9 @@ typedef struct CurlObject {
 #ifdef HAVE_CURLOPT_RESOLVE
     struct curl_slist *resolve;
 #endif
+#ifdef HAVE_CURL_7_20_0_OPTS
+    struct curl_slist *mail_rcpt;
+#endif
     /* callbacks */
     PyObject *w_cb;
     PyObject *h_cb;
diff --git a/tests/__init__.py b/tests/__init__.py
new file mode 100644
index 0000000..840f94c
--- /dev/null
+++ b/tests/__init__.py
@@ -0,0 +1,8 @@
+def setup_package():
+    # import here, not globally, so that running
+    # python -m tests.appmanager
+    # to launch the app manager is possible without having pycurl installed
+    # (as the test app does not depend on pycurl)
+    import pycurl
+    
+    print('Testing %s' % pycurl.version)
diff --git a/tests/app.py b/tests/app.py
new file mode 100644
index 0000000..20658bc
--- /dev/null
+++ b/tests/app.py
@@ -0,0 +1,113 @@
+import time as _time, sys
+import bottle
+try:
+    import json
+except ImportError:
+    import simplejson as json
+
+py3 = sys.version_info[0] == 3
+
+app = bottle.Bottle()
+app.debug = True
+
+ at app.route('/success')
+def ok():
+    return 'success'
+
+ at app.route('/short_wait')
+def ok():
+    _time.sleep(0.1)
+    return 'success'
+
+ at app.route('/status/403')
+def forbidden():
+    return bottle.HTTPResponse('forbidden', 403)
+
+ at app.route('/status/404')
+def not_found():
+    return bottle.HTTPResponse('not found', 404)
+
+ at app.route('/postfields', method='post')
+def postfields():
+    return json.dumps(dict(bottle.request.forms))
+
+ at app.route('/raw_utf8', method='post')
+def raw_utf8():
+    data = bottle.request.body.getvalue().decode('utf8')
+    return json.dumps(data)
+
+# XXX file is not a bottle FileUpload instance, but FieldStorage?
+def convert_file(key, file):
+    return {
+        'key': key,
+        'name': file.name,
+        'raw_filename': file.raw_filename,
+        'headers': file.headers,
+        'content_type': file.content_type,
+        'content_length': file.content_length,
+        'data': file.read(),
+    }
+
+if hasattr(bottle, 'FileUpload'):
+    # bottle 0.12
+    def convert_file(key, file):
+        return {
+            'name': file.name,
+            # file.filename lowercases the file name
+            # https://github.com/defnull/bottle/issues/582
+            # raw_filenames is a string on python 3
+            'filename': file.raw_filename,
+            'data': file.file.read().decode(),
+        }
+else:
+    # bottle 0.11
+    def convert_file(key, file):
+        return {
+            'name': file.name,
+            'filename': file.filename,
+            'data': file.file.read().decode(),
+        }
+
+ at app.route('/files', method='post')
+def files():
+    files = [convert_file(key, bottle.request.files[key]) for key in bottle.request.files]
+    return json.dumps(files)
+
+ at app.route('/header')
+def header():
+    return bottle.request.headers[bottle.request.query['h']]
+
+# This is a hacky endpoint to test non-ascii text being given to libcurl
+# via headers.
+# HTTP RFC requires headers to be latin1-encoded.
+# Any string can be decoded as latin1; here we encode the header value
+# back into latin1 to obtain original bytestring, then decode it in utf-8.
+# Thanks to bdarnell for the idea: https://github.com/pycurl/pycurl/issues/124
+ at app.route('/header_utf8')
+def header():
+    header_value = bottle.request.headers[bottle.request.query['h']]
+    if py3:
+        # header_value is a string, headers are decoded in latin1
+        header_value = header_value.encode('latin1').decode('utf8')
+    else:
+        # header_value is a binary string, decode in utf-8 directly
+        header_value = header_value.decode('utf8')
+    return header_value
+
+ at app.route('/param_utf8_hack', method='post')
+def param_utf8_hack():
+    param = bottle.request.forms['p']
+    if py3:
+        # python 3 decodes bytes as latin1 perhaps?
+        # apply the latin1-utf8 hack
+        param = param.encode('latin').decode('utf8')
+    return param
+
+def pause_writer():
+    yield 'part1'
+    _time.sleep(0.5)
+    yield 'part2'
+
+ at app.route('/pause')
+def pause():
+    return pause_writer()
diff --git a/tests/appmanager.py b/tests/appmanager.py
new file mode 100644
index 0000000..f01dd07
--- /dev/null
+++ b/tests/appmanager.py
@@ -0,0 +1,56 @@
+import sys, time, os
+
+def noop(*args):
+    pass
+
+def setup(*specs):
+    if os.environ.get('PYCURL_STANDALONE_APP') and os.environ['PYCURL_STANDALONE_APP'].lower() in ['1', 'yes', 'true']:
+        return (noop, noop)
+    else:
+        return perform_setup(*specs)
+
+def perform_setup(*specs):
+    from . import runwsgi
+    
+    app_specs = []
+    for spec in specs:
+        app_module = __import__(spec[0], globals(), locals(), ['app'], 1)
+        app = getattr(app_module, 'app')
+        app_specs.append([app] + list(spec[1:]))
+    
+    return runwsgi.app_runner_setup(*app_specs)
+
+quit = False
+
+def sigterm_handler(*args):
+    global quit
+    quit = True
+
+def run_standalone():
+    import signal
+    
+    funcs = []
+    
+    signal.signal(signal.SIGTERM, sigterm_handler)
+    
+    funcs.append(setup(('app', 8380)))
+    funcs.append(setup(('app', 8381)))
+    funcs.append(setup(('app', 8382)))
+    funcs.append(setup(('app', 8383, dict(ssl=True))))
+    
+    for setup_func, teardown_func in funcs:
+        setup_func(sys.modules[__name__])
+    
+    sys.stdout.write("Running, use SIGTERM or SIGINT to stop\n")
+    
+    try:
+        while not quit:
+            time.sleep(1)
+    except KeyboardInterrupt:
+        pass
+    
+    for setup_func, teardown_func in funcs:
+        teardown_func(sys.modules[__name__])
+
+if __name__ == '__main__':
+    run_standalone()
diff --git a/tests/certinfo_test.py b/tests/certinfo_test.py
new file mode 100644
index 0000000..26d669d
--- /dev/null
+++ b/tests/certinfo_test.py
@@ -0,0 +1,67 @@
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+# vi:ts=4:et
+
+import pycurl
+import unittest
+import nose.plugins.skip
+
+from . import appmanager
+from . import util
+
+setup_module, teardown_module = appmanager.setup(('app', 8383, dict(ssl=True)))
+
+class CertinfoTest(unittest.TestCase):
+    def setUp(self):
+        self.curl = pycurl.Curl()
+    
+    def tearDown(self):
+        self.curl.close()
+    
+    # CURLOPT_CERTINFO was introduced in libcurl-7.19.1
+    @util.min_libcurl(7, 19, 1)
+    def test_certinfo_option(self):
+        assert hasattr(pycurl, 'OPT_CERTINFO')
+    
+    # CURLOPT_CERTINFO was introduced in libcurl-7.19.1
+    @util.min_libcurl(7, 19, 1)
+    @util.only_ssl
+    def test_request_without_certinfo(self):
+        self.curl.setopt(pycurl.URL, 'https://localhost:8383/success')
+        sio = util.BytesIO()
+        self.curl.setopt(pycurl.WRITEFUNCTION, sio.write)
+        # self signed certificate
+        self.curl.setopt(pycurl.SSL_VERIFYPEER, 0)
+        self.curl.perform()
+        assert sio.getvalue().decode() == 'success'
+        
+        certinfo = self.curl.getinfo(pycurl.INFO_CERTINFO)
+        self.assertEqual([], certinfo)
+    
+    # CURLOPT_CERTINFO was introduced in libcurl-7.19.1
+    @util.min_libcurl(7, 19, 1)
+    @util.only_ssl
+    def test_request_with_certinfo(self):
+        # CURLOPT_CERTINFO only works with OpenSSL
+        if 'openssl' not in pycurl.version.lower():
+            raise nose.plugins.skip.SkipTest('libcurl does not use openssl')
+        
+        self.curl.setopt(pycurl.URL, 'https://localhost:8383/success')
+        sio = util.BytesIO()
+        self.curl.setopt(pycurl.WRITEFUNCTION, sio.write)
+        self.curl.setopt(pycurl.OPT_CERTINFO, 1)
+        # self signed certificate
+        self.curl.setopt(pycurl.SSL_VERIFYPEER, 0)
+        self.curl.perform()
+        assert sio.getvalue().decode() == 'success'
+        
+        certinfo = self.curl.getinfo(pycurl.INFO_CERTINFO)
+        # self signed certificate, one certificate in chain
+        assert len(certinfo) == 1
+        certinfo = certinfo[0]
+        # convert to a dictionary
+        certinfo_dict = {}
+        for entry in certinfo:
+            certinfo_dict[entry[0]] = entry[1]
+        assert 'Subject' in certinfo_dict
+        assert 'PycURL test suite' in certinfo_dict['Subject']
diff --git a/tests/certs/server.crt b/tests/certs/server.crt
new file mode 100644
index 0000000..f904889
--- /dev/null
+++ b/tests/certs/server.crt
@@ -0,0 +1,14 @@
+-----BEGIN CERTIFICATE-----
+MIICGzCCAYQCCQCdeJzNRLLLvDANBgkqhkiG9w0BAQUFADBSMQswCQYDVQQGEwJB
+VTETMBEGA1UECBMKU29tZS1TdGF0ZTEaMBgGA1UEChMRUHljVVJMIHRlc3Qgc3Vp
+dGUxEjAQBgNVBAMTCWxvY2FsaG9zdDAeFw0xMzEyMjIxMzA0MTVaFw0xNzA5MTcx
+MzA0MTVaMFIxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMRowGAYD
+VQQKExFQeWNVUkwgdGVzdCBzdWl0ZTESMBAGA1UEAxMJbG9jYWxob3N0MIGfMA0G
+CSqGSIb3DQEBAQUAA4GNADCBiQKBgQDETT7n0p/bP1xxnJQC4oZCmRBpe0QkLXd7
+FjhJYh+vvwV8JK12qll1+abrp2MUQ2GZoBlgaw8cZesQgdCqNrbspiQejhxcvGSx
+HgNvTXI8y0xT3EfODfs5MhLaUZGYzEt24pzlcqzED3w9X8PWTiSyotwsMf/9h0tH
+SJhRgs4iAwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAGhX0iIMCrRcI6T6S4YydkXf
+7LrXZpjSJwVGSCd5ehx3Qvc1LQNJjpB68F0MhVTqbDP1o3CAHaTa2s/8NC9j3tV7
+bUynoKJT3srpHisfdd/SV538mWvFDtGRctbmmqp8qT4On+kr76dKj+/d3HyfOKIK
+Aasa7ODxFKbbY542yYHu
+-----END CERTIFICATE-----
diff --git a/tests/certs/server.key b/tests/certs/server.key
new file mode 100644
index 0000000..5bdbbf9
--- /dev/null
+++ b/tests/certs/server.key
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQDETT7n0p/bP1xxnJQC4oZCmRBpe0QkLXd7FjhJYh+vvwV8JK12
+qll1+abrp2MUQ2GZoBlgaw8cZesQgdCqNrbspiQejhxcvGSxHgNvTXI8y0xT3EfO
+Dfs5MhLaUZGYzEt24pzlcqzED3w9X8PWTiSyotwsMf/9h0tHSJhRgs4iAwIDAQAB
+AoGAMLNFTvgnJpqikaEZ61lNm8ojkze8oQkSolvR3QrV96D5eGIVEuKSTT2Blucx
+In7RAO8CPLRyzEXQuoiqPwBSAxY2Xswd+zcAgN2Zi8uqWTmPNsW6451BJRemgLjK
+OxLxCdVTOTxHfttj/CnwYQ6zn55oyZJGGmaVGykbvH/AgukCQQD3HfhOPExsI/6X
+Bp7CeZOhmM+LBOQGQGDjRnBdRp0s3HiUfaDxU2mbEafGPI2OyuzpYAqxHVTJLai6
+CQlJGuQXAkEAy1upObz2bcN2dUCHNufk2qdfRSCRkmKemuqznwCW3fSoRKB+qOu3
+xyTLEkTvLBNnAFjoyd6B75QzL/7//qvo9QJAE0xV3dY7qZ5N/YFY2Jsh+layroqd
+PBe++UDA+afQEnbNO9trvCzlbGS+k26bJ3GVeswzSY2e128nZA/cl8bv1QJAfTEO
+uybjpqtAj+qL03drYljLw+jK9Y2VCtYWgnqAZmAp/yW3FBMZbpXuFm8ttrqzHHmf
+xjcfUvivkoqv2n7GyQJBAKxbBVx/LQiSVpOTnXTEA1NJF8NS2NCF+3sm3kGhFKql
+Hi/cCAFrhBl9MoPJF/6noukfIkq0SzjkWrYIcoBDoVg=
+-----END RSA PRIVATE KEY-----
diff --git a/tests/curl_object_test.py b/tests/curl_object_test.py
new file mode 100644
index 0000000..4b3e8da
--- /dev/null
+++ b/tests/curl_object_test.py
@@ -0,0 +1,27 @@
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+# vi:ts=4:et
+
+import pycurl
+import unittest
+import nose.tools
+
+class CurlObjectTest(unittest.TestCase):
+    def test_close(self):
+        c = pycurl.Curl()
+        c.close()
+    
+    def test_close_twice(self):
+        c = pycurl.Curl()
+        c.close()
+        c.close()
+    
+    # positional arguments are rejected
+    @nose.tools.raises(TypeError)
+    def test_positional_arguments(self):
+        c = pycurl.Curl(1)
+    
+    # keyword arguments are rejected
+    @nose.tools.raises(TypeError)
+    def test_keyword_arguments(self):
+        c = pycurl.Curl(a=1)
diff --git a/tests/debug_test.py b/tests/debug_test.py
new file mode 100644
index 0000000..5c273ce
--- /dev/null
+++ b/tests/debug_test.py
@@ -0,0 +1,52 @@
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+# vi:ts=4:et
+
+import pycurl
+import unittest
+
+from . import appmanager
+from . import util
+
+setup_module, teardown_module = appmanager.setup(('app', 8380))
+
+class DebugTest(unittest.TestCase):
+    def setUp(self):
+        self.curl = pycurl.Curl()
+        self.debug_entries = []
+    
+    def tearDown(self):
+        self.curl.close()
+    
+    def debug_function(self, t, b):
+        self.debug_entries.append((t, b))
+    
+    def test_perform_get_with_debug_function(self):
+        self.curl.setopt(pycurl.VERBOSE, 1)
+        self.curl.setopt(pycurl.DEBUGFUNCTION, self.debug_function)
+        self.curl.setopt(pycurl.URL, 'http://localhost:8380/success')
+        sio = util.BytesIO()
+        self.curl.setopt(pycurl.WRITEFUNCTION, sio.write)
+        self.curl.perform()
+        
+        # Some checks with no particular intent
+        self.check(0, 'Trying')
+        if util.pycurl_version_less_than(7, 24):
+            self.check(0, 'connected')
+        else:
+            self.check(0, 'Connected to localhost')
+        self.check(0, 'port 8380')
+        # request
+        self.check(2, 'GET /success HTTP/1.1')
+        # response
+        self.check(1, 'HTTP/1.0 200 OK')
+        self.check(1, 'Content-Length: 7')
+        # result
+        self.check(3, 'success')
+    
+    def check(self, wanted_t, wanted_b):
+        for t, b in self.debug_entries:
+            if t == wanted_t and wanted_b in b:
+                return
+        assert False, "%d: %s not found in debug entries\nEntries are:\n%s" % \
+            (wanted_t, wanted_b, repr(self.debug_entries))
diff --git a/tests/default_write_function_test.py b/tests/default_write_function_test.py
new file mode 100644
index 0000000..c552568
--- /dev/null
+++ b/tests/default_write_function_test.py
@@ -0,0 +1,84 @@
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+# vi:ts=4:et
+
+import unittest
+import pycurl
+import sys
+import tempfile
+import os
+
+from . import appmanager
+
+setup_module, teardown_module = appmanager.setup(('app', 8380))
+
+STDOUT_FD_NUM = 1
+
+def try_fsync(fd):
+    try:
+        os.fsync(fd)
+    except OSError:
+        # On travis:
+        # OSError: [Errno 22] Invalid argument
+        # ignore
+        pass
+
+class DefaultWriteFunctionTest(unittest.TestCase):
+    def setUp(self):
+        self.curl = pycurl.Curl()
+    
+    def tearDown(self):
+        self.curl.close()
+    
+    def test_perform_get(self):
+        # This test performs a GET request without doing anything else.
+        # Unfortunately, the default curl behavior is to print response
+        # body to standard output, which spams test output.
+        # As a result this test is commented out. Uncomment for debugging.
+        # test_perform_get_with_default_write_function is the test
+        # which exercises default curl write handler.
+        
+        self.curl.setopt(pycurl.URL, 'http://localhost:8380/success')
+        self.curl.perform()
+        # If this flush is not done, stdout output bleeds into the next test
+        # that is executed (without nose output capture)
+        sys.stdout.flush()
+        try_fsync(STDOUT_FD_NUM)
+    
+    # I have a really hard time getting this to work with nose output capture
+    def skip_perform_get_with_default_write_function(self):
+        self.curl.setopt(pycurl.URL, 'http://localhost:8380/success')
+        f = tempfile.NamedTemporaryFile()
+        try:
+        #with open('w', 'w+') as f:
+            # nose output capture plugin replaces sys.stdout with a StringIO
+            # instance. We want to redirect the underlying file descriptor
+            # anyway because underlying C code uses it.
+            # Therefore:
+            # 1. Use file descriptor 1 rather than sys.stdout.fileno() to
+            # reference the standard output file descriptor.
+            # 2. We do not touch sys.stdout. This means anything written to
+            # sys.stdout will be captured by nose, and not make it to our code.
+            # But the output we care about happens at libcurl level, below
+            # nose, therefore this is fine.
+            saved_stdout_fd = os.dup(STDOUT_FD_NUM)
+            os.dup2(f.fileno(), STDOUT_FD_NUM)
+            #os.dup2(1, 100)
+            #os.dup2(2, 1)
+            # We also need to flush the output that libcurl wrote to stdout.
+            # Since sys.stdout might be nose's StringIO instance, open the
+            # stdout file descriptor manually.
+            
+            try:
+                self.curl.perform()
+                sys.stdout.flush()
+            finally:
+                try_fsync(STDOUT_FD_NUM)
+                os.dup2(saved_stdout_fd, STDOUT_FD_NUM)
+                os.close(saved_stdout_fd)
+                #os.dup2(100, 1)
+            f.seek(0)
+            body = f.read()
+        finally:
+            f.close()
+        self.assertEqual('success', body)
diff --git a/tests/error_constants_test.py b/tests/error_constants_test.py
new file mode 100644
index 0000000..26767fe
--- /dev/null
+++ b/tests/error_constants_test.py
@@ -0,0 +1,21 @@
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+# vi:ts=4:et
+
+import pycurl
+import unittest
+
+from . import util
+
+class ErrorConstantsTest(unittest.TestCase):
+    @util.min_libcurl(7, 21, 5)
+    def test_not_built_in(self):
+        assert hasattr(pycurl, 'E_NOT_BUILT_IN')
+    
+    @util.min_libcurl(7, 24, 0)
+    def test_ftp_accept_failed(self):
+        assert hasattr(pycurl, 'E_FTP_ACCEPT_FAILED')
+    
+    @util.min_libcurl(7, 21, 5)
+    def test_unknown_option(self):
+        assert hasattr(pycurl, 'E_UNKNOWN_OPTION')
diff --git a/tests/error_test.py b/tests/error_test.py
new file mode 100644
index 0000000..32a5add
--- /dev/null
+++ b/tests/error_test.py
@@ -0,0 +1,82 @@
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+# vi:ts=4:et
+
+import pycurl
+import sys
+import unittest
+
+class ErrorTest(unittest.TestCase):
+    def setUp(self):
+        self.curl = pycurl.Curl()
+
+    def tearDown(self):
+        self.curl.close()
+
+    # error originating in libcurl
+    def test_pycurl_error_libcurl(self):
+        try:
+            # perform without a url
+            self.curl.perform()
+        except pycurl.error:
... 4720 lines suppressed ...

-- 
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