Show More
@@ -16,6 +16,9 b' Authors:' | |||||
16 | # Imports |
|
16 | # Imports | |
17 | #----------------------------------------------------------------------------- |
|
17 | #----------------------------------------------------------------------------- | |
18 |
|
18 | |||
|
19 | import logging | |||
|
20 | import Cookie | |||
|
21 | ||||
19 | from tornado import web |
|
22 | from tornado import web | |
20 | from tornado import websocket |
|
23 | from tornado import websocket | |
21 |
|
24 | |||
@@ -165,20 +168,58 b' class ZMQStreamHandler(websocket.WebSocketHandler):' | |||||
165 | else: |
|
168 | else: | |
166 | self.write_message(msg) |
|
169 | self.write_message(msg) | |
167 |
|
170 | |||
168 |
|
171 | class AuthenticatedZMQStreamHandler(ZMQStreamHandler): | ||
169 | class IOPubHandler(ZMQStreamHandler): |
|
172 | def open(self, kernel_id): | |
|
173 | self.kernel_id = kernel_id | |||
|
174 | self.session = Session() | |||
|
175 | self.save_on_message = self.on_message | |||
|
176 | self.on_message = self.on_first_message | |||
|
177 | ||||
|
178 | def get_current_user(self): | |||
|
179 | password = self.get_secure_cookie("password") | |||
|
180 | if password is None: | |||
|
181 | # clear cookies, to prevent future Invalid cookie signature warnings | |||
|
182 | self._cookies = Cookie.SimpleCookie() | |||
|
183 | if self.application.password and self.application.password != password: | |||
|
184 | return None | |||
|
185 | return self.get_secure_cookie("user") or 'anonymous' | |||
|
186 | ||||
|
187 | def _inject_cookie_message(self, msg): | |||
|
188 | """Inject the first message, which is the document cookie, | |||
|
189 | for authentication.""" | |||
|
190 | if isinstance(msg, unicode): | |||
|
191 | # Cookie can't constructor doesn't accept unicode strings for some reason | |||
|
192 | msg = msg.encode('utf8', 'replace') | |||
|
193 | try: | |||
|
194 | self._cookies = Cookie.SimpleCookie(msg) | |||
|
195 | except: | |||
|
196 | logging.warn("couldn't parse cookie string: %s",msg, exc_info=True) | |||
|
197 | ||||
|
198 | def on_first_message(self, msg): | |||
|
199 | self._inject_cookie_message(msg) | |||
|
200 | if self.get_current_user() is None: | |||
|
201 | logging.warn("Couldn't authenticate WebSocket connection") | |||
|
202 | raise web.HTTPError(403) | |||
|
203 | self.on_message = self.save_on_message | |||
|
204 | ||||
|
205 | ||||
|
206 | class IOPubHandler(AuthenticatedZMQStreamHandler): | |||
170 |
|
207 | |||
171 | def initialize(self, *args, **kwargs): |
|
208 | def initialize(self, *args, **kwargs): | |
172 | self._kernel_alive = True |
|
209 | self._kernel_alive = True | |
173 | self._beating = False |
|
210 | self._beating = False | |
174 | self.iopub_stream = None |
|
211 | self.iopub_stream = None | |
175 | self.hb_stream = None |
|
212 | self.hb_stream = None | |
176 |
|
213 | |||
177 | def open(self, kernel_id): |
|
214 | def on_first_message(self, msg): | |
|
215 | try: | |||
|
216 | super(IOPubHandler, self).on_first_message(msg) | |||
|
217 | except web.HTTPError: | |||
|
218 | self.close() | |||
|
219 | return | |||
178 | km = self.application.kernel_manager |
|
220 | km = self.application.kernel_manager | |
179 | self.kernel_id = kernel_id |
|
|||
180 | self.session = Session() |
|
|||
181 | self.time_to_dead = km.time_to_dead |
|
221 | self.time_to_dead = km.time_to_dead | |
|
222 | kernel_id = self.kernel_id | |||
182 | try: |
|
223 | try: | |
183 | self.iopub_stream = km.create_iopub_stream(kernel_id) |
|
224 | self.iopub_stream = km.create_iopub_stream(kernel_id) | |
184 | self.hb_stream = km.create_hb_stream(kernel_id) |
|
225 | self.hb_stream = km.create_hb_stream(kernel_id) | |
@@ -187,9 +228,13 b' class IOPubHandler(ZMQStreamHandler):' | |||||
187 | # close the connection. |
|
228 | # close the connection. | |
188 | if not self.stream.closed(): |
|
229 | if not self.stream.closed(): | |
189 | self.stream.close() |
|
230 | self.stream.close() | |
|
231 | self.close() | |||
190 | else: |
|
232 | else: | |
191 | self.iopub_stream.on_recv(self._on_zmq_reply) |
|
233 | self.iopub_stream.on_recv(self._on_zmq_reply) | |
192 | self.start_hb(self.kernel_died) |
|
234 | self.start_hb(self.kernel_died) | |
|
235 | ||||
|
236 | def on_message(self, msg): | |||
|
237 | pass | |||
193 |
|
238 | |||
194 | def on_close(self): |
|
239 | def on_close(self): | |
195 | # This method can be called twice, once by self.kernel_died and once |
|
240 | # This method can be called twice, once by self.kernel_died and once | |
@@ -245,15 +290,20 b' class IOPubHandler(ZMQStreamHandler):' | |||||
245 | self.on_close() |
|
290 | self.on_close() | |
246 |
|
291 | |||
247 |
|
292 | |||
248 | class ShellHandler(ZMQStreamHandler): |
|
293 | class ShellHandler(AuthenticatedZMQStreamHandler): | |
249 |
|
294 | |||
250 | def initialize(self, *args, **kwargs): |
|
295 | def initialize(self, *args, **kwargs): | |
251 | self.shell_stream = None |
|
296 | self.shell_stream = None | |
252 |
|
297 | |||
253 | def open(self, kernel_id): |
|
298 | def on_first_message(self, msg): | |
|
299 | try: | |||
|
300 | super(ShellHandler, self).on_first_message(msg) | |||
|
301 | except web.HTTPError: | |||
|
302 | self.close() | |||
|
303 | return | |||
254 | km = self.application.kernel_manager |
|
304 | km = self.application.kernel_manager | |
255 | self.max_msg_size = km.max_msg_size |
|
305 | self.max_msg_size = km.max_msg_size | |
256 |
|
|
306 | kernel_id = self.kernel_id | |
257 | try: |
|
307 | try: | |
258 | self.shell_stream = km.create_shell_stream(kernel_id) |
|
308 | self.shell_stream = km.create_shell_stream(kernel_id) | |
259 | except web.HTTPError: |
|
309 | except web.HTTPError: | |
@@ -261,8 +311,8 b' class ShellHandler(ZMQStreamHandler):' | |||||
261 | # close the connection. |
|
311 | # close the connection. | |
262 | if not self.stream.closed(): |
|
312 | if not self.stream.closed(): | |
263 | self.stream.close() |
|
313 | self.stream.close() | |
|
314 | self.close() | |||
264 | else: |
|
315 | else: | |
265 | self.session = Session() |
|
|||
266 | self.shell_stream.on_recv(self._on_zmq_reply) |
|
316 | self.shell_stream.on_recv(self._on_zmq_reply) | |
267 |
|
317 | |||
268 | def on_message(self, msg): |
|
318 | def on_message(self, msg): |
@@ -91,6 +91,12 b' var IPython = (function (IPython) {' | |||||
91 | console.log("Starting WS:", ws_url); |
|
91 | console.log("Starting WS:", ws_url); | |
92 | this.shell_channel = new this.WebSocket(ws_url + "/shell"); |
|
92 | this.shell_channel = new this.WebSocket(ws_url + "/shell"); | |
93 | this.iopub_channel = new this.WebSocket(ws_url + "/iopub"); |
|
93 | this.iopub_channel = new this.WebSocket(ws_url + "/iopub"); | |
|
94 | send_cookie = function(){ | |||
|
95 | this.send(document.cookie); | |||
|
96 | console.log(this); | |||
|
97 | } | |||
|
98 | this.shell_channel.onopen = send_cookie; | |||
|
99 | this.iopub_channel.onopen = send_cookie; | |||
94 | }; |
|
100 | }; | |
95 |
|
101 | |||
96 |
|
102 |
General Comments 0
You need to be logged in to leave comments.
Login now