mirror of
https://github.com/httprunner/httprunner.git
synced 2026-09-05 07:26:55 +08:00
bugfix: POST content-type is application/x-www-form-urlencoded
This commit is contained in:
+16
-6
@@ -14,6 +14,7 @@ import time
|
|||||||
|
|
||||||
from httprunner.compat import basestring, builtin_str, integer_types, str
|
from httprunner.compat import basestring, builtin_str, integer_types, str
|
||||||
from httprunner.exceptions import ParamsError
|
from httprunner.exceptions import ParamsError
|
||||||
|
from httprunner.utils import convert_dict_to_params, lower_dict_keys
|
||||||
from requests_toolbelt import MultipartEncoder
|
from requests_toolbelt import MultipartEncoder
|
||||||
|
|
||||||
|
|
||||||
@@ -134,14 +135,23 @@ def endswith(check_value, expect_value):
|
|||||||
"""
|
"""
|
||||||
def setup_hook_prepare_kwargs(request):
|
def setup_hook_prepare_kwargs(request):
|
||||||
if request["method"] == "POST":
|
if request["method"] == "POST":
|
||||||
content_type = request.get("headers", {}).get("content-type")
|
req_headers = lower_dict_keys(request.get("headers", {}))
|
||||||
|
content_type = req_headers.get("content-type")
|
||||||
if content_type and "data" in request:
|
if content_type and "data" in request:
|
||||||
# if request content-type is application/json, request data should be dumped
|
req_data = request["data"]
|
||||||
if content_type.startswith("application/json") and isinstance(request["data"], (dict, list)):
|
|
||||||
request["data"] = json.dumps(request["data"])
|
|
||||||
|
|
||||||
if isinstance(request["data"], str):
|
# if request content-type is application/json, request data should be dumped
|
||||||
request["data"] = request["data"].encode('utf-8')
|
if content_type.startswith("application/json") and isinstance(req_data, (dict, list)):
|
||||||
|
req_data = json.dumps(req_data)
|
||||||
|
|
||||||
|
# if request content-type is application/x-www-form-urlencoded, request data should be in params format
|
||||||
|
elif content_type.startswith("application/x-www-form-urlencoded") and isinstance(req_data, dict):
|
||||||
|
req_data = convert_dict_to_params(req_data)
|
||||||
|
|
||||||
|
if isinstance(req_data, str):
|
||||||
|
req_data = req_data.encode('utf-8')
|
||||||
|
|
||||||
|
request["data"] = req_data
|
||||||
|
|
||||||
def sleep_N_secs(n_secs):
|
def sleep_N_secs(n_secs):
|
||||||
""" sleep n seconds
|
""" sleep n seconds
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import time
|
|||||||
import requests
|
import requests
|
||||||
import urllib3
|
import urllib3
|
||||||
from httprunner import logger
|
from httprunner import logger
|
||||||
from httprunner.utils import build_url
|
from httprunner.utils import build_url, lower_dict_keys
|
||||||
from requests import Request, Response
|
from requests import Request, Response
|
||||||
from requests.exceptions import (InvalidSchema, InvalidURL, MissingSchema,
|
from requests.exceptions import (InvalidSchema, InvalidURL, MissingSchema,
|
||||||
RequestException)
|
RequestException)
|
||||||
@@ -138,11 +138,13 @@ class HttpSession(requests.Session):
|
|||||||
self.meta_data["response"]["url"] = response.url
|
self.meta_data["response"]["url"] = response.url
|
||||||
self.meta_data["response"]["status_code"] = response.status_code
|
self.meta_data["response"]["status_code"] = response.status_code
|
||||||
self.meta_data["response"]["reason"] = response.reason
|
self.meta_data["response"]["reason"] = response.reason
|
||||||
self.meta_data["response"]["headers"] = dict(response.headers)
|
|
||||||
self.meta_data["response"]["cookies"] = response.cookies or {}
|
self.meta_data["response"]["cookies"] = response.cookies or {}
|
||||||
self.meta_data["response"]["encoding"] = response.encoding
|
self.meta_data["response"]["encoding"] = response.encoding
|
||||||
|
resp_headers = dict(response.headers)
|
||||||
|
self.meta_data["response"]["headers"] = resp_headers
|
||||||
|
|
||||||
content_type = response.headers.get("Content-Type", "")
|
lower_resp_headers = lower_dict_keys(resp_headers)
|
||||||
|
content_type = lower_resp_headers.get("content-type", "")
|
||||||
self.meta_data["response"]["content_type"] = content_type
|
self.meta_data["response"]["content_type"] = content_type
|
||||||
|
|
||||||
if "image" in content_type:
|
if "image" in content_type:
|
||||||
|
|||||||
@@ -152,6 +152,7 @@ def get_uniform_comparator(comparator):
|
|||||||
else:
|
else:
|
||||||
return comparator
|
return comparator
|
||||||
|
|
||||||
|
|
||||||
def deep_update_dict(origin_dict, override_dict):
|
def deep_update_dict(origin_dict, override_dict):
|
||||||
""" update origin dict with override dict recursively
|
""" update origin dict with override dict recursively
|
||||||
e.g. origin_dict = {'a': 1, 'b': {'c': 2, 'd': 4}}
|
e.g. origin_dict = {'a': 1, 'b': {'c': 2, 'd': 4}}
|
||||||
@@ -173,6 +174,31 @@ def deep_update_dict(origin_dict, override_dict):
|
|||||||
|
|
||||||
return origin_dict
|
return origin_dict
|
||||||
|
|
||||||
|
|
||||||
|
def convert_dict_to_params(src_dict):
|
||||||
|
""" convert dict to params string
|
||||||
|
|
||||||
|
Args:
|
||||||
|
src_dict (dict): source mapping data structure
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: string params data
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
>>> src_dict = {
|
||||||
|
"a": 1,
|
||||||
|
"b": 2
|
||||||
|
}
|
||||||
|
>>> convert_dict_to_params(src_dict)
|
||||||
|
>>> "a=1&b=2"
|
||||||
|
|
||||||
|
"""
|
||||||
|
return "&".join([
|
||||||
|
"{}={}".format(key, value)
|
||||||
|
for key, value in src_dict.items()
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
def lower_dict_keys(origin_dict):
|
def lower_dict_keys(origin_dict):
|
||||||
""" convert keys in dict to lower case
|
""" convert keys in dict to lower case
|
||||||
|
|
||||||
@@ -210,6 +236,7 @@ def lower_dict_keys(origin_dict):
|
|||||||
for key, value in origin_dict.items()
|
for key, value in origin_dict.items()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def lower_test_dict_keys(test_dict):
|
def lower_test_dict_keys(test_dict):
|
||||||
""" convert keys in test_dict to lower case, convertion will occur in two places:
|
""" convert keys in test_dict to lower case, convertion will occur in two places:
|
||||||
1, all keys in test_dict;
|
1, all keys in test_dict;
|
||||||
|
|||||||
@@ -70,3 +70,21 @@ class TestHttpClient(ApiServerUnittest):
|
|||||||
}
|
}
|
||||||
setup_hook_prepare_kwargs(request)
|
setup_hook_prepare_kwargs(request)
|
||||||
self.assertIsInstance(request["data"], bytes)
|
self.assertIsInstance(request["data"], bytes)
|
||||||
|
|
||||||
|
def test_prepare_kwargs_content_type_x_www_form_urlencoded(self):
|
||||||
|
request = {
|
||||||
|
"url": "/path",
|
||||||
|
"method": "POST",
|
||||||
|
"headers": {
|
||||||
|
"content-type": "application/x-www-form-urlencoded; charset=utf-8"
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"a": 1,
|
||||||
|
"b": 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setup_hook_prepare_kwargs(request)
|
||||||
|
self.assertIsInstance(request["data"], bytes)
|
||||||
|
self.assertIn(b'a=1', request["data"])
|
||||||
|
self.assertIn(b'&', request["data"])
|
||||||
|
self.assertIn(b'b=2', request["data"])
|
||||||
|
|||||||
Reference in New Issue
Block a user