@@ -288,7 +288,14 @@ this will cause errors in the URL library."
288
288
; ; Don't use `jupyter-api-request' here to avoid an infinite authentication
289
289
; ; loop since this function is used during authentication.
290
290
(let (jupyter-api-request-headers jupyter-api-request-data)
291
- (jupyter-api-http-request (oref client url) " login" " GET" )))
291
+ (or
292
+ ; ; Already have the xsrf cookie, no need to request the login
293
+ ; ; page to receive it as a side effect.
294
+ (jupyter-api-xsrf-header-from-cookies (oref client url))
295
+ ; ; FIXME: It is not reliable to attempt to get the xsrf cookie as
296
+ ; ; a side effect of requesting the login page since it may not
297
+ ; ; always exist.
298
+ (jupyter-api-http-request (oref client url) " login" " GET" ))))
292
299
293
300
(defun jupyter-api-url-cookies (url )
294
301
" Return the list of cookies for URL."
@@ -441,18 +448,6 @@ Return the modified PLIST."
441
448
t ))))
442
449
,@body ))))
443
450
444
- (defun jupyter-api--verify-login (status )
445
- (let ((err (plist-get status :error )))
446
- (unless
447
- (or (not err)
448
- ; ; Handle HTTP 1.0. When given a POST request, 302 redirection
449
- ; ; doesn't change the method to GET dynamically. On the Jupyter
450
- ; ; notebook, the redirected page expects a GET and will return
451
- ; ; 405 (invalid method).
452
- (and (plist-get status :redirect )
453
- (= (nth 2 err) 405 )))
454
- (signal 'jupyter-api-login-failed err))))
455
-
456
451
(defun jupyter-api-login (client )
457
452
" Attempt to login to the server using CLIENT.
458
453
Login is attempted by sending a GET request to CLIENT's login
@@ -468,25 +463,35 @@ raise an error.
468
463
469
464
If the login attempt failed, raise a `jupyter-api-login-failed'
470
465
error with the data being the error received by `url-retrieve' ."
471
- (jupyter-api--without-url-http-authentication-handler
472
- (condition-case err
473
- (let (status done)
474
- (jupyter-api-url-request
475
- (concat (oref client url) " /login" )
476
- (lambda (s &rest _ )
477
- (url-mark-buffer-as-dead (current-buffer ))
478
- (setq status s done t )))
479
- (jupyter-with-timeout
480
- (nil jupyter-long-timeout
481
- (error " Timeout reached during login " ))
482
- done)
483
- (jupyter-api--verify-login status)
484
- (jupyter-api-copy-cookies-for-websocket (oref client url))
485
- (url-cookie-write-file )
486
- t )
487
- (error
488
- (when (eq (nth 2 err) 'connection-failed )
489
- (signal (car err) (cdr err)))))))
466
+ (let (status done)
467
+ (jupyter-api--without-url-http-authentication-handler
468
+ (jupyter-api-url-request
469
+ (concat (oref client url) " /login" )
470
+ (lambda (s &rest _ )
471
+ (url-mark-buffer-as-dead (current-buffer ))
472
+ (setq status s done t )))
473
+ (jupyter-with-timeout
474
+ (nil jupyter-long-timeout
475
+ (error " Login [%s ]: Timeout reached " (oref client url)))
476
+ done))
477
+ ; ; Verify login.
478
+ (let ((err (plist-get status :error )))
479
+ (unless
480
+ (or (not err)
481
+ ; ; jupyter_server can sometimes not have a login page,
482
+ ; ; for example when there is no password or token.
483
+ ; ; Therefore no need to login.
484
+ (= (nth 2 err) 404 )
485
+ ; ; Handle HTTP 1.0. When given a POST request, 302 redirection
486
+ ; ; doesn't change the method to GET dynamically. On the Jupyter
487
+ ; ; notebook, the redirected page expects a GET and will return
488
+ ; ; 405 (invalid method).
489
+ (and (plist-get status :redirect )
490
+ (= (nth 2 err) 405 )))
491
+ (signal 'jupyter-api-login-failed err)))
492
+ ; ; Handle cookies.
493
+ (jupyter-api-copy-cookies-for-websocket (oref client url))
494
+ (url-cookie-write-file )))
490
495
491
496
; ;;; Authenticators
492
497
0 commit comments