@@ -288,7 +288,14 @@ this will cause errors in the URL library."
288288 ; ; Don't use `jupyter-api-request' here to avoid an infinite authentication
289289 ; ; loop since this function is used during authentication.
290290 (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" ))))
292299
293300(defun jupyter-api-url-cookies (url )
294301 " Return the list of cookies for URL."
@@ -441,18 +448,6 @@ Return the modified PLIST."
441448 t ))))
442449 ,@body ))))
443450
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-
456451(defun jupyter-api-login (client )
457452 " Attempt to login to the server using CLIENT.
458453Login is attempted by sending a GET request to CLIENT's login
@@ -468,25 +463,35 @@ raise an error.
468463
469464If the login attempt failed, raise a `jupyter-api-login-failed'
470465error 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 )))
490495
491496; ;;; Authenticators
492497
0 commit comments