Pickle non-str objects to survive connection return (#63110)
* Fail more helpfully when data is not str * Pickle arbitrary objects to return from connection
This commit is contained in:
parent
11dc3a972f
commit
ffe8f45ddd
2 changed files with 14 additions and 3 deletions
|
@ -155,7 +155,7 @@ class Connection(object):
|
|||
try:
|
||||
response = json.loads(out)
|
||||
except ValueError:
|
||||
params = list(args) + ['{0}={1}'.format(k, v) for k, v in iteritems(kwargs)]
|
||||
params = [repr(arg) for arg in args] + ['{0}={1!r}'.format(k, v) for k, v in iteritems(kwargs)]
|
||||
params = ', '.join(params)
|
||||
raise ConnectionError(
|
||||
"Unable to decode JSON from response to {0}({1}). Received '{2}'.".format(name, params, out)
|
||||
|
@ -163,6 +163,8 @@ class Connection(object):
|
|||
|
||||
if response['id'] != reqid:
|
||||
raise ConnectionError('invalid json-rpc id received')
|
||||
if "result_type" in response:
|
||||
response["result"] = cPickle.loads(to_bytes(response["result"]))
|
||||
|
||||
return response
|
||||
|
||||
|
|
|
@ -9,7 +9,8 @@ import traceback
|
|||
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.connection import ConnectionError
|
||||
from ansible.module_utils.six import binary_type
|
||||
from ansible.module_utils.six import binary_type, text_type
|
||||
from ansible.module_utils.six.moves import cPickle
|
||||
from ansible.utils.display import Display
|
||||
|
||||
display = Display()
|
||||
|
@ -60,7 +61,12 @@ class JsonRpcServer(object):
|
|||
else:
|
||||
response = self.response(result)
|
||||
|
||||
try:
|
||||
response = json.dumps(response)
|
||||
except Exception as exc:
|
||||
display.vvv(traceback.format_exc())
|
||||
error = self.internal_error(data=to_text(exc, errors='surrogate_then_replace'))
|
||||
response = json.dumps(error)
|
||||
|
||||
delattr(self, '_identifier')
|
||||
|
||||
|
@ -76,6 +82,9 @@ class JsonRpcServer(object):
|
|||
response = self.header()
|
||||
if isinstance(result, binary_type):
|
||||
result = to_text(result)
|
||||
if not isinstance(result, text_type):
|
||||
response["result_type"] = "pickle"
|
||||
result = to_text(cPickle.dumps(result, protocol=0))
|
||||
response['result'] = result
|
||||
return response
|
||||
|
||||
|
|
Loading…
Reference in a new issue