diff --git a/IPython/html/base/zmqhandlers.py b/IPython/html/base/zmqhandlers.py
index 99b7077..0287502 100644
--- a/IPython/html/base/zmqhandlers.py
+++ b/IPython/html/base/zmqhandlers.py
@@ -23,7 +23,7 @@ from tornado import web
from tornado import websocket
from IPython.kernel.zmq.session import Session
-from IPython.utils.jsonutil import date_default
+from IPython.utils.jsonutil import date_default, extract_dates
from IPython.utils.py3compat import PY3, cast_unicode
from .handlers import IPythonHandler
@@ -45,7 +45,9 @@ def serialize_binary_message(msg):
The message serialized to bytes.
"""
- buffers = msg.pop('buffers')
+ # don't modify msg or buffer list in-place
+ msg = msg.copy()
+ buffers = list(msg.pop('buffers'))
bmsg = json.dumps(msg, default=date_default).encode('utf8')
buffers.insert(0, bmsg)
nbufs = len(buffers)
@@ -72,13 +74,15 @@ def deserialize_binary_message(bmsg):
message dictionary
"""
- nbufs = struct.unpack('i', bmsg[:4])[0]
+ nbufs = struct.unpack('!i', bmsg[:4])[0]
offsets = list(struct.unpack('!' + 'i' * nbufs, bmsg[4:4*(nbufs+1)]))
offsets.append(None)
bufs = []
for start, stop in zip(offsets[:-1], offsets[1:]):
bufs.append(bmsg[start:stop])
- msg = json.loads(bufs[0])
+ msg = json.loads(bufs[0].decode('utf8'))
+ msg['header'] = extract_dates(msg['header'])
+ msg['parent_header'] = extract_dates(msg['parent_header'])
msg['buffers'] = bufs[1:]
return msg
@@ -139,14 +143,6 @@ class ZMQStreamHandler(websocket.WebSocketHandler):
"""
idents, msg_list = self.session.feed_identities(msg_list)
msg = self.session.deserialize(msg_list)
- try:
- msg['header'].pop('date')
- except KeyError:
- pass
- try:
- msg['parent_header'].pop('date')
- except KeyError:
- pass
if msg['buffers']:
buf = serialize_binary_message(msg)
return buf
diff --git a/IPython/html/tests/test_serialize.py b/IPython/html/tests/test_serialize.py
new file mode 100644
index 0000000..7a88b29
--- /dev/null
+++ b/IPython/html/tests/test_serialize.py
@@ -0,0 +1,26 @@
+"""Test serialize/deserialize messages with buffers"""
+
+import os
+
+import nose.tools as nt
+
+from IPython.kernel.zmq.session import Session
+from ..base.zmqhandlers import (
+ serialize_binary_message,
+ deserialize_binary_message,
+)
+
+def test_serialize_binary():
+ s = Session()
+ msg = s.msg('data_pub', content={'a': 'b'})
+ msg['buffers'] = [ os.urandom(3) for i in range(3) ]
+ bmsg = serialize_binary_message(msg)
+ nt.assert_is_instance(bmsg, bytes)
+
+def test_deserialize_binary():
+ s = Session()
+ msg = s.msg('data_pub', content={'a': 'b'})
+ msg['buffers'] = [ os.urandom(2) for i in range(3) ]
+ bmsg = serialize_binary_message(msg)
+ msg2 = deserialize_binary_message(bmsg)
+ nt.assert_equal(msg2, msg)