blob: e8304ea66d98e1418465354d289725a7c8553d34 (
plain)
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
|
#![cfg_attr(not(ci_arti_nightly), allow(unknown_lints))]
// @@ begin test lint list maintained by maint/add_warning @@
#![allow(clippy::bool_assert_comparison)]
#![allow(clippy::clone_on_copy)]
#![allow(clippy::dbg_macro)]
#![allow(clippy::mixed_attributes_style)]
#![allow(clippy::print_stderr)]
#![allow(clippy::print_stdout)]
#![allow(clippy::single_char_pattern)]
#![allow(clippy::unwrap_used)]
#![allow(clippy::unchecked_duration_subtraction)]
#![allow(clippy::useless_vec)]
#![allow(clippy::needless_pass_by_value)]
//! <!-- @@ end test lint list maintained by maint/add_warning @@ -->
use anyhow::Result;
use arti_client::{TorClient, TorClientConfig};
use tokio_crate as tokio;
use futures::io::{AsyncReadExt, AsyncWriteExt};
use tor_error::ErrorReport;
#[tokio::main]
async fn main() -> Result<()> {
// Arti uses the `tracing` crate for logging. Install a handler for this, to print Arti's logs.
tracing_subscriber::fmt::init();
// The client config includes things like where to store persistent Tor network state.
// The defaults provided are the same as the Arti standalone application, and save data
// to a conventional place depending on operating system (for example, ~/.local/share/arti
// on Linux platforms)
let config = TorClientConfig::default();
eprintln!("connecting to Tor...");
// We now let the Arti client start and bootstrap a connection to the network.
// (This takes a while to gather the necessary consensus state, etc.)
let tor_client = TorClient::create_bootstrapped(config).await?;
eprintln!("connecting to example.com...");
// Initiate a connection over Tor to example.com, port 80.
// Note: here we try to handle the potential error using match
match tor_client.connect(("example.com", 80)).await {
Ok(mut stream) => {
eprintln!("sending request...");
stream
.write_all(b"GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n")
.await?;
// IMPORTANT: Make sure the request was written.
// Arti buffers data, so flushing the buffer is usually required.
stream.flush().await?;
eprintln!("reading response...");
// Read and print the result.
let mut buf = Vec::new();
stream.read_to_end(&mut buf).await?;
println!("{}", String::from_utf8_lossy(&buf));
}
Err(err) => {
// Use .report() on an error to get a nicer error message
// Raw Debug output will be much harder to decipher for all parties involved
eprintln!("{}", err.report());
}
}
Ok(())
}
|