Skip to content
This repository has been archived by the owner on Jul 13, 2023. It is now read-only.

Commit

Permalink
feat: switch proxy_protocol -> proxy_protocol_port (#789)
Browse files Browse the repository at this point in the history
now toggles exposing a separate port w/ proxy protocol handling

fixes #788
  • Loading branch information
pjenvey authored and bbangert committed Jan 27, 2017
1 parent f8c819e commit 81e3af4
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 36 deletions.
28 changes: 16 additions & 12 deletions autopush/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ def obsolete_args(parser):
parser.add_argument('--max_message_size', type=int, help="OBSOLETE")
parser.add_argument('--s3_bucket', help='OBSOLETE')
parser.add_argument('--senderid_expry', help='OBSOLETE')
parser.add_argument('--proxy_protocol', help="OBSOLETE")
# old APNs args
parser.add_argument('--apns_enabled', help="OBSOLETE")
parser.add_argument('--apns_sandbox', help="OBSOLETE")
Expand Down Expand Up @@ -316,10 +317,11 @@ def _parse_endpoint(sysargs, use_files=True):
parser.add_argument('--client_certs',
help="Allowed TLS client certificates",
type=str, env_var='CLIENT_CERTS', default="{}")
parser.add_argument('--proxy_protocol',
help="Enable HAProxy Proxy Protocol handling",
action="store_true", default=False,
env_var='PROXY_PROTOCOL')
parser.add_argument('--proxy_protocol_port',
help="Enable a secondary Endpoint Port with HAProxy "
"Proxy Protocol handling",
type=int, default=None,
env_var='PROXY_PROTOCOL_PORT')

add_shared_args(parser)

Expand Down Expand Up @@ -602,20 +604,22 @@ def endpoint_main(sysargs=None, use_files=True):

settings.metrics.start()

# start the senderIDs refresh timer
if args.ssl_key:
def create_endpoint(port):
if not args.ssl_key:
return TCP4ServerEndpoint(reactor, port)
ssl_cf = AutopushSSLContextFactory(
args.ssl_key,
args.ssl_cert,
dh_file=args.ssl_dh_param,
require_peer_certs=settings.enable_tls_auth)
endpoint = SSL4ServerEndpoint(reactor, args.port, ssl_cf)
else:
endpoint = TCP4ServerEndpoint(reactor, args.port)
if args.proxy_protocol:
from twisted.protocols.haproxy import proxyEndpoint
endpoint = proxyEndpoint(endpoint)
return SSL4ServerEndpoint(reactor, port, ssl_cf)

endpoint = create_endpoint(args.port)
endpoint.listen(site)
if args.proxy_protocol_port:
from twisted.protocols.haproxy import proxyEndpoint
pendpoint = proxyEndpoint(create_endpoint(args.proxy_protocol_port))
pendpoint.listen(site)

# Start the table rotation checker/updater
l = task.LoopingCall(settings.update_rotating_tables)
Expand Down
51 changes: 31 additions & 20 deletions autopush/tests/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ def wait_for(self, func):
class IntegrationBase(unittest.TestCase):
track_objects = True
track_objects_excludes = [AutopushSettings, WebSocketServerFactory]
proxy_protocol_port = None

def setUp(self):
import cyclone.web
Expand Down Expand Up @@ -441,33 +442,36 @@ def setUp(self):
)
mount_health_handlers(site, settings)
self._settings = settings
if is_https:
ep = SSL4ServerEndpoint(
reactor,
self.endpoint_port,
self.endpoint_SSLCF())
else:
ep = TCP4ServerEndpoint(reactor, self.endpoint_port)
ep = self.wrap_endpoint(ep)

self.endpoints = []
ep = self._create_endpoint(self.endpoint_port, is_https)
ep.listen(site).addCallback(self._endpoint_listening)

if self.proxy_protocol_port:
from twisted.protocols.haproxy import proxyEndpoint
ep = proxyEndpoint(
self._create_endpoint(self.proxy_protocol_port, is_https)
)
ep.listen(site).addCallback(self._endpoint_listening)

def _create_endpoint(self, port, is_https):
if not is_https:
return TCP4ServerEndpoint(reactor, port)
return SSL4ServerEndpoint(reactor, port, self.endpoint_SSLCF())

def _endpoint_listening(self, port):
self.website = port
self.endpoints.append(port)

def make_client_certs(self):
return None

def endpoint_SSLCF(self):
raise NotImplementedError # pragma: nocover

def wrap_endpoint(self, ep):
return ep

@inlineCallbacks
def tearDown(self):
dones = [self.websocket.stopListening(), self.website.stopListening(),
self.ws_website.stopListening()]
for d in filter(None, dones):
sites = [self.websocket, self.ws_website] + self.endpoints
for d in filter(None, (site.stopListening() for site in sites)):
yield d

# Dirty reactor unless we shut down the cached connections
Expand Down Expand Up @@ -2005,10 +2009,7 @@ def test_registration(self):


class TestProxyProtocol(IntegrationBase):

def wrap_endpoint(self, ep):
from twisted.protocols.haproxy import proxyEndpoint
return proxyEndpoint(ep)
proxy_protocol_port = 9021

@inlineCallbacks
def test_proxy_protocol(self):
Expand All @@ -2018,13 +2019,23 @@ def test_proxy_protocol(self):
# it in before the verb
response, body = yield _agent(
'{}GET'.format(proto_line),
"http://localhost:9020/v1/err",
"http://localhost:{}/v1/err".format(self.proxy_protocol_port),
)
eq_(response.code, 418)
payload = json.loads(body)
eq_(payload['error'], "Test Error")
ok_(self.logs.logged_ci(lambda ci: ci.get('remote_ip') == ip))

@inlineCallbacks
def test_no_proxy_protocol(self):
response, body = yield _agent(
'GET',
"http://localhost:{}/v1/err".format(self.endpoint_port),
)
eq_(response.code, 418)
payload = json.loads(body)
eq_(payload['error'], "Test Error")


@inlineCallbacks
def _agent(method, url, contextFactory=None, headers=None, body=None):
Expand Down
4 changes: 2 additions & 2 deletions autopush/tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,9 +300,9 @@ def test_client_certs(self):
], False)
ok_(not returncode)

def test_proxy_protocol(self):
def test_proxy_protocol_port(self):
endpoint_main([
"--proxy_protocol",
"--proxy_protocol_port=8081",
], False)

@patch('hyper.tls', spec=hyper.tls)
Expand Down
5 changes: 3 additions & 2 deletions configs/autopush_endpoint.ini.sample
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,6 @@ port = 8082
; {"client1": ["2C:78:31.."], "client2": ["3F:D0:E0..", "E2:19:B1.."]}
#client_certs =

; Enable HAProxy Proxy Protocol handling
#proxy_protocol
; Enable a secondary port to listen for notifications with HAProxy
; Proxy Protocol handling
#proxy_protocol_port = 8083

0 comments on commit 81e3af4

Please sign in to comment.