hyper-named-pipe 0.1.0

Hyper client bindings for Windows Named Pipes
use std::error::Error;

use http_body_util::{BodyExt, Full};
use hyper::{body::Bytes, service::service_fn, Response};
use hyper_named_pipe::{NamedPipeConnector, NAMED_PIPE_SCHEME};
use hyper_util::{
    client::legacy::Client,
    rt::{TokioExecutor, TokioIo},
};
use tokio::net::windows::named_pipe::ServerOptions;

#[tokio::test]
async fn test_roundtrip() -> Result<(), Box<dyn Error + Send + Sync>> {
    let pipe_name = r"\\.\pipe\named-pipe-test-server";
    let phrase = "hyper-named-pipe";

    let server = ServerOptions::new()
        .first_pipe_instance(true)
        .create(pipe_name)?;

    let service =
        service_fn(|_req| async { Ok::<_, hyper::Error>(Response::new(phrase.to_string())) });

    let _server = tokio::spawn(async move {
        server
            .connect()
            .await
            .expect("Failed to connect to named pipe");

        let io = TokioIo::new(server);

        hyper::server::conn::http1::Builder::new()
            .serve_connection(io, service)
            .await
            .expect("Failed to wrap named pipe server with hyper HTTP interface")
    });

    let builder = Client::builder(TokioExecutor::new());
    let client: Client<NamedPipeConnector, Full<Bytes>> = builder.build(NamedPipeConnector);

    let host = hex::encode(pipe_name);
    let uri_str = format!("{}://{}", NAMED_PIPE_SCHEME, host);
    let url = uri_str.parse().expect("Failed to parse uri");

    let mut response = client
        .get(url)
        .await
        .expect("Failed to get URL using hyper client");
    let mut bytes = Vec::default();

    while let Some(frame_result) = response.frame().await {
        let frame = frame_result.expect("Failed to fetch chunk from HTTP response");

        if let Some(segment) = frame.data_ref() {
            bytes.extend(segment.iter().as_slice());
        }
    }

    let string = String::from_utf8(bytes).expect("Failed to utf8 encode HTTP response bytes");

    assert_eq!(phrase, string);

    Ok(())
}