mirror of
https://github.com/httprunner/httprunner.git
synced 2026-05-14 03:39:41 +08:00
bugfix: POST content-type is application/x-www-form-urlencoded
This commit is contained in:
@@ -14,6 +14,7 @@ import time
|
||||
|
||||
from httprunner.compat import basestring, builtin_str, integer_types, str
|
||||
from httprunner.exceptions import ParamsError
|
||||
from httprunner.utils import convert_dict_to_params, lower_dict_keys
|
||||
from requests_toolbelt import MultipartEncoder
|
||||
|
||||
|
||||
@@ -134,14 +135,23 @@ def endswith(check_value, expect_value):
|
||||
"""
|
||||
def setup_hook_prepare_kwargs(request):
|
||||
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 request content-type is application/json, request data should be dumped
|
||||
if content_type.startswith("application/json") and isinstance(request["data"], (dict, list)):
|
||||
request["data"] = json.dumps(request["data"])
|
||||
req_data = request["data"]
|
||||
|
||||
if isinstance(request["data"], str):
|
||||
request["data"] = request["data"].encode('utf-8')
|
||||
# if request content-type is application/json, request data should be dumped
|
||||
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):
|
||||
""" sleep n seconds
|
||||
|
||||
@@ -5,7 +5,7 @@ import time
|
||||
import requests
|
||||
import urllib3
|
||||
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.exceptions import (InvalidSchema, InvalidURL, MissingSchema,
|
||||
RequestException)
|
||||
@@ -138,11 +138,13 @@ class HttpSession(requests.Session):
|
||||
self.meta_data["response"]["url"] = response.url
|
||||
self.meta_data["response"]["status_code"] = response.status_code
|
||||
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"]["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
|
||||
|
||||
if "image" in content_type:
|
||||
|
||||
@@ -152,6 +152,7 @@ def get_uniform_comparator(comparator):
|
||||
else:
|
||||
return comparator
|
||||
|
||||
|
||||
def deep_update_dict(origin_dict, override_dict):
|
||||
""" update origin dict with override dict recursively
|
||||
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
|
||||
|
||||
|
||||
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):
|
||||
""" convert keys in dict to lower case
|
||||
|
||||
@@ -210,6 +236,7 @@ def lower_dict_keys(origin_dict):
|
||||
for key, value in origin_dict.items()
|
||||
}
|
||||
|
||||
|
||||
def lower_test_dict_keys(test_dict):
|
||||
""" convert keys in test_dict to lower case, convertion will occur in two places:
|
||||
1, all keys in test_dict;
|
||||
|
||||
@@ -70,3 +70,21 @@ class TestHttpClient(ApiServerUnittest):
|
||||
}
|
||||
setup_hook_prepare_kwargs(request)
|
||||
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