Path: blob/master/venv/Lib/site-packages/urllib3/request.py
811 views
from __future__ import absolute_import12from .filepost import encode_multipart_formdata3from .packages.six.moves.urllib.parse import urlencode456__all__ = ["RequestMethods"]789class RequestMethods(object):10"""11Convenience mixin for classes who implement a :meth:`urlopen` method, such12as :class:`~urllib3.connectionpool.HTTPConnectionPool` and13:class:`~urllib3.poolmanager.PoolManager`.1415Provides behavior for making common types of HTTP request methods and16decides which type of request field encoding to use.1718Specifically,1920:meth:`.request_encode_url` is for sending requests whose fields are21encoded in the URL (such as GET, HEAD, DELETE).2223:meth:`.request_encode_body` is for sending requests whose fields are24encoded in the *body* of the request using multipart or www-form-urlencoded25(such as for POST, PUT, PATCH).2627:meth:`.request` is for making any kind of request, it will look up the28appropriate encoding format and use one of the above two methods to make29the request.3031Initializer parameters:3233:param headers:34Headers to include with all requests, unless other headers are given35explicitly.36"""3738_encode_url_methods = {"DELETE", "GET", "HEAD", "OPTIONS"}3940def __init__(self, headers=None):41self.headers = headers or {}4243def urlopen(44self,45method,46url,47body=None,48headers=None,49encode_multipart=True,50multipart_boundary=None,51**kw52): # Abstract53raise NotImplementedError(54"Classes extending RequestMethods must implement "55"their own ``urlopen`` method."56)5758def request(self, method, url, fields=None, headers=None, **urlopen_kw):59"""60Make a request using :meth:`urlopen` with the appropriate encoding of61``fields`` based on the ``method`` used.6263This is a convenience method that requires the least amount of manual64effort. It can be used in most situations, while still having the65option to drop down to more specific methods when necessary, such as66:meth:`request_encode_url`, :meth:`request_encode_body`,67or even the lowest level :meth:`urlopen`.68"""69method = method.upper()7071urlopen_kw["request_url"] = url7273if method in self._encode_url_methods:74return self.request_encode_url(75method, url, fields=fields, headers=headers, **urlopen_kw76)77else:78return self.request_encode_body(79method, url, fields=fields, headers=headers, **urlopen_kw80)8182def request_encode_url(self, method, url, fields=None, headers=None, **urlopen_kw):83"""84Make a request using :meth:`urlopen` with the ``fields`` encoded in85the url. This is useful for request methods like GET, HEAD, DELETE, etc.86"""87if headers is None:88headers = self.headers8990extra_kw = {"headers": headers}91extra_kw.update(urlopen_kw)9293if fields:94url += "?" + urlencode(fields)9596return self.urlopen(method, url, **extra_kw)9798def request_encode_body(99self,100method,101url,102fields=None,103headers=None,104encode_multipart=True,105multipart_boundary=None,106**urlopen_kw107):108"""109Make a request using :meth:`urlopen` with the ``fields`` encoded in110the body. This is useful for request methods like POST, PUT, PATCH, etc.111112When ``encode_multipart=True`` (default), then113:meth:`urllib3.filepost.encode_multipart_formdata` is used to encode114the payload with the appropriate content type. Otherwise115:meth:`urllib.urlencode` is used with the116'application/x-www-form-urlencoded' content type.117118Multipart encoding must be used when posting files, and it's reasonably119safe to use it in other times too. However, it may break request120signing, such as with OAuth.121122Supports an optional ``fields`` parameter of key/value strings AND123key/filetuple. A filetuple is a (filename, data, MIME type) tuple where124the MIME type is optional. For example::125126fields = {127'foo': 'bar',128'fakefile': ('foofile.txt', 'contents of foofile'),129'realfile': ('barfile.txt', open('realfile').read()),130'typedfile': ('bazfile.bin', open('bazfile').read(),131'image/jpeg'),132'nonamefile': 'contents of nonamefile field',133}134135When uploading a file, providing a filename (the first parameter of the136tuple) is optional but recommended to best mimic behavior of browsers.137138Note that if ``headers`` are supplied, the 'Content-Type' header will139be overwritten because it depends on the dynamic random boundary string140which is used to compose the body of the request. The random boundary141string can be explicitly set with the ``multipart_boundary`` parameter.142"""143if headers is None:144headers = self.headers145146extra_kw = {"headers": {}}147148if fields:149if "body" in urlopen_kw:150raise TypeError(151"request got values for both 'fields' and 'body', can only specify one."152)153154if encode_multipart:155body, content_type = encode_multipart_formdata(156fields, boundary=multipart_boundary157)158else:159body, content_type = (160urlencode(fields),161"application/x-www-form-urlencoded",162)163164extra_kw["body"] = body165extra_kw["headers"] = {"Content-Type": content_type}166167extra_kw["headers"].update(headers)168extra_kw.update(urlopen_kw)169170return self.urlopen(method, url, **extra_kw)171172173