def _comment_out_directive(block, location, include_location): """Comment out the line at location, with a note of explanation.""" comment_message = ' duplicated in {0}'.format(include_location) # add the end comment # create a dumpable object out of block[location] (so it includes the ;) directive = block[location] new_dir_block = nginxparser.UnspacedList([]) # just a wrapper new_dir_block.append(directive) dumped = nginxparser.dumps(new_dir_block) commented = dumped + ' #' + comment_message # add the comment directly to the one-line string new_dir = nginxparser.loads(commented) # reload into UnspacedList # add the beginning comment insert_location = 0 if new_dir[0].spaced[0] != new_dir[0][ 0]: # if there's whitespace at the beginning insert_location = 1 new_dir[0].spaced.insert(insert_location, "# ") # comment out the line new_dir[0].spaced.append( ";") # directly add in the ;, because now dumping won't work properly dumped = nginxparser.dumps(new_dir) new_dir = nginxparser.loads(dumped) # reload into an UnspacedList block[location] = new_dir[ 0] # set the now-single-line-comment directive back in place
def test_issue_518(self): parsed = loads('if ($http_accept ~* "webp") { set $webp "true"; }') self.assertEqual(parsed, [ [['if', '($http_accept ~* "webp")'], [['set', '$webp "true"']]] ])
def test_comment_out_directive(self): server_block = nginxparser.loads(""" server { listen 80; root /var/www/html; index star.html; server_name *.functorkitten.xyz; ssl_session_timeout 1440m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; }""") block = server_block[0][1] from certbot_nginx.parser import _comment_out_directive _comment_out_directive(block, 4, "blah1") _comment_out_directive(block, 5, "blah2") _comment_out_directive(block, 6, "blah3") self.assertEqual(block.spaced, [ ['\n ', 'listen', ' ', '80'], ['\n ', 'root', ' ', '/var/www/html'], ['\n ', 'index', ' ', 'star.html'], ['\n\n ', 'server_name', ' ', '*.functorkitten.xyz'], ['\n ', '#', ' ssl_session_timeout 1440m; # duplicated in blah1'], [' ', '#', ' ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # duplicated in blah2'], ['\n\n ', '#', ' ssl_prefer_server_ciphers on; # duplicated in blah3'], '\n '])
def test_add_header(self): # see issue #3798 parsed = loads('add_header Cache-Control no-cache,no-store,must-revalidate,max-age=0;') self.assertEqual(parsed, [ ['add_header', 'Cache-Control', 'no-cache,no-store,must-revalidate,max-age=0'] ])
def test_variable_name(self): parsed = loads('try_files /typo3temp/tx_ncstaticfilecache/' '$host${request_uri}index.html @nocache;') self.assertEqual(parsed, [[ 'try_files', '/typo3temp/tx_ncstaticfilecache/$host${request_uri}index.html', '@nocache' ]])
def test_variable_name(self): parsed = loads('try_files /typo3temp/tx_ncstaticfilecache/' '$host${request_uri}index.html @nocache;') self.assertEqual(parsed, [ ['try_files', '/typo3temp/tx_ncstaticfilecache/$host${request_uri}index.html', '@nocache'] ])
def test_comment_in_block(self): parsed = loads("""http { # server{ }""") self.assertEqual(parsed, [ [['http'], [['#', ' server{']]] ])
def test_access_log(self): # see issue #3798 parsed = loads('access_log syslog:server=unix:/dev/log,facility=auth,' 'tag=nginx_post,severity=info custom;') self.assertEqual(parsed, [[ 'access_log', 'syslog:server=unix:/dev/log,facility=auth,tag=nginx_post,severity=info', 'custom' ]])
def test_access_log(self): # see issue #3798 parsed = loads('access_log syslog:server=unix:/dev/log,facility=auth,' 'tag=nginx_post,severity=info custom;') self.assertEqual(parsed, [ ['access_log', 'syslog:server=unix:/dev/log,facility=auth,tag=nginx_post,severity=info', 'custom'] ])
def test_edge_cases(self): # quotes parsed = loads(r'"hello\""; # blah "heh heh"') self.assertEqual(parsed, [['"hello\\""'], ['#', ' blah "heh heh"']]) # empty var as block parsed = loads(r"${}") self.assertEqual(parsed, [[['$'], []]]) # if with comment parsed = loads("""if ($http_cookie ~* "id=([^;]+)(?:;|$)") { # blah ) }""") self.assertEqual( parsed, [[['if', '($http_cookie', '~*', '"id=([^;]+)(?:;|$)")'], [['#', ' blah )']]]]) # end paren test = """ one"test"; ("two"); "test")red; "test")"blue"; "test")"three; (one"test")one; one"; one"test; one"test"one; """ parsed = loads(test) self.assertEqual( parsed, [['one"test"'], ['("two")'], ['"test")red'], ['"test")"blue"'], ['"test")"three'], ['(one"test")one'], ['one"'], ['one"test'], ['one"test"one']]) self.assertRaises(ParseException, loads, r'"test"one;') # fails self.assertRaises(ParseException, loads, r'"test;') # fails # newlines test = """ server_name foo.example.com bar.example.com \ baz.example.com qux.example.com; server_name foo.example.com bar.example.com baz.example.com qux.example.com; """ parsed = loads(test) self.assertEqual( parsed, [[ 'server_name', 'foo.example.com', 'bar.example.com', 'baz.example.com', 'qux.example.com' ], [ 'server_name', 'foo.example.com', 'bar.example.com', 'baz.example.com', 'qux.example.com' ]]) # variable weirdness parsed = loads("directive $var;") self.assertEqual(parsed, [['directive', '$var']]) self.assertRaises(ParseException, loads, "server {server_name test.com};") self.assertRaises(ParseException, loads, "directive ${var};")
def test_edge_cases(self): # quotes parsed = loads(r'"hello\""; # blah "heh heh"') self.assertEqual(parsed, [['"hello\\""'], ['#', ' blah "heh heh"']]) # if with comment parsed = loads("""if ($http_cookie ~* "id=([^;]+)(?:;|$)") { # blah ) }""") self.assertEqual(parsed, [[['if', '($http_cookie', '~*', '"id=([^;]+)(?:;|$)")'], [['#', ' blah )']]]]) # end paren test = """ one"test"; ("two"); "test")red; "test")"blue"; "test")"three; (one"test")one; one"; one"test; one"test"one; """ parsed = loads(test) self.assertEqual(parsed, [ ['one"test"'], ['("two")'], ['"test")red'], ['"test")"blue"'], ['"test")"three'], ['(one"test")one'], ['one"'], ['one"test'], ['one"test"one'] ]) self.assertRaises(ParseException, loads, r'"test"one;') # fails self.assertRaises(ParseException, loads, r'"test;') # fails # newlines test = """ server_name foo.example.com bar.example.com \ baz.example.com qux.example.com; server_name foo.example.com bar.example.com baz.example.com qux.example.com; """ parsed = loads(test) self.assertEqual(parsed, [ ['server_name', 'foo.example.com', 'bar.example.com', 'baz.example.com', 'qux.example.com'], ['server_name', 'foo.example.com', 'bar.example.com', 'baz.example.com', 'qux.example.com'] ]) # variable weirdness parsed = loads("directive $var ${var} $ ${};") self.assertEqual(parsed, [['directive', '$var', '${var}', '$', '${}']]) self.assertRaises(ParseException, loads, "server {server_name test.com};") self.assertEqual(loads("blag${dfgdfg};"), [['blag${dfgdfg}']]) self.assertRaises(ParseException, loads, "blag${dfgdf{g};")
def _comment_out_directive(block, location, include_location): """Comment out the line at location, with a note of explanation.""" comment_message = ' duplicated in {0}'.format(include_location) # add the end comment # create a dumpable object out of block[location] (so it includes the ;) directive = block[location] new_dir_block = nginxparser.UnspacedList([]) # just a wrapper new_dir_block.append(directive) dumped = nginxparser.dumps(new_dir_block) commented = dumped + ' #' + comment_message # add the comment directly to the one-line string new_dir = nginxparser.loads(commented) # reload into UnspacedList # add the beginning comment insert_location = 0 if new_dir[0].spaced[0] != new_dir[0][0]: # if there's whitespace at the beginning insert_location = 1 new_dir[0].spaced.insert(insert_location, "# ") # comment out the line new_dir[0].spaced.append(";") # directly add in the ;, because now dumping won't work properly dumped = nginxparser.dumps(new_dir) new_dir = nginxparser.loads(dumped) # reload into an UnspacedList block[location] = new_dir[0] # set the now-single-line-comment directive back in place
def roundtrip(stuff): success = True for t in stuff: print t if not os.path.isfile(t): continue with open(t, "r") as f: config = f.read() try: if nginxparser.dumps(nginxparser.loads(config)) != config: print("Failed parsing round-trip for {0}".format(t)) success = False except Exception as e: print("Failed parsing {0} ({1})".format(t, e)) success = False return success
def test_weird_blocks(self): test = r""" if ($http_user_agent ~ MSIE) { rewrite ^(.*)$ /msie/$1 break; } if ($http_cookie ~* "id=([^;]+)(?:;|$)") { set $id $1; } if ($request_method = POST) { return 405; } if ($request_method) { return 403; } if ($args ~ post=140){ rewrite ^ http://example.com/; } location ~ ^/users/(.+\.(?:gif|jpe?g|png))$ { alias /data/w3/images/$1; } proxy_set_header X-Origin-URI ${scheme}://${http_host}/$request_uri; """ parsed = loads(test) self.assertEqual( parsed, [[['if', '($http_user_agent', '~', 'MSIE)'], [['rewrite', '^(.*)$', '/msie/$1', 'break']]], [['if', '($http_cookie', '~*', '"id=([^;]+)(?:;|$)")'], [['set', '$id', '$1']]], [['if', '($request_method', '=', 'POST)'], [['return', '405']]], [['if', '($request_method)'], [['return', '403']]], [['if', '($args', '~', 'post=140)'], [['rewrite', '^', 'http://example.com/']]], [['location', '~', '^/users/(.+\\.(?:gif|jpe?g|png))$'], [['alias', '/data/w3/images/$1']]], [ 'proxy_set_header', 'X-Origin-URI', '${scheme}://${http_host}/$request_uri' ]])
def test_map_then_assignment_in_block(self): # see issue #3798 test_str = """http { map $http_upgrade $connection_upgrade { default upgrade; '' close; "~Opera Mini" 1; *.example.com 1; } one; }""" parsed = loads(test_str) self.assertEqual( parsed, [[['http'], [[['map', '$http_upgrade', '$connection_upgrade'], [['default', 'upgrade'], ["''", 'close'], ['"~Opera Mini"', '1'], ['*.example.com', '1']]], ['one']]]])
def test_weird_blocks(self): test = r""" if ($http_user_agent ~ MSIE) { rewrite ^(.*)$ /msie/$1 break; } if ($http_cookie ~* "id=([^;]+)(?:;|$)") { set $id $1; } if ($request_method = POST) { return 405; } if ($request_method) { return 403; } if ($args ~ post=140){ rewrite ^ http://example.com/; } location ~ ^/users/(.+\.(?:gif|jpe?g|png))$ { alias /data/w3/images/$1; } proxy_set_header X-Origin-URI ${scheme}://${http_host}/$request_uri; """ parsed = loads(test) self.assertEqual(parsed, [[['if', '($http_user_agent', '~', 'MSIE)'], [['rewrite', '^(.*)$', '/msie/$1', 'break']]], [['if', '($http_cookie', '~*', '"id=([^;]+)(?:;|$)")'], [['set', '$id', '$1']]], [['if', '($request_method', '=', 'POST)'], [['return', '405']]], [['if', '($request_method)'], [['return', '403']]], [['if', '($args', '~', 'post=140)'], [['rewrite', '^', 'http://example.com/']]], [['location', '~', '^/users/(.+\\.(?:gif|jpe?g|png))$'], [['alias', '/data/w3/images/$1']]], ['proxy_set_header', 'X-Origin-URI', '${scheme}://${http_host}/$request_uri']] )
def test_map_then_assignment_in_block(self): # see issue #3798 test_str = """http { map $http_upgrade $connection_upgrade { default upgrade; '' close; "~Opera Mini" 1; *.example.com 1; } one; }""" parsed = loads(test_str) self.assertEqual(parsed, [ [['http'], [ [['map', '$http_upgrade', '$connection_upgrade'], [ ['default', 'upgrade'], ["''", 'close'], ['"~Opera Mini"', '1'], ['*.example.com', '1'] ]], ['one'] ]] ])