### Installation Source: https://github.com/pires/go-proxyproto/blob/main/README.md Command to install the go-proxyproto library. ```shell go get -u github.com/pires/go-proxyproto ``` -------------------------------- ### NewConn Example Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/listener-conn.md Example demonstrating how to create a wrapped connection using NewConn with custom policy and timeout settings. ```go import ( "net" "time" proxyproto "github.com/pires/go-proxyproto" ) listener, _ := net.Listen("tcp", "127.0.0.1:9876") baseConn, _ := listener.Accept() // Create a wrapped connection with specific policy and timeout pConn := proxyproto.NewConn( baseConn, proxyproto.WithPolicy(proxyproto.USE), proxyproto.SetReadHeaderTimeout(5*time.Second), ) deffer pConn.Close() // Read data - header is processed transparently on first read buf := make([]byte, 1024) n, _ := pConn.Read(buf) ``` -------------------------------- ### Listener.Accept Example Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/listener-conn.md Example demonstrating how to use Listener.Accept to accept connections and access original client addresses via PROXY protocol headers. ```go import ( "net" proxyproto "github.com/pires/go-proxyproto" ) listener, _ := net.Listen("tcp", "127.0.0.1:9876") proxyListener := &proxyproto.Listener{ Listener: listener, } deffer proxyListener.Close() for { conn, err := proxyListener.Accept() if err != nil { panic(err) } defer conn.Close() // RemoteAddr() returns the original client address from PROXY header if present println("Client:", conn.RemoteAddr().String()) } ``` -------------------------------- ### Conn.ProxyHeader Example Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/listener-conn.md Example demonstrating how to retrieve and use the parsed PROXY header after a read operation. ```go conn, _ := proxyproto.NewConn( baseConn, proxyproto.WithPolicy(proxyproto.USE), ) // Make a read to trigger header processing buf := make([]byte, 1) conn.Read(buf) if header := conn.ProxyHeader(); header != nil { println("PROXY header found, version:", header.Version) println("Client:", header.SourceAddr.String()) } ``` -------------------------------- ### Connection WithPolicy Option Example Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/configuration.md Example of using the WithPolicy option with NewConn. ```go import ( "net" proxyproto "github.com/pires/go-proxyproto" ) conn, _ := net.Dial("tcp", "localhost:9876") pConn := proxyproto.NewConn( conn, proxyproto.WithPolicy(proxyproto.REQUIRE), // Require PROXY header ) ``` -------------------------------- ### SetTLVs Example Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/header.md Example of setting TLVs in a proxy protocol header. ```go header := &proxyproto.Header{ Version: 2, Command: proxyproto.PROXY, TransportProtocol: proxyproto.TCPv4, SourceAddr: &net.TCPAddr{ IP: net.ParseIP("10.1.1.1"), Port: 1000, }, DestinationAddr: &net.TCPAddr{ IP: net.ParseIP("20.2.2.2"), Port: 2000, }, } tlv := proxyproto.TLV{ Type: proxyproto.PP2_TYPE_ALPN, Value: []byte("h2"), } err := header.SetTLVs([]proxyproto.TLV{tlv}) if err != nil { panic(err) } ``` -------------------------------- ### NewServer Example Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/http2-helper.md Creates a new HTTP/1 and HTTP/2 server and serves connections from a TLS listener. ```go import ( "crypto/tls" "net" "net/http" "golang.org/x/net/http2" "github.com/pires/go-proxyproto/helper/http2" ) h1 := &http.Server{ Addr: ":8080", Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Hello")) }), } h2Srv := &http2.Server{} srv := http2.NewServer(h1, h2Srv) // Create TLS listener for HTTPS/2 cert, _ := tls.LoadX509KeyPair("cert.pem", "key.pem") tlsConfig := &tls.Config{ Certificates: []tls.Certificate{cert}, } ln, _ := tls.Listen("tcp", ":8080", tlsConfig) err := srv.Serve(ln) if err != nil && err != http.ErrServerClosed { panic(err) } ``` -------------------------------- ### Example with PROXY + ALPN TLV Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/http2-helper.md Demonstrates creating a PROXY protocol header with an ALPN TLV for routing. ```go import ( "bufio" "net" proxyproto "github.com/pires/go-proxyproto" ) // Create header with ALPN TLV header := &proxyproto.Header{ Version: 2, Command: proxyproto.PROXY, TransportProtocol: proxyproto.TCPv4, SourceAddr: &net.TCPAddr{IP: net.ParseIP("10.1.1.1"), Port: 1000}, DestinationAddr: &net.TCPAddr{IP: net.ParseIP("20.2.2.2"), Port: 2000}, } tlv := proxyproto.TLV{ Type: proxyproto.PP2_TYPE_ALPN, Value: []byte("h2"), } header.SetTLVs([]proxyproto.TLV{tlv}) // Send to server buf, _ := header.Format() // Send buf + HTTP/2 connection data ``` -------------------------------- ### Server Usage Source: https://github.com/pires/go-proxyproto/blob/main/README.md Example of how to use the go-proxyproto library as a server to accept PROXY protocol headers. ```go package main import ( "log" "net" proxyproto "github.com/pires/go-proxyproto" ) func main() { // Create a listener addr := "localhost:9876" list, err := net.Listen("tcp", addr) if err != nil { log.Fatalf("couldn't listen to %q: %q\n", addr, err.Error()) } // Wrap listener in a proxyproto listener proxyListener := &proxyproto.Listener{Listener: list} defer proxyListener.Close() // Wait for a connection and accept it conn, err := proxyListener.Accept() defer conn.Close() // Print connection details if conn.LocalAddr() == nil { log.Fatal("couldn't retrieve local address") } log.Printf("local address: %q", conn.LocalAddr().String()) if conn.RemoteAddr() == nil { log.Fatal("couldn't retrieve remote address") } log.Printf("remote address: %q", conn.RemoteAddr().String()) } ``` -------------------------------- ### HTTP/1 and HTTP/2 Coexistence Example Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/http2-helper.md Shows how to configure the server to handle both HTTP/1.1 and HTTP/2 connections on the same TCP listener using the http2helper. ```go import ( "net" "net/http" "golang.org/x/net/http2" http2helper "github.com/pires/go-proxyproto/helper/http2" ) h1 := &http.Server{ Addr: ":8080", Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { proto := r.Proto w.Write([]byte("Protocol: " + proto)) }), } h2 := &http2.Server{} srv := http2helper.NewServer(h1, h2) // Both HTTP/1.1 and HTTP/2 clients can connect to the same address ln, _ := net.Listen("tcp", ":8080") srv.Serve(ln) ``` -------------------------------- ### Listener Integration Example Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/http2-helper.md Demonstrates how to integrate the proxyproto.Listener with the http2helper.NewServer to handle proxy protocol and serve HTTP requests. ```go import ( "net" "net/http" "time" proxyproto "github.com/pires/go-proxyproto" http2helper "github.com/pires/go-proxyproto/helper/http2" ) h1 := &http.Server{ Addr: ":9000", Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { println("Client IP:", r.Header.Get("X-Forwarded-For")) w.Write([]byte("OK")) }), } srv := http2helper.NewServer(h1, nil) ln, _ := net.Listen("tcp", ":9000") proxyLn := &proxyproto.Listener{ Listener: ln, ReadHeaderTimeout: 10 * time.Second, } if err := srv.Serve(proxyLn); err != nil && err != http.ErrServerClosed { panic(err) } ``` -------------------------------- ### Example Usage of ExtractPSCConnectionID Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/tlvparse.md Example of how to use ExtractPSCConnectionID to find the PSC Connection ID. ```go import ( "github.com/pires/go-proxyproto" "github.com/pires/go-proxyproto/tlvparse" ) header, _ := proxyproto.Read(reader) tlvs, _ := header.TLVs() if pscID, found := tlvparse.ExtractPSCConnectionID(tlvs); found { println("PSC Connection ID:", pscID) } ``` -------------------------------- ### Client Usage Source: https://github.com/pires/go-proxyproto/blob/main/README.md Example of how to use the go-proxyproto library as a client to send PROXY protocol headers. ```go package main import ( "io" "log" "net" proxyproto "github.com/pires/go-proxyproto" ) func chkErr(err error) { if err != nil { log.Fatalf("Error: %s", err.Error()) } } func main() { // Dial some proxy listener e.g. https://github.com/mailgun/proxyproto target, err := net.ResolveTCPAddr("tcp", "127.0.0.1:2319") chkErr(err) conn, err := net.DialTCP("tcp", nil, target) chkErr(err) defer conn.Close() // Create a proxyprotocol header or use HeaderProxyFromAddrs() if you // have two conn's header := &proxyproto.Header{ Version: 1, Command: proxyproto.PROXY, TransportProtocol: proxyproto.TCPv4, SourceAddr: &net.TCPAddr{ IP: net.ParseIP("10.1.1.1"), Port: 1000, }, DestinationAddr: &net.TCPAddr{ IP: net.ParseIP("20.2.2.2"), Port: 2000, }, } // After the connection was created write the proxy headers first _, err = header.WriteTo(conn) chkErr(err) // Then your data... e.g.: _, err = io.WriteString(conn, "HELO") chkErr(err) } ``` -------------------------------- ### Listener ReadBufferSize Configuration Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/configuration.md Example of configuring the ReadBufferSize for a proxyproto Listener. ```go listener, _ := net.Listen("tcp", ":9876") proxyListener := &proxyproto.Listener{ Listener: listener, ReadBufferSize: 512, // Larger buffer if TLVs are large } ``` -------------------------------- ### Server.Serve Example with PROXY Protocol Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/http2-helper.md Serves incoming connections from a PROXY protocol listener, handling both HTTP/1 and HTTP/2 transparently. ```go import ( "crypto/tls" "net" "net/http" "golang.org/x/net/http2" proxyproto "github.com/pires/go-proxyproto" http2helper "github.com/pires/go-proxyproto/helper/http2" ) h1 := &http.Server{ Addr: ":8080", Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Hello")) }), } srv := http2helper.NewServer(h1, nil) // Create PROXY protocol listener baseLn, _ := net.Listen("tcp", ":8080") proxyLn := &proxyproto.Listener{ Listener: baseLn, } err := srv.Serve(proxyLn) if err != nil && err != http.ErrServerClosed { panic(err) } ``` -------------------------------- ### ConnStrictWhiteListPolicy Example Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/policy.md Example of creating and using ConnStrictWhiteListPolicy to allow specific IPs/CIDRs and reject others. ```go import ( "net" proxyproto "github.com/pires/go-proxyproto" ) policy, err := proxyproto.ConnStrictWhiteListPolicy([]string{ "10.1.1.1", "10.0.0.0/8", }) if err != nil { panic(err) } listener, _ := net.Listen("tcp", "127.0.0.1:9876") proxyListener := &proxyproto.Listener{ Listener: listener, ConnPolicy: policy, } ``` -------------------------------- ### Scenario 1: Trusted Proxy (Simple) Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/configuration.md Example configuration for a listener that trusts connections from a specific CIDR range. ```go listener, _ := net.Listen("tcp", ":9876") proxyListener := &proxyproto.Listener{ Listener: listener, ConnPolicy: proxyproto.ConnMustLaxWhiteListPolicy([]string{ "10.0.0.0/8", }), } ``` -------------------------------- ### HTTP/2 Server Configuration Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/configuration.md Example of configuring an http.Server and http2.Server for use with the go-proxyproto helper. ```go import ( "net/http" "golang.org/x/net/http2" http2helper "github.com/pires/go-proxyproto/helper/http2" ) h1 := &http.Server{ Addr: ":8080", Handler: myHandler, // Standard http.Server options ReadTimeout: 15 * time.Second, WriteTimeout: 15 * time.Second, IdleTimeout: 60 * time.Second, // Error logging ErrorLog: myLogger, // Connection context (called for each connection) ConnContext: func(ctx context.Context, c net.Conn) context.Context { // Custom per-connection setup return ctx }, } h2 := &http2.Server{ // HTTP/2 specific settings MaxConcurrentStreams: 100, } srv := http2helper.NewServer(h1, h2) ``` -------------------------------- ### HTTP Server Usage Source: https://github.com/pires/go-proxyproto/blob/main/README.md Example of integrating go-proxyproto with an HTTP server. ```go package main import ( "net" "net/http" "time" "github.com/pires/go-proxyproto" ) func main() { server := http.Server{ Addr: ":8080", } ln, err := net.Listen("tcp", server.Addr) if err != nil { panic(err) } proxyListener := &proxyproto.Listener{ Listener: ln, ReadHeaderTimeout: 10 * time.Second, } defer proxyListener.Close() server.Serve(proxyListener) } ``` -------------------------------- ### ErrUnsupportedProtocolVersionAndCommand Example Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/errors.md Definition of ErrUnsupportedProtocolVersionAndCommand. ```go var ErrUnsupportedProtocolVersionAndCommand = errors.New("proxyproto: unsupported proxy protocol version and command") ``` -------------------------------- ### JoinTLVs Example Usage Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/tlv.md Demonstrates creating TLVs and joining them into a raw byte slice, then setting them on a header. ```go import ( proxyproto "github.com/pires/go-proxyproto" ) tlvs := []proxyproto.TLV{ { Type: proxyproto.PP2_TYPE_ALPN, Value: []byte("h2"), }, } raw, err := proxyproto.JoinTLVs(tlvs) if err != nil { panic(err) } header := &proxyproto.Header{ Version: 2, Command: proxyproto.PROXY, TransportProtocol: proxyproto.TCPv4, SourceAddr: &net.TCPAddr{IP: net.ParseIP("10.1.1.1"), Port: 1000}, DestinationAddr: &net.TCPAddr{IP: net.ParseIP("20.2.2.2"), Port: 2000}, } header.SetTLVs(tlvs) ``` -------------------------------- ### Example Usage of FindAzurePrivateEndpointLinkID Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/tlvparse.md Example of how to use FindAzurePrivateEndpointLinkID to find the Private Endpoint LinkID. ```go import ( "github.com/pires/go-proxyproto" "github.com/pires/go-proxyproto/tlvparse" ) header, _ := proxyproto.Read(reader) tlvs, _ := header.TLVs() if linkID, found := tlvparse.FindAzurePrivateEndpointLinkID(tlvs); found { println("Azure Private Endpoint LinkID:", linkID) } ``` -------------------------------- ### Example Usage of AWSVPCEndpointID Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/tlvparse.md Example of how to use AWSVPCEndpointID to extract the VPC Endpoint ID. ```go import ( "github.com/pires/go-proxyproto" "github.com/pires/go-proxyproto/tlvparse" ) header, _ := proxyproto.Read(reader) tlvs, _ := header.TLVs() for _, tlv := range tlvs { if vpceID, err := tlvparse.AWSVPCEndpointID(tlv); err == nil { println("VPC Endpoint ID:", vpceID) } } ``` -------------------------------- ### Basic Client Usage Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/README.md Example of creating and sending a PROXY header using the go-proxyproto library. ```go import ( "net" proxyproto "github.com/pires/go-proxyproto" ) // Create and send PROXY header header := &proxyproto.Header{ Version: 2, Command: proxyproto.PROXY, TransportProtocol: proxyproto.TCPv4, SourceAddr: &net.TCPAddr{IP: net.ParseIP("10.1.1.1"), Port: 1000}, DestinationAddr: &net.TCPAddr{IP: net.ParseIP("20.2.2.2"), Port: 2000}, } conn, _ := net.DialTCP("tcp", nil, &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 2319}) header.WriteTo(conn) ``` -------------------------------- ### SplitTLVs Example Usage Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/tlv.md Demonstrates how to read a PROXY protocol header and extract TLVs using SplitTLVs. ```go import ( proxyproto "github.com/pires/go-proxyproto" ) header, _ := proxyproto.Read(reader) tlvs, err := header.TLVs() if err != nil { panic(err) } for _, tlv := range tlvs { println("Type:", tlv.Type, "Length:", len(tlv.Value)) } ``` -------------------------------- ### Simple Server with Default Settings Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/README.md A basic server setup using default PROXY protocol listener settings. ```go listener, _ := net.Listen("tcp", ":9876") proxyListener := &proxyproto.Listener{Listener: listener} // RemoteAddr() returns original client address conn, _ := proxyListener.Accept() log.Print(conn.RemoteAddr()) ``` -------------------------------- ### ErrCantResolveSourceUnixAddress Example Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/errors.md Definition of ErrCantResolveSourceUnixAddress. ```go var ErrCantResolveSourceUnixAddress = errors.New("proxyproto: can't resolve source Unix address") ``` -------------------------------- ### HTTP Server with PROXY Support Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/README.md Example of setting up an HTTP server that supports the PROXY protocol. ```go import ( "net" "net/http" proxyproto "github.com/pires/go-proxyproto" ) listener, _ := net.Listen("tcp", ":8080") proxyListener := &proxyproto.Listener{Listener: listener} http.ListenAndServe("", &http.Server{ Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Client: " + r.RemoteAddr)) }), }) ``` -------------------------------- ### Listener ConnPolicy Configuration Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/configuration.md Example of configuring the ConnPolicy function for a proxyproto Listener. ```go import ( "net" proxyproto "github.com/pires/go-proxyproto" ) listener, _ := net.Listen("tcp", ":9876") proxyListener := &proxyproto.Listener{ Listener: listener, ConnPolicy: func(opts proxyproto.ConnPolicyOptions) (proxyproto.Policy, error) { // Allow PROXY headers only from localhost if opts.Upstream.String() == "127.0.0.1:12345" { return proxyproto.USE, nil } return proxyproto.IGNORE, nil }, } ``` -------------------------------- ### ErrUnsupportedAddressFamilyAndProtocol Example Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/errors.md Definition of ErrUnsupportedAddressFamilyAndProtocol. ```go var ErrUnsupportedAddressFamilyAndProtocol = errors.New("proxyproto: unsupported address family and protocol") ``` -------------------------------- ### ConnLaxWhiteListPolicy Example Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/policy.md Example of creating and using ConnLaxWhiteListPolicy to allow specific IPs/CIDRs to send PROXY headers. ```go import ( "net" proxyproto "github.com/pires/go-proxyproto" ) policy, err := proxyproto.ConnLaxWhiteListPolicy([]string{ "10.1.1.1", "10.0.0.0/8", "192.168.0.0/16", }) if err != nil { panic(err) } listener, _ := net.Listen("tcp", "127.0.0.1:9876") proxyListener := &proxyproto.Listener{ Listener: listener, ConnPolicy: policy, } ``` -------------------------------- ### Scenario 2: Local Development (No Proxy) Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/configuration.md Example configuration for a listener that skips PROXY header processing for local connections (e.g., localhost). ```go listener, _ := net.Listen("tcp", ":9876") proxyListener := &proxyproto.Listener{ Listener: listener, ConnPolicy: proxyproto.ConnSkipProxyHeaderForCIDR( net.ParseCIDR("127.0.0.0/8")[1], proxyproto.USE, ), } ``` -------------------------------- ### IgnoreProxyHeaderNotOnInterface Example Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/policy.md Example of using IgnoreProxyHeaderNotOnInterface to control PROXY header usage based on the connection interface. ```go import ( "net" proxyproto "github.com/pires/go-proxyproto" ) policy := proxyproto.IgnoreProxyHeaderNotOnInterface(net.ParseIP("10.0.0.1")) listener, _ := net.Listen("tcp", "0.0.0.0:9876") proxyListener := &proxyproto.Listener{ Listener: listener, ConnPolicy: policy, } ``` -------------------------------- ### ConnSkipProxyHeaderForCIDR Example Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/policy.md Example of using ConnSkipProxyHeaderForCIDR to skip PROXY header requirement for a specific CIDR. ```go import ( "net" proxyproto "github.com/pires/go-proxyproto" ) _, localNet, _ := net.ParseCIDR("127.0.0.0/8") policy := proxyproto.ConnSkipProxyHeaderForCIDR(localNet, proxyproto.REQUIRE) listener, _ := net.Listen("tcp", "127.0.0.1:9876") proxyListener := &proxyproto.Listener{ Listener: listener, ConnPolicy: policy, } ``` -------------------------------- ### Scenario 3: Strict Security Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/configuration.md Example configuration for a listener with strict security settings, including a custom header validation and a strict whitelist policy. ```go listener, _ := net.Listen("tcp", ":9876") proxyListener := &proxyproto.Listener{ Listener: listener, ReadHeaderTimeout: 5 * time.Second, ConnPolicy: proxyproto.ConnMustStrictWhiteListPolicy([]string{ "10.0.0.1", "10.0.0.2", }), ValidateHeader: func(h *proxyproto.Header) error { // Custom validation if h.Version != 2 { return errors.New("v2 required") } return nil }, } ``` -------------------------------- ### Handling Incompatible TLV Type Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/errors.md Example demonstrating how to handle ErrIncompatibleTLV when parsing TLVs. ```go import ( proxyproto "github.com/pires/go-proxyproto" "github.com/pires/go-proxyproto/tlvparse" ) header, _ := proxyproto.Read(reader) tlvs, _ := header.TLVs() for _, tlv := range tlvs { if ssl, err := tlvparse.SSL(tlv); err == nil { println("SSL TLV found") } else if err == proxyproto.ErrIncompatibleTLV { println("Not an SSL TLV") } } ``` -------------------------------- ### Basic Server Usage Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/README.md Example of using the go-proxyproto library on the server-side to accept connections and retrieve the original client address. ```go import ( "net" proxyproto "github.com/pires/go-proxyproto" ) listener, _ := net.Listen("tcp", ":9876") proxyListener := &proxyproto.Listener{Listener: listener} defer proxyListener.Close() conn, _ := proxyListener.Accept() defer conn.Close() // conn.RemoteAddr() returns original client address from PROXY header println("Client:", conn.RemoteAddr().String()) ``` -------------------------------- ### ErrCantResolveDestinationUnixAddress Example Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/errors.md Definition of ErrCantResolveDestinationUnixAddress. ```go var ErrCantResolveDestinationUnixAddress = errors.New("proxyproto: can't resolve destination Unix address") ``` -------------------------------- ### Listener ReadHeaderTimeout Configuration Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/configuration.md Example of configuring the ReadHeaderTimeout for a proxyproto Listener. ```go import ( "net" "time" proxyproto "github.com/pires/go-proxyproto" ) listener, _ := net.Listen("tcp", ":9876") proxyListener := &proxyproto.Listener{ Listener: listener, ReadHeaderTimeout: 5 * time.Second, // 5 second timeout } ``` -------------------------------- ### Handling ErrSuperfluousProxyHeader Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/errors.md Example of how to handle the ErrSuperfluousProxyHeader error. ```go import ( "net" proxyproto "github.com/pires/go-proxyproto" ) conn, _ := net.Dial("tcp", "localhost:9876") pConn := proxyproto.NewConn( conn, proxyproto.WithPolicy(proxyproto.REJECT), ) buf := make([]byte, 1) _, err := pConn.Read(buf) if err == proxyproto.ErrSuperfluousProxyHeader { println("PROXY header not allowed") } ``` -------------------------------- ### Listener ValidateHeader Configuration Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/configuration.md Example of configuring the ValidateHeader function for a proxyproto Listener. ```go import ( "errors" "net" proxyproto "github.com/pires/go-proxyproto" ) validator := func(h *proxyproto.Header) error { // Only allow TCP headers if !h.TransportProtocol.IsStream() { return errors.New("only TCP allowed") } // Only allow specific source IPs srcIP, _, ok := h.IPs() if ok && !srcIP.IsPrivate() { return errors.New("public IPs not allowed") } return nil } listener, _ := net.Listen("tcp", ":9876") proxyListener := &proxyproto.Listener{ Listener: listener, ValidateHeader: validator, } ``` -------------------------------- ### ErrSuperfluousProxyHeader Example Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/errors.md Definition of ErrSuperfluousProxyHeader. ```go var ErrSuperfluousProxyHeader = errors.New("proxyproto: upstream connection sent PROXY header but isn't allowed to send one") ``` -------------------------------- ### Listener Policy Configuration (Deprecated) Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/configuration.md Example of configuring the deprecated Policy function for a proxyproto Listener. ```go import ( "net" proxyproto "github.com/pires/go-proxyproto" ) oldPolicy := func(upstream net.Addr) (proxyproto.Policy, error) { // Check IP return proxyproto.USE, nil } listener, _ := net.Listen("tcp", ":9876") proxyListener := &proxyproto.Listener{ Listener: listener, Policy: oldPolicy, // Deprecated - use ConnPolicy } ``` -------------------------------- ### Reading Headers Directly Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/README.md Example of reading PROXY protocol headers directly from a connection's reader. ```go reader := bufio.NewReader(conn) header, err := proxyproto.Read(reader) if err == proxyproto.ErrNoProxyProtocol { // No header, handle as regular connection } else if err != nil { // Parse error } else { // Header available log.Print(header.SourceAddr) } ``` -------------------------------- ### TLV Extraction Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/README.md Example of how to read and extract Type-Length-Value (TLV) data from a PROXY protocol header. ```go header, _ := proxyproto.Read(reader) tlvs, _ := header.TLVs() for _, tlv := range tlvs { switch tlv.Type { case proxyproto.PP2_TYPE_ALPN: protocol := string(tlv.Value) log.Print("Protocol:", protocol) case proxyproto.PP2_TYPE_SSL: ssl, _ := tlvparse.SSL(tlv) if ssl.Verified() { log.Print("Client certificate verified") } } } ``` -------------------------------- ### ErrInvalidLength Example Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/errors.md Definition of ErrInvalidLength. ```go var ErrInvalidLength = errors.New("proxyproto: invalid length") ``` -------------------------------- ### ErrInvalidPortNumber Example Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/errors.md Definition of ErrInvalidPortNumber. ```go var ErrInvalidPortNumber = errors.New("proxyproto: invalid port number") ``` -------------------------------- ### ErrInvalidAddress Example Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/errors.md Definition of ErrInvalidAddress. ```go var ErrInvalidAddress = errors.New("proxyproto: invalid address") ``` -------------------------------- ### Conn.Write Method Signature Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/listener-conn.md Writes data to the connection. ```go func (p *Conn) Write(b []byte) (int, error) ``` -------------------------------- ### HTTP/2 with Proxy Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/configuration.md This code snippet demonstrates how to use go-proxyproto with HTTP/2. ```go h1 := &http.Server{ Addr: ":8080", Handler: myHandler, } srv := http2helper.NewServer(h1, nil) ln, _ := net.Listen("tcp", ":8080") proxyLn := &proxyproto.Listener{ Listener: ln, ReadHeaderTimeout: 10 * time.Second, } srv.Serve(proxyLn) ``` -------------------------------- ### Conn.ReadFrom Method Signature Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/listener-conn.md Implements io.ReaderFrom interface for efficient copying from a reader to the connection. ```go func (p *Conn) ReadFrom(r io.Reader) (int64, error) ``` -------------------------------- ### Conn.WriteTo Method Signature Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/listener-conn.md Implements io.WriterTo interface for efficient copying from the connection to a writer. ```go func (p *Conn) WriteTo(w io.Writer) (int64, error) ``` -------------------------------- ### Listener.Accept Method Signature Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/listener-conn.md The Accept method waits for and returns the next valid connection to the listener, wrapping it for PROXY protocol handling. ```go func (p *Listener) Accept() (net.Conn, error) ``` -------------------------------- ### Format Method Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/header.md Renders a proxy protocol header in wire format. ```go func (header *Header) Format() ([]byte, error) ``` ```go import ( "net" proxyproto "github.com/pires/go-proxyproto" ) header := &proxyproto.Header{ Version: 2, Command: proxyproto.PROXY, TransportProtocol: proxyproto.TCPv4, SourceAddr: &net.TCPAddr{ IP: net.ParseIP("10.1.1.1"), Port: 1000, }, DestinationAddr: &net.TCPAddr{ IP: net.ParseIP("20.2.2.2"), Port: 2000, }, } buf, err := header.Format() if err != nil { panic(err) } // buf now contains the binary representation of the PROXY protocol header ``` -------------------------------- ### Conn.UDPConn Method Signature Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/listener-conn.md Returns the underlying UDP connection if the connection is UDP-based. ```go func (p *Conn) UDPConn() (conn *net.UDPConn, ok bool) ``` -------------------------------- ### PP2SSL.ClientCert Method Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/tlvparse.md Returns the raw X.509 client certificate in ASN.1 DER format and whether it exists. ```go func (s PP2SSL) ClientCert() ([]byte, bool) ``` -------------------------------- ### Conn.Raw Method Signature Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/listener-conn.md Returns the underlying net.Conn. Use only when you need access to connection-specific methods not exposed by the wrapper. ```go func (p *Conn) Raw() net.Conn ``` -------------------------------- ### Conn.UnixConn Method Signature Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/listener-conn.md Returns the underlying Unix socket connection if the connection is Unix-based. ```go func (p *Conn) UnixConn() (conn *net.UnixConn, ok bool) ``` -------------------------------- ### Conn.SetReadDeadline Method Signature Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/listener-conn.md Sets the read deadline on the connection. ```go func (p *Conn) SetReadDeadline(t time.Time) error ``` -------------------------------- ### WithBufferSize Option Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/configuration.md Sets a custom read buffer size for header detection. This allows tuning the buffer used specifically for reading the PROXY protocol header. ```go import ( "net" proxyproto "github.com/pires/go-proxyproto" ) conn, _ := net.Dial("tcp", "localhost:9876") pConn := proxyproto.NewConn( conn, proxyproto.WithBufferSize(512), ) ``` -------------------------------- ### Custom Policy Returning ErrInvalidUpstream Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/errors.md Example of a custom policy function returning ErrInvalidUpstream if the upstream address is not trusted. ```go import ( "net" proxyproto "github.com/pires/go-proxyproto" ) customPolicy := func(opts proxyproto.ConnPolicyOptions) (proxyproto.Policy, error) { // Check if upstream is trusted if !isTrustedSource(opts.Upstream) { return proxyproto.REJECT, proxyproto.ErrInvalidUpstream } return proxyproto.USE, nil } ``` -------------------------------- ### NewConn Function Signature Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/listener-conn.md Creates a new connection wrapper that may be speaking the PROXY protocol, with options for configuration. ```go func NewConn(conn net.Conn, opts ...func(*Conn)) *Conn ``` -------------------------------- ### Conn.SetDeadline Method Signature Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/listener-conn.md Sets the read and write deadline on the connection. ```go func (p *Conn) SetDeadline(t time.Time) error ``` -------------------------------- ### Conn.SetWriteDeadline Method Signature Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/listener-conn.md Sets the write deadline on the connection. ```go func (p *Conn) SetWriteDeadline(t time.Time) error ``` -------------------------------- ### Build-time Override for DefaultReadHeaderTimeout Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/configuration.md Allows overriding the DefaultReadHeaderTimeout at build time using ldflags. ```bash go build -ldflags "-X github.com/pires/go-proxyproto.DefaultReadHeaderTimeout=30s" . ``` -------------------------------- ### Listener.Addr Method Signature Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/listener-conn.md The Addr method returns the address of the underlying listener. ```go func (p *Listener) Addr() net.Addr ``` -------------------------------- ### PP2SSL.Verified Method Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/tlvparse.md Returns true if the client certificate was presented and successfully verified. ```go func (s PP2SSL) Verified() bool ``` -------------------------------- ### Conn.TCPConn Method Signature Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/listener-conn.md Returns the underlying TCP connection if the connection is TCP-based. ```go func (p *Conn) TCPConn() (conn *net.TCPConn, ok bool) ``` -------------------------------- ### Conn.Close Method Signature Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/listener-conn.md Closes the underlying connection. ```go func (p *Conn) Close() error ``` -------------------------------- ### Ports Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/header.md Returns source and destination ports for TCP/UDP headers. ```go func (header *Header) Ports() (sourcePort, destPort int, ok bool) ``` ```go header := &proxyproto.Header{ TransportProtocol: proxyproto.TCPv4, SourceAddr: &net.TCPAddr{ IP: net.ParseIP("10.1.1.1"), Port: 1000, }, DestinationAddr: &net.TCPAddr{ IP: net.ParseIP("20.2.2.2"), Port: 2000, }, } srcPort, dstPort, ok := header.Ports() if ok { println("Source port:", srcPort) println("Dest port:", dstPort) } ``` -------------------------------- ### Experiment Method Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/tlv.md Checks if a PP2Type is reserved for temporary experimental use. ```go func (p PP2Type) Experiment() bool ``` -------------------------------- ### PP2SSL.ClientCertConn Method Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/tlvparse.md Returns true if the client provided a certificate on the current connection. ```go func (s PP2SSL) ClientCertConn() bool ``` -------------------------------- ### WriteTo Method Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/header.md Renders a proxy protocol header and writes it to an io.Writer. ```go func (header *Header) WriteTo(w io.Writer) (int64, error) ``` ```go import ( "net" proxyproto "github.com/pires/go-proxyproto" ) conn, _ := net.DialTCP("tcp", nil, &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 2319}) deferr conn.Close() header := &proxyproto.Header{ Version: 1, Command: proxyproto.PROXY, TransportProtocol: proxyproto.TCPv4, SourceAddr: &net.TCPAddr{ IP: net.ParseIP("10.1.1.1"), Port: 1000, }, DestinationAddr: &net.TCPAddr{ IP: net.ParseIP("20.2.2.2"), Port: 2000, }, } n, err := header.WriteTo(conn) if err != nil { panic(err) } ``` -------------------------------- ### Conn.ProxyHeader Method Signature Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/listener-conn.md Returns the parsed PROXY protocol header, if one was present and successfully parsed. ```go func (p *Conn) ProxyHeader() *Header ``` -------------------------------- ### EqualsTo Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/header.md Checks if two headers are equivalent. ```go func (header *Header) EqualsTo(otherHeader *Header) bool ``` ```go header1 := &proxyproto.Header{ Version: 1, Command: proxyproto.PROXY, TransportProtocol: proxyproto.TCPv4, SourceAddr: &net.TCPAddr{ IP: net.ParseIP("10.1.1.1"), Port: 1000, }, DestinationAddr: &net.TCPAddr{ IP: net.ParseIP("20.2.2.2"), Port: 2000, }, } header2 := header1 if header1.EqualsTo(header2) { println("Headers are equal") } ``` -------------------------------- ### Conn.LocalAddr Method Signature Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/listener-conn.md Returns the server address. If a PROXY header is present, returns the destination address from the header; otherwise returns the local address of the underlying connection. ```go func (p *Conn) LocalAddr() net.Addr ``` -------------------------------- ### Azure TLV Constants Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/tlvparse.md Constants for Azure TLV types and subtypes. ```go const ( PP2_TYPE_AZURE = 0xEE // Azure TLV extension type PP2_SUBTYPE_AZURE_PRIVATEENDPOINT_LINKID = 0x01 // Private Endpoint LinkID subtype ) ``` -------------------------------- ### Bitfield Constants Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/tlvparse.md Constants for SSL flags in the PP2SSL struct. ```go const ( PP2_BITFIELD_CLIENT_SSL uint8 = 0x01 // Client used SSL/TLS PP2_BITFIELD_CLIENT_CERT_CONN uint8 = 0x02 // Client cert on this connection PP2_BITFIELD_CLIENT_CERT_SESS uint8 = 0x04 // Client cert in session ) ``` -------------------------------- ### Strict Whitelist Policy Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/README.md Configuring a listener with a strict whitelist policy to only accept connections from specified IP ranges. ```go policy, _ := proxyproto.ConnStrictWhiteListPolicy([]string{"10.0.0.0/8"}) proxyListener := &proxyproto.Listener{ Listener: listener, ConnPolicy: policy, } ``` -------------------------------- ### App Method Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/tlv.md Checks if a PP2Type is reserved for application-specific data. ```go func (p PP2Type) App() bool ``` -------------------------------- ### SSL Function Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/tlvparse.md Parses a TLV as an SSL TLV. ```go func SSL(t proxyproto.TLV) (PP2SSL, error) ``` ```go import ( "github.com/pires/go-proxyproto" "github.com/pires/go-proxyproto/tlvparse" ) header, _ := proxyproto.Read(reader) tlVs, _ := header.TLVs() for _, tlv := range tlVs { if ssl, err := tlvparse.SSL(tlv); err == nil { if ssl.Verified() { println("Client certificate verified") } } } ``` -------------------------------- ### Conn.Read Method Signature Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/listener-conn.md Reads data from the connection, handling PROXY header processing transparently. On first call, it processes the PROXY header if present. Subsequent calls read directly from the underlying connection. If header processing fails with a policy-related error, it returns the error. ```go func (p *Conn) Read(b []byte) (int, error) ``` -------------------------------- ### PP2SSL.Marshal Method Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/tlvparse.md Formats the PP2SSL structure as a TLV for setting in a header. ```go func (s PP2SSL) Marshal() (proxyproto.TLV, error) ``` ```go import ( "github.com/pires/go-proxyproto/tlvparse" ) ssl := tlvparse.PP2SSL{ Client: tlvparse.PP2_BITFIELD_CLIENT_SSL, Verify: 0, } tlV, err := ssl.Marshal() if err != nil { panic(err) } ``` -------------------------------- ### IPs Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/header.md Returns source and destination IP addresses for TCP/UDP headers. ```go func (header *Header) IPs() (sourceIP, destIP net.IP, ok bool) ``` ```go header := &proxyproto.Header{ TransportProtocol: proxyproto.TCPv4, SourceAddr: &net.TCPAddr{ IP: net.ParseIP("10.1.1.1"), Port: 1000, }, DestinationAddr: &net.TCPAddr{ IP: net.ParseIP("20.2.2.2"), Port: 2000, }, } srcIP, dstIP, ok := header.IPs() if ok { println("Source IP:", srcIP.String()) println("Dest IP:", dstIP.String()) } ``` -------------------------------- ### Listener.Close Method Signature Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/listener-conn.md The Close method closes the underlying listener. ```go func (p *Listener) Close() error ``` -------------------------------- ### Listener Struct Definition Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/listener-conn.md Defines the structure of the Listener, which wraps a standard net.Listener to handle PROXY protocol headers. ```go type Listener struct { Listener net.Listener Policy PolicyFunc // Deprecated: use ConnPolicy ConnPolicy ConnPolicyFunc ValidateHeader Validator ReadHeaderTimeout time.Duration ReadBufferSize int } ``` -------------------------------- ### UnixAddrs Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/header.md Returns UNIX socket source and destination addresses if the header is UNIX-based. ```go func (header *Header) UnixAddrs() (sourceAddr, destAddr *net.UnixAddr, ok bool) ``` -------------------------------- ### PP2SSL.ClientSSL Method Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/tlvparse.md Returns true if the client connected over SSL/TLS. ```go func (s PP2SSL) ClientSSL() bool ``` -------------------------------- ### Conn.RemoteAddr Method Signature Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/listener-conn.md Returns the client address. If a PROXY header is present, returns the source address from the header; otherwise returns the remote address of the underlying connection. ```go func (p *Conn) RemoteAddr() net.Addr ``` -------------------------------- ### SIGV1 Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/protocol-io.md Byte signature for PROXY protocol version 1. ```go var SIGV1 = []byte{'"P"', '"R"', '"O"', '"X"', '"Y"'} ``` -------------------------------- ### PP2SSL.SSLVersion Method Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/tlvparse.md Returns the TLS version string (e.g., "TLSv1.3") and whether it exists in the TLV. ```go func (s PP2SSL) SSLVersion() (string, bool) ``` -------------------------------- ### Conn Struct Definition Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/listener-conn.md Defines the structure of the Conn wrapper, which handles PROXY protocol headers on a net.Conn. ```go type Conn struct { ProxyHeaderPolicy Policy Validate Validator readDeadline atomic.Value // stores time.Time readErr error bufReader *bufio.Reader header *Header // ... unexported fields ... } ``` -------------------------------- ### SIGV2 Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/protocol-io.md Byte signature for PROXY protocol version 2. ```go var SIGV2 = []byte{' ', ' ', ' ', ' ', ' ', ' ', ' ', 'Q', 'U', 'I', 'T', ' '} ``` -------------------------------- ### Policy Enum Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/types.md Enum defining how to handle PROXY headers. ```go type Policy int ``` -------------------------------- ### Future Method Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/tlv.md Checks if a PP2Type is reserved for future use. ```go func (p PP2Type) Future() bool ``` -------------------------------- ### Read Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/protocol-io.md Reads a PROXY protocol header from a buffered reader and identifies the protocol version automatically. ```go func Read(reader *bufio.Reader) (*Header, error) ``` ```go import ( "bufio" "net" proxyproto "github.com/pires/go-proxyproto" ) conn, _ := net.Listen("tcp", "127.0.0.1:9876") clientConn, _ := conn.Accept() defer clientConn.Close() reader := bufio.NewReader(clientConn) header, err := proxyproto.Read(reader) if err == proxyproto.ErrNoProxyProtocol { // No PROXY header present, process as regular connection println("Regular connection, no PROXY header") } else if err != nil { // Header was present but parsing failed panic(err) } else { // Header parsed successfully println("Client IP:", header.SourceAddr.String()) } ``` -------------------------------- ### IsSSL Function Source: https://github.com/pires/go-proxyproto/blob/main/_autodocs/api-reference/tlvparse.md Returns true if the TLV is a valid SSL TLV with minimum required data. ```go func IsSSL(t proxyproto.TLV) bool ```