Commit 4fb34ff9 authored by Michael Fladischer's avatar Michael Fladischer

Update upstream source from tag 'upstream/1.4.2'

Update to upstream version '1.4.2'
with Debian dir 1b693af631b6c36745cb455f05e8245083c134db
parents 69d3a121 0b8b502f
sudo: false sudo: false
dist: trusty
language: python language: python
......
1.4.2 (2018-01-05)
------------------
* Bugfix for WebSocket protocol when X-Forwarded-For is turned on.
1.4.1 (2018-01-02)
------------------
* Bugfix for a bad merge of HTTPFactory for X-Forwarded-Proto causing Daphne
to not start.
1.4.0 (2018-01-02)
------------------
* The X-Forwarded-Proto header can now be used to pass along protocol from
a reverse proxy.
* WebSocket headers are now correctly always passed as bytestrings.
1.3.0 (2017-06-16) 1.3.0 (2017-06-16)
------------------ ------------------
......
...@@ -57,7 +57,7 @@ Daphne 1.1 and above supports terminating HTTP/2 connections natively. You'll ...@@ -57,7 +57,7 @@ Daphne 1.1 and above supports terminating HTTP/2 connections natively. You'll
need to do a couple of things to get it working, though. First, you need to need to do a couple of things to get it working, though. First, you need to
make sure you install the Twisted ``http2`` and ``tls`` extras:: make sure you install the Twisted ``http2`` and ``tls`` extras::
pip install -U Twisted[tls,http2] pip install -U 'Twisted[tls,http2]'
Next, because all current browsers only support HTTP/2 when using TLS, you will Next, because all current browsers only support HTTP/2 when using TLS, you will
need to start Daphne with TLS turned on, which can be done using the Twisted endpoint syntax:: need to start Daphne with TLS turned on, which can be done using the Twisted endpoint syntax::
......
__version__ = "1.3.0" __version__ = "1.4.2"
...@@ -213,6 +213,7 @@ class CommandLineInterface(object): ...@@ -213,6 +213,7 @@ class CommandLineInterface(object):
verbosity=args.verbosity, verbosity=args.verbosity,
proxy_forwarded_address_header='X-Forwarded-For' if args.proxy_headers else None, proxy_forwarded_address_header='X-Forwarded-For' if args.proxy_headers else None,
proxy_forwarded_port_header='X-Forwarded-Port' if args.proxy_headers else None, proxy_forwarded_port_header='X-Forwarded-Port' if args.proxy_headers else None,
proxy_forwarded_proto_header='X-Forwarded-Proto' if args.proxy_headers else None,
force_sync=args.force_sync, force_sync=args.force_sync,
) )
self.server.run() self.server.run()
...@@ -80,12 +80,16 @@ class WebRequest(http.Request): ...@@ -80,12 +80,16 @@ class WebRequest(http.Request):
self.client_addr = None self.client_addr = None
self.server_addr = None self.server_addr = None
self.client_scheme = 'https' if self.isSecure() else 'http'
if self.factory.proxy_forwarded_address_header: if self.factory.proxy_forwarded_address_header:
self.client_addr = parse_x_forwarded_for( self.client_addr, self.client_scheme = parse_x_forwarded_for(
self.requestHeaders, self.requestHeaders,
self.factory.proxy_forwarded_address_header, self.factory.proxy_forwarded_address_header,
self.factory.proxy_forwarded_port_header, self.factory.proxy_forwarded_port_header,
self.client_addr self.factory.proxy_forwarded_proto_header,
self.client_addr,
self.client_scheme
) )
# Check for unicodeish path (or it'll crash when trying to parse) # Check for unicodeish path (or it'll crash when trying to parse)
...@@ -166,7 +170,7 @@ class WebRequest(http.Request): ...@@ -166,7 +170,7 @@ class WebRequest(http.Request):
"method": self.method.decode("ascii"), "method": self.method.decode("ascii"),
"path": self.unquote(self.path), "path": self.unquote(self.path),
"root_path": self.root_path, "root_path": self.root_path,
"scheme": "https" if self.isSecure() else "http", "scheme": self.client_scheme,
"query_string": self.query_string, "query_string": self.query_string,
"headers": self.clean_headers, "headers": self.clean_headers,
"body": self.content.read(), "body": self.content.read(),
...@@ -308,7 +312,7 @@ class HTTPFactory(http.HTTPFactory): ...@@ -308,7 +312,7 @@ class HTTPFactory(http.HTTPFactory):
routed appropriately. routed appropriately.
""" """
def __init__(self, channel_layer, action_logger=None, send_channel=None, timeout=120, websocket_timeout=86400, ping_interval=20, ping_timeout=30, ws_protocols=None, root_path="", websocket_connect_timeout=30, proxy_forwarded_address_header=None, proxy_forwarded_port_header=None, websocket_handshake_timeout=5): def __init__(self, channel_layer, action_logger=None, send_channel=None, timeout=120, websocket_timeout=86400, ping_interval=20, ping_timeout=30, ws_protocols=None, root_path="", websocket_connect_timeout=30, proxy_forwarded_address_header=None, proxy_forwarded_port_header=None, proxy_forwarded_proto_header=None, websocket_handshake_timeout=5):
http.HTTPFactory.__init__(self) http.HTTPFactory.__init__(self)
self.channel_layer = channel_layer self.channel_layer = channel_layer
self.action_logger = action_logger self.action_logger = action_logger
...@@ -320,6 +324,7 @@ class HTTPFactory(http.HTTPFactory): ...@@ -320,6 +324,7 @@ class HTTPFactory(http.HTTPFactory):
self.ping_interval = ping_interval self.ping_interval = ping_interval
self.proxy_forwarded_address_header = proxy_forwarded_address_header self.proxy_forwarded_address_header = proxy_forwarded_address_header
self.proxy_forwarded_port_header = proxy_forwarded_port_header self.proxy_forwarded_port_header = proxy_forwarded_port_header
self.proxy_forwarded_proto_header = proxy_forwarded_proto_header
# We track all sub-protocols for response channel mapping # We track all sub-protocols for response channel mapping
self.reply_protocols = {} self.reply_protocols = {}
# Make a factory for WebSocket protocols # Make a factory for WebSocket protocols
......
...@@ -36,6 +36,7 @@ class Server(object): ...@@ -36,6 +36,7 @@ class Server(object):
root_path="", root_path="",
proxy_forwarded_address_header=None, proxy_forwarded_address_header=None,
proxy_forwarded_port_header=None, proxy_forwarded_port_header=None,
proxy_forwarded_proto_header=None,
force_sync=False, force_sync=False,
verbosity=1, verbosity=1,
websocket_handshake_timeout=5 websocket_handshake_timeout=5
...@@ -66,6 +67,7 @@ class Server(object): ...@@ -66,6 +67,7 @@ class Server(object):
self.ping_timeout = ping_timeout self.ping_timeout = ping_timeout
self.proxy_forwarded_address_header = proxy_forwarded_address_header self.proxy_forwarded_address_header = proxy_forwarded_address_header
self.proxy_forwarded_port_header = proxy_forwarded_port_header self.proxy_forwarded_port_header = proxy_forwarded_port_header
self.proxy_forwarded_proto_header = proxy_forwarded_proto_header
# If they did not provide a websocket timeout, default it to the # If they did not provide a websocket timeout, default it to the
# channel layer's group_expiry value if present, or one day if not. # channel layer's group_expiry value if present, or one day if not.
self.websocket_timeout = websocket_timeout or getattr(channel_layer, "group_expiry", 86400) self.websocket_timeout = websocket_timeout or getattr(channel_layer, "group_expiry", 86400)
...@@ -95,6 +97,7 @@ class Server(object): ...@@ -95,6 +97,7 @@ class Server(object):
root_path=self.root_path, root_path=self.root_path,
proxy_forwarded_address_header=self.proxy_forwarded_address_header, proxy_forwarded_address_header=self.proxy_forwarded_address_header,
proxy_forwarded_port_header=self.proxy_forwarded_port_header, proxy_forwarded_port_header=self.proxy_forwarded_port_header,
proxy_forwarded_proto_header=self.proxy_forwarded_proto_header,
websocket_handshake_timeout=self.websocket_handshake_timeout websocket_handshake_timeout=self.websocket_handshake_timeout
) )
if self.verbosity <= 1: if self.verbosity <= 1:
...@@ -121,10 +124,19 @@ class Server(object): ...@@ -121,10 +124,19 @@ class Server(object):
logger.info("Listening on endpoint %s" % socket_description) logger.info("Listening on endpoint %s" % socket_description)
# Twisted requires str on python2 (not unicode) and str on python3 (not bytes) # Twisted requires str on python2 (not unicode) and str on python3 (not bytes)
ep = serverFromString(reactor, str(socket_description)) ep = serverFromString(reactor, str(socket_description))
self.listeners.append(ep.listen(self.factory)) listener = ep.listen(self.factory)
listener.addErrback(self.on_listener_error)
self.listeners.append(listener)
reactor.run(installSignalHandlers=self.signal_handlers) reactor.run(installSignalHandlers=self.signal_handlers)
def on_listener_error(self, failure):
"""
Callback function used to process interface listener errors.
"""
logger.error(failure.getErrorMessage())
def backend_reader_sync(self): def backend_reader_sync(self):
""" """
Runs as an-often-as-possible task with the reactor, unless there was Runs as an-often-as-possible task with the reactor, unless there was
...@@ -215,7 +227,7 @@ def build_endpoint_description_strings( ...@@ -215,7 +227,7 @@ def build_endpoint_description_strings(
if unix_socket: if unix_socket:
socket_descriptions.append('unix:%s' % unix_socket) socket_descriptions.append('unix:%s' % unix_socket)
if file_descriptor: if file_descriptor is not None:
socket_descriptions.append('fd:fileno=%d' % int(file_descriptor)) socket_descriptions.append('fd:fileno=%d' % int(file_descriptor))
return socket_descriptions return socket_descriptions
from hypothesis import HealthCheck, settings
settings.register_profile(
'daphne',
settings(suppress_health_check=[HealthCheck.too_slow]),
)
settings.load_profile('daphne')
...@@ -8,7 +8,7 @@ import unittest ...@@ -8,7 +8,7 @@ import unittest
from six.moves.urllib import parse from six.moves.urllib import parse
from asgiref.inmemory import ChannelLayer from asgiref.inmemory import ChannelLayer
from hypothesis import given, assume, settings, HealthCheck from hypothesis import given, assume
from twisted.test import proto_helpers from twisted.test import proto_helpers
from daphne.http_protocol import HTTPFactory from daphne.http_protocol import HTTPFactory
...@@ -99,7 +99,6 @@ class TestHTTPRequestSpec(testcases.ASGIHTTPTestCase): ...@@ -99,7 +99,6 @@ class TestHTTPRequestSpec(testcases.ASGIHTTPTestCase):
request_body=http_strategies.http_body(), request_body=http_strategies.http_body(),
) )
# This test is slow enough that on Travis, hypothesis sometimes complains. # This test is slow enough that on Travis, hypothesis sometimes complains.
@settings(suppress_health_check=[HealthCheck.too_slow])
def test_kitchen_sink( def test_kitchen_sink(
self, request_method, request_path, request_params, request_headers, request_body): self, request_method, request_path, request_params, request_headers, request_body):
""" """
...@@ -172,6 +171,7 @@ class TestProxyHandling(unittest.TestCase): ...@@ -172,6 +171,7 @@ class TestProxyHandling(unittest.TestCase):
def test_x_forwarded_for_parsed(self): def test_x_forwarded_for_parsed(self):
self.factory.proxy_forwarded_address_header = 'X-Forwarded-For' self.factory.proxy_forwarded_address_header = 'X-Forwarded-For'
self.factory.proxy_forwarded_port_header = 'X-Forwarded-Port' self.factory.proxy_forwarded_port_header = 'X-Forwarded-Port'
self.factory.proxy_forwarded_proto_header = 'X-Forwarded-Proto'
self.proto.dataReceived( self.proto.dataReceived(
b"GET /te%20st-%C3%A0/?foo=+bar HTTP/1.1\r\n" + b"GET /te%20st-%C3%A0/?foo=+bar HTTP/1.1\r\n" +
b"Host: somewhere.com\r\n" + b"Host: somewhere.com\r\n" +
...@@ -186,6 +186,7 @@ class TestProxyHandling(unittest.TestCase): ...@@ -186,6 +186,7 @@ class TestProxyHandling(unittest.TestCase):
def test_x_forwarded_for_port_missing(self): def test_x_forwarded_for_port_missing(self):
self.factory.proxy_forwarded_address_header = 'X-Forwarded-For' self.factory.proxy_forwarded_address_header = 'X-Forwarded-For'
self.factory.proxy_forwarded_port_header = 'X-Forwarded-Port' self.factory.proxy_forwarded_port_header = 'X-Forwarded-Port'
self.factory.proxy_forwarded_proto_header = 'X-Forwarded-Proto'
self.proto.dataReceived( self.proto.dataReceived(
b"GET /te%20st-%C3%A0/?foo=+bar HTTP/1.1\r\n" + b"GET /te%20st-%C3%A0/?foo=+bar HTTP/1.1\r\n" +
b"Host: somewhere.com\r\n" + b"Host: somewhere.com\r\n" +
......
...@@ -70,7 +70,7 @@ class TestHTTPResponseSpec(testcases.ASGIHTTPTestCase): ...@@ -70,7 +70,7 @@ class TestHTTPResponseSpec(testcases.ASGIHTTPTestCase):
@given( @given(
headers=http_strategies.headers(), headers=http_strategies.headers(),
body=http_strategies.http_body() body=http_strategies.http_body(),
) )
def test_kitchen_sink(self, headers, body): def test_kitchen_sink(self, headers, body):
""" """
......
...@@ -16,11 +16,13 @@ class TestXForwardedForHttpParsing(TestCase): ...@@ -16,11 +16,13 @@ class TestXForwardedForHttpParsing(TestCase):
def test_basic(self): def test_basic(self):
headers = Headers({ headers = Headers({
b'X-Forwarded-For': [b'10.1.2.3'], b'X-Forwarded-For': [b'10.1.2.3'],
b'X-Forwarded-Port': [b'1234'] b'X-Forwarded-Port': [b'1234'],
b'X-Forwarded-Proto': [b'https']
}) })
result = parse_x_forwarded_for(headers) result = parse_x_forwarded_for(headers)
self.assertEqual(result, ['10.1.2.3', 1234]) self.assertEqual(result, (['10.1.2.3', 1234], 'https'))
self.assertIsInstance(result[0], six.text_type) self.assertIsInstance(result[0][0], six.text_type)
self.assertIsInstance(result[1], six.text_type)
def test_address_only(self): def test_address_only(self):
headers = Headers({ headers = Headers({
...@@ -28,7 +30,7 @@ class TestXForwardedForHttpParsing(TestCase): ...@@ -28,7 +30,7 @@ class TestXForwardedForHttpParsing(TestCase):
}) })
self.assertEqual( self.assertEqual(
parse_x_forwarded_for(headers), parse_x_forwarded_for(headers),
['10.1.2.3', 0] (['10.1.2.3', 0], None)
) )
def test_v6_address(self): def test_v6_address(self):
...@@ -37,7 +39,7 @@ class TestXForwardedForHttpParsing(TestCase): ...@@ -37,7 +39,7 @@ class TestXForwardedForHttpParsing(TestCase):
}) })
self.assertEqual( self.assertEqual(
parse_x_forwarded_for(headers), parse_x_forwarded_for(headers),
['1043::a321:0001', 0] (['1043::a321:0001', 0], None)
) )
def test_multiple_proxys(self): def test_multiple_proxys(self):
...@@ -46,19 +48,39 @@ class TestXForwardedForHttpParsing(TestCase): ...@@ -46,19 +48,39 @@ class TestXForwardedForHttpParsing(TestCase):
}) })
self.assertEqual( self.assertEqual(
parse_x_forwarded_for(headers), parse_x_forwarded_for(headers),
['10.1.2.3', 0] (['10.1.2.3', 0], None)
) )
def test_original(self): def test_original_addr(self):
headers = Headers({})
self.assertEqual(
parse_x_forwarded_for(headers, original_addr=['127.0.0.1', 80]),
(['127.0.0.1', 80], None)
)
def test_original_proto(self):
headers = Headers({}) headers = Headers({})
self.assertEqual( self.assertEqual(
parse_x_forwarded_for(headers, original=['127.0.0.1', 80]), parse_x_forwarded_for(headers, original_scheme='http'),
['127.0.0.1', 80] (None, 'http')
) )
def test_no_original(self): def test_no_original(self):
headers = Headers({}) headers = Headers({})
self.assertIsNone(parse_x_forwarded_for(headers)) self.assertEqual(
parse_x_forwarded_for(headers),
(None, None)
)
def test_address_and_proto(self):
headers = Headers({
b'X-Forwarded-For': [b'10.1.2.3'],
b'X-Forwarded-Proto': [b'https'],
})
self.assertEqual(
parse_x_forwarded_for(headers),
(['10.1.2.3', 0], 'https')
)
class TestXForwardedForWsParsing(TestCase): class TestXForwardedForWsParsing(TestCase):
...@@ -73,7 +95,7 @@ class TestXForwardedForWsParsing(TestCase): ...@@ -73,7 +95,7 @@ class TestXForwardedForWsParsing(TestCase):
} }
self.assertEqual( self.assertEqual(
parse_x_forwarded_for(headers), parse_x_forwarded_for(headers),
['10.1.2.3', 1234] (['10.1.2.3', 1234], None)
) )
def test_address_only(self): def test_address_only(self):
...@@ -82,7 +104,7 @@ class TestXForwardedForWsParsing(TestCase): ...@@ -82,7 +104,7 @@ class TestXForwardedForWsParsing(TestCase):
} }
self.assertEqual( self.assertEqual(
parse_x_forwarded_for(headers), parse_x_forwarded_for(headers),
['10.1.2.3', 0] (['10.1.2.3', 0], None)
) )
def test_v6_address(self): def test_v6_address(self):
...@@ -91,7 +113,7 @@ class TestXForwardedForWsParsing(TestCase): ...@@ -91,7 +113,7 @@ class TestXForwardedForWsParsing(TestCase):
} }
self.assertEqual( self.assertEqual(
parse_x_forwarded_for(headers), parse_x_forwarded_for(headers),
['1043::a321:0001', 0] (['1043::a321:0001', 0], None)
) )
def test_multiple_proxys(self): def test_multiple_proxys(self):
...@@ -100,16 +122,19 @@ class TestXForwardedForWsParsing(TestCase): ...@@ -100,16 +122,19 @@ class TestXForwardedForWsParsing(TestCase):
} }
self.assertEqual( self.assertEqual(
parse_x_forwarded_for(headers), parse_x_forwarded_for(headers),
['10.1.2.3', 0] (['10.1.2.3', 0], None)
) )
def test_original(self): def test_original(self):
headers = {} headers = {}
self.assertEqual( self.assertEqual(
parse_x_forwarded_for(headers, original=['127.0.0.1', 80]), parse_x_forwarded_for(headers, original_addr=['127.0.0.1', 80]),
['127.0.0.1', 80] (['127.0.0.1', 80], None)
) )
def test_no_original(self): def test_no_original(self):
headers = {} headers = {}
self.assertIsNone(parse_x_forwarded_for(headers)) self.assertEqual(
parse_x_forwarded_for(headers),
(None, None)
)
# coding: utf8 # coding: utf8
from __future__ import unicode_literals from __future__ import unicode_literals
from hypothesis import assume, given, strategies from hypothesis import assume, given, strategies, settings
from twisted.test import proto_helpers from twisted.test import proto_helpers
from asgiref.inmemory import ChannelLayer from asgiref.inmemory import ChannelLayer
...@@ -66,6 +66,7 @@ class TestHandshake(testcases.ASGIWebSocketTestCase): ...@@ -66,6 +66,7 @@ class TestHandshake(testcases.ASGIWebSocketTestCase):
params=http_strategies.query_params(), params=http_strategies.query_params(),
headers=http_strategies.headers(), headers=http_strategies.headers(),
) )
@settings(perform_health_check=False)
def test_connection(self, path, params, headers): def test_connection(self, path, params, headers):
message = WebSocketConnection().connect(path, params, headers) message = WebSocketConnection().connect(path, params, headers)
self.assert_valid_websocket_connect_message(message, path, params, headers) self.assert_valid_websocket_connect_message(message, path, params, headers)
......
...@@ -5,41 +5,51 @@ def header_value(headers, header_name): ...@@ -5,41 +5,51 @@ def header_value(headers, header_name):
value = headers[header_name] value = headers[header_name]
if isinstance(value, list): if isinstance(value, list):
value = value[0] value = value[0]
return value.decode("utf-8") # decode to urf-8 if value is bytes
if isinstance(value, bytes):
value = value.decode("utf-8")
return value
def parse_x_forwarded_for(headers, def parse_x_forwarded_for(headers,
address_header_name='X-Forwarded-For', address_header_name='X-Forwarded-For',
port_header_name='X-Forwarded-Port', port_header_name='X-Forwarded-Port',
original=None): proto_header_name='X-Forwarded-Proto',
original_addr=None,
original_scheme=None):
""" """
Parses an X-Forwarded-For header and returns a host/port pair as a list. Parses an X-Forwarded-For header and returns a host/port pair as a list.
@param headers: The twisted-style object containing a request's headers @param headers: The twisted-style object containing a request's headers
@param address_header_name: The name of the expected host header @param address_header_name: The name of the expected host header
@param port_header_name: The name of the expected port header @param port_header_name: The name of the expected port header
@param original: A host/port pair that should be returned if the headers are not in the request @param proto_header_name: The name of the expected protocol header
@return: A list containing a host (string) as the first entry and a port (int) as the second. @param original_addr: A host/port pair that should be returned if the headers are not in the request
@param original_scheme: A scheme that should be returned if the headers are not in the request
@return: A tuple containing a list [host (string), port (int)] as the first entry and a proto (string) as the second
""" """
if not address_header_name: if not address_header_name:
return original return (original_addr, original_scheme)
# Convert twisted-style headers into dicts
if isinstance(headers, Headers): if isinstance(headers, Headers):
# Convert twisted-style headers into a dict
headers = dict(headers.getAllRawHeaders()) headers = dict(headers.getAllRawHeaders())
# Lowercase all header keys
# Lowercase all header names in the dict headers = {name.lower(): values for name, values in headers.items()}
headers = {name.lower(): values for name, values in headers.items()} else:
# Lowercase (and encode to utf-8 where needed) non-twisted header keys
headers = {name.lower() if isinstance(name, bytes) else name.lower().encode("utf-8"): values for name, values in headers.items()}
address_header_name = address_header_name.lower().encode("utf-8") address_header_name = address_header_name.lower().encode("utf-8")
result = original result_addr = original_addr
result_scheme = original_scheme
if address_header_name in headers: if address_header_name in headers:
address_value = header_value(headers, address_header_name) address_value = header_value(headers, address_header_name)
if ',' in address_value: if ',' in address_value:
address_value = address_value.split(",")[0].strip() address_value = address_value.split(",")[0].strip()
result = [address_value, 0] result_addr = [address_value, 0]
if port_header_name: if port_header_name:
# We only want to parse the X-Forwarded-Port header if we also parsed the X-Forwarded-For # We only want to parse the X-Forwarded-Port header if we also parsed the X-Forwarded-For
...@@ -48,8 +58,13 @@ def parse_x_forwarded_for(headers, ...@@ -48,8 +58,13 @@ def parse_x_forwarded_for(headers,
if port_header_name in headers: if port_header_name in headers:
port_value = header_value(headers, port_header_name) port_value = header_value(headers, port_header_name)
try: try:
result[1] = int(port_value) result_addr[1] = int(port_value)
except ValueError: except ValueError:
pass pass
return result if proto_header_name:
proto_header_name = proto_header_name.lower().encode("utf-8")
if proto_header_name in headers:
result_scheme = header_value(headers, proto_header_name)
return result_addr, result_scheme
...@@ -4,7 +4,7 @@ import logging ...@@ -4,7 +4,7 @@ import logging
import six import six
import time import time
import traceback import traceback
from six.moves.urllib_parse import unquote, urlencode from six.moves.urllib_parse import unquote
from twisted.internet import defer from twisted.internet import defer
from autobahn.twisted.websocket import WebSocketServerProtocol, WebSocketServerFactory, ConnectionDeny from autobahn.twisted.websocket import WebSocketServerProtocol, WebSocketServerFactory, ConnectionDeny
...@@ -57,10 +57,11 @@ class WebSocketProtocol(WebSocketServerProtocol): ...@@ -57,10 +57,11 @@ class WebSocketProtocol(WebSocketServerProtocol):
self.server_addr = None self.server_addr = None
if self.main_factory.proxy_forwarded_address_header: if self.main_factory.proxy_forwarded_address_header:
self.client_addr = parse_x_forwarded_for( self.client_addr, self.client_scheme = parse_x_forwarded_for(
self.http_headers, self.http_headers,
self.main_factory.proxy_forwarded_address_header, self.main_factory.proxy_forwarded_address_header,
self.main_factory.proxy_forwarded_port_header, self.main_factory.proxy_forwarded_port_header,
self.main_factory.proxy_forwarded_proto_header,
self.client_addr self.client_addr
) )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment