Merged revisions 73436 via svnmerge from

svn+ssh://pythondev@svn.python.org/python/trunk

........
  r73436 | tarek.ziade | 2009-06-16 01:30:13 +0200 (Tue, 16 Jun 2009) | 1 line

  Issue #6286: distutils upload command now uses urllib2
........
This commit is contained in:
Tarek Ziadé 2009-06-28 21:26:27 +00:00
parent 2c02bdc8a6
commit 25bd2062f1
3 changed files with 55 additions and 64 deletions

View File

@ -5,10 +5,9 @@ import sys
import os, io
import socket
import platform
import configparser
import http.client as httpclient
from urllib.request import urlopen, Request, HTTPError
import base64
import urllib.parse
from urllib.parse import urlparse
from hashlib import md5
from distutils.errors import *
@ -61,6 +60,15 @@ class upload(PyPIRCCommand):
self.upload_file(command, pyversion, filename)
def upload_file(self, command, pyversion, filename):
# Makes sure the repository URL is compliant
schema, netloc, url, params, query, fragments = \
urlparse(self.repository)
if params or query or fragments:
raise AssertionError("Incompatible url %s" % self.repository)
if schema not in ('http', 'https'):
raise AssertionError("unsupported schema " + schema)
# Sign if requested
if self.sign:
gpg_args = ["gpg", "--detach-sign", "-a", filename]
@ -153,40 +161,30 @@ class upload(PyPIRCCommand):
self.announce("Submitting %s to %s" % (filename, self.repository), log.INFO)
# build the Request
# We can't use urllib since we need to send the Basic
# auth right with the first request
# TODO(jhylton): Can we fix urllib?
schema, netloc, url, params, query, fragments = \
urllib.parse.urlparse(self.repository)
assert not params and not query and not fragments
if schema == 'http':
http = httpclient.HTTPConnection(netloc)
elif schema == 'https':
http = httpclient.HTTPSConnection(netloc)
else:
raise AssertionError("unsupported schema "+schema)
headers = {'Content-type':
'multipart/form-data; boundary=%s' % boundary,
'Content-length': str(len(body)),
'Authorization': auth}
data = ''
loglevel = log.INFO
request = Request(self.repository, data=body,
headers=headers)
# send the data
try:
http.connect()
http.putrequest("POST", url)
http.putheader('Content-type',
'multipart/form-data; boundary=%s'%boundary)
http.putheader('Content-length', str(len(body)))
http.putheader('Authorization', auth)
http.endheaders()
http.send(body)
result = urlopen(request)
status = result.getcode()
reason = result.msg
except socket.error as e:
self.announce(str(e), log.ERROR)
return
except HTTPError as e:
status = e.code
reason = e.msg
r = http.getresponse()
if r.status == 200:
self.announce('Server response (%s): %s' % (r.status, r.reason),
if status == 200:
self.announce('Server response (%s): %s' % (status, reason),
log.INFO)
else:
self.announce('Upload failed (%s): %s' % (r.status, r.reason),
self.announce('Upload failed (%s): %s' % (status, reason),
log.ERROR)
if self.show_response:
self.announce('-'*75, r.read(), '-'*75)
self.announce('-'*75, result.read(), '-'*75)

View File

@ -2,8 +2,8 @@
import sys
import os
import unittest
import http.client as httpclient
from distutils.command import upload as upload_mod
from distutils.command.upload import upload
from distutils.core import Distribution
@ -19,48 +19,37 @@ index-servers =
[server1]
username:me
"""
class Response(object):
def __init__(self, status=200, reason='OK'):
self.status = status
self.reason = reason
class FakeConnection(object):
class FakeOpen(object):
def __init__(self):
self.requests = []
self.headers = []
self.body = ''
def __init__(self, url):
self.url = url
if not isinstance(url, str):
self.req = url
else:
self.req = None
self.msg = 'OK'
def __call__(self, netloc):
return self
def getcode(self):
return 200
def connect(self):
pass
endheaders = connect
def putrequest(self, method, url):
self.requests.append((method, url))
def putheader(self, name, value):
self.headers.append((name, value))
def send(self, body):
self.body = body
def getresponse(self):
return Response()
class uploadTestCase(PyPIRCCommandTestCase):
def setUp(self):
super(uploadTestCase, self).setUp()
self.old_class = httpclient.HTTPConnection
self.conn = httpclient.HTTPConnection = FakeConnection()
self.old_open = upload_mod.urlopen
upload_mod.urlopen = self._urlopen
self.last_open = None
def tearDown(self):
httpclient.HTTPConnection = self.old_class
upload_mod.urlopen = self.old_open
super(uploadTestCase, self).tearDown()
def _urlopen(self, url):
self.last_open = FakeOpen(url)
return self.last_open
def test_finalize_options(self):
# new format
@ -105,12 +94,13 @@ class uploadTestCase(PyPIRCCommandTestCase):
cmd.run()
# what did we send ?
headers = dict(self.conn.headers)
headers = dict(self.last_open.req.headers)
self.assertEquals(headers['Content-length'], '2087')
self.assert_(headers['Content-type'].startswith('multipart/form-data'))
self.assertEquals(self.conn.requests, [('POST', '/pypi')])
self.assert_((b'xxx') in self.conn.body)
self.assertEquals(self.last_open.req.get_method(), 'POST')
self.assertEquals(self.last_open.req.get_full_url(),
'http://pypi.python.org/pypi')
self.assert_(b'xxx' in self.last_open.req.data)
def test_suite():
return unittest.makeSuite(uploadTestCase)

View File

@ -839,6 +839,9 @@ Core and Builtins
Library
-------
- Issue #6286: Now Distutils upload command is based on urllib2 instead of
httplib, allowing the usage of http_proxy.
- Issue #6287: Added the license field in Distutils documentation.
- Issue #6263: Fixed syntax error in distutils.cygwincompiler.