123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551 |
- 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 ($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', ['$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)
|