mirror of
https://github.com/certbot/certbot.git
synced 2026-07-30 16:14:44 +02:00
Add support and tests for some Nginx config edge cases
1. Match "if" statements 2. Allow special characters in nginx directives when enclosed in single or double quotes.
This commit is contained in:
@@ -3,7 +3,7 @@ import string
|
||||
|
||||
from pyparsing import (
|
||||
Literal, White, Word, alphanums, CharsNotIn, Forward, Group,
|
||||
Optional, OneOrMore, ZeroOrMore, pythonStyleComment)
|
||||
Optional, OneOrMore, Regex, ZeroOrMore, pythonStyleComment)
|
||||
|
||||
|
||||
class RawNginxParser(object):
|
||||
@@ -16,17 +16,21 @@ class RawNginxParser(object):
|
||||
semicolon = Literal(";").suppress()
|
||||
space = White().suppress()
|
||||
key = Word(alphanums + "_/")
|
||||
value = CharsNotIn("{};,")
|
||||
# Matches anything that is not a special character AND any chars in single
|
||||
# or double quotes
|
||||
value = Regex(r"((\".*\")?(\'.*\')?[^\{\};,]?)+")
|
||||
location = CharsNotIn("{};," + string.whitespace)
|
||||
# modifier for location uri [ = | ~ | ~* | ^~ ]
|
||||
modifier = Literal("=") | Literal("~*") | Literal("~") | Literal("^~")
|
||||
|
||||
# rules
|
||||
assignment = (key + Optional(space + value) + semicolon)
|
||||
location_statement = Optional(space + modifier) + Optional(space + location)
|
||||
if_statement = Literal("if") + space + Regex(r"\(.+\)") + space
|
||||
block = Forward()
|
||||
|
||||
block << Group(
|
||||
Group(key + Optional(space + modifier) + Optional(space + location))
|
||||
(Group(key + location_statement) ^ Group(if_statement))
|
||||
+ left_bracket
|
||||
+ Group(ZeroOrMore(Group(assignment) | block))
|
||||
+ right_bracket)
|
||||
|
||||
@@ -84,6 +84,26 @@ class TestRawNginxParser(unittest.TestCase):
|
||||
]]]]]
|
||||
)
|
||||
|
||||
def test_parse_from_file2(self):
|
||||
parsed = load(open(util.get_data_filename('edge_cases.conf')))
|
||||
self.assertEqual(
|
||||
parsed,
|
||||
[[['server'], [['server_name', 'simple']]],
|
||||
[['server'],
|
||||
[['server_name', 'with.if'],
|
||||
[['location', '~', '^/services/.+$'],
|
||||
[[['if', '($request_filename ~* \\.(ttf|woff)$)'],
|
||||
[['add_header', 'Access-Control-Allow-Origin "*"']]]]]]],
|
||||
[['server'],
|
||||
[['server_name', 'with.complicated.headers'],
|
||||
[['location', '~*', '\\.(?:gif|jpe?g|png)$'],
|
||||
[['add_header', 'Pragma public'],
|
||||
['add_header',
|
||||
'Cache-Control \'public, must-revalidate, proxy-revalidate\''
|
||||
' "test,;{}" foo'],
|
||||
['blah', '"hello;world"'],
|
||||
['try_files', '$uri @rewrites']]]]]])
|
||||
|
||||
def test_dump_as_file(self):
|
||||
parsed = load(open(util.get_data_filename('nginx.conf')))
|
||||
parsed[-1][-1].append([['server'],
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
# This is not a valid nginx config file but it tests edge cases in valid nginx syntax
|
||||
|
||||
server {
|
||||
server_name simple;
|
||||
}
|
||||
|
||||
server {
|
||||
server_name with.if;
|
||||
location ~ ^/services/.+$ {
|
||||
if ($request_filename ~* \.(ttf|woff)$) {
|
||||
add_header Access-Control-Allow-Origin "*";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
server_name with.complicated.headers;
|
||||
|
||||
location ~* \.(?:gif|jpe?g|png)$ {
|
||||
|
||||
add_header Pragma public;
|
||||
add_header Cache-Control 'public, must-revalidate, proxy-revalidate' "test,;{}" foo;
|
||||
blah "hello;world";
|
||||
|
||||
try_files $uri @rewrites;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user