Skip to content

Commit fd764fa

Browse files
authored
Merge pull request #21 from n0-computer/matheus23/transfer-example
docs: Add simple file transfer example
2 parents d87f671 + 68d0b94 commit fd764fa

File tree

3 files changed

+96
-1
lines changed

3 files changed

+96
-1
lines changed

Diff for: Cargo.toml

+4-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ futures-util = "0.3.30"
9595
testdir = "0.9.1"
9696

9797
[features]
98-
default = ["fs-store", "rpc", "net_protocol", "example-iroh"]
98+
default = ["fs-store", "rpc", "net_protocol"]
9999
downloader = ["dep:parking_lot", "tokio-util/time", "dep:hashlink"]
100100
net_protocol = ["downloader"]
101101
fs-store = ["dep:reflink-copy", "redb", "dep:redb_v1", "dep:tempfile"]
@@ -134,6 +134,9 @@ name = "fetch-fsm"
134134
[[example]]
135135
name = "fetch-stream"
136136

137+
[[example]]
138+
name = "transfer"
139+
137140
[[example]]
138141
name = "hello-world-fetch"
139142
required-features = ["example-iroh"]

Diff for: examples/transfer.rs

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
use std::{path::PathBuf, str::FromStr};
2+
3+
use anyhow::Result;
4+
use iroh::{protocol::Router, Endpoint};
5+
use iroh_base::ticket::BlobTicket;
6+
use iroh_blobs::{
7+
net_protocol::Blobs,
8+
rpc::client::blobs::{ReadAtLen, WrapOption},
9+
util::{local_pool::LocalPool, SetTagOption},
10+
};
11+
12+
#[tokio::main]
13+
async fn main() -> Result<()> {
14+
// Create an endpoint, it allows creating and accepting
15+
// connections in the iroh p2p world
16+
let endpoint = Endpoint::builder().discovery_n0().bind().await?;
17+
18+
// We initialize the Blobs protocol in-memory
19+
let local_pool = LocalPool::default();
20+
let blobs = Blobs::memory().build(&local_pool, &endpoint);
21+
22+
// Now we build a router that accepts blobs connections & routes them
23+
// to the blobs protocol.
24+
let node = Router::builder(endpoint)
25+
.accept(iroh_blobs::ALPN, blobs.clone())
26+
.spawn()
27+
.await?;
28+
29+
let blobs = blobs.client();
30+
31+
let args = std::env::args().collect::<Vec<_>>();
32+
match &args.iter().map(String::as_str).collect::<Vec<_>>()[..] {
33+
[_cmd, "send", path] => {
34+
let abs_path = PathBuf::from_str(path)?.canonicalize()?;
35+
36+
println!("Analyzing file.");
37+
38+
let blob = blobs
39+
.add_from_path(abs_path, true, SetTagOption::Auto, WrapOption::NoWrap)
40+
.await?
41+
.finish()
42+
.await?;
43+
44+
let node_id = node.endpoint().node_id();
45+
let ticket = BlobTicket::new(node_id.into(), blob.hash, blob.format)?;
46+
47+
println!("File analyzed. Fetch this file by running:");
48+
println!("cargo run --example transfer -- receive {ticket} {path}");
49+
50+
tokio::signal::ctrl_c().await?;
51+
}
52+
[_cmd, "receive", ticket, path] => {
53+
let path_buf = PathBuf::from_str(path)?;
54+
let ticket = BlobTicket::from_str(ticket)?;
55+
56+
println!("Starting download.");
57+
58+
blobs
59+
.download(ticket.hash(), ticket.node_addr().clone())
60+
.await?
61+
.finish()
62+
.await?;
63+
64+
println!("Finished download.");
65+
println!("Copying to destination.");
66+
67+
let mut file = tokio::fs::File::create(path_buf).await?;
68+
let mut reader = blobs.read_at(ticket.hash(), 0, ReadAtLen::All).await?;
69+
tokio::io::copy(&mut reader, &mut file).await?;
70+
71+
println!("Finished copying.");
72+
}
73+
_ => {
74+
println!("Couldn't parse command line arguments.");
75+
println!("Usage:");
76+
println!(" # to send:");
77+
println!(" cargo run --example transfer -- send [FILE]");
78+
println!(" # this will print a ticket.");
79+
println!();
80+
println!(" # to receive:");
81+
println!(" cargo run --example transfer -- receive [TICKET] [FILE]");
82+
}
83+
}
84+
85+
// Gracefully shut down the node
86+
println!("Shutting down.");
87+
node.shutdown().await?;
88+
local_pool.shutdown().await;
89+
90+
Ok(())
91+
}

Diff for: src/downloader/test.rs

+1
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ async fn deduplication() {
121121
}
122122

123123
/// Tests that the request is cancelled only when all intents are cancelled.
124+
#[ignore = "flaky"]
124125
#[tokio::test]
125126
async fn cancellation() {
126127
let _guard = iroh_test::logging::setup();

0 commit comments

Comments
 (0)