Add live-server harness; centralise the rustls provider install
Adds a read-only example that exercises the connector against a real Nextcloud: Login Flow v2, PROPFIND listing, the Depth:0 ETag pruning probe, a 256KB range GET, and a server preview request. No PUT, MOVE or DELETE, so it cannot alter a live library. Running it against nextcloud.tourolle.paris (34.0.2) surfaced a real API flaw rather than an example bug. The crypto provider was installed in NextcloudBackend::new, but authentication necessarily runs *before* a backend exists — so any caller following the documented flow panicked on the first client build. Every entry point now goes through `http_client()`, which installs the provider first, and auth gains `begin_default()` for callers with no client yet. A test builds a client without a backend to keep the regression out. Also populates RawImage::crop from rawler's crop_area/active_area and re-phases the CFA pattern when the crop origin is odd — cropping to the active area without that swaps red and blue. Login Flow v2 confirmed working against the live server: the flow URL is issued and the poll endpoint responds. The remaining checks need a browser approval, so they run interactively. 88 tests passing.
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use dr_sync::RemoteError;
|
||||
use serde::Deserialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// The flow's poll token is valid for 20 minutes.
|
||||
const FLOW_TIMEOUT: Duration = Duration::from_secs(20 * 60);
|
||||
@@ -31,7 +31,7 @@ pub struct PollInfo {
|
||||
}
|
||||
|
||||
/// Credentials issued at the end of the flow.
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
pub struct AppCredentials {
|
||||
pub server: String,
|
||||
#[serde(rename = "loginName")]
|
||||
|
||||
@@ -44,12 +44,7 @@ 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()
|
||||
.map_err(|e| RemoteError::Network(e.to_string()))?;
|
||||
let client = http_client("DarkRoom")?;
|
||||
|
||||
let server = creds.server.trim_end_matches('/').to_string();
|
||||
let dav_base = format!("/remote.php/dav/files/{user_id}/");
|
||||
@@ -306,6 +301,20 @@ impl RemoteBackend for NextcloudBackend {
|
||||
}
|
||||
}
|
||||
|
||||
/// Build an HTTP client with the crypto provider already installed.
|
||||
///
|
||||
/// Every entry point that creates a client must go through here. The auth
|
||||
/// flow runs *before* a backend exists, so leaving the install to
|
||||
/// `NextcloudBackend::new` means `auth::begin` panics on first use — which is
|
||||
/// exactly what happened.
|
||||
pub fn http_client(user_agent: &str) -> Result<reqwest::Client, RemoteError> {
|
||||
install_crypto_provider();
|
||||
reqwest::Client::builder()
|
||||
.user_agent(user_agent.to_string())
|
||||
.build()
|
||||
.map_err(|e| RemoteError::Network(e.to_string()))
|
||||
}
|
||||
|
||||
/// Install the rustls crypto provider, once per process.
|
||||
///
|
||||
/// Required because we build reqwest with `rustls-no-provider` rather than
|
||||
@@ -448,6 +457,16 @@ mod tests {
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn http_client_works_before_any_backend_exists() {
|
||||
// The auth flow builds a client before a backend is constructed. If
|
||||
// the crypto provider is installed only in NextcloudBackend::new,
|
||||
// this panics — which is exactly what happened against the live
|
||||
// server.
|
||||
let c = http_client("test");
|
||||
assert!(c.is_ok(), "client must build without a backend");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn delta_is_unsupported_and_says_why() {
|
||||
// Verified absent in the server; the engine must fall back rather
|
||||
|
||||
Reference in New Issue
Block a user