refractium 3.0.12

Extensible low-level reverse proxy for port multiplexing and protocol-based routing
Documentation
#[cfg(feature = "hooks")]
use crate::protocols::hooks::HookContext;
use tokio::io::{self, copy_bidirectional};
use tokio::net::TcpStream;

#[cfg(feature = "hooks")]
use crate::protocols::hooks::{Direction, HookedStream, ProtocolHook};
#[cfg(feature = "hooks")]
use std::sync::Arc;

/// Proxies data between two TCP streams bidirectionally.
///
/// This function sets `nodelay` on both sockets and performs a high-performance
/// asynchronous transfer of data between the client and the backend.
///
/// # Errors
///
/// Returns an `io::Error` if:
/// - Setting `nodelay` fails.
/// - Connecting to either stream fails.
/// - The bidirectional copy operation encounters a network error.
pub async fn proxy_tcp(
    mut client: TcpStream,
    mut backend: TcpStream,
    #[cfg(feature = "hooks")] hooks: Vec<Arc<dyn ProtocolHook>>,
    #[cfg(feature = "hooks")] protocol_name: String,
) -> io::Result<()> {
    client.set_nodelay(true)?;
    backend.set_nodelay(true)?;

    #[cfg(feature = "hooks")]
    {
        if !hooks.is_empty() {
            let client_addr = client.peer_addr()?;
            let ctx = HookContext {
                client_addr,
                protocol: protocol_name,
                session_id: rand::random::<u64>(),
            };

            let mut hooked_client =
                HookedStream::new(client, Direction::Inbound, hooks.clone(), ctx.clone());
            let mut hooked_backend = HookedStream::new(backend, Direction::Outbound, hooks, ctx);
            copy_bidirectional(&mut hooked_client, &mut hooked_backend).await?;
            return Ok(());
        }
    }

    copy_bidirectional(&mut client, &mut backend).await?;
    Ok(())
}