gixy/tests/parser/test_raw_parser.py

557 lines
12 KiB
Python

from nose.tools import assert_equals
from gixy.parser.raw_parser import *
def test_directive():
config = '''
access_log syslog:server=127.0.0.1,tag=nginx_sentry toolsformat;
user http;
internal;
set $foo "bar";
set $foo 'bar';
proxy_pass http://unix:/run/sock.socket;
rewrite ^/([a-zA-Z0-9]+)$ /$1/${arg_v}.pb break;
server_name some.tld ~^(www\.)?podberi.(?:ru|com|ua)$
~^(www\.)?guru.yandex.ru$;
'''
expected = [
['access_log', 'syslog:server=127.0.0.1,tag=nginx_sentry', 'toolsformat'],
['user', 'http'],
['internal'],
['set', '$foo', 'bar'],
['set', '$foo', 'bar'],
['proxy_pass', 'http://unix:/run/sock.socket'],
['rewrite', '^/([a-zA-Z0-9]+)$', '/$1/${arg_v}.pb', 'break'],
['server_name', 'some.tld', '~^(www\.)?podberi.(?:ru|com|ua)$', '~^(www\.)?guru.yandex.ru$']
]
assert_config(config, expected)
def test_block():
config = '''
http {
}
'''
expected = [['http', [], []]]
assert_config(config, expected)
def test_block_with_child():
config = '''
http {
gzip on;
}
'''
expected = [['http', [], [['gzip', 'on']]]]
assert_config(config, expected)
def test_location_simple():
config = '''
location / {
}
location = /foo {
}
location ~ ^/bar {
}
location ~* ^/baz$ {
}
location ^~ ^/bazz {
}
# Whitespace may be omitted:((
location ~\.(js|css)$ {
}
'''
expected = [['location', ['/'], []],
['location', ['=', '/foo'], []],
['location', ['~', '^/bar'], []],
['location', ['~*', '^/baz$'], []],
['location', ['^~', '^/bazz'], []],
['Whitespace may be omitted:(('],
['location', ['~', '\.(js|css)$'], []]]
assert_config(config, expected)
def test_quoted_strings():
config = '''
some_sq '\\'la\\.\\/\\"';
some_dq '\\'la\\.\\/\\"';
'''
expected = [['some_sq', '\'la\\.\\/\"'],
['some_dq', '\'la\\.\\/\"']]
assert_config(config, expected)
def test_location_child():
config = '''
location = /foo {
proxy_pass http://unix:/run/sock.socket;
}
'''
expected = [['location', ['=', '/foo'], [
['proxy_pass', 'http://unix:/run/sock.socket']
]]]
assert_config(config, expected)
def test_nested_location():
config = '''
location ~* ^/foo {
location = /foo/bar {
internal;
proxy_pass http://any.yandex.ru;
}
location = /foo/baz {
proxy_pass upstream;
}
}
'''
expected = [['location', ['~*', '^/foo'], [
['location', ['=', '/foo/bar'], [
['internal'],
['proxy_pass', 'http://any.yandex.ru']
]],
['location', ['=', '/foo/baz'], [
['proxy_pass', 'upstream']
]],
]]]
assert_config(config, expected)
def test_hash_block():
config = '''
geo $geo {
default 0;
127.0.0.1 2;
192.168.1.0/24 1;
10.1.0.0/16 1;
::1 2;
2001:0db8::/32 1;
}
'''
expected = [['geo', ['$geo'], [
['default', '0'],
['127.0.0.1', '2'],
['192.168.1.0/24', '1'],
['10.1.0.0/16', '1'],
['::1', '2'],
['2001:0db8::/32', '1']
]]]
assert_config(config, expected)
def test_hash_block_in_location():
config = '''
location /iphone/ {
types {
text/html html htm shtml;
application/json json;
application/rss+xml rss;
text/vnd.sun.j2me.app-descriptor jad;
}
}
'''
expected = [['location', ['/iphone/'], [
['types', [], [
['text/html', 'html', 'htm', 'shtml'],
['application/json', 'json'],
['application/rss+xml', 'rss'],
['text/vnd.sun.j2me.app-descriptor', 'jad']
]],
]]]
assert_config(config, expected)
def test_named_location():
config = '''
location @foo {
proxy_pass http://any.yandex.ru;
}
'''
expected = [['location', ['@foo'], [
['proxy_pass', 'http://any.yandex.ru']
]]]
assert_config(config, expected)
def test_if():
config = '''
# http://nginx.org/ru/docs/http/ngx_http_rewrite_module.html#if
if ($http_user_agent ~ MSIE) {
rewrite ^(.*)$ /msie/$1 break;
}
if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
set $id $1;
}
if ($request_method = POST) {
return 405;
}
if ($slow) {
limit_rate 10k;
}
if ($invalid_referer) {
return 403;
}
if (!-e "/var/data/$dataset") {
return 503;
}
if ($https_or_slb = (by_\(sl\)b|https)) {
}
if ($host ~* (lori|rage2)\.yandex\.(ru|ua|com|com\.tr)) {
set $x_frame_options ALLOW;
}
if ($request_filename ~* ^.*?/(\d+_)([^/]+)$) {
}
if ($http_user_agent ~* "^WordPress.*; verifying pingback") {
}
if ($foo = "BAR") { rewrite ^(.*)$ /bar; }
'''
expected = [
['http://nginx.org/ru/docs/http/ngx_http_rewrite_module.html#if'],
['if', ['$http_user_agent', '~', 'MSIE'], [
['rewrite', '^(.*)$', '/msie/$1', 'break']
]],
['if', ['$http_cookie', '~*', 'id=([^;]+)(?:;|$)'], [
['set', '$id', '$1']
]],
['if', ['$request_method', '=', 'POST'], [
['return', '405']
]],
['if', ['$slow'], [
['limit_rate', '10k']
]],
['if', ['$invalid_referer'], [
['return', '403']
]],
['if', ['!-e', '/var/data/$dataset'], [
['return', '503']
]],
['if', ['$https_or_slb', '=', '(by_\(sl\)b|https)'], [
]],
['if', ['$host', '~*', '(lori|rage2)\.yandex\.(ru|ua|com|com\.tr)'], [
['set', '$x_frame_options', 'ALLOW']
]],
['if', ['$request_filename', '~*', '^.*?/(\d+_)([^/]+)$'], [
]],
['if', ['$http_user_agent', '~*', '^WordPress.*; verifying pingback'], [
]],
['if', ['$foo', '=', 'BAR'], [
['rewrite', '^(.*)$', '/bar']
]]
]
assert_config(config, expected)
def test_hash_block_map():
config = '''
# http://nginx.org/ru/docs/http/ngx_http_map_module.html
map $http_host $name {
hostnames;
default 0;
example.com 1;
*.example.com 1;
example.org 2;
*.example.org 2;
.example.net 3;
wap.* 4;
}
map $http_user_agent $mobile {
default 0;
"~Opera Mini" 1;
}
'''
expected = [
['http://nginx.org/ru/docs/http/ngx_http_map_module.html'],
['map', ['$http_host', '$name'], [
['hostnames'],
['default', '0'],
['example.com', '1'],
['*.example.com', '1'],
['example.org', '2'],
['*.example.org', '2'],
['.example.net', '3'],
['wap.*', '4'],
]],
['map', ['$http_user_agent', '$mobile'], [
['default', '0'],
['~Opera Mini', '1'],
]]
]
assert_config(config, expected)
def test_upstream():
config = '''
# http://nginx.org/ru/docs/http/ngx_http_upstream_module.html
upstream backend {
server backend1.example.com weight=5;
server backend2.example.com:8080;
server unix:/tmp/backend3;
server backup1.example.com:8080 backup;
server backup2.example.com:8080 backup;
}
server {
location / {
proxy_pass http://backend;
}
}
'''
expected = [
['http://nginx.org/ru/docs/http/ngx_http_upstream_module.html'],
['upstream', ['backend'], [
['server', 'backend1.example.com', 'weight=5'],
['server', 'backend2.example.com:8080'],
['server', 'unix:/tmp/backend3'],
['server', 'backup1.example.com:8080', 'backup'],
['server', 'backup2.example.com:8080', 'backup'],
]],
['server', [], [
['location', ['/'], [
['proxy_pass', 'http://backend']
]]
]]]
assert_config(config, expected)
def test_issue_8():
config = '''
# http://nginx.org/ru/docs/http/ngx_http_upstream_module.html
if ($http_referer ~* (\.(ru|ua|by|kz)/(pages/music|partners/|page-no-rights\.xml)) ) {
set $temp A;
}
'''
expected = [
['http://nginx.org/ru/docs/http/ngx_http_upstream_module.html'],
['if', ['$http_referer', '~*', '(\.(ru|ua|by|kz)/(pages/music|partners/|page-no-rights\.xml))'], [
['set', '$temp', 'A']
]]
]
assert_config(config, expected)
def test_issue_11():
config = '''
init_by_lua_block {
tvm = require "nginx.tvm"
}
'''
expected = [
['init_by_lua_block', [], ['tvm', '=', 'require', '"nginx.tvm"']]
]
assert_config(config, expected)
def test_lua_block():
config = '''
# https://github.com/openresty/lua-nginx-module#typical-uses
location = /lua {
# MIME type determined by default_type:
default_type 'text/plain';
content_by_lua_block {
local res = ngx.location.capture("/some_other_location")
if res then
ngx.say("status: ", res.status)
ngx.say("body:")
ngx.print(res.body)
end
}
}
'''
expected = [
['https://github.com/openresty/lua-nginx-module#typical-uses'],
['location', ['=', '/lua'], [
['MIME type determined by default_type:'],
['default_type', 'text/plain'],
['content_by_lua_block', [], [
'local', 'res', '=', 'ngx.location.capture(', '"/some_other_location"', ')',
'if', 'res', 'then',
'ngx.say(', '"status: "', ',', 'res.status)',
'ngx.say(', '"body:"', ')',
'ngx.print(res.body)',
'end']]
]]
]
assert_config(config, expected)
def test_lua_block_brackets():
config = '''
location = /foo {
rewrite_by_lua_block {
res = ngx.location.capture("/memc",
{ args = { cmd = "incr", key = ngx.var.uri } }
)
}
proxy_pass http://blah.blah.com;
}
'''
expected = [
['location', ['=', '/foo'], [
['rewrite_by_lua_block', [], [
'res', '=', 'ngx.location.capture(', '"/memc"', ',',
['args', '=', ['cmd', '=', '"incr"', ',', 'key', '=', 'ngx.var.uri']],
')']],
['proxy_pass', 'http://blah.blah.com']
]]
]
assert_config(config, expected)
def test_file_delims():
config = '''
# configuration file /etc/nginx/nginx.conf:
http {
include sites/*.conf;
}
# configuration file /etc/nginx/sites/default.conf:
server {
}
'''
expected = [
['/etc/nginx/nginx.conf'],
['http', [], [
['include', 'sites/*.conf']
]],
['/etc/nginx/sites/default.conf'],
['server', [], []]
]
assert_config(config, expected)
def test_comments():
config = '''
# Some comment
add_header X-Some-Comment some;
#
# Comment with padding
#
add_header X-Padding-Comment padding;
#
add_header X-Blank-Comment blank;
'''
expected = [
['Some comment'],
['add_header', 'X-Some-Comment', 'some'],
[''],
['Comment with padding'],
[''],
['add_header', 'X-Padding-Comment', 'padding'],
[''],
['add_header', 'X-Blank-Comment', 'blank'],
]
assert_config(config, expected)
def test_upstream_dot():
config = '''
upstream test.mysite.com {
server 127.0.0.1:9009;
}
'''
expected = [
['upstream', ['test.mysite.com'], [
['server', '127.0.0.1:9009']
]],
]
assert_config(config, expected)
def test_empty_config():
config = '''
'''
expected = []
assert_config(config, expected)
def test_utfbom_decoding():
config = b'''\xef\xbb\xbf
add_header X-Test "Windows-1251";
'''
expected = [
['add_header', 'X-Test', 'Windows-1251']
]
assert_config(config, expected)
def test_national_comment_decoding():
config = b'''
# \xeb\xff-\xeb\xff-\xeb\xff = Lya-lya-lya
add_header X-Test "Windows-1251";
'''
actual = RawParser().parse(config)
assert_equals(len(actual.asList()), 2)
def assert_config(config, expected):
actual = RawParser().parse(config)
assert_equals(actual.asList(), expected)