Skip to content
Merged
22 changes: 10 additions & 12 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,42 +41,40 @@ required-features = [ "caldav" ]
[dependencies]
bytes = "1.0.1"
dyn-clone = "1"
futures-util = "0.3.16"
futures-util = { version = "0.3.16", default-features = false, features = ["alloc"] }
futures-channel = "0.3.16"
headers = "0.4.0"
htmlescape = "0.3.1"
http = "1.0.0"
http-body = "1.0.0"
http-body-util = "0.1.0"
lazy_static = "1.4.0"
libc = { version = "0.2.0", optional = true }
log = "0.4.0"
lru = { version = "0.14.0", optional = true }
lru = { version = "0.16.0", optional = true }
mime_guess = "2.0.0"
parking_lot = { version = "0.12.0", optional = true }
percent-encoding = "2.1.0"
pin-project = "1.0.4"
pin-utils = "0.1.0"
regex = "1.4.0"
pin-project-lite = "0.2.16"
tokio = { version = "1.3.0", features = [ "rt-multi-thread", "io-util", "net", "time", "sync" ] }
time = { version = "0.3.2", default-features = false, features = [ "macros", "formatting" ] }
url = "2.2.0"
uuid = { version = "1.1.2", features = ["v4"] }
xml-rs = "0.8.0"
xmltree = "0.11.0"
xml-rs = "1"
xmltree = "0.12.0"

hyper = { version = "1.1.0", optional = true }
hyper = { version = "1.1.0", default-features = false, features = ["server"], optional = true }
warp = { version = "0.3.0", optional = true, default-features = false }
actix-web = { version = "4.0.0-beta.15", optional = true }
actix-web = { version = "4.0.0-beta.15", default-features = false, optional = true }
reflink-copy = { version = "0.1.14", optional = true }
icalendar = { version = "0.17.1", optional = true }
chrono = { version = "0.4", optional = true }
chrono = { version = "0.4", default-features = false, features = ["now"], optional = true }
derive-where = "1.6.0"

[dev-dependencies]
clap = { version = "4.0.0", features = ["derive"] }
env_logger = "0.11.0"
actix-web = { version = "4.0.0-beta.15", default-features = false, features = ["macros"] }
hyper = { version = "1.1.0", features = ["http1", "server"] }
hyper-util = { version = "0.1.2", features = ["tokio"] }
tokio = { version = "1.3.0", features = ["full"] }
axum = { version = "0.8", features = [] }
axum = { version = "0.8", features = [] }
21 changes: 11 additions & 10 deletions src/actix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
//!
use std::{
convert::TryInto,
io,
future, io,
pin::Pin,
task::{Context, Poll},
};
Expand All @@ -23,8 +23,8 @@ use actix_web::body::BoxBody;
use actix_web::error::PayloadError;
use actix_web::{Error, FromRequest, HttpRequest, HttpResponse, dev};
use bytes::Bytes;
use futures_util::{Stream, future};
use pin_project::pin_project;
use futures_util::Stream;
use pin_project_lite::pin_project;

/// http::Request compatibility.
///
Expand Down Expand Up @@ -71,13 +71,14 @@ impl FromRequest for DavRequest {
}
}

