Connection

Struct Connection 

Source
pub struct Connection { /* private fields */ }
Expand description

A wrapper around a TCP stream that provides additional connection management functionality.

The Connection struct encapsulates a Tokio TcpStream and provides methods for accessing connection metadata, managing the connection lifecycle, and obtaining address information for both the local and remote endpoints.

§Design Philosophy

This struct follows the principle of providing a clean, safe interface around the underlying TCP stream while maintaining high performance and low overhead. It allows for future extensibility of connection management features without breaking existing code.

§Thread Safety

The Connection struct is not inherently thread-safe, as it wraps a TcpStream which is designed to be used from a single task. However, it can be safely moved between tasks and used in async contexts.

§Examples

§Basic Usage

use ignitia::server::connection::Connection;
use tokio::net::TcpStream;

// Create a connection (usually done by the server)
let stream = TcpStream::connect("httpbin.org:80").await?;
let connection = Connection::new(stream);

// Access connection information
let peer = connection.peer_addr()?;
let local = connection.local_addr()?;

println!("Connected to {} from {}", peer, local);

§Connection Information Logging

use ignitia::server::connection::Connection;
use tokio::net::TcpStream;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};

let stream = TcpStream::connect("example.com:443").await?;
let connection = Connection::new(stream);

if let Ok(peer_addr) = connection.peer_addr() {
    match peer_addr.ip() {
        IpAddr::V4(ipv4) => {
            println!("IPv4 connection: {}:{}", ipv4, peer_addr.port());
            if ipv4.is_private() {
                println!("Connection from private network");
            }
        }
        IpAddr::V6(ipv6) => {
            println!("IPv6 connection: [{}]:{}", ipv6, peer_addr.port());
            if ipv6.is_loopback() {
                println!("Local IPv6 connection");
            }
        }
    }
}

Implementations§

Source§

impl Connection

Source

pub fn new(stream: TcpStream) -> Self

Creates a new Connection wrapper around the provided TCP stream.

This constructor takes ownership of the TCP stream and wraps it in a Connection instance that provides additional functionality and a cleaner API for connection management.

§Parameters
  • stream: The TcpStream to wrap
§Returns

A new Connection instance

§Examples
use ignitia::server::connection::Connection;
use tokio::net::TcpStream;

let stream = TcpStream::connect("example.com:80").await?;
let connection = Connection::new(stream);
§Server Context Usage
use ignitia::server::connection::Connection;
use tokio::net::{TcpListener, TcpStream};

let listener = TcpListener::bind("127.0.0.1:3000").await?;

loop {
    let (stream, _addr) = listener.accept().await?;
    let connection = Connection::new(stream);

    // Handle the connection
    tokio::spawn(async move {
        // Connection handling logic would go here
        if let Ok(peer) = connection.peer_addr() {
            println!("New connection from: {}", peer);
        }
    });
}
Source

pub fn stream(&self) -> &TcpStream

Returns a reference to the underlying TCP stream.

This method provides read-only access to the wrapped TcpStream without transferring ownership. This is useful when you need to inspect stream properties or perform operations that require a stream reference.

§Returns

A reference to the underlying TcpStream

§Examples
use ignitia::server::connection::Connection;
use tokio::net::TcpStream;

let stream = TcpStream::connect("example.com:80").await?;
let connection = Connection::new(stream);

// Access the stream reference
let stream_ref = connection.stream();

// You can now use stream_ref for operations that need a reference
// For example, checking if the stream is readable
§Advanced Stream Operations
use ignitia::server::connection::Connection;
use tokio::net::TcpStream;
use tokio::io::{AsyncReadExt, AsyncWriteExt};

let stream = TcpStream::connect("httpbin.org:80").await?;
let mut connection = Connection::new(stream);

// Get a reference to perform operations
let stream_ref = connection.stream();

// Note: For actual I/O operations, you'd typically use into_stream()
// to get ownership of the stream
Source

pub fn into_stream(self) -> TcpStream

Consumes the connection and returns the underlying TCP stream.

This method transfers ownership of the wrapped TcpStream back to the caller, consuming the Connection wrapper in the process. This is useful when you need direct access to the stream for I/O operations or when integrating with APIs that require ownership of the stream.

§Returns

The underlying TcpStream

§Examples
use ignitia::server::connection::Connection;
use tokio::net::TcpStream;
use tokio::io::{AsyncReadExt, AsyncWriteExt};

let stream = TcpStream::connect("httpbin.org:80").await?;
let connection = Connection::new(stream);

// Extract the stream for direct I/O operations
let mut stream = connection.into_stream();

// Now you can perform I/O operations directly
stream.write_all(b"GET / HTTP/1.1\r\nHost: httpbin.org\r\n\r\n").await?;

let mut response = Vec::new();
stream.read_to_end(&mut response).await?;
§Integration with WebSocket Libraries
use ignitia::server::connection::Connection;
use tokio::net::TcpStream;

let stream = TcpStream::connect("echo.websocket.org:80").await?;
let connection = Connection::new(stream);

// Extract stream for WebSocket upgrade
let stream = connection.into_stream();

// Use stream with WebSocket libraries
// let ws_stream = tokio_tungstenite::accept_async(stream).await?;
Source

pub fn peer_addr(&self) -> Result<SocketAddr>

Returns the remote peer address of the TCP connection.

This method retrieves the socket address of the remote peer that this connection is connected to. This is useful for logging, security checks, rate limiting, and other connection management tasks.

§Returns
  • Ok(SocketAddr): The remote peer’s socket address
  • Err(io::Error): If the peer address cannot be determined
§Errors

This method can return an error if:

  • The connection has been closed
  • The underlying socket is in an invalid state
  • System-level networking errors occur
§Examples
§Basic Peer Address Retrieval
use ignitia::server::connection::Connection;
use tokio::net::TcpStream;

let stream = TcpStream::connect("httpbin.org:80").await?;
let connection = Connection::new(stream);

match connection.peer_addr() {
    Ok(addr) => println!("Connected to: {}", addr),
    Err(e) => eprintln!("Failed to get peer address: {}", e),
}
§Security and Rate Limiting
use ignitia::server::connection::Connection;
use tokio::net::TcpStream;
use std::collections::HashMap;

let stream = TcpStream::connect("example.com:80").await?;
let connection = Connection::new(stream);

// Example rate limiting based on IP address
if let Ok(peer_addr) = connection.peer_addr() {
    let ip = peer_addr.ip();

    // Check if this IP is allowed
    if ip.is_loopback() {
        println!("Local connection allowed: {}", ip);
    } else if ip.to_string().starts_with("192.168.") {
        println!("Private network connection: {}", ip);
    } else {
        println!("External connection from: {}", ip);
    }
}
§Geographic Information (Conceptual)
use ignitia::server::connection::Connection;
use tokio::net::TcpStream;
use std::net::IpAddr;

let stream = TcpStream::connect("google.com:80").await?;
let connection = Connection::new(stream);

if let Ok(peer_addr) = connection.peer_addr() {
    match peer_addr.ip() {
        IpAddr::V4(ipv4) => {
            if ipv4.is_private() {
                println!("Private IPv4: {}", ipv4);
            } else if ipv4.is_multicast() {
                println!("Multicast IPv4: {}", ipv4);
            } else {
                println!("Public IPv4: {}", ipv4);
                // In a real application, you might do GeoIP lookup here
            }
        }
        IpAddr::V6(ipv6) => {
            if ipv6.is_loopback() {
                println!("Loopback IPv6: {}", ipv6);
            } else {
                println!("IPv6 address: {}", ipv6);
            }
        }
    }
}
Source

pub fn local_addr(&self) -> Result<SocketAddr>

Returns the local socket address of the TCP connection.

This method retrieves the local socket address that this connection is bound to. This is useful for determining which local interface and port the connection is using, which can be important for logging, debugging, and network configuration validation.

§Returns
  • Ok(SocketAddr): The local socket address
  • Err(io::Error): If the local address cannot be determined
§Errors

This method can return an error if:

  • The connection has been closed
  • The underlying socket is in an invalid state
  • System-level networking errors occur
§Examples
§Basic Local Address Retrieval
use ignitia::server::connection::Connection;
use tokio::net::TcpStream;

let stream = TcpStream::connect("httpbin.org:80").await?;
let connection = Connection::new(stream);

match connection.local_addr() {
    Ok(addr) => println!("Local address: {}", addr),
    Err(e) => eprintln!("Failed to get local address: {}", e),
}
§Server Configuration Validation
use ignitia::server::connection::Connection;
use tokio::net::{TcpListener, TcpStream};

// Server setup
let listener = TcpListener::bind("127.0.0.1:0").await?; // Bind to any available port
let server_addr = listener.local_addr()?;

// Client connection
let stream = TcpStream::connect(server_addr).await?;
let connection = Connection::new(stream);

// Verify the connection is using the expected local configuration
if let Ok(local_addr) = connection.local_addr() {
    println!("Connected via local address: {}", local_addr);
    println!("Local port: {}", local_addr.port());

    if local_addr.ip().is_loopback() {
        println!("Using loopback interface");
    }
}
§Multi-Interface Server Debugging
use ignitia::server::connection::Connection;
use tokio::net::TcpStream;
use std::net::{IpAddr, Ipv4Addr};

let stream = TcpStream::connect("example.com:80").await?;
let connection = Connection::new(stream);

// Debug which local interface is being used
if let (Ok(local_addr), Ok(peer_addr)) = (connection.local_addr(), connection.peer_addr()) {
    println!("Connection: {} -> {}", local_addr, peer_addr);

    match local_addr.ip() {
        IpAddr::V4(ipv4) => {
            if ipv4 == Ipv4Addr::LOCALHOST {
                println!("Using localhost interface");
            } else if ipv4.is_private() {
                println!("Using private network interface: {}", ipv4);
            } else {
                println!("Using public interface: {}", ipv4);
            }
        }
        IpAddr::V6(ipv6) => {
            println!("Using IPv6 interface: {}", ipv6);
        }
    }
}
§Load Balancer Detection
use ignitia::server::connection::Connection;
use tokio::net::TcpStream;

let stream = TcpStream::connect("example.com:80").await?;
let connection = Connection::new(stream);

// In a real server environment, you might want to detect
// if connections are coming through a load balancer
if let Ok(local_addr) = connection.local_addr() {
    let port = local_addr.port();

    if port == 80 || port == 443 {
        println!("Direct HTTP/HTTPS connection on port {}", port);
    } else {
        println!("Connection on non-standard port: {}", port);
        // Might indicate load balancer or proxy
    }
}

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> ErasedDestructor for T
where T: 'static,