Skip to content

Commit 20fa5e1

Browse files
authored
Merge pull request #9 from icgood/tlv
Support TLV data in V2 headers
2 parents 48c317f + aa7f050 commit 20fa5e1

21 files changed

Lines changed: 1276 additions & 356 deletions

.coveragerc

Lines changed: 0 additions & 6 deletions
This file was deleted.

.travis.yml

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
language: python
22
python:
3-
- "3.7"
43
- "3.8"
4+
- "3.7"
55
dist: bionic # https://docs.travis-ci.com/user/languages/python/#python-37-and-higher
66
install:
77
- travis_retry pip install -U -r doc/requirements.txt
@@ -19,10 +19,14 @@ branches:
1919
only:
2020
- master
2121
deploy:
22-
provider: pages
23-
skip_cleanup: true
24-
github_token: $GH_TOKEN
25-
keep_history: true
26-
on:
27-
branch: master
28-
local_dir: doc/build/html
22+
- provider: pages:git
23+
on:
24+
tags: true
25+
local_dir: doc/build/html
26+
edge: true
27+
- provider: pypi
28+
distributions: sdist bdist_wheel
29+
skip_existing: true
30+
on:
31+
tags: true
32+
edge: true

proxyprotocol/__init__.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
import pkg_resources
44
from abc import abstractmethod, ABCMeta
55
from socket import AddressFamily, SocketKind
6-
from typing import Any, Optional, Sequence
6+
from ssl import SSLSocket, SSLObject
7+
from typing import Any, Union, Optional, Sequence
78

9+
from .tlv import ProxyProtocolTLV
810
from .typing import Address, StreamReaderProtocol
911

