Skip to content

Commit 77eae3f

Browse files
authored
handle the include directive (#20)
* handle the include directive * simplify managing differences of default nginx config location across platforms
1 parent 4a48bb3 commit 77eae3f

File tree

5 files changed

+85
-17
lines changed

5 files changed

+85
-17
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ go 1.13
55
require (
66
github.com/caddyserver/caddy/v2 v2.0.0
77
github.com/caddyserver/ntlm-transport v0.1.1-0.20200409193839-5d99ab17e974
8+
github.com/hairyhenderson/go-which v0.2.0
89
)

go.sum

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t
358358
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
359359
github.com/grpc-ecosystem/grpc-gateway v1.12.1/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c=
360360
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
361+
github.com/hairyhenderson/go-which v0.2.0 h1:vxoCKdgYc6+MTBzkJYhWegksHjjxuXPNiqo5G2oBM+4=
362+
github.com/hairyhenderson/go-which v0.2.0/go.mod h1:U1BQQRCjxYHfOkXDyCgst7OZVknbqI7KuGKhGnmyIik=
361363
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
362364
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
363365
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
@@ -409,6 +411,7 @@ github.com/kolo/xmlrpc v0.0.0-20190717152603-07c4ee3fd181/go.mod h1:o03bZfuBwAXH
409411
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
410412
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
411413
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
414+
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
412415
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
413416
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
414417
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
@@ -506,6 +509,8 @@ github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJE
506509
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
507510
github.com/newrelic/go-agent v2.15.0+incompatible/go.mod h1:a8Fv1b/fYhFSReoTU6HDkTYIMZeSVNffmoS726Y0LzQ=
508511
github.com/ngdinhtoan/glide-cleanup v0.2.0/go.mod h1:UQzsmiDOb8YV3nOsCxK/c9zPpCZVNoHScRE3EO9pVMM=
512+
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
513+
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
509514
github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E=
510515
github.com/nrdcg/auroradns v1.0.0/go.mod h1:6JPXKzIRzZzMqtTDgueIhTi6rFf1QvYE/HzqidhOhjw=
511516
github.com/nrdcg/auroradns v1.0.1/go.mod h1:y4pc0i9QXYlFCWrhWrUSIETnZgrf4KuwjDIWmmXo3JI=
@@ -541,6 +546,7 @@ github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi
541546
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
542547
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
543548
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
549+
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
544550
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
545551
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
546552
github.com/pquerna/otp v1.0.0/go.mod h1:Zad1CMQfSQZI5KLpahDiSUX4tMMREnXw98IvL1nhgMk=
@@ -659,6 +665,8 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasO
659665
github.com/spf13/afero v1.1.0/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
660666
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
661667
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
668+
github.com/spf13/afero v1.3.3 h1:p5gZEKLYoL7wh8VrJesMaYeNxdEd1v3cb4irOk9zB54=
669+
github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4=
662670
github.com/spf13/cast v1.2.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg=
663671
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
664672
github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
@@ -781,6 +789,7 @@ golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACk
781789
golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
782790
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
783791
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
792+
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
784793
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
785794
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
786795
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@@ -966,6 +975,7 @@ golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBn
966975
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
967976
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
968977
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
978+
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
969979
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
970980
golang.org/x/tools v0.0.0-20190719005602-e377ae9d6386/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
971981
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
@@ -1076,6 +1086,8 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33
10761086
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
10771087
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
10781088
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
1089+
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
1090+
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
10791091
gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
10801092
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
10811093
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
@@ -1109,6 +1121,8 @@ gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
11091121
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
11101122
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
11111123
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
1124+
gotest.tools/v3 v3.0.2 h1:kG1BFyqVHuQoVQiR1bWGnfz/fmHvvuiSPIV7rvl360E=
1125+
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
11121126
grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=
11131127
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
11141128
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

lexer.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ import (
2121
"unicode"
2222
)
2323

24-
func tokenize(body []byte) []token {
25-
lex := newLexer("nginx.conf", bytes.NewReader(body))
24+
func tokenize(body []byte, filename string) []token {
25+
lex := newLexer(filename, bytes.NewReader(body))
2626

2727
var tokens []token
2828
for lex.nextToken() {

nginxadapter.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package nginxconf
1717
import (
1818
"encoding/json"
1919
"fmt"
20+
"path/filepath"
2021
"strconv"
2122
"strings"
2223

@@ -38,7 +39,12 @@ type Adapter struct{}
3839

3940
// Adapt converts the NGINX config in body to Caddy JSON.
4041
func (Adapter) Adapt(body []byte, options map[string]interface{}) ([]byte, []caddyconfig.Warning, error) {
41-
tokens := tokenize(body)
42+
filename := "nginx.conf"
43+
if v, ok := options["filename"].(string); ok {
44+
filename = v
45+
filename, _ = filepath.Abs(filename)
46+
}
47+
tokens := tokenize(body, filename)
4248
dirs, err := parse(tokens)
4349
if err != nil {
4450
return nil, nil, fmt.Errorf("parsing: %v", err)

parse.go

Lines changed: 61 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,48 @@ import (
2020
"io/ioutil"
2121
"os"
2222
"path/filepath"
23+
"runtime"
2324
"strings"
25+
26+
which "github.com/hairyhenderson/go-which"
2427
)
2528

29+
// Reference: https://wiki.debian.org/Nginx/DirectoryStructure
30+
var nginxConfPrefix string
31+
32+
func init() {
33+
switch runtime.GOOS {
34+
case "freebsd", "darwin":
35+
// https://www.cyberciti.biz/faq/freebsd-install-nginx-webserver/
36+
nginxConfPrefix = "/usr/local/etc/nginx"
37+
case "netbsd":
38+
// https://www.netbsd.mx/nginx-php.html
39+
nginxConfPrefix = "/usr/pkg/etc/nginx"
40+
case "solaris", "illumos":
41+
// https://www.nginx.com/resources/wiki/start/topics/tutorials/solaris_11/
42+
nginxConfPrefix = "/opt/local/nginx"
43+
for k, v := range nginxConfDirs {
44+
if v == "conf.d/" {
45+
nginxConfDirs[k] = "conf/"
46+
}
47+
}
48+
case "windows":
49+
// "nginx/Windows uses the directory where it has been run as the prefix for relative paths in the configuration."
50+
// Source: https://nginx.org/en/docs/windows.html
51+
// However, the "conf/" directory, where some of the standard snippets live, is neighboring the nginx.exe. Therefore,
52+
// it's more likely to hit a match in this root than elsewhere.
53+
nginxPath := which.Which("nginx.exe")
54+
nginxConfPrefix = filepath.Dir(nginxPath)
55+
for k, v := range nginxConfDirs {
56+
if v == "conf.d/" {
57+
nginxConfDirs[k] = "conf/"
58+
}
59+
}
60+
default:
61+
nginxConfPrefix = "/etc/nginx"
62+
}
63+
}
64+
2665
func parse(tokens []token) ([]Directive, error) {
2766
parser := nginxParser{tokens: tokens}
2867
return parser.nextBlock()
@@ -103,9 +142,6 @@ func (p *nginxParser) next() (Directive, error) {
103142
return dir, nil
104143
}
105144

106-
// Reference: https://wiki.debian.org/Nginx/DirectoryStructure
107-
const nginxConfPrefix = "/etc/nginx"
108-
109145
var nginxConfDirs = []string{
110146
"conf.d/",
111147
"modules-available/",
@@ -137,20 +173,25 @@ func (p *nginxParser) doInclude() error {
137173
// See issue #2096 - a pattern with many glob expansions can hang for too long
138174
return fmt.Errorf("Glob pattern may only contain one wildcard (*), but has others: %s", includeArg)
139175
}
176+
177+
// first assume the included file is relative
140178
var importedFiles []string
141-
if filepath.IsAbs(includeArg) {
142-
matches, err := filepath.Glob(includeArg)
143-
if err != nil {
144-
return err
145-
}
146-
for _, v := range matches {
147-
if _, err := os.Stat(v); !os.IsNotExist(err) {
148-
importedFiles = append(importedFiles, v)
149-
}
179+
globArg := includeArg
180+
if !filepath.IsAbs(includeArg) {
181+
currentConfDir := filepath.Dir(p.currentToken().file)
182+
globArg = filepath.Join(currentConfDir, includeArg)
183+
}
184+
matches, err := filepath.Glob(globArg)
185+
if err != nil {
186+
return err
187+
}
188+
for _, v := range matches {
189+
if _, err := os.Stat(v); !os.IsNotExist(err) {
190+
importedFiles = append(importedFiles, v)
150191
}
151192
}
152193

153-
// if not absolute, we'll only support including files within /etc/nginx/.
194+
// if not absolute, we'll only support including files within standard config location.
154195
if len(importedFiles) == 0 {
155196
// is it one of the standard files?
156197
for _, v := range nginxStdConfs {
@@ -159,6 +200,8 @@ func (p *nginxParser) doInclude() error {
159200
break
160201
}
161202
}
203+
}
204+
if len(importedFiles) == 0 {
162205
// by here it is not one of the direct descendant files of /etc/nginx/.
163206
// Is it in one of the subdirectories?
164207
//
@@ -175,6 +218,10 @@ func (p *nginxParser) doInclude() error {
175218
}
176219
}
177220

221+
if len(importedFiles) == 0 {
222+
return fmt.Errorf("included file is not found: %s:%d %s", includeToken.file, includeToken.line, includeArg)
223+
}
224+
178225
var importedTokens []token
179226
for _, importFile := range importedFiles {
180227
newTokens, err := p.doSingleInclude(importFile)
@@ -222,7 +269,7 @@ func (p *nginxParser) doSingleInclude(importFile string) ([]token, error) {
222269
// It returns all the tokens from the input, unstructured
223270
// and in order.
224271
func allTokens(filename string, input []byte) []token {
225-
tokens := tokenize(input)
272+
tokens := tokenize(input, filename)
226273
for i := range tokens {
227274
tokens[i].file = filename
228275
}

0 commit comments

Comments
 (0)