1.1--- a/lisp/ffi/alpm/alpm.asd Sun Dec 03 22:18:30 2023 -0500
1.2+++ b/lisp/ffi/alpm/alpm.asd Sun Dec 03 23:25:08 2023 -0500
1.3@@ -5,10 +5,23 @@
1.4 ;;; Commentary:
1.5
1.6 ;;; Code:
1.7-(defsystem "alpm"
1.8+(eval-when (:compile-toplevel :load-toplevel :execute)
1.9+ (require :sb-grovel))
1.10+
1.11+(defpackage :alpm.sys
1.12+ (:use :cl :asdf :sb-grovel :sb-alien))
1.13+
1.14+(in-package :alpm.sys)
1.15+
1.16+(defsystem :alpm
1.17 :description "ALPM FFI"
1.18- :defsystem-depends-on (:asdf-package-system)
1.19- :class :package-inferred-system
1.20- :depends-on (:std :alpm/pkg)
1.21- :in-order-to ((test-op (test-op "alpm/tests")))
1.22+ :depends-on (:sb-grovel :std)
1.23+ :components ((:file "pkg")
1.24+ (grovel-constants-file "constants"
1.25+ :package :alpm))
1.26+ :in-order-to ((test-op (test-op "alpm/tests"))))
1.27+
1.28+(defsystem :alpm/tests
1.29+ :depends-on (:std/rt :alpm)
1.30+ :components ((:file "tests"))
1.31 :perform (test-op (op c) (uiop:symbol-call '#:rt '#:do-tests :alpm)))
2.1--- a/lisp/ffi/alpm/constants.lisp Sun Dec 03 22:18:30 2023 -0500
2.2+++ b/lisp/ffi/alpm/constants.lisp Sun Dec 03 23:25:08 2023 -0500
2.3@@ -1,3 +1,3 @@
2.4-()
2.5+("stdlib.h" "alpm_list.h" "stdint.h" "sys/types.h" "stdarg.h" "archive.h" "archive_entry.h")
2.6
2.7 ()
3.1--- a/lisp/ffi/bqn/bqn.asd Sun Dec 03 22:18:30 2023 -0500
3.2+++ b/lisp/ffi/bqn/bqn.asd Sun Dec 03 23:25:08 2023 -0500
3.3@@ -10,10 +10,23 @@
3.4 ;; see also: https://github.com/Detegr/cbqn-sys
3.5
3.6 ;;; Code:
3.7-(defsystem "bqn"
3.8+(eval-when (:compile-toplevel :load-toplevel :execute)
3.9+ (require :sb-grovel))
3.10+
3.11+(defpackage :bqn.sys
3.12+ (:use :cl :asdf :sb-grovel :sb-alien))
3.13+
3.14+(in-package :bqn.sys)
3.15+
3.16+(defsystem :bqn
3.17 :description "CBQN FFI"
3.18- :defsystem-depends-on (:asdf-package-system)
3.19- :class :package-inferred-system
3.20- :depends-on (:std :bqn/pkg)
3.21- :in-order-to ((test-op (test-op "bqn/tests")))
3.22+ :depends-on (:sb-grovel :std)
3.23+ :components ((:file "pkg")
3.24+ (grovel-constants-file "constants"
3.25+ :package :bqn))
3.26+ :in-order-to ((test-op (test-op "bqn/tests"))))
3.27+
3.28+(defsystem :bqn/tests
3.29+ :depends-on (:std/rt :bqn)
3.30+ :components ((:file "tests"))
3.31 :perform (test-op (op c) (uiop:symbol-call '#:rt '#:do-tests :bqn)))
4.1--- a/lisp/ffi/bqn/constants.lisp Sun Dec 03 22:18:30 2023 -0500
4.2+++ b/lisp/ffi/bqn/constants.lisp Sun Dec 03 23:25:08 2023 -0500
4.3@@ -1,3 +1,11 @@
4.4-()
4.5+("stddef.h" "stdint.h" "stdbool.h" "bqnffi.h")
4.6
4.7-()
4.8+((:enum bqneltype
4.9+ ((elt-unk "elt_unk")
4.10+ (elt-i8 "elt_i8")
4.11+ (elt-i16 "elt_i16")
4.12+ (elt-i32 "elt_i32")
4.13+ (elt-f64 "elt_f64")
4.14+ (elt-c8 "elt_c8")
4.15+ (elt-c16 "elt_c16")
4.16+ (elt-c32 "elt_c32"))))
5.1--- a/lisp/ffi/k/constants.lisp Sun Dec 03 22:18:30 2023 -0500
5.2+++ b/lisp/ffi/k/constants.lisp Sun Dec 03 23:25:08 2023 -0500
5.3@@ -0,0 +1,3 @@
5.4+("k.h")
5.5+
5.6+()
6.1--- a/lisp/ffi/k/k.asd Sun Dec 03 22:18:30 2023 -0500
6.2+++ b/lisp/ffi/k/k.asd Sun Dec 03 23:25:08 2023 -0500
6.3@@ -7,10 +7,22 @@
6.4 ;;
6.5
6.6 ;;; Code:
6.7-(defsystem "k"
6.8+(eval-when (:compile-toplevel :load-toplevel :execute)
6.9+ (require :sb-grovel))
6.10+
6.11+(defpackage :k.sys
6.12+ (:use :cl :asdf :sb-grovel :sb-alien))
6.13+
6.14+(in-package :k.sys)
6.15+
6.16+(defsystem :k
6.17 :description "ngn/k FFI"
6.18- :defsystem-depends-on (:asdf-package-system)
6.19- :class :package-inferred-system
6.20- :depends-on (:std :k/pkg)
6.21- :in-order-to ((test-op (test-op "k/tests")))
6.22+ :depends-on (:sb-grovel :std)
6.23+ :components ((:file "pkg")
6.24+ (grovel-constants-file "constants"
6.25+ :package :k))
6.26+ :in-order-to ((test-op (test-op "k/tests"))))
6.27+
6.28+(defsystem :k/tests
6.29+ :depends-on (:std/rt :k)
6.30 :perform (test-op (op c) (uiop:symbol-call '#:rt '#:do-tests :k)))
7.1--- a/lisp/ffi/tree-sitter/constants.lisp Sun Dec 03 22:18:30 2023 -0500
7.2+++ b/lisp/ffi/tree-sitter/constants.lisp Sun Dec 03 23:25:08 2023 -0500
7.3@@ -0,0 +1,7 @@
7.4+("stdio.h" "stdlib.h" "stdint.h" "stdbool.h" "tree_sitter/api.h" "tree_sitter/parser.h")
7.5+
7.6+((:integer +tree-sitter-language-version+ "TREE_SITTER_LANGUAGE_VERSION" t t)
7.7+ (:integer +tree-sitter-min-compatible-language-version+ "TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION" t t)
7.8+ (:integer +ts-builtin-sym-error+ "ts_builtin_sym_error" t t)
7.9+ (:integer +ts-builtin-sym-end+ "ts_builtin_sym_end" t t)
7.10+ (:integer +tree-sitter-serialization-buffer-size+ "TREE_SITTER_SERIALIZATION_BUFFER_SIZE" t t))
8.1--- a/lisp/ffi/tree-sitter/tree-sitter.asd Sun Dec 03 22:18:30 2023 -0500
8.2+++ b/lisp/ffi/tree-sitter/tree-sitter.asd Sun Dec 03 23:25:08 2023 -0500
8.3@@ -3,9 +3,22 @@
8.4 ;; TREE-SITTER for lisp.
8.5
8.6 ;;; Code:
8.7+(eval-when (:compile-toplevel :load-toplevel :execute)
8.8+ (require :sb-grovel))
8.9+
8.10+(defpackage :tree-sitter.sys
8.11+ (:use :cl :asdf :sb-grovel :sb-alien))
8.12+
8.13+(in-package :tree-sitter.sys)
8.14+
8.15 (defsystem :tree-sitter
8.16- :class :package-inferred-system
8.17- :defsystem-depends-on (:asdf-package-system)
8.18- :depends-on (:std)
8.19- :in-order-to ((test-op (test-op :tree-sitter/tests)))
8.20+ :depends-on (:sb-grovel :std)
8.21+ :components ((:file "pkg")
8.22+ (grovel-constants-file "constants"
8.23+ :package :tree-sitter))
8.24+ :in-order-to ((test-op (test-op :tree-sitter/tests))))
8.25+
8.26+(defsystem :tree-sitter/tests
8.27+ :depends-on (:std/rt :tree-sitter)
8.28+ :components ((:file "tests"))
8.29 :perform (test-op (op c) (uiop:symbol-call '#:rt '#:do-tests :tree-sitter)))
9.1--- a/lisp/ffi/uring/constants.lisp Sun Dec 03 22:18:30 2023 -0500
9.2+++ b/lisp/ffi/uring/constants.lisp Sun Dec 03 23:25:08 2023 -0500
9.3@@ -0,0 +1,5 @@
9.4+("sys/socket.h" "sys/stat.h" "sys/uio.h" "errno.h" "signal.h" "stdbool.h"
9.5+ "inttypes.h" "time.h" "fcntl.h" "sched.h" "linux/swab.h" "liburing/compat.h"
9.6+ "liburing/io_uring.h" "liburing/io_uring_version.h" "liburing/barrier.h")
9.7+
9.8+()
10.1--- a/lisp/ffi/uring/uring.asd Sun Dec 03 22:18:30 2023 -0500
10.2+++ b/lisp/ffi/uring/uring.asd Sun Dec 03 23:25:08 2023 -0500
10.3@@ -1,7 +1,20 @@
10.4 ;;; uring.asd-*- mode: lisp; -*-
10.5+(eval-when (:compile-toplevel :load-toplevel :execute)
10.6+ (require :sb-grovel))
10.7+
10.8+(defpackage :uring.sys
10.9+ (:use :cl :asdf :sb-grovel :sb-alien))
10.10+
10.11+(in-package :uring.sys)
10.12+
10.13 (defsystem :uring
10.14- :class :package-inferred-system
10.15- :defsystem-depends-on (:asdf-package-system)
10.16- :depends-on (:std :uring/pkg)
10.17- :in-order-to ((test-op (test-op :uring/tests)))
10.18+ :depends-on (:sb-grovel :std)
10.19+ :components ((:file "pkg")
10.20+ (grovel-constants-file "constants"
10.21+ :package :uring))
10.22+ :in-order-to ((test-op (test-op :uring/tests))))
10.23+
10.24+(defsystem :uring/tests
10.25+ :depends-on (:std/rt :uring)
10.26+ :components ((:file "tests"))
10.27 :perform (test-op (op c) (uiop:symbol-call '#:rt '#:do-tests :uring)))
11.1--- a/lisp/ffi/zstd/constants.lisp Sun Dec 03 22:18:30 2023 -0500
11.2+++ b/lisp/ffi/zstd/constants.lisp Sun Dec 03 23:25:08 2023 -0500
11.3@@ -0,0 +1,39 @@
11.4+("stddef.h" "zstd_errors.h" "zstd.h")
11.5+
11.6+((:enum zstd-errorcode
11.7+ ((zstd-error-no-error "ZSTD_error_no_error")
11.8+ (zstd-error-generic "ZSTD_error_GENERIC")
11.9+ (zstd-error-prefix-unknown "ZSTD_error_prefix_unknown")
11.10+ (zstd-error-version-unsupported "ZSTD_error_version_unsupported")
11.11+ (zstd-error-frameparameter-unsupported "ZSTD_error_frameParameter_unsupported")
11.12+ (zstd-error-frameparameter-windowtoolarge "ZSTD_error_frameParameter_windowTooLarge")
11.13+ (zstd-error-corruption-detected "ZSTD_error_corruption_detected")
11.14+ (zstd-error-checksum-wrong "ZSTD_error_checksum_wrong")
11.15+ (zstd-error-literals-headerwrong "ZSTD_error_literals_headerWrong")
11.16+ (zstd-error-dictionary-corrupted "ZSTD_error_dictionary_corrupted")
11.17+ (zstd-error-dictionary-wrong "ZSTD_error_dictionary_wrong")
11.18+ (zstd-error-dictionarycreation-failed "ZSTD_error_dictionaryCreation_failed")
11.19+ (zstd-error-parameter-unsupported "ZSTD_error_parameter_unsupported")
11.20+ (zstd-error-parameter-combination-unsupported "ZSTD_error_parameter_combination_unsupported")
11.21+ (zstd-error-parameter-outofbound "ZSTD_error_parameter_outOfBound")
11.22+ (zstd-error-tablelog-toolarge "ZSTD_error_tableLog_tooLarge")
11.23+ (zstd-error-maxsymbolvalue-toolarge "ZSTD_error_maxSymbolValue_tooLarge")
11.24+ (zstd-error-maxsymbolvalue-toosmall "ZSTD_error_maxSymbolValue_tooSmall")
11.25+ (zstd-error-stabilitycondition-notrespected "ZSTD_error_stabilityCondition_notRespected")
11.26+ (zstd-error-stage-wrong "ZSTD_error_stage_wrong")
11.27+ (zstd-error-init-missing "ZSTD_error_init_missing")
11.28+ (zstd-error-memory-allocation "ZSTD_error_memory_allocation")
11.29+ (zstd-error-workspace-toosmall "ZSTD_error_workSpace_tooSmall")
11.30+ (zstd-error-dstsize-toosmall "ZSTD_error_dstSize_tooSmall")
11.31+ (zstd-error-srcsize-wrong "ZSTD_error_srcSize_wrong")
11.32+ (zstd-error-dstbuffer-null "ZSTD_error_dstBuffer_null")
11.33+ (zstd-error-noforwardprogress-destfull "ZSTD_error_noForwardProgress_destFull")
11.34+ (zstd-error-noforwardprogress-inputempty "ZSTD_error_noForwardProgress_inputEmpty")
11.35+ ;; UNSTABLE
11.36+ (zstd-error-frameindex-toolarge "ZSTD_error_frameIndex_tooLarge")
11.37+ (zstd-error-seekableio "ZSTD_error_seekableIO")
11.38+ (zstd-error-dstbuffer-wrong "ZSTD_error_dstBuffer_wrong")
11.39+ (zstd-error-srcbuffer-wrong "ZSTD_error_srcBuffer_wrong")
11.40+ (zstd-error-sequenceproducer-failed "ZSTD_error_sequenceProducer_failed")
11.41+ (zstd-error-externalsequences-invalid "ZSTD_error_externalSequences_invalid")
11.42+ (zstd-error-maxcode "ZSTD_error_maxCode"))))
12.1--- a/lisp/ffi/zstd/zstd.asd Sun Dec 03 22:18:30 2023 -0500
12.2+++ b/lisp/ffi/zstd/zstd.asd Sun Dec 03 23:25:08 2023 -0500
12.3@@ -1,7 +1,20 @@
12.4 ;;; uring.asd-*- mode: lisp; -*-
12.5+(eval-when (:compile-toplevel :load-toplevel :execute)
12.6+ (require :sb-grovel))
12.7+
12.8+(defpackage :zstd.sys
12.9+ (:use :cl :asdf :sb-grovel :sb-alien))
12.10+
12.11+(in-package :zstd.sys)
12.12+
12.13 (defsystem :zstd
12.14- :class :package-inferred-system
12.15- :defsystem-depends-on (:asdf-package-system)
12.16- :depends-on (:std :zstd/pkg)
12.17- :in-order-to ((test-op (test-op :zstd/tests)))
12.18+ :depends-on (:sb-grovel :std)
12.19+ :components ((:file "pkg")
12.20+ (grovel-constants-file "constants"
12.21+ :package :zstd))
12.22+ :in-order-to ((test-op (test-op :zstd/tests))))
12.23+
12.24+(defsystem :zstd/tests
12.25+ :depends-on (:std/rt :zstd)
12.26+ :components ((:file "tests"))
12.27 :perform (test-op (op c) (uiop:symbol-call '#:rt '#:do-tests :zstd)))
13.1--- a/rust/app/cli/cc-init/main.rs Sun Dec 03 22:18:30 2023 -0500
13.2+++ b/rust/app/cli/cc-init/main.rs Sun Dec 03 23:25:08 2023 -0500
13.3@@ -1,12 +1,16 @@
13.4 use clap::Parser;
13.5-use std::path::Path;
13.6-use logger::{Logger, info, trace};
13.7-use util::{Result, Url};
13.8-use util::{cli::log_level_str_from_cli};
13.9 use dl::{download_to_path_with_backend, Backend, TlsBackend};
13.10-use std::env;
13.11+use logger::{info, trace, Logger};
13.12+use std::{env, path::Path};
13.13+use util::{cli::log_level_str_from_cli, Result, Url};
13.14
13.15-pub const ABOUT: &str = concat!("cc-init ", env!("CORE_VERSION"), " (", env!("CORE_TARGET"), ")");
13.16+pub const ABOUT: &str = concat!(
13.17+ "cc-init ",
13.18+ env!("CORE_VERSION"),
13.19+ " (",
13.20+ env!("CORE_TARGET"),
13.21+ ")"
13.22+);
13.23
13.24 #[derive(Debug, Parser)]
13.25 #[command(name="cc-init",author, version=env!("CORE_VERSION"), about=ABOUT)]
13.26@@ -19,7 +23,7 @@
13.27 level: u8,
13.28 }
13.29
13.30-fn dl<P:AsRef<Path> + std::fmt::Debug>(url:&str,dst:P) -> Result<()> {
13.31+fn dl<P: AsRef<Path> + std::fmt::Debug>(url: &str, dst: P) -> Result<()> {
13.32 info!("downloading {url} -> {dst:?}");
13.33 let url = Url::parse(url)?;
13.34 download_to_path_with_backend(
13.35@@ -27,7 +31,8 @@
13.36 &url,
13.37 dst.as_ref(),
13.38 true,
13.39- None)
13.40+ None,
13.41+ )
13.42 }
13.43
13.44 fn main() -> Result<()> {
14.1--- a/rust/app/cli/krypt/main.rs Sun Dec 03 22:18:30 2023 -0500
14.2+++ b/rust/app/cli/krypt/main.rs Sun Dec 03 23:25:08 2023 -0500
14.3@@ -3,8 +3,7 @@
14.4 use logger::{debug, info, trace, warn, Logger};
14.5 use obj::Objective;
14.6 use std::path::PathBuf;
14.7-use util::Result;
14.8-use util::cli::log_level_str_from_cli;
14.9+use util::{cli::log_level_str_from_cli, Result};
14.10 #[derive(Debug, Parser)]
14.11 #[command(name="krypt",author, version, about, long_about = None)]
14.12 struct Cli {
15.1--- a/rust/app/cli/mailman/main.rs Sun Dec 03 22:18:30 2023 -0500
15.2+++ b/rust/app/cli/mailman/main.rs Sun Dec 03 23:25:08 2023 -0500
15.3@@ -1,9 +1,8 @@
15.4 use clap::{Parser, Subcommand};
15.5-use logger::{Logger,trace};
15.6+use logger::{trace, Logger};
15.7 // use obj::Objective;
15.8 use std::path::PathBuf;
15.9-use util::Result;
15.10-use util::cli::log_level_str_from_cli;
15.11+use util::{cli::log_level_str_from_cli, Result};
15.12 // use jmap_client::{client::Client, core::query::Filter, email, mailbox};
15.13
15.14 #[derive(Debug, Parser)]
16.1--- a/rust/lib/dl/src/errors.rs Sun Dec 03 22:18:30 2023 -0500
16.2+++ b/rust/lib/dl/src/errors.rs Sun Dec 03 23:25:08 2023 -0500
16.3@@ -2,20 +2,20 @@
16.4
16.5 #[derive(Debug, Error)]
16.6 pub enum DownloadError {
16.7- #[error("http request returned an unsuccessful status code: {0}")]
16.8- HttpStatus(u32),
16.9- #[error("file not found")]
16.10- FileNotFound,
16.11- #[error("download backend '{0}' unavailable")]
16.12- BackendUnavailable(&'static str),
16.13- #[error("{0}")]
16.14- Message(String),
16.15- #[error(transparent)]
16.16- IoError(#[from] std::io::Error),
16.17- #[cfg(feature = "reqwest-backend")]
16.18- #[error(transparent)]
16.19- Reqwest(#[from] ::reqwest::Error),
16.20- #[cfg(feature = "curl-backend")]
16.21- #[error(transparent)]
16.22- CurlError(#[from] curl::Error),
16.23+ #[error("http request returned an unsuccessful status code: {0}")]
16.24+ HttpStatus(u32),
16.25+ #[error("file not found")]
16.26+ FileNotFound,
16.27+ #[error("download backend '{0}' unavailable")]
16.28+ BackendUnavailable(&'static str),
16.29+ #[error("{0}")]
16.30+ Message(String),
16.31+ #[error(transparent)]
16.32+ IoError(#[from] std::io::Error),
16.33+ #[cfg(feature = "reqwest-backend")]
16.34+ #[error(transparent)]
16.35+ Reqwest(#[from] ::reqwest::Error),
16.36+ #[cfg(feature = "curl-backend")]
16.37+ #[error(transparent)]
16.38+ CurlError(#[from] curl::Error),
16.39 }
17.1--- a/rust/lib/dl/src/lib.rs Sun Dec 03 22:18:30 2023 -0500
17.2+++ b/rust/lib/dl/src/lib.rs Sun Dec 03 23:25:08 2023 -0500
17.3@@ -1,8 +1,8 @@
17.4 //! Easy file downloading
17.5 #![deny(rust_2018_idioms)]
17.6
17.7+use anyhow::{Context, Result};
17.8 use std::path::Path;
17.9-use anyhow::{Context, Result};
17.10 use url::Url;
17.11 mod errors;
17.12 pub use crate::errors::*;
17.13@@ -12,127 +12,135 @@
17.14
17.15 #[derive(Debug, Copy, Clone)]
17.16 pub enum Backend {
17.17- Curl,
17.18- Reqwest(TlsBackend),
17.19+ Curl,
17.20+ Reqwest(TlsBackend),
17.21 }
17.22
17.23 #[derive(Debug, Copy, Clone)]
17.24 pub enum TlsBackend {
17.25- Rustls,
17.26- Default,
17.27+ Rustls,
17.28+ Default,
17.29 }
17.30
17.31 #[derive(Debug, Copy, Clone)]
17.32 pub enum Event<'a> {
17.33- ResumingPartialDownload,
17.34- /// Received the Content-Length of the to-be downloaded data.
17.35- DownloadContentLengthReceived(u64),
17.36- /// Received some data.
17.37- DownloadDataReceived(&'a [u8]),
17.38+ ResumingPartialDownload,
17.39+ /// Received the Content-Length of the to-be downloaded data.
17.40+ DownloadContentLengthReceived(u64),
17.41+ /// Received some data.
17.42+ DownloadDataReceived(&'a [u8]),
17.43 }
17.44
17.45 fn download_with_backend(
17.46- backend: Backend,
17.47- url: &Url,
17.48- resume_from: u64,
17.49- callback: &dyn Fn(Event<'_>) -> Result<()>,
17.50+ backend: Backend,
17.51+ url: &Url,
17.52+ resume_from: u64,
17.53+ callback: &dyn Fn(Event<'_>) -> Result<()>,
17.54 ) -> Result<()> {
17.55- match backend {
17.56- Backend::Curl => curl::download(url, resume_from, callback),
17.57- Backend::Reqwest(tls) => reqwest_be::download(url, resume_from, callback, tls),
17.58+ match backend {
17.59+ Backend::Curl => curl::download(url, resume_from, callback),
17.60+ Backend::Reqwest(tls) => {
17.61+ reqwest_be::download(url, resume_from, callback, tls)
17.62 }
17.63+ }
17.64 }
17.65
17.66 type DownloadCallback<'a> = &'a dyn Fn(Event<'_>) -> Result<()>;
17.67
17.68 pub fn download_to_path_with_backend(
17.69- backend: Backend,
17.70- url: &Url,
17.71- path: &Path,
17.72- resume_from_partial: bool,
17.73- callback: Option<DownloadCallback<'_>>,
17.74+ backend: Backend,
17.75+ url: &Url,
17.76+ path: &Path,
17.77+ resume_from_partial: bool,
17.78+ callback: Option<DownloadCallback<'_>>,
17.79 ) -> Result<()> {
17.80- use std::cell::RefCell;
17.81- use std::fs::remove_file;
17.82- use std::fs::OpenOptions;
17.83- use std::io::{Read, Seek, SeekFrom, Write};
17.84+ use std::{
17.85+ cell::RefCell,
17.86+ fs::{remove_file, OpenOptions},
17.87+ io::{Read, Seek, SeekFrom, Write},
17.88+ };
17.89
17.90- || -> Result<()> {
17.91- let (file, resume_from) = if resume_from_partial {
17.92- let possible_partial = OpenOptions::new().read(true).open(path);
17.93+ || -> Result<()> {
17.94+ let (file, resume_from) = if resume_from_partial {
17.95+ let possible_partial = OpenOptions::new().read(true).open(path);
17.96
17.97- let downloaded_so_far = if let Ok(mut partial) = possible_partial {
17.98- if let Some(cb) = callback {
17.99- cb(Event::ResumingPartialDownload)?;
17.100+ let downloaded_so_far = if let Ok(mut partial) = possible_partial {
17.101+ if let Some(cb) = callback {
17.102+ cb(Event::ResumingPartialDownload)?;
17.103
17.104- let mut buf = vec![0; 32768];
17.105- let mut downloaded_so_far = 0;
17.106- loop {
17.107- let n = partial.read(&mut buf)?;
17.108- downloaded_so_far += n as u64;
17.109- if n == 0 {
17.110- break;
17.111- }
17.112- cb(Event::DownloadDataReceived(&buf[..n]))?;
17.113- }
17.114+ let mut buf = vec![0; 32768];
17.115+ let mut downloaded_so_far = 0;
17.116+ loop {
17.117+ let n = partial.read(&mut buf)?;
17.118+ downloaded_so_far += n as u64;
17.119+ if n == 0 {
17.120+ break;
17.121+ }
17.122+ cb(Event::DownloadDataReceived(&buf[..n]))?;
17.123+ }
17.124
17.125- downloaded_so_far
17.126- } else {
17.127- let file_info = partial.metadata()?;
17.128- file_info.len()
17.129- }
17.130- } else {
17.131- 0
17.132- };
17.133+ downloaded_so_far
17.134+ } else {
17.135+ let file_info = partial.metadata()?;
17.136+ file_info.len()
17.137+ }
17.138+ } else {
17.139+ 0
17.140+ };
17.141+
17.142+ let mut possible_partial = OpenOptions::new()
17.143+ .write(true)
17.144+ .create(true)
17.145+ .open(path)
17.146+ .context("error opening file for download")?;
17.147
17.148- let mut possible_partial = OpenOptions::new()
17.149- .write(true)
17.150- .create(true)
17.151- .open(path)
17.152- .context("error opening file for download")?;
17.153-
17.154- possible_partial.seek(SeekFrom::End(0))?;
17.155+ possible_partial.seek(SeekFrom::End(0))?;
17.156
17.157- (possible_partial, downloaded_so_far)
17.158- } else {
17.159- (
17.160- OpenOptions::new()
17.161- .write(true)
17.162- .create(true)
17.163- .open(path)
17.164- .context("error creating file for download")?,
17.165- 0,
17.166- )
17.167- };
17.168+ (possible_partial, downloaded_so_far)
17.169+ } else {
17.170+ (
17.171+ OpenOptions::new()
17.172+ .write(true)
17.173+ .create(true)
17.174+ .open(path)
17.175+ .context("error creating file for download")?,
17.176+ 0,
17.177+ )
17.178+ };
17.179
17.180- let file = RefCell::new(file);
17.181+ let file = RefCell::new(file);
17.182
17.183- download_with_backend(backend, url, resume_from, &|event| {
17.184- if let Event::DownloadDataReceived(data) = event {
17.185- file.borrow_mut()
17.186- .write_all(data)
17.187- .context("unable to write download to disk")?;
17.188- }
17.189- match callback {
17.190- Some(cb) => cb(event),
17.191- None => Ok(()),
17.192- }
17.193- })?;
17.194+ download_with_backend(backend, url, resume_from, &|event| {
17.195+ if let Event::DownloadDataReceived(data) = event {
17.196+ file
17.197+ .borrow_mut()
17.198+ .write_all(data)
17.199+ .context("unable to write download to disk")?;
17.200+ }
17.201+ match callback {
17.202+ Some(cb) => cb(event),
17.203+ None => Ok(()),
17.204+ }
17.205+ })?;
17.206
17.207- file.borrow_mut()
17.208- .sync_data()
17.209- .context("unable to sync download to disk")?;
17.210+ file
17.211+ .borrow_mut()
17.212+ .sync_data()
17.213+ .context("unable to sync download to disk")?;
17.214
17.215- Ok(())
17.216- }()
17.217- .map_err(|e| {
17.218- // TODO: We currently clear up the cached download on any error, should we restrict it to a subset?
17.219- if let Err(file_err) = remove_file(path).context("cleaning up cached downloads") {
17.220- file_err.context(e)
17.221- } else {
17.222- e
17.223- }
17.224- })
17.225+ Ok(())
17.226+ }()
17.227+ .map_err(|e| {
17.228+ // TODO: We currently clear up the cached download on any error, should we
17.229+ // restrict it to a subset?
17.230+ if let Err(file_err) =
17.231+ remove_file(path).context("cleaning up cached downloads")
17.232+ {
17.233+ file_err.context(e)
17.234+ } else {
17.235+ e
17.236+ }
17.237+ })
17.238 }
17.239
17.240 #[cfg(all(not(feature = "reqwest-backend"), not(feature = "curl-backend")))]
17.241@@ -142,316 +150,320 @@
17.242 /// stack via libcurl
17.243 #[cfg(feature = "curl-backend")]
17.244 pub mod curl {
17.245- use std::cell::RefCell;
17.246- use std::str;
17.247- use std::time::Duration;
17.248+ use std::{cell::RefCell, str, time::Duration};
17.249
17.250- use anyhow::{Context, Result};
17.251- use curl::easy::Easy;
17.252- use url::Url;
17.253+ use anyhow::{Context, Result};
17.254+ use curl::easy::Easy;
17.255+ use url::Url;
17.256
17.257- use super::Event;
17.258- use crate::errors::*;
17.259+ use super::Event;
17.260+ use crate::errors::*;
17.261
17.262- pub fn download(
17.263- url: &Url,
17.264- resume_from: u64,
17.265- callback: &dyn Fn(Event<'_>) -> Result<()>,
17.266- ) -> Result<()> {
17.267- // Fetch either a cached libcurl handle (which will preserve open
17.268- // connections) or create a new one if it isn't listed.
17.269- //
17.270- // Once we've acquired it, reset the lifetime from 'static to our local
17.271- // scope.
17.272- thread_local!(static EASY: RefCell<Easy> = RefCell::new(Easy::new()));
17.273- EASY.with(|handle| {
17.274- let mut handle = handle.borrow_mut();
17.275+ pub fn download(
17.276+ url: &Url,
17.277+ resume_from: u64,
17.278+ callback: &dyn Fn(Event<'_>) -> Result<()>,
17.279+ ) -> Result<()> {
17.280+ // Fetch either a cached libcurl handle (which will preserve open
17.281+ // connections) or create a new one if it isn't listed.
17.282+ //
17.283+ // Once we've acquired it, reset the lifetime from 'static to our local
17.284+ // scope.
17.285+ thread_local!(static EASY: RefCell<Easy> = RefCell::new(Easy::new()));
17.286+ EASY.with(|handle| {
17.287+ let mut handle = handle.borrow_mut();
17.288
17.289- handle.url(url.as_ref())?;
17.290- handle.follow_location(true)?;
17.291- handle.useragent(super::USER_AGENT)?;
17.292+ handle.url(url.as_ref())?;
17.293+ handle.follow_location(true)?;
17.294+ handle.useragent(super::USER_AGENT)?;
17.295
17.296- if resume_from > 0 {
17.297- handle.resume_from(resume_from)?;
17.298- } else {
17.299- // an error here indicates that the range header isn't supported by underlying curl,
17.300- // so there's nothing to "clear" - safe to ignore this error.
17.301- let _ = handle.resume_from(0);
17.302- }
17.303+ if resume_from > 0 {
17.304+ handle.resume_from(resume_from)?;
17.305+ } else {
17.306+ // an error here indicates that the range header isn't supported by
17.307+ // underlying curl, so there's nothing to "clear" - safe to
17.308+ // ignore this error.
17.309+ let _ = handle.resume_from(0);
17.310+ }
17.311
17.312- // Take at most 30s to connect
17.313- handle.connect_timeout(Duration::new(30, 0))?;
17.314+ // Take at most 30s to connect
17.315+ handle.connect_timeout(Duration::new(30, 0))?;
17.316
17.317- {
17.318- let cberr = RefCell::new(None);
17.319- let mut transfer = handle.transfer();
17.320+ {
17.321+ let cberr = RefCell::new(None);
17.322+ let mut transfer = handle.transfer();
17.323
17.324- // Data callback for libcurl which is called with data that's
17.325- // downloaded. We just feed it into our hasher and also write it out
17.326- // to disk.
17.327- transfer.write_function(|data| {
17.328- match callback(Event::DownloadDataReceived(data)) {
17.329- Ok(()) => Ok(data.len()),
17.330- Err(e) => {
17.331- *cberr.borrow_mut() = Some(e);
17.332- Ok(0)
17.333- }
17.334- }
17.335- })?;
17.336+ // Data callback for libcurl which is called with data that's
17.337+ // downloaded. We just feed it into our hasher and also write it out
17.338+ // to disk.
17.339+ transfer.write_function(|data| {
17.340+ match callback(Event::DownloadDataReceived(data)) {
17.341+ Ok(()) => Ok(data.len()),
17.342+ Err(e) => {
17.343+ *cberr.borrow_mut() = Some(e);
17.344+ Ok(0)
17.345+ }
17.346+ }
17.347+ })?;
17.348
17.349- // Listen for headers and parse out a `Content-Length` (case-insensitive) if it
17.350- // comes so we know how much we're downloading.
17.351- transfer.header_function(|header| {
17.352- if let Ok(data) = str::from_utf8(header) {
17.353- let prefix = "content-length: ";
17.354- if data.to_ascii_lowercase().starts_with(prefix) {
17.355- if let Ok(s) = data[prefix.len()..].trim().parse::<u64>() {
17.356- let msg = Event::DownloadContentLengthReceived(s + resume_from);
17.357- match callback(msg) {
17.358- Ok(()) => (),
17.359- Err(e) => {
17.360- *cberr.borrow_mut() = Some(e);
17.361- return false;
17.362- }
17.363- }
17.364- }
17.365- }
17.366- }
17.367- true
17.368- })?;
17.369+ // Listen for headers and parse out a `Content-Length`
17.370+ // (case-insensitive) if it comes so we know how much we're
17.371+ // downloading.
17.372+ transfer.header_function(|header| {
17.373+ if let Ok(data) = str::from_utf8(header) {
17.374+ let prefix = "content-length: ";
17.375+ if data.to_ascii_lowercase().starts_with(prefix) {
17.376+ if let Ok(s) = data[prefix.len()..].trim().parse::<u64>() {
17.377+ let msg = Event::DownloadContentLengthReceived(s + resume_from);
17.378+ match callback(msg) {
17.379+ Ok(()) => (),
17.380+ Err(e) => {
17.381+ *cberr.borrow_mut() = Some(e);
17.382+ return false;
17.383+ }
17.384+ }
17.385+ }
17.386+ }
17.387+ }
17.388+ true
17.389+ })?;
17.390
17.391- // If an error happens check to see if we had a filesystem error up
17.392- // in `cberr`, but we always want to punt it up.
17.393- transfer.perform().or_else(|e| {
17.394- // If the original error was generated by one of our
17.395- // callbacks, return it.
17.396- match cberr.borrow_mut().take() {
17.397- Some(cberr) => Err(cberr),
17.398- None => {
17.399- // Otherwise, return the error from curl
17.400- if e.is_file_couldnt_read_file() {
17.401- Err(e).context(DownloadError::FileNotFound)
17.402- } else {
17.403- Err(e).context("error during download")?
17.404- }
17.405- }
17.406- }
17.407- })?;
17.408+ // If an error happens check to see if we had a filesystem error up
17.409+ // in `cberr`, but we always want to punt it up.
17.410+ transfer.perform().or_else(|e| {
17.411+ // If the original error was generated by one of our
17.412+ // callbacks, return it.
17.413+ match cberr.borrow_mut().take() {
17.414+ Some(cberr) => Err(cberr),
17.415+ None => {
17.416+ // Otherwise, return the error from curl
17.417+ if e.is_file_couldnt_read_file() {
17.418+ Err(e).context(DownloadError::FileNotFound)
17.419+ } else {
17.420+ Err(e).context("error during download")?
17.421+ }
17.422 }
17.423+ }
17.424+ })?;
17.425+ }
17.426
17.427- // If we didn't get a 20x or 0 ("OK" for files) then return an error
17.428- let code = handle.response_code()?;
17.429- match code {
17.430- 0 | 200..=299 => {}
17.431- _ => {
17.432- return Err(DownloadError::HttpStatus(code).into());
17.433- }
17.434- };
17.435+ // If we didn't get a 20x or 0 ("OK" for files) then return an error
17.436+ let code = handle.response_code()?;
17.437+ match code {
17.438+ 0 | 200..=299 => {}
17.439+ _ => {
17.440+ return Err(DownloadError::HttpStatus(code).into());
17.441+ }
17.442+ };
17.443
17.444- Ok(())
17.445- })
17.446- }
17.447+ Ok(())
17.448+ })
17.449+ }
17.450 }
17.451
17.452 #[cfg(feature = "reqwest-backend")]
17.453 pub mod reqwest_be {
17.454- #[cfg(all(
17.455- not(feature = "reqwest-rustls-tls"),
17.456- not(feature = "reqwest-default-tls")
17.457- ))]
17.458- compile_error!("Must select a reqwest TLS backend");
17.459-
17.460- use std::io;
17.461- use std::time::Duration;
17.462+ #[cfg(all(
17.463+ not(feature = "reqwest-rustls-tls"),
17.464+ not(feature = "reqwest-default-tls")
17.465+ ))]
17.466+ compile_error!("Must select a reqwest TLS backend");
17.467
17.468- use anyhow::{anyhow, Context, Result};
17.469- #[cfg(any(feature = "reqwest-rustls-tls", feature = "reqwest-default-tls"))]
17.470- use once_cell::sync::Lazy;
17.471- use reqwest::blocking::{Client, ClientBuilder, Response};
17.472- use reqwest::{header, Proxy};
17.473- use url::Url;
17.474-
17.475- use super::Event;
17.476- use super::TlsBackend;
17.477- use crate::errors::*;
17.478+ use std::{io, time::Duration};
17.479
17.480- pub fn download(
17.481- url: &Url,
17.482- resume_from: u64,
17.483- callback: &dyn Fn(Event<'_>) -> Result<()>,
17.484- tls: TlsBackend,
17.485- ) -> Result<()> {
17.486- // Short-circuit reqwest for the "file:" URL scheme
17.487- if download_from_file_url(url, resume_from, callback)? {
17.488- return Ok(());
17.489- }
17.490-
17.491- let mut res = request(url, resume_from, tls).context("failed to make network request")?;
17.492-
17.493- if !res.status().is_success() {
17.494- let code: u16 = res.status().into();
17.495- return Err(anyhow!(DownloadError::HttpStatus(u32::from(code))));
17.496- }
17.497+ use anyhow::{anyhow, Context, Result};
17.498+ #[cfg(any(
17.499+ feature = "reqwest-rustls-tls",
17.500+ feature = "reqwest-default-tls"
17.501+ ))]
17.502+ use once_cell::sync::Lazy;
17.503+ use reqwest::{
17.504+ blocking::{Client, ClientBuilder, Response},
17.505+ header, Proxy,
17.506+ };
17.507+ use url::Url;
17.508
17.509- let buffer_size = 0x10000;
17.510- let mut buffer = vec![0u8; buffer_size];
17.511-
17.512- if let Some(len) = res.headers().get(header::CONTENT_LENGTH) {
17.513- // TODO possible issues during unwrap?
17.514- let len = len.to_str().unwrap().parse::<u64>().unwrap() + resume_from;
17.515- callback(Event::DownloadContentLengthReceived(len))?;
17.516- }
17.517+ use super::{Event, TlsBackend};
17.518+ use crate::errors::*;
17.519
17.520- loop {
17.521- let bytes_read = io::Read::read(&mut res, &mut buffer)?;
17.522-
17.523- if bytes_read != 0 {
17.524- callback(Event::DownloadDataReceived(&buffer[0..bytes_read]))?;
17.525- } else {
17.526- return Ok(());
17.527- }
17.528- }
17.529+ pub fn download(
17.530+ url: &Url,
17.531+ resume_from: u64,
17.532+ callback: &dyn Fn(Event<'_>) -> Result<()>,
17.533+ tls: TlsBackend,
17.534+ ) -> Result<()> {
17.535+ // Short-circuit reqwest for the "file:" URL scheme
17.536+ if download_from_file_url(url, resume_from, callback)? {
17.537+ return Ok(());
17.538 }
17.539
17.540- fn client_generic() -> ClientBuilder {
17.541- Client::builder()
17.542- .gzip(false)
17.543- .user_agent(super::USER_AGENT)
17.544- .proxy(Proxy::custom(env_proxy))
17.545- .timeout(Duration::from_secs(30))
17.546+ let mut res = request(url, resume_from, tls)
17.547+ .context("failed to make network request")?;
17.548+
17.549+ if !res.status().is_success() {
17.550+ let code: u16 = res.status().into();
17.551+ return Err(anyhow!(DownloadError::HttpStatus(u32::from(code))));
17.552+ }
17.553+
17.554+ let buffer_size = 0x10000;
17.555+ let mut buffer = vec![0u8; buffer_size];
17.556+
17.557+ if let Some(len) = res.headers().get(header::CONTENT_LENGTH) {
17.558+ // TODO possible issues during unwrap?
17.559+ let len = len.to_str().unwrap().parse::<u64>().unwrap() + resume_from;
17.560+ callback(Event::DownloadContentLengthReceived(len))?;
17.561 }
17.562
17.563- #[cfg(feature = "reqwest-rustls-tls")]
17.564- static CLIENT_RUSTLS_TLS: Lazy<Client> = Lazy::new(|| {
17.565- let catcher = || client_generic().use_rustls_tls().build();
17.566+ loop {
17.567+ let bytes_read = io::Read::read(&mut res, &mut buffer)?;
17.568+
17.569+ if bytes_read != 0 {
17.570+ callback(Event::DownloadDataReceived(&buffer[0..bytes_read]))?;
17.571+ } else {
17.572+ return Ok(());
17.573+ }
17.574+ }
17.575+ }
17.576
17.577- // woah, an unwrap?!
17.578- // It's OK. This is the same as what is happening in curl.
17.579- //
17.580- // The curl::Easy::new() internally assert!s that the initialized
17.581- // Easy is not null. Inside reqwest, the errors here would be from
17.582- // the TLS library returning a null pointer as well.
17.583- catcher().unwrap()
17.584- });
17.585+ fn client_generic() -> ClientBuilder {
17.586+ Client::builder()
17.587+ .gzip(false)
17.588+ .user_agent(super::USER_AGENT)
17.589+ .proxy(Proxy::custom(env_proxy))
17.590+ .timeout(Duration::from_secs(30))
17.591+ }
17.592+
17.593+ #[cfg(feature = "reqwest-rustls-tls")]
17.594+ static CLIENT_RUSTLS_TLS: Lazy<Client> = Lazy::new(|| {
17.595+ let catcher = || client_generic().use_rustls_tls().build();
17.596+
17.597+ // woah, an unwrap?!
17.598+ // It's OK. This is the same as what is happening in curl.
17.599+ //
17.600+ // The curl::Easy::new() internally assert!s that the initialized
17.601+ // Easy is not null. Inside reqwest, the errors here would be from
17.602+ // the TLS library returning a null pointer as well.
17.603+ catcher().unwrap()
17.604+ });
17.605+
17.606+ #[cfg(feature = "reqwest-default-tls")]
17.607+ static CLIENT_DEFAULT_TLS: Lazy<Client> = Lazy::new(|| {
17.608+ let catcher = || client_generic().build();
17.609
17.610- #[cfg(feature = "reqwest-default-tls")]
17.611- static CLIENT_DEFAULT_TLS: Lazy<Client> = Lazy::new(|| {
17.612- let catcher = || client_generic().build();
17.613+ // woah, an unwrap?!
17.614+ // It's OK. This is the same as what is happening in curl.
17.615+ //
17.616+ // The curl::Easy::new() internally assert!s that the initialized
17.617+ // Easy is not null. Inside reqwest, the errors here would be from
17.618+ // the TLS library returning a null pointer as well.
17.619+ catcher().unwrap()
17.620+ });
17.621+
17.622+ fn env_proxy(url: &Url) -> Option<Url> {
17.623+ env_proxy::for_url(url).to_url()
17.624+ }
17.625
17.626- // woah, an unwrap?!
17.627- // It's OK. This is the same as what is happening in curl.
17.628- //
17.629- // The curl::Easy::new() internally assert!s that the initialized
17.630- // Easy is not null. Inside reqwest, the errors here would be from
17.631- // the TLS library returning a null pointer as well.
17.632- catcher().unwrap()
17.633- });
17.634+ fn request(
17.635+ url: &Url,
17.636+ resume_from: u64,
17.637+ backend: TlsBackend,
17.638+ ) -> Result<Response, DownloadError> {
17.639+ let client: &Client = match backend {
17.640+ #[cfg(feature = "reqwest-rustls-tls")]
17.641+ TlsBackend::Rustls => &CLIENT_RUSTLS_TLS,
17.642+ #[cfg(not(feature = "reqwest-rustls-tls"))]
17.643+ TlsBackend::Rustls => {
17.644+ return Err(DownloadError::BackendUnavailable("reqwest rustls"));
17.645+ }
17.646+ #[cfg(feature = "reqwest-default-tls")]
17.647+ TlsBackend::Default => &CLIENT_DEFAULT_TLS,
17.648+ #[cfg(not(feature = "reqwest-default-tls"))]
17.649+ TlsBackend::Default => {
17.650+ return Err(DownloadError::BackendUnavailable("reqwest default TLS"));
17.651+ }
17.652+ };
17.653+ let mut req = client.get(url.as_str());
17.654
17.655- fn env_proxy(url: &Url) -> Option<Url> {
17.656- env_proxy::for_url(url).to_url()
17.657+ if resume_from != 0 {
17.658+ req = req.header(header::RANGE, format!("bytes={resume_from}-"));
17.659 }
17.660
17.661- fn request(
17.662- url: &Url,
17.663- resume_from: u64,
17.664- backend: TlsBackend,
17.665- ) -> Result<Response, DownloadError> {
17.666- let client: &Client = match backend {
17.667- #[cfg(feature = "reqwest-rustls-tls")]
17.668- TlsBackend::Rustls => &CLIENT_RUSTLS_TLS,
17.669- #[cfg(not(feature = "reqwest-rustls-tls"))]
17.670- TlsBackend::Rustls => {
17.671- return Err(DownloadError::BackendUnavailable("reqwest rustls"));
17.672- }
17.673- #[cfg(feature = "reqwest-default-tls")]
17.674- TlsBackend::Default => &CLIENT_DEFAULT_TLS,
17.675- #[cfg(not(feature = "reqwest-default-tls"))]
17.676- TlsBackend::Default => {
17.677- return Err(DownloadError::BackendUnavailable("reqwest default TLS"));
17.678- }
17.679- };
17.680- let mut req = client.get(url.as_str());
17.681+ Ok(req.send()?)
17.682+ }
17.683
17.684- if resume_from != 0 {
17.685- req = req.header(header::RANGE, format!("bytes={resume_from}-"));
17.686- }
17.687-
17.688- Ok(req.send()?)
17.689- }
17.690+ fn download_from_file_url(
17.691+ url: &Url,
17.692+ resume_from: u64,
17.693+ callback: &dyn Fn(Event<'_>) -> Result<()>,
17.694+ ) -> Result<bool> {
17.695+ use std::fs;
17.696
17.697- fn download_from_file_url(
17.698- url: &Url,
17.699- resume_from: u64,
17.700- callback: &dyn Fn(Event<'_>) -> Result<()>,
17.701- ) -> Result<bool> {
17.702- use std::fs;
17.703+ // The file scheme is mostly for use by tests to mock the dist server
17.704+ if url.scheme() == "file" {
17.705+ let src = url.to_file_path().map_err(|_| {
17.706+ DownloadError::Message(format!("bogus file url: '{url}'"))
17.707+ })?;
17.708+ if !src.is_file() {
17.709+ // Because some of rustup's logic depends on checking
17.710+ // the error when a downloaded file doesn't exist, make
17.711+ // the file case return the same error value as the
17.712+ // network case.
17.713+ return Err(anyhow!(DownloadError::FileNotFound));
17.714+ }
17.715
17.716- // The file scheme is mostly for use by tests to mock the dist server
17.717- if url.scheme() == "file" {
17.718- let src = url
17.719- .to_file_path()
17.720- .map_err(|_| DownloadError::Message(format!("bogus file url: '{url}'")))?;
17.721- if !src.is_file() {
17.722- // Because some of rustup's logic depends on checking
17.723- // the error when a downloaded file doesn't exist, make
17.724- // the file case return the same error value as the
17.725- // network case.
17.726- return Err(anyhow!(DownloadError::FileNotFound));
17.727- }
17.728+ let mut f =
17.729+ fs::File::open(src).context("unable to open downloaded file")?;
17.730+ io::Seek::seek(&mut f, io::SeekFrom::Start(resume_from))?;
17.731
17.732- let mut f = fs::File::open(src).context("unable to open downloaded file")?;
17.733- io::Seek::seek(&mut f, io::SeekFrom::Start(resume_from))?;
17.734+ let mut buffer = vec![0u8; 0x10000];
17.735+ loop {
17.736+ let bytes_read = io::Read::read(&mut f, &mut buffer)?;
17.737+ if bytes_read == 0 {
17.738+ break;
17.739+ }
17.740+ callback(Event::DownloadDataReceived(&buffer[0..bytes_read]))?;
17.741+ }
17.742
17.743- let mut buffer = vec![0u8; 0x10000];
17.744- loop {
17.745- let bytes_read = io::Read::read(&mut f, &mut buffer)?;
17.746- if bytes_read == 0 {
17.747- break;
17.748- }
17.749- callback(Event::DownloadDataReceived(&buffer[0..bytes_read]))?;
17.750- }
17.751-
17.752- Ok(true)
17.753- } else {
17.754- Ok(false)
17.755- }
17.756+ Ok(true)
17.757+ } else {
17.758+ Ok(false)
17.759 }
17.760+ }
17.761 }
17.762
17.763 #[cfg(not(feature = "curl-backend"))]
17.764 pub mod curl {
17.765
17.766- use anyhow::{anyhow, Result};
17.767+ use anyhow::{anyhow, Result};
17.768
17.769- use super::Event;
17.770- use crate::errors::*;
17.771- use url::Url;
17.772+ use super::Event;
17.773+ use crate::errors::*;
17.774+ use url::Url;
17.775
17.776- pub fn download(
17.777- _url: &Url,
17.778- _resume_from: u64,
17.779- _callback: &dyn Fn(Event<'_>) -> Result<()>,
17.780- ) -> Result<()> {
17.781- Err(anyhow!(DownloadError::BackendUnavailable("curl")))
17.782- }
17.783+ pub fn download(
17.784+ _url: &Url,
17.785+ _resume_from: u64,
17.786+ _callback: &dyn Fn(Event<'_>) -> Result<()>,
17.787+ ) -> Result<()> {
17.788+ Err(anyhow!(DownloadError::BackendUnavailable("curl")))
17.789+ }
17.790 }
17.791
17.792 #[cfg(not(feature = "reqwest-backend"))]
17.793 pub mod reqwest_be {
17.794
17.795- use anyhow::{anyhow, Result};
17.796+ use anyhow::{anyhow, Result};
17.797
17.798- use super::Event;
17.799- use super::TlsBackend;
17.800- use crate::errors::*;
17.801- use url::Url;
17.802+ use super::{Event, TlsBackend};
17.803+ use crate::errors::*;
17.804+ use url::Url;
17.805
17.806- pub fn download(
17.807- _url: &Url,
17.808- _resume_from: u64,
17.809- _callback: &dyn Fn(Event<'_>) -> Result<()>,
17.810- _tls: TlsBackend,
17.811- ) -> Result<()> {
17.812- Err(anyhow!(DownloadError::BackendUnavailable("reqwest")))
17.813- }
17.814+ pub fn download(
17.815+ _url: &Url,
17.816+ _resume_from: u64,
17.817+ _callback: &dyn Fn(Event<'_>) -> Result<()>,
17.818+ _tls: TlsBackend,
17.819+ ) -> Result<()> {
17.820+ Err(anyhow!(DownloadError::BackendUnavailable("reqwest")))
17.821+ }
17.822 }
18.1--- a/rust/lib/dl/tests/download-curl-resume.rs Sun Dec 03 22:18:30 2023 -0500
18.2+++ b/rust/lib/dl/tests/download-curl-resume.rs Sun Dec 03 23:25:08 2023 -0500
18.3@@ -1,7 +1,9 @@
18.4 #![cfg(feature = "curl-backend")]
18.5
18.6-use std::sync::atomic::{AtomicBool, Ordering};
18.7-use std::sync::Mutex;
18.8+use std::sync::{
18.9+ atomic::{AtomicBool, Ordering},
18.10+ Mutex,
18.11+};
18.12
18.13 use url::Url;
18.14
18.15@@ -12,65 +14,71 @@
18.16
18.17 #[test]
18.18 fn partially_downloaded_file_gets_resumed_from_byte_offset() {
18.19- let tmpdir = tmp_dir();
18.20- let from_path = tmpdir.path().join("download-source");
18.21- write_file(&from_path, "xxx45");
18.22+ let tmpdir = tmp_dir();
18.23+ let from_path = tmpdir.path().join("download-source");
18.24+ write_file(&from_path, "xxx45");
18.25+
18.26+ let target_path = tmpdir.path().join("downloaded");
18.27+ write_file(&target_path, "123");
18.28
18.29- let target_path = tmpdir.path().join("downloaded");
18.30- write_file(&target_path, "123");
18.31+ let from_url = Url::from_file_path(&from_path).unwrap();
18.32+ download_to_path_with_backend(
18.33+ Backend::Curl,
18.34+ &from_url,
18.35+ &target_path,
18.36+ true,
18.37+ None,
18.38+ )
18.39+ .expect("Test download failed");
18.40
18.41- let from_url = Url::from_file_path(&from_path).unwrap();
18.42- download_to_path_with_backend(Backend::Curl, &from_url, &target_path, true, None)
18.43- .expect("Test download failed");
18.44-
18.45- assert_eq!(std::fs::read_to_string(&target_path).unwrap(), "12345");
18.46+ assert_eq!(std::fs::read_to_string(&target_path).unwrap(), "12345");
18.47 }
18.48
18.49 #[test]
18.50 fn callback_gets_all_data_as_if_the_download_happened_all_at_once() {
18.51- let tmpdir = tmp_dir();
18.52- let target_path = tmpdir.path().join("downloaded");
18.53- write_file(&target_path, "123");
18.54+ let tmpdir = tmp_dir();
18.55+ let target_path = tmpdir.path().join("downloaded");
18.56+ write_file(&target_path, "123");
18.57
18.58- let addr = serve_file(b"xxx45".to_vec());
18.59+ let addr = serve_file(b"xxx45".to_vec());
18.60
18.61- let from_url = format!("http://{addr}").parse().unwrap();
18.62+ let from_url = format!("http://{addr}").parse().unwrap();
18.63
18.64- let callback_partial = AtomicBool::new(false);
18.65- let callback_len = Mutex::new(None);
18.66- let received_in_callback = Mutex::new(Vec::new());
18.67+ let callback_partial = AtomicBool::new(false);
18.68+ let callback_len = Mutex::new(None);
18.69+ let received_in_callback = Mutex::new(Vec::new());
18.70
18.71- download_to_path_with_backend(
18.72- Backend::Curl,
18.73- &from_url,
18.74- &target_path,
18.75- true,
18.76- Some(&|msg| {
18.77- match msg {
18.78- Event::ResumingPartialDownload => {
18.79- assert!(!callback_partial.load(Ordering::SeqCst));
18.80- callback_partial.store(true, Ordering::SeqCst);
18.81- }
18.82- Event::DownloadContentLengthReceived(len) => {
18.83- let mut flag = callback_len.lock().unwrap();
18.84- assert!(flag.is_none());
18.85- *flag = Some(len);
18.86- }
18.87- Event::DownloadDataReceived(data) => {
18.88- for b in data.iter() {
18.89- received_in_callback.lock().unwrap().push(*b);
18.90- }
18.91- }
18.92- }
18.93+ download_to_path_with_backend(
18.94+ Backend::Curl,
18.95+ &from_url,
18.96+ &target_path,
18.97+ true,
18.98+ Some(&|msg| {
18.99+ match msg {
18.100+ Event::ResumingPartialDownload => {
18.101+ assert!(!callback_partial.load(Ordering::SeqCst));
18.102+ callback_partial.store(true, Ordering::SeqCst);
18.103+ }
18.104+ Event::DownloadContentLengthReceived(len) => {
18.105+ let mut flag = callback_len.lock().unwrap();
18.106+ assert!(flag.is_none());
18.107+ *flag = Some(len);
18.108+ }
18.109+ Event::DownloadDataReceived(data) => {
18.110+ for b in data.iter() {
18.111+ received_in_callback.lock().unwrap().push(*b);
18.112+ }
18.113+ }
18.114+ }
18.115
18.116- Ok(())
18.117- }),
18.118- )
18.119- .expect("Test download failed");
18.120+ Ok(())
18.121+ }),
18.122+ )
18.123+ .expect("Test download failed");
18.124
18.125- assert!(callback_partial.into_inner());
18.126- assert_eq!(*callback_len.lock().unwrap(), Some(5));
18.127- let observed_bytes = received_in_callback.into_inner().unwrap();
18.128- assert_eq!(observed_bytes, vec![b'1', b'2', b'3', b'4', b'5']);
18.129- assert_eq!(std::fs::read_to_string(&target_path).unwrap(), "12345");
18.130+ assert!(callback_partial.into_inner());
18.131+ assert_eq!(*callback_len.lock().unwrap(), Some(5));
18.132+ let observed_bytes = received_in_callback.into_inner().unwrap();
18.133+ assert_eq!(observed_bytes, vec![b'1', b'2', b'3', b'4', b'5']);
18.134+ assert_eq!(std::fs::read_to_string(&target_path).unwrap(), "12345");
18.135 }
19.1--- a/rust/lib/dl/tests/download-reqwest-resume.rs Sun Dec 03 22:18:30 2023 -0500
19.2+++ b/rust/lib/dl/tests/download-reqwest-resume.rs Sun Dec 03 23:25:08 2023 -0500
19.3@@ -1,7 +1,9 @@
19.4 #![cfg(feature = "reqwest-backend")]
19.5
19.6-use std::sync::atomic::{AtomicBool, Ordering};
19.7-use std::sync::Mutex;
19.8+use std::sync::{
19.9+ atomic::{AtomicBool, Ordering},
19.10+ Mutex,
19.11+};
19.12
19.13 use url::Url;
19.14
19.15@@ -12,71 +14,71 @@
19.16
19.17 #[test]
19.18 fn resume_partial_from_file_url() {
19.19- let tmpdir = tmp_dir();
19.20- let from_path = tmpdir.path().join("download-source");
19.21- write_file(&from_path, "xxx45");
19.22+ let tmpdir = tmp_dir();
19.23+ let from_path = tmpdir.path().join("download-source");
19.24+ write_file(&from_path, "xxx45");
19.25
19.26- let target_path = tmpdir.path().join("downloaded");
19.27- write_file(&target_path, "123");
19.28+ let target_path = tmpdir.path().join("downloaded");
19.29+ write_file(&target_path, "123");
19.30
19.31- let from_url = Url::from_file_path(&from_path).unwrap();
19.32- download_to_path_with_backend(
19.33- Backend::Reqwest(TlsBackend::Default),
19.34- &from_url,
19.35- &target_path,
19.36- true,
19.37- None,
19.38- )
19.39- .expect("Test download failed");
19.40+ let from_url = Url::from_file_path(&from_path).unwrap();
19.41+ download_to_path_with_backend(
19.42+ Backend::Reqwest(TlsBackend::Default),
19.43+ &from_url,
19.44+ &target_path,
19.45+ true,
19.46+ None,
19.47+ )
19.48+ .expect("Test download failed");
19.49
19.50- assert_eq!(std::fs::read_to_string(&target_path).unwrap(), "12345");
19.51+ assert_eq!(std::fs::read_to_string(&target_path).unwrap(), "12345");
19.52 }
19.53
19.54 #[test]
19.55 fn callback_gets_all_data_as_if_the_download_happened_all_at_once() {
19.56- let tmpdir = tmp_dir();
19.57- let target_path = tmpdir.path().join("downloaded");
19.58- write_file(&target_path, "123");
19.59+ let tmpdir = tmp_dir();
19.60+ let target_path = tmpdir.path().join("downloaded");
19.61+ write_file(&target_path, "123");
19.62
19.63- let addr = serve_file(b"xxx45".to_vec());
19.64+ let addr = serve_file(b"xxx45".to_vec());
19.65
19.66- let from_url = format!("http://{addr}").parse().unwrap();
19.67+ let from_url = format!("http://{addr}").parse().unwrap();
19.68
19.69- let callback_partial = AtomicBool::new(false);
19.70- let callback_len = Mutex::new(None);
19.71- let received_in_callback = Mutex::new(Vec::new());
19.72+ let callback_partial = AtomicBool::new(false);
19.73+ let callback_len = Mutex::new(None);
19.74+ let received_in_callback = Mutex::new(Vec::new());
19.75
19.76- download_to_path_with_backend(
19.77- Backend::Reqwest(TlsBackend::Default),
19.78- &from_url,
19.79- &target_path,
19.80- true,
19.81- Some(&|msg| {
19.82- match msg {
19.83- Event::ResumingPartialDownload => {
19.84- assert!(!callback_partial.load(Ordering::SeqCst));
19.85- callback_partial.store(true, Ordering::SeqCst);
19.86- }
19.87- Event::DownloadContentLengthReceived(len) => {
19.88- let mut flag = callback_len.lock().unwrap();
19.89- assert!(flag.is_none());
19.90- *flag = Some(len);
19.91- }
19.92- Event::DownloadDataReceived(data) => {
19.93- for b in data.iter() {
19.94- received_in_callback.lock().unwrap().push(*b);
19.95- }
19.96- }
19.97- }
19.98+ download_to_path_with_backend(
19.99+ Backend::Reqwest(TlsBackend::Default),
19.100+ &from_url,
19.101+ &target_path,
19.102+ true,
19.103+ Some(&|msg| {
19.104+ match msg {
19.105+ Event::ResumingPartialDownload => {
19.106+ assert!(!callback_partial.load(Ordering::SeqCst));
19.107+ callback_partial.store(true, Ordering::SeqCst);
19.108+ }
19.109+ Event::DownloadContentLengthReceived(len) => {
19.110+ let mut flag = callback_len.lock().unwrap();
19.111+ assert!(flag.is_none());
19.112+ *flag = Some(len);
19.113+ }
19.114+ Event::DownloadDataReceived(data) => {
19.115+ for b in data.iter() {
19.116+ received_in_callback.lock().unwrap().push(*b);
19.117+ }
19.118+ }
19.119+ }
19.120
19.121- Ok(())
19.122- }),
19.123- )
19.124- .expect("Test download failed");
19.125+ Ok(())
19.126+ }),
19.127+ )
19.128+ .expect("Test download failed");
19.129
19.130- assert!(callback_partial.into_inner());
19.131- assert_eq!(*callback_len.lock().unwrap(), Some(5));
19.132- let observed_bytes = received_in_callback.into_inner().unwrap();
19.133- assert_eq!(observed_bytes, vec![b'1', b'2', b'3', b'4', b'5']);
19.134- assert_eq!(std::fs::read_to_string(&target_path).unwrap(), "12345");
19.135+ assert!(callback_partial.into_inner());
19.136+ assert_eq!(*callback_len.lock().unwrap(), Some(5));
19.137+ let observed_bytes = received_in_callback.into_inner().unwrap();
19.138+ assert_eq!(observed_bytes, vec![b'1', b'2', b'3', b'4', b'5']);
19.139+ assert_eq!(std::fs::read_to_string(&target_path).unwrap(), "12345");
19.140 }
20.1--- a/rust/lib/dl/tests/read-proxy-env.rs Sun Dec 03 22:18:30 2023 -0500
20.2+++ b/rust/lib/dl/tests/read-proxy-env.rs Sun Dec 03 23:25:08 2023 -0500
20.3@@ -1,12 +1,16 @@
20.4 #![cfg(feature = "reqwest-backend")]
20.5
20.6-use std::env::{remove_var, set_var};
20.7-use std::error::Error;
20.8-use std::net::TcpListener;
20.9-use std::sync::atomic::{AtomicUsize, Ordering};
20.10-use std::sync::Mutex;
20.11-use std::thread;
20.12-use std::time::Duration;
20.13+use std::{
20.14+ env::{remove_var, set_var},
20.15+ error::Error,
20.16+ net::TcpListener,
20.17+ sync::{
20.18+ atomic::{AtomicUsize, Ordering},
20.19+ Mutex,
20.20+ },
20.21+ thread,
20.22+ time::Duration,
20.23+};
20.24
20.25 use env_proxy::for_url;
20.26 use reqwest::{blocking::Client, Proxy};
20.27@@ -15,69 +19,69 @@
20.28 static SERIALISE_TESTS: Mutex<()> = Mutex::new(());
20.29
20.30 fn scrub_env() {
20.31- remove_var("http_proxy");
20.32- remove_var("https_proxy");
20.33- remove_var("HTTPS_PROXY");
20.34- remove_var("ftp_proxy");
20.35- remove_var("FTP_PROXY");
20.36- remove_var("all_proxy");
20.37- remove_var("ALL_PROXY");
20.38- remove_var("no_proxy");
20.39- remove_var("NO_PROXY");
20.40+ remove_var("http_proxy");
20.41+ remove_var("https_proxy");
20.42+ remove_var("HTTPS_PROXY");
20.43+ remove_var("ftp_proxy");
20.44+ remove_var("FTP_PROXY");
20.45+ remove_var("all_proxy");
20.46+ remove_var("ALL_PROXY");
20.47+ remove_var("no_proxy");
20.48+ remove_var("NO_PROXY");
20.49 }
20.50
20.51 // Tests for correctly retrieving the proxy (host, port) tuple from $https_proxy
20.52 #[test]
20.53 fn read_basic_proxy_params() {
20.54- let _guard = SERIALISE_TESTS
20.55- .lock()
20.56- .expect("Unable to lock the test guard");
20.57- scrub_env();
20.58- set_var("https_proxy", "http://proxy.example.com:8080");
20.59- let u = Url::parse("https://www.example.org").ok().unwrap();
20.60- assert_eq!(
20.61- for_url(&u).host_port(),
20.62- Some(("proxy.example.com".to_string(), 8080))
20.63- );
20.64+ let _guard = SERIALISE_TESTS
20.65+ .lock()
20.66+ .expect("Unable to lock the test guard");
20.67+ scrub_env();
20.68+ set_var("https_proxy", "http://proxy.example.com:8080");
20.69+ let u = Url::parse("https://www.example.org").ok().unwrap();
20.70+ assert_eq!(
20.71+ for_url(&u).host_port(),
20.72+ Some(("proxy.example.com".to_string(), 8080))
20.73+ );
20.74 }
20.75
20.76 // Tests to verify if socks feature is available and being used
20.77 #[test]
20.78 fn socks_proxy_request() {
20.79- static CALL_COUNT: AtomicUsize = AtomicUsize::new(0);
20.80- let _guard = SERIALISE_TESTS
20.81- .lock()
20.82- .expect("Unable to lock the test guard");
20.83+ static CALL_COUNT: AtomicUsize = AtomicUsize::new(0);
20.84+ let _guard = SERIALISE_TESTS
20.85+ .lock()
20.86+ .expect("Unable to lock the test guard");
20.87
20.88- scrub_env();
20.89- set_var("all_proxy", "socks5://127.0.0.1:1080");
20.90+ scrub_env();
20.91+ set_var("all_proxy", "socks5://127.0.0.1:1080");
20.92
20.93- thread::spawn(move || {
20.94- let listener = TcpListener::bind("127.0.0.1:1080").unwrap();
20.95- let incoming = listener.incoming();
20.96- for _ in incoming {
20.97- CALL_COUNT.fetch_add(1, Ordering::SeqCst);
20.98- }
20.99- });
20.100+ thread::spawn(move || {
20.101+ let listener = TcpListener::bind("127.0.0.1:1080").unwrap();
20.102+ let incoming = listener.incoming();
20.103+ for _ in incoming {
20.104+ CALL_COUNT.fetch_add(1, Ordering::SeqCst);
20.105+ }
20.106+ });
20.107
20.108- let env_proxy = |url: &Url| for_url(url).to_url();
20.109- let url = Url::parse("http://192.168.0.1/").unwrap();
20.110+ let env_proxy = |url: &Url| for_url(url).to_url();
20.111+ let url = Url::parse("http://192.168.0.1/").unwrap();
20.112
20.113- let client = Client::builder()
20.114- .proxy(Proxy::custom(env_proxy))
20.115- .timeout(Duration::from_secs(1))
20.116- .build()
20.117- .unwrap();
20.118- let res = client.get(url.as_str()).send();
20.119+ let client = Client::builder()
20.120+ .proxy(Proxy::custom(env_proxy))
20.121+ .timeout(Duration::from_secs(1))
20.122+ .build()
20.123+ .unwrap();
20.124+ let res = client.get(url.as_str()).send();
20.125
20.126- if let Err(e) = res {
20.127- let s = e.source().unwrap();
20.128- assert!(
20.129- s.to_string().contains("socks connect error"),
20.130- "Expected socks connect error, got: {s}",
20.131- );
20.132- assert_eq!(CALL_COUNT.load(Ordering::SeqCst), 1);
20.133- } else {
20.134- panic!("Socks proxy was ignored")
20.135- }
20.136+ if let Err(e) = res {
20.137+ let s = e.source().unwrap();
20.138+ assert!(
20.139+ s.to_string().contains("socks connect error"),
20.140+ "Expected socks connect error, got: {s}",
20.141+ );
20.142+ assert_eq!(CALL_COUNT.load(Ordering::SeqCst), 1);
20.143+ } else {
20.144+ panic!("Socks proxy was ignored")
20.145+ }
20.146 }
21.1--- a/rust/lib/dl/tests/support/mod.rs Sun Dec 03 22:18:30 2023 -0500
21.2+++ b/rust/lib/dl/tests/support/mod.rs Sun Dec 03 23:25:08 2023 -0500
21.3@@ -1,119 +1,126 @@
21.4-use std::convert::Infallible;
21.5-use std::fs;
21.6-use std::io;
21.7-use std::net::SocketAddr;
21.8-use std::path::Path;
21.9-use std::sync::mpsc::{channel, Sender};
21.10-use std::thread;
21.11+use std::{
21.12+ convert::Infallible,
21.13+ fs, io,
21.14+ net::SocketAddr,
21.15+ path::Path,
21.16+ sync::mpsc::{channel, Sender},
21.17+ thread,
21.18+};
21.19
21.20 use http_body_util::Full;
21.21-use hyper::body::Bytes;
21.22-use hyper::server::conn::http1;
21.23-use hyper::service::service_fn;
21.24-use hyper::Request;
21.25+use hyper::{body::Bytes, server::conn::http1, service::service_fn, Request};
21.26 use tempfile::TempDir;
21.27
21.28 pub fn tmp_dir() -> TempDir {
21.29- tempfile::Builder::new()
21.30- .prefix("rustup-download-test-")
21.31- .tempdir()
21.32- .expect("creating tempdir for test")
21.33+ tempfile::Builder::new()
21.34+ .prefix("rustup-download-test-")
21.35+ .tempdir()
21.36+ .expect("creating tempdir for test")
21.37 }
21.38
21.39 pub fn write_file(path: &Path, contents: &str) {
21.40- let mut file = fs::OpenOptions::new()
21.41- .write(true)
21.42- .truncate(true)
21.43- .create(true)
21.44- .open(path)
21.45- .expect("writing test data");
21.46+ let mut file = fs::OpenOptions::new()
21.47+ .write(true)
21.48+ .truncate(true)
21.49+ .create(true)
21.50+ .open(path)
21.51+ .expect("writing test data");
21.52
21.53- io::Write::write_all(&mut file, contents.as_bytes()).expect("writing test data");
21.54+ io::Write::write_all(&mut file, contents.as_bytes())
21.55+ .expect("writing test data");
21.56
21.57- file.sync_data().expect("writing test data");
21.58+ file.sync_data().expect("writing test data");
21.59 }
21.60
21.61 // A dead simple hyper server implementation.
21.62 // For more info, see:
21.63 // https://hyper.rs/guides/1/server/hello-world/
21.64-async fn run_server(addr_tx: Sender<SocketAddr>, addr: SocketAddr, contents: Vec<u8>) {
21.65- let svc = service_fn(move |req: Request<hyper::body::Incoming>| {
21.66- let contents = contents.clone();
21.67- async move {
21.68- let res = serve_contents(req, contents);
21.69- Ok::<_, Infallible>(res)
21.70- }
21.71- });
21.72+async fn run_server(
21.73+ addr_tx: Sender<SocketAddr>,
21.74+ addr: SocketAddr,
21.75+ contents: Vec<u8>,
21.76+) {
21.77+ let svc = service_fn(move |req: Request<hyper::body::Incoming>| {
21.78+ let contents = contents.clone();
21.79+ async move {
21.80+ let res = serve_contents(req, contents);
21.81+ Ok::<_, Infallible>(res)
21.82+ }
21.83+ });
21.84
21.85- let listener = tokio::net::TcpListener::bind(&addr)
21.86- .await
21.87- .expect("can not bind");
21.88+ let listener = tokio::net::TcpListener::bind(&addr)
21.89+ .await
21.90+ .expect("can not bind");
21.91
21.92- let addr = listener.local_addr().unwrap();
21.93- addr_tx.send(addr).unwrap();
21.94+ let addr = listener.local_addr().unwrap();
21.95+ addr_tx.send(addr).unwrap();
21.96
21.97- loop {
21.98- let (stream, _) = listener
21.99- .accept()
21.100- .await
21.101- .expect("could not accept connection");
21.102- let io = hyper_util::rt::TokioIo::new(stream);
21.103+ loop {
21.104+ let (stream, _) = listener
21.105+ .accept()
21.106+ .await
21.107+ .expect("could not accept connection");
21.108+ let io = hyper_util::rt::TokioIo::new(stream);
21.109
21.110- let svc = svc.clone();
21.111- tokio::spawn(async move {
21.112- if let Err(err) = http1::Builder::new().serve_connection(io, svc).await {
21.113- eprintln!("failed to serve connection: {:?}", err);
21.114- }
21.115- });
21.116- }
21.117+ let svc = svc.clone();
21.118+ tokio::spawn(async move {
21.119+ if let Err(err) = http1::Builder::new().serve_connection(io, svc).await {
21.120+ eprintln!("failed to serve connection: {:?}", err);
21.121+ }
21.122+ });
21.123+ }
21.124 }
21.125
21.126 pub fn serve_file(contents: Vec<u8>) -> SocketAddr {
21.127- let addr = ([127, 0, 0, 1], 0).into();
21.128- let (addr_tx, addr_rx) = channel();
21.129+ let addr = ([127, 0, 0, 1], 0).into();
21.130+ let (addr_tx, addr_rx) = channel();
21.131
21.132- thread::spawn(move || {
21.133- let server = run_server(addr_tx, addr, contents);
21.134- let rt = tokio::runtime::Runtime::new().expect("could not creating Runtime");
21.135- rt.block_on(server);
21.136- });
21.137+ thread::spawn(move || {
21.138+ let server = run_server(addr_tx, addr, contents);
21.139+ let rt =
21.140+ tokio::runtime::Runtime::new().expect("could not creating Runtime");
21.141+ rt.block_on(server);
21.142+ });
21.143
21.144- let addr = addr_rx.recv();
21.145- addr.unwrap()
21.146+ let addr = addr_rx.recv();
21.147+ addr.unwrap()
21.148 }
21.149
21.150 fn serve_contents(
21.151- req: hyper::Request<hyper::body::Incoming>,
21.152- contents: Vec<u8>,
21.153+ req: hyper::Request<hyper::body::Incoming>,
21.154+ contents: Vec<u8>,
21.155 ) -> hyper::Response<Full<Bytes>> {
21.156- let mut range_header = None;
21.157- let (status, body) = if let Some(range) = req.headers().get(hyper::header::RANGE) {
21.158- // extract range "bytes={start}-"
21.159- let range = range.to_str().expect("unexpected Range header");
21.160- assert!(range.starts_with("bytes="));
21.161- let range = range.trim_start_matches("bytes=");
21.162- assert!(range.ends_with('-'));
21.163- let range = range.trim_end_matches('-');
21.164- assert_eq!(range.split('-').count(), 1);
21.165- let start: u64 = range.parse().expect("unexpected Range header");
21.166+ let mut range_header = None;
21.167+ let (status, body) =
21.168+ if let Some(range) = req.headers().get(hyper::header::RANGE) {
21.169+ // extract range "bytes={start}-"
21.170+ let range = range.to_str().expect("unexpected Range header");
21.171+ assert!(range.starts_with("bytes="));
21.172+ let range = range.trim_start_matches("bytes=");
21.173+ assert!(range.ends_with('-'));
21.174+ let range = range.trim_end_matches('-');
21.175+ assert_eq!(range.split('-').count(), 1);
21.176+ let start: u64 = range.parse().expect("unexpected Range header");
21.177
21.178- range_header = Some(format!("bytes {}-{len}/{len}", start, len = contents.len()));
21.179- (
21.180- hyper::StatusCode::PARTIAL_CONTENT,
21.181- contents[start as usize..].to_vec(),
21.182- )
21.183+ range_header =
21.184+ Some(format!("bytes {}-{len}/{len}", start, len = contents.len()));
21.185+ (
21.186+ hyper::StatusCode::PARTIAL_CONTENT,
21.187+ contents[start as usize..].to_vec(),
21.188+ )
21.189 } else {
21.190- (hyper::StatusCode::OK, contents)
21.191+ (hyper::StatusCode::OK, contents)
21.192 };
21.193
21.194- let mut res = hyper::Response::builder()
21.195- .status(status)
21.196- .header(hyper::header::CONTENT_LENGTH, body.len())
21.197- .body(Full::new(Bytes::from(body)))
21.198- .unwrap();
21.199- if let Some(range) = range_header {
21.200- res.headers_mut()
21.201- .insert(hyper::header::CONTENT_RANGE, range.parse().unwrap());
21.202- }
21.203+ let mut res = hyper::Response::builder()
21.204+ .status(status)
21.205+ .header(hyper::header::CONTENT_LENGTH, body.len())
21.206+ .body(Full::new(Bytes::from(body)))
21.207+ .unwrap();
21.208+ if let Some(range) = range_header {
21.209 res
21.210+ .headers_mut()
21.211+ .insert(hyper::header::CONTENT_RANGE, range.parse().unwrap());
21.212+ }
21.213+ res
21.214 }
22.1--- a/rust/lib/util/src/bs/version.rs Sun Dec 03 22:18:30 2023 -0500
22.2+++ b/rust/lib/util/src/bs/version.rs Sun Dec 03 23:25:08 2023 -0500
22.3@@ -29,11 +29,7 @@
22.4 get_version_short(&commit)
22.5 );
22.6
22.7- println!(
22.8- "cargo:rustc-env=CORE_TARGET={}",
22.9- get_platform()
22.10- );
22.11-
22.12+ println!("cargo:rustc-env=CORE_TARGET={}", get_platform());
22.13 }
22.14
22.15 pub fn get_platform() -> String {
23.1--- a/rust/lib/util/src/lib.rs Sun Dec 03 22:18:30 2023 -0500
23.2+++ b/rust/lib/util/src/lib.rs Sun Dec 03 23:25:08 2023 -0500
23.3@@ -1,6 +1,6 @@
23.4 //! util library
23.5 #[cfg(feature = "anyhow")]
23.6-pub use anyhow::{Result,Context};
23.7+pub use anyhow::{Context, Result};
23.8 #[cfg(feature = "bs")]
23.9 pub mod bs;
23.10 #[cfg(feature = "cli")]