reverted distutils its 3.1 state. All new work is now happening in disutils2, and distutils is now feature-frozen.
diff --git a/Lib/distutils/command/upload.py b/Lib/distutils/command/upload.py
index bb1b7fc..f602fbe 100644
--- a/Lib/distutils/command/upload.py
+++ b/Lib/distutils/command/upload.py
@@ -1,19 +1,25 @@
 """distutils.command.upload
 
 Implements the Distutils 'upload' subcommand (upload package to PyPI)."""
-import os
-import io
-import socket
-import platform
-from urllib.request import urlopen, Request, HTTPError
-from base64 import standard_b64encode
-from urllib.parse import urlparse
-from hashlib import md5
 
-from distutils.errors import DistutilsOptionError
+from distutils.errors import *
 from distutils.core import PyPIRCCommand
 from distutils.spawn import spawn
 from distutils import log
+import sys
+import os, io
+import socket
+import platform
+import configparser
+import http.client as httpclient
+from base64 import standard_b64encode
+import urllib.parse
+
+# this keeps compatibility for 2.3 and 2.4
+if sys.version < "2.5":
+    from md5 import md5
+else:
+    from hashlib import md5
 
 class upload(PyPIRCCommand):
 
@@ -60,15 +66,6 @@
             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]
@@ -140,10 +137,10 @@
         for key, value in data.items():
             title = '\nContent-Disposition: form-data; name="%s"' % key
             # handle multiple entries for the same name
-            if not isinstance(value, list):
+            if type(value) != type([]):
                 value = [value]
             for value in value:
-                if isinstance(value, tuple):
+                if type(value) is tuple:
                     title += '; filename="%s"' % value[0]
                     value = value[1]
                 else:
@@ -161,30 +158,40 @@
         self.announce("Submitting %s to %s" % (filename, self.repository), log.INFO)
 
         # build the Request
-        headers = {'Content-type':
-                        'multipart/form-data; boundary=%s' % boundary,
-                   'Content-length': str(len(body)),
-                   'Authorization': auth}
+        # 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)
 
-        request = Request(self.repository, data=body,
-                          headers=headers)
-        # send the data
+        data = ''
+        loglevel = log.INFO
         try:
-            result = urlopen(request)
-            status = result.getcode()
-            reason = result.msg
+            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)
         except socket.error as e:
             self.announce(str(e), log.ERROR)
             return
-        except HTTPError as e:
-            status = e.code
-            reason = e.msg
 
-        if status == 200:
-            self.announce('Server response (%s): %s' % (status, reason),
+        r = http.getresponse()
+        if r.status == 200:
+            self.announce('Server response (%s): %s' % (r.status, r.reason),
                           log.INFO)
         else:
-            self.announce('Upload failed (%s): %s' % (status, reason),
+            self.announce('Upload failed (%s): %s' % (r.status, r.reason),
                           log.ERROR)
         if self.show_response:
-            self.announce('-'*75, result.read(), '-'*75)
+            self.announce('-'*75, r.read(), '-'*75)