From c65a5343edc221bfebf620055a7430a662622e2f Mon Sep 17 00:00:00 2001 From: Yichao Yu Date: Sun, 5 Sep 2021 16:23:26 -0400 Subject: [PATCH] httpclient: Support arbitrary request body The body will be supplied as a string. This is the only method I can find that is supported by all the backends as well as the config file. Make sure all the backends have the same default content types. --- nvchecker/httpclient/aiohttp_httpclient.py | 9 ++++++++- nvchecker/httpclient/base.py | 3 +++ nvchecker/httpclient/httpx_httpclient.py | 8 +++++++- nvchecker/httpclient/tornado_httpclient.py | 6 +++++- 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/nvchecker/httpclient/aiohttp_httpclient.py b/nvchecker/httpclient/aiohttp_httpclient.py index a122571..6af4b0f 100644 --- a/nvchecker/httpclient/aiohttp_httpclient.py +++ b/nvchecker/httpclient/aiohttp_httpclient.py @@ -35,6 +35,7 @@ class AiohttpSession(BaseSession): follow_redirects: bool = True, params = (), json = None, + body = None, verify_cert: bool = True, ) -> Response: kwargs = { @@ -47,7 +48,13 @@ class AiohttpSession(BaseSession): if proxy is not None: kwargs['proxy'] = proxy - if json is not None: + if body is not None: + # Make sure all backends have the same default encoding for post data. + if 'Content-Type' not in headers: + headers = {**headers, 'Content-Type': 'application/x-www-form-urlencoded'} + kwargs['headers'] = headers + kwargs['data'] = body.encode() + elif json is not None: kwargs['json'] = json try: diff --git a/nvchecker/httpclient/base.py b/nvchecker/httpclient/base.py index b9e2101..ae861f9 100644 --- a/nvchecker/httpclient/base.py +++ b/nvchecker/httpclient/base.py @@ -61,6 +61,7 @@ class BaseSession: follow_redirects: bool = True, params = (), json = None, + body = None, ) -> Response: t = tries.get() p = proxy.get() @@ -82,6 +83,7 @@ class BaseSession: params = params, follow_redirects = follow_redirects, json = json, + body = body, proxy = p or None, verify_cert = verify, ) @@ -103,6 +105,7 @@ class BaseSession: follow_redirects: bool = True, params = (), json = None, + body = None, verify_cert: bool = True, ) -> Response: ''':meta private:''' diff --git a/nvchecker/httpclient/httpx_httpclient.py b/nvchecker/httpclient/httpx_httpclient.py index 7cf2345..3a17fb3 100644 --- a/nvchecker/httpclient/httpx_httpclient.py +++ b/nvchecker/httpclient/httpx_httpclient.py @@ -27,6 +27,7 @@ class HttpxSession(BaseSession): follow_redirects: bool = True, params = (), json = None, + body = None, verify_cert: bool = True, ) -> Response: client = self.clients.get((proxy, verify_cert)) @@ -40,8 +41,13 @@ class HttpxSession(BaseSession): self.clients[(proxy, verify_cert)] = client try: + if body is not None: + # Make sure all backends have the same default encoding for post data. + if 'Content-Type' not in headers: + headers = {**headers, 'Content-Type': 'application/x-www-form-urlencoded'} + body = body.encode() r = await client.request( - method, url, json = json, + method, url, json = json, content = body, headers = headers, allow_redirects = follow_redirects, params = params, diff --git a/nvchecker/httpclient/tornado_httpclient.py b/nvchecker/httpclient/tornado_httpclient.py index 6d5240c..ce813ff 100644 --- a/nvchecker/httpclient/tornado_httpclient.py +++ b/nvchecker/httpclient/tornado_httpclient.py @@ -52,6 +52,7 @@ class TornadoSession(BaseSession): follow_redirects: bool = True, params = (), json = None, + body = None, verify_cert: bool = True, ) -> Response: kwargs: Dict[str, Any] = { @@ -62,7 +63,10 @@ class TornadoSession(BaseSession): 'validate_cert': verify_cert, } - if json: + if body: + # By default the content type is already 'application/x-www-form-urlencoded' + kwargs['body'] = body + elif json: kwargs['body'] = _json.dumps(json) kwargs['prepare_curl_callback'] = try_use_http2