]> granicus.if.org Git - python/commitdiff
Merged revisions 76952 via svnmerge from
authorTarek Ziadé <ziade.tarek@gmail.com>
Sun, 20 Dec 2009 23:54:52 +0000 (23:54 +0000)
committerTarek Ziadé <ziade.tarek@gmail.com>
Sun, 20 Dec 2009 23:54:52 +0000 (23:54 +0000)
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r76952 | tarek.ziade | 2009-12-21 00:23:34 +0100 (Mon, 21 Dec 2009) | 1 line

  Fixed #7552: fixed distutils.command.upload failure on very long passwords
........

Lib/distutils/command/upload.py
Lib/distutils/tests/support.py
Lib/distutils/tests/test_upload.py
Misc/NEWS

index 8805d41da0e62fa5658a34422600e26b8b73bfa3..9f1aae6aa44e59c98f08d7bb49e0dd78465eaf49 100644 (file)
@@ -11,7 +11,7 @@ import os
 import socket
 import platform
 import httplib
-import base64
+from base64 import standard_b64encode
 import urlparse
 import cStringIO as StringIO
 from ConfigParser import ConfigParser
@@ -115,7 +115,8 @@ class upload(PyPIRCCommand):
                                      open(filename+".asc").read())
 
         # set up the authentication
-        auth = "Basic " + base64.encodestring(self.username + ":" + self.password).strip()
+        auth = "Basic " + standard_b64encode(self.username + ":" +
+                                             self.password)
 
         # Build up the MIME payload for the POST data
         boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254'
index d24a18ea0e67b1059bc72966d1e2348cc8605353..9d373e94e4f73206a7b82131b5be4ecd20fd6b6b 100644 (file)
@@ -1,10 +1,10 @@
 """Support code for distutils test cases."""
-
+import os
 import shutil
 import tempfile
 
 from distutils import log
-
+from distutils.dist import Distribution
 
 class LoggingSilencer(object):
 
@@ -55,6 +55,23 @@ class TempdirManager(object):
         finally:
             f.close()
 
+    def create_dist(self, pkg_name='foo', **kw):
+        """Will generate a test environment.
+
+        This function creates:
+         - a Distribution instance using keywords
+         - a temporary directory with a package structure
+
+        It returns the package directory and the distribution
+        instance.
+        """
+        tmp_dir = self.mkdtemp()
+        pkg_dir = os.path.join(tmp_dir, pkg_name)
+        os.mkdir(pkg_dir)
+        dist = Distribution(attrs=kw)
+
+        return pkg_dir, dist
+
 class DummyCommand:
     """Class to store options for retrieval via set_undefined_options()."""
 
index b05ab1f78bba987a472fa91ff6af7ca187028b14..322beb778ce75d5e0dd665a3a01d488d2c66eb81 100644 (file)
@@ -2,6 +2,7 @@
 import sys
 import os
 import unittest
+import httplib
 
 from distutils.command.upload import upload
 from distutils.core import Distribution
@@ -9,8 +10,66 @@ from distutils.core import Distribution
 from distutils.tests import support
 from distutils.tests.test_config import PYPIRC, PyPIRCCommandTestCase
 
+PYPIRC_LONG_PASSWORD = """\
+[distutils]
+
+index-servers =
+    server1
+    server2
+
+[server1]
+username:me
+password:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+
+[server2]
+username:meagain
+password: secret
+realm:acme
+repository:http://another.pypi/
+"""
+
+class _Resp(object):
+    def __init__(self, status):
+        self.status = status
+        self.reason = 'OK'
+
+_CONNECTIONS = []
+
+class _FakeHTTPConnection(object):
+    def __init__(self, netloc):
+        self.requests = []
+        self.headers = {}
+        self.body = None
+        self.netloc = netloc
+        _CONNECTIONS.append(self)
+
+    def connect(self):
+        pass
+    endheaders = connect
+
+    def send(self, body):
+        self.body = body
+
+    def putrequest(self, type_, data):
+        self.requests.append((type_, data))
+
+    def putheader(self, name, value):
+        self.headers[name] = value
+
+    def getresponse(self):
+        return _Resp(200)
+
 class uploadTestCase(PyPIRCCommandTestCase):
 
+    def setUp(self):
+        super(uploadTestCase, self).setUp()
+        self.old_klass = httplib.HTTPConnection
+        httplib.HTTPConnection = _FakeHTTPConnection
+
+    def tearDown(self):
+        httplib.HTTPConnection = self.old_klass
+        super(uploadTestCase, self).tearDown()
+
     def test_finalize_options(self):
 
         # new format
@@ -27,6 +86,33 @@ class uploadTestCase(PyPIRCCommandTestCase):
             self.assertEquals(getattr(cmd, attr), waited)
 
 
+    def test_upload(self):
+        tmp = self.mkdtemp()
+        path = os.path.join(tmp, 'xxx')
+        self.write_file(path)
+        command, pyversion, filename = 'xxx', '2.6', path
+        dist_files = [(command, pyversion, filename)]
+        self.write_file(self.rc, PYPIRC_LONG_PASSWORD)
+
+        # lets run it
+        pkg_dir, dist = self.create_dist(dist_files=dist_files)
+        cmd = upload(dist)
+        cmd.ensure_finalized()
+        cmd.run()
+
+        # what did we send ?
+        res = _CONNECTIONS[-1]
+
+        headers = res.headers
+        self.assertEquals(headers['Content-length'], '2086')
+        self.assertTrue(headers['Content-type'].startswith('multipart/form-data'))
+
+        method, request = res.requests[-1]
+        self.assertEquals(method, 'POST')
+        self.assertEquals(res.netloc, 'pypi.python.org')
+        self.assertTrue('xxx' in res.body)
+        self.assertFalse('\n' in headers['Authorization'])
+
 def test_suite():
     return unittest.makeSuite(uploadTestCase)
 
index 817429270f50c5740fb26139a686106ad88e2060..6cbb39dfe59f860bd4dda2a45a0625a32cda7de6 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -35,6 +35,10 @@ Core and Builtins
 Library
 -------
 
+- Issue #7552: Removed line feed in the base64 Authorization header in
+  the Distutils upload command to avoid an error when PyPI reads it.
+  This occurs on long passwords. Initial patch by JP St. Pierre.
+
 - Issue #7231: urllib2 cannot handle https with proxy requiring auth. Patch by
   Tatsuhiro Tsujikawa.