Module proxy_header::io

source ·
Expand description

IO wrapper for proxied streams.

PROXY protocol header is variable length so it is not possible to read a fixed number of bytes directly from the stream and reading it byte-by-byte can be inefficient. ProxiedStream reads enough bytes to parse the header and retains any extra bytes that may have been read.

If the underlying stream is already buffered (i.e. std::io::BufRead or equivalent), it is probably a better idea to just decode the header directly instead of using ProxiedStream.

The wrapper is usable both with standard (std::io::Read) and Tokio streams ([tokio::io::AsyncRead]).

§Example (Tokio)

use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::TcpListener;
use proxy_header::io::ProxiedStream;

let listener = TcpListener::bind("[::]:1234").await?;

loop {
    let (mut socket, _) = listener.accept().await?;
    tokio::spawn(async move {
        // Read the proxy header first
        let mut socket = ProxiedStream::create_from_tokio(socket, Default::default())
            .await
            .expect("failed to create proxied stream");

        // We can now inspect the address
        println!("proxy header: {:?}", socket.proxy_header());

        /// Then process the protocol
        let mut buf = vec![0; 1024];
        loop {
            let n = socket.read(&mut buf).await.unwrap();
            if n == 0 {
                return;
            }
            socket.write_all(&buf[0..n]).await.unwrap();
        }
    });
}

Structs§

  • Wrapper around a stream that starts with a proxy header.