Show More
@@ -102,20 +102,28 b' A message is defined by the following four-dictionary structure::' | |||||
102 | # clients can track where messages come from. |
|
102 | # clients can track where messages come from. | |
103 | 'parent_header' : dict, |
|
103 | 'parent_header' : dict, | |
104 |
|
104 | |||
|
105 | # Any metadata associated with the message. | |||
|
106 | 'metadata' : dict, | |||
|
107 | ||||
105 | # The actual content of the message must be a dict, whose structure |
|
108 | # The actual content of the message must be a dict, whose structure | |
106 | # depends on the message type. |
|
109 | # depends on the message type. | |
107 | 'content' : dict, |
|
110 | 'content' : dict, | |
108 |
|
||||
109 | # Any metadata associated with the message. |
|
|||
110 | 'metadata' : dict, |
|
|||
111 | } |
|
111 | } | |
112 |
|
112 | |||
113 | The Wire Protocol |
|
113 | The Wire Protocol | |
114 | ================= |
|
114 | ================= | |
115 |
|
115 | |||
|
116 | ||||
116 | This message format exists at a high level, |
|
117 | This message format exists at a high level, | |
117 | but does not describe the actual *implementation* at the wire level in zeromq. |
|
118 | but does not describe the actual *implementation* at the wire level in zeromq. | |
118 | The canonical implementation of the message spec is our :class:`~IPython.kernel.zmq.session.Session` class. |
|
119 | The canonical implementation of the message spec is our :class:`~IPython.kernel.zmq.session.Session` class. | |
|
120 | ||||
|
121 | .. note:: | |||
|
122 | ||||
|
123 | This section should only be relevant to non-Python consumers of the protocol. | |||
|
124 | Python consumers should simply import and use IPython's own implementation of the wire protocol | |||
|
125 | in the :class:`IPython.kernel.zmq.session.Session` object. | |||
|
126 | ||||
119 | Every message is serialized to a sequence of at least six blobs of bytes: |
|
127 | Every message is serialized to a sequence of at least six blobs of bytes: | |
120 |
|
128 | |||
121 | .. sourcecode:: python |
|
129 | .. sourcecode:: python | |
@@ -135,13 +143,15 b' Every message is serialized to a sequence of at least six blobs of bytes:' | |||||
135 | The front of the message is the ZeroMQ routing prefix, |
|
143 | The front of the message is the ZeroMQ routing prefix, | |
136 | which can be zero or more socket identities. |
|
144 | which can be zero or more socket identities. | |
137 | This is every piece of the message prior to the delimiter key ``<IDS|MSG>``. |
|
145 | This is every piece of the message prior to the delimiter key ``<IDS|MSG>``. | |
138 | In the case of IOPub, there should be just one prefix, |
|
146 | In the case of IOPub, there should be just one prefix component, | |
139 |
which is the topic for IOPub subscribers, e.g. `` |
|
147 | which is the topic for IOPub subscribers, e.g. ``pyout``, ``display_data``. | |
140 |
|
148 | |||
141 | .. note:: |
|
149 | .. note:: | |
142 |
|
150 | |||
143 | In most cases, the IOPub topics are irrelevant and completely ignored, |
|
151 | In most cases, the IOPub topics are irrelevant and completely ignored, | |
144 | because frontends just subscribe to all topics. |
|
152 | because frontends just subscribe to all topics. | |
|
153 | The convention used in the IPython kernel is to use the msg_type as the topic, | |||
|
154 | and possibly extra information about the message, e.g. ``pyout`` or ``stream.stdout`` | |||
145 |
|
155 | |||
146 | After the delimiter is the `HMAC`_ signature of the message, used for authentication. |
|
156 | After the delimiter is the `HMAC`_ signature of the message, used for authentication. | |
147 | If authentication is disabled, this should be an empty string. |
|
157 | If authentication is disabled, this should be an empty string. | |
@@ -154,15 +164,28 b' By default, the hashing function used for computing these signatures is sha256.' | |||||
154 | To disable authentication and signature checking, |
|
164 | To disable authentication and signature checking, | |
155 | set the `key` field of a connection file to an empty string. |
|
165 | set the `key` field of a connection file to an empty string. | |
156 |
|
166 | |||
157 |
The signature is |
|
167 | The signature is the HMAC hex digest of the concatenation of: | |
158 |
|
168 | |||
159 |
- A shared key ( |
|
169 | - A shared key (typically the ``key`` field of a connection file) | |
160 | - The serialized header dict |
|
170 | - The serialized header dict | |
161 | - The serialized parent header dict |
|
171 | - The serialized parent header dict | |
162 | - The serialized metadata dict |
|
172 | - The serialized metadata dict | |
163 | - The serialized content dict |
|
173 | - The serialized content dict | |
164 |
|
174 | |||
165 | After the signature is the actual message, always in four byte sequences. |
|
175 | In Python, this is implemented via: | |
|
176 | ||||
|
177 | .. sourcecode:: python | |||
|
178 | ||||
|
179 | # once: | |||
|
180 | digester = HMAC(key, digestmod=hashlib.sha256) | |||
|
181 | ||||
|
182 | # for each message | |||
|
183 | d = digester.copy() | |||
|
184 | for serialized_dict in (header, parent, metadata, content): | |||
|
185 | d.update(serialized_dict) | |||
|
186 | signature = d.hexdigest() | |||
|
187 | ||||
|
188 | After the signature is the actual message, always in four frames of bytes. | |||
166 | The four dictionaries that compose a message are serialized separately, |
|
189 | The four dictionaries that compose a message are serialized separately, | |
167 | in the order of header, parent header, metadata, and content. |
|
190 | in the order of header, parent header, metadata, and content. | |
168 | These can be serialized by any function that turns a dict into bytes. |
|
191 | These can be serialized by any function that turns a dict into bytes. |
General Comments 0
You need to be logged in to leave comments.
Login now