mosquito / aiohttp-xmlrpc

XMLRPC for aiohttp
MIT License
34 stars 19 forks source link

TypeError raised when response contains an empty base64 tag #15

Closed plumiron closed 6 years ago

plumiron commented 6 years ago

Hello, I got a response fomr xmlrpc server like this:

<methodResponse>
  <params>
    <param>
      <value>
        <struct>
          <member>
            <name>stdout</name>
            <value>
              <base64>DQpNaWNyb3NvZnQgV2luZG93cyBbVmVyc2lvbiA2LjEuNzYwMV0NCg==</base64>
            </value>
          </member>
          <member>
            <name>stderr</name>
            <value>
              <base64/>
            </value>
          </member>
          <member>
            <name>rc</name>
            <value>
              <i4>0</i4>
            </value>
          </member>
        </struct>
      </value>
    </param>
  </params>
</methodResponse>

But when parsing the response, a TypeError raised as following. Since there's an empty base64 tag in the response, the value passed to Binary.fromstring() was None. Can we just return None or b'' in this scenario (if the value is None)?

Traceback (most recent call last):
  File "check.py", line 258, in <module>
    check_io_tools()
  File "/cygdrive/c/workspaces/io_tools_checker/venv/lib/python3.6/site-packages/click/core.py", line 722, in __call__
    return self.main(*args, **kwargs)
  File "/cygdrive/c/workspaces/io_tools_checker/venv/lib/python3.6/site-packages/click/core.py", line 697, in main
    rv = self.invoke(ctx)
  File "/cygdrive/c/workspaces/io_tools_checker/venv/lib/python3.6/site-packages/click/core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/cygdrive/c/workspaces/io_tools_checker/venv/lib/python3.6/site-packages/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "check.py", line 254, in check_io_tools
    loop.run_until_complete(check_io_tools_on_hosts(hosts))
  File "/usr/lib/python3.6/asyncio/base_events.py", line 467, in run_until_complete
    return future.result()
  File "check.py", line 232, in check_io_tools_on_hosts
    await future
  File "/usr/lib/python3.6/asyncio/tasks.py", line 458, in _wait_for_one
    return f.result()  # May raise f.exception().
  File "check.py", line 225, in check_io_tools_on_host
    log('OS: {}'.format(await rpc_h.os))
  File "check.py", line 89, in os
    ret = await self.server['Command.cmd']({'command': ['cmd', '/c', 'ver']})
  File "/cygdrive/c/workspaces/io_tools_checker/venv/lib/python3.6/site-packages/aiohttp_xmlrpc-0.7.3-py3.6.egg/aiohttp_xmlrpc/client.py", line 104, in __remote_call
    return self._parse_response(r, method_name)
  File "/cygdrive/c/workspaces/io_tools_checker/venv/lib/python3.6/site-packages/aiohttp_xmlrpc-0.7.3-py3.6.egg/aiohttp_xmlrpc/client.py", line 74, in _parse_response
    return xml2py(result[0])
  File "/cygdrive/c/workspaces/io_tools_checker/venv/lib/python3.6/site-packages/aiohttp_xmlrpc-0.7.3-py3.6.egg/aiohttp_xmlrpc/common.py", line 164, in xml2py
    return XML2PY_TYPES.get(value.tag)(value)
  File "/cygdrive/c/workspaces/io_tools_checker/venv/lib/python3.6/site-packages/aiohttp_xmlrpc-0.7.3-py3.6.egg/aiohttp_xmlrpc/common.py", line 139, in xml2struct
    map(xml2py, p.xpath("./member/value/*"))
  File "/cygdrive/c/workspaces/io_tools_checker/venv/lib/python3.6/site-packages/aiohttp_xmlrpc-0.7.3-py3.6.egg/aiohttp_xmlrpc/common.py", line 164, in xml2py
    return XML2PY_TYPES.get(value.tag)(value)
  File "/cygdrive/c/workspaces/io_tools_checker/venv/lib/python3.6/site-packages/aiohttp_xmlrpc-0.7.3-py3.6.egg/aiohttp_xmlrpc/common.py", line 151, in <lambda>
    'base64': lambda x: Binary.fromstring(x.text),
  File "/cygdrive/c/workspaces/io_tools_checker/venv/lib/python3.6/site-packages/aiohttp_xmlrpc-0.7.3-py3.6.egg/aiohttp_xmlrpc/common.py", line 26, in fromstring
    return cls(base64.b64decode(data))
  File "/cygdrive/c/workspaces/io_tools_checker/venv/lib/python3.6/base64.py", line 80, in b64decode
    s = _bytes_from_decode_data(s)
  File "/cygdrive/c/workspaces/io_tools_checker/venv/lib/python3.6/base64.py", line 46, in _bytes_from_decode_data
    "string, not %r" % s.__class__.__name__) from None
TypeError: argument should be a bytes-like object or ASCII string, not 'NoneType'
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x6fffef9c940>
Unclosed connector
connections: ['[(<aiohttp.client_proto.ResponseHandler object at 0x6fffef9c9b0>, 1324445.127690263)]']
connector: <aiohttp.connector.TCPConnector object at 0x6fffef9c9e8>