mirror of
https://github.com/caddyserver/caddy.git
synced 2025-02-02 14:17:01 +01:00
Merge branch 'master' into macros
This commit is contained in:
commit
9ebc11d775
25 changed files with 245 additions and 60 deletions
|
@ -57,7 +57,12 @@ Caddy binaries have no dependencies and are available for every platform. Get Ca
|
|||
customize your build in the browser
|
||||
- **[Latest release](https://github.com/mholt/caddy/releases/latest)** for
|
||||
pre-built, vanilla binaries
|
||||
- **go get** to build from source: `go get github.com/mholt/caddy/caddy` (requires Go 1.8 or newer) - to build with proper version information (required when filing issues), `cd` to the `caddy` folder and use `go get github.com/caddyserver/builds` followed by `go run build.go`.
|
||||
|
||||
## Build
|
||||
To build from source you need **[Git](https://git-scm.com/downloads)** and **[Go](https://golang.org/doc/install)** (1.8 or newer). Follow these instruction for fast building:
|
||||
|
||||
- Get source `go get github.com/mholt/caddy/caddy` and then run `go get github.com/caddyserver/builds`
|
||||
- Now `cd` to `$GOPATH/src/github.com/mholt/caddy/caddy` and run `go run build.go`
|
||||
|
||||
Then make sure the `caddy` binary is in your PATH.
|
||||
|
||||
|
|
|
@ -25,9 +25,15 @@ func TestAssetsPath(t *testing.T) {
|
|||
t.Errorf("Expected path to be a .caddy folder, got: %v", actual)
|
||||
}
|
||||
|
||||
os.Setenv("CADDYPATH", "testpath")
|
||||
err := os.Setenv("CADDYPATH", "testpath")
|
||||
if err != nil {
|
||||
t.Error("Could not set CADDYPATH")
|
||||
}
|
||||
if actual, expected := AssetsPath(), "testpath"; actual != expected {
|
||||
t.Errorf("Expected path to be %v, got: %v", expected, actual)
|
||||
}
|
||||
os.Setenv("CADDYPATH", "")
|
||||
err = os.Setenv("CADDYPATH", "")
|
||||
if err != nil {
|
||||
t.Error("Could not set CADDYPATH")
|
||||
}
|
||||
}
|
||||
|
|
38
caddy.go
38
caddy.go
|
@ -206,12 +206,15 @@ func (i *Instance) Restart(newCaddyfile Input) (*Instance, error) {
|
|||
|
||||
// success! stop the old instance
|
||||
for _, shutdownFunc := range i.onShutdown {
|
||||
err := shutdownFunc()
|
||||
err = shutdownFunc()
|
||||
if err != nil {
|
||||
return i, err
|
||||
}
|
||||
}
|
||||
i.Stop()
|
||||
err = i.Stop()
|
||||
if err != nil {
|
||||
return i, err
|
||||
}
|
||||
|
||||
// Execute instantiation events
|
||||
EmitEvent(InstanceStartupEvent, newInst)
|
||||
|
@ -483,14 +486,14 @@ func startWithListenerFds(cdyfile Input, inst *Instance, restartFds map[string]r
|
|||
if !IsUpgrade() && restartFds == nil {
|
||||
// first startup means not a restart or upgrade
|
||||
for _, firstStartupFunc := range inst.onFirstStartup {
|
||||
err := firstStartupFunc()
|
||||
err = firstStartupFunc()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, startupFunc := range inst.onStartup {
|
||||
err := startupFunc()
|
||||
err = startupFunc()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -565,12 +568,7 @@ func ValidateAndExecuteDirectives(cdyfile Input, inst *Instance, justValidate bo
|
|||
return err
|
||||
}
|
||||
|
||||
err = executeDirectives(inst, cdyfile.Path(), stype.Directives(), sblocks, justValidate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return executeDirectives(inst, cdyfile.Path(), stype.Directives(), sblocks, justValidate)
|
||||
}
|
||||
|
||||
func executeDirectives(inst *Instance, filename string,
|
||||
|
@ -658,7 +656,10 @@ func startServers(serverList []Server, inst *Instance, restartFds map[string]res
|
|||
if fdIndex, ok := loadedGob.ListenerFds["tcp"+addr]; ok {
|
||||
file := os.NewFile(fdIndex, "")
|
||||
ln, err = net.FileListener(file)
|
||||
file.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = file.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -666,7 +667,10 @@ func startServers(serverList []Server, inst *Instance, restartFds map[string]res
|
|||
if fdIndex, ok := loadedGob.ListenerFds["udp"+addr]; ok {
|
||||
file := os.NewFile(fdIndex, "")
|
||||
pc, err = net.FilePacketConn(file)
|
||||
file.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = file.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -689,7 +693,10 @@ func startServers(serverList []Server, inst *Instance, restartFds map[string]res
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
file.Close()
|
||||
err = file.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// packetconn
|
||||
if old.packet != nil {
|
||||
|
@ -701,7 +708,10 @@ func startServers(serverList []Server, inst *Instance, restartFds map[string]res
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
file.Close()
|
||||
err = file.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -252,7 +252,7 @@ func directoryListing(files []os.FileInfo, canGoUp bool, urlPath string, config
|
|||
for _, f := range files {
|
||||
name := f.Name()
|
||||
|
||||
for _, indexName := range staticfiles.IndexPages {
|
||||
for _, indexName := range config.Fs.IndexPages {
|
||||
if name == indexName {
|
||||
hasIndexFile = true
|
||||
break
|
||||
|
|
|
@ -78,8 +78,9 @@ func browseParse(c *caddy.Controller) ([]Config, error) {
|
|||
}
|
||||
|
||||
bc.Fs = staticfiles.FileServer{
|
||||
Root: http.Dir(cfg.Root),
|
||||
Hide: cfg.HiddenFiles,
|
||||
Root: http.Dir(cfg.Root),
|
||||
Hide: cfg.HiddenFiles,
|
||||
IndexPages: cfg.IndexPages,
|
||||
}
|
||||
|
||||
// Second argument would be the template file to use
|
||||
|
|
|
@ -27,6 +27,7 @@ import (
|
|||
|
||||
"github.com/mholt/caddy"
|
||||
"github.com/mholt/caddy/caddyfile"
|
||||
"github.com/mholt/caddy/caddyhttp/staticfiles"
|
||||
"github.com/mholt/caddy/caddytls"
|
||||
)
|
||||
|
||||
|
@ -155,6 +156,7 @@ func (h *httpContext) InspectServerBlocks(sourceFile string, serverBlocks []cadd
|
|||
AltTLSSNIPort: altTLSSNIPort,
|
||||
},
|
||||
originCaddyfile: sourceFile,
|
||||
IndexPages: staticfiles.DefaultIndexPages,
|
||||
}
|
||||
h.saveConfig(key, cfg)
|
||||
}
|
||||
|
@ -234,7 +236,7 @@ func GetConfig(c *caddy.Controller) *SiteConfig {
|
|||
// we should only get here during tests because directive
|
||||
// actions typically skip the server blocks where we make
|
||||
// the configs
|
||||
cfg := &SiteConfig{Root: Root, TLS: new(caddytls.Config)}
|
||||
cfg := &SiteConfig{Root: Root, TLS: new(caddytls.Config), IndexPages: staticfiles.DefaultIndexPages}
|
||||
ctx.saveConfig(key, cfg)
|
||||
return cfg
|
||||
}
|
||||
|
|
|
@ -142,7 +142,7 @@ func NewServer(addr string, group []*SiteConfig) (*Server, error) {
|
|||
|
||||
// Compile custom middleware for every site (enables virtual hosting)
|
||||
for _, site := range group {
|
||||
stack := Handler(staticfiles.FileServer{Root: http.Dir(site.Root), Hide: site.HiddenFiles})
|
||||
stack := Handler(staticfiles.FileServer{Root: http.Dir(site.Root), Hide: site.HiddenFiles, IndexPages: site.IndexPages})
|
||||
for i := len(site.middleware) - 1; i >= 0; i-- {
|
||||
stack = site.middleware[i](stack)
|
||||
}
|
||||
|
|
|
@ -26,6 +26,9 @@ type SiteConfig struct {
|
|||
// The address of the site
|
||||
Addr Address
|
||||
|
||||
// The list of viable index page names of the site
|
||||
IndexPages []string
|
||||
|
||||
// The hostname to bind listener to;
|
||||
// defaults to Addr.Host
|
||||
ListenHost string
|
||||
|
|
|
@ -16,7 +16,7 @@ package index
|
|||
|
||||
import (
|
||||
"github.com/mholt/caddy"
|
||||
"github.com/mholt/caddy/caddyhttp/staticfiles"
|
||||
"github.com/mholt/caddy/caddyhttp/httpserver"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -29,6 +29,8 @@ func init() {
|
|||
func setupIndex(c *caddy.Controller) error {
|
||||
var index []string
|
||||
|
||||
cfg := httpserver.GetConfig(c)
|
||||
|
||||
for c.Next() {
|
||||
args := c.RemainingArgs()
|
||||
|
||||
|
@ -40,7 +42,7 @@ func setupIndex(c *caddy.Controller) error {
|
|||
index = append(index, in)
|
||||
}
|
||||
|
||||
staticfiles.IndexPages = index
|
||||
cfg.IndexPages = index
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/mholt/caddy"
|
||||
"github.com/mholt/caddy/caddyhttp/httpserver"
|
||||
"github.com/mholt/caddy/caddyhttp/staticfiles"
|
||||
)
|
||||
|
||||
|
@ -31,7 +32,7 @@ func TestIndexIncompleteParams(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestIndex(t *testing.T) {
|
||||
c := caddy.NewTestController("", "index a.html b.html c.html")
|
||||
c := caddy.NewTestController("http", "index a.html b.html c.html")
|
||||
|
||||
err := setupIndex(c)
|
||||
if err != nil {
|
||||
|
@ -40,14 +41,85 @@ func TestIndex(t *testing.T) {
|
|||
|
||||
expectedIndex := []string{"a.html", "b.html", "c.html"}
|
||||
|
||||
if len(staticfiles.IndexPages) != 3 {
|
||||
t.Errorf("Expected 3 values, got %v", len(staticfiles.IndexPages))
|
||||
siteConfig := httpserver.GetConfig(c)
|
||||
|
||||
if len(siteConfig.IndexPages) != len(expectedIndex) {
|
||||
t.Errorf("Expected 3 values, got %v", len(siteConfig.IndexPages))
|
||||
}
|
||||
|
||||
// Ensure ordering is correct
|
||||
for i, actual := range staticfiles.IndexPages {
|
||||
for i, actual := range siteConfig.IndexPages {
|
||||
if actual != expectedIndex[i] {
|
||||
t.Errorf("Expected value in position %d to be %v, got %v", i, expectedIndex[i], actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultiSiteIndexWithEitherHasDefault(t *testing.T) {
|
||||
// TestIndex already covers the correctness of the directive
|
||||
// when used on a single controller, so no need to verify test setupIndex again.
|
||||
// This sets the stage for the actual verification.
|
||||
customIndex := caddy.NewTestController("http", "index a.html b.html")
|
||||
|
||||
// setupIndex against customIdx should not pollute the
|
||||
// index list for other controllers.
|
||||
err := setupIndex(customIndex)
|
||||
if err != nil {
|
||||
t.Errorf("Expected no errors, got: %v", err)
|
||||
}
|
||||
|
||||
// Represents a virtual host with no index directive.
|
||||
defaultIndex := caddy.NewTestController("http", "")
|
||||
|
||||
// Not calling setupIndex because it guards against lack of arguments,
|
||||
// and we need to ensure the site gets the default set of index pages.
|
||||
|
||||
siteConfig := httpserver.GetConfig(defaultIndex)
|
||||
|
||||
// In case the index directive is not used, the virtual host
|
||||
// should receive staticfiles.DefaultIndexPages slice. The length, as checked here,
|
||||
// and the values, as checked in the upcoming loop, should match.
|
||||
if len(siteConfig.IndexPages) != len(staticfiles.DefaultIndexPages) {
|
||||
t.Errorf("Expected %d values, got %d", len(staticfiles.DefaultIndexPages), len(siteConfig.IndexPages))
|
||||
}
|
||||
|
||||
// Ensure values match the expected default index pages
|
||||
for i, actual := range siteConfig.IndexPages {
|
||||
if actual != staticfiles.DefaultIndexPages[i] {
|
||||
t.Errorf("Expected value in position %d to be %v, got %v", i, staticfiles.DefaultIndexPages[i], actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPerSiteIndexPageIsolation(t *testing.T) {
|
||||
firstIndex := "first.html"
|
||||
secondIndex := "second.html"
|
||||
|
||||
// Create two sites with different index page configurations
|
||||
firstSite := caddy.NewTestController("http", "index first.html")
|
||||
err := setupIndex(firstSite)
|
||||
if err != nil {
|
||||
t.Errorf("Expected no errors, got: %v", err)
|
||||
}
|
||||
|
||||
secondSite := caddy.NewTestController("http", "index second.html")
|
||||
err = setupIndex(secondSite)
|
||||
if err != nil {
|
||||
t.Errorf("Expected no errors, got: %v", err)
|
||||
}
|
||||
|
||||
firstSiteConfig := httpserver.GetConfig(firstSite)
|
||||
if firstSiteConfig.IndexPages[0] != firstIndex {
|
||||
t.Errorf("Expected index for first site as %s, received %s", firstIndex, firstSiteConfig.IndexPages[0])
|
||||
}
|
||||
|
||||
secondSiteConfig := httpserver.GetConfig(secondSite)
|
||||
if secondSiteConfig.IndexPages[0] != secondIndex {
|
||||
t.Errorf("Expected index for second site as %s, received %s", secondIndex, secondSiteConfig.IndexPages[0])
|
||||
}
|
||||
|
||||
// They should have different index pages, as per the provided config.
|
||||
if firstSiteConfig.IndexPages[0] == secondSiteConfig.IndexPages[0] {
|
||||
t.Errorf("Expected different index pages for both sites, got %s for first and %s for second", firstSiteConfig.IndexPages[0], secondSiteConfig.IndexPages[0])
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/mholt/caddy/caddyhttp/httpserver"
|
||||
"github.com/mholt/caddy/caddyhttp/staticfiles"
|
||||
)
|
||||
|
||||
func (h Middleware) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||
|
@ -44,7 +43,7 @@ outer:
|
|||
matches := httpserver.Path(urlPath).Matches(rule.Path)
|
||||
// Also check IndexPages when requesting a directory
|
||||
if !matches {
|
||||
indexFile, isIndexFile := httpserver.IndexFile(h.Root, urlPath, staticfiles.IndexPages)
|
||||
indexFile, isIndexFile := httpserver.IndexFile(h.Root, urlPath, h.indexPages)
|
||||
if isIndexFile {
|
||||
matches = httpserver.Path(indexFile).Matches(rule.Path)
|
||||
}
|
||||
|
|
|
@ -393,7 +393,8 @@ func TestMiddlewareShouldPushIndexFile(t *testing.T) {
|
|||
{Path: "/index.css", Method: http.MethodGet},
|
||||
}},
|
||||
},
|
||||
Root: http.Dir(root),
|
||||
Root: http.Dir(root),
|
||||
indexPages: []string{indexFile},
|
||||
}
|
||||
|
||||
indexFilePath := filepath.Join(root, indexFile)
|
||||
|
|
|
@ -36,9 +36,10 @@ type (
|
|||
|
||||
// Middleware supports pushing resources to clients
|
||||
Middleware struct {
|
||||
Next httpserver.Handler
|
||||
Rules []Rule
|
||||
Root http.FileSystem
|
||||
Next httpserver.Handler
|
||||
Rules []Rule
|
||||
Root http.FileSystem
|
||||
indexPages []string // will be injected from SiteConfig on setup
|
||||
}
|
||||
|
||||
ruleOp func([]Resource)
|
||||
|
|
|
@ -50,7 +50,7 @@ func setup(c *caddy.Controller) error {
|
|||
|
||||
cfg := httpserver.GetConfig(c)
|
||||
cfg.AddMiddleware(func(next httpserver.Handler) httpserver.Handler {
|
||||
return Middleware{Next: next, Rules: rules, Root: http.Dir(cfg.Root)}
|
||||
return Middleware{Next: next, Rules: rules, Root: http.Dir(cfg.Root), indexPages: cfg.IndexPages}
|
||||
})
|
||||
|
||||
return nil
|
||||
|
|
|
@ -45,6 +45,10 @@ import (
|
|||
type FileServer struct {
|
||||
Root http.FileSystem // jailed access to the file system
|
||||
Hide []string // list of files for which to respond with "Not Found"
|
||||
|
||||
// A list of pages that may be understood as the "index" files to directories.
|
||||
// Injected from *SiteConfig.
|
||||
IndexPages []string
|
||||
}
|
||||
|
||||
// ServeHTTP serves static files for r according to fs's configuration.
|
||||
|
@ -118,7 +122,7 @@ func (fs FileServer) serveFile(w http.ResponseWriter, r *http.Request) (int, err
|
|||
// if an index file was explicitly requested, strip file name from the request
|
||||
// ("/foo/index.html" -> "/foo/")
|
||||
var requestPage = path.Base(urlCopy.Path)
|
||||
for _, indexPage := range IndexPages {
|
||||
for _, indexPage := range fs.IndexPages {
|
||||
if requestPage == indexPage {
|
||||
urlCopy.Path = urlCopy.Path[:len(urlCopy.Path)-len(indexPage)]
|
||||
redir = true
|
||||
|
@ -134,7 +138,7 @@ func (fs FileServer) serveFile(w http.ResponseWriter, r *http.Request) (int, err
|
|||
|
||||
// use contents of an index file, if present, for directory requests
|
||||
if d.IsDir() {
|
||||
for _, indexPage := range IndexPages {
|
||||
for _, indexPage := range fs.IndexPages {
|
||||
indexPath := path.Join(reqPath, indexPage)
|
||||
indexFile, err := fs.Root.Open(indexPath)
|
||||
if err != nil {
|
||||
|
@ -253,9 +257,9 @@ func calculateEtag(d os.FileInfo) string {
|
|||
return `"` + t + s + `"`
|
||||
}
|
||||
|
||||
// IndexPages is a list of pages that may be understood as
|
||||
// DefaultIndexPages is a list of pages that may be understood as
|
||||
// the "index" files to directories.
|
||||
var IndexPages = []string{
|
||||
var DefaultIndexPages = []string{
|
||||
"index.html",
|
||||
"index.htm",
|
||||
"index.txt",
|
||||
|
|
|
@ -36,8 +36,9 @@ func TestServeHTTP(t *testing.T) {
|
|||
defer afterServeHTTPTest(t, tmpWebRootDir)
|
||||
|
||||
fileserver := FileServer{
|
||||
Root: http.Dir(filepath.Join(tmpWebRootDir, webrootName)),
|
||||
Hide: []string{"dir/hidden.html"},
|
||||
Root: http.Dir(filepath.Join(tmpWebRootDir, webrootName)),
|
||||
Hide: []string{"dir/hidden.html"},
|
||||
IndexPages: DefaultIndexPages,
|
||||
}
|
||||
|
||||
movedPermanently := "Moved Permanently"
|
||||
|
|
|
@ -148,6 +148,11 @@ type OnDemandState struct {
|
|||
// Set from max_certs in tls config, it specifies the
|
||||
// maximum number of certificates that can be issued.
|
||||
MaxObtain int32
|
||||
|
||||
// The url to call to check if an on-demand tls certificate should
|
||||
// be issued. If a request to the URL fails or returns a non 2xx
|
||||
// status on-demand issuances must fail.
|
||||
AskURL *url.URL
|
||||
}
|
||||
|
||||
// ObtainCert obtains a certificate for name using c, as long
|
||||
|
|
|
@ -19,6 +19,8 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
@ -135,8 +137,8 @@ func (cfg *Config) getCertDuringHandshake(name string, loadIfNecessary, obtainIf
|
|||
|
||||
name = strings.ToLower(name)
|
||||
|
||||
// Make sure aren't over any applicable limits
|
||||
err := cfg.checkLimitsForObtainingNewCerts(name)
|
||||
// Make sure the certificate should be obtained based on config
|
||||
err := cfg.checkIfCertShouldBeObtained(name)
|
||||
if err != nil {
|
||||
return Certificate{}, err
|
||||
}
|
||||
|
@ -159,10 +161,52 @@ func (cfg *Config) getCertDuringHandshake(name string, loadIfNecessary, obtainIf
|
|||
return Certificate{}, fmt.Errorf("no certificate available for %s", name)
|
||||
}
|
||||
|
||||
// checkIfCertShouldBeObtained checks to see if an on-demand tls certificate
|
||||
// should be obtained for a given domain based upon the config settings. If
|
||||
// a non-nil error is returned, do not issue a new certificate for name.
|
||||
func (cfg *Config) checkIfCertShouldBeObtained(name string) error {
|
||||
// If the "ask" URL is defined in the config, use to determine if a
|
||||
// cert should obtained
|
||||
if cfg.OnDemandState.AskURL != nil {
|
||||
return cfg.checkURLForObtainingNewCerts(name)
|
||||
}
|
||||
|
||||
// Otherwise use the limit defined by the "max_certs" setting
|
||||
return cfg.checkLimitsForObtainingNewCerts(name)
|
||||
}
|
||||
|
||||
func (cfg *Config) checkURLForObtainingNewCerts(name string) error {
|
||||
client := http.Client{
|
||||
Timeout: 10 * time.Second,
|
||||
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
||||
return errors.New("following http redirects is not allowed")
|
||||
},
|
||||
}
|
||||
|
||||
// Copy the URL from the config in order to modify it for this request
|
||||
askURL := new(url.URL)
|
||||
*askURL = *cfg.OnDemandState.AskURL
|
||||
|
||||
query := askURL.Query()
|
||||
query.Set("domain", name)
|
||||
askURL.RawQuery = query.Encode()
|
||||
|
||||
resp, err := client.Get(askURL.String())
|
||||
if err != nil {
|
||||
return fmt.Errorf("error checking %v to deterine if certificate for hostname '%s' should be allowed: %v", cfg.OnDemandState.AskURL, name, err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode < 200 || resp.StatusCode > 299 {
|
||||
return fmt.Errorf("certificate for hostname '%s' not allowed, non-2xx status code %d returned from %v", name, resp.StatusCode, cfg.OnDemandState.AskURL)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// checkLimitsForObtainingNewCerts checks to see if name can be issued right
|
||||
// now according to mitigating factors we keep track of and preferences the
|
||||
// user has set. If a non-nil error is returned, do not issue a new certificate
|
||||
// for name.
|
||||
// now according the maximum count defined in the configuration. If a non-nil
|
||||
// error is returned, do not issue a new certificate for name.
|
||||
func (cfg *Config) checkLimitsForObtainingNewCerts(name string) error {
|
||||
// User can set hard limit for number of certs for the process to issue
|
||||
if cfg.OnDemandState.MaxObtain > 0 &&
|
||||
|
|
|
@ -21,6 +21,7 @@ import (
|
|||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
|
@ -49,7 +50,7 @@ func setupTLS(c *caddy.Controller) error {
|
|||
config.Enabled = true
|
||||
|
||||
for c.Next() {
|
||||
var certificateFile, keyFile, loadDir, maxCerts string
|
||||
var certificateFile, keyFile, loadDir, maxCerts, askURL string
|
||||
|
||||
args := c.RemainingArgs()
|
||||
switch len(args) {
|
||||
|
@ -164,6 +165,9 @@ func setupTLS(c *caddy.Controller) error {
|
|||
case "max_certs":
|
||||
c.Args(&maxCerts)
|
||||
config.OnDemand = true
|
||||
case "ask":
|
||||
c.Args(&askURL)
|
||||
config.OnDemand = true
|
||||
case "dns":
|
||||
args := c.RemainingArgs()
|
||||
if len(args) != 1 {
|
||||
|
@ -213,6 +217,19 @@ func setupTLS(c *caddy.Controller) error {
|
|||
config.OnDemandState.MaxObtain = int32(maxCertsNum)
|
||||
}
|
||||
|
||||
if askURL != "" {
|
||||
parsedURL, err := url.Parse(askURL)
|
||||
if err != nil {
|
||||
return c.Err("ask must be a valid url")
|
||||
}
|
||||
|
||||
if parsedURL.Scheme != "http" && parsedURL.Scheme != "https" {
|
||||
return c.Err("ask URL must use http or https")
|
||||
}
|
||||
|
||||
config.OnDemandState.AskURL = parsedURL
|
||||
}
|
||||
|
||||
// don't try to load certificates unless we're supposed to
|
||||
if !config.Enabled || !config.Manual {
|
||||
continue
|
||||
|
|
2
dist/init/freebsd/caddy
vendored
2
dist/init/freebsd/caddy
vendored
|
@ -62,7 +62,7 @@ fi
|
|||
pidfile="/var/run/${name}.pid"
|
||||
procname="${caddy_bin_path}" #enabled builtin pid checking for start / stop
|
||||
command="/usr/sbin/daemon"
|
||||
command_args="-u ${caddy_user} -p ${pidfile} /usr/bin/env ${caddy_env} ${procname} -cpu ${caddy_cpu} -log stdout -conf ${caddy_config_path} -agree -email ${caddy_cert_email} < /dev/null >> ${caddy_logfile} 2>&1"
|
||||
command_args="-p ${pidfile} /usr/bin/env ${caddy_env} ${procname} -cpu ${caddy_cpu} -log stdout -conf ${caddy_config_path} -agree -email ${caddy_cert_email} < /dev/null >> ${caddy_logfile} 2>&1"
|
||||
|
||||
start_precmd="caddy_startprecmd"
|
||||
|
||||
|
|
|
@ -28,10 +28,10 @@ func (cfg *Config) Hook(event caddy.EventName, info interface{}) error {
|
|||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
if nonblock {
|
||||
log.Printf("[INFO] Nonblocking Command with ID %s: \"%s %s\"", cfg.ID, cfg.Command, strings.Join(cfg.Args, " "))
|
||||
log.Printf("[INFO] Nonblocking Command \"%s %s\" with ID %s", cfg.Command, strings.Join(cfg.Args, " "), cfg.ID)
|
||||
return cmd.Start()
|
||||
}
|
||||
log.Printf("[INFO] Blocking Command with ID %s: \"%s %s\"", cfg.ID, cfg.Command, strings.Join(cfg.Args, " "))
|
||||
log.Printf("[INFO] Blocking Command \"%s %s\" with ID %s", cfg.Command, strings.Join(cfg.Args, " "), cfg.ID)
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -20,9 +20,12 @@ func setup(c *caddy.Controller) error {
|
|||
}
|
||||
|
||||
// Register Event Hooks.
|
||||
for _, cfg := range config {
|
||||
caddy.RegisterEventHook("on-"+cfg.ID, cfg.Hook)
|
||||
}
|
||||
c.OncePerServerBlock(func() error {
|
||||
for _, cfg := range config {
|
||||
caddy.RegisterEventHook("on-"+cfg.ID, cfg.Hook)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ func trapSignalsPosix() {
|
|||
}
|
||||
|
||||
// Kick off the restart; our work is done
|
||||
inst, err = inst.Restart(caddyfileToUse)
|
||||
_, err = inst.Restart(caddyfileToUse)
|
||||
if err != nil {
|
||||
log.Printf("[ERROR] SIGUSR1: %v", err)
|
||||
}
|
||||
|
|
|
@ -36,9 +36,12 @@ func Startup(c *caddy.Controller) error {
|
|||
}
|
||||
|
||||
// Register Event Hooks.
|
||||
for _, cfg := range config {
|
||||
caddy.RegisterEventHook("on-"+cfg.ID, cfg.Hook)
|
||||
}
|
||||
c.OncePerServerBlock(func() error {
|
||||
for _, cfg := range config {
|
||||
caddy.RegisterEventHook("on-"+cfg.ID, cfg.Hook)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
fmt.Println("NOTICE: Startup directive will be removed in a later version. Please migrate to 'on startup'")
|
||||
|
||||
|
|
12
upgrade.go
12
upgrade.go
|
@ -136,7 +136,10 @@ func Upgrade() error {
|
|||
|
||||
// immediately close our dup'ed fds and the write end of our signal pipe
|
||||
for _, f := range extraFiles {
|
||||
f.Close()
|
||||
err = f.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// feed Caddyfile to the child
|
||||
|
@ -144,11 +147,14 @@ func Upgrade() error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
wpipe.Close()
|
||||
err = wpipe.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// determine whether child startup succeeded
|
||||
answer, readErr := ioutil.ReadAll(sigrpipe)
|
||||
if answer == nil || len(answer) == 0 {
|
||||
if len(answer) == 0 {
|
||||
cmdErr := cmd.Wait() // get exit status
|
||||
errStr := fmt.Sprintf("child failed to initialize: %v", cmdErr)
|
||||
if readErr != nil {
|
||||
|
|
Loading…
Reference in a new issue