/// Body type for `DavRequest`.
///
/// It wraps actix's `PayLoad` and implements `http_body::Body`.
#[pin_project]
pub struct DavBody {
#[pin]
body: dev::Payload,
pin_project! {
/// Body type for `DavRequest`.
///
/// It wraps actix's `PayLoad` and implements `http_body::Body`.
pub struct DavBody {
#[pin]
body: dev::Payload,
}
}

impl http_body::Body for DavBody {
Expand Down
18 changes: 9 additions & 9 deletions src/body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use std::task::{Context, Poll};
use bytes::{Buf, Bytes};
use futures_util::stream::Stream;
use http_body::Body as HttpBody;
use pin_project_lite::pin_project;

use crate::async_stream::AsyncStream;

Expand Down Expand Up @@ -91,15 +92,14 @@ impl From<AsyncStream<Bytes, io::Error>> for Body {
}
}

use pin_project::pin_project;

//
// A struct that contains a Stream, and implements http_body::Body.
//
#[pin_project]
pub(crate) struct StreamBody<B> {
#[pin]
body: B,
pin_project! {
//
// A struct that contains a Stream, and implements http_body::Body.
//
pub(crate) struct StreamBody<B> {
#[pin]
body: B,
}
}

impl<ReqBody, ReqData, ReqError> HttpBody for StreamBody<ReqBody>
Expand Down
3 changes: 2 additions & 1 deletion src/davhandler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
//
use std::error::Error as StdError;
use std::io;
use std::pin::pin;
use std::sync::Arc;

use bytes::{self, buf::Buf};
Expand Down Expand Up @@ -368,7 +369,7 @@ where
ReqError: StdError + Send + Sync + 'static,
{
let mut data = Vec::new();
pin_utils::pin_mut!(body);
let mut body = pin!(body);

while let Some(res) = body.frame().await {
let mut data_frame = res.map_err(|_| {
Expand Down
38 changes: 15 additions & 23 deletions src/davheaders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,21 @@ use std::str::FromStr;

use headers::Header;
use http::header::{HeaderName, HeaderValue};
use lazy_static::lazy_static;
use regex::Regex;
use url::Url;

use crate::fs::DavMetaData;

lazy_static! {
static ref RE_URL: Regex = Regex::new(r"https?://[^/]*([^#?]+).*$").unwrap();
pub static ref DEPTH: HeaderName = HeaderName::from_static("depth");
pub static ref TIMEOUT: HeaderName = HeaderName::from_static("timeout");
pub static ref OVERWRITE: HeaderName = HeaderName::from_static("overwrite");
pub static ref DESTINATION: HeaderName = HeaderName::from_static("destination");
pub static ref ETAG: HeaderName = HeaderName::from_static("etag");
pub static ref IF_RANGE: HeaderName = HeaderName::from_static("if-range");
pub static ref IF_MATCH: HeaderName = HeaderName::from_static("if-match");
pub static ref IF_NONE_MATCH: HeaderName = HeaderName::from_static("if-none-match");
pub static ref X_UPDATE_RANGE: HeaderName = HeaderName::from_static("x-update-range");
pub static ref IF: HeaderName = HeaderName::from_static("if");
pub static ref CONTENT_LANGUAGE: HeaderName = HeaderName::from_static("content-language");
}
pub static DEPTH: HeaderName = HeaderName::from_static("depth");
pub static TIMEOUT: HeaderName = HeaderName::from_static("timeout");
pub static OVERWRITE: HeaderName = HeaderName::from_static("overwrite");
pub static DESTINATION: HeaderName = HeaderName::from_static("destination");
pub static ETAG: HeaderName = HeaderName::from_static("etag");
pub static IF_RANGE: HeaderName = HeaderName::from_static("if-range");
pub static IF_MATCH: HeaderName = HeaderName::from_static("if-match");
pub static IF_NONE_MATCH: HeaderName = HeaderName::from_static("if-none-match");
pub static X_UPDATE_RANGE: HeaderName = HeaderName::from_static("x-update-range");
pub static IF: HeaderName = HeaderName::from_static("if");
pub static CONTENT_LANGUAGE: HeaderName = HeaderName::from_static("content-language");

// helper.
fn one<'i, I>(values: &mut I) -> Result<&'i HeaderValue, headers::Error>
Expand All @@ -49,9 +45,7 @@ fn map_invalid(_e: impl std::error::Error) -> headers::Error {

macro_rules! header {
($tname:ident, $hname:ident, $sname:expr_2021) => {
lazy_static! {
pub static ref $hname: HeaderName = HeaderName::from_static($sname);
}
pub static $hname: HeaderName = HeaderName::from_static($sname);

#[derive(Debug, Clone, PartialEq)]
pub struct $tname(pub String);
Expand Down Expand Up @@ -256,10 +250,8 @@ impl Header for Destination {
if s.starts_with('/') {
return Ok(Destination(s.to_string()));
}
if let Some(caps) = RE_URL.captures(s)
&& let Some(path) = caps.get(1)
{
return Ok(Destination(path.as_str().to_string()));
if let Ok(url) = s.parse::<Url>() {
return Ok(Destination(url.path().to_string()));
}
Err(invalid())
}
Expand Down
3 changes: 2 additions & 1 deletion src/fakels.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@
//! If: headers always succeeds, and nothing is every really locked.
//!
//! `FakeLs` implements such a fake locksystem.
use std::future;
use std::time::{Duration, SystemTime};

use futures_util::{FutureExt, future};
use futures_util::FutureExt;
use uuid::Uuid;
use xmltree::Element;

Expand Down
15 changes: 11 additions & 4 deletions src/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
//! filesystem backend. Otherwise, just use 'LocalFs' or 'MemFs'.
//!
use std::fmt::Debug;
use std::future::{self, Future};
use std::io::SeekFrom;
use std::pin::Pin;
use std::time::{SystemTime, UNIX_EPOCH};

use dyn_clone::{DynClone, clone_trait_object};
use futures_util::{Future, FutureExt, Stream, TryFutureExt, future};
use futures_util::{FutureExt, Stream, TryFutureExt};
use http::StatusCode;

use crate::davpath::DavPath;
Expand Down Expand Up @@ -664,19 +665,25 @@ pub trait DavDirEntry: Send + Sync {
/// expensive and there is a cheaper way to provide the same info
/// (e.g. dirent.d_type in unix filesystems).
fn is_dir(&'_ self) -> FsFuture<'_, bool> {
Box::pin(self.metadata().and_then(|meta| future::ok(meta.is_dir())))
Box::pin(
self.metadata()
.and_then(|meta| future::ready(Ok(meta.is_dir()))),
)
}

/// Likewise. Default: `!is_dir()`.
fn is_file(&'_ self) -> FsFuture<'_, bool> {
Box::pin(self.metadata().and_then(|meta| future::ok(meta.is_file())))
Box::pin(
self.metadata()
.and_then(|meta| future::ready(Ok(meta.is_file()))),
)
}

/// Likewise. Default: `false`.
fn is_symlink(&'_ self) -> FsFuture<'_, bool> {
Box::pin(
self.metadata()
.and_then(|meta| future::ok(meta.is_symlink())),
.and_then(|meta| future::ready(Ok(meta.is_symlink()))),
)
}
}
Expand Down
9 changes: 4 additions & 5 deletions src/handle_props.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::borrow::Cow;
use std::collections::HashMap;
use std::convert::TryFrom;
use std::io::{self, Cursor};
use std::sync::LazyLock;

use futures_util::{FutureExt, StreamExt, future::BoxFuture};
use headers::HeaderMapExt;
Expand Down Expand Up @@ -129,11 +130,9 @@ const MS_ALLPROP_STR: &[&str] = &[
"Z:Win32LastModifiedTime",
];

lazy_static! {
static ref ALLPROP: Vec<Element> = init_staticprop(ALLPROP_STR);
static ref MS_ALLPROP: Vec<Element> = init_staticprop(MS_ALLPROP_STR);
static ref PROPNAME: Vec<Element> = init_staticprop(PROPNAME_STR);
}
static ALLPROP: LazyLock<Vec<Element>> = LazyLock::new(|| init_staticprop(ALLPROP_STR));
static MS_ALLPROP: LazyLock<Vec<Element>> = LazyLock::new(|| init_staticprop(MS_ALLPROP_STR));
static PROPNAME: LazyLock<Vec<Element>> = LazyLock::new(|| init_staticprop(PROPNAME_STR));

type Emitter = EventWriter<MemBuffer>;
type Sender = crate::async_stream::Sender<bytes::Bytes, io::Error>;
Expand Down
3 changes: 2 additions & 1 deletion src/handle_put.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::any::Any;
use std::error::Error as StdError;
use std::io;
use std::pin::pin;

use bytes::{Buf, Bytes};
use headers::HeaderMapExt;
Expand Down Expand Up @@ -233,7 +234,7 @@ impl<C: Clone + Send + Sync + 'static> DavInner<C> {
res.headers_mut()
.typed_insert(headers::AcceptRanges::bytes());

pin_utils::pin_mut!(body);
let mut body = pin!(body);

// loop, read body, write to file.
let mut total = 0u64;
Expand Down
2 changes: 0 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,6 @@

#[macro_use]
extern crate log;
#[macro_use]
extern crate lazy_static;

mod async_stream;
mod conditional;
Expand Down
9 changes: 4 additions & 5 deletions src/localfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use std::any::Any;
use std::collections::VecDeque;
use std::future::Future;
use std::future::{self, Future};
use std::io::{self, Read, Seek, SeekFrom, Write};
#[cfg(unix)]
use std::os::unix::{
Expand All @@ -17,14 +17,14 @@ use std::os::unix::{
use std::os::windows::prelude::*;
use std::path::{Path, PathBuf};
use std::pin::Pin;
use std::pin::pin;
use std::sync::Arc;
use std::sync::atomic::{AtomicU32, Ordering};
use std::task::{Context, Poll};
use std::time::{Duration, SystemTime, UNIX_EPOCH};

use bytes::{Buf, Bytes, BytesMut};
use futures_util::{FutureExt, Stream, future, future::BoxFuture};
use pin_utils::pin_mut;
use futures_util::{FutureExt, Stream, future::BoxFuture};
use tokio::task;

use libc;
Expand Down Expand Up @@ -553,8 +553,7 @@ impl Stream for LocalFsReadDir {
}

// Poll the future.
let fut = this.fut.as_mut().unwrap();
pin_mut!(fut);
let mut fut = pin!(this.fut.as_mut().unwrap());
match Pin::new(&mut fut).poll(cx) {
Poll::Ready(batch) => {
this.fut.take();
Expand Down
6 changes: 2 additions & 4 deletions src/localfs_macos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use std::num::NonZeroUsize;
#[cfg(unix)]
use std::os::unix::ffi::OsStrExt;
use std::path::{Path, PathBuf};
use std::sync::Arc;
use std::sync::LazyLock;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::thread;
use std::time::{Duration, SystemTime, UNIX_EPOCH};
Expand All @@ -29,9 +29,7 @@ const DU_CACHE_ENTRIES: usize = 4096;
const DU_CACHE_MAX_AGE: u64 = 60;
const DU_CACHE_SLEEP_MS: u64 = 10037;

lazy_static! {
static ref DU_CACHE: Arc<DUCache> = Arc::new(DUCache::new(DU_CACHE_ENTRIES));
}
static DU_CACHE: LazyLock<DUCache> = LazyLock::new(|| DUCache::new(DU_CACHE_ENTRIES));

static DIR_ID: AtomicUsize = AtomicUsize::new(1);

Expand Down
8 changes: 3 additions & 5 deletions src/localfs_windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::fs;
use std::io::ErrorKind;
use std::num::NonZeroUsize;
use std::path::{Path, PathBuf};
use std::sync::Arc;
use std::sync::LazyLock;
use std::thread;
use std::time::{Duration, SystemTime, UNIX_EPOCH};

Expand All @@ -21,9 +21,7 @@ const CACHE_ENTRIES: usize = 4096;
const CACHE_MAX_AGE: u64 = 15 * 60;
const CACHE_SLEEP_MS: u64 = 30059;

lazy_static! {
static ref CACHE: Arc<Cache> = Arc::new(Cache::new(CACHE_ENTRIES));
}
static CACHE: LazyLock<Cache> = LazyLock::new(|| Cache::new(CACHE_ENTRIES));

// Do a case-insensitive path lookup.
pub(crate) fn resolve(base: impl Into<PathBuf>, path: &DavPath) -> PathBuf {
Expand All @@ -43,7 +41,7 @@ pub(crate) fn resolve(base: impl Into<PathBuf>, path: &DavPath) -> PathBuf {
None => return fullpath,
};

// deref in advance: first lazy_static, then Arc.
// deref in advance: first LazyLock, then Arc.
let cache = &*CACHE;

// In the cache?
Expand Down
Loading
Loading