def post_to_server(self, data, auth=None): ''' Post a query to the server, and return a string response. ''' if 'name' in data: logger.info('Registering %s to %s', data['name'], self.repository) # Build up the MIME payload for the urllib2 POST data content_type, body = encode_multipart(data.items(), []) # build the Request headers = { 'Content-type': content_type, 'Content-length': str(len(body)) } req = urllib2.Request(self.repository, body, headers) # handle HTTP and include the Basic Auth handler opener = urllib2.build_opener( urllib2.HTTPBasicAuthHandler(password_mgr=auth) ) data = '' try: result = opener.open(req) except urllib2.HTTPError, e: if self.show_response: data = e.fp.read() result = e.code, e.msg
def run(self): name = self.distribution.metadata['Name'] version = self.distribution.metadata['Version'] zip_file = zip_dir(self.upload_dir) fields = [(':action', 'doc_upload'), ('name', name), ('version', version)] files = [('content', name, zip_file.getvalue())] content_type, body = encode_multipart(fields, files) credentials = self.username + ':' + self.password # FIXME should use explicit encoding auth = b"Basic " + base64.encodebytes(credentials.encode()).strip() logger.info("Submitting documentation to %s", self.repository) scheme, netloc, url, params, query, fragments = urllib.parse.urlparse( self.repository) if scheme == "http": conn = http.client.HTTPConnection(netloc) elif scheme == "https": conn = http.client.HTTPSConnection(netloc) else: raise AssertionError("unsupported scheme %r" % scheme) try: conn.connect() conn.putrequest("POST", url) conn.putheader('Content-type', content_type) conn.putheader('Content-length', str(len(body))) conn.putheader('Authorization', auth) conn.endheaders() conn.send(body) except socket.error as e: logger.error(e) return r = conn.getresponse() if r.status == 200: logger.info('Server response (%s): %s', r.status, r.reason) elif r.status == 301: location = r.getheader('Location') if location is None: location = 'http://packages.python.org/%s/' % name logger.info('Upload successful. Visit %s', location) else: logger.error('Upload failed (%s): %s', r.status, r.reason) if self.show_response and logger.isEnabledFor(logging.INFO): sep = '-' * 75 logger.info('%s\n%s\n%s', sep, r.read().decode('utf-8'), sep)
def run(self): name = self.distribution.metadata['Name'] version = self.distribution.metadata['Version'] zip_file = zip_dir(self.upload_dir) fields = [(':action', 'doc_upload'), ('name', name), ('version', version)] files = [('content', name, zip_file.getvalue())] content_type, body = encode_multipart(fields, files) credentials = self.username + ':' + self.password # FIXME should use explicit encoding auth = "Basic " + base64.encodestring(credentials.encode()).strip() logger.info("Submitting documentation to %s", self.repository) scheme, netloc, url, params, query, fragments = urlparse.urlparse( self.repository) if scheme == "http": conn = httplib.HTTPConnection(netloc) elif scheme == "https": conn = httplib.HTTPSConnection(netloc) else: raise AssertionError("unsupported scheme %r" % scheme) try: conn.connect() conn.putrequest("POST", url) conn.putheader('Content-type', content_type) conn.putheader('Content-length', str(len(body))) conn.putheader('Authorization', auth) conn.endheaders() conn.send(body) except socket.error, e: logger.error(e) return
def post_to_server(self, data, auth=None): ''' Post a query to the server, and return a string response. ''' if 'name' in data: logger.info('Registering %s to %s', data['name'], self.repository) # Build up the MIME payload for the urllib2 POST data content_type, body = encode_multipart(data.items(), []) # build the Request headers = { 'Content-type': content_type, 'Content-length': str(len(body)) } req = urllib.request.Request(self.repository, body, headers) # handle HTTP and include the Basic Auth handler opener = urllib.request.build_opener( urllib.request.HTTPBasicAuthHandler(password_mgr=auth)) data = '' try: result = opener.open(req) except urllib.error.HTTPError as e: if self.show_response: data = e.fp.read() result = e.code, e.msg except urllib.error.URLError as e: result = 500, str(e) else: if self.show_response: data = result.read() result = 200, 'OK' if self.show_response: dashes = '-' * 75 logger.info('%s%s%s', dashes, data, dashes) return result
def upload_file(self, command, pyversion, filename): # Makes sure the repository URL is compliant scheme, netloc, url, params, query, fragments = \ urllib.parse.urlparse(self.repository) if params or query or fragments: raise AssertionError("Incompatible url %s" % self.repository) if scheme not in ('http', 'https'): raise AssertionError("unsupported scheme " + scheme) # Sign if requested if self.sign: gpg_args = ["gpg", "--detach-sign", "-a", filename] if self.identity: gpg_args[2:2] = ["--local-user", self.identity] spawn(gpg_args, dry_run=self.dry_run) # Fill in the data - send all the metadata in case we need to # register a new release with open(filename, 'rb') as f: content = f.read() data = self.distribution.metadata.todict() # extra upload infos data[':action'] = 'file_upload' data['protcol_version'] = '1' data['content'] = (os.path.basename(filename), content) data['filetype'] = command data['pyversion'] = pyversion data['md5_digest'] = md5(content).hexdigest() if command == 'bdist_dumb': data['comment'] = 'built for %s' % platform.platform(terse=True) if self.sign: with open(filename + '.asc') as fp: sig = fp.read() data['gpg_signature'] = [ (os.path.basename(filename) + ".asc", sig)] # set up the authentication # The exact encoding of the authentication string is debated. # Anyway PyPI only accepts ascii for both username or password. user_pass = (self.username + ":" + self.password).encode('ascii') auth = b"Basic " + standard_b64encode(user_pass) # Build up the MIME payload for the POST data files = [] for key in ('content', 'gpg_signature'): if key in data: filename_, value = data.pop(key) files.append((key, filename_, value)) content_type, body = encode_multipart(data.items(), files) logger.info("Submitting %s to %s", filename, self.repository) # build the Request headers = {'Content-type': content_type, 'Content-length': str(len(body)), 'Authorization': auth} request = Request(self.repository, body, headers) # send the data try: result = urlopen(request) status = result.code reason = result.msg except socket.error as e: logger.error(e) return except HTTPError as e: status = e.code reason = e.msg if status == 200: logger.info('Server response (%s): %s', status, reason) else: logger.error('Upload failed (%s): %s', status, reason) if self.show_response and logger.isEnabledFor(logging.INFO): sep = '-' * 75 logger.info('%s\n%s\n%s', sep, result.read().decode(), sep)
def upload_file(self, command, pyversion, filename): # Makes sure the repository URL is compliant scheme, netloc, url, params, query, fragments = \ urlparse.urlparse(self.repository) if params or query or fragments: raise AssertionError("Incompatible url %s" % self.repository) if scheme not in ('http', 'https'): raise AssertionError("unsupported scheme " + scheme) # Sign if requested if self.sign: gpg_args = ["gpg", "--detach-sign", "-a", filename] if self.identity: gpg_args[2:2] = ["--local-user", self.identity] spawn(gpg_args, dry_run=self.dry_run) # Fill in the data - send all the metadata in case we need to # register a new release f = open(filename, 'rb') try: content = f.read() finally: f.close() data = self.distribution.metadata.todict() # extra upload infos data[':action'] = 'file_upload' data['protcol_version'] = '1' data['content'] = (os.path.basename(filename), content) data['filetype'] = command data['pyversion'] = pyversion data['md5_digest'] = md5(content).hexdigest() if command == 'bdist_dumb': data['comment'] = 'built for %s' % platform.platform(terse=True) if self.sign: fp = open(filename + '.asc') try: sig = fp.read() finally: fp.close() data['gpg_signature'] = [ (os.path.basename(filename) + ".asc", sig)] # set up the authentication # The exact encoding of the authentication string is debated. # Anyway PyPI only accepts ascii for both username or password. user_pass = (self.username + ":" + self.password).encode('ascii') auth = "Basic " + standard_b64encode(user_pass) # Build up the MIME payload for the POST data files = [] for key in ('content', 'gpg_signature'): if key in data: filename_, value = data.pop(key) files.append((key, filename_, value)) content_type, body = encode_multipart(data.items(), files) logger.info("Submitting %s to %s", filename, self.repository) # build the Request headers = {'Content-type': content_type, 'Content-length': str(len(body)), 'Authorization': auth} request = Request(self.repository, body, headers) # send the data try: result = urlopen(request) status = result.code reason = result.msg except socket.error, e: logger.error(e) return
def test_encode_multipart(self): fields = [('username', 'wok'), ('password', 'secret')] files = [('picture', 'wok.png', 'PNG89')] content_type, body = encode_multipart(fields, files, '-x') self.assertEqual('multipart/form-data; boundary=-x', content_type) self.assertEqual(EXPECTED_MULTIPART_OUTPUT, body.split('\r\n'))