deprecate None value support for app name (#1705)

*  deprecate None value support for app name

* 🚨 cleanup linter issues across the codebase
This commit is contained in:
Harsha Narayana 2019-10-23 21:42:20 +05:30 committed by 7
parent fcdc9c83c5
commit e506c89304
5 changed files with 101 additions and 57 deletions

View File

@ -46,6 +46,13 @@ class Sanic:
# Get name from previous stack frame # Get name from previous stack frame
if name is None: if name is None:
warnings.warn(
"Sanic(name=None) is deprecated and None value support "
"for `name` will be removed in the next release. "
"Please use Sanic(name='your_application_name') instead.",
DeprecationWarning,
stacklevel=2,
)
frame_records = stack()[1] frame_records = stack()[1]
name = getmodulename(frame_records[1]) name = getmodulename(frame_records[1])

View File

@ -8,27 +8,33 @@ from sanic import headers
[ [
("text/plain", ("text/plain", {})), ("text/plain", ("text/plain", {})),
("text/vnd.just.made.this.up ; ", ("text/vnd.just.made.this.up", {})), ("text/vnd.just.made.this.up ; ", ("text/vnd.just.made.this.up", {})),
("text/plain;charset=us-ascii", ("text/plain", {"charset": "us-ascii"})), (
('text/plain ; charset="us-ascii"', ("text/plain", {"charset": "us-ascii"})), "text/plain;charset=us-ascii",
("text/plain", {"charset": "us-ascii"}),
),
(
'text/plain ; charset="us-ascii"',
("text/plain", {"charset": "us-ascii"}),
),
( (
'text/plain ; charset="us-ascii"; another=opt', 'text/plain ; charset="us-ascii"; another=opt',
("text/plain", {"charset": "us-ascii", "another": "opt"}) ("text/plain", {"charset": "us-ascii", "another": "opt"}),
), ),
( (
'attachment; filename="silly.txt"', 'attachment; filename="silly.txt"',
("attachment", {"filename": "silly.txt"}) ("attachment", {"filename": "silly.txt"}),
), ),
( (
'attachment; filename="strange;name"', 'attachment; filename="strange;name"',
("attachment", {"filename": "strange;name"}) ("attachment", {"filename": "strange;name"}),
), ),
( (
'attachment; filename="strange;name";size=123;', 'attachment; filename="strange;name";size=123;',
("attachment", {"filename": "strange;name", "size": "123"}) ("attachment", {"filename": "strange;name", "size": "123"}),
), ),
( (
'form-data; name="files"; filename="fo\\"o;bar\\"', 'form-data; name="files"; filename="fo\\"o;bar\\"',
('form-data', {'name': 'files', 'filename': 'fo"o;bar\\'}) ("form-data", {"name": "files", "filename": 'fo"o;bar\\'})
# cgi.parse_header: # cgi.parse_header:
# ('form-data', {'name': 'files', 'filename': 'fo"o;bar\\'}) # ('form-data', {'name': 'files', 'filename': 'fo"o;bar\\'})
# werkzeug.parse_options_header: # werkzeug.parse_options_header:
@ -39,7 +45,7 @@ from sanic import headers
# Chrome: # Chrome:
# Content-Disposition: form-data; name="foo%22;bar\"; filename="😀" # Content-Disposition: form-data; name="foo%22;bar\"; filename="😀"
'form-data; name="foo%22;bar\\"; filename="😀"', 'form-data; name="foo%22;bar\\"; filename="😀"',
('form-data', {'name': 'foo";bar\\', 'filename': '😀'}) ("form-data", {"name": 'foo";bar\\', "filename": "😀"})
# cgi: ('form-data', {'name': 'foo%22;bar"; filename="😀'}) # cgi: ('form-data', {'name': 'foo%22;bar"; filename="😀'})
# werkzeug: ('form-data', {'name': 'foo%22;bar"; filename='}) # werkzeug: ('form-data', {'name': 'foo%22;bar"; filename='})
), ),
@ -47,11 +53,11 @@ from sanic import headers
# Firefox: # Firefox:
# Content-Disposition: form-data; name="foo\";bar\"; filename="😀" # Content-Disposition: form-data; name="foo\";bar\"; filename="😀"
'form-data; name="foo\\";bar\\"; filename="😀"', 'form-data; name="foo\\";bar\\"; filename="😀"',
('form-data', {'name': 'foo";bar\\', 'filename': '😀'}) ("form-data", {"name": 'foo";bar\\', "filename": "😀"})
# cgi: ('form-data', {'name': 'foo";bar"; filename="😀'}) # cgi: ('form-data', {'name': 'foo";bar"; filename="😀'})
# werkzeug: ('form-data', {'name': 'foo";bar"; filename='}) # werkzeug: ('form-data', {'name': 'foo";bar"; filename='})
), ),
] ],
) )
def test_parse_headers(input, expected): def test_parse_headers(input, expected):
assert headers.parse_content_header(input) == expected assert headers.parse_content_header(input) == expected

View File

@ -8,6 +8,7 @@ try:
except ImportError: except ImportError:
from json import loads from json import loads
def test_custom_context(app): def test_custom_context(app):
@app.middleware("request") @app.middleware("request")
def store(request): def store(request):
@ -21,14 +22,16 @@ def test_custom_context(app):
invalid = request.ctx.missing invalid = request.ctx.missing
except AttributeError as e: except AttributeError as e:
invalid = str(e) invalid = str(e)
return json({ return json(
"user": request.ctx.user, {
"session": request.ctx.session, "user": request.ctx.user,
"has_user": hasattr(request.ctx, "user"), "session": request.ctx.session,
"has_session": hasattr(request.ctx, "session"), "has_user": hasattr(request.ctx, "user"),
"has_missing": hasattr(request.ctx, "missing"), "has_session": hasattr(request.ctx, "session"),
"invalid": invalid "has_missing": hasattr(request.ctx, "missing"),
}) "invalid": invalid,
}
)
request, response = app.test_client.get("/") request, response = app.test_client.get("/")
assert response.json == { assert response.json == {

View File

@ -413,15 +413,15 @@ def test_standard_forwarded(app):
"Forwarded": ( "Forwarded": (
'for=1.1.1.1, for=injected;host="' 'for=1.1.1.1, for=injected;host="'
', for="[::2]";proto=https;host=me.tld;path="/app/";secret=mySecret' ', for="[::2]";proto=https;host=me.tld;path="/app/";secret=mySecret'
',for=broken;;secret=b0rked' ",for=broken;;secret=b0rked"
', for=127.0.0.3;scheme=http;port=1234' ", for=127.0.0.3;scheme=http;port=1234"
), ),
"X-Real-IP": "127.0.0.2", "X-Real-IP": "127.0.0.2",
"X-Forwarded-For": "127.0.1.1", "X-Forwarded-For": "127.0.1.1",
"X-Scheme": "ws", "X-Scheme": "ws",
} }
request, response = app.test_client.get("/", headers=headers) request, response = app.test_client.get("/", headers=headers)
assert response.json == { "for": "127.0.0.2", "proto": "ws" } assert response.json == {"for": "127.0.0.2", "proto": "ws"}
assert request.remote_addr == "127.0.0.2" assert request.remote_addr == "127.0.0.2"
assert request.scheme == "ws" assert request.scheme == "ws"
assert request.server_port == 80 assert request.server_port == 80
@ -433,7 +433,7 @@ def test_standard_forwarded(app):
"proto": "https", "proto": "https",
"host": "me.tld", "host": "me.tld",
"path": "/app/", "path": "/app/",
"secret": "mySecret" "secret": "mySecret",
} }
assert request.remote_addr == "[::2]" assert request.remote_addr == "[::2]"
assert request.server_name == "me.tld" assert request.server_name == "me.tld"
@ -443,7 +443,7 @@ def test_standard_forwarded(app):
# Empty Forwarded header -> use X-headers # Empty Forwarded header -> use X-headers
headers["Forwarded"] = "" headers["Forwarded"] = ""
request, response = app.test_client.get("/", headers=headers) request, response = app.test_client.get("/", headers=headers)
assert response.json == { "for": "127.0.0.2", "proto": "ws" } assert response.json == {"for": "127.0.0.2", "proto": "ws"}
# Header present but not matching anything # Header present but not matching anything
request, response = app.test_client.get("/", headers={"Forwarded": "."}) request, response = app.test_client.get("/", headers={"Forwarded": "."})
@ -451,8 +451,8 @@ def test_standard_forwarded(app):
# Forwarded header present but no matching secret -> use X-headers # Forwarded header present but no matching secret -> use X-headers
headers = { headers = {
"Forwarded": 'for=1.1.1.1;secret=x, for=127.0.0.1', "Forwarded": "for=1.1.1.1;secret=x, for=127.0.0.1",
"X-Real-IP": "127.0.0.2" "X-Real-IP": "127.0.0.2",
} }
request, response = app.test_client.get("/", headers=headers) request, response = app.test_client.get("/", headers=headers)
assert response.json == {"for": "127.0.0.2"} assert response.json == {"for": "127.0.0.2"}
@ -464,7 +464,7 @@ def test_standard_forwarded(app):
assert response.json == { assert response.json == {
"for": "127.0.0.4", "for": "127.0.0.4",
"port": 1234, "port": 1234,
"secret": "mySecret" "secret": "mySecret",
} }
# Test escapes (modify this if you see anyone implementing quoted-pairs) # Test escapes (modify this if you see anyone implementing quoted-pairs)
@ -472,29 +472,29 @@ def test_standard_forwarded(app):
request, response = app.test_client.get("/", headers=headers) request, response = app.test_client.get("/", headers=headers)
assert response.json == { assert response.json == {
"for": "test", "for": "test",
"quoted": '\\,x=x;y=\\', "quoted": "\\,x=x;y=\\",
"secret": "mySecret" "secret": "mySecret",
} }
# Secret insulated by malformed field #1 # Secret insulated by malformed field #1
headers = {"Forwarded": 'for=test;secret=mySecret;b0rked;proto=wss;'} headers = {"Forwarded": "for=test;secret=mySecret;b0rked;proto=wss;"}
request, response = app.test_client.get("/", headers=headers) request, response = app.test_client.get("/", headers=headers)
assert response.json == {"for": "test", "secret": "mySecret"} assert response.json == {"for": "test", "secret": "mySecret"}
# Secret insulated by malformed field #2 # Secret insulated by malformed field #2
headers = {"Forwarded": 'for=test;b0rked;secret=mySecret;proto=wss'} headers = {"Forwarded": "for=test;b0rked;secret=mySecret;proto=wss"}
request, response = app.test_client.get("/", headers=headers) request, response = app.test_client.get("/", headers=headers)
assert response.json == {"proto": "wss", "secret": "mySecret"} assert response.json == {"proto": "wss", "secret": "mySecret"}
# Unexpected termination should not lose existing acceptable values # Unexpected termination should not lose existing acceptable values
headers = {"Forwarded": 'b0rked;secret=mySecret;proto=wss'} headers = {"Forwarded": "b0rked;secret=mySecret;proto=wss"}
request, response = app.test_client.get("/", headers=headers) request, response = app.test_client.get("/", headers=headers)
assert response.json == {"proto": "wss", "secret": "mySecret"} assert response.json == {"proto": "wss", "secret": "mySecret"}
# Field normalization # Field normalization
headers = { headers = {
"Forwarded": 'PROTO=WSS;BY="CAFE::8000";FOR=unknown;PORT=X;HOST="A:2";' "Forwarded": 'PROTO=WSS;BY="CAFE::8000";FOR=unknown;PORT=X;HOST="A:2";'
'PATH="/With%20Spaces%22Quoted%22/sanicApp?key=val";SECRET=mySecret' 'PATH="/With%20Spaces%22Quoted%22/sanicApp?key=val";SECRET=mySecret'
} }
request, response = app.test_client.get("/", headers=headers) request, response = app.test_client.get("/", headers=headers)
assert response.json == { assert response.json == {
@ -507,7 +507,7 @@ def test_standard_forwarded(app):
# Using "by" field as secret # Using "by" field as secret
app.config.FORWARDED_SECRET = "_proxySecret" app.config.FORWARDED_SECRET = "_proxySecret"
headers = {"Forwarded": 'for=1.2.3.4; by=_proxySecret'} headers = {"Forwarded": "for=1.2.3.4; by=_proxySecret"}
request, response = app.test_client.get("/", headers=headers) request, response = app.test_client.get("/", headers=headers)
assert response.json == {"for": "1.2.3.4", "by": "_proxySecret"} assert response.json == {"for": "1.2.3.4", "by": "_proxySecret"}
@ -525,15 +525,15 @@ async def test_standard_forwarded_asgi(app):
"Forwarded": ( "Forwarded": (
'for=1.1.1.1, for=injected;host="' 'for=1.1.1.1, for=injected;host="'
', for="[::2]";proto=https;host=me.tld;path="/app/";secret=mySecret' ', for="[::2]";proto=https;host=me.tld;path="/app/";secret=mySecret'
',for=broken;;secret=b0rked' ",for=broken;;secret=b0rked"
', for=127.0.0.3;scheme=http;port=1234' ", for=127.0.0.3;scheme=http;port=1234"
), ),
"X-Real-IP": "127.0.0.2", "X-Real-IP": "127.0.0.2",
"X-Forwarded-For": "127.0.1.1", "X-Forwarded-For": "127.0.1.1",
"X-Scheme": "ws", "X-Scheme": "ws",
} }
request, response = await app.asgi_client.get("/", headers=headers) request, response = await app.asgi_client.get("/", headers=headers)
assert response.json() == { "for": "127.0.0.2", "proto": "ws" } assert response.json() == {"for": "127.0.0.2", "proto": "ws"}
assert request.remote_addr == "127.0.0.2" assert request.remote_addr == "127.0.0.2"
assert request.scheme == "ws" assert request.scheme == "ws"
assert request.server_port == 80 assert request.server_port == 80
@ -545,7 +545,7 @@ async def test_standard_forwarded_asgi(app):
"proto": "https", "proto": "https",
"host": "me.tld", "host": "me.tld",
"path": "/app/", "path": "/app/",
"secret": "mySecret" "secret": "mySecret",
} }
assert request.remote_addr == "[::2]" assert request.remote_addr == "[::2]"
assert request.server_name == "me.tld" assert request.server_name == "me.tld"
@ -555,16 +555,18 @@ async def test_standard_forwarded_asgi(app):
# Empty Forwarded header -> use X-headers # Empty Forwarded header -> use X-headers
headers["Forwarded"] = "" headers["Forwarded"] = ""
request, response = await app.asgi_client.get("/", headers=headers) request, response = await app.asgi_client.get("/", headers=headers)
assert response.json() == { "for": "127.0.0.2", "proto": "ws" } assert response.json() == {"for": "127.0.0.2", "proto": "ws"}
# Header present but not matching anything # Header present but not matching anything
request, response = await app.asgi_client.get("/", headers={"Forwarded": "."}) request, response = await app.asgi_client.get(
"/", headers={"Forwarded": "."}
)
assert response.json() == {} assert response.json() == {}
# Forwarded header present but no matching secret -> use X-headers # Forwarded header present but no matching secret -> use X-headers
headers = { headers = {
"Forwarded": 'for=1.1.1.1;secret=x, for=127.0.0.1', "Forwarded": "for=1.1.1.1;secret=x, for=127.0.0.1",
"X-Real-IP": "127.0.0.2" "X-Real-IP": "127.0.0.2",
} }
request, response = await app.asgi_client.get("/", headers=headers) request, response = await app.asgi_client.get("/", headers=headers)
assert response.json() == {"for": "127.0.0.2"} assert response.json() == {"for": "127.0.0.2"}
@ -576,7 +578,7 @@ async def test_standard_forwarded_asgi(app):
assert response.json() == { assert response.json() == {
"for": "127.0.0.4", "for": "127.0.0.4",
"port": 1234, "port": 1234,
"secret": "mySecret" "secret": "mySecret",
} }
# Test escapes (modify this if you see anyone implementing quoted-pairs) # Test escapes (modify this if you see anyone implementing quoted-pairs)
@ -584,29 +586,29 @@ async def test_standard_forwarded_asgi(app):
request, response = await app.asgi_client.get("/", headers=headers) request, response = await app.asgi_client.get("/", headers=headers)
assert response.json() == { assert response.json() == {
"for": "test", "for": "test",
"quoted": '\\,x=x;y=\\', "quoted": "\\,x=x;y=\\",
"secret": "mySecret" "secret": "mySecret",
} }
# Secret insulated by malformed field #1 # Secret insulated by malformed field #1
headers = {"Forwarded": 'for=test;secret=mySecret;b0rked;proto=wss;'} headers = {"Forwarded": "for=test;secret=mySecret;b0rked;proto=wss;"}
request, response = await app.asgi_client.get("/", headers=headers) request, response = await app.asgi_client.get("/", headers=headers)
assert response.json() == {"for": "test", "secret": "mySecret"} assert response.json() == {"for": "test", "secret": "mySecret"}
# Secret insulated by malformed field #2 # Secret insulated by malformed field #2
headers = {"Forwarded": 'for=test;b0rked;secret=mySecret;proto=wss'} headers = {"Forwarded": "for=test;b0rked;secret=mySecret;proto=wss"}
request, response = await app.asgi_client.get("/", headers=headers) request, response = await app.asgi_client.get("/", headers=headers)
assert response.json() == {"proto": "wss", "secret": "mySecret"} assert response.json() == {"proto": "wss", "secret": "mySecret"}
# Unexpected termination should not lose existing acceptable values # Unexpected termination should not lose existing acceptable values
headers = {"Forwarded": 'b0rked;secret=mySecret;proto=wss'} headers = {"Forwarded": "b0rked;secret=mySecret;proto=wss"}
request, response = await app.asgi_client.get("/", headers=headers) request, response = await app.asgi_client.get("/", headers=headers)
assert response.json() == {"proto": "wss", "secret": "mySecret"} assert response.json() == {"proto": "wss", "secret": "mySecret"}
# Field normalization # Field normalization
headers = { headers = {
"Forwarded": 'PROTO=WSS;BY="CAFE::8000";FOR=unknown;PORT=X;HOST="A:2";' "Forwarded": 'PROTO=WSS;BY="CAFE::8000";FOR=unknown;PORT=X;HOST="A:2";'
'PATH="/With%20Spaces%22Quoted%22/sanicApp?key=val";SECRET=mySecret' 'PATH="/With%20Spaces%22Quoted%22/sanicApp?key=val";SECRET=mySecret'
} }
request, response = await app.asgi_client.get("/", headers=headers) request, response = await app.asgi_client.get("/", headers=headers)
assert response.json() == { assert response.json() == {
@ -619,7 +621,7 @@ async def test_standard_forwarded_asgi(app):
# Using "by" field as secret # Using "by" field as secret
app.config.FORWARDED_SECRET = "_proxySecret" app.config.FORWARDED_SECRET = "_proxySecret"
headers = {"Forwarded": 'for=1.2.3.4; by=_proxySecret'} headers = {"Forwarded": "for=1.2.3.4; by=_proxySecret"}
request, response = await app.asgi_client.get("/", headers=headers) request, response = await app.asgi_client.get("/", headers=headers)
assert response.json() == {"for": "1.2.3.4", "by": "_proxySecret"} assert response.json() == {"for": "1.2.3.4", "by": "_proxySecret"}
@ -813,11 +815,14 @@ def test_forwarded_scheme(app):
assert request.scheme == "http" assert request.scheme == "http"
request, response = app.test_client.get( request, response = app.test_client.get(
"/", headers={"X-Forwarded-For": "127.1.2.3", "X-Forwarded-Proto": "https"} "/",
headers={"X-Forwarded-For": "127.1.2.3", "X-Forwarded-Proto": "https"},
) )
assert request.scheme == "https" assert request.scheme == "https"
request, response = app.test_client.get("/", headers={"X-Forwarded-For": "127.1.2.3", "X-Scheme": "https"}) request, response = app.test_client.get(
"/", headers={"X-Forwarded-For": "127.1.2.3", "X-Scheme": "https"}
)
assert request.scheme == "https" assert request.scheme == "https"
@ -1872,7 +1877,7 @@ def test_request_server_name_in_host_header(app):
request, response = app.test_client.get( request, response = app.test_client.get(
"/", headers={"Host": "mal_formed"} "/", headers={"Host": "mal_formed"}
) )
assert request.server_name == None # For now (later maybe 127.0.0.1) assert request.server_name == None # For now (later maybe 127.0.0.1)
def test_request_server_name_forwarded(app): def test_request_server_name_forwarded(app):
@ -1883,7 +1888,11 @@ def test_request_server_name_forwarded(app):
app.config.PROXIES_COUNT = 1 app.config.PROXIES_COUNT = 1
request, response = app.test_client.get( request, response = app.test_client.get(
"/", "/",
headers={"Host": "my-server:5555", "X-Forwarded-For": "127.1.2.3", "X-Forwarded-Host": "your-server"}, headers={
"Host": "my-server:5555",
"X-Forwarded-For": "127.1.2.3",
"X-Forwarded-Host": "your-server",
},
) )
assert request.server_name == "your-server" assert request.server_name == "your-server"
@ -1925,7 +1934,12 @@ def test_request_server_port_forwarded(app):
app.config.PROXIES_COUNT = 1 app.config.PROXIES_COUNT = 1
request, response = app.test_client.get( request, response = app.test_client.get(
"/", headers={"Host": "my-server:5555", "X-Forwarded-For": "127.1.2.3", "X-Forwarded-Port": "4444"} "/",
headers={
"Host": "my-server:5555",
"X-Forwarded-For": "127.1.2.3",
"X-Forwarded-Port": "4444",
},
) )
assert request.server_port == 4444 assert request.server_port == 4444
@ -1948,7 +1962,10 @@ def test_server_name_and_url_for(app):
app.config.SERVER_NAME = "my-server" app.config.SERVER_NAME = "my-server"
assert app.url_for("handler", _external=True) == "http://my-server/foo" assert app.url_for("handler", _external=True) == "http://my-server/foo"
request, response = app.test_client.get("/foo") request, response = app.test_client.get("/foo")
assert request.url_for("handler") == f"http://my-server:{app.test_client.port}/foo" assert (
request.url_for("handler")
== f"http://my-server:{app.test_client.port}/foo"
)
app.config.SERVER_NAME = "https://my-server/path" app.config.SERVER_NAME = "https://my-server/path"
request, response = app.test_client.get("/foo") request, response = app.test_client.get("/foo")
@ -1969,7 +1986,12 @@ def test_url_for_with_forwarded_request(app):
app.config.SERVER_NAME = "my-server" app.config.SERVER_NAME = "my-server"
app.config.PROXIES_COUNT = 1 app.config.PROXIES_COUNT = 1
request, response = app.test_client.get( request, response = app.test_client.get(
"/", headers={"X-Forwarded-For": "127.1.2.3", "X-Forwarded-Proto": "https", "X-Forwarded-Port": "6789"} "/",
headers={
"X-Forwarded-For": "127.1.2.3",
"X-Forwarded-Proto": "https",
"X-Forwarded-Port": "6789",
},
) )
assert app.url_for("view_name") == "/another_view" assert app.url_for("view_name") == "/another_view"
assert ( assert (
@ -1981,7 +2003,12 @@ def test_url_for_with_forwarded_request(app):
) )
request, response = app.test_client.get( request, response = app.test_client.get(
"/", headers={"X-Forwarded-For": "127.1.2.3", "X-Forwarded-Proto": "https", "X-Forwarded-Port": "443"} "/",
headers={
"X-Forwarded-For": "127.1.2.3",
"X-Forwarded-Proto": "https",
"X-Forwarded-Port": "443",
},
) )
assert request.url_for("view_name") == "https://my-server/another_view" assert request.url_for("view_name") == "https://my-server/another_view"

View File

@ -91,6 +91,7 @@ async def test_trigger_before_events_create_server(app):
assert hasattr(app, "db") assert hasattr(app, "db")
assert isinstance(app.db, MySanicDb) assert isinstance(app.db, MySanicDb)
def test_create_server_trigger_events(app): def test_create_server_trigger_events(app):
"""Test if create_server can trigger server events""" """Test if create_server can trigger server events"""