Closed singlecheeze closed 9 years ago
can you post the complete traceback?
also: what Crossbar.io version? trunk?
WIN NEW LOGO!
__ __ __ __ __ __ __ __
/ `|__)/ \/__`/__`|__) /\ |__) |/ \
\__,| \\__/.__/.__/|__)/~~\| \. |\__/
Crossbar.io : 0.11.0
Autobahn : 0.10.5-2
UTF8 Validator : wsaccel-0.6.2
XOR Masker : wsaccel-0.6.2
JSON Codec : stdlib
MsgPack Codec : -
Twisted : 15.3.0-EPollReactor
Python : 3.4.0/CPython
OS : Linux-3.19.0-26-generic-x86_64-with-Ubuntu-14.04-trusty
Machine : x86_64
Installed via: sudo pip3 install -U https://github.com/crossbario/crossbar/zipball/master
2015-08-27T12:14:40-0400 [Controller 3793] __ __ __ __ __ __ __ __
2015-08-27T12:14:40-0400 [Controller 3793] / `|__)/ \/__`/__`|__) /\ |__) |/ \
2015-08-27T12:14:40-0400 [Controller 3793] \__,| \\__/.__/.__/|__)/~~\| \. |\__/
2015-08-27T12:14:40-0400 [Controller 3793]
2015-08-27T12:14:40-0400 [Controller 3793] Version: 0.11.0
2015-08-27T12:14:40-0400 [Controller 3793] Started: 2015-08-27T16:14:40.988Z
2015-08-27T12:14:40-0400 [Controller 3793]
2015-08-27T12:14:40-0400 [Controller 3793] Starting from node directory /home/dave/xbar/.crossbar
2015-08-27T12:14:41-0400 [Controller 3793] Loading node configuration file '/home/dave/xbar/.crossbar/config.json'
2015-08-27T12:14:41-0400 [Controller 3793] Entering reactor event loop...
2015-08-27T12:14:41-0400 [Controller 3793] Process utilities not available
2015-08-27T12:14:41-0400 [Controller 3793] Joined realm 'crossbar' on node management router
2015-08-27T12:14:41-0400 [Controller 3793] No WAMPlets detected in enviroment.
2015-08-27T12:14:41-0400 [Controller 3793] Starting Router with ID 'wamprouter'...
2015-08-27T12:14:41-0400 [Router 3797] Running under CPython using EPollReactor reactor
2015-08-27T12:14:41-0400 [Router 3797] Entering event loop...
2015-08-27T12:14:41-0400 [Router 3797] Process utilities not available
2015-08-27T12:14:41-0400 [Controller 3793] Router with ID 'wamprouter' and PID 3797 started
2015-08-27T12:14:41-0400 [Router 3797] Worker ready to roll!
2015-08-27T12:14:41-0400 [Controller 3793] Router 'wamprouter': realm 'realm1' (named 'realm1') started
2015-08-27T12:14:41-0400 [Controller 3793] Router 'wamprouter': role 'role1' (named 'authenticator') started on realm 'realm1'
2015-08-27T12:14:41-0400 [Controller 3793] Router 'wamprouter': role 'role2' (named 'authorizer') started on realm 'realm1'
2015-08-27T12:14:41-0400 [Controller 3793] Router 'wamprouter': role 'role3' (named 'backend') started on realm 'realm1'
2015-08-27T12:14:41-0400 [Controller 3793] Router 'wamprouter': role 'role4' (named 'frontend') started on realm 'realm1'
2015-08-27T12:14:41-0400 [Router 3797] WampWebSocketServerFactory starting on 9090
2015-08-27T12:14:41-0400 [Controller 3793] Router 'wamprouter': transport 'loopback' started
2015-08-27T12:14:41-0400 [Router 3797] Site starting on 8081
2015-08-27T12:14:41-0400 [Controller 3793] Router 'wamprouter': transport 'web' started
2015-08-27T12:14:41-0400 [Controller 3793] Using guest worker executable '/usr/bin/python3' (executable path detected from environment)
2015-08-27T12:14:41-0400 [Controller 3793] Starting Guest with ID 'authenticator'...
2015-08-27T12:14:41-0400 [Controller 3793] Guest with ID 'authenticator' and PID 3801 started
2015-08-27T12:14:41-0400 [Controller 3793] Warning: cannot watch directory for changes - feature DirWatcher unavailable
2015-08-27T12:14:41-0400 [Controller 3793] Guest 'authenticator': started
2015-08-27T12:14:41-0400 [Controller 3793] Using guest worker executable '/usr/bin/python3' (executable path detected from environment)
2015-08-27T12:14:41-0400 [Controller 3793] Starting Guest with ID 'authorizer'...
2015-08-27T12:14:41-0400 [Controller 3793] Guest with ID 'authorizer' and PID 3802 started
2015-08-27T12:14:41-0400 [Controller 3793] Warning: cannot watch directory for changes - feature DirWatcher unavailable
2015-08-27T12:14:41-0400 [Controller 3793] Guest 'authorizer': started
2015-08-27T12:14:41-0400 [Controller 3793] Using guest worker executable '/usr/bin/python3' (executable path detected from environment)
2015-08-27T12:14:41-0400 [Controller 3793] Starting Guest with ID 'backend'...
2015-08-27T12:14:41-0400 [Controller 3793] Guest with ID 'backend' and PID 3803 started
2015-08-27T12:14:41-0400 [Controller 3793] Warning: cannot watch directory for changes - feature DirWatcher unavailable
2015-08-27T12:14:41-0400 [Controller 3793] Guest 'backend': started
2015-08-27T12:14:41-0400 [Router 3797] Cookie tracking disabled on WebSocket connection <crossbar.router.protocol.WampWebSocketServerProtocol object at 0x7ff9067d5f98>
2015-08-27T12:14:41-0400 [Guest 3801] Connected. Joining realm realm1 as user authenUser ...
2015-08-27T12:14:41-0400 [Router 3797] Traceback (most recent call last):
2015-08-27T12:14:41-0400 [Router 3797] File "/usr/local/lib/python3.4/dist-packages/crossbar/router/session.py", line 586, in onHello
2015-08-27T12:14:41-0400 [Router 3797] user['secret'].encode('utf8'))
2015-08-27T12:14:41-0400 [Router 3797] File "/usr/local/lib/python3.4/dist-packages/crossbar/router/auth.py", line 104, in __init__
2015-08-27T12:14:41-0400 [Router 3797] self.signature = auth.compute_wcs(secret, self.challenge)
2015-08-27T12:14:41-0400 [Router 3797] File "/usr/local/lib/python3.4/dist-packages/autobahn/wamp/auth.py", line 234, in compute_wcs
2015-08-27T12:14:41-0400 [Router 3797] assert(type(challenge) == bytes)
2015-08-27T12:14:41-0400 [Router 3797] AssertionError
2015-08-27T12:14:41-0400 [Guest 3802] Traceback (most recent call last):
2015-08-27T12:14:41-0400 [Guest 3802] File "/usr/lib/python3.4/asyncio/base_events.py", line 410, in create_connection
2015-08-27T12:14:41-0400 [Guest 3802] yield from self.sock_connect(sock, address)
2015-08-27T12:14:41-0400 [Guest 3802] File "/usr/lib/python3.4/asyncio/futures.py", line 348, in __iter__
2015-08-27T12:14:41-0400 [Guest 3802] yield self # This tells Task to wait for completion.
2015-08-27T12:14:41-0400 [Guest 3802] File "/usr/lib/python3.4/asyncio/tasks.py", line 351, in _wakeup
2015-08-27T12:14:41-0400 [Guest 3802] value = future.result()
2015-08-27T12:14:41-0400 [Guest 3802] File "/usr/lib/python3.4/asyncio/futures.py", line 243, in result
2015-08-27T12:14:41-0400 [Guest 3802] raise self._exception
2015-08-27T12:14:41-0400 [Guest 3802] File "/usr/lib/python3.4/asyncio/selector_events.py", line 300, in _sock_connect
2015-08-27T12:14:41-0400 [Guest 3802] raise OSError(err, 'Connect call failed %s' % (address,))
2015-08-27T12:14:41-0400 [Guest 3802] ConnectionRefusedError: [Errno 111] Connect call failed ('127.0.0.1', 8080)
2015-08-27T12:14:41-0400 [Guest 3802] During handling of the above exception, another exception occurred:
2015-08-27T12:14:41-0400 [Guest 3802] Traceback (most recent call last):
2015-08-27T12:14:41-0400 [Guest 3802] File "authorization.py", line 79, in <module>
2015-08-27T12:14:41-0400 [Guest 3802] runner.run(MyBackendComponent)
2015-08-27T12:14:41-0400 [Guest 3802] File "/usr/local/lib/python3.4/dist-packages/autobahn/asyncio/wamp.py", line 162, in run
2015-08-27T12:14:41-0400 [Guest 3802] (transport, protocol) = loop.run_until_complete(coro)
2015-08-27T12:14:41-0400 [Guest 3802] File "/usr/lib/python3.4/asyncio/base_events.py", line 208, in run_until_complete
2015-08-27T12:14:41-0400 [Guest 3802] return future.result()
2015-08-27T12:14:41-0400 [Guest 3802] File "/usr/lib/python3.4/asyncio/futures.py", line 243, in result
2015-08-27T12:14:41-0400 [Guest 3802] raise self._exception
2015-08-27T12:14:41-0400 [Guest 3802] File "/usr/lib/python3.4/asyncio/tasks.py", line 298, in _step
2015-08-27T12:14:41-0400 [Guest 3802] result = coro.throw(exc)
2015-08-27T12:14:41-0400 [Guest 3802] File "/usr/lib/python3.4/asyncio/base_events.py", line 428, in create_connection
2015-08-27T12:14:41-0400 [Guest 3802] ', '.join(str(exc) for exc in exceptions)))
2015-08-27T12:14:41-0400 [Guest 3802] OSError: Multiple exceptions: [Errno 111] Connect call failed ('127.0.0.1', 8080), [Errno 101] Network is unreachable
2015-08-27T12:14:41-0400 [Guest 3803] Traceback (most recent call last):
2015-08-27T12:14:41-0400 [Guest 3803] File "/usr/lib/python3.4/asyncio/base_events.py", line 410, in create_connection
2015-08-27T12:14:41-0400 [Guest 3803] yield from self.sock_connect(sock, address)
2015-08-27T12:14:41-0400 [Guest 3803] File "/usr/lib/python3.4/asyncio/futures.py", line 348, in __iter__
2015-08-27T12:14:41-0400 [Guest 3803] yield self # This tells Task to wait for completion.
2015-08-27T12:14:41-0400 [Guest 3803] File "/usr/lib/python3.4/asyncio/tasks.py", line 351, in _wakeup
2015-08-27T12:14:41-0400 [Guest 3803] value = future.result()
2015-08-27T12:14:41-0400 [Guest 3803] File "/usr/lib/python3.4/asyncio/futures.py", line 243, in result
2015-08-27T12:14:41-0400 [Guest 3803] raise self._exception
2015-08-27T12:14:41-0400 [Guest 3803] File "/usr/lib/python3.4/asyncio/selector_events.py", line 300, in _sock_connect
2015-08-27T12:14:41-0400 [Guest 3803] raise OSError(err, 'Connect call failed %s' % (address,))
2015-08-27T12:14:41-0400 [Guest 3803] ConnectionRefusedError: [Errno 111] Connect call failed ('127.0.0.1', 8080)
2015-08-27T12:14:41-0400 [Guest 3803] During handling of the above exception, another exception occurred:
2015-08-27T12:14:41-0400 [Guest 3803] Traceback (most recent call last):
2015-08-27T12:14:41-0400 [Guest 3803] File "backend.py", line 229, in <module>
2015-08-27T12:14:41-0400 [Guest 3803] runner.run(MyBackendComponent)
2015-08-27T12:14:41-0400 [Guest 3803] File "/usr/local/lib/python3.4/dist-packages/autobahn/asyncio/wamp.py", line 162, in run
2015-08-27T12:14:41-0400 [Guest 3803] (transport, protocol) = loop.run_until_complete(coro)
2015-08-27T12:14:41-0400 [Guest 3803] File "/usr/lib/python3.4/asyncio/base_events.py", line 208, in run_until_complete
2015-08-27T12:14:41-0400 [Guest 3803] return future.result()
2015-08-27T12:14:41-0400 [Guest 3803] File "/usr/lib/python3.4/asyncio/futures.py", line 243, in result
2015-08-27T12:14:41-0400 [Guest 3803] raise self._exception
2015-08-27T12:14:41-0400 [Guest 3803] File "/usr/lib/python3.4/asyncio/tasks.py", line 298, in _step
2015-08-27T12:14:41-0400 [Guest 3803] result = coro.throw(exc)
2015-08-27T12:14:41-0400 [Guest 3803] File "/usr/lib/python3.4/asyncio/base_events.py", line 428, in create_connection
2015-08-27T12:14:41-0400 [Guest 3803] ', '.join(str(exc) for exc in exceptions)))
2015-08-27T12:14:41-0400 [Guest 3803] OSError: Multiple exceptions: [Errno 111] Connect call failed ('127.0.0.1', 8080), [Errno 101] Network is unreachable
2015-08-27T12:14:41-0400 [Controller 3793] Guest authorizer exited with error A process has ended with a probable error condition: process ended with exit code 1.
2015-08-27T12:14:41-0400 [Controller 3793] Guest backend exited with error A process has ended with a probable error condition: process ended with exit code 1.
you seem to be running a guest worker which is a Python 3 / asyncio component, but the guest worker fails to connect back to the router worker: "Network is unreachable"
the root cause is this assert that breaks:
2015-08-27T12:14:41-0400 [Router 3797] File "/usr/local/lib/python3.4/dist-packages/autobahn/wamp/auth.py", line 234, in compute_wcs
2015-08-27T12:14:41-0400 [Router 3797] assert(type(challenge) == bytes)
2015-08-27T12:14:41-0400 [Router 3797] AssertionError
So yes, there might lurk a bug with WAMP-CRA + Python 3 + asyncio at least.
Yes, I am running 3 guest workers. Please see my jason.config below:
{
"controller": {
},
"workers": [
{
"id": "wamprouter",
"type": "router",
"options": {
"title": "WAMP Router"
},
"realms": [
{
"name": "realm1",
"roles": [
{
"name": "authenticator",
"permissions": [
{
"uri": "com.aurora.authenticate",
"register": true
}
]
},
{
"name": "authorizer",
"permissions": [
{
"uri": "com.aurora.authorize",
"register": true
}
]
},
{
"name": "backend",
"authorizer": "com.aurora.authorize"
},
{
"name": "frontend",
"authorizer": "com.aurora.authorize"
}
]
}
],
"transports": [
{
"id": "loopback",
"type": "websocket",
"endpoint": {
"type": "tcp",
"port": 9090,
"interface": "127.0.0.1"
},
"auth": {
"wampcra": {
"type": "static",
"users": {
"authenUser": {
"secret": "prq7+YkJ1/KlW1X0YczMHw==",
"role": "authenticator",
"salt": "salt123",
"iterations": 100,
"keylen": 16
}
}
}
},
"debug": false,
"options": {
"compression": {
"deflate": {
"request_no_context_takeover": false,
"request_max_window_bits": 11,
"no_context_takeover": false,
"max_window_bits": 11,
"memory_level": 4
}
},
"auto_ping_interval": 10000,
"auto_ping_timeout": 5000,
"auto_ping_size": 4
}
},
{
"id": "web",
"type": "web",
"endpoint": {
"type": "tcp",
"port": 8081
},
"paths": {
"/": {
"type": "static",
"directory": "../frontend"
},
"ws": {
"type": "websocket",
"url": "ws://localhost:8080/ws",
"auth": {
"wampcra": {
"type": "dynamic",
"authenticator": "com.aurora.authenticate"
}
},
"debug": false,
"options": {
"compression": {
"deflate": {
"request_no_context_takeover": false,
"request_max_window_bits": 11,
"no_context_takeover": false,
"max_window_bits": 11,
"memory_level": 4
}
},
"auto_ping_interval": 10000,
"auto_ping_timeout": 5000,
"auto_ping_size": 4
}
}
}
}
]
},
{
"id": "authenticator",
"type": "guest",
"executable": "python3",
"arguments": ["authentication.py"],
"options": {
"env": {
"vars": {
"PYTHONUNBUFFERED": "1"
}
},
"workdir": "../backend",
"stdout": "log",
"stderr": "log",
"watch": {
"directories": ["../backend"],
"action": "restart"
}
}
},
{
"id": "authorizer",
"type": "guest",
"executable": "python3",
"arguments": ["authorization.py"],
"options": {
"env": {
"vars": {
"PYTHONUNBUFFERED": "1"
}
},
"workdir": "../backend",
"stdout": "log",
"stderr": "log",
"watch": {
"directories": ["../backend"],
"action": "restart"
}
}
},
{
"id": "backend",
"type": "guest",
"executable": "python3",
"arguments": ["backend.py"],
"options": {
"env": {
"vars": {
"PYTHONUNBUFFERED": "1"
}
},
"workdir": "../backend",
"stdout": "log",
"stderr": "log",
"watch": {
"directories": ["../backend"],
"action": "restart"
}
}
}
]
}
I reduced the above to just the "authorizor" part, it works for me on Crossbar master + Autobahn master or 0.10.5-2 (with crossbar running on python2, and the guest on python 3.4.2). My onChallenge
looks like this:
def onChallenge(self, challenge):
signature = auth.compute_wcs(
"prq7+YkJ1/KlW1X0YczMHw==".encode('utf8'),
challenge.extra['challenge'].encode('utf8')
)
return signature.decode('ascii')
And mine.... they look equivalent to me, only difference is I'm running crossbar in python 3.4.0. Could this be a bytes problem? Going to try on 3.4.2.....
One thing to note, latest Autobahn|JS for my frontend is at 0.9.6 from (I know I'm not even getting that far, just not sure if it needs and update too): https://autobahn.s3.amazonaws.com/autobahnjs/latest/autobahn.min.jgz
def onChallenge(self, challenge):
# print("Authentication challenge received: {}".format(challenge))
if challenge.method == "wampcra":
if'salt' in challenge.extra:
key = auth.derive_key(PASSWORD.encode('utf8'),
challenge.extra['salt'].encode('utf8'),
challenge.extra.get('iterations', None),
challenge.extra.get('keylen', None))
else:
key = PASSWORD.encode('utf8')
signature = auth.compute_wcs(key, challenge.extra['challenge'].encode('utf8'))
return signature.decode('ascii')
else:
raise Exception("Don't know how to compute challenge for authmethod {}".format(challenge.method))
One thing to note ..
So what is the point? WAMP-CRA (salted and unsalted) works with AutobahnJS.
Just commenting that there is a version difference between Autobahn|JS and Autobahn|Python... not sure if things need to be updated that's all :-)
@meejah would you be willing to test crossbar in python 3.4.0 and 3.4.2...
I think I just boned my Ubuntu server after mistyping installing 3.4.2...
@singlecheeze ah, you're running crossbar itself in Python3? (I did run my guest worker in 3.4.2, and that works to a crossbar on 2.7.x).
Yes, running crossbar itself in Python 3.4.2 I see the assert(type(challenge)) == bytes
error (on the router side)
For now, you can work around it by NOT doing the .decode('ascii')
and simply return signature
in your onAuthenticate call...
Ah, sorry that's not sufficient to work around it. Essentially a bytes vs str encoding issue on Python3 with the "challenge" etc. @oberstet I'm not sure why we insist that the challenge is bytes? (It makes some sense, but auth.py isn't ensuring that properly, hence the asserts...).
Meta-thing: maybe we should add a "python3" label for bugs? (That is, if it's purely a "crossbar on Python3" issue).
@meejah we can certainly restructure that code I guess. I think the trick was to get the HMAC-SHA256 compute the correct signature making sure the input types are right. what matters is bytes on the wire and the spec https://github.com/tavendo/WAMP/blob/master/spec/advanced.md#challenge-response-authentication
Yeah, I think insisting that it's bytes
is a good idea.
Might need some thinking to make sure this all works fine. crossbar.router.auth
is just doing self.challenge = json.dumps(...)
which will always be not-bytes on Python3 (but just adding .encode('utf8')
means all signature-producing code has to NOT do .decode('ascii')
as the docs currently say to do...
At this point I guess the only real "workaround" is "use Python2 to run crossbar"
I was thinking it might make some sense to re-factor the auth code a little so it's easier to use and at the same time harder to pass the "wrong thing" to compute_wcs
(e.g. it's really easy to accidentally pass the actual secret instead of derived key)
Also, I'm not sure of wider implications, but WCS_SECRET_CHARSET is awfully close to url-safe base64 encoding and it might be worth simply using that instead...?
It's also not safe to use random
for cryptographic secrets so generate_wcs
should probably actually be something like return b64encode(os.urandom(32))
(this method isn't actually used by crossbar, but still).
@oberstet Hmm, looking at the spec, maybe it's actually better to specify the encoding and insist that the challenge is always a string in that particular encoding (e.g. utf8? ascii?) instead of bytes since the spec says it "MUST BE a JSON serialized object". According to Python docs, json.dumps
will always be returning an ASCII str
object, with any non-ASCII characters escaped (so this could be put into the WAMP spec too). I'm unsure how this might affect non-Python implementations...
Thank you @meejah for taking a close look at this!!!
I'll hit you guys up on IRC if that's still something you guys use daily too? On Aug 27, 2015 8:31 PM, "meejah" notifications@github.com wrote:
@oberstet https://github.com/oberstet Hmm, looking at the spec, maybe it's actually better to specify the encoding and insist that the challenge is always a string in that particular encoding (e.g. utf8? ascii?) instead of bytes since the spec says it "MUST BE a JSON serialized object". According to Python docs, json.dumps will always be returning an ASCII str object, with any non-ASCII characters escaped (so this could be put into the WAMP spec too). I'm unsure how this might affect non-Python implementations...
— Reply to this email directly or view it on GitHub https://github.com/crossbario/crossbar/issues/412#issuecomment-135591800 .
Yes, I'm usually idling in #autobahn -- if you put "meejah: " in front I'm way more likely to notice faster :) (I do check IRC, but do leave your client connected if I don't respond right away).
https://docs.python.org/3/howto/pyporting.html#text-versus-binary-data
I think we have a conflict here
Yes, running crossbar itself in Python 3.4.2 I see the assert(type(challenge)) == bytes error (on the router side)
The signature for WAMP-CRA is computed within the router here: https://github.com/crossbario/crossbar/blob/master/crossbar/router/auth.py#L104:
self.signature = auth.compute_wcs(secret, self.challenge)
That is, secret
actually is already bytes
(sidenote: the doc string on PendingAuthWampCra
is wrong): https://github.com/crossbario/crossbar/blob/master/crossbar/router/session.py#L601
but self.challenge
is computed as
self.challenge = json.dumps(challenge_obj)
and this isn't bytes
on Python 3.
Personally, I find it "unexpected" (and I always forget it) that
json.dumps
produces a string (=unicode) under Python 3, notbytes
. But that's how it is.
@meejah could you try changing above line to
self.challenge = json.dumps(challenge_obj, ensure_ascii=False).encode('utf8')
and see if that does away with the traceback in the router?
Actually, there are more instances of this we should check:
(python279_1)oberstet@thinkpad-t430s:~/scm/crossbar/crossbar$ find . -name "*.py" -exec grep -Hi "json\.dumps" {} \;
./crossbar/controller/guest.py: self.transport.write(json.dumps(options['stdin']['value']))
./crossbar/controller/cli.py: fd.write("{}\n".format(json.dumps(pid_data, sort_keys=False, indent=3, separators=(',', ': '))))
./crossbar/adapter/rest/publisher.py: body = json.dumps(res, separators=(',', ':'))
./crossbar/adapter/rest/webhook.py: json.loads(json.dumps(message)),
./crossbar/adapter/rest/caller.py: body = json.dumps(res, separators=(',', ':'))
./crossbar/adapter/rest/subscriber.py: body = json.dumps({"args": args, "kwargs": kwargs},
./crossbar/router/cookiestore.py: self._cookie_file.write(json.dumps({
./crossbar/router/auth.py: self.challenge = json.dumps(challenge_obj)
./crossbar/router/service.py: if json.dumps(schema) != json.dumps(self._schemas[uri]):
./crossbar/twisted/resource.py: self._data = json.dumps(value, sort_keys=True, indent=3, ensure_ascii=False)
./crossbar/twisted/resource.py: self._data = json.dumps(value, separators=(',', ':'), ensure_ascii=False)
and
(python279_1)oberstet@thinkpad-t430s:~/scm/autobahn/AutobahnPython$ find autobahn/ -name "*.py" -exec grep -Hi "json\.dumps" {} \;
autobahn/wamp/role.py: return json.dumps(self.__dict__)
autobahn/wamp/test/test_auth.py: challenge = json.dumps([1, 2, 3], ensure_ascii=False).encode('utf8')
autobahn/wamp/serializer.py: return ujson.dumps(obj, double_precision=15, ensure_ascii=False)
autobahn/wamp/serializer.py: return json.dumps(obj, separators=(',', ':'), ensure_ascii=False)
autobahn/twisted/longpoll.py: payload = json.dumps(result)
autobahn/websocket/protocol.py: return json.dumps(self.__json__())
autobahn/websocket/protocol.py: return json.dumps(self.__json__())
autobahn/websocket/protocol.py: return json.dumps(self.__json__())
Thank you Tobias! On Aug 31, 2015 6:59 PM, "Tobias Oberstein" notifications@github.com wrote:
Actually, there are more instances of this we should check:
(python279_1)oberstet@thinkpad-t430s:~/scm/crossbar/crossbar$ find . -name "*.py" -exec grep -Hi "json.dumps" {} \;./crossbar/controller/guest.py: self.transport.write(json.dumps(options['stdin']['value']))./crossbar/controller/cli.py: fd.write("{}\n".format(json.dumps(pid_data, sort_keys=False, indent=3, separators=(',', ': '))))./crossbar/adapter/rest/publisher.py: body = json.dumps(res, separators=(',', ':'))./crossbar/adapter/rest/webhook.py: json.loads(json.dumps(message)),./crossbar/adapter/rest/caller.py: body = json.dumps(res, separators=(',', ':'))./crossbar/adapter/rest/subscriber.py: body = json.dumps({"args": args, "kwargs": kwargs},./crossbar/router/cookiestore.py: self._cookie_file.write(json.dumps({./crossbar/router/auth.py: self.challenge = json.dumps(challenge_obj)./crossbar/router/service.py: if json.dumps(schema) != json.dumps(self._schemas[uri]):./crossbar/twisted/resource.py: self._data = json.dumps(value, sort_keys=True, indent=3, ensure_ascii=False)./crossbar/twisted/resource.py: self._data = json.dumps(value, separators=(',', ':'), ensure_ascii=False)
and
(python279_1)oberstet@thinkpad-t430s:~/scm/autobahn/AutobahnPython$ find autobahn/ -name "*.py" -exec grep -Hi "json.dumps" {} \;autobahn/wamp/role.py: return json.dumps(self.dict)autobahn/wamp/test/test_auth.py: challenge = json.dumps([1, 2, 3], ensure_ascii=False).encode('utf8')autobahn/wamp/serializer.py: return ujson.dumps(obj, double_precision=15, ensure_ascii=False)autobahn/wamp/serializer.py: return json.dumps(obj, separators=(',', ':'), ensure_ascii=False)autobahn/twisted/longpoll.py: payload = json.dumps(result)autobahn/websocket/protocol.py: return json.dumps(self.json())autobahn/websocket/protocol.py: return json.dumps(self.json())autobahn/websocket/protocol.py: return json.dumps(self.json())
— Reply to this email directly or view it on GitHub https://github.com/crossbario/crossbar/issues/412#issuecomment-136522924 .
Also of side note... in python 3 isn't the correct arg 'utf-8' instead of 'utf8' ? Or does the method accept both? On Aug 31, 2015 6:59 PM, "Tobias Oberstein" notifications@github.com wrote:
Actually, there are more instances of this we should check:
(python279_1)oberstet@thinkpad-t430s:~/scm/crossbar/crossbar$ find . -name "*.py" -exec grep -Hi "json.dumps" {} \;./crossbar/controller/guest.py: self.transport.write(json.dumps(options['stdin']['value']))./crossbar/controller/cli.py: fd.write("{}\n".format(json.dumps(pid_data, sort_keys=False, indent=3, separators=(',', ': '))))./crossbar/adapter/rest/publisher.py: body = json.dumps(res, separators=(',', ':'))./crossbar/adapter/rest/webhook.py: json.loads(json.dumps(message)),./crossbar/adapter/rest/caller.py: body = json.dumps(res, separators=(',', ':'))./crossbar/adapter/rest/subscriber.py: body = json.dumps({"args": args, "kwargs": kwargs},./crossbar/router/cookiestore.py: self._cookie_file.write(json.dumps({./crossbar/router/auth.py: self.challenge = json.dumps(challenge_obj)./crossbar/router/service.py: if json.dumps(schema) != json.dumps(self._schemas[uri]):./crossbar/twisted/resource.py: self._data = json.dumps(value, sort_keys=True, indent=3, ensure_ascii=False)./crossbar/twisted/resource.py: self._data = json.dumps(value, separators=(',', ':'), ensure_ascii=False)
and
(python279_1)oberstet@thinkpad-t430s:~/scm/autobahn/AutobahnPython$ find autobahn/ -name "*.py" -exec grep -Hi "json.dumps" {} \;autobahn/wamp/role.py: return json.dumps(self.dict)autobahn/wamp/test/test_auth.py: challenge = json.dumps([1, 2, 3], ensure_ascii=False).encode('utf8')autobahn/wamp/serializer.py: return ujson.dumps(obj, double_precision=15, ensure_ascii=False)autobahn/wamp/serializer.py: return json.dumps(obj, separators=(',', ':'), ensure_ascii=False)autobahn/twisted/longpoll.py: payload = json.dumps(result)autobahn/websocket/protocol.py: return json.dumps(self.json())autobahn/websocket/protocol.py: return json.dumps(self.json())autobahn/websocket/protocol.py: return json.dumps(self.json())
— Reply to this email directly or view it on GitHub https://github.com/crossbario/crossbar/issues/412#issuecomment-136522924 .
@singlecheeze it accepts both, utf8
is an alias to utf-8
.
Bumping this... I saw the announcement for Crossbar 11 and have noticed that 10.4 has been replaced on python 2 pip. Any idea when this will be fixed? I know auth is tough and there is probably other low hanging fruit on the list but without the ability to run 10.4 on py 2 I'm at a standstill :-(
I'm about to push a PR for just this issue -- @oberstet should we move the "double-check these other things" to a separate ticket?
It might be worth putting this one fix into a 0.11.1 release since it means you can't really run crossbar on Python3 if you also want to do WAMP-CRA :/
I'm VERY satisfied with the support Tavendo is providing for this product ;)
On Tue, Sep 8, 2015 at 3:37 PM, meejah notifications@github.com wrote:
I'm about to push a PR for just this issue -- @oberstet https://github.com/oberstet should we move the "double-check these other things" to a separate ticket?
It might be worth putting this one fix into a 0.11.1 release since it means you can't really run crossbar on Python3 if you also want to do WAMP-CRA :/
— Reply to this email directly or view it on GitHub https://github.com/crossbario/crossbar/issues/412#issuecomment-138678589 .
@singlecheeze thanks for recognizing;) please spread the word ..
@meejah yeah, CB follow up release .. good idea. lets wait another 1-2 days and see if another hot-fix worthy issue pops up and we can coalesce. it's a big release with tons of change ..
I can't run authenticate wamprca examples on Python 3. There's something still broken?
I see this in the repo, is wamp-cra not supported yet?: