github.com/mholt/caddy-l4@v0.0.0-20241104153248-ec8fae209322/modules/l4proxyprotocol/matcher_test.go (about)

     1  package l4proxyprotocol
     2  
     3  import (
     4  	"encoding/hex"
     5  	"io"
     6  	"net"
     7  	"sync"
     8  	"testing"
     9  
    10  	"go.uber.org/zap"
    11  
    12  	"github.com/mholt/caddy-l4/layer4"
    13  )
    14  
    15  var ProxyV1Example = []byte("PROXY TCP4 192.168.0.1 192.168.0.11 56324 443\r\n")
    16  var ProxyV2Example, _ = hex.DecodeString("0d0a0d0a000d0a515549540a2111000c7f0000017f000001b80701bb")
    17  
    18  func assertNoError(t *testing.T, err error) {
    19  	t.Helper()
    20  	if err != nil {
    21  		t.Fatalf("Unexpected error: %s\n", err)
    22  	}
    23  }
    24  
    25  func closePipe(wg *sync.WaitGroup, c1 net.Conn, c2 net.Conn) {
    26  	wg.Wait()
    27  	_ = c1.Close()
    28  	_ = c2.Close()
    29  }
    30  
    31  func TestProxyProtocolMatchV1(t *testing.T) {
    32  	wg := &sync.WaitGroup{}
    33  	in, out := net.Pipe()
    34  	defer closePipe(wg, in, out)
    35  
    36  	cx := layer4.WrapConnection(in, []byte{}, zap.NewNop())
    37  	go func() {
    38  		wg.Add(1)
    39  		defer wg.Done()
    40  		defer func() { _ = out.Close() }()
    41  		_, err := out.Write(ProxyV1Example)
    42  		assertNoError(t, err)
    43  	}()
    44  
    45  	matcher := MatchProxyProtocol{}
    46  
    47  	matched, err := matcher.Match(cx)
    48  	assertNoError(t, err)
    49  
    50  	if !matched {
    51  		t.Fatalf("matcher did not match v1")
    52  	}
    53  
    54  	_, _ = io.Copy(io.Discard, in)
    55  }
    56  
    57  func TestProxyProtocolMatchV2(t *testing.T) {
    58  	wg := &sync.WaitGroup{}
    59  	in, out := net.Pipe()
    60  	defer closePipe(wg, in, out)
    61  
    62  	cx := layer4.WrapConnection(in, []byte{}, zap.NewNop())
    63  	go func() {
    64  		wg.Add(1)
    65  		defer wg.Done()
    66  		defer func() { _ = out.Close() }()
    67  		_, err := out.Write(ProxyV2Example)
    68  		assertNoError(t, err)
    69  	}()
    70  
    71  	matcher := MatchProxyProtocol{}
    72  
    73  	matched, err := matcher.Match(cx)
    74  	assertNoError(t, err)
    75  
    76  	if !matched {
    77  		t.Fatalf("matcher did not match v2")
    78  	}
    79  
    80  	_, _ = io.Copy(io.Discard, in)
    81  }
    82  
    83  func TestProxyProtocolMatchGarbage(t *testing.T) {
    84  	wg := &sync.WaitGroup{}
    85  	in, out := net.Pipe()
    86  	defer closePipe(wg, in, out)
    87  
    88  	cx := layer4.WrapConnection(in, []byte{}, zap.NewNop())
    89  	go func() {
    90  		wg.Add(1)
    91  		defer wg.Done()
    92  		defer func() { _ = out.Close() }()
    93  		_, err := out.Write([]byte("Hello World Hello World Hello World Hello World"))
    94  		assertNoError(t, err)
    95  	}()
    96  
    97  	matcher := MatchProxyProtocol{}
    98  
    99  	matched, err := matcher.Match(cx)
   100  	assertNoError(t, err)
   101  
   102  	if matched {
   103  		t.Fatalf("matcher did match garbage but should not")
   104  	}
   105  
   106  	_, _ = io.Copy(io.Discard, in)
   107  }