caddyfile: Expand imports inside named routes (#7986)
parent
894442fe86
commit
c1645c544d
|
|
@ -173,8 +173,15 @@ func (p *parser) begin() error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tokens = append([]Token{nameToken}, tokens...)
|
||||
p.block.Segments = []Segment{tokens}
|
||||
|
||||
// expand any import directives inside the named route block
|
||||
expandedTokens, err := p.expandImportsInBlock(tokens)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
expandedTokens = append([]Token{nameToken}, expandedTokens...)
|
||||
p.block.Segments = []Segment{expandedTokens}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -583,6 +590,41 @@ func (p *parser) doImport(nesting int) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// expandImportsInBlock takes a slice of tokens (typically the contents of a
|
||||
// named route block including its outer curly braces) and expands any import
|
||||
// directives found at the beginning of a line. The expansion is done by
|
||||
// creating a temporary parser that shares the same snippets and import graph,
|
||||
// then looping through the tokens and calling doImport whenever an import
|
||||
// directive is encountered. All other tokens are left untouched.
|
||||
func (p *parser) expandImportsInBlock(tokens []Token) ([]Token, error) {
|
||||
// Create a temporary parser that operates on the provided tokens.
|
||||
// The Dispenser is initialized with the token slice; snippets and the
|
||||
// import graph are shared so that imports and cycle detection work
|
||||
// consistently across the whole Caddyfile.
|
||||
tempParser := &parser{
|
||||
Dispenser: NewDispenser(tokens),
|
||||
definedSnippets: p.definedSnippets,
|
||||
importGraph: p.importGraph,
|
||||
}
|
||||
|
||||
// Loop through the tokens. We only care about import directives that
|
||||
// appear at the start of a line (same logic as directives()).
|
||||
for tempParser.Next() {
|
||||
if tempParser.Val() == "import" && tempParser.isNewLine() {
|
||||
if err := tempParser.doImport(1); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Roll back the cursor so the next iteration sees the first
|
||||
// token of the imported content (or the next token after it).
|
||||
tempParser.cursor--
|
||||
}
|
||||
}
|
||||
|
||||
// The temporary parser's token slice has been modified in place by
|
||||
// doImport, so we return it directly.
|
||||
return tempParser.tokens, nil
|
||||
}
|
||||
|
||||
// doSingleImport lexes the individual file at importFile and returns
|
||||
// its tokens or an error, if any.
|
||||
func (p *parser) doSingleImport(importFile string) ([]Token, error) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,62 @@
|
|||
(common) {
|
||||
respond "from snippet"
|
||||
}
|
||||
|
||||
&(foo) {
|
||||
import common
|
||||
}
|
||||
|
||||
localhost:9080 {
|
||||
invoke foo
|
||||
}
|
||||
----------
|
||||
{
|
||||
"apps": {
|
||||
"http": {
|
||||
"servers": {
|
||||
"srv0": {
|
||||
"listen": [
|
||||
":9080"
|
||||
],
|
||||
"routes": [
|
||||
{
|
||||
"match": [
|
||||
{
|
||||
"host": [
|
||||
"localhost"
|
||||
]
|
||||
}
|
||||
],
|
||||
"handle": [
|
||||
{
|
||||
"handler": "subroute",
|
||||
"routes": [
|
||||
{
|
||||
"handle": [
|
||||
{
|
||||
"handler": "invoke",
|
||||
"name": "foo"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"terminal": true
|
||||
}
|
||||
],
|
||||
"named_routes": {
|
||||
"foo": {
|
||||
"handle": [
|
||||
{
|
||||
"body": "from snippet",
|
||||
"handler": "static_response"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
(common) {
|
||||
respond "{args.0}"
|
||||
}
|
||||
|
||||
&(foo) {
|
||||
import common "hello"
|
||||
}
|
||||
|
||||
localhost:9080 {
|
||||
invoke foo
|
||||
}
|
||||
----------
|
||||
{
|
||||
"apps": {
|
||||
"http": {
|
||||
"servers": {
|
||||
"srv0": {
|
||||
"listen": [
|
||||
":9080"
|
||||
],
|
||||
"routes": [
|
||||
{
|
||||
"match": [
|
||||
{
|
||||
"host": [
|
||||
"localhost"
|
||||
]
|
||||
}
|
||||
],
|
||||
"handle": [
|
||||
{
|
||||
"handler": "subroute",
|
||||
"routes": [
|
||||
{
|
||||
"handle": [
|
||||
{
|
||||
"handler": "invoke",
|
||||
"name": "foo"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"terminal": true
|
||||
}
|
||||
],
|
||||
"named_routes": {
|
||||
"foo": {
|
||||
"handle": [
|
||||
{
|
||||
"body": "hello",
|
||||
"handler": "static_response"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
(common) {
|
||||
route /api/* {
|
||||
respond "api"
|
||||
}
|
||||
}
|
||||
|
||||
&(foo) {
|
||||
import common
|
||||
}
|
||||
|
||||
localhost:9080 {
|
||||
invoke foo
|
||||
}
|
||||
----------
|
||||
{
|
||||
"apps": {
|
||||
"http": {
|
||||
"servers": {
|
||||
"srv0": {
|
||||
"listen": [
|
||||
":9080"
|
||||
],
|
||||
"routes": [
|
||||
{
|
||||
"match": [
|
||||
{
|
||||
"host": [
|
||||
"localhost"
|
||||
]
|
||||
}
|
||||
],
|
||||
"handle": [
|
||||
{
|
||||
"handler": "subroute",
|
||||
"routes": [
|
||||
{
|
||||
"handle": [
|
||||
{
|
||||
"handler": "invoke",
|
||||
"name": "foo"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"terminal": true
|
||||
}
|
||||
],
|
||||
"named_routes": {
|
||||
"foo": {
|
||||
"handle": [
|
||||
{
|
||||
"handler": "subroute",
|
||||
"routes": [
|
||||
{
|
||||
"handle": [
|
||||
{
|
||||
"handler": "subroute",
|
||||
"routes": [
|
||||
{
|
||||
"handle": [
|
||||
{
|
||||
"body": "api",
|
||||
"handler": "static_response"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"match": [
|
||||
{
|
||||
"path": [
|
||||
"/api/*"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
(inner) {
|
||||
respond "inner"
|
||||
}
|
||||
|
||||
(outer) {
|
||||
import inner
|
||||
}
|
||||
|
||||
&(foo) {
|
||||
import outer
|
||||
}
|
||||
|
||||
localhost:9080 {
|
||||
invoke foo
|
||||
}
|
||||
----------
|
||||
{
|
||||
"apps": {
|
||||
"http": {
|
||||
"servers": {
|
||||
"srv0": {
|
||||
"listen": [
|
||||
":9080"
|
||||
],
|
||||
"routes": [
|
||||
{
|
||||
"match": [
|
||||
{
|
||||
"host": [
|
||||
"localhost"
|
||||
]
|
||||
}
|
||||
],
|
||||
"handle": [
|
||||
{
|
||||
"handler": "subroute",
|
||||
"routes": [
|
||||
{
|
||||
"handle": [
|
||||
{
|
||||
"handler": "invoke",
|
||||
"name": "foo"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"terminal": true
|
||||
}
|
||||
],
|
||||
"named_routes": {
|
||||
"foo": {
|
||||
"handle": [
|
||||
{
|
||||
"body": "inner",
|
||||
"handler": "static_response"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue