@marcel91200 / caddy Mirror · read-only
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 10, 22:30 UTC

master
go 160 lines 4.99 KB
Raw
1 // Copyright 2015 Matthew Holt and The Caddy Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 package caddy
16
17 import (
18 "os"
19 "path/filepath"
20 "runtime"
21
22 "github.com/caddyserver/certmagic"
23 "go.uber.org/zap"
24 )
25
26 // StorageConverter is a type that can convert itself
27 // to a valid, usable certmagic.Storage value. (The
28 // value might be short-lived.) This interface allows
29 // us to adapt any CertMagic storage implementation
30 // into a consistent API for Caddy configuration.
31 type StorageConverter interface {
32 CertMagicStorage() (certmagic.Storage, error)
33 }
34
35 // HomeDir returns the best guess of the current user's home
36 // directory from environment variables. If unknown, "." (the
37 // current directory) is returned instead, except GOOS=android,
38 // which returns "/sdcard".
39 func HomeDir() string {
40 home := homeDirUnsafe()
41 if home == "" && runtime.GOOS == "android" {
42 home = "/sdcard"
43 }
44 if home == "" {
45 home = "."
46 }
47 return home
48 }
49
50 // homeDirUnsafe is a low-level function that returns
51 // the user's home directory from environment
52 // variables. Careful: if it cannot be determined, an
53 // empty string is returned. If not accounting for
54 // that case, use HomeDir() instead; otherwise you
55 // may end up using the root of the file system.
56 func homeDirUnsafe() string {
57 home := os.Getenv("HOME")
58 if home == "" && runtime.GOOS == "windows" {
59 drive := os.Getenv("HOMEDRIVE")
60 path := os.Getenv("HOMEPATH")
61 home = drive + path
62 if drive == "" || path == "" {
63 home = os.Getenv("USERPROFILE")
64 }
65 }
66 if home == "" && runtime.GOOS == "plan9" {
67 home = os.Getenv("home")
68 }
69 return home
70 }
71
72 // AppConfigDir returns the directory where to store user's config.
73 //
74 // If XDG_CONFIG_HOME is set, it returns: $XDG_CONFIG_HOME/caddy.
75 // Otherwise, os.UserConfigDir() is used; if successful, it appends
76 // "Caddy" (Windows & Mac) or "caddy" (every other OS) to the path.
77 // If it returns an error, the fallback path "./caddy" is returned.
78 //
79 // The config directory is not guaranteed to be different from
80 // AppDataDir().
81 //
82 // Unlike os.UserConfigDir(), this function prefers the
83 // XDG_CONFIG_HOME env var on all platforms, not just Unix.
84 //
85 // Ref: https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
86 func AppConfigDir() string {
87 if basedir := os.Getenv("XDG_CONFIG_HOME"); basedir != "" {
88 return filepath.Join(basedir, "caddy")
89 }
90 basedir, err := os.UserConfigDir()
91 if err != nil {
92 Log().Warn("unable to determine directory for user configuration; falling back to current directory", zap.Error(err))
93 return "./caddy"
94 }
95 subdir := "caddy"
96 switch runtime.GOOS {
97 case "windows", "darwin":
98 subdir = "Caddy"
99 }
100 return filepath.Join(basedir, subdir)
101 }
102
103 // AppDataDir returns a directory path that is suitable for storing
104 // application data on disk. It uses the environment for finding the
105 // best place to store data, and appends a "caddy" or "Caddy" (depending
106 // on OS and environment) subdirectory.
107 //
108 // For a base directory path:
109 // If XDG_DATA_HOME is set, it returns: $XDG_DATA_HOME/caddy; otherwise,
110 // on Windows it returns: %AppData%/Caddy,
111 // on Mac: $HOME/Library/Application Support/Caddy,
112 // on Plan9: $home/lib/caddy,
113 // on Android: $HOME/caddy,
114 // and on everything else: $HOME/.local/share/caddy.
115 //
116 // If a data directory cannot be determined, it returns "./caddy"
117 // (this is not ideal, and the environment should be fixed).
118 //
119 // The data directory is not guaranteed to be different from AppConfigDir().
120 //
121 // Ref: https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
122 func AppDataDir() string {
123 if basedir := os.Getenv("XDG_DATA_HOME"); basedir != "" {
124 return filepath.Join(basedir, "caddy")
125 }
126 switch runtime.GOOS {
127 case "windows":
128 appData := os.Getenv("AppData")
129 if appData != "" {
130 return filepath.Join(appData, "Caddy")
131 }
132 case "darwin":
133 home := homeDirUnsafe()
134 if home != "" {
135 return filepath.Join(home, "Library", "Application Support", "Caddy")
136 }
137 case "plan9":
138 home := homeDirUnsafe()
139 if home != "" {
140 return filepath.Join(home, "lib", "caddy")
141 }
142 case "android":
143 home := homeDirUnsafe()
144 if home != "" {
145 return filepath.Join(home, "caddy")
146 }
147 default:
148 home := homeDirUnsafe()
149 if home != "" {
150 return filepath.Join(home, ".local", "share", "caddy")
151 }
152 }
153 return "./caddy"
154 }
155
156 // ConfigAutosavePath is the default path to which the last config will be persisted.
157 var ConfigAutosavePath = filepath.Join(AppConfigDir(), "autosave.json")
158
159 // DefaultStorage is Caddy's default storage module.
160 var DefaultStorage = &certmagic.FileStorage{Path: AppDataDir()}