mirror of
				https://github.com/alecthomas/chroma.git
				synced 2025-10-30 23:57:49 +02:00 
			
		
		
		
	Major updates to Caddyfile lexer (#932)
* Major updates to Caddyfile lexer * yaml editorconfig * nolint false positive
This commit is contained in:
		| @@ -11,3 +11,7 @@ insert_final_newline = true | ||||
| indent_style = space | ||||
| indent_size = 2 | ||||
| insert_final_newline = false | ||||
|  | ||||
| [*.yml] | ||||
| indent_style = space | ||||
| indent_size = 2 | ||||
|   | ||||
| @@ -4,52 +4,82 @@ import ( | ||||
| 	. "github.com/alecthomas/chroma/v2" // nolint | ||||
| ) | ||||
|  | ||||
| // Matcher token stub for docs, or | ||||
| // Named matcher: @name, or | ||||
| // Path matcher: /foo, or | ||||
| // Wildcard path matcher: * | ||||
| // nolint: gosec | ||||
| var caddyfileMatcherTokenRegexp = `(\[\<matcher\>\]|@[^\s]+|/[^\s]+|\*)` | ||||
|  | ||||
| // Comment at start of line, or | ||||
| // Comment preceded by whitespace | ||||
| var caddyfileCommentRegexp = `(^|\s+)#.*\n` | ||||
|  | ||||
| // caddyfileCommon are the rules common to both of the lexer variants | ||||
| func caddyfileCommonRules() Rules { | ||||
| 	return Rules{ | ||||
| 		"site_block_common": { | ||||
| 			Include("site_body"), | ||||
| 			// Any other directive | ||||
| 			{`[^\s#]+`, Keyword, Push("directive")}, | ||||
| 			Include("base"), | ||||
| 		}, | ||||
| 		"site_body": { | ||||
| 			// Import keyword | ||||
| 			{`(import)(\s+)([^\s]+)`, ByGroups(Keyword, Text, NameVariableMagic), nil}, | ||||
| 			{`\b(import|invoke)\b( [^\s#]+)`, ByGroups(Keyword, Text), Push("subdirective")}, | ||||
| 			// Matcher definition | ||||
| 			{`@[^\s]+(?=\s)`, NameDecorator, Push("matcher")}, | ||||
| 			// Matcher token stub for docs | ||||
| 			{`\[\<matcher\>\]`, NameDecorator, Push("matcher")}, | ||||
| 			// These cannot have matchers but may have things that look like | ||||
| 			// matchers in their arguments, so we just parse as a subdirective. | ||||
| 			{`try_files`, Keyword, Push("subdirective")}, | ||||
| 			{`\b(try_files|tls|log|bind)\b`, Keyword, Push("subdirective")}, | ||||
| 			// These are special, they can nest more directives | ||||
| 			{`handle_errors|handle|route|handle_path|not`, Keyword, Push("nested_directive")}, | ||||
| 			// Any other directive | ||||
| 			{`[^\s#]+`, Keyword, Push("directive")}, | ||||
| 			Include("base"), | ||||
| 			{`\b(handle_errors|handle_path|handle_response|replace_status|handle|route)\b`, Keyword, Push("nested_directive")}, | ||||
| 			// uri directive has special syntax | ||||
| 			{`\b(uri)\b`, Keyword, Push("uri_directive")}, | ||||
| 		}, | ||||
| 		"matcher": { | ||||
| 			{`\{`, Punctuation, Push("block")}, | ||||
| 			// Not can be one-liner | ||||
| 			{`not`, Keyword, Push("deep_not_matcher")}, | ||||
| 			// Heredoc for CEL expression | ||||
| 			Include("heredoc"), | ||||
| 			// Backtick for CEL expression | ||||
| 			{"`", StringBacktick, Push("backticks")}, | ||||
| 			// Any other same-line matcher | ||||
| 			{`[^\s#]+`, Keyword, Push("arguments")}, | ||||
| 			// Terminators | ||||
| 			{`\n`, Text, Pop(1)}, | ||||
| 			{`\s*\n`, Text, Pop(1)}, | ||||
| 			{`\}`, Punctuation, Pop(1)}, | ||||
| 			Include("base"), | ||||
| 		}, | ||||
| 		"block": { | ||||
| 			{`\}`, Punctuation, Pop(2)}, | ||||
| 			// Using double quotes doesn't stop at spaces | ||||
| 			{`"`, StringDouble, Push("double_quotes")}, | ||||
| 			// Using backticks doesn't stop at spaces | ||||
| 			{"`", StringBacktick, Push("backticks")}, | ||||
| 			// Not can be one-liner | ||||
| 			{`not`, Keyword, Push("not_matcher")}, | ||||
| 			// Any other subdirective | ||||
| 			// Directives & matcher definitions | ||||
| 			Include("site_body"), | ||||
| 			// Any directive | ||||
| 			{`[^\s#]+`, Keyword, Push("subdirective")}, | ||||
| 			Include("base"), | ||||
| 		}, | ||||
| 		"nested_block": { | ||||
| 			{`\}`, Punctuation, Pop(2)}, | ||||
| 			// Matcher definition | ||||
| 			{`@[^\s]+(?=\s)`, NameDecorator, Push("matcher")}, | ||||
| 			// Something that starts with literally < is probably a docs stub | ||||
| 			{`\<[^#]+\>`, Keyword, Push("nested_directive")}, | ||||
| 			// Any other directive | ||||
| 			{`[^\s#]+`, Keyword, Push("nested_directive")}, | ||||
| 			// Using double quotes doesn't stop at spaces | ||||
| 			{`"`, StringDouble, Push("double_quotes")}, | ||||
| 			// Using backticks doesn't stop at spaces | ||||
| 			{"`", StringBacktick, Push("backticks")}, | ||||
| 			// Not can be one-liner | ||||
| 			{`not`, Keyword, Push("not_matcher")}, | ||||
| 			// Directives & matcher definitions | ||||
| 			Include("site_body"), | ||||
| 			// Any other subdirective | ||||
| 			{`[^\s#]+`, Keyword, Push("directive")}, | ||||
| 			Include("base"), | ||||
| 		}, | ||||
| 		"not_matcher": { | ||||
| @@ -66,69 +96,97 @@ func caddyfileCommonRules() Rules { | ||||
| 		}, | ||||
| 		"directive": { | ||||
| 			{`\{(?=\s)`, Punctuation, Push("block")}, | ||||
| 			Include("matcher_token"), | ||||
| 			Include("comments_pop_1"), | ||||
| 			{`\n`, Text, Pop(1)}, | ||||
| 			{caddyfileMatcherTokenRegexp, NameDecorator, Push("arguments")}, | ||||
| 			{caddyfileCommentRegexp, CommentSingle, Pop(1)}, | ||||
| 			{`\s*\n`, Text, Pop(1)}, | ||||
| 			Include("base"), | ||||
| 		}, | ||||
| 		"nested_directive": { | ||||
| 			{`\{(?=\s)`, Punctuation, Push("nested_block")}, | ||||
| 			Include("matcher_token"), | ||||
| 			Include("comments_pop_1"), | ||||
| 			{`\n`, Text, Pop(1)}, | ||||
| 			{caddyfileMatcherTokenRegexp, NameDecorator, Push("nested_arguments")}, | ||||
| 			{caddyfileCommentRegexp, CommentSingle, Pop(1)}, | ||||
| 			{`\s*\n`, Text, Pop(1)}, | ||||
| 			Include("base"), | ||||
| 		}, | ||||
| 		"subdirective": { | ||||
| 			{`\{(?=\s)`, Punctuation, Push("block")}, | ||||
| 			Include("comments_pop_1"), | ||||
| 			{`\n`, Text, Pop(1)}, | ||||
| 			{caddyfileCommentRegexp, CommentSingle, Pop(1)}, | ||||
| 			{`\s*\n`, Text, Pop(1)}, | ||||
| 			Include("base"), | ||||
| 		}, | ||||
| 		"arguments": { | ||||
| 			{`\{(?=\s)`, Punctuation, Push("block")}, | ||||
| 			Include("comments_pop_2"), | ||||
| 			{caddyfileCommentRegexp, CommentSingle, Pop(2)}, | ||||
| 			{`\\\n`, Text, nil}, // Skip escaped newlines | ||||
| 			{`\n`, Text, Pop(2)}, | ||||
| 			{`\s*\n`, Text, Pop(2)}, | ||||
| 			Include("base"), | ||||
| 		}, | ||||
| 		"nested_arguments": { | ||||
| 			{`\{(?=\s)`, Punctuation, Push("nested_block")}, | ||||
| 			{caddyfileCommentRegexp, CommentSingle, Pop(2)}, | ||||
| 			{`\\\n`, Text, nil}, // Skip escaped newlines | ||||
| 			{`\s*\n`, Text, Pop(2)}, | ||||
| 			Include("base"), | ||||
| 		}, | ||||
| 		"deep_subdirective": { | ||||
| 			{`\{(?=\s)`, Punctuation, Push("block")}, | ||||
| 			Include("comments_pop_3"), | ||||
| 			{`\n`, Text, Pop(3)}, | ||||
| 			{caddyfileCommentRegexp, CommentSingle, Pop(3)}, | ||||
| 			{`\s*\n`, Text, Pop(3)}, | ||||
| 			Include("base"), | ||||
| 		}, | ||||
| 		"matcher_token": { | ||||
| 			{`@[^\s]+`, NameDecorator, Push("arguments")},         // Named matcher | ||||
| 			{`/[^\s]+`, NameDecorator, Push("arguments")},         // Path matcher | ||||
| 			{`\*`, NameDecorator, Push("arguments")},              // Wildcard path matcher | ||||
| 			{`\[\<matcher\>\]`, NameDecorator, Push("arguments")}, // Matcher token stub for docs | ||||
| 		"uri_directive": { | ||||
| 			{`\{(?=\s)`, Punctuation, Push("block")}, | ||||
| 			{caddyfileMatcherTokenRegexp, NameDecorator, nil}, | ||||
| 			{`(strip_prefix|strip_suffix|replace|path_regexp)`, NameConstant, Push("arguments")}, | ||||
| 			{caddyfileCommentRegexp, CommentSingle, Pop(1)}, | ||||
| 			{`\s*\n`, Text, Pop(1)}, | ||||
| 			Include("base"), | ||||
| 		}, | ||||
| 		"comments": { | ||||
| 			{`^#.*\n`, CommentSingle, nil},   // Comment at start of line | ||||
| 			{`\s+#.*\n`, CommentSingle, nil}, // Comment preceded by whitespace | ||||
| 		"double_quotes": { | ||||
| 			Include("placeholder"), | ||||
| 			{`\\"`, StringDouble, nil}, | ||||
| 			{`[^"]`, StringDouble, nil}, | ||||
| 			{`"`, StringDouble, Pop(1)}, | ||||
| 		}, | ||||
| 		"comments_pop_1": { | ||||
| 			{`^#.*\n`, CommentSingle, Pop(1)},   // Comment at start of line | ||||
| 			{`\s+#.*\n`, CommentSingle, Pop(1)}, // Comment preceded by whitespace | ||||
| 		"backticks": { | ||||
| 			Include("placeholder"), | ||||
| 			{"\\\\`", StringBacktick, nil}, | ||||
| 			{"[^`]", StringBacktick, nil}, | ||||
| 			{"`", StringBacktick, Pop(1)}, | ||||
| 		}, | ||||
| 		"comments_pop_2": { | ||||
| 			{`^#.*\n`, CommentSingle, Pop(2)},   // Comment at start of line | ||||
| 			{`\s+#.*\n`, CommentSingle, Pop(2)}, // Comment preceded by whitespace | ||||
| 		"optional": { | ||||
| 			// Docs syntax for showing optional parts with [ ] | ||||
| 			{`\[`, Punctuation, Push("optional")}, | ||||
| 			Include("name_constants"), | ||||
| 			{`\|`, Punctuation, nil}, | ||||
| 			{`[^\[\]\|]+`, String, nil}, | ||||
| 			{`\]`, Punctuation, Pop(1)}, | ||||
| 		}, | ||||
| 		"comments_pop_3": { | ||||
| 			{`^#.*\n`, CommentSingle, Pop(3)},   // Comment at start of line | ||||
| 			{`\s+#.*\n`, CommentSingle, Pop(3)}, // Comment preceded by whitespace | ||||
| 		"heredoc": { | ||||
| 			{`(<<([a-zA-Z0-9_-]+))(\n(.*|\n)*)(\s*)(\2)`, ByGroups(StringHeredoc, nil, String, String, String, StringHeredoc), nil}, | ||||
| 		}, | ||||
| 		"name_constants": { | ||||
| 			{`\b(most_recently_modified|largest_size|smallest_size|first_exist|internal|disable_redirects|ignore_loaded_certs|disable_certs|private_ranges|first|last|before|after|on|off)\b(\||(?=\]|\s|$))`, ByGroups(NameConstant, Punctuation), nil}, | ||||
| 		}, | ||||
| 		"placeholder": { | ||||
| 			// Placeholder with dots, colon for default value, brackets for args[0:] | ||||
| 			{`\{[\w+.\[\]\:\$-]+\}`, StringEscape, nil}, | ||||
| 			// Handle opening brackets with no matching closing one | ||||
| 			{`\{[^\}\s]*\b`, String, nil}, | ||||
| 		}, | ||||
| 		"base": { | ||||
| 			Include("comments"), | ||||
| 			{`(on|off|first|last|before|after|internal|strip_prefix|strip_suffix|replace)\b`, NameConstant, nil}, | ||||
| 			{`(https?://)?([a-z0-9.-]+)(:)([0-9]+)`, ByGroups(Name, Name, Punctuation, LiteralNumberInteger), nil}, | ||||
| 			{`[a-z-]+/[a-z-+]+`, LiteralString, nil}, | ||||
| 			{`[0-9]+[km]?\b`, LiteralNumberInteger, nil}, | ||||
| 			{`\{[\w+.\$-]+\}`, LiteralStringEscape, nil}, // Placeholder | ||||
| 			{`\[(?=[^#{}$]+\])`, Punctuation, nil}, | ||||
| 			{`\]|\|`, Punctuation, nil}, | ||||
| 			{`[^\s#{}$\]]+`, LiteralString, nil}, | ||||
| 			{caddyfileCommentRegexp, CommentSingle, nil}, | ||||
| 			{`\[\<matcher\>\]`, NameDecorator, nil}, | ||||
| 			Include("name_constants"), | ||||
| 			Include("heredoc"), | ||||
| 			{`(https?://)?([a-z0-9.-]+)(:)([0-9]+)([^\s]*)`, ByGroups(Name, Name, Punctuation, NumberInteger, Name), nil}, | ||||
| 			{`\[`, Punctuation, Push("optional")}, | ||||
| 			{"`", StringBacktick, Push("backticks")}, | ||||
| 			{`"`, StringDouble, Push("double_quotes")}, | ||||
| 			Include("placeholder"), | ||||
| 			{`[a-z-]+/[a-z-+]+`, String, nil}, | ||||
| 			{`[0-9]+([smhdk]|ns|us|µs|ms)?\b`, NumberInteger, nil}, | ||||
| 			{`[^\s\n#\{]+`, String, nil}, | ||||
| 			{`/[^\s#]*`, Name, nil}, | ||||
| 			{`\s+`, Text, nil}, | ||||
| 		}, | ||||
| @@ -149,27 +207,29 @@ var Caddyfile = Register(MustNewLexer( | ||||
| func caddyfileRules() Rules { | ||||
| 	return Rules{ | ||||
| 		"root": { | ||||
| 			Include("comments"), | ||||
| 			{caddyfileCommentRegexp, CommentSingle, nil}, | ||||
| 			// Global options block | ||||
| 			{`^\s*(\{)\s*$`, ByGroups(Punctuation), Push("globals")}, | ||||
| 			// Top level import | ||||
| 			{`(import)(\s+)([^\s]+)`, ByGroups(Keyword, Text, NameVariableMagic), nil}, | ||||
| 			// Snippets | ||||
| 			{`(\([^\s#]+\))(\s*)(\{)`, ByGroups(NameVariableAnonymous, Text, Punctuation), Push("snippet")}, | ||||
| 			{`(&?\([^\s#]+\))(\s*)(\{)`, ByGroups(NameVariableAnonymous, Text, Punctuation), Push("snippet")}, | ||||
| 			// Site label | ||||
| 			{`[^#{(\s,]+`, GenericHeading, Push("label")}, | ||||
| 			// Site label with placeholder | ||||
| 			{`\{[\w+.\$-]+\}`, LiteralStringEscape, Push("label")}, | ||||
| 			{`\{[\w+.\[\]\:\$-]+\}`, StringEscape, Push("label")}, | ||||
| 			{`\s+`, Text, nil}, | ||||
| 		}, | ||||
| 		"globals": { | ||||
| 			{`\}`, Punctuation, Pop(1)}, | ||||
| 			{`[^\s#]+`, Keyword, Push("directive")}, | ||||
| 			// Global options are parsed as subdirectives (no matcher) | ||||
| 			{`[^\s#]+`, Keyword, Push("subdirective")}, | ||||
| 			Include("base"), | ||||
| 		}, | ||||
| 		"snippet": { | ||||
| 			{`\}`, Punctuation, Pop(1)}, | ||||
| 			// Matcher definition | ||||
| 			{`@[^\s]+(?=\s)`, NameDecorator, Push("matcher")}, | ||||
| 			// Any directive | ||||
| 			Include("site_body"), | ||||
| 			// Any other directive | ||||
| 			{`[^\s#]+`, Keyword, Push("directive")}, | ||||
| 			Include("base"), | ||||
| 		}, | ||||
| @@ -179,7 +239,7 @@ func caddyfileRules() Rules { | ||||
| 			{`,\s*\n?`, Text, nil}, | ||||
| 			{` `, Text, nil}, | ||||
| 			// Site label with placeholder | ||||
| 			{`\{[\w+.\$-]+\}`, LiteralStringEscape, nil}, | ||||
| 			Include("placeholder"), | ||||
| 			// Site label | ||||
| 			{`[^#{(\s,]+`, GenericHeading, nil}, | ||||
| 			// Comment after non-block label (hack because comments end in \n) | ||||
|   | ||||
							
								
								
									
										76
									
								
								lexers/testdata/caddyfile.actual
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										76
									
								
								lexers/testdata/caddyfile.actual
									
									
									
									
										vendored
									
									
								
							| @@ -4,21 +4,42 @@ | ||||
| 	on_demand_tls { | ||||
| 		ask https://example.com | ||||
| 	} | ||||
| 	log default { | ||||
| 		output file /var/log/caddy/access.log | ||||
| 		format json | ||||
| 	} | ||||
| 	auto_https disable_redirects | ||||
| 	renew_interval 20m | ||||
|  | ||||
| 	# this is a comment | ||||
| 	servers 192.168.1.2:8080 { | ||||
| 		name public | ||||
| 		trusted_proxies static private_ranges | ||||
| 		log_credentials | ||||
| 	} | ||||
| } | ||||
|  | ||||
| (blocking) {   | ||||
| # top level comment | ||||
|  | ||||
| (blocking) { | ||||
| 	@blocked { | ||||
| 		path *.txt *.md *.mdown /site/* | ||||
| 	} | ||||
| 	redir @blocked / | ||||
| } | ||||
|  | ||||
| http://example.com { | ||||
| 	respond "http" | ||||
| } | ||||
|  | ||||
| example.com, fake.org, {$ENV_SITE} { | ||||
| 	root * /srv | ||||
|  | ||||
| 	respond /get-env {$ENV_VAR} | ||||
| 	respond /get-env {$ENV_VAR:default} | ||||
|  | ||||
| 	tls off | ||||
| 	tls internal | ||||
| 	tls /path/to/cert.pem /path/to/key.pem | ||||
|  | ||||
| 	route { | ||||
| 		# Add trailing slash for directory requests | ||||
| @@ -67,6 +88,55 @@ example.com, fake.org, {$ENV_SITE} { | ||||
| 	respond @singleLine "Awesome." | ||||
|  | ||||
| 	import blocking | ||||
| 	import blocking foo | ||||
| 	import glob/* | ||||
|  | ||||
| 	file_server | ||||
| } | ||||
|  | ||||
| 	@named host example.com | ||||
| 	handle @named { | ||||
| 		handle /foo* { | ||||
| 			handle /foo* { | ||||
| 				respond "{path} foo" | ||||
| 			} | ||||
| 		} | ||||
| 		respond "foo" | ||||
| 	} | ||||
|  | ||||
| 	handle_path /foo* { | ||||
| 		respond "foo" | ||||
| 	} | ||||
|  | ||||
| 	reverse_proxy /api/* unix//var/run/api.sock { | ||||
| 		@good status 200 | ||||
| 		handle_response @good { | ||||
| 			rewrite * /foo{uri} | ||||
| 			file_server | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	respond <<HTML | ||||
| 		<!DOCTYPE html> | ||||
| 		<html> | ||||
| 			<head> | ||||
| 				<title>Test</title> | ||||
| 			</head> | ||||
| 			<body> | ||||
| 				<h1>Hello, world!</h1> | ||||
| 			</body> | ||||
| 		</html> | ||||
| 		HTML 200 | ||||
|  | ||||
| 	@file `file()` | ||||
| 	@first `file({'try_files': [{path}, {path} + '/', 'index.html']})` | ||||
| 	@smallest `file({'try_policy': 'smallest_size', 'try_files': ['a.txt', 'b.txt']})` | ||||
|  | ||||
| 	@without-both { | ||||
| 		not { | ||||
| 			path /api/* | ||||
| 			method POST | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	path_regexp [<name>] <regexp> | ||||
| } | ||||
|   | ||||
							
								
								
									
										242
									
								
								lexers/testdata/caddyfile.expected
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										242
									
								
								lexers/testdata/caddyfile.expected
									
									
									
									
										vendored
									
									
								
							| @@ -16,13 +16,63 @@ | ||||
|   {"type":"LiteralString","value":"https://example.com"}, | ||||
|   {"type":"Text","value":"\n\t"}, | ||||
|   {"type":"Punctuation","value":"}"}, | ||||
|   {"type":"Text","value":"\n\t"}, | ||||
|   {"type":"Keyword","value":"log"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"LiteralString","value":"default"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"Punctuation","value":"{"}, | ||||
|   {"type":"Text","value":"\n\t\t"}, | ||||
|   {"type":"Keyword","value":"output"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"LiteralString","value":"file"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"LiteralString","value":"/var/log/caddy/access.log"}, | ||||
|   {"type":"Text","value":"\n\t\t"}, | ||||
|   {"type":"Keyword","value":"format"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"LiteralString","value":"json"}, | ||||
|   {"type":"Text","value":"\n\t"}, | ||||
|   {"type":"Punctuation","value":"}"}, | ||||
|   {"type":"Text","value":"\n\t"}, | ||||
|   {"type":"Keyword","value":"auto_https"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"NameConstant","value":"disable_redirects"}, | ||||
|   {"type":"Text","value":"\n\t"}, | ||||
|   {"type":"Keyword","value":"renew_interval"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"LiteralNumberInteger","value":"20m"}, | ||||
|   {"type":"CommentSingle","value":"\n\n\t# this is a comment\n"}, | ||||
|   {"type":"Text","value":"\t"}, | ||||
|   {"type":"Keyword","value":"servers"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"Name","value":"192.168.1.2"}, | ||||
|   {"type":"Punctuation","value":":"}, | ||||
|   {"type":"LiteralNumberInteger","value":"8080"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"Punctuation","value":"{"}, | ||||
|   {"type":"Text","value":"\n\t\t"}, | ||||
|   {"type":"Keyword","value":"name"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"LiteralString","value":"public"}, | ||||
|   {"type":"Text","value":"\n\t\t"}, | ||||
|   {"type":"Keyword","value":"trusted_proxies"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"LiteralString","value":"static"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"NameConstant","value":"private_ranges"}, | ||||
|   {"type":"Text","value":"\n\t\t"}, | ||||
|   {"type":"Keyword","value":"log_credentials"}, | ||||
|   {"type":"Text","value":"\n\t"}, | ||||
|   {"type":"Punctuation","value":"}"}, | ||||
|   {"type":"Text","value":"\n"}, | ||||
|   {"type":"Punctuation","value":"}"}, | ||||
|   {"type":"Text","value":"\n\n"}, | ||||
|   {"type":"CommentSingle","value":"\n\n# top level comment\n"}, | ||||
|   {"type":"Text","value":"\n"}, | ||||
|   {"type":"NameVariableAnonymous","value":"(blocking)"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"Punctuation","value":"{"}, | ||||
|   {"type":"Text","value":"  \n\t"}, | ||||
|   {"type":"Text","value":"\n\t"}, | ||||
|   {"type":"NameDecorator","value":"@blocked"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"Punctuation","value":"{"}, | ||||
| @@ -47,6 +97,16 @@ | ||||
|   {"type":"Text","value":"\n"}, | ||||
|   {"type":"Punctuation","value":"}"}, | ||||
|   {"type":"Text","value":"\n\n"}, | ||||
|   {"type":"GenericHeading","value":"http://example.com"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"Punctuation","value":"{"}, | ||||
|   {"type":"Text","value":"\n\t"}, | ||||
|   {"type":"Keyword","value":"respond"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"LiteralStringDouble","value":"\"http\""}, | ||||
|   {"type":"Text","value":"\n"}, | ||||
|   {"type":"Punctuation","value":"}"}, | ||||
|   {"type":"Text","value":"\n\n"}, | ||||
|   {"type":"GenericHeading","value":"example.com"}, | ||||
|   {"type":"Text","value":", "}, | ||||
|   {"type":"GenericHeading","value":"fake.org"}, | ||||
| @@ -66,10 +126,22 @@ | ||||
|   {"type":"NameDecorator","value":"/get-env"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"LiteralStringEscape","value":"{$ENV_VAR}"}, | ||||
|   {"type":"Text","value":"\n\t"}, | ||||
|   {"type":"Keyword","value":"respond"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"NameDecorator","value":"/get-env"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"LiteralStringEscape","value":"{$ENV_VAR:default}"}, | ||||
|   {"type":"Text","value":"\n\n\t"}, | ||||
|   {"type":"Keyword","value":"tls"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"NameConstant","value":"off"}, | ||||
|   {"type":"NameConstant","value":"internal"}, | ||||
|   {"type":"Text","value":"\n\t"}, | ||||
|   {"type":"Keyword","value":"tls"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"LiteralString","value":"/path/to/cert.pem"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"LiteralString","value":"/path/to/key.pem"}, | ||||
|   {"type":"Text","value":"\n\n\t"}, | ||||
|   {"type":"Keyword","value":"route"}, | ||||
|   {"type":"Text","value":" "}, | ||||
| @@ -203,9 +275,7 @@ | ||||
|   {"type":"Text","value":"\n\t\t"}, | ||||
|   {"type":"Keyword","value":"X-XSS-Protection"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"LiteralString","value":"\"1;"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"LiteralString","value":"mode=block\""}, | ||||
|   {"type":"LiteralStringDouble","value":"\"1; mode=block\""}, | ||||
|   {"type":"Text","value":"\n\t\t"}, | ||||
|   {"type":"Keyword","value":"X-Robots-Tag"}, | ||||
|   {"type":"Text","value":" "}, | ||||
| @@ -213,9 +283,7 @@ | ||||
|   {"type":"Text","value":"\n\t\t"}, | ||||
|   {"type":"Keyword","value":"Content-Security-Policy"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"LiteralString","value":"\"frame-ancestors"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"LiteralString","value":"'self'\""}, | ||||
|   {"type":"LiteralStringDouble","value":"\"frame-ancestors 'self'\""}, | ||||
|   {"type":"Text","value":"\n\t\t"}, | ||||
|   {"type":"Keyword","value":"X-Frame-Options"}, | ||||
|   {"type":"Text","value":" "}, | ||||
| @@ -239,13 +307,159 @@ | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"NameDecorator","value":"@singleLine"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"LiteralString","value":"\"Awesome.\""}, | ||||
|   {"type":"LiteralStringDouble","value":"\"Awesome.\""}, | ||||
|   {"type":"Text","value":"\n\n\t"}, | ||||
|   {"type":"Keyword","value":"import"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"NameVariableMagic","value":"blocking"}, | ||||
|   {"type":"Text","value":"\n\n\t"}, | ||||
|   {"type":"Text","value":" blocking\n\t"}, | ||||
|   {"type":"Keyword","value":"import"}, | ||||
|   {"type":"Text","value":" blocking "}, | ||||
|   {"type":"LiteralString","value":"foo"}, | ||||
|   {"type":"Text","value":"\n\t"}, | ||||
|   {"type":"Keyword","value":"import"}, | ||||
|   {"type":"Text","value":" glob/*\n\n\t"}, | ||||
|   {"type":"Keyword","value":"file_server"}, | ||||
|   {"type":"Text","value":"\n\n\t"}, | ||||
|   {"type":"NameDecorator","value":"@named"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"Keyword","value":"host"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"LiteralString","value":"example.com"}, | ||||
|   {"type":"Text","value":"\n\t"}, | ||||
|   {"type":"Keyword","value":"handle"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"NameDecorator","value":"@named"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"Punctuation","value":"{"}, | ||||
|   {"type":"Text","value":"\n\t\t"}, | ||||
|   {"type":"Keyword","value":"handle"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"NameDecorator","value":"/foo*"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"Punctuation","value":"{"}, | ||||
|   {"type":"Text","value":"\n\t\t\t"}, | ||||
|   {"type":"Keyword","value":"handle"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"NameDecorator","value":"/foo*"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"Punctuation","value":"{"}, | ||||
|   {"type":"Text","value":"\n\t\t\t\t"}, | ||||
|   {"type":"Keyword","value":"respond"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"LiteralStringDouble","value":"\""}, | ||||
|   {"type":"LiteralStringEscape","value":"{path}"}, | ||||
|   {"type":"LiteralStringDouble","value":" foo\""}, | ||||
|   {"type":"Text","value":"\n\t\t\t"}, | ||||
|   {"type":"Punctuation","value":"}"}, | ||||
|   {"type":"Text","value":"\n\t\t"}, | ||||
|   {"type":"Punctuation","value":"}"}, | ||||
|   {"type":"Text","value":"\n\t\t"}, | ||||
|   {"type":"Keyword","value":"respond"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"LiteralStringDouble","value":"\"foo\""}, | ||||
|   {"type":"Text","value":"\n\t"}, | ||||
|   {"type":"Punctuation","value":"}"}, | ||||
|   {"type":"Text","value":"\n\n\t"}, | ||||
|   {"type":"Keyword","value":"handle_path"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"NameDecorator","value":"/foo*"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"Punctuation","value":"{"}, | ||||
|   {"type":"Text","value":"\n\t\t"}, | ||||
|   {"type":"Keyword","value":"respond"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"LiteralStringDouble","value":"\"foo\""}, | ||||
|   {"type":"Text","value":"\n\t"}, | ||||
|   {"type":"Punctuation","value":"}"}, | ||||
|   {"type":"Text","value":"\n\n\t"}, | ||||
|   {"type":"Keyword","value":"reverse_proxy"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"NameDecorator","value":"/api/*"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"LiteralString","value":"unix//var/run/api.sock"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"Punctuation","value":"{"}, | ||||
|   {"type":"Text","value":"\n\t\t"}, | ||||
|   {"type":"NameDecorator","value":"@good"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"Keyword","value":"status"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"LiteralNumberInteger","value":"200"}, | ||||
|   {"type":"Text","value":"\n\t\t"}, | ||||
|   {"type":"Keyword","value":"handle_response"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"NameDecorator","value":"@good"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"Punctuation","value":"{"}, | ||||
|   {"type":"Text","value":"\n\t\t\t"}, | ||||
|   {"type":"Keyword","value":"rewrite"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"NameDecorator","value":"*"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"LiteralString","value":"/foo"}, | ||||
|   {"type":"LiteralStringEscape","value":"{uri}"}, | ||||
|   {"type":"Text","value":"\n\t\t\t"}, | ||||
|   {"type":"Keyword","value":"file_server"}, | ||||
|   {"type":"Text","value":"\n\t\t"}, | ||||
|   {"type":"Punctuation","value":"}"}, | ||||
|   {"type":"Text","value":"\n\t"}, | ||||
|   {"type":"Punctuation","value":"}"}, | ||||
|   {"type":"Text","value":"\n\n\t"}, | ||||
|   {"type":"Keyword","value":"respond"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"LiteralStringHeredoc","value":"\u003c\u003cHTML"}, | ||||
|   {"type":"LiteralString","value":"\n\t\t\u003c!DOCTYPE html\u003e\n\t\t\u003chtml\u003e\n\t\t\t\u003chead\u003e\n\t\t\t\t\u003ctitle\u003eTest\u003c/title\u003e\n\t\t\t\u003c/head\u003e\n\t\t\t\u003cbody\u003e\n\t\t\t\t\u003ch1\u003eHello, world!\u003c/h1\u003e\n\t\t\t\u003c/body\u003e\n\t\t\u003c/html\u003e\n\t\t"}, | ||||
|   {"type":"LiteralStringHeredoc","value":"HTML"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"LiteralNumberInteger","value":"200"}, | ||||
|   {"type":"Text","value":"\n\n\t"}, | ||||
|   {"type":"NameDecorator","value":"@file"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"LiteralStringBacktick","value":"`file()`"}, | ||||
|   {"type":"Text","value":"\n\t"}, | ||||
|   {"type":"NameDecorator","value":"@first"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"LiteralStringBacktick","value":"`file("}, | ||||
|   {"type":"LiteralString","value":"{'try_files"}, | ||||
|   {"type":"LiteralStringBacktick","value":"': ["}, | ||||
|   {"type":"LiteralStringEscape","value":"{path}"}, | ||||
|   {"type":"LiteralStringBacktick","value":", "}, | ||||
|   {"type":"LiteralStringEscape","value":"{path}"}, | ||||
|   {"type":"LiteralStringBacktick","value":" + '/', 'index.html']})`"}, | ||||
|   {"type":"Text","value":"\n\t"}, | ||||
|   {"type":"NameDecorator","value":"@smallest"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"LiteralStringBacktick","value":"`file("}, | ||||
|   {"type":"LiteralString","value":"{'try_policy"}, | ||||
|   {"type":"LiteralStringBacktick","value":"': 'smallest_size', 'try_files': ['a.txt', 'b.txt']})`"}, | ||||
|   {"type":"Text","value":"\n\n\t"}, | ||||
|   {"type":"NameDecorator","value":"@without-both"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"Punctuation","value":"{"}, | ||||
|   {"type":"Text","value":"\n\t\t"}, | ||||
|   {"type":"Keyword","value":"not"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"Punctuation","value":"{"}, | ||||
|   {"type":"Text","value":"\n\t\t\t"}, | ||||
|   {"type":"Keyword","value":"path"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"LiteralString","value":"/api/*"}, | ||||
|   {"type":"Text","value":"\n\t\t\t"}, | ||||
|   {"type":"Keyword","value":"method"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"LiteralString","value":"POST"}, | ||||
|   {"type":"Text","value":"\n\t\t"}, | ||||
|   {"type":"Punctuation","value":"}"}, | ||||
|   {"type":"Text","value":"\n\t"}, | ||||
|   {"type":"Punctuation","value":"}"}, | ||||
|   {"type":"Text","value":"\n\n\t"}, | ||||
|   {"type":"Keyword","value":"path_regexp"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"Punctuation","value":"["}, | ||||
|   {"type":"LiteralString","value":"\u003cname\u003e"}, | ||||
|   {"type":"Punctuation","value":"]"}, | ||||
|   {"type":"Text","value":" "}, | ||||
|   {"type":"LiteralString","value":"\u003cregexp\u003e"}, | ||||
|   {"type":"Text","value":"\n"}, | ||||
|   {"type":"Punctuation","value":"}"} | ||||
|   {"type":"Punctuation","value":"}"}, | ||||
|   {"type":"Text","value":"\n"} | ||||
| ] | ||||
|   | ||||
		Reference in New Issue
	
	Block a user