Add ForwardedAllowIPS option.

This commit is contained in:
Konstantin Kapustin 2012-07-24 17:45:00 +04:00 committed by benoitc
parent ab5473be92
commit d28366a683
3 changed files with 40 additions and 6 deletions

View File

@ -212,6 +212,14 @@ def validate_string(val):
raise TypeError("Not a string: %s" % val)
return val.strip()
def validate_string_to_list(val):
val = validate_string(val)
if not val:
return []
return [v.strip() for v in val.split(",") if v]
def validate_class(val):
if inspect.isfunction(val) or inspect.ismethod(val):
val = val()
@ -682,6 +690,17 @@ class XForwardedFor(Setting):
address of the client connection to gunicorn via a proxy.
"""
class ForwardedAllowIPS(Setting):
name = "forwarded_allow_ips"
section = "Server Mechanics"
meta = "STRING"
validator = validate_string_to_list
default = "127.0.0.1"
desc = """\
Front-end's IPs from which allowed to handle X-Forwarded-* headers.
(comma separate).
"""
class AccessLog(Setting):
name = "accesslog"
section = "Logging"

View File

@ -66,22 +66,24 @@ def create(req, sock, client, server, cfg):
# authors should be aware that REMOTE_HOST and REMOTE_ADDR
# may not qualify the remote addr:
# http://www.ietf.org/rfc/rfc3875
client = client or "127.0.0.1"
forward = client
forward = client or "127.0.0.1"
url_scheme = "http"
script_name = os.environ.get("SCRIPT_NAME", "")
secure_headers = cfg.secure_scheme_headers
x_forwarded_for_header = cfg.x_forwarded_for_header
if client and client[0] not in cfg.forwarded_allow_ips:
x_forwarded_for_header = None
secure_headers = {}
for hdr_name, hdr_value in req.headers:
if hdr_name == "EXPECT":
# handle expect
if hdr_value.lower() == "100-continue":
sock.send("HTTP/1.1 100 Continue\r\n\r\n")
elif hdr_name == x_forwarded_for_header:
elif x_forwarded_for_header and hdr_name == x_forwarded_for_header:
forward = hdr_value
elif (hdr_name.upper() in secure_headers and
elif secure_headers and (hdr_name.upper() in secure_headers and
hdr_value == secure_headers[hdr_name.upper()]):
url_scheme = "https"
elif hdr_name == "HOST":

View File

@ -56,7 +56,8 @@ class NoConfigApp(Application):
def test_defaults():
c = config.Config()
for s in config.KNOWN_SETTINGS:
t.eq(s.default, c.settings[s.name].get())
t.eq(c.settings[s.name].validator(s.default),
c.settings[s.name].get())
def test_property_access():
c = config.Config()
@ -129,6 +130,17 @@ def test_str_validation():
t.eq(c.proc_name, "foo")
t.raises(TypeError, c.set, "proc_name", 2)
def test_str_to_list_validation():
c = config.Config()
t.eq(c.forwarded_allow_ips, ["127.0.0.1"])
c.set("forwarded_allow_ips", "127.0.0.1,192.168.0.1")
t.eq(c.forwarded_allow_ips, ["127.0.0.1", "192.168.0.1"])
c.set("forwarded_allow_ips", "")
t.eq(c.forwarded_allow_ips, [])
c.set("forwarded_allow_ips", None)
t.eq(c.forwarded_allow_ips, [])
t.raises(TypeError, c.set, "forwarded_allow_ips", 1)
def test_callable_validation():
c = config.Config()
def func(a, b):
@ -153,7 +165,8 @@ def test_app_config():
with AltArgs():
app = NoConfigApp()
for s in config.KNOWN_SETTINGS:
t.eq(s.default, app.cfg.settings[s.name].get())
t.eq(app.cfg.settings[s.name].validator(s.default),
app.cfg.settings[s.name].get())
def test_load_config():
with AltArgs(["prog_name", "-c", cfg_file()]):