webdav_handler/lib.rs
1#![doc(html_root_url = "https://docs.rs/webdav-handler/0.2.0")]
2//! ## Generic async HTTP/Webdav handler
3//!
4//! [`Webdav`] (RFC4918) is defined as
5//! HTTP (GET/HEAD/PUT/DELETE) plus a bunch of extension methods (PROPFIND, etc).
6//! These extension methods are used to manage collections (like unix directories),
7//! get information on collections (like unix `ls` or `readdir`), rename and
8//! copy items, lock/unlock items, etc.
9//!
10//! A `handler` is a piece of code that takes a `http::Request`, processes it in some
11//! way, and then generates a `http::Response`. This library is a `handler` that maps
12//! the HTTP/Webdav protocol to the filesystem. Or actually, "a" filesystem. Included
13//! is an adapter for the local filesystem (`localfs`), and an adapter for an
14//! in-memory filesystem (`memfs`).
15//!
16//! So this library can be used as a handler with HTTP servers like [hyper],
17//! [warp], [actix-web], etc. Either as a correct and complete HTTP handler for
18//! files (GET/HEAD) or as a handler for the entire Webdav protocol. In the latter case, you can
19//! mount it as a remote filesystem: Linux, Windows, macOS can all mount Webdav filesystems.
20//!
21//! ## Backend interfaces.
22//!
23//! The backend interfaces are similar to the ones from the Go `x/net/webdav package`:
24//!
25//! - the library contains a [HTTP handler][DavHandler].
26//! - you supply a [filesystem][DavFileSystem] for backend storage, which can optionally
27//! implement reading/writing [DAV properties][DavProp].
28//! - you can supply a [locksystem][DavLockSystem] that handles webdav locks.
29//!
30//! The handler in this library works with the standard http types
31//! from the `http` and `http_body` crates. That means that you can use it
32//! straight away with http libraries / frameworks that also work with
33//! those types, like hyper. Compatibility modules for [actix-web][actix-compat]
34//! and [warp][warp-compat] are also provided.
35//!
36//! ## Implemented standards.
37//!
38//! Currently [passes the "basic", "copymove", "props", "locks" and "http"
39//! checks][README_litmus] of the Webdav Litmus Test testsuite. That's all of the base
40//! [RFC4918] webdav specification.
41//!
42//! The litmus test suite also has tests for RFC3744 "acl" and "principal",
43//! RFC5842 "bind", and RFC3253 "versioning". Those we do not support right now.
44//!
45//! The relevant parts of the HTTP RFCs are also implemented, such as the
46//! preconditions (If-Match, If-None-Match, If-Modified-Since, If-Unmodified-Since,
47//! If-Range), partial transfers (Range).
48//!
49//! Also implemented is `partial PUT`, for which there are currently two
50//! non-standard ways to do it: [`PUT` with the `Content-Range` header][PUT],
51//! which is what Apache's `mod_dav` implements, and [`PATCH` with the `X-Update-Range`
52//! header][PATCH] from `SabreDav`.
53//!
54//! ## Backends.
55//!
56//! Included are two filesystems:
57//!
58//! - [`LocalFs`]: serves a directory on the local filesystem
59//! - [`MemFs`]: ephemeral in-memory filesystem. supports DAV properties.
60//!
61//! Also included are two locksystems:
62//!
63//! - [`MemLs`]: ephemeral in-memory locksystem.
64//! - [`FakeLs`]: fake locksystem. just enough LOCK/UNLOCK support for macOS/Windows.
65//!
66//! ## Example.
67//!
68//! Example server using [hyper] that serves the /tmp directory in r/w mode. You should be
69//! able to mount this network share from Linux, macOS and Windows. [Examples][examples]
70//! for other frameworks are also available.
71//!
72//! ```no_run
73//! use std::convert::Infallible;
74//! use webdav_handler::{fakels::FakeLs, localfs::LocalFs, DavHandler};
75//!
76//! #[tokio::main]
77//! async fn main() {
78//! let dir = "/tmp";
79//! let addr = ([127, 0, 0, 1], 4918).into();
80//!
81//! let dav_server = DavHandler::builder()
82//! .filesystem(LocalFs::new(dir, false, false, false))
83//! .locksystem(FakeLs::new())
84//! .build_handler();
85//!
86//! let make_service = hyper::service::make_service_fn(move |_| {
87//! let dav_server = dav_server.clone();
88//! async move {
89//! let func = move |req| {
90//! let dav_server = dav_server.clone();
91//! async move {
92//! Ok::<_, Infallible>(dav_server.handle(req).await)
93//! }
94//! };
95//! Ok::<_, Infallible>(hyper::service::service_fn(func))
96//! }
97//! });
98//!
99//! println!("Serving {} on {}", dir, addr);
100//! let _ = hyper::Server::bind(&addr)
101//! .serve(make_service)
102//! .await
103//! .map_err(|e| eprintln!("server error: {}", e));
104//! }
105//! ```
106//! [DavHandler]: struct.DavHandler.html
107//! [DavFileSystem]: fs/index.html
108//! [DavLockSystem]: ls/index.html
109//! [DavProp]: fs/struct.DavProp.html
110//! [`WebDav`]: https://tools.ietf.org/html/rfc4918
111//! [RFC4918]: https://tools.ietf.org/html/rfc4918
112//! [`MemLs`]: memls/index.html
113//! [`MemFs`]: memfs/index.html
114//! [`LocalFs`]: localfs/index.html
115//! [`FakeLs`]: fakels/index.html
116//! [actix-compat]: actix/index.html
117//! [warp-compat]: warp/index.html
118//! [README_litmus]: https://github.com/miquels/webdav-handler-rs/blob/master/README.litmus-test.md
119//! [examples]: https://github.com/miquels/webdav-handler-rs/tree/master/examples/
120//! [PUT]: https://github.com/miquels/webdav-handler-rs/tree/master/doc/Apache-PUT-with-Content-Range.md
121//! [PATCH]: https://github.com/miquels/webdav-handler-rs/tree/master/doc/SABREDAV-partialupdate.md
122//! [hyper]: https://hyper.rs/
123//! [warp]: https://crates.io/crates/warp
124//! [actix-web]: https://actix.rs/
125
126#![cfg_attr(docsrs, feature(doc_cfg))]
127
128#[macro_use]
129extern crate log;
130#[macro_use]
131extern crate lazy_static;
132
133mod async_stream;
134mod conditional;
135mod davhandler;
136mod davheaders;
137mod errors;
138mod handle_copymove;
139mod handle_delete;
140mod handle_gethead;
141mod handle_lock;
142mod handle_mkcol;
143mod handle_options;
144mod handle_props;
145mod handle_put;
146mod localfs_macos;
147mod localfs_windows;
148mod multierror;
149mod tree;
150mod util;
151mod voidfs;
152mod xmltree_ext;
153
154pub mod body;
155pub mod davpath;
156pub mod fakels;
157pub mod fs;
158pub mod localfs;
159pub mod ls;
160pub mod memfs;
161pub mod memls;
162
163#[cfg(any(docsrs, feature = "actix-compat"))]
164#[cfg_attr(docsrs, doc(cfg(feature = "actix-compat")))]
165pub mod actix;
166
167#[cfg(any(docsrs, feature = "warp-compat"))]
168#[cfg_attr(docsrs, doc(cfg(feature = "warp-compat")))]
169pub mod warp;
170
171pub(crate) use crate::davhandler::DavInner;
172pub(crate) use crate::errors::{DavError, DavResult};
173pub(crate) use crate::fs::*;
174
175pub use crate::davhandler::{DavConfig, DavHandler};
176pub use crate::util::{DavMethod, DavMethodSet};