1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
//! Universal "give me the bytes" entry point that dispatches on URL scheme.
//!
//! This is the API the CLI uses for non-HTTP URLs and the natural front door
//! for callers that just want curl-like behavior across many protocols.
//!
//! For HTTP/HTTPS, prefer [`crate::Request`] / [`crate::get`] directly —
//! they expose status, headers, and the full response model. `transfer`
//! discards everything except the body for those schemes.
use crate::error::{Error, Result};
use crate::url::Url;
/// Run the default operation for the URL's scheme and return its payload.
pub fn transfer(url_str: &str) -> Result<Vec<u8>> {
let url = Url::parse(url_str)?;
transfer_url(&url)
}
/// Same as [`transfer`] but starts from an already-parsed URL.
pub fn transfer_url(url: &Url) -> Result<Vec<u8>> {
match url.scheme.as_str() {
"http" | "https" => crate::Request::get(&format!(
"{}://{}{}{}",
url.scheme,
url.host,
if (url.scheme == "http" && url.port == 80)
|| (url.scheme == "https" && url.port == 443)
{
String::new()
} else {
format!(":{}", url.port)
},
url.path
))?
.send()
.map(|r| r.body),
"ftp" | "ftps" => crate::ftp::fetch(url),
"dict" => crate::dict::fetch(url),
"file" => crate::file::fetch(url),
"gopher" | "gophers" => crate::gopher::fetch(url),
"imap" | "imaps" => crate::imap::fetch(url),
"ldap" | "ldaps" => crate::ldap::fetch(url),
"mqtt" | "mqtts" => crate::mqtt::fetch(url),
"pop3" | "pop3s" => crate::pop3::fetch(url),
"rtsp" => crate::rtsp::fetch(url),
"sftp" | "scp" => {
// Library default: derive the user from the URL/`$USER`, take any
// password from the URL userinfo, and use TOFU known_hosts (no
// `-k`). The CLI calls `ssh::fetch_traced` directly so it can also
// thread `-u`, `--key`, and `-k`.
let user = crate::ssh::resolve_user(url, None)?;
let (_, password) = crate::ssh::userinfo_password(url);
let opts = crate::ssh::SshOptions {
password,
..Default::default()
};
crate::ssh::fetch(url, &opts, &user)
}
"tftp" => crate::tftp::fetch(url),
"ws" | "wss" => crate::websocket::fetch(url),
other => Err(Error::UnsupportedScheme(other.to_string())),
}
}