1 个不稳定版本
0.1.0 | 2021 年 4 月 11 日 |
---|
#1109 在 文件系统
69KB
1.5K SLoC
vfs-https
通过 HTTPS 提供虚拟文件系统 (VFS)。
HttpsFSServer 提供了一个 VFS(实现 FileSystem),通过 HTTPS 提供访问。可以使用 HttpsFS 来访问 HttpsFSServer 提供的 FileSystem。
示例
这两个示例展示了 HttpsFSServer 和 HttpsFS 的使用方法。假设示例在 crate 根目录下执行。因此,可以在 crate 仓库中找到引用的文件。
请注意,假设使用的证书是针对 "localhost" 签发的。
您可以使用以下命令从仓库根目录运行服务器端示例
cargo run --example https_fs_server
在另一个终端启动客户端示例
cargo run --example https_fs
服务器端
此示例通过 HTTPS 提供一个内存文件系统。一旦服务器终止,文件系统的内容将丢失。
// Create a file system, which the server uses to access the files.
let fs = MemoryFS::new();
let server = HttpsFSServer::builder(fs)
// Since this test will not be executed as super user, we are not allowed to listen on
// a TCP port below 1000, such as the https port 443. Therefore we use a different port.
.set_port(8443)
// It is a https server, therefore we need to load a certificate, which the server
// uses. For the example we use a self signed certificate. If you want to know how to
// create a self signed certificate, see "/examples/cert/create.sh".
.load_certificates("examples/cert/cert.crt")
// We also need to load the private key, which belongs to the certificate.
.load_private_key("examples/cert/private-key.key")
// The server needs to authenticate the clients. Therefore we have to provide a method
// which // validates the user credentials. In this example, only the username 'user'
// and the password 'pass' is accepted.
// As authentication process, the 'Basic' method as defined by the
// [RFC7617](https://tools.ietf.org/html/rfc7617) is used.
.set_credential_validator(|username: &str, password: &str| {
username == "user" && password == "pass"
});
// Run the server. This call is blocking.
server.run()
客户端
此示例连接到 HttpsFSServer 并创建一个名为 "example.txt" 的文件(如果不存在的话),并向其追加一行新内容。之后,它读取整个文件并将内容打印到 stdout。只要服务器没有重启,此程序的输出将随每次调用而变化。
有关 FileSystem 的使用,请参阅 crate [vfs]。此 crate 使用 [chrono] 来生成时间戳。
// You can not access the server from a different host, since the used certificate is issued
// for the localhost and you have to use https://127.0.0.1:8443 to access the server. You can
// also not use IPs, i.g. https://127.0.0.1:8443, since we didn't issue the certificate
// for the IP.
let builder = HttpsFS::builder("localhost")
// Set the port used by the server. The default is 443.
.set_port(8443)
// Add the self signed certificate as root certificate. If we don't do this, the client
// refuses to connect to the HttpsFSServer. If the server uses a certificate issued by
// an official certificate authority, than we don't need to add an additional root
// certificate.
.add_root_certificate("examples/cert/cert.crt")
// The client will use the following method to get credentials for the authentication.
.set_credential_provider(|server_msg| {
println!(
"Server request authentification with message \"{}\".",
server_msg
);
(String::from("user"), String::from("pass"))
});
let root: VfsPath = builder.build()?.into();
let root = root.join("example.txt")?;
// make sure that the file exists
if !root.exists()? {
root.create_file()?;
}
// add a new line to the file
let mut file = root.append_file()?;
let time = Local::now();
let line = format!("{}: Hello HttpsFS!\n", time);
file.write(line.as_bytes())?;
// open file reading
let file = root.open_file()?;
// One should really use a BufReader, which reads files in chunks of 8kb.
// The Read trait, issues a new request to the HttpsFSServer with each call,
// even if only on byte is read. The headers of the http-protocol needs
// several hundred bytes, which makes small reads inefficient.
let mut buffed_file = std::io::BufReader::new(file);
// read file content
let mut content = String::new();
buffed_file.read_to_string(&mut content)?;
println!("Content of example.txt: \n{}", content);
待办事项
- 实现 HttpsFSServer 的 CGI 版本。
- 这将允许用户使用其最喜欢的网络托管商提供的任何网络服务器作为基础设施。优点是,网络托管商可以接管证书管理,这通常被视为一种责任。
- 编写一个可编译为 WebAssembly 的 HttpsFS 版本。
- 考虑提供 HttpsFS 的非阻塞版本。
- 连接到 HttpsFSServer 后执行版本检查。
许可协议:Apache-2.0
依赖项
~16–29MB
~569K SLoC