Kaydet (Commit) 023518a6 authored tarafından Jeremy Hylton's avatar Jeremy Hylton

Rewrite AbstractHTTPHandler to use modern httplib interface.

The chief benefit of this change is that requests will now use
HTTP/1.1 instead of HTTP/1.0.  Bump the module version number as part
of the change.

There are two possible incompatibilities that we'll need to watch out
for when we get to an alpha release.  We may get a different class of
exceptions out of httplib, and the do_open() method changed its
signature.  The latter is only important if anyone actually subclasses
AbstractHTTPHandler.
üst a7b673f4
...@@ -120,7 +120,7 @@ from urllib import unwrap, unquote, splittype, splithost, \ ...@@ -120,7 +120,7 @@ from urllib import unwrap, unquote, splittype, splithost, \
# support for FileHandler, proxies via environment variables # support for FileHandler, proxies via environment variables
from urllib import localhost, url2pathname, getproxies from urllib import localhost, url2pathname, getproxies
__version__ = "2.1" __version__ = "2.4"
_opener = None _opener = None
def urlopen(url, data=None): def urlopen(url, data=None):
...@@ -207,6 +207,8 @@ class Request: ...@@ -207,6 +207,8 @@ class Request:
else: else:
return "GET" return "GET"
# XXX these helper methods are lame
def add_data(self, data): def add_data(self, data):
self.data = data self.data = data
...@@ -936,10 +938,16 @@ class AbstractHTTPHandler(BaseHandler): ...@@ -936,10 +938,16 @@ class AbstractHTTPHandler(BaseHandler):
return request return request
# XXX Should rewrite do_open() to use the new httplib interface,
# would be a little simpler.
def do_open(self, http_class, req): def do_open(self, http_class, req):
"""Return an addinfourl object for the request, using http_class.
http_class must implement the HTTPConnection API from httplib.
The addinfourl return value is a file-like object. It also
has methods and attributes including:
- info(): return a mimetools.Message object for the headers
- geturl(): return the original request URL
- code: HTTP status code
"""
host = req.get_host() host = req.get_host()
if not host: if not host:
raise URLError('no host given') raise URLError('no host given')
...@@ -947,33 +955,26 @@ class AbstractHTTPHandler(BaseHandler): ...@@ -947,33 +955,26 @@ class AbstractHTTPHandler(BaseHandler):
h = http_class(host) # will parse host:port h = http_class(host) # will parse host:port
h.set_debuglevel(self._debuglevel) h.set_debuglevel(self._debuglevel)
h.putrequest(req.get_method(), req.get_selector()) headers = dict(req.headers)
for k, v in req.headers.items(): headers.update(req.unredirected_hdrs)
h.putheader(k, v)
for k, v in req.unredirected_hdrs.items():
h.putheader(k, v)
# httplib will attempt to connect() here. be prepared
# to convert a socket error to a URLError.
try: try:
h.endheaders() h.request(req.get_method(), req.get_selector(), req.data, headers)
except socket.error, err: r = h.getresponse()
except socket.error, err: # XXX what error?
raise URLError(err) raise URLError(err)
if req.has_data():
h.send(req.get_data()) # Pick apart the HTTPResponse object to get the various pieces
# of the
code, msg, hdrs = h.getreply() resp = addinfourl(r.fp, r.msg, req.get_full_url())
fp = h.getfile() resp.code = r.status
response = addinfourl(fp, hdrs, req.get_full_url()) resp.msg = r.reason
# XXXX should these be methods, for uniformity with rest of interface? return resp
response.code = code
response.msg = msg
return response
class HTTPHandler(AbstractHTTPHandler): class HTTPHandler(AbstractHTTPHandler):
def http_open(self, req): def http_open(self, req):
return self.do_open(httplib.HTTP, req) return self.do_open(httplib.HTTPConnection, req)
http_request = AbstractHTTPHandler.do_request http_request = AbstractHTTPHandler.do_request
...@@ -981,7 +982,7 @@ if hasattr(httplib, 'HTTPS'): ...@@ -981,7 +982,7 @@ if hasattr(httplib, 'HTTPS'):
class HTTPSHandler(AbstractHTTPHandler): class HTTPSHandler(AbstractHTTPHandler):
def https_open(self, req): def https_open(self, req):
return self.do_open(httplib.HTTPS, req) return self.do_open(httplib.HTTPSConnection, req)
https_request = AbstractHTTPHandler.do_request https_request = AbstractHTTPHandler.do_request
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment