mirror of
https://github.com/python/cpython.git
synced 2025-12-31 12:33:28 +00:00
Fix closes issue 1673007 urllib.request to support HEAD requests with a new method arg.
This commit is contained in:
parent
d8886fc831
commit
de49d64dbc
5 changed files with 72 additions and 9 deletions
|
|
@ -132,7 +132,7 @@ The :mod:`urllib.request` module defines the following functions:
|
|||
|
||||
The following classes are provided:
|
||||
|
||||
.. class:: Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False)
|
||||
.. class:: Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)
|
||||
|
||||
This class is an abstraction of a URL request.
|
||||
|
||||
|
|
@ -140,8 +140,8 @@ The following classes are provided:
|
|||
|
||||
*data* may be a string specifying additional data to send to the
|
||||
server, or ``None`` if no such data is needed. Currently HTTP
|
||||
requests are the only ones that use *data*; the HTTP request will
|
||||
be a POST instead of a GET when the *data* parameter is provided.
|
||||
requests are the only ones that use *data*, in order to choose between
|
||||
``'GET'`` and ``'POST'`` when *method* is not specified.
|
||||
*data* should be a buffer in the standard
|
||||
:mimetype:`application/x-www-form-urlencoded` format. The
|
||||
:func:`urllib.parse.urlencode` function takes a mapping or sequence
|
||||
|
|
@ -157,8 +157,8 @@ The following classes are provided:
|
|||
:mod:`urllib`'s default user agent string is
|
||||
``"Python-urllib/2.6"`` (on Python 2.6).
|
||||
|
||||
The final two arguments are only of interest for correct handling
|
||||
of third-party HTTP cookies:
|
||||
The following two arguments, *origin_req_host* and *unverifiable*,
|
||||
are only of interest for correct handling of third-party HTTP cookies:
|
||||
|
||||
*origin_req_host* should be the request-host of the origin
|
||||
transaction, as defined by :rfc:`2965`. It defaults to
|
||||
|
|
@ -175,6 +175,13 @@ The following classes are provided:
|
|||
document, and the user had no option to approve the automatic
|
||||
fetching of the image, this should be true.
|
||||
|
||||
*method* should be a string that indicates the HTTP request method that
|
||||
will be used (e.g. ``'HEAD'``). Its value is stored in the
|
||||
:attr:`Request.method` attribute and is used by :meth:`Request.get_method()`.
|
||||
|
||||
.. versionchanged:: 3.3
|
||||
:attr:`Request.method` argument is added to the Request class.
|
||||
|
||||
|
||||
.. class:: OpenerDirector()
|
||||
|
||||
|
|
@ -369,6 +376,15 @@ request.
|
|||
boolean, indicates whether the request is unverifiable as defined
|
||||
by RFC 2965.
|
||||
|
||||
.. attribute:: Request.method
|
||||
|
||||
The HTTP request method to use. This value is used by
|
||||
:meth:`Request.get_method` to override the computed HTTP request
|
||||
method that would otherwise be returned. This attribute is
|
||||
initialized with the value of the *method* argument passed to the constructor.
|
||||
|
||||
..versionadded:: 3.3
|
||||
|
||||
.. method:: Request.add_data(data)
|
||||
|
||||
Set the :class:`Request` data to *data*. This is ignored by all handlers except
|
||||
|
|
@ -378,8 +394,13 @@ request.
|
|||
|
||||
.. method:: Request.get_method()
|
||||
|
||||
Return a string indicating the HTTP request method. This is only meaningful for
|
||||
HTTP requests, and currently always returns ``'GET'`` or ``'POST'``.
|
||||
Return a string indicating the HTTP request method. If
|
||||
:attr:`Request.method` is not ``None``, return its value, otherwise return
|
||||
``'GET'`` if :attr:`Request.data` is ``None``, or ``'POST'`` if it's not.
|
||||
This is only meaningful for HTTP requests.
|
||||
|
||||
.. versionchanged:: 3.3
|
||||
get_method now looks at the value of :attr:`Request.method` first.
|
||||
|
||||
|
||||
.. method:: Request.has_data()
|
||||
|
|
|
|||
|
|
@ -474,6 +474,16 @@ shutil
|
|||
path also specifying the user/group names and not only their numeric
|
||||
ids. (Contributed by Sandro Tosi in :issue:`12191`)
|
||||
|
||||
urllib
|
||||
------
|
||||
|
||||
The :class:`~urllib.request.Request` class, now accepts a *method* argument
|
||||
used by :meth:`~urllib.request.Request.get_method` to determine what HTTP method
|
||||
should be used. For example, this will send an ``'HEAD'`` request::
|
||||
|
||||
>>> urlopen(Request('http://www.python.org', method='HEAD'))
|
||||
|
||||
(:issue:`1673007`)
|
||||
|
||||
Optimizations
|
||||
=============
|
||||
|
|
|
|||
|
|
@ -1157,6 +1157,28 @@ def open_spam(self, url):
|
|||
# self.assertEqual(ftp.ftp.sock.gettimeout(), 30)
|
||||
# ftp.close()
|
||||
|
||||
class RequestTests(unittest.TestCase):
|
||||
"""Unit tests for urllib.request.Request."""
|
||||
|
||||
def test_default_values(self):
|
||||
Request = urllib.request.Request
|
||||
request = Request("http://www.python.org")
|
||||
self.assertEqual(request.get_method(), 'GET')
|
||||
request = Request("http://www.python.org", {})
|
||||
self.assertEqual(request.get_method(), 'POST')
|
||||
|
||||
def test_with_method_arg(self):
|
||||
Request = urllib.request.Request
|
||||
request = Request("http://www.python.org", method='HEAD')
|
||||
self.assertEqual(request.method, 'HEAD')
|
||||
self.assertEqual(request.get_method(), 'HEAD')
|
||||
request = Request("http://www.python.org", {}, method='HEAD')
|
||||
self.assertEqual(request.method, 'HEAD')
|
||||
self.assertEqual(request.get_method(), 'HEAD')
|
||||
request = Request("http://www.python.org", method='GET')
|
||||
self.assertEqual(request.get_method(), 'GET')
|
||||
request.method = 'HEAD'
|
||||
self.assertEqual(request.get_method(), 'HEAD')
|
||||
|
||||
|
||||
def test_main():
|
||||
|
|
@ -1172,6 +1194,7 @@ def test_main():
|
|||
Utility_Tests,
|
||||
URLopener_Tests,
|
||||
#FTPWrapperTests,
|
||||
RequestTests,
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -177,7 +177,8 @@ def request_host(request):
|
|||
class Request:
|
||||
|
||||
def __init__(self, url, data=None, headers={},
|
||||
origin_req_host=None, unverifiable=False):
|
||||
origin_req_host=None, unverifiable=False,
|
||||
method=None):
|
||||
# unwrap('<URL:type://host/path>') --> 'type://host/path'
|
||||
self.full_url = unwrap(url)
|
||||
self.full_url, self.fragment = splittag(self.full_url)
|
||||
|
|
@ -191,6 +192,7 @@ def __init__(self, url, data=None, headers={},
|
|||
origin_req_host = request_host(self)
|
||||
self.origin_req_host = origin_req_host
|
||||
self.unverifiable = unverifiable
|
||||
self.method = method
|
||||
self._parse()
|
||||
|
||||
def _parse(self):
|
||||
|
|
@ -202,7 +204,10 @@ def _parse(self):
|
|||
self.host = unquote(self.host)
|
||||
|
||||
def get_method(self):
|
||||
if self.data is not None:
|
||||
"""Return a string indicating the HTTP request method."""
|
||||
if self.method is not None:
|
||||
return self.method
|
||||
elif self.data is not None:
|
||||
return "POST"
|
||||
else:
|
||||
return "GET"
|
||||
|
|
|
|||
|
|
@ -304,6 +304,10 @@ Core and Builtins
|
|||
|
||||
Library
|
||||
-------
|
||||
|
||||
- issue #1673007: urllib2 to support HEAD request via new method argument.
|
||||
Patch contributions by David Stanek, Patrick Westerhoff and Ezio Melotti.
|
||||
|
||||
- Issue #12386: packaging does not fail anymore when writing the RESOURCES
|
||||
file.
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue