arti/crates/arti-client/examples
eta dcdd8c59df Improve top-level arti-client documentation, add example code
This overhauls the top-level `arti-client` documentation significantly:

- the "Using arti-client" section walks the user through all of the
  necessary steps to initiate a Torified TCP connection, and then
  provides a code example
  - this example is also available as `examples/readme.rs`; it's not run
    as a doctest, since it involves connecting to Tor
  - a "More advanced usage" subheading provides information about stream
    isolation (and can potentially be used for other interesting
    features once we get them).
- a new "Multiple runtime support" section was added to explain the
  purpose and usage of the `tor-rtcompat` crate
- the section on design and privacy considerations was removed; this is
  probably okay to keep in a README, but users of the crate aren't going
  to be interested in this (at least I don't think)

(also, the doc comment for `arti_client::Error` was fixed to make actual
sense)
2021-10-28 19:20:42 +01:00
..
hyper.rs Rename tor_client/arti_tor_client to arti_client. 2021-10-21 14:22:11 -04:00
readme.rs Improve top-level arti-client documentation, add example code 2021-10-28 19:20:42 +01:00

readme.rs

use anyhow::Result;
use arti_client::{TorClient, TorClientConfig};
use tokio_crate as tokio;

use futures::io::{AsyncReadExt, AsyncWriteExt};

#[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 "sane 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::sane_defaults()?;
    // Arti needs an async runtime handle to spawn async tasks.
    let rt = tor_rtcompat::tokio::current_runtime()?;

    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::bootstrap(rt, config).await?;

    eprintln!("connecting to example.com...");

    let mut stream = tor_client.connect(("example.com", 80), None).await?;

    eprintln!("sending request...");

    stream
        .write_all(b"GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n")
        .await?;

    stream.flush().await?;

    eprintln!("reading response...");

    let mut buf = Vec::new();
    stream.read_to_end(&mut buf).await?;

    println!("{}", String::from_utf8_lossy(&buf));

    Ok(())
}