Repository: pires/go-proxyproto
Pull request #31 (2020-09-07 21:22:36)

Introduce HeaderProxyFromAddrs
Clients usually need to create a Header they'll WriteTo the underlying
connection.

This commit allows users to easily create a Header from a source
and destination net.Addr. If the net.Addr cannot be represented
by proxyporoto, the transport information is left unspecified.

coveralls: 
[![Coverage Status](https://coveralls.io/builds/33288242/badge)](https://coveralls.io/builds/33288242)

Coverage decreased (-1.1%) to 90.08% when pulling **62581098fa4f394277caad26418550e28f535475 on emersion:header-from-addrs** into **fbefd10859f2cba1f6af048b259f4568a17aa83c on pires:master**.

emersion: All done!

Patch:
diff --git a/addr_proto.go b/addr_proto.go
index 0d0bc70..56b9155 100644
--- a/addr_proto.go
+++ b/addr_proto.go
@@ -4,13 +4,13 @@ package proxyproto
 type AddressFamilyAndProtocol byte
 
 const (
-	UNSPEC       AddressFamilyAndProtocol = '\x00'
-	TCPv4        AddressFamilyAndProtocol = '\x11'
-	UDPv4        AddressFamilyAndProtocol = '\x12'
-	TCPv6        AddressFamilyAndProtocol = '\x21'
-	UDPv6        AddressFamilyAndProtocol = '\x22'
-	UnixStream   AddressFamilyAndProtocol = '\x31'
-	UnixDatagram AddressFamilyAndProtocol = '\x32'
+	UNSPEC       = '\x00'
+	TCPv4        = '\x11'
+	UDPv4        = '\x12'
+	TCPv6        = '\x21'
+	UDPv6        = '\x22'
+	UnixStream   = '\x31'
+	UnixDatagram = '\x32'
 )
 
 var supportedTransportProtocol = map[AddressFamilyAndProtocol]bool{
@@ -54,18 +54,18 @@ func (ap AddressFamilyAndProtocol) IsUnspec() bool {
 
 func (ap AddressFamilyAndProtocol) toByte() byte {
 	if ap.IsIPv4() && ap.IsStream() {
-		return byte(TCPv4)
+		return TCPv4
 	} else if ap.IsIPv4() && ap.IsDatagram() {
-		return byte(UDPv4)
+		return UDPv4
 	} else if ap.IsIPv6() && ap.IsStream() {
-		return byte(TCPv6)
+		return TCPv6
 	} else if ap.IsIPv6() && ap.IsDatagram() {
-		return byte(UDPv6)
+		return UDPv6
 	} else if ap.IsUnix() && ap.IsStream() {
-		return byte(UnixStream)
+		return UnixStream
 	} else if ap.IsUnix() && ap.IsDatagram() {
-		return byte(UnixDatagram)
+		return UnixDatagram
 	}
 
-	return byte(UNSPEC)
+	return UNSPEC
 }
diff --git a/header.go b/header.go
index 60e12d5..7d2a55f 100644
--- a/header.go
+++ b/header.go
@@ -16,19 +16,19 @@ var (
 	SIGV1 = []byte{'\x50', '\x52', '\x4F', '\x58', '\x59'}
 	SIGV2 = []byte{'\x0D', '\x0A', '\x0D', '\x0A', '\x00', '\x0D', '\x0A', '\x51', '\x55', '\x49', '\x54', '\x0A'}
 
-	ErrCantReadProtocolVersionAndCommand    = errors.New("proxyproto: can't read proxy protocol version and command")
-	ErrCantReadAddressFamilyAndProtocol     = errors.New("proxyproto: can't read address family or protocol")
-	ErrCantReadLength                       = errors.New("proxyproto: can't read length")
-	ErrCantResolveSourceUnixAddress         = errors.New("proxyproto: can't resolve source Unix address")
-	ErrCantResolveDestinationUnixAddress    = errors.New("proxyproto: can't resolve destination Unix address")
-	ErrNoProxyProtocol                      = errors.New("proxyproto: proxy protocol signature not present")
-	ErrUnknownProxyProtocolVersion          = errors.New("proxyproto: unknown proxy protocol version")
-	ErrUnsupportedProtocolVersionAndCommand = errors.New("proxyproto: unsupported proxy protocol version and command")
-	ErrUnsupportedAddressFamilyAndProtocol  = errors.New("proxyproto: unsupported address family and protocol")
-	ErrInvalidLength                        = errors.New("proxyproto: invalid length")
-	ErrInvalidAddress                       = errors.New("proxyproto: invalid address")
-	ErrInvalidPortNumber                    = errors.New("proxyproto: invalid port number")
-	ErrSuperfluousProxyHeader               = errors.New("proxyproto: upstream connection sent PROXY header but isn't allowed to send one")
+	ErrCantReadProtocolVersionAndCommand    = errors.New("Can't read proxy protocol version and command")
+	ErrCantReadAddressFamilyAndProtocol     = errors.New("Can't read address family or protocol")
+	ErrCantReadLength                       = errors.New("Can't read length")
+	ErrCantResolveSourceUnixAddress         = errors.New("Can't resolve source Unix address")
+	ErrCantResolveDestinationUnixAddress    = errors.New("Can't resolve destination Unix address")
+	ErrNoProxyProtocol                      = errors.New("Proxy protocol signature not present")
+	ErrUnknownProxyProtocolVersion          = errors.New("Unknown proxy protocol version")
+	ErrUnsupportedProtocolVersionAndCommand = errors.New("Unsupported proxy protocol version and command")
+	ErrUnsupportedAddressFamilyAndProtocol  = errors.New("Unsupported address family and protocol")
+	ErrInvalidLength                        = errors.New("Invalid length")
+	ErrInvalidAddress                       = errors.New("Invalid address")
+	ErrInvalidPortNumber                    = errors.New("Invalid port number")
+	ErrSuperfluousProxyHeader               = errors.New("Upstream connection sent PROXY header but isn't allowed to send one")
 )
 
 // Header is the placeholder for proxy protocol header.
@@ -43,6 +43,69 @@ type Header struct {
 	rawTLVs            []byte
 }
 
+// HeaderProxyFromAddrs creates a new PROXY header from a source and a
+// destination address. If version is zero, the latest protocol version is
+// used.
+//
+// The header is filled on a best-effort basis: if hints cannot be inferred
+// from the provided addresses, the header will be left unspecified.
+func HeaderProxyFromAddrs(version byte, sourceAddr, destAddr net.Addr) *Header {
+	if version < 1 || version > 2 {
+		version = 2
+	}
+	h := &Header{
+		Version:           version,
+		Command:           PROXY,
+		TransportProtocol: UNSPEC,
+	}
+	switch sourceAddr := sourceAddr.(type) {
+	case *net.TCPAddr:
+		destAddr, ok := destAddr.(*net.TCPAddr)
+		if !ok {
+			break
+		}
+		if len(sourceAddr.IP.To4()) == net.IPv4len {
+			h.TransportProtocol = TCPv4
+		} else if len(sourceAddr.IP) == net.IPv6len {
+			h.TransportProtocol = TCPv6
+		} else {
+			break
+		}
+		h.SourceAddress = sourceAddr.IP
+		h.DestinationAddress = destAddr.IP
+		h.SourcePort = uint16(sourceAddr.Port)
+		h.DestinationPort = uint16(destAddr.Port)
+	case *net.UDPAddr:
+		destAddr, ok := destAddr.(*net.UDPAddr)
+		if !ok {
+			break
+		}
+		if len(sourceAddr.IP.To4()) == net.IPv4len {
+			h.TransportProtocol = UDPv4
+		} else if len(sourceAddr.IP) == net.IPv6len {
+			h.TransportProtocol = UDPv6
+		} else {
+			break
+		}
+		h.SourceAddress = sourceAddr.IP
+		h.DestinationAddress = destAddr.IP
+		h.SourcePort = uint16(sourceAddr.Port)
+		h.DestinationPort = uint16(destAddr.Port)
+	case *net.UnixAddr:
+		_, ok := destAddr.(*net.UnixAddr)
+		if !ok {
+			break
+		}
+		switch sourceAddr.Net {
+		case "unix":
+			h.TransportProtocol = UnixStream
+		case "unixgram":
+			h.TransportProtocol = UnixDatagram
+		}
+	}
+	return h
+}
+
 // RemoteAddr returns the address of the remote endpoint of the connection.
 func (header *Header) RemoteAddr() net.Addr {
 	return &net.TCPAddr{
diff --git a/policy.go b/policy.go
index 71ad62b..c76ec67 100644
--- a/policy.go
+++ b/policy.go
@@ -117,14 +117,14 @@ func parse(allowed []string) ([]func(net.IP) bool, error) {
 		if strings.LastIndex(allowFrom, "/") > 0 {
 			_, ipRange, err := net.ParseCIDR(allowFrom)
 			if err != nil {
-				return nil, fmt.Errorf("proxyproto: given string %q is not a valid IP range: %v", allowFrom, err)
+				return nil, fmt.Errorf("Given string %q is not a valid IP range: %v", allowFrom, err)
 			}
 
 			a[i] = ipRange.Contains
 		} else {
 			allowed := net.ParseIP(allowFrom)
 			if allowed == nil {
-				return nil, fmt.Errorf("proxyproto: given string %q is not a valid IP address", allowFrom)
+				return nil, fmt.Errorf("Given string %q is not a valid IP address", allowFrom)
 			}
 
 			a[i] = allowed.Equal
@@ -142,7 +142,7 @@ func ipFromAddr(upstream net.Addr) (net.IP, error) {
 
 	upstreamIP := net.ParseIP(upstreamString)
 	if nil == upstreamIP {
-		return nil, fmt.Errorf("proxyproto: invalid IP address")
+		return nil, fmt.Errorf("invalid IP address")
 	}
 
 	return upstreamIP, nil
diff --git a/tlv.go b/tlv.go
index e6a2149..bbc86b5 100644
--- a/tlv.go
+++ b/tlv.go
@@ -11,30 +11,30 @@ import (
 const (
 	// Section 2.2
 	PP2_TYPE_ALPN           PP2Type = 0x01
-	PP2_TYPE_AUTHORITY      PP2Type = 0x02
-	PP2_TYPE_CRC32C         PP2Type = 0x03
-	PP2_TYPE_NOOP           PP2Type = 0x04
-	PP2_TYPE_SSL            PP2Type = 0x20
-	PP2_SUBTYPE_SSL_VERSION PP2Type = 0x21
-	PP2_SUBTYPE_SSL_CN      PP2Type = 0x22
-	PP2_SUBTYPE_SSL_CIPHER  PP2Type = 0x23
-	PP2_SUBTYPE_SSL_SIG_ALG PP2Type = 0x24
-	PP2_SUBTYPE_SSL_KEY_ALG PP2Type = 0x25
-	PP2_TYPE_NETNS          PP2Type = 0x30
+	PP2_TYPE_AUTHORITY              = 0x02
+	PP2_TYPE_CRC32C                 = 0x03
+	PP2_TYPE_NOOP                   = 0x04
+	PP2_TYPE_SSL                    = 0x20
+	PP2_SUBTYPE_SSL_VERSION         = 0x21
+	PP2_SUBTYPE_SSL_CN              = 0x22
+	PP2_SUBTYPE_SSL_CIPHER          = 0x23
+	PP2_SUBTYPE_SSL_SIG_ALG         = 0x24
+	PP2_SUBTYPE_SSL_KEY_ALG         = 0x25
+	PP2_TYPE_NETNS                  = 0x30
 
 	// Section 2.2.7, reserved types
-	PP2_TYPE_MIN_CUSTOM     PP2Type = 0xE0
-	PP2_TYPE_MAX_CUSTOM     PP2Type = 0xEF
-	PP2_TYPE_MIN_EXPERIMENT PP2Type = 0xF0
-	PP2_TYPE_MAX_EXPERIMENT PP2Type = 0xF7
-	PP2_TYPE_MIN_FUTURE     PP2Type = 0xF8
-	PP2_TYPE_MAX_FUTURE     PP2Type = 0xFF
+	PP2_TYPE_MIN_CUSTOM     = 0xE0
+	PP2_TYPE_MAX_CUSTOM     = 0xEF
+	PP2_TYPE_MIN_EXPERIMENT = 0xF0
+	PP2_TYPE_MAX_EXPERIMENT = 0xF7
+	PP2_TYPE_MIN_FUTURE     = 0xF8
+	PP2_TYPE_MAX_FUTURE     = 0xFF
 )
 
 var (
-	ErrTruncatedTLV    = errors.New("proxyproto: truncated TLV")
-	ErrMalformedTLV    = errors.New("proxyproto: malformed TLV Value")
-	ErrIncompatibleTLV = errors.New("proxyproto: incompatible TLV type")
+	ErrTruncatedTLV    = errors.New("Truncated TLV")
+	ErrMalformedTLV    = errors.New("Malformed TLV Value")
+	ErrIncompatibleTLV = errors.New("Incompatible TLV type")
 )
 
 // PP2Type is the proxy protocol v2 type
diff --git a/v1.go b/v1.go
index a8ba25b..d21df9a 100644
--- a/v1.go
+++ b/v1.go
@@ -9,8 +9,8 @@ import (
 )
 
 const (
-	crlf      = "\r\n"
-	separator = " "
+	CRLF      = "\r\n"
+	SEPARATOR = " "
 )
 
 func initVersion1() *Header {
@@ -24,10 +24,10 @@ func initVersion1() *Header {
 func parseVersion1(reader *bufio.Reader) (*Header, error) {
 	// Make sure we have a v1 header
 	line, err := reader.ReadString('\n')
-	if !strings.HasSuffix(line, crlf) {
+	if !strings.HasSuffix(line, CRLF) {
 		return nil, ErrCantReadProtocolVersionAndCommand
 	}
-	tokens := strings.Split(line[:len(line)-2], separator)
+	tokens := strings.Split(line[:len(line)-2], SEPARATOR)
 	if len(tokens) < 6 {
 		return nil, ErrCantReadProtocolVersionAndCommand
 	}
@@ -79,17 +79,17 @@ func (header *Header) formatVersion1() ([]byte, error) {
 
 	buf := bytes.NewBuffer(make([]byte, 0, 108))
 	buf.Write(SIGV1)
-	buf.WriteString(separator)
+	buf.WriteString(SEPARATOR)
 	buf.WriteString(proto)
-	buf.WriteString(separator)
+	buf.WriteString(SEPARATOR)
 	buf.WriteString(header.SourceAddress.String())
-	buf.WriteString(separator)
+	buf.WriteString(SEPARATOR)
 	buf.WriteString(header.DestinationAddress.String())
-	buf.WriteString(separator)
+	buf.WriteString(SEPARATOR)
 	buf.WriteString(strconv.Itoa(int(header.SourcePort)))
-	buf.WriteString(separator)
+	buf.WriteString(SEPARATOR)
 	buf.WriteString(strconv.Itoa(int(header.DestinationPort)))
-	buf.WriteString(crlf)
+	buf.WriteString(CRLF)
 
 	return buf.Bytes(), nil
 }
diff --git a/v2.go b/v2.go
index 1450b5d..f404607 100644
--- a/v2.go
+++ b/v2.go
@@ -28,7 +28,7 @@ var (
 		binary.BigEndian.PutUint16(a, lengthUnix)
 		return a
 	}()
-	errUint16Overflow = errors.New("proxyproto: uint16 overflow")
+	errUint16Overflow = errors.New("uint16 overflow")
 )
 
 type _ports struct {
diff --git a/version_cmd.go b/version_cmd.go
index 67ce303..2ee1a05 100644
--- a/version_cmd.go
+++ b/version_cmd.go
@@ -4,8 +4,8 @@ package proxyproto
 type ProtocolVersionAndCommand byte
 
 const (
-	LOCAL ProtocolVersionAndCommand = '\x20'
-	PROXY ProtocolVersionAndCommand = '\x21'
+	LOCAL = '\x20'
+	PROXY = '\x21'
 )
 
 var supportedCommand = map[ProtocolVersionAndCommand]bool{
@@ -30,10 +30,10 @@ func (pvc ProtocolVersionAndCommand) IsUnspec() bool {
 
 func (pvc ProtocolVersionAndCommand) toByte() byte {
 	if pvc.IsLocal() {
-		return byte(LOCAL)
+		return LOCAL
 	} else if pvc.IsProxy() {
-		return byte(PROXY)
+		return PROXY
 	}
 
-	return byte(LOCAL)
+	return LOCAL
 }


Test patch:
diff --git a/header_test.go b/header_test.go
index 12e8e6e..a9671e8 100644
--- a/header_test.go
+++ b/header_test.go
@@ -294,3 +294,211 @@ func TestFormat(t *testing.T) {
 		}
 	}
 }
+
+func TestHeaderProxyFromAddrs(t *testing.T) {
+	unspec := &Header{
+		Version:           2,
+		Command:           PROXY,
+		TransportProtocol: UNSPEC,
+	}
+
+	tests := []struct {
+		name                 string
+		version              byte
+		sourceAddr, destAddr net.Addr
+		expected             *Header
+	}{
+		{
+			name: "TCPv4",
+			sourceAddr: &net.TCPAddr{
+				IP:   net.ParseIP("10.1.1.1"),
+				Port: 1000,
+			},
+			destAddr: &net.TCPAddr{
+				IP:   net.ParseIP("20.2.2.2"),
+				Port: 2000,
+			},
+			expected: &Header{
+				Version:            2,
+				Command:            PROXY,
+				TransportProtocol:  TCPv4,
+				SourceAddress:      net.ParseIP("10.1.1.1"),
+				SourcePort:         1000,
+				DestinationAddress: net.ParseIP("20.2.2.2"),
+				DestinationPort:    2000,
+			},
+		},
+		{
+			name: "TCPv6",
+			sourceAddr: &net.TCPAddr{
+				IP:   net.ParseIP("fde7::372"),
+				Port: 1000,
+			},
+			destAddr: &net.TCPAddr{
+				IP:   net.ParseIP("fde7::1"),
+				Port: 2000,
+			},
+			expected: &Header{
+				Version:            2,
+				Command:            PROXY,
+				TransportProtocol:  TCPv6,
+				SourceAddress:      net.ParseIP("fde7::372"),
+				SourcePort:         1000,
+				DestinationAddress: net.ParseIP("fde7::1"),
+				DestinationPort:    2000,
+			},
+		},
+		{
+			name: "UDPv4",
+			sourceAddr: &net.UDPAddr{
+				IP:   net.ParseIP("10.1.1.1"),
+				Port: 1000,
+			},
+			destAddr: &net.UDPAddr{
+				IP:   net.ParseIP("20.2.2.2"),
+				Port: 2000,
+			},
+			expected: &Header{
+				Version:            2,
+				Command:            PROXY,
+				TransportProtocol:  UDPv4,
+				SourceAddress:      net.ParseIP("10.1.1.1"),
+				SourcePort:         1000,
+				DestinationAddress: net.ParseIP("20.2.2.2"),
+				DestinationPort:    2000,
+			},
+		},
+		{
+			name: "UDPv6",
+			sourceAddr: &net.UDPAddr{
+				IP:   net.ParseIP("fde7::372"),
+				Port: 1000,
+			},
+			destAddr: &net.UDPAddr{
+				IP:   net.ParseIP("fde7::1"),
+				Port: 2000,
+			},
+			expected: &Header{
+				Version:            2,
+				Command:            PROXY,
+				TransportProtocol:  UDPv6,
+				SourceAddress:      net.ParseIP("fde7::372"),
+				SourcePort:         1000,
+				DestinationAddress: net.ParseIP("fde7::1"),
+				DestinationPort:    2000,
+			},
+		},
+		{
+			name: "UnixStream",
+			sourceAddr: &net.UnixAddr{
+				Net: "unix",
+			},
+			destAddr: &net.UnixAddr{
+				Net: "unix",
+			},
+			expected: &Header{
+				Version:           2,
+				Command:           PROXY,
+				TransportProtocol: UnixStream,
+			},
+		},
+		{
+			name: "UnixDatagram",
+			sourceAddr: &net.UnixAddr{
+				Net: "unixgram",
+			},
+			destAddr: &net.UnixAddr{
+				Net: "unixgram",
+			},
+			expected: &Header{
+				Version:           2,
+				Command:           PROXY,
+				TransportProtocol: UnixDatagram,
+			},
+		},
+		{
+			name:    "Version1",
+			version: 1,
+			sourceAddr: &net.UnixAddr{
+				Net: "unix",
+			},
+			destAddr: &net.UnixAddr{
+				Net: "unix",
+			},
+			expected: &Header{
+				Version:           1,
+				Command:           PROXY,
+				TransportProtocol: UnixStream,
+			},
+		},
+		{
+			name: "TCPInvalidIP",
+			sourceAddr: &net.TCPAddr{
+				IP:   nil,
+				Port: 1000,
+			},
+			destAddr: &net.TCPAddr{
+				IP:   nil,
+				Port: 2000,
+			},
+			expected: unspec,
+		},
+		{
+			name: "UDPInvalidIP",
+			sourceAddr: &net.UDPAddr{
+				IP:   nil,
+				Port: 1000,
+			},
+			destAddr: &net.UDPAddr{
+				IP:   nil,
+				Port: 2000,
+			},
+			expected: unspec,
+		},
+		{
+			name: "TCPAddrTypeMismatch",
+			sourceAddr: &net.TCPAddr{
+				IP:   net.ParseIP("10.1.1.1"),
+				Port: 1000,
+			},
+			destAddr: &net.UDPAddr{
+				IP:   net.ParseIP("20.2.2.2"),
+				Port: 2000,
+			},
+			expected: unspec,
+		},
+		{
+			name: "UDPAddrTypeMismatch",
+			sourceAddr: &net.UDPAddr{
+				IP:   net.ParseIP("10.1.1.1"),
+				Port: 1000,
+			},
+			destAddr: &net.TCPAddr{
+				IP:   net.ParseIP("20.2.2.2"),
+				Port: 2000,
+			},
+			expected: unspec,
+		},
+		{
+			name: "UnixAddrTypeMismatch",
+			sourceAddr: &net.UnixAddr{
+				Net: "unix",
+			},
+			destAddr: &net.TCPAddr{
+				IP:   net.ParseIP("20.2.2.2"),
+				Port: 2000,
+			},
+			expected: unspec,
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			h := HeaderProxyFromAddrs(tt.version, tt.sourceAddr, tt.destAddr)
+
+			if !h.EqualsTo(tt.expected) {
+				t.Errorf("expected %+v, actual %+v for source %+v and destination %+v", tt.expected, h, tt.sourceAddr, tt.destAddr)
+			}
+		})
+	}
+}
diff --git a/tlv_test.go b/tlv_test.go
index e699cdd..b0fa576 100644
--- a/tlv_test.go
+++ b/tlv_test.go
@@ -8,10 +8,10 @@ import (
 )
 
 var (
-	fixtureOneByteTLV    = []byte{byte(PP2_TYPE_MIN_CUSTOM) + 1}
-	fixtureTwoByteTLV    = []byte{byte(PP2_TYPE_MIN_CUSTOM) + 2, 0x00}
-	fixtureEmptyLenTLV   = []byte{byte(PP2_TYPE_MIN_CUSTOM) + 3, 0x00, 0x01}
-	fixturePartialLenTLV = []byte{byte(PP2_TYPE_MIN_CUSTOM) + 3, 0x00, 0x02, 0x00}
+	fixtureOneByteTLV    = []byte{PP2_TYPE_MIN_CUSTOM + 1}
+	fixtureTwoByteTLV    = []byte{PP2_TYPE_MIN_CUSTOM + 2, 0x00}
+	fixtureEmptyLenTLV   = []byte{PP2_TYPE_MIN_CUSTOM + 3, 0x00, 0x01}
+	fixturePartialLenTLV = []byte{PP2_TYPE_MIN_CUSTOM + 3, 0x00, 0x02, 0x00}
 )
 
 func checkTLVs(t *testing.T, name string, raw []byte, expected []PP2Type) []TLV {
@@ -52,25 +52,25 @@ var invalidTLVTests = []struct {
 }{
 	{
 		name: "One byte TLV",
-		reader: newBufioReader(append(append(SIGV2, byte(PROXY), byte(TCPv4)), fixtureWithTLV(lengthV4Bytes, fixtureIPv4Address,
+		reader: newBufioReader(append(append(SIGV2, PROXY, TCPv4), fixtureWithTLV(lengthV4Bytes, fixtureIPv4Address,
 			fixtureOneByteTLV)...)),
 		expectedError: ErrTruncatedTLV,
 	},
 	{
 		name: "Two byte TLV",
-		reader: newBufioReader(append(append(SIGV2, byte(PROXY), byte(TCPv4)), fixtureWithTLV(lengthV4Bytes, fixtureIPv4Address,
+		reader: newBufioReader(append(append(SIGV2, PROXY, TCPv4), fixtureWithTLV(lengthV4Bytes, fixtureIPv4Address,
 			fixtureTwoByteTLV)...)),
 		expectedError: ErrTruncatedTLV,
 	},
 	{
 		name: "Empty Len TLV",
-		reader: newBufioReader(append(append(SIGV2, byte(PROXY), byte(TCPv4)), fixtureWithTLV(lengthV4Bytes, fixtureIPv4Address,
+		reader: newBufioReader(append(append(SIGV2, PROXY, TCPv4), fixtureWithTLV(lengthV4Bytes, fixtureIPv4Address,
 			fixtureEmptyLenTLV)...)),
 		expectedError: ErrTruncatedTLV,
 	},
 	{
 		name: "Partial Len TLV",
-		reader: newBufioReader(append(append(SIGV2, byte(PROXY), byte(TCPv4)), fixtureWithTLV(lengthV4Bytes, fixtureIPv4Address,
+		reader: newBufioReader(append(append(SIGV2, PROXY, TCPv4), fixtureWithTLV(lengthV4Bytes, fixtureIPv4Address,
 			fixturePartialLenTLV)...)),
 		expectedError: ErrTruncatedTLV,
 	},
diff --git a/v1_test.go b/v1_test.go
index 4a35df7..2e54da0 100644
--- a/v1_test.go
+++ b/v1_test.go
@@ -9,12 +9,12 @@ import (
 )
 
 var (
-	TCP4AddressesAndPorts        = strings.Join([]string{IP4_ADDR, IP4_ADDR, strconv.Itoa(PORT), strconv.Itoa(PORT)}, separator)
-	TCP4AddressesAndInvalidPorts = strings.Join([]string{IP4_ADDR, IP4_ADDR, strconv.Itoa(INVALID_PORT), strconv.Itoa(INVALID_PORT)}, separator)
-	TCP6AddressesAndPorts        = strings.Join([]string{IP6_ADDR, IP6_ADDR, strconv.Itoa(PORT), strconv.Itoa(PORT)}, separator)
+	TCP4AddressesAndPorts        = strings.Join([]string{IP4_ADDR, IP4_ADDR, strconv.Itoa(PORT), strconv.Itoa(PORT)}, SEPARATOR)
+	TCP4AddressesAndInvalidPorts = strings.Join([]string{IP4_ADDR, IP4_ADDR, strconv.Itoa(INVALID_PORT), strconv.Itoa(INVALID_PORT)}, SEPARATOR)
+	TCP6AddressesAndPorts        = strings.Join([]string{IP6_ADDR, IP6_ADDR, strconv.Itoa(PORT), strconv.Itoa(PORT)}, SEPARATOR)
 
-	fixtureTCP4V1 = "PROXY TCP4 " + TCP4AddressesAndPorts + crlf + "GET /"
-	fixtureTCP6V1 = "PROXY TCP6 " + TCP6AddressesAndPorts + crlf + "GET /"
+	fixtureTCP4V1 = "PROXY TCP4 " + TCP4AddressesAndPorts + CRLF + "GET /"
+	fixtureTCP6V1 = "PROXY TCP6 " + TCP6AddressesAndPorts + CRLF + "GET /"
 )
 
 var invalidParseV1Tests = []struct {
@@ -38,15 +38,15 @@ var invalidParseV1Tests = []struct {
 		ErrCantReadProtocolVersionAndCommand,
 	},
 	{
-		newBufioReader([]byte("PROXY TCP6 " + TCP4AddressesAndPorts + crlf)),
+		newBufioReader([]byte("PROXY TCP6 " + TCP4AddressesAndPorts + CRLF)),
 		ErrInvalidAddress,
 	},
 	{
-		newBufioReader([]byte("PROXY TCP4 " + TCP6AddressesAndPorts + crlf)),
+		newBufioReader([]byte("PROXY TCP4 " + TCP6AddressesAndPorts + CRLF)),
 		ErrInvalidAddress,
 	},
 	// PROXY TCP IPv4
-	{newBufioReader([]byte("PROXY TCP4 " + TCP4AddressesAndInvalidPorts + crlf)),
+	{newBufioReader([]byte("PROXY TCP4 " + TCP4AddressesAndInvalidPorts + CRLF)),
 		ErrInvalidPortNumber,
 	},
 }
diff --git a/v2_test.go b/v2_test.go
index e812e46..7b44b12 100644
--- a/v2_test.go
+++ b/v2_test.go
@@ -78,35 +78,35 @@ var invalidParseV2Tests = []struct {
 		ErrUnsupportedProtocolVersionAndCommand,
 	},
 	{
-		newBufioReader(append(SIGV2, byte(PROXY))),
+		newBufioReader(append(SIGV2, PROXY)),
 		ErrCantReadAddressFamilyAndProtocol,
 	},
 	{
-		newBufioReader(append(SIGV2, byte(PROXY), invalidRune)),
+		newBufioReader(append(SIGV2, PROXY, invalidRune)),
 		ErrUnsupportedAddressFamilyAndProtocol,
 	},
 	{
-		newBufioReader(append(SIGV2, byte(PROXY), byte(TCPv4))),
+		newBufioReader(append(SIGV2, PROXY, TCPv4)),
 		ErrCantReadLength,
 	},
 	{
-		newBufioReader(append(SIGV2, byte(PROXY), byte(TCPv4), invalidRune)),
+		newBufioReader(append(SIGV2, PROXY, TCPv4, invalidRune)),
 		ErrCantReadLength,
 	},
 	{
-		newBufioReader(append(append(SIGV2, byte(PROXY), byte(TCPv4)), lengthV4Bytes...)),
+		newBufioReader(append(append(SIGV2, PROXY, TCPv4), lengthV4Bytes...)),
 		ErrInvalidLength,
 	},
 	{
-		newBufioReader(append(append(SIGV2, byte(PROXY), byte(TCPv6)), lengthV6Bytes...)),
+		newBufioReader(append(append(SIGV2, PROXY, TCPv6), lengthV6Bytes...)),
 		ErrInvalidLength,
 	},
 	{
-		newBufioReader(append(append(append(SIGV2, byte(PROXY), byte(TCPv4)), lengthEmptyBytes...), fixtureIPv6Address...)),
+		newBufioReader(append(append(append(SIGV2, PROXY, TCPv4), lengthEmptyBytes...), fixtureIPv6Address...)),
 		ErrInvalidLength,
 	},
 	{
-		newBufioReader(append(append(append(SIGV2, byte(PROXY), byte(TCPv6)), lengthV6Bytes...), fixtureIPv4Address...)),
+		newBufioReader(append(append(append(SIGV2, PROXY, TCPv6), lengthV6Bytes...), fixtureIPv4Address...)),
 		ErrInvalidLength,
 	},
 }
@@ -125,7 +125,7 @@ var validParseAndWriteV2Tests = []struct {
 }{
 	// LOCAL
 	{
-		newBufioReader(append(append(SIGV2, byte(LOCAL), byte(TCPv4)), fixtureIPv4V2...)),
+		newBufioReader(append(append(SIGV2, LOCAL, TCPv4), fixtureIPv4V2...)),
 		&Header{
 			Version:            2,
 			Command:            LOCAL,
@@ -138,7 +138,7 @@ var validParseAndWriteV2Tests = []struct {
 	},
 	// PROXY TCP IPv4
 	{
-		newBufioReader(append(append(SIGV2, byte(PROXY), byte(TCPv4)), fixtureIPv4V2...)),
+		newBufioReader(append(append(SIGV2, PROXY, TCPv4), fixtureIPv4V2...)),
 		&Header{
 			Version:            2,
 			Command:            PROXY,
@@ -151,7 +151,7 @@ var validParseAndWriteV2Tests = []struct {
 	},
 	// PROXY TCP IPv6
 	{
-		newBufioReader(append(append(SIGV2, byte(PROXY), byte(TCPv6)), fixtureIPv6V2...)),
+		newBufioReader(append(append(SIGV2, PROXY, TCPv6), fixtureIPv6V2...)),
 		&Header{
 			Version:            2,
 			Command:            PROXY,
@@ -164,7 +164,7 @@ var validParseAndWriteV2Tests = []struct {
 	},
 	// PROXY TCP IPv4 with TLV
 	{
-		newBufioReader(append(append(SIGV2, byte(PROXY), byte(TCPv4)), fixtureIPv4V2TLV...)),
+		newBufioReader(append(append(SIGV2, PROXY, TCPv4), fixtureIPv4V2TLV...)),
 		&Header{
 			Version:            2,
 			Command:            PROXY,
@@ -178,7 +178,7 @@ var validParseAndWriteV2Tests = []struct {
 	},
 	// PROXY TCP IPv6 with TLV
 	{
-		newBufioReader(append(append(SIGV2, byte(PROXY), byte(TCPv6)), fixtureIPv6V2TLV...)),
+		newBufioReader(append(append(SIGV2, PROXY, TCPv6), fixtureIPv6V2TLV...)),
 		&Header{
 			Version:            2,
 			Command:            PROXY,
@@ -192,7 +192,7 @@ var validParseAndWriteV2Tests = []struct {
 	},
 	// PROXY UDP IPv4
 	{
-		newBufioReader(append(append(SIGV2, byte(PROXY), byte(UDPv4)), fixtureIPv4V2...)),
+		newBufioReader(append(append(SIGV2, PROXY, UDPv4), fixtureIPv4V2...)),
 		&Header{
 			Version:            2,
 			Command:            PROXY,
@@ -205,7 +205,7 @@ var validParseAndWriteV2Tests = []struct {
 	},
 	// PROXY UDP IPv6
 	{
-		newBufioReader(append(append(SIGV2, byte(PROXY), byte(UDPv6)), fixtureIPv6V2...)),
+		newBufioReader(append(append(SIGV2, PROXY, UDPv6), fixtureIPv6V2...)),
 		&Header{
 			Version:            2,
 			Command:            PROXY,
@@ -259,7 +259,7 @@ var validParseV2PaddedTests = []struct {
 }{
 	// PROXY TCP IPv4
 	{
-		append(append(SIGV2, byte(PROXY), byte(TCPv4)), fixtureIPv4V2Padded...),
+		append(append(SIGV2, PROXY, TCPv4), fixtureIPv4V2Padded...),
 		&Header{
 			Version:            2,
 			Command:            PROXY,
@@ -273,7 +273,7 @@ var validParseV2PaddedTests = []struct {
 	},
 	// PROXY TCP IPv6
 	{
-		append(append(SIGV2, byte(PROXY), byte(TCPv6)), fixtureIPv6V2Padded...),
+		append(append(SIGV2, PROXY, TCPv6), fixtureIPv6V2Padded...),
 		&Header{
 			Version:            2,
 			Command:            PROXY,
@@ -287,7 +287,7 @@ var validParseV2PaddedTests = []struct {
 	},
 	// PROXY UDP IPv4
 	{
-		append(append(SIGV2, byte(PROXY), byte(UDPv4)), fixtureIPv4V2Padded...),
+		append(append(SIGV2, PROXY, UDPv4), fixtureIPv4V2Padded...),
 		&Header{
 			Version:            2,
 			Command:            PROXY,
@@ -301,7 +301,7 @@ var validParseV2PaddedTests = []struct {
 	},
 	// PROXY UDP IPv6
 	{
-		append(append(SIGV2, byte(PROXY), byte(UDPv6)), fixtureIPv6V2Padded...),
+		append(append(SIGV2, PROXY, UDPv6), fixtureIPv6V2Padded...),
 		&Header{
 			Version:            2,
 			Command:            PROXY,
@@ -348,7 +348,7 @@ func TestV2EqualsToTLV(t *testing.T) {
 		SourcePort:         PORT,
 		DestinationPort:    PORT,
 	}
-	hdr, err := Read(newBufioReader(append(append(SIGV2, byte(PROXY), byte(TCPv4)), fixtureIPv4V2TLV...)))
+	hdr, err := Read(newBufioReader(append(append(SIGV2, PROXY, TCPv4), fixtureIPv4V2TLV...)))
 	if err != nil {
 		t.Fatal("TestV2EqualsToTLV: Unexpected error ", err)
 	}