diff --git a/README.rst b/README.rst index 932df78..0b85862 100644 --- a/README.rst +++ b/README.rst @@ -144,7 +144,9 @@ The following options are available : - port (the port of the server receiving the request) - path (the path of the request) - query (the query string of the request) -- body (the entire request body) +- raw\_body (the entire request body as is) +- body (the entire request body unmarshalled by content-type + i.e. xmlrpc, json, form-urlencoded, falling back on raw\_body) - headers (the headers of the request) Backwards compatible matchers: diff --git a/vcr/config.py b/vcr/config.py index 1faef3b..7655a3a 100644 --- a/vcr/config.py +++ b/vcr/config.py @@ -47,6 +47,7 @@ class VCR(object): 'path': matchers.path, 'query': matchers.query, 'headers': matchers.headers, + 'raw_body': matchers.raw_body, 'body': matchers.body, } self.record_mode = record_mode diff --git a/vcr/matchers.py b/vcr/matchers.py index 91bce11..96c5190 100644 --- a/vcr/matchers.py +++ b/vcr/matchers.py @@ -1,3 +1,5 @@ +import json +from six.moves import urllib, xmlrpc_client import logging log = logging.getLogger(__name__) @@ -30,12 +32,29 @@ def query(r1, r2): return r1.query == r2.query -def body(r1, r2): +def raw_body(r1, r2): if hasattr(r1.body, 'read') and hasattr(r2.body, 'read'): return r1.body.read() == r2.body.read() return r1.body == r2.body +def body(r1, r2): + if hasattr(r1.body, 'read') and hasattr(r2.body, 'read'): + r1_body = r1.body.read() + r2_body = r2.body.read() + else: + r1_body = r1.body + r2_body = r2.body + if r1.headers.get('Content-Type') == r2.headers.get('Content-Type') == 'application/x-www-form-urlencoded': + return urllib.parse.parse_qs(r1_body) == urllib.parse.parse_qs(r2_body) + if r1.headers.get('Content-Type') == r2.headers.get('Content-Type') == 'application/json': + return json.loads(r1_body) == json.loads(r2_body) + if ('xmlrpc' in r1.headers.get('User-Agent', '') and 'xmlrpc' in r2.headers.get('User-Agent', '') and + r1.headers.get('Content-Type') == r2.headers.get('Content-Type') == 'text/xml'): + return xmlrpc_client.loads(r1_body) == xmlrpc_client.loads(r2_body) + return r1_body == r2_body + + def headers(r1, r2): return r1.headers == r2.headers