@@ -8468,6 +8468,72 @@ nil."
84688468
84698469
84708470;; Download URL handling
8471+
8472+ (defun lsp-download-install--url-retrieve (url file callback error-callback)
8473+ "Download URL to FILE using url-retrieve asynchronously.
8474+ Call CALLBACK on success or ERROR-CALLBACK on failure."
8475+ (url-retrieve
8476+ url
8477+ (lambda (status &rest args)
8478+ (cond
8479+ ;; Check for errors
8480+ ((plist-get status :error)
8481+ (lsp--error "Download failed: %s" (plist-get status :error))
8482+ (funcall error-callback (plist-get status :error)))
8483+
8484+ ;; Success - save to file
8485+ (t
8486+ (condition-case err
8487+ (progn
8488+ ;; Move past HTTP headers
8489+ (goto-char (point-min))
8490+ (re-search-forward "\n\n" nil t)
8491+
8492+ ;; Write content to file
8493+ (let ((coding-system-for-write 'binary))
8494+ (write-region (point) (point-max) file nil 'silent))
8495+
8496+ ;; Clean up and call success callback
8497+ (kill-buffer)
8498+ (funcall callback))
8499+ (error
8500+ (lsp--error "Failed to save downloaded file: %s" err)
8501+ (funcall error-callback err))))))
8502+ nil 'silent 'inhibit-cookies))
8503+
8504+ (defun lsp-download-install--verify-signature (main-url main-file asc-url pgp-key)
8505+ "Verify GPG signature for MAIN-FILE.
8506+ Download signature from ASC-URL and verify with PGP-KEY.
8507+ This is a synchronous operation that should be called after the main download."
8508+ (if (executable-find epg-gpg-program)
8509+ (let ((asc-download-path (concat main-file ".asc"))
8510+ (context (epg-make-context))
8511+ (fingerprint)
8512+ (signature))
8513+ (when (f-exists? asc-download-path)
8514+ (f-delete asc-download-path))
8515+
8516+ ;; Download signature file - using synchronous download for simplicity
8517+ ;; since signature files are typically very small
8518+ (lsp--info "Downloading signature from %s..." asc-url)
8519+ (url-copy-file asc-url asc-download-path)
8520+ (lsp--info "Downloaded signature file")
8521+
8522+ ;; Import and verify
8523+ (epg-import-keys-from-string context pgp-key)
8524+ (setq fingerprint (epg-import-status-fingerprint
8525+ (car
8526+ (epg-import-result-imports
8527+ (epg-context-result-for context 'import)))))
8528+ (lsp--info "Verifying signature %s..." asc-download-path)
8529+ (epg-verify-file context asc-download-path main-file)
8530+ (setq signature (car (epg-context-result-for context 'verify)))
8531+ (unless (and
8532+ (eq (epg-signature-status signature) 'good)
8533+ (equal (epg-signature-fingerprint signature) fingerprint))
8534+ (error "Failed to verify GPG signature: %s" (epg-signature-to-string signature))))
8535+ (lsp--warn "GPG is not installed, skipping the signature check.")))
8536+
84718537(cl-defun lsp-download-install (callback error-callback &key url asc-url pgp-key store-path decompress &allow-other-keys)
84728538 (let* ((url (lsp-resolve-value url))
84738539 (store-path (lsp-resolve-value store-path))
@@ -8479,52 +8545,44 @@ nil."
84798545 (:targz (concat store-path ".tar.gz"))
84808546 (`nil store-path)
84818547 (_ (error ":decompress must be `:gzip', `:zip', `:targz' or `nil'")))))
8482- (make-thread
8548+ ;; Clean up any existing files
8549+ (when (f-exists? download-path)
8550+ (f-delete download-path))
8551+ (when (and (f-exists? store-path) (not (equal download-path store-path)))
8552+ (f-delete store-path))
8553+
8554+ ;; Create parent directory if needed
8555+ (mkdir (f-parent download-path) t)
8556+
8557+ ;; Start async download
8558+ (lsp--info "Starting to download %s to %s..." url download-path)
8559+ (lsp-download-install--url-retrieve
8560+ url
8561+ download-path
84838562 (lambda ()
8563+ ;; Success handler - continue with decompression and verification
8564+ (lsp--info "Finished downloading %s..." download-path)
84848565 (condition-case err
84858566 (progn
8486- (when (f-exists? download-path)
8487- (f-delete download-path))
8488- (when (f-exists? store-path)
8489- (f-delete store-path))
8490- (lsp--info "Starting to download %s to %s..." url download-path)
8491- (mkdir (f-parent download-path) t)
8492- (url-copy-file url download-path)
8493- (lsp--info "Finished downloading %s..." download-path)
8567+ ;; Handle signature verification if requested
84948568 (when (and lsp-verify-signature asc-url pgp-key)
8495- (if (executable-find epg-gpg-program)
8496- (let ((asc-download-path (concat download-path ".asc"))
8497- (context (epg-make-context))
8498- (fingerprint)
8499- (signature))
8500- (when (f-exists? asc-download-path)
8501- (f-delete asc-download-path))
8502- (lsp--info "Starting to download %s to %s..." asc-url asc-download-path)
8503- (url-copy-file asc-url asc-download-path)
8504- (lsp--info "Finished downloading %s..." asc-download-path)
8505- (epg-import-keys-from-string context pgp-key)
8506- (setq fingerprint (epg-import-status-fingerprint
8507- (car
8508- (epg-import-result-imports
8509- (epg-context-result-for context 'import)))))
8510- (lsp--info "Verifying signature %s..." asc-download-path)
8511- (epg-verify-file context asc-download-path download-path)
8512- (setq signature (car (epg-context-result-for context 'verify)))
8513- (unless (and
8514- (eq (epg-signature-status signature) 'good)
8515- (equal (epg-signature-fingerprint signature) fingerprint))
8516- (error "Failed to verify GPG signature: %s" (epg-signature-to-string signature))))
8517- (lsp--warn "GPG is not installed, skipping the signature check.")))
8569+ (lsp-download-install--verify-signature url download-path asc-url pgp-key))
8570+
8571+ ;; Handle decompression if needed
85188572 (when decompress
85198573 (lsp--info "Decompressing %s..." download-path)
85208574 (pcase decompress
8521- (:gzip
8522- (lsp-gunzip download-path))
8575+ (:gzip (lsp-gunzip download-path))
85238576 (:zip (lsp-unzip download-path (f-parent store-path)))
85248577 (:targz (lsp-tar-gz-decompress download-path (f-parent store-path))))
85258578 (lsp--info "Decompressed %s..." store-path))
8579+
8580+ ;; Call success callback
85268581 (funcall callback))
8527- (error (funcall error-callback err)))))))
8582+ (error
8583+ (lsp--error "Error in post-download processing: %s" err)
8584+ (funcall error-callback err))))
8585+ error-callback)))
85288586
85298587(cl-defun lsp-download-path (&key store-path binary-path set-executable? &allow-other-keys)
85308588 "Download URL and store it into STORE-PATH.
0 commit comments