1012
__all__ = ['__version__', 'ProxyProtocolError', 'ProxyProtocolResult',
@@ -63,6 +65,12 @@ def protocol(self) -> Optional[SocketKind]:
6365
"""The original socket protocol."""
6466
return None
6567

68+
@property
69+
@abstractmethod
70+
def tlv(self) -> ProxyProtocolTLV:
71+
"""Additional information about the connection."""
72+
...
73+
6674
@property
6775
def _sockname(self) -> Address:
6876
return None
@@ -113,6 +121,8 @@ async def read(self, reader: StreamReaderProtocol, *,
113121
@abstractmethod
114122
def build(self, source: Address, dest: Address, *, family: AddressFamily,
115123
protocol: Optional[SocketKind] = None,
124+
ssl: Union[None, SSLObject, SSLSocket] = None,
125+
unique_id: Optional[bytes] = None,
116126
proxied: bool = True) -> bytes:
117127
"""Builds a PROXY protocol v1 header that may be sent at the beginning
118128
of an outbound, client-side connection to indicate the original
@@ -123,6 +133,8 @@ def build(self, source: Address, dest: Address, *, family: AddressFamily,
123133
dest: The original destination address of the connection.
124134
family: The original socket family.
125135
protocol: The original socket protocol.
136+
ssl: The original socket SSL information.
137+
unique_id: The original connection unique identifier.
126138
proxied: True if the connection should not be considered proxied.
127139
128140
Raises:

proxyprotocol/detect.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11

22
from socket import AddressFamily, SocketKind
3-
from typing import Optional
3+
from ssl import SSLSocket, SSLObject
4+
from typing import Union, Optional
45

56
from . import ProxyProtocolError, ProxyProtocolResult, ProxyProtocol
67
from .result import ProxyProtocolResultUnknown
@@ -25,7 +26,7 @@ class ProxyProtocolDetect(ProxyProtocol):
2526

2627
def __init__(self, *versions: ProxyProtocol) -> None:
2728
super().__init__()
28-
self.versions = versions or [ProxyProtocolV1(), ProxyProtocolV2()]
29+
self.versions = versions or [ProxyProtocolV2(), ProxyProtocolV1()]
2930

3031
def is_valid(self, signature: bytes) -> bool:
3132
return any(v.is_valid(signature) for v in self.versions)
@@ -55,11 +56,14 @@ def choose_version(self, signature: bytes) -> ProxyProtocol:
5556

5657
def build(self, source: Address, dest: Address, *, family: AddressFamily,
5758
protocol: Optional[SocketKind] = None,
59+
ssl: Union[None, SSLSocket, SSLObject] = None,
60+
unique_id: Optional[bytes] = None,
5861
proxied: bool = True) -> bytes:
5962
for version in self.versions:
6063
try:
6164
return version.build(source, dest, family=family,
62-
protocol=protocol, proxied=proxied)
65+
protocol=protocol, ssl=ssl,
66+
unique_id=unique_id, proxied=proxied)
6367
except (KeyError, ValueError):
6468
pass
6569
else:

proxyprotocol/noop.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11

22
from socket import AddressFamily, SocketKind
3-
from typing import Optional, Sequence, NoReturn
3+
from ssl import SSLSocket, SSLObject
4+
from typing import Union, Optional, Sequence, NoReturn
45

56
from . import ProxyProtocol
67
from .result import ProxyProtocolResultLocal
@@ -30,5 +31,7 @@ async def read(self, reader: StreamReaderProtocol, *,
3031

3132
def build(self, source: Address, dest: Address, *, family: AddressFamily,
3233
protocol: Optional[SocketKind] = None,
34+
ssl: Union[None, SSLSocket, SSLObject] = None,
35+
unique_id: Optional[bytes] = None,
3336
proxied: bool = True) -> bytes:
3437
return b''

proxyprotocol/result.py

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from typing_extensions import Literal
77

88
from . import ProxyProtocolResult
9+
from .tlv import ProxyProtocolTLV
910

1011
__all__ = ['ProxyProtocolResult', 'ProxyProtocolResultLocal',
1112
'ProxyProtocolResultUnknown', 'ProxyProtocolResultIPv4',
@@ -34,6 +35,10 @@ def source(self) -> None:
3435
def dest(self) -> None:
3536
return None
3637

38+
@property
39+
def tlv(self) -> ProxyProtocolTLV:
40+
return ProxyProtocolTLV()
41+
3742

3843
class ProxyProtocolResultUnknown(ProxyProtocolResult):
3944
"""Indicates that the source of the connection is unknown."""
@@ -64,6 +69,10 @@ def source(self) -> None:
6469
def dest(self) -> None:
6570
return None
6671

72+
@property
73+
def tlv(self) -> ProxyProtocolTLV:
74+
return ProxyProtocolTLV()
75+
6776

6877
class ProxyProtocolResultIPv4(ProxyProtocolResult):
6978
"""The original connection was made with an IPv4 socket. The
@@ -72,15 +81,17 @@ class ProxyProtocolResultIPv4(ProxyProtocolResult):
7281
7382
"""
7483

75-
__slots__ = ['_source', '_dest', '_protocol']
84+
__slots__ = ['_source', '_dest', '_protocol', '_tlv']
7685

7786
def __init__(self, source: Tuple[IPv4Address, int],
7887
dest: Tuple[IPv4Address, int], *,
79-
protocol: Optional[SocketKind] = None) -> None:
88+
protocol: Optional[SocketKind] = None,
89+
tlv: ProxyProtocolTLV = ProxyProtocolTLV()) -> None:
8090
super().__init__()
8191
self._source = source
8292
self._dest = dest
8393
self._protocol = protocol
94+
self._tlv = tlv
8495

8596
@property
8697
def proxied(self) -> Literal[True]:
@@ -102,6 +113,10 @@ def family(self) -> AddressFamily:
102113
def protocol(self) -> Optional[SocketKind]:
103114
return self._protocol
104115

116+
@property
117+
def tlv(self) -> ProxyProtocolTLV:
118+
return self._tlv
119+
105120
@property
106121
def _peername(self) -> Tuple[str, int]:
107122
return str(self.source[0]), self.source[1]
@@ -125,15 +140,17 @@ class ProxyProtocolResultIPv6(ProxyProtocolResult):
125140
126141
"""
127142

128-
__slots__ = ['_source', '_dest', '_protocol']
143+
__slots__ = ['_source', '_dest', '_protocol', '_tlv']
129144

130145
def __init__(self, source: Tuple[IPv6Address, int],
131146
dest: Tuple[IPv6Address, int], *,
132-
protocol: Optional[SocketKind] = None) -> None:
147+
protocol: Optional[SocketKind] = None,
148+
tlv: ProxyProtocolTLV = ProxyProtocolTLV()) -> None:
133149
super().__init__()
134150
self._source = source
135151
self._dest = dest
136152
self._protocol = protocol
153+
self._tlv = tlv
137154

138155
@property
139156
def proxied(self) -> Literal[True]:
@@ -155,6 +172,10 @@ def family(self) -> AddressFamily:
155172
def protocol(self) -> Optional[SocketKind]:
156173
return self._protocol
157174

175+
@property
176+
def tlv(self) -> ProxyProtocolTLV:
177+
return self._tlv
178+
158179
@property
159180
def _peername(self) -> Tuple[str, int, int, int]:
160181
return str(self.source[0]), self.source[1], 0, 0
@@ -178,14 +199,16 @@ class ProxyProtocolResultUnix(ProxyProtocolResult):
178199
179200
"""
180201

181-
__slots__ = ['_source', '_dest', '_protocol']
202+
__slots__ = ['_source', '_dest', '_protocol', '_tlv']
182203

183204
def __init__(self, source: str, dest: str, *,
184-
protocol: Optional[SocketKind] = None) -> None:
205+
protocol: Optional[SocketKind] = None,
206+
tlv: ProxyProtocolTLV = ProxyProtocolTLV()) -> None:
185207
super().__init__()
186208
self._source = source
187209
self._dest = dest
188210
self._protocol = protocol
211+
self._tlv = tlv
189212

190213
@property
191214
def proxied(self) -> Literal[True]:
@@ -207,6 +230,10 @@ def family(self) -> AddressFamily:
207230
def protocol(self) -> Optional[SocketKind]:
208231
return self._protocol
209232

233+
@property
234+
def tlv(self) -> ProxyProtocolTLV:
235+
return self._tlv
236+
210237
@property
211238
def _peername(self) -> str:
212239
return self.source

0 commit comments

Comments
 (0)