Skip to content

WIP: HttpsFS #16

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 8 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,24 @@ travis-ci = { repository = "manuel-woelker/rust-vfs", branch = "master" }
thiserror = "1.0"
rust-embed = { version = "5.6", optional = true }
radix_trie = { version = "0.1", optional = true }
hyper = { version = "0.14.2", features = [ "server" ] }
hyper-rustls = "0.22.1"
rustls = "0.19.0"
tokio = { version = "1.1.0", features = [ "io-std", "macros", "net", "rt-multi-thread" ] }
tokio-rustls = "0.22.0"
syn = "1.0.60"
async-stream = "0.3.0"
futures-util = { version = "0.3.12", default-features = false }
reqwest = { version = "0.11", features = ["blocking", "cookies"] }
serde = { version = "1.0.123", features = ["derive"] }
serde_json = "1.0.60"
base64 = "0.13.0"
rand = "0.8.3"
chrono = "0.4.0"

[dev-dependencies]
uuid = { version = "=0.8.1", features = ["v4"] }
lazy_static = "1.4.0"

[features]
embedded-fs = ["rust-embed", "radix_trie"]
4 changes: 4 additions & 0 deletions examples/cert/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# DO NOT USE THIS CERTIFICATE IN YOUR PROJECT

This certificate is used for the unit tests and for the example program.
Create your own certificate for your project!
29 changes: 29 additions & 0 deletions examples/cert/cert.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
-----BEGIN CERTIFICATE-----
MIIFCTCCAvGgAwIBAgIUE2NwJIRWBysQLCMYCc/qUVU3N8gwDQYJKoZIhvcNAQEL
BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTIxMDEyNjE5NTUzMloXDTIyMDEy
NjE5NTUzMlowFDESMBAGA1UEAwwJbG9jYWxob3N0MIICIjANBgkqhkiG9w0BAQEF
AAOCAg8AMIICCgKCAgEAyIobXqqFcKbYGJ8Xko4XrFngIYaDhYV5sQoytGECzZJa
QuSLHwITTByBbuhZQAFY08yIv+fpbXxWwm0NnLf9xsTTqCwjANIGxNPvsCP3Z8pv
8Q1O/YbQJZ6EVflSYKmUvHLG+gIsldLaZg+0fY1l0elYce818zl0oM589n5tDlMX
0jiKT5gnXAq4lqEyWe7uNc0Dm3qB+im6SPdNVi8B6g+orlcZ3pubZ07z+RWqHMV6
cr5AGY1FVvjEcSGs2v++oYajyA2pHT3ITGq6XHd7Kqmeq5UaOzwhWJzNZuM4yMpS
sk81KuoA2RG+xDg+3thcG8ePiruaWt7MjALwoR+VvwaraDC8xGj6MP5yCvrQLCbV
Vk5yMOAL66mHg1u5MJhb+yte7XrBEpPJm9OHwxTyLuhf0bkY5sXSmbWtiNYeLGCa
qRal1bErbvCcgNrCZ9hrXn1IoCS1i14vmVqj+ZCPNThx7ROr/f/XUtPUvyR/kKUa
VEChLlDHxo120flTXrU8VGpkKCht1CMeT9iASNmu0od9c4iAcH86eDyMueaKiP0i
xr1crYp1UAWpZbxmFh/a9UbVVltLpS96TQ3RhAfwIs0VL4uMXt4Xs+CcB94Ma/4z
wPASZIoRPFhr+Mo4lrkP5NavLcHu5TfBx9YNiCnMCzXxeLUOpSy8Qzci7xoshg0C
AwEAAaNTMFEwHQYDVR0OBBYEFENBLBVjK1WgzQkP3fL5x/BRvVDsMB8GA1UdIwQY
MBaAFENBLBVjK1WgzQkP3fL5x/BRvVDsMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI
hvcNAQELBQADggIBAC5N0nO6qCyVNPk/a9gkj1aD2RkKz2otvzxQtxqPstUXeq3w
XRskxpwcgXFdPaFEen33k3ntvwVf9TNbOSodnfstHU4tCmH5UeNmOArJAjcCe7WD
ImAPqPUfjaxIZQraRuLXpn7B9dYA4txDDCSmwox0StcP+5lSE9Ih7FE7ACQr6zbn
jcPubVm7EMWKyOiA1+4+xp1FlAQdX2ilDRddOVaIpZmvFuh2inZOIhyZFuaKkE/b
15AlWp1eRupRiBzgV08KFnmwpHCziSjaFDKjyqXlgHmiiB9x8DyqqXY3c0AzA6ZJ
CNpXe/opCoT7aIi0jqY/5vEXFEN+8GDxt+DDhFqqrM7h5Ss3lQTHP0h1DZXK7qJ7
OGEv2eL+Zu6e4x5eQMCsx9QSORbPQQ1045HBwSRdWbloB6kC2IpUPnWEX9HqaqZl
5UmWtlD53/+qGKtg8uesLKXoSH6UXzyFOMkPN/+pTHi7qkJyDo436aM4JJisXRjC
rWd79fV1Iw0iBwxLILd81rWk4C46MfMby2KX27SyXvKEg2r6jT+HM/E0dY6nBB9y
z+ow+7TLEedfHudnbqSRRi2UjoWYwVecSV1FeQqHLgeTV7agcXPKpPGfudd0Z80u
7sppz5OFEQaF+hggJZGHd4KKuwwp0ME32BbmTpLOdOZQUzuZjwhDgEmF1ou+
-----END CERTIFICATE-----
3 changes: 3 additions & 0 deletions examples/cert/create.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh

openssl req -x509 -newkey rsa:4096 -keyout private-key.key -out cert.crt -days 365 -sha256 -nodes --subj '/CN=localhost/'
52 changes: 52 additions & 0 deletions examples/cert/private-key.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
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
VbKjdjPHxtqQ3UX3lu/gpPx52zGl
-----END PRIVATE KEY-----
70 changes: 70 additions & 0 deletions examples/https_fs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
use chrono::prelude::*;
use std::io::Read;
use vfs::HttpsFS;
use vfs::VfsPath;

// this is an example for the HttpsFS which creates a file "example.txt" and
// writes one new line to it, containing the current date and "Hello World!".
// Afterwards it reads the whole file and prints the content to the stdout.
//
// As long as the server is not restarted, the output of this program will
// change with each call.
//
// Since the example HttpsFSServer (https_fs_server.rs) is using a MemoryFS,
// the content of the server are lost after a restart.
fn main() -> vfs::VfsResult<()> {
// load the certificate by our server (https_fs_server.rs)
let cert = HttpsFS::load_certificate("examples/cert/cert.crt").unwrap();

// create a server
// You can not access the server from a different host, since our certificate
// is issued for the localhost and you have to use https://localhost:8443 to
// access the server. You can 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, as default the client uses 443
.set_port(8443)
// we need to add our self signed certificate as root
// certificate, otherwise the client don't connect to the
// HttpsFSServer.
// If the server uses a certificate issued by a official
// certificate authority, than we don't need to add an additional
// certificate.
.add_root_certificate(cert)
// if the server requests a authentification, than this method is called to
// get the credentials for the authentification
.set_credential_provider(|server_msg| {
println!(
"Server request authentification with message \"{}\".",
server_msg
);
(String::from("user"), String::from("pass"))
});
let root: VfsPath = builder.build().unwrap().into();
let root = root.join("example.txt")?;

// make sure that file exists
if !root.exists()? {
root.create_file()?;
}

// add additional a new line
let mut file = root.append_file()?;
let time = Local::now();
let line = format!("{}: Hello World!\n", time);
file.write(line.as_bytes())?;

// read file content
let mut content = String::new();
let file = root.open_file()?;

// One should really use a BufReader, which reads files in chunks of 8kb.
// The read() of 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);
buffed_file.read_to_string(&mut content)?;
println!("Content example.txt: \n{}", content);

Ok(())
}
36 changes: 36 additions & 0 deletions examples/https_fs_server.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use vfs::{load_certs, load_private_key, HttpsFSServer, MemoryFS};

fn main() {
// create a file system, which the server uses to access the file system
// Note: You can also put another HttpsFS in the HttpsFSServer, which would
// redirect the request to another HttpsFSServer. Obviously, this does
// not make much sense.
let fs = MemoryFS::new();

// It is a https server, therefore we need to load certificate, which the server
// uses. For the example we use a self signed certificate. If you are interested
// in how to use the certificate, see "/examples/cert/create.sh"
let cert = load_certs("examples/cert/cert.crt").unwrap();

// We need also a private key, which belongs to the certificate
let private_key = load_private_key("examples/cert/private-key.key").unwrap();

// Since this test will not be executed as root, we are not allowed to listen on
// a tcp port below 1000, such as the https port 443. Therefore lets take a
// different port.
let port = 8443;

// The server will use this method to validate, whether the login credentials
// are valide or not. In this example, only the username 'user' and the password
// 'pass' is accepted.
// As authentication process, 'Basic' method as defined by the
// [RFC7617](https://tools.ietf.org/html/rfc7617) is used.
let credential_validator =
|username: &str, password: &str| username == "user" && password == "pass";

// Initiate the server object
let mut server = HttpsFSServer::new(port, cert, private_key, fs, credential_validator);

// Start the server.
server.run().unwrap();
}
Loading