Support requesting VFS hydration; fix Android TLS cross-compilation
Correcting the previous commit: I claimed VFS placeholders could not be
downloaded. That was wrong. The desktop client exposes a socket at
$XDG_RUNTIME_DIR/Nextcloud/socket speaking newline-delimited
COMMAND:argument, and MAKE_AVAILABLE_LOCALLY:<path> does fetch the file.
Verified against client 4.0.7: a 1-byte stub became a real 2.8MB file in
2.8 seconds.
Implemented as dr-sync-nextcloud::desktop_client, deliberately optional.
Android has no desktop client, no XDG_RUNTIME_DIR socket and no
placeholders, so detect() returns None there and callers fall back to the
connector. It earns its place only because it is ~30 lines with no
dependencies: where a library already lives in a VFS folder, asking the
client to fetch beats downloading a second copy over WebDAV and leaving
the client's placeholder state inconsistent.
What this does not change: hydration is whole-file, so it suits the
original tier and never browsing. Filling a grid this way downloads the
entire library. Range extraction remains the only mechanism satisfying
FR-NC-3, and ARCH §9.0 now says so precisely.
Also fixes two real Android build failures found by cross-compiling:
- reqwest's `rustls` feature defaults to aws-lc-rs, whose aws-lc-sys
crate is C and fails under the NDK — exactly the pain D1 chose Rust
to avoid. Switched to rustls-no-provider + ring, installing the
provider in the constructor so no caller can build a client that
panics on first use.
- ring itself needs CC/AR per target; cargo-ndk sets only the linker.
Added them to the container.
87 tests passing. dr-sync-nextcloud cross-compiles for aarch64-linux-android.
This commit is contained in:
@@ -14,9 +14,11 @@ use dr_sync::{
|
||||
};
|
||||
|
||||
pub mod auth;
|
||||
pub mod desktop_client;
|
||||
mod propfind;
|
||||
|
||||
pub use auth::{AppCredentials, LoginFlow};
|
||||
pub use desktop_client::DesktopClient;
|
||||
|
||||
/// Chunk sizes Nextcloud's chunked upload v2 accepts.
|
||||
const CHUNKS: ChunkConstraints = ChunkConstraints {
|
||||
@@ -42,6 +44,8 @@ pub struct NextcloudBackend {
|
||||
impl NextcloudBackend {
|
||||
/// Build a backend from credentials obtained via [`auth`].
|
||||
pub fn new(creds: &AppCredentials, user_id: &str) -> Result<Self, RemoteError> {
|
||||
install_crypto_provider();
|
||||
|
||||
let client = reqwest::Client::builder()
|
||||
.user_agent("DarkRoom")
|
||||
.build()
|
||||
@@ -302,6 +306,24 @@ impl RemoteBackend for NextcloudBackend {
|
||||
}
|
||||
}
|
||||
|
||||
/// Install the rustls crypto provider, once per process.
|
||||
///
|
||||
/// Required because we build reqwest with `rustls-no-provider` rather than
|
||||
/// `rustls`: the default provider is aws-lc-rs, whose `aws-lc-sys` crate is C
|
||||
/// and does not cross-compile for Android. `ring` is pure Rust apart from a
|
||||
/// small assembly core that builds fine under the NDK.
|
||||
///
|
||||
/// Done here rather than left to callers so there is no way to construct a
|
||||
/// client that panics on first use.
|
||||
fn install_crypto_provider() {
|
||||
use std::sync::Once;
|
||||
static ONCE: Once = Once::new();
|
||||
ONCE.call_once(|| {
|
||||
// Errs only if a provider is already installed, which is fine.
|
||||
let _ = rustls::crypto::ring::default_provider().install_default();
|
||||
});
|
||||
}
|
||||
|
||||
/// Translate an HTTP status into a typed error.
|
||||
fn map_status(status: reqwest::StatusCode, what: &str) -> Result<(), RemoteError> {
|
||||
match status.as_u16() {
|
||||
|
||||
Reference in New Issue
Block a user