~athorp96/Coil

9d629cba1a1cb95ea10e5843b92ab654225eb3d2 — Andrew Thorp 3 years ago c81468a
Add README
6 files changed, 67 insertions(+), 155 deletions(-)

M Cargo.lock
M Cargo.toml
A README.md
M src/main.rs
M src/request.rs
M src/response.rs
M Cargo.lock => Cargo.lock +0 -126
@@ 30,12 30,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"

[[package]]
name = "bumpalo"
version = "3.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631"

[[package]]
name = "bytes"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 95,7 89,6 @@ dependencies = [
 "tokio",
 "tokio-native-tls",
 "url",
 "webpki-roots",
]

[[package]]


@@ 196,15 189,6 @@ dependencies = [
]

[[package]]
name = "js-sys"
version = "0.3.51"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83bdfbace3a0e81a4253f73b49e960b053e396a11012cbd49b9b74d6a2b67062"
dependencies = [
 "wasm-bindgen",
]

[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 466,21 450,6 @@ dependencies = [
]

[[package]]
name = "ring"
version = "0.16.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
dependencies = [
 "cc",
 "libc",
 "once_cell",
 "spin",
 "untrusted",
 "web-sys",
 "winapi",
]

[[package]]
name = "schannel"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 514,12 483,6 @@ dependencies = [
]

[[package]]
name = "spin"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"

[[package]]
name = "strsim"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 658,12 621,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"

[[package]]
name = "untrusted"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"

[[package]]
name = "url"
version = "2.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 700,89 657,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"

[[package]]
name = "wasm-bindgen"
version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd"
dependencies = [
 "cfg-if",
 "wasm-bindgen-macro",
]

[[package]]
name = "wasm-bindgen-backend"
version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900"
dependencies = [
 "bumpalo",
 "lazy_static",
 "log",
 "proc-macro2",
 "quote",
 "syn",
 "wasm-bindgen-shared",
]

[[package]]
name = "wasm-bindgen-macro"
version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4"
dependencies = [
 "quote",
 "wasm-bindgen-macro-support",
]

[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97"
dependencies = [
 "proc-macro2",
 "quote",
 "syn",
 "wasm-bindgen-backend",
 "wasm-bindgen-shared",
]

[[package]]
name = "wasm-bindgen-shared"
version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f"

[[package]]
name = "web-sys"
version = "0.3.51"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e828417b379f3df7111d3a2a9e5753706cae29c41f7c4029ee9fd77f3e09e582"
dependencies = [
 "js-sys",
 "wasm-bindgen",
]

[[package]]
name = "webpki"
version = "0.21.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea"
dependencies = [
 "ring",
 "untrusted",
]

[[package]]
name = "webpki-roots"
version = "0.21.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940"
dependencies = [
 "webpki",
]

[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"

M Cargo.toml => Cargo.toml +0 -1
@@ 13,4 13,3 @@ native-tls = "0.2"
tokio = { version = "1.9.0", features = ["rt-multi-thread", "macros", "net", "io-std", "io-util"] }
tokio-native-tls = "0.3"
url = "2.2.2"
webpki-roots = "0.21"

A README.md => README.md +25 -0
@@ 0,0 1,25 @@
# Coil

Coil is a curl-like [Gemini](https://gemini.circumlunar.space) client.

It is still under development, so the best usage instructions would be the current `clap` help.
This can be found with `coil --help` or in the cloned repository with `cargo run -- --help`.

## Installation 
### Dependencies
- Rust 1.47.0 (stable) or compatible
- Cargo

### Clone repository
```
git clone git@git.sr.ht::~athorp/Coil coil
cd coil
```

### Build and Install
```
cargo build --release

# Copy or symlink the binary into your path or call from the compiled location with
./target/release/coil --help
```

M src/main.rs => src/main.rs +26 -26
@@ 1,15 1,11 @@
use anyhow::{anyhow, Context, Result};
use anyhow::{Context, Result};
use clap::{AppSettings, Clap};
use native_tls::TlsConnector;
use std::convert::TryFrom;
use std::fs::File;
use std::io;
use std::io::BufReader;
use std::net::ToSocketAddrs;
use std::path::PathBuf;
use std::sync::Arc;
use tokio::io::{copy, split, stdout as tokio_stdout, AsyncWriteExt};
use tokio::io::AsyncWriteExt;
use tokio::net::TcpStream;
use tokio_native_tls::TlsStream as TokioTlsStream;

mod request;
mod response;


@@ 27,14 23,12 @@ struct Coil {
    port: u16,
}

#[tokio::main]
async fn main() -> Result<()> {
    let coil: Coil = Coil::parse();

    let req = request::Request::try_from(coil.hostname).context("Error creating request")?;

    // Open TCP connection
    let addr = (req.host.clone(), coil.port)
/// Open a TLS connection and return the resulting TlsStream
async fn open_tls_connection(
    request: request::Request,
    port: u16,
) -> Result<TokioTlsStream<TcpStream>> {
    let addr = (request.host.clone(), port)
        .to_socket_addrs()
        .context("Error parsing hostname")?
        .next()


@@ 50,24 44,30 @@ async fn main() -> Result<()> {
        .await
        .context("TCP Connection failure")?;

    let mut stream = connector
        .connect(req.host.as_str(), stream)
    // TLS handshake
    let stream = connector
        .connect(request.host.as_str(), stream)
        .await
        .context("Connection failed")?;

    stream.write_all(&req.as_bytes()).await?;
    Ok(stream)
}

    let (mut reader, mut writer) = split(stream);
#[tokio::main]
async fn main() -> Result<()> {
    let coil: Coil = Coil::parse();

    let mut stdout = tokio_stdout();
    let req = request::Request::try_from(coil.hostname).context("Error creating request")?;

    println!("Response from server: ");
    let mut stream = open_tls_connection(req.clone(), coil.port)
        .await
        .context("Error establishing TLS connection")?;

    copy(&mut reader, &mut stdout).await?;
    stream.write_all(&req.as_bytes()).await?;

    Ok(())
    response::handle_response(stream)
        .await
        .context("Error handling response")?;

    // Validate certificate
    // Send request
    // Handle response
    Ok(())
}

M src/request.rs => src/request.rs +2 -2
@@ 1,8 1,8 @@
use anyhow::{anyhow, Context, Result};
use std::convert::TryFrom;
use url::{Host, Url};
use url::Url;

#[derive(Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Request {
    pub protocol: String,
    pub host: String,

M src/response.rs => src/response.rs +14 -0
@@ 1,5 1,8 @@
use anyhow::{anyhow, Result};
use std::convert::TryFrom;
use tokio::io::{copy, split, stdout as tokio_stdout};
use tokio::net::TcpStream;
use tokio_native_tls::TlsStream as TokioTlsStream;

#[derive(Debug, Eq, PartialEq)]
enum StatusCode {


@@ 104,3 107,14 @@ mod tests {
        );
    }
}

pub async fn handle_response(stream: TokioTlsStream<TcpStream>) -> Result<()> {
    let (mut reader, _writer) = split(stream);

    let mut stdout = tokio_stdout();

    println!("Response from server: ");

    copy(&mut reader, &mut stdout).await?;
    Ok(())
}