diff --git a/internal/cmd/proxy.go b/internal/cmd/proxy.go index f272af30..c0728f43 100644 --- a/internal/cmd/proxy.go +++ b/internal/cmd/proxy.go @@ -4,11 +4,14 @@ import ( "context" "crypto/tls" "fmt" + "io/fs" "log/slog" "net" "net/netip" "net/url" "os" + "path" + "path/filepath" "strings" "time" @@ -514,7 +517,7 @@ func (conf *configuration) hostsFiles(ctx context.Context, l *slog.Logger) (path l.DebugContext(ctx, "hosts files are enabled") if len(conf.HostsFiles) > 0 { - return conf.HostsFiles, nil + return prepareHostsFilesPaths(conf.HostsFiles) } paths, err = hostsfile.DefaultHostsPaths() @@ -526,3 +529,40 @@ func (conf *configuration) hostsFiles(ctx context.Context, l *slog.Logger) (path return paths, nil } + +func prepareHostsFilesPaths(paths []string) (res []string, err error) { + defer func() { err = errors.Annotate(err, "preparing hosts files paths: %w") }() + + execPath, err := os.Executable() + if err != nil { + // Don't wrap the error, as it will get annotated. + return nil, err + } + + execDir := filepath.Dir(execPath) + + var errs []error + for _, p := range paths { + if strings.HasPrefix(p, "./") { + p = path.Join(execDir, p) + } + + p = strings.TrimPrefix(p, "/") + + if !fs.ValidPath(p) { + errs = append(errs, fmt.Errorf("invalid path: %q", p)) + + continue + } + + res = append(res, p) + } + + err = errors.Join(errs...) + if err != nil { + // Don't wrap the error, as it will get annotated. + return nil, err + } + + return res, nil +}