-
Notifications
You must be signed in to change notification settings - Fork 28
Expand file tree
/
Copy pathtransfer.rs
More file actions
93 lines (73 loc) · 3.41 KB
/
transfer.rs
File metadata and controls
93 lines (73 loc) · 3.41 KB
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
use std::path::PathBuf;
use iroh::{endpoint::presets, protocol::Router, Endpoint};
use iroh_blobs::{store::mem::MemStore, ticket::BlobTicket, BlobsProtocol};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// Create an endpoint, it allows creating and accepting
// connections in the iroh p2p world
let endpoint = Endpoint::bind(presets::N0).await?;
// We initialize an in-memory backing store for iroh-blobs
let store = MemStore::new();
// Then we initialize a struct that can accept blobs requests over iroh connections
let blobs = BlobsProtocol::new(&store, None);
// Grab all passed in arguments, the first one is the binary itself, so we skip it.
let args: Vec<String> = std::env::args().skip(1).collect();
// Convert to &str, so we can pattern-match easily:
let arg_refs: Vec<&str> = args.iter().map(String::as_str).collect();
match arg_refs.as_slice() {
["send", filename] => {
let filename: PathBuf = filename.parse()?;
let abs_path = std::path::absolute(&filename)?;
println!("Hashing file.");
// When we import a blob, we get back a "tag" that refers to said blob in the store
// and allows us to control when/if it gets garbage-collected
let tag = store.blobs().add_path(abs_path).await?;
let node_id = endpoint.id();
let ticket = BlobTicket::new(node_id.into(), tag.hash, tag.format);
println!("File hashed. Fetch this file by running:");
println!(
"cargo run --example transfer -- receive {ticket} {}",
filename.display()
);
// For sending files we build a router that accepts blobs connections & routes them
// to the blobs protocol.
let router = Router::builder(endpoint)
.accept(iroh_blobs::ALPN, blobs)
.spawn();
tokio::signal::ctrl_c().await?;
// Gracefully shut down the node
println!("Shutting down.");
router.shutdown().await?;
}
["receive", ticket, filename] => {
let filename: PathBuf = filename.parse()?;
let abs_path = std::path::absolute(filename)?;
let ticket: BlobTicket = ticket.parse()?;
// For receiving files, we create a "downloader" that allows us to fetch files
// from other nodes via iroh connections
let downloader = store.downloader(&endpoint);
println!("Starting download.");
downloader
.download(ticket.hash(), Some(ticket.addr().id))
.await?;
println!("Finished download.");
println!("Copying to destination.");
store.blobs().export(ticket.hash(), abs_path).await?;
println!("Finished copying.");
// Gracefully shut down the node
println!("Shutting down.");
endpoint.close().await;
}
_ => {
println!("Couldn't parse command line arguments: {args:?}");
println!("Usage:");
println!(" # to send:");
println!(" cargo run --example transfer -- send [FILE]");
println!(" # this will print a ticket.");
println!();
println!(" # to receive:");
println!(" cargo run --example transfer -- receive [TICKET] [FILE]");
}
}
Ok(())
}