@@ -8468,6 +8468,72 @@ nil."
8468
8468
8469
8469
8470
8470
;; 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
+
8471
8537
(cl-defun lsp-download-install (callback error-callback &key url asc-url pgp-key store-path decompress &allow-other-keys)
8472
8538
(let* ((url (lsp-resolve-value url))
8473
8539
(store-path (lsp-resolve-value store-path))
@@ -8479,52 +8545,44 @@ nil."
8479
8545
(:targz (concat store-path ".tar.gz"))
8480
8546
(`nil store-path)
8481
8547
(_ (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
8483
8562
(lambda ()
8563
+ ;; Success handler - continue with decompression and verification
8564
+ (lsp--info "Finished downloading %s..." download-path)
8484
8565
(condition-case err
8485
8566
(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
8494
8568
(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
8518
8572
(when decompress
8519
8573
(lsp--info "Decompressing %s..." download-path)
8520
8574
(pcase decompress
8521
- (:gzip
8522
- (lsp-gunzip download-path))
8575
+ (:gzip (lsp-gunzip download-path))
8523
8576
(:zip (lsp-unzip download-path (f-parent store-path)))
8524
8577
(:targz (lsp-tar-gz-decompress download-path (f-parent store-path))))
8525
8578
(lsp--info "Decompressed %s..." store-path))
8579
+
8580
+ ;; Call success callback
8526
8581
(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)))
8528
8586
8529
8587
(cl-defun lsp-download-path (&key store-path binary-path set-executable? &allow-other-keys)
8530
8588
"Download URL and store it into STORE-PATH.
0 commit comments