Files
godoxy-yusing/internal/net
yusing dd33980d18 fix(middleware): allow HTML rewrite for chunked and unknown-length bodies
Relax response-body gating so HTML and XHTML can be buffered when
Transfer-Encoding is chunked-only, or when Content-Length is missing,
while still rejecting non-identity encodings that are not chunked HTML
and other non-HTML cases.

Update modifyHTML to cap reads for unknown length, splice the original
stream back when the cap is hit, and document the behavior in the
package README. Extend tests for themed middleware and the rewrite gate.
2026-04-23 17:23:39 +08:00
..
2025-04-24 15:02:31 +08:00

internal/net

The net package provides network utility functions for GoDoxy, including TCP connection testing and network-related helpers.

Overview

The net package implements network utility functions that are used throughout GoDoxy for connectivity testing, TCP operations, and network-related utilities.

Key Features

  • TCP connection testing (ping)
  • Connection utilities

Core Functions

TCP Ping

// PingTCP pings a TCP endpoint by attempting a connection.
func PingTCP(ctx context.Context, ip net.IP, port int) error

Usage

Basic Usage

import "github.com/yusing/godoxy/internal/net"

func checkService(ctx context.Context, ip string, port int) error {
    addr := net.ParseIP(ip)
    if addr == nil {
        return fmt.Errorf("invalid IP: %s", ip)
    }

    err := net.PingTCP(ctx, addr, port)
    if err != nil {
        return fmt.Errorf("service %s:%d unreachable: %w", ip, port, err)
    }

    fmt.Printf("Service %s:%d is reachable\n", ip, port)
    return nil
}

Timeout Usage

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

ip := net.ParseIP("192.168.1.100")
err := net.PingTCP(ctx, ip, 8080)

if err != nil {
    if errors.Is(err, context.DeadlineExceeded) {
        log.Println("Connection timed out")
    } else {
        log.Printf("Connection failed: %v", err)
    }
}

Implementation

func PingTCP(ctx context.Context, ip net.IP, port int) error {
    var dialer net.Dialer
    conn, err := dialer.DialContext(ctx, "tcp", fmt.Sprintf("%s:%d", ip, port))
    if err != nil {
        return err
    }
    conn.Close()
    return nil
}

Data Flow

sequenceDiagram
    participant Caller
    participant Dialer
    participant TCPEndpoint
    participant Connection

    Caller->>Dialer: DialContext("tcp", "ip:port")
    Dialer->>TCPEndpoint: SYN
    TCPEndpoint-->>Dialer: SYN-ACK
    Dialer->>Connection: Create connection
    Connection-->>Dialer: Connection
    Dialer-->>Caller: nil error

    Note over Caller,Connection: Connection immediately closed
    Connection->>TCPEndpoint: FIN
    TCPEndpoint-->>Connection: FIN-ACK

Use Cases

Service Health Check

func checkServices(ctx context.Context, services []Service) error {
    for _, svc := range services {
        ip := net.ParseIP(svc.IP)
        if ip == nil {
            return fmt.Errorf("invalid IP for %s: %s", svc.Name, svc.IP)
        }

        if err := net.PingTCP(ctx, ip, svc.Port); err != nil {
            return fmt.Errorf("service %s (%s:%d) unreachable: %w",
                svc.Name, svc.IP, svc.Port, err)
        }
    }
    return nil
}

Proxmox Container Reachability

// Check if a Proxmox container is reachable on its proxy port
func checkContainerReachability(ctx context.Context, node *proxmox.Node, vmid int, port int) error {
    ips, err := node.LXCGetIPs(ctx, vmid)
    if err != nil {
        return err
    }

    for _, ip := range ips {
        if err := net.PingTCP(ctx, ip, port); err == nil {
            return nil // Found reachable IP
        }
    }

    return fmt.Errorf("no reachable IP found for container %d", vmid)
}
  • Route: Uses TCP ping for load balancing health checks
  • Proxmox: Uses TCP ping to verify container reachability
  • Idlewatcher: Uses TCP ping to check idle status