ExampleReadHeaderTimeout demonstrates the cancellable, low-level way to read a PROXY protocol header directly from a net.Conn you manage yourself. Unlike the deprecated ReadTimeout, it is given the conn and sets a real read deadline, so a peer that connects but never sends the header cannot block th
()
| 15 | // deprecated ReadTimeout, it is given the conn and sets a real read deadline, so |
| 16 | // a peer that connects but never sends the header cannot block the read forever. |
| 17 | func ExampleReadHeaderTimeout() { |
| 18 | serverConn, clientConn := net.Pipe() |
| 19 | defer func() { _ = serverConn.Close() }() |
| 20 | |
| 21 | go func() { |
| 22 | // A PROXY v1 header naming the real client, followed by application data. |
| 23 | _, _ = clientConn.Write([]byte(proxyV1Line)) |
| 24 | _, _ = clientConn.Write([]byte("HELO")) |
| 25 | _ = clientConn.Close() |
| 26 | }() |
| 27 | |
| 28 | // reader must be buffered over conn: any bytes read past the header remain |
| 29 | // available for the caller to consume afterwards. |
| 30 | reader := bufio.NewReader(serverConn) |
| 31 | header, err := proxyproto.ReadHeaderTimeout(serverConn, reader, time.Second) |
| 32 | if err != nil && err != proxyproto.ErrNoProxyProtocol { |
| 33 | fmt.Println("error:", err) |
| 34 | return |
| 35 | } |
| 36 | if header != nil { |
| 37 | fmt.Println("client:", header.SourceAddr) |
| 38 | } |
| 39 | |
| 40 | // Continue reading the application data from the same buffered reader. |
| 41 | data, _ := io.ReadAll(reader) |
| 42 | fmt.Printf("data: %s\n", data) |
| 43 | // Output: |
| 44 | // client: 192.168.1.1:12345 |
| 45 | // data: HELO |
| 46 | } |