add support for basic authentication, based on patch #624180

by Phillip J. Eby
This commit is contained in:
Fredrik Lundh 2002-10-22 18:23:00 +00:00
parent 7d428ecc57
commit 1303c7cb16
2 changed files with 51 additions and 12 deletions

View file

@ -28,6 +28,13 @@ URLs and an internal HTTP \class{Transport} instance otherwise. The
optional third argument is an encoding, by default UTF-8. The optional
fourth argument is a debugging flag.
Both the HTTP and HTTPS transports support the URL syntax extension for
HTTP Basic Authorization: \code{http://user:pass@host:port/path}. The
\code{user:pass} portion will be base64-encoded as an HTTP `Authorization'
header, and sent to the remote server as part of the connection process
when invoking an XML-RPC method. You only need to use this if the
remote server requires a Basic Authentication user and password.
The returned instance is a proxy object with methods that can be used
to invoke corresponding RPC calls on the remote server. If the remote
server supports the introspection API, the proxy can also be used to query

View file

@ -43,6 +43,7 @@
# 2002-04-16 fl Added __str__ methods to datetime/binary wrappers
# 2002-05-15 fl Added error constants (from Andrew Kuchling)
# 2002-06-27 fl Merged with Python CVS version
# 2002-10-22 fl Added basic authentication (based on code from Phillip Eby)
#
# Copyright (c) 1999-2002 by Secret Labs AB.
# Copyright (c) 1999-2002 by Fredrik Lundh.
@ -1043,6 +1044,37 @@ def getparser(self):
# get parser and unmarshaller
return getparser()
##
# Get authorization info from host parameter
# Host may be a string, or a (host, x509-dict) tuple; if a string,
# it is checked for a "user:pw@host" format, and a "Basic
# Authentication" header is added if appropriate.
#
# @param host Host descriptor (URL or (URL, x509 info) tuple).
# @return A 3-tuple containing (actual host, extra headers,
# x509 info). The header and x509 fields may be None.
def get_host_info(self, host):
x509 = {}
if isinstance(host, TupleType):
host, x509 = host
import urllib
auth, host = urllib.splituser(host)
if auth:
import base64
auth = base64.encodestring(auth)
auth = string.join(string.split(auth), "") # get rid of whitespace
extra_headers = [
("Authorization", "Basic " + auth)
]
else:
extra_headers = None
return host, extra_headers, x509
##
# Connect to server.
#
@ -1052,6 +1084,7 @@ def getparser(self):
def make_connection(self, host):
# create a HTTP connection object from a host descriptor
import httplib
host, extra_headers, x509 = self.get_host_info(host)
return httplib.HTTP(host)
##
@ -1071,7 +1104,13 @@ def send_request(self, connection, handler, request_body):
# @param host Host name.
def send_host(self, connection, host):
host, extra_headers, x509 = self.get_host_info(host)
connection.putheader("Host", host)
if extra_headers:
if isinstance(extra_headers, DictType):
extra_headers = extra_headers.items()
for key, value in extra_headers:
connection.putheader(key, value)
##
# Send user-agent identifier.
@ -1147,22 +1186,15 @@ def make_connection(self, host):
# create a HTTPS connection object from a host descriptor
# host may be a string, or a (host, x509-dict) tuple
import httplib
if isinstance(host, TupleType):
host, x509 = host
else:
x509 = {}
host, extra_headers, x509 = self.get_host_info(host)
try:
HTTPS = httplib.HTTPS
except AttributeError:
raise NotImplementedError,\
"your version of httplib doesn't support HTTPS"
raise NotImplementedError(
"your version of httplib doesn't support HTTPS"
)
else:
return apply(HTTPS, (host, None), x509)
def send_host(self, connection, host):
if isinstance(host, TupleType):
host, x509 = host
connection.putheader("Host", host)
return apply(HTTPS, (host, None), x509 or {})
##
# Standard server proxy. This class establishes a virtual connection