Show More
@@ -146,18 +146,31 b' class AuthenticatedZMQStreamHandler(ZMQStreamHandler, IPythonHandler):' | |||||
146 | which doesn't make sense for websockets |
|
146 | which doesn't make sense for websockets | |
147 | """ |
|
147 | """ | |
148 | pass |
|
148 | pass | |
149 |
|
149 | |||
150 |
def |
|
150 | def get(self, *args, **kwargs): | |
151 | self.kernel_id = cast_unicode(kernel_id, 'ascii') |
|
|||
152 | # Check to see that origin matches host directly, including ports |
|
151 | # Check to see that origin matches host directly, including ports | |
153 | # Tornado 4 already does CORS checking |
|
152 | # Tornado 4 already does CORS checking | |
154 | if tornado.version_info[0] < 4: |
|
153 | if tornado.version_info[0] < 4: | |
155 | if not self.check_origin(self.get_origin()): |
|
154 | if not self.check_origin(self.get_origin()): | |
156 | raise web.HTTPError(403) |
|
155 | raise web.HTTPError(403) | |
157 |
|
156 | |||
|
157 | # authenticate the request before opening the websocket | |||
|
158 | if self.get_current_user() is None: | |||
|
159 | self.log.warn("Couldn't authenticate WebSocket connection") | |||
|
160 | raise web.HTTPError(403) | |||
|
161 | ||||
|
162 | if self.get_argument('session_id'): | |||
|
163 | self.session.session = cast_unicode(self.get_argument('session_id')) | |||
|
164 | else: | |||
|
165 | self.log.warn("No session ID specified") | |||
|
166 | ||||
|
167 | return super(AuthenticatedZMQStreamHandler, self).get(*args, **kwargs) | |||
|
168 | ||||
|
169 | def initialize(self): | |||
158 | self.session = Session(config=self.config) |
|
170 | self.session = Session(config=self.config) | |
159 | self.save_on_message = self.on_message |
|
171 | ||
160 | self.on_message = self.on_first_message |
|
172 | def open(self, kernel_id): | |
|
173 | self.kernel_id = cast_unicode(kernel_id, 'ascii') | |||
161 |
|
174 | |||
162 | # start the pinging |
|
175 | # start the pinging | |
163 | if self.ping_interval > 0: |
|
176 | if self.ping_interval > 0: | |
@@ -187,28 +200,3 b' class AuthenticatedZMQStreamHandler(ZMQStreamHandler, IPythonHandler):' | |||||
187 |
|
200 | |||
188 | def on_pong(self, data): |
|
201 | def on_pong(self, data): | |
189 | self.last_pong = ioloop.IOLoop.instance().time() |
|
202 | self.last_pong = ioloop.IOLoop.instance().time() | |
190 |
|
||||
191 | def _inject_cookie_message(self, msg): |
|
|||
192 | """Inject the first message, which is the document cookie, |
|
|||
193 | for authentication.""" |
|
|||
194 | if not PY3 and isinstance(msg, unicode): |
|
|||
195 | # Cookie constructor doesn't accept unicode strings |
|
|||
196 | # under Python 2.x for some reason |
|
|||
197 | msg = msg.encode('utf8', 'replace') |
|
|||
198 | try: |
|
|||
199 | identity, msg = msg.split(':', 1) |
|
|||
200 | self.session.session = cast_unicode(identity, 'ascii') |
|
|||
201 | except Exception: |
|
|||
202 | logging.error("First ws message didn't have the form 'identity:[cookie]' - %r", msg) |
|
|||
203 |
|
||||
204 | try: |
|
|||
205 | self.request._cookies = SimpleCookie(msg) |
|
|||
206 | except: |
|
|||
207 | self.log.warn("couldn't parse cookie string: %s",msg, exc_info=True) |
|
|||
208 |
|
||||
209 | def on_first_message(self, msg): |
|
|||
210 | self._inject_cookie_message(msg) |
|
|||
211 | if self.get_current_user() is None: |
|
|||
212 | self.log.warn("Couldn't authenticate WebSocket connection") |
|
|||
213 | raise web.HTTPError(403) |
|
|||
214 | self.on_message = self.save_on_message |
|
@@ -126,16 +126,12 b' class ZMQChannelHandler(AuthenticatedZMQStreamHandler):' | |||||
126 | self.kernel_info_channel.close() |
|
126 | self.kernel_info_channel.close() | |
127 | self.kernel_info_channel = None |
|
127 | self.kernel_info_channel = None | |
128 |
|
128 | |||
129 |
|
129 | def initialize(self): | ||
130 | def initialize(self, *args, **kwargs): |
|
130 | super(ZMQChannelHandler, self).initialize() | |
131 | self.zmq_stream = None |
|
131 | self.zmq_stream = None | |
132 |
|
132 | |||
133 | def on_first_message(self, msg): |
|
133 | def open(self, kernel_id): | |
134 | try: |
|
134 | super(ZMQChannelHandler, self).open(kernel_id) | |
135 | super(ZMQChannelHandler, self).on_first_message(msg) |
|
|||
136 | except web.HTTPError: |
|
|||
137 | self.close() |
|
|||
138 | return |
|
|||
139 | try: |
|
135 | try: | |
140 | self.create_stream() |
|
136 | self.create_stream() | |
141 | except web.HTTPError: |
|
137 | except web.HTTPError: |
@@ -424,16 +424,17 b' define([' | |||||
424 | var ws_host_url = this.ws_url + this.kernel_url; |
|
424 | var ws_host_url = this.ws_url + this.kernel_url; | |
425 |
|
425 | |||
426 | console.log("Starting WebSockets:", ws_host_url); |
|
426 | console.log("Starting WebSockets:", ws_host_url); | |
427 |
|
427 | |||
428 | this.channels.shell = new this.WebSocket( |
|
428 | var channel_url = function(channel) { | |
429 | this.ws_url + utils.url_join_encode(this.kernel_url, "shell") |
|
429 | return [ | |
430 | ); |
|
430 | that.ws_url, | |
431 | this.channels.stdin = new this.WebSocket( |
|
431 | utils.url_join_encode(that.kernel_url, channel), | |
432 | this.ws_url + utils.url_join_encode(this.kernel_url, "stdin") |
|
432 | "?session_id=" + that.session_id | |
433 | ); |
|
433 | ].join(''); | |
434 | this.channels.iopub = new this.WebSocket( |
|
434 | }; | |
435 | this.ws_url + utils.url_join_encode(this.kernel_url, "iopub") |
|
435 | this.channels.shell = new this.WebSocket(channel_url("shell")); | |
436 | ); |
|
436 | this.channels.stdin = new this.WebSocket(channel_url("stdin")); | |
|
437 | this.channels.iopub = new this.WebSocket(channel_url("iopub")); | |||
437 |
|
438 | |||
438 | var already_called_onclose = false; // only alert once |
|
439 | var already_called_onclose = false; // only alert once | |
439 | var ws_closed_early = function(evt){ |
|
440 | var ws_closed_early = function(evt){ | |
@@ -492,16 +493,12 b' define([' | |||||
492 | }; |
|
493 | }; | |
493 |
|
494 | |||
494 | /** |
|
495 | /** | |
495 |
* Handle a websocket entering the open state |
|
496 | * Handle a websocket entering the open state, | |
496 | * cookie authentication info as first message. |
|
497 | * signaling that the kernel is connected when all channels are open. | |
497 | * |
|
498 | * | |
498 | * @function _ws_opened |
|
499 | * @function _ws_opened | |
499 | */ |
|
500 | */ | |
500 | Kernel.prototype._ws_opened = function (evt) { |
|
501 | Kernel.prototype._ws_opened = function (evt) { | |
501 | // send the session id so the Session object Python-side |
|
|||
502 | // has the same identity |
|
|||
503 | evt.target.send(this.session_id + ':' + document.cookie); |
|
|||
504 |
|
||||
505 | if (this.is_connected()) { |
|
502 | if (this.is_connected()) { | |
506 | // all events ready, trigger started event. |
|
503 | // all events ready, trigger started event. | |
507 | this._kernel_connected(); |
|
504 | this._kernel_connected(); |
General Comments 0
You need to be logged in to leave comments.
Login now