Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

External commands do no handle non ascii characters #27

Open
jccomputing opened this issue Jun 25, 2014 · 0 comments
Open

External commands do no handle non ascii characters #27

jccomputing opened this issue Jun 25, 2014 · 0 comments

Comments

@jccomputing
Copy link
Contributor

Hello

I found that when I send an external command that contains non ascii characters, it's not taken into account. I tested this with Thruk and Nagvis with French accents.

The external tools do send a proper UTF-8 encoded string (verified with Firebug for the http part and tcpdump for the livestatus tcp socket). The broker receives the external command, but it's never transmitted to the scheduler.

Here is the reason why:
The string is received as a Python byte string. Then it's decoded to a proper Python unicode string. The representation of this object contains escaped Unicode characters and some are mapped to the latin1 character set. When Shinken tries to send this Unicode string, it serializes it with Pickle, then convert the output to JSON with json.dumps. The JSON dumps function expects UTF-8 input, but it finds latin1 in the Pickle dump and throws a UnicodeDecodeError exception. The external never reaches it's destination.

Here is how to reproduce this behavior in the Python interpreter:

Python 2.7.3 (default, Mar 13 2014, 11:03:55) 
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import locale
>>> locale.getdefaultlocale()[1]
'UTF-8'
>>> import json
>>> import cPickle
>>> s = "[1403598279] ACKNOWLEDGE_HOST_PROBLEM;dummy-host-crit;2;1;0;thrukadmin;test é"
>>> u = s.decode('utf8')
>>> u
u'[1403598279] ACKNOWLEDGE_HOST_PROBLEM;dummy-host-crit;2;1;0;thrukadmin;test \xe9'
>>> cp = cPickle.dumps(u)
>>> json.dumps(cp)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "/usr/lib/python2.7/json/encoder.py", line 194, in encode
    return encode_basestring_ascii(o)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xe9 in position 77: invalid continuation byte
>>>

We have two solutions to this problem:

  1. Drop the bytestring to unicode conversion. This solution affects the Livestatus module itself. To do this we should delete this line.
  2. Ensure that the data are 7 bits safe. This solution affects Shinken's core. We should use for external commands what's done in other parts: cPickle, then zlib compression, then base64 encoding.

For information, the named-pipe module doesn't decode incoming data to unicode so it works, but the webui module does, so it has the same problem.

JCC

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant