openmedialibrary_platform/Shared/lib/python3.4/site-packages/urllib3/request.py

151 lines
5.9 KiB
Python
Raw Normal View History

2016-02-23 06:06:55 +00:00
from __future__ import absolute_import
2013-10-11 17:28:32 +00:00
from .filepost import encode_multipart_formdata
2019-01-13 08:01:53 +00:00
from .packages.six.moves.urllib.parse import urlencode
2013-10-11 17:28:32 +00:00
__all__ = ['RequestMethods']
class RequestMethods(object):
"""
Convenience mixin for classes who implement a :meth:`urlopen` method, such
as :class:`~urllib3.connectionpool.HTTPConnectionPool` and
:class:`~urllib3.poolmanager.PoolManager`.
Provides behavior for making common types of HTTP request methods and
decides which type of request field encoding to use.
Specifically,
2016-02-23 06:06:55 +00:00
:meth:`.request_encode_url` is for sending requests whose fields are
encoded in the URL (such as GET, HEAD, DELETE).
2013-10-11 17:28:32 +00:00
:meth:`.request_encode_body` is for sending requests whose fields are
encoded in the *body* of the request using multipart or www-form-urlencoded
(such as for POST, PUT, PATCH).
:meth:`.request` is for making any kind of request, it will look up the
appropriate encoding format and use one of the above two methods to make
the request.
Initializer parameters:
:param headers:
Headers to include with all requests, unless other headers are given
explicitly.
"""
2019-01-13 08:01:53 +00:00
_encode_url_methods = {'DELETE', 'GET', 'HEAD', 'OPTIONS'}
2013-10-11 17:28:32 +00:00
def __init__(self, headers=None):
self.headers = headers or {}
def urlopen(self, method, url, body=None, headers=None,
encode_multipart=True, multipart_boundary=None,
2016-02-23 06:06:55 +00:00
**kw): # Abstract
2019-01-13 08:01:53 +00:00
raise NotImplementedError("Classes extending RequestMethods must implement "
"their own ``urlopen`` method.")
2013-10-11 17:28:32 +00:00
def request(self, method, url, fields=None, headers=None, **urlopen_kw):
"""
Make a request using :meth:`urlopen` with the appropriate encoding of
``fields`` based on the ``method`` used.
This is a convenience method that requires the least amount of manual
2016-02-23 06:06:55 +00:00
effort. It can be used in most situations, while still having the
option to drop down to more specific methods when necessary, such as
2013-10-11 17:28:32 +00:00
:meth:`request_encode_url`, :meth:`request_encode_body`,
or even the lowest level :meth:`urlopen`.
"""
method = method.upper()
2019-01-13 08:01:53 +00:00
urlopen_kw['request_url'] = url
2013-10-11 17:28:32 +00:00
if method in self._encode_url_methods:
return self.request_encode_url(method, url, fields=fields,
2016-02-23 06:06:55 +00:00
headers=headers,
**urlopen_kw)
2013-10-11 17:28:32 +00:00
else:
return self.request_encode_body(method, url, fields=fields,
2016-02-23 06:06:55 +00:00
headers=headers,
**urlopen_kw)
2013-10-11 17:28:32 +00:00
2016-02-23 06:06:55 +00:00
def request_encode_url(self, method, url, fields=None, headers=None,
**urlopen_kw):
2013-10-11 17:28:32 +00:00
"""
Make a request using :meth:`urlopen` with the ``fields`` encoded in
the url. This is useful for request methods like GET, HEAD, DELETE, etc.
"""
2016-02-23 06:06:55 +00:00
if headers is None:
headers = self.headers
extra_kw = {'headers': headers}
extra_kw.update(urlopen_kw)
2013-10-11 17:28:32 +00:00
if fields:
url += '?' + urlencode(fields)
2016-02-23 06:06:55 +00:00
return self.urlopen(method, url, **extra_kw)
2013-10-11 17:28:32 +00:00
def request_encode_body(self, method, url, fields=None, headers=None,
encode_multipart=True, multipart_boundary=None,
**urlopen_kw):
"""
Make a request using :meth:`urlopen` with the ``fields`` encoded in
the body. This is useful for request methods like POST, PUT, PATCH, etc.
When ``encode_multipart=True`` (default), then
2016-02-23 06:06:55 +00:00
:meth:`urllib3.filepost.encode_multipart_formdata` is used to encode
the payload with the appropriate content type. Otherwise
2013-10-11 17:28:32 +00:00
:meth:`urllib.urlencode` is used with the
'application/x-www-form-urlencoded' content type.
Multipart encoding must be used when posting files, and it's reasonably
2016-02-23 06:06:55 +00:00
safe to use it in other times too. However, it may break request
signing, such as with OAuth.
2013-10-11 17:28:32 +00:00
Supports an optional ``fields`` parameter of key/value strings AND
key/filetuple. A filetuple is a (filename, data, MIME type) tuple where
2016-02-23 06:06:55 +00:00
the MIME type is optional. For example::
2013-10-11 17:28:32 +00:00
fields = {
'foo': 'bar',
'fakefile': ('foofile.txt', 'contents of foofile'),
'realfile': ('barfile.txt', open('realfile').read()),
'typedfile': ('bazfile.bin', open('bazfile').read(),
'image/jpeg'),
'nonamefile': 'contents of nonamefile field',
}
When uploading a file, providing a filename (the first parameter of the
2019-01-13 08:01:53 +00:00
tuple) is optional but recommended to best mimic behavior of browsers.
2013-10-11 17:28:32 +00:00
2016-02-23 06:06:55 +00:00
Note that if ``headers`` are supplied, the 'Content-Type' header will
be overwritten because it depends on the dynamic random boundary string
2013-10-11 17:28:32 +00:00
which is used to compose the body of the request. The random boundary
string can be explicitly set with the ``multipart_boundary`` parameter.
"""
if headers is None:
headers = self.headers
2016-02-23 06:06:55 +00:00
extra_kw = {'headers': {}}
if fields:
if 'body' in urlopen_kw:
raise TypeError(
"request got values for both 'fields' and 'body', can only specify one.")
if encode_multipart:
body, content_type = encode_multipart_formdata(fields, boundary=multipart_boundary)
else:
body, content_type = urlencode(fields), 'application/x-www-form-urlencoded'
extra_kw['body'] = body
extra_kw['headers'] = {'Content-Type': content_type}
extra_kw['headers'].update(headers)
extra_kw.update(urlopen_kw)
2013-10-11 17:28:32 +00:00
2016-02-23 06:06:55 +00:00
return self.urlopen(method, url, **extra_kw)