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:
yan
2015-05-18 17:58:28 -04:00
parent 1ada2cab15
commit 24f9da5275
3 changed files with 54 additions and 3 deletions
+7 -3
View File
@@ -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;
}
}