pub struct WebDavClient<C>{
pub base_url: Uri,
/* private fields */
}Expand description
Generic WebDAV client.
A WebDAV client that uses a parametrised http client C to perform the underlying HTTP
requests.
An existing http client that can be used is hyper_util::client::legacy::Client, although any
client which implements the trait bounds is acceptable. Essentially an http clients needs to
implement tower_service::Service, taking a Request<Service> as input and returning a
Response<Incoming>.
This means that the provided http client can simply be one that wraps around an existing one. These wrappers are called middleware in the Tower/Hyper ecosystem.
The most common and obvious example is one that adds an Authorization header to all outgoing
requests:
use http::Uri;
use hyper_rustls::HttpsConnectorBuilder;
use hyper_util::{client::legacy::Client, rt::TokioExecutor};
use tower_http::auth::AddAuthorization;
let uri = Uri::try_from("https://example.com").unwrap();
let https_connector = HttpsConnectorBuilder::new()
.with_native_roots()
.unwrap()
.https_or_http()
.enable_http1()
.build();
let http_client = Client::builder(TokioExecutor::new()).build(https_connector);
let auth_client = AddAuthorization::basic(http_client, "user", "secret");
let webdav = WebDavClient::new(uri, auth_client);The concrete type of the client in the above example is somewhat complex. For this reason, application code will usually want to use an alias for the concrete type being used, and use this alias through all types and functions that handle the WebDAV client:
type MyClient = WebDavClient<AddAuthorization<Client<HttpsConnector<HttpConnector>, String>>>;§Setting a custom User-Agent header
The following example uses a custom middleware which sets a specific User-Agent on each outgoing request:
use std::task::{Context, Poll};
use hyper::{
header::{HeaderValue, USER_AGENT},
Request, Response,
};
use tower_service::Service;
#[derive(Debug, Clone)]
pub struct UserAgent<S> {
inner: S,
user_agent: HeaderValue,
}
impl<S> UserAgent<S> {
/// Add a custom User-Agent to outgoing requests.
pub fn new(inner: S, user_agent: HeaderValue) -> UserAgent<S> {
UserAgent { inner, user_agent }
}
}
impl<S, Tx, Rx> Service<Request<Tx>> for UserAgent<S>
where
S: Service<Request<Tx>, Response = Response<Rx>>,
{
type Response = S::Response;
type Error = S::Error;
type Future = S::Future;
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.inner.poll_ready(cx)
}
fn call(&mut self, mut req: Request<Tx>) -> Self::Future {
req.headers_mut()
.insert(USER_AGENT, self.user_agent.clone());
self.inner.call(req)
}
}
// Elsewhere in your codebase...
use http::Uri;
use hyper_rustls::HttpsConnectorBuilder;
use hyper_util::{client::legacy::Client, rt::TokioExecutor};
use tower_http::auth::AddAuthorization;
let uri = Uri::try_from("https://example.com").unwrap();
let https_connector = HttpsConnectorBuilder::new()
.with_native_roots()
.unwrap()
.https_or_http()
.enable_http1()
.build();
let http_client = Client::builder(TokioExecutor::new()).build(https_connector);
let auth_client = UserAgent::new(http_client, "myapp/0.2.7".try_into().unwrap());
let webdav = WebDavClient::new(uri, auth_client);For other generic middleware of this style, consult the tower-http crate.
Fields§
§base_url: UriBase URL to be used for all requests.
This is composed of the domain+port used for the server, plus the context path where WebDAV requests are served.
Implementations§
Source§impl<C> WebDavClient<C>
impl<C> WebDavClient<C>
Sourcepub fn new(base_url: Uri, http_client: C) -> WebDavClient<C>
pub fn new(base_url: Uri, http_client: C) -> WebDavClient<C>
Builds a new WebDAV client.
Sourcepub fn relative_uri(&self, path: &str) -> Result<Uri, Error>
pub fn relative_uri(&self, path: &str) -> Result<Uri, Error>
Returns a new URI relative to the server’s root.
path MUST NOT be percent-encoded, except for any reserved characters.
§Errors
If this client’s base_url is invalid or the provided path is not an acceptable path.
Sourcepub async fn find_current_user_principal(
&self,
) -> Result<Option<Uri>, FindCurrentUserPrincipalError<C::Error>>
pub async fn find_current_user_principal( &self, ) -> Result<Option<Uri>, FindCurrentUserPrincipalError<C::Error>>
Resolves the current user’s principal resource.
First queries the base_url, then the root path on the same host.
Returns None if the response’s status code is 404 or if no principal was found.
§Errors
See FindCurrentUserPrincipalError
§See also
The DAV:current-user-principal property is defined in
https://www.rfc-editor.org/rfc/rfc5397#section-3
Sourcepub async fn request_raw(
&self,
request: Request<String>,
) -> Result<(Parts, Bytes), RequestError<C::Error>>
pub async fn request_raw( &self, request: Request<String>, ) -> Result<(Parts, Bytes), RequestError<C::Error>>
Send a raw request to the server.
Sends a request, applying any necessary authentication and logging the response.
This is a lower-level API. Prefer using WebDavClient::request with the Requests API
instead.
§Errors
Returns an error if the underlying http request fails or if streaming the response fails.
Sourcepub async fn find_context_path(
&self,
service: DiscoverableService,
host: &str,
port: u16,
) -> Result<Option<Uri>, ResolveContextPathError<C::Error>>
pub async fn find_context_path( &self, service: DiscoverableService, host: &str, port: u16, ) -> Result<Option<Uri>, ResolveContextPathError<C::Error>>
Resolve the default context path using a well-known path.
This only applies for servers supporting WebDAV extensions like CalDAV or CardDAV. Returns
Ok(None) if the well-known path does not redirect to another location.
§Errors
- If the provided scheme, host and port cannot be used to construct a valid URL.
- If there are any network errors.
- If the response is not an HTTP redirection.
- If the
Locationheader in the response is missing or invalid.
§See also
Sourcepub async fn request<R>(
&self,
request: R,
) -> Result<R::Response, R::Error<C::Error>>where
R: DavRequest,
R::Error<C::Error>: From<Error> + From<RequestError<C::Error>> + From<R::ParseError>,
pub async fn request<R>(
&self,
request: R,
) -> Result<R::Response, R::Error<C::Error>>where
R: DavRequest,
R::Error<C::Error>: From<Error> + From<RequestError<C::Error>> + From<R::ParseError>,
Execute a typed DAV request.
Provides a type-safe way to execute WebDAV operations using typed requests and response
types. Each request type implements the crate::requests::DavRequest trait, and can
therefore:
- Serialise itself into an HTTP request.
- Parse the HTTP response into a typed response.
§Example
use libdav::dav::GetEtag;
let response = webdav.request(
GetEtag::new("/calendar/event.ics")
).await?;
println!("Etag: {}", response.etag);§Errors
Returns an error if:
- The request cannot be prepared (e.g., invalid parameters).
- The HTTP request fails.
- The response cannot be parsed.
Trait Implementations§
Source§impl<C> Clone for WebDavClient<C>
impl<C> Clone for WebDavClient<C>
Source§fn clone(&self) -> WebDavClient<C>
fn clone(&self) -> WebDavClient<C>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more