aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMatt Holt <[email protected]>2024-04-13 19:08:20 -0400
committerGitHub <[email protected]>2024-04-13 19:08:20 -0400
commitf698ad13da8d1e72bae33b6e9b9bb0a0fafaa0a6 (patch)
treea38d503777d879faa8edbf5dc3c15757e2b12930
parent61fecb130a2b3e5dc93b7656172c066d8701af7d (diff)
parentdc9dd2e4b3e266cb1267f672e3bcfd50c67cc3d4 (diff)
downloadcaddy-f698ad13da8d1e72bae33b6e9b9bb0a0fafaa0a6.tar.gz
caddy-f698ad13da8d1e72bae33b6e9b9bb0a0fafaa0a6.zip
Merge branch 'master' into zerosslzerossl
-rw-r--r--admin.go27
-rw-r--r--caddytest/integration/caddyfile_adapt/file_server_etag_file_extensions.caddyfiletest40
-rw-r--r--caddytest/integration/caddyfile_adapt/reverse_proxy_http_transport_tls_file_cert.txt47
-rw-r--r--caddytest/integration/caddyfile_adapt/reverse_proxy_http_transport_tls_inline_cert.txt47
-rw-r--r--cmd/main.go15
-rw-r--r--modules/caddyhttp/autohttps.go2
-rw-r--r--modules/caddyhttp/fileserver/browse.html2
-rw-r--r--modules/caddyhttp/fileserver/caddyfile.go7
-rw-r--r--modules/caddyhttp/fileserver/staticfiles.go38
-rw-r--r--modules/caddyhttp/reverseproxy/caddyfile.go29
-rw-r--r--modules/caddyhttp/reverseproxy/httptransport.go22
-rw-r--r--modules/caddyhttp/reverseproxy/httptransport_test.go96
-rw-r--r--modules/caddytls/tls.go7
13 files changed, 365 insertions, 14 deletions
diff --git a/admin.go b/admin.go
index 7c1e9e80e..3950a92fa 100644
--- a/admin.go
+++ b/admin.go
@@ -953,17 +953,28 @@ func makeEtag(path string, hash hash.Hash) string {
return fmt.Sprintf(`"%s %x"`, path, hash.Sum(nil))
}
+// This buffer pool is used to keep buffers for
+// reading the config file during eTag header generation
+var bufferPool = sync.Pool{
+ New: func() any {
+ return new(bytes.Buffer)
+ },
+}
+
func handleConfig(w http.ResponseWriter, r *http.Request) error {
switch r.Method {
case http.MethodGet:
w.Header().Set("Content-Type", "application/json")
- // Set the ETag as a trailer header.
- // The alternative is to write the config to a buffer, and
- // then hash that.
- w.Header().Set("Trailer", "ETag")
-
hash := etagHasher()
- configWriter := io.MultiWriter(w, hash)
+
+ // Read the config into a buffer instead of writing directly to
+ // the response writer, as we want to set the ETag as the header,
+ // not the trailer.
+ buf := bufferPool.Get().(*bytes.Buffer)
+ buf.Reset()
+ defer bufferPool.Put(buf)
+
+ configWriter := io.MultiWriter(buf, hash)
err := readConfig(r.URL.Path, configWriter)
if err != nil {
return APIError{HTTPStatus: http.StatusBadRequest, Err: err}
@@ -972,6 +983,10 @@ func handleConfig(w http.ResponseWriter, r *http.Request) error {
// we could consider setting up a sync.Pool for the summed
// hashes to reduce GC pressure.
w.Header().Set("Etag", makeEtag(r.URL.Path, hash))
+ _, err = w.Write(buf.Bytes())
+ if err != nil {
+ return APIError{HTTPStatus: http.StatusInternalServerError, Err: err}
+ }
return nil
diff --git a/caddytest/integration/caddyfile_adapt/file_server_etag_file_extensions.caddyfiletest b/caddytest/integration/caddyfile_adapt/file_server_etag_file_extensions.caddyfiletest
new file mode 100644
index 000000000..d0dc79216
--- /dev/null
+++ b/caddytest/integration/caddyfile_adapt/file_server_etag_file_extensions.caddyfiletest
@@ -0,0 +1,40 @@
+:8080 {
+ root * ./
+ file_server {
+ etag_file_extensions .b3sum .sha256
+ }
+}
+----------
+{
+ "apps": {
+ "http": {
+ "servers": {
+ "srv0": {
+ "listen": [
+ ":8080"
+ ],
+ "routes": [
+ {
+ "handle": [
+ {
+ "handler": "vars",
+ "root": "./"
+ },
+ {
+ "etag_file_extensions": [
+ ".b3sum",
+ ".sha256"
+ ],
+ "handler": "file_server",
+ "hide": [
+ "./Caddyfile"
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/caddytest/integration/caddyfile_adapt/reverse_proxy_http_transport_tls_file_cert.txt b/caddytest/integration/caddyfile_adapt/reverse_proxy_http_transport_tls_file_cert.txt
new file mode 100644
index 000000000..d43aa1175
--- /dev/null
+++ b/caddytest/integration/caddyfile_adapt/reverse_proxy_http_transport_tls_file_cert.txt
@@ -0,0 +1,47 @@
+:8884
+reverse_proxy 127.0.0.1:65535 {
+ transport http {
+ tls_trust_pool file {
+ pem_file ../caddy.ca.cer
+ }
+ }
+}
+----------
+{
+ "apps": {
+ "http": {
+ "servers": {
+ "srv0": {
+ "listen": [
+ ":8884"
+ ],
+ "routes": [
+ {
+ "handle": [
+ {
+ "handler": "reverse_proxy",
+ "transport": {
+ "protocol": "http",
+ "tls": {
+ "ca": {
+ "pem_files": [
+ "../caddy.ca.cer"
+ ],
+ "provider": "file"
+ }
+ }
+ },
+ "upstreams": [
+ {
+ "dial": "127.0.0.1:65535"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ }
+}
diff --git a/caddytest/integration/caddyfile_adapt/reverse_proxy_http_transport_tls_inline_cert.txt b/caddytest/integration/caddyfile_adapt/reverse_proxy_http_transport_tls_inline_cert.txt
new file mode 100644
index 000000000..ef9e8243a
--- /dev/null
+++ b/caddytest/integration/caddyfile_adapt/reverse_proxy_http_transport_tls_inline_cert.txt
@@ -0,0 +1,47 @@
+:8884
+reverse_proxy 127.0.0.1:65535 {
+ transport http {
+ tls_trust_pool inline {
+ trust_der MIIDSzCCAjOgAwIBAgIUfIRObjWNUA4jxQ/0x8BOCvE2Vw4wDQYJKoZIhvcNAQELBQAwFjEUMBIGA1UEAwwLRWFzeS1SU0EgQ0EwHhcNMTkwODI4MTYyNTU5WhcNMjkwODI1MTYyNTU5WjAWMRQwEgYDVQQDDAtFYXN5LVJTQSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK5m5elxhQfMp/3aVJ4JnpN9PUSz6LlP6LePAPFU7gqohVVFVtDkChJAG3FNkNQNlieVTja/bgH9IcC6oKbROwdY1h0MvNV8AHHigvl03WuJD8g2ReVFXXwsnrPmKXCFzQyMI6TYk3m2gYrXsZOU1GLnfMRC3KAMRgE2F45twOs9hqG169YJ6mM2eQjzjCHWI6S2/iUYvYxRkCOlYUbLsMD/AhgAf1plzg6LPqNxtdlwxZnA0ytgkmhK67HtzJu0+ovUCsMv0RwcMhsEo9T8nyFAGt9XLZ63X5WpBCTUApaAUhnG0XnerjmUWb6eUWw4zev54sEfY5F3x002iQaW6cECAwEAAaOBkDCBjTAdBgNVHQ4EFgQU4CBUbZsS2GaNIkGRz/cBsD5ivjswUQYDVR0jBEowSIAU4CBUbZsS2GaNIkGRz/cBsD5ivjuhGqQYMBYxFDASBgNVBAMMC0Vhc3ktUlNBIENBghR8hE5uNY1QDiPFD/THwE4K8TZXDjAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAKB3V4HIzoiO/Ch6WMj9bLJ2FGbpkMrcb/Eq01hT5zcfKD66lVS1MlK+cRL446Z2b2KDP1oFyVs+qmrmtdwrWgD+nfe2sBmmIHo9m9KygMkEOfG3MghGTEcS+0cTKEcoHYWYyOqQh6jnedXY8Cdm4GM1hAc9MiL3/sqV8YCVSLNnkoNysmr06/rZ0MCUZPGUtRmfd0heWhrfzAKw2HLgX+RAmpOE2MZqWcjvqKGyaRiaZks4nJkP6521aC2Lgp0HhCz1j8/uQ5ldoDszCnu/iro0NAsNtudTMD+YoLQxLqdleIh6CW+illc2VdXwj7mn6J04yns9jfE2jRjW/yTLFuQ==
+ }
+ }
+}
+----------
+{
+ "apps": {
+ "http": {
+ "servers": {
+ "srv0": {
+ "listen": [
+ ":8884"
+ ],
+ "routes": [
+ {
+ "handle": [
+ {
+ "handler": "reverse_proxy",
+ "transport": {
+ "protocol": "http",
+ "tls": {
+ "ca": {
+ "provider": "inline",
+ "trusted_ca_certs": [
+ "MIIDSzCCAjOgAwIBAgIUfIRObjWNUA4jxQ/0x8BOCvE2Vw4wDQYJKoZIhvcNAQELBQAwFjEUMBIGA1UEAwwLRWFzeS1SU0EgQ0EwHhcNMTkwODI4MTYyNTU5WhcNMjkwODI1MTYyNTU5WjAWMRQwEgYDVQQDDAtFYXN5LVJTQSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK5m5elxhQfMp/3aVJ4JnpN9PUSz6LlP6LePAPFU7gqohVVFVtDkChJAG3FNkNQNlieVTja/bgH9IcC6oKbROwdY1h0MvNV8AHHigvl03WuJD8g2ReVFXXwsnrPmKXCFzQyMI6TYk3m2gYrXsZOU1GLnfMRC3KAMRgE2F45twOs9hqG169YJ6mM2eQjzjCHWI6S2/iUYvYxRkCOlYUbLsMD/AhgAf1plzg6LPqNxtdlwxZnA0ytgkmhK67HtzJu0+ovUCsMv0RwcMhsEo9T8nyFAGt9XLZ63X5WpBCTUApaAUhnG0XnerjmUWb6eUWw4zev54sEfY5F3x002iQaW6cECAwEAAaOBkDCBjTAdBgNVHQ4EFgQU4CBUbZsS2GaNIkGRz/cBsD5ivjswUQYDVR0jBEowSIAU4CBUbZsS2GaNIkGRz/cBsD5ivjuhGqQYMBYxFDASBgNVBAMMC0Vhc3ktUlNBIENBghR8hE5uNY1QDiPFD/THwE4K8TZXDjAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAKB3V4HIzoiO/Ch6WMj9bLJ2FGbpkMrcb/Eq01hT5zcfKD66lVS1MlK+cRL446Z2b2KDP1oFyVs+qmrmtdwrWgD+nfe2sBmmIHo9m9KygMkEOfG3MghGTEcS+0cTKEcoHYWYyOqQh6jnedXY8Cdm4GM1hAc9MiL3/sqV8YCVSLNnkoNysmr06/rZ0MCUZPGUtRmfd0heWhrfzAKw2HLgX+RAmpOE2MZqWcjvqKGyaRiaZks4nJkP6521aC2Lgp0HhCz1j8/uQ5ldoDszCnu/iro0NAsNtudTMD+YoLQxLqdleIh6CW+illc2VdXwj7mn6J04yns9jfE2jRjW/yTLFuQ=="
+ ]
+ }
+ }
+ },
+ "upstreams": [
+ {
+ "dial": "127.0.0.1:65535"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ }
+}
diff --git a/cmd/main.go b/cmd/main.go
index d832cbc5e..ac9786faf 100644
--- a/cmd/main.go
+++ b/cmd/main.go
@@ -157,11 +157,16 @@ func loadConfigWithLogger(logger *zap.Logger, configFile, adapterName string) ([
}
}
- // as a special case, if a config file called "Caddyfile" was
- // specified, and no adapter is specified, assume caddyfile adapter
- // for convenience
- if strings.HasPrefix(filepath.Base(configFile), "Caddyfile") &&
- filepath.Ext(configFile) != ".json" &&
+ // as a special case, if a config file starts with "caddyfile" or
+ // has a ".caddyfile" extension, and no adapter is specified, and
+ // no adapter module name matches the extension, assume
+ // caddyfile adapter for convenience
+ baseConfig := strings.ToLower(filepath.Base(configFile))
+ baseConfigExt := filepath.Ext(baseConfig)
+ if (strings.HasPrefix(baseConfig, "caddyfile") ||
+ strings.HasSuffix(baseConfig, ".caddyfile")) &&
+ (len(baseConfigExt) == 0 || caddyconfig.GetAdapter(baseConfigExt[1:]) == nil) &&
+ baseConfigExt != ".json" &&
adapterName == "" {
adapterName = "caddyfile"
}
diff --git a/modules/caddyhttp/autohttps.go b/modules/caddyhttp/autohttps.go
index 9259201f0..54a2d9ccd 100644
--- a/modules/caddyhttp/autohttps.go
+++ b/modules/caddyhttp/autohttps.go
@@ -260,7 +260,7 @@ func (app *App) automaticHTTPSPhase1(ctx caddy.Context, repl *caddy.Replacer) er
// port, we'll have to choose one, so prefer the HTTPS port
if _, ok := redirDomains[d]; !ok ||
addr.StartPort == uint(app.httpsPort()) {
- redirDomains[d] = []caddy.NetworkAddress{addr}
+ redirDomains[d] = append(redirDomains[d], addr)
}
}
}
diff --git a/modules/caddyhttp/fileserver/browse.html b/modules/caddyhttp/fileserver/browse.html
index 484d90020..fdc4b9c3c 100644
--- a/modules/caddyhttp/fileserver/browse.html
+++ b/modules/caddyhttp/fileserver/browse.html
@@ -21,7 +21,7 @@
</svg>
{{- else if .HasExt ".jpg" ".jpeg" ".png" ".gif" ".webp" ".tiff" ".bmp" ".heif" ".heic" ".svg"}}
{{- if eq .Tpl.Layout "grid"}}
- <img loading="lazy" src="{{html .Name}}">
+ <img loading="lazy" src="{{.Name | replace "#" "%23" | replace "?" "%3f" | html}}">
{{- else}}
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-photo" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
diff --git a/modules/caddyhttp/fileserver/caddyfile.go b/modules/caddyhttp/fileserver/caddyfile.go
index d90e4f9a0..f65695018 100644
--- a/modules/caddyhttp/fileserver/caddyfile.go
+++ b/modules/caddyhttp/fileserver/caddyfile.go
@@ -164,6 +164,13 @@ func (fsrv *FileServer) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
}
fsrv.PassThru = true
+ case "etag_file_extensions":
+ etagFileExtensions := d.RemainingArgs()
+ if len(etagFileExtensions) == 0 {
+ return d.ArgErr()
+ }
+ fsrv.EtagFileExtensions = etagFileExtensions
+
default:
return d.Errf("unknown subdirective '%s'", d.Val())
}
diff --git a/modules/caddyhttp/fileserver/staticfiles.go b/modules/caddyhttp/fileserver/staticfiles.go
index 57d1bc851..15ae35e38 100644
--- a/modules/caddyhttp/fileserver/staticfiles.go
+++ b/modules/caddyhttp/fileserver/staticfiles.go
@@ -161,6 +161,12 @@ type FileServer struct {
PrecompressedOrder []string `json:"precompressed_order,omitempty"`
precompressors map[string]encode.Precompressed
+ // List of file extensions to try to read Etags from.
+ // If set, file Etags will be read from sidecar files
+ // with any of these suffixes, instead of generating
+ // our own Etag.
+ EtagFileExtensions []string `json:"etag_file_extensions,omitempty"`
+
fsmap caddy.FileSystems
logger *zap.Logger
@@ -396,6 +402,14 @@ func (fsrv *FileServer) ServeHTTP(w http.ResponseWriter, r *http.Request, next c
w.Header().Del("Accept-Ranges")
w.Header().Add("Vary", "Accept-Encoding")
+ // try to get the etag from pre computed files if an etag suffix list was provided
+ if etag == "" && fsrv.EtagFileExtensions != nil {
+ etag, err = fsrv.getEtagFromFile(fileSystem, compressedFilename)
+ if err != nil {
+ return err
+ }
+ }
+
// don't assign info = compressedInfo because sidecars are kind
// of transparent; however we do need to set the Etag:
// https://caddy.community/t/gzipped-sidecar-file-wrong-same-etag/16793
@@ -420,7 +434,13 @@ func (fsrv *FileServer) ServeHTTP(w http.ResponseWriter, r *http.Request, next c
return err // error is already structured
}
defer file.Close()
-
+ // try to get the etag from pre computed files if an etag suffix list was provided
+ if etag == "" && fsrv.EtagFileExtensions != nil {
+ etag, err = fsrv.getEtagFromFile(fileSystem, filename)
+ if err != nil {
+ return err
+ }
+ }
if etag == "" {
etag = calculateEtag(info)
}
@@ -639,6 +659,22 @@ func calculateEtag(d os.FileInfo) string {
return `"` + t + s + `"`
}
+// Finds the first corresponding etag file for a given file in the file system and return its content
+func (fsrv *FileServer) getEtagFromFile(fileSystem fs.FS, filename string) (string, error) {
+ for _, suffix := range fsrv.EtagFileExtensions {
+ etagFilename := filename + suffix
+ etag, err := fs.ReadFile(fileSystem, etagFilename)
+ if errors.Is(err, fs.ErrNotExist) {
+ continue
+ }
+ if err != nil {
+ return "", fmt.Errorf("cannot read etag from file %s: %v", etagFilename, err)
+ }
+ return string(etag), nil
+ }
+ return "", nil
+}
+
// redirect performs a redirect to a given path. The 'toPath' parameter
// MUST be solely a path, and MUST NOT include a query.
func redirect(w http.ResponseWriter, r *http.Request, toPath string) error {
diff --git a/modules/caddyhttp/reverseproxy/caddyfile.go b/modules/caddyhttp/reverseproxy/caddyfile.go
index 9e0726be6..8dfbd93da 100644
--- a/modules/caddyhttp/reverseproxy/caddyfile.go
+++ b/modules/caddyhttp/reverseproxy/caddyfile.go
@@ -30,6 +30,7 @@ import (
"github.com/caddyserver/caddy/v2/modules/caddyhttp"
"github.com/caddyserver/caddy/v2/modules/caddyhttp/headers"
"github.com/caddyserver/caddy/v2/modules/caddyhttp/rewrite"
+ "github.com/caddyserver/caddy/v2/modules/caddytls"
)
func init() {
@@ -1145,6 +1146,9 @@ func (h *HTTPTransport) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
if h.TLS == nil {
h.TLS = new(TLSConfig)
}
+ if len(h.TLS.CARaw) != 0 {
+ return d.Err("cannot specify both 'tls_trust_pool' and 'tls_trusted_ca_certs")
+ }
h.TLS.RootCAPEMFiles = args
case "tls_server_name":
@@ -1260,6 +1264,31 @@ func (h *HTTPTransport) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
}
h.MaxConnsPerHost = num
+ case "tls_trust_pool":
+ if !d.NextArg() {
+ return d.ArgErr()
+ }
+ modStem := d.Val()
+ modID := "tls.ca_pool.source." + modStem
+ unm, err := caddyfile.UnmarshalModule(d, modID)
+ if err != nil {
+ return err
+ }
+ ca, ok := unm.(caddytls.CA)
+ if !ok {
+ return d.Errf("module %s is not a caddytls.CA", modID)
+ }
+ if h.TLS == nil {
+ h.TLS = new(TLSConfig)
+ }
+ if len(h.TLS.RootCAPEMFiles) != 0 {
+ return d.Err("cannot specify both 'tls_trust_pool' and 'tls_trusted_ca_certs'")
+ }
+ if h.TLS.CARaw != nil {
+ return d.Err("cannot specify \"tls_trust_pool\" twice in caddyfile")
+ }
+ h.TLS.CARaw = caddyconfig.JSONModuleObject(ca, "provider", modStem, nil)
+
default:
return d.Errf("unrecognized subdirective %s", d.Val())
}
diff --git a/modules/caddyhttp/reverseproxy/httptransport.go b/modules/caddyhttp/reverseproxy/httptransport.go
index dd8ece251..895873b9d 100644
--- a/modules/caddyhttp/reverseproxy/httptransport.go
+++ b/modules/caddyhttp/reverseproxy/httptransport.go
@@ -19,6 +19,7 @@ import (
"crypto/tls"
"crypto/x509"
"encoding/base64"
+ "encoding/json"
"fmt"
weakrand "math/rand"
"net"
@@ -472,9 +473,14 @@ func (h HTTPTransport) Cleanup() error {
// TLSConfig holds configuration related to the TLS configuration for the
// transport/client.
type TLSConfig struct {
+ // Certificate authority module which provides the certificate pool of trusted certificates
+ CARaw json.RawMessage `json:"ca,omitempty" caddy:"namespace=tls.ca_pool.source inline_key=provider"`
+
+ // DEPRECATED: Use the `ca` field with the `tls.ca_pool.source.inline` module instead.
// Optional list of base64-encoded DER-encoded CA certificates to trust.
RootCAPool []string `json:"root_ca_pool,omitempty"`
+ // DEPRECATED: Use the `ca` field with the `tls.ca_pool.source.file` module instead.
// List of PEM-encoded CA certificate files to add to the same trust
// store as RootCAPool (or root_ca_pool in the JSON).
RootCAPEMFiles []string `json:"root_ca_pem_files,omitempty"`
@@ -576,6 +582,7 @@ func (t TLSConfig) MakeTLSClientConfig(ctx caddy.Context) (*tls.Config, error) {
// trusted root CAs
if len(t.RootCAPool) > 0 || len(t.RootCAPEMFiles) > 0 {
+ ctx.Logger().Warn("root_ca_pool and root_ca_pem_files are deprecated. Use one of the tls.ca_pool.source modules instead")
rootPool := x509.NewCertPool()
for _, encodedCACert := range t.RootCAPool {
caCert, err := decodeBase64DERCert(encodedCACert)
@@ -594,6 +601,21 @@ func (t TLSConfig) MakeTLSClientConfig(ctx caddy.Context) (*tls.Config, error) {
cfg.RootCAs = rootPool
}
+ if t.CARaw != nil {
+ if len(t.RootCAPool) > 0 || len(t.RootCAPEMFiles) > 0 {
+ return nil, fmt.Errorf("conflicting config for Root CA pool")
+ }
+ caRaw, err := ctx.LoadModule(t, "CARaw")
+ if err != nil {
+ return nil, fmt.Errorf("failed to load ca module: %v", err)
+ }
+ ca, ok := caRaw.(caddytls.CA)
+ if !ok {
+ return nil, fmt.Errorf("CA module '%s' is not a certificate pool provider", ca)
+ }
+ cfg.RootCAs = ca.CertPool()
+ }
+
// Renegotiation
switch t.Renegotiation {
case "never", "":
diff --git a/modules/caddyhttp/reverseproxy/httptransport_test.go b/modules/caddyhttp/reverseproxy/httptransport_test.go
new file mode 100644
index 000000000..46931c8b1
--- /dev/null
+++ b/modules/caddyhttp/reverseproxy/httptransport_test.go
@@ -0,0 +1,96 @@
+package reverseproxy
+
+import (
+ "encoding/json"
+ "fmt"
+ "reflect"
+ "testing"
+
+ "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
+)
+
+func TestHTTPTransportUnmarshalCaddyFileWithCaPools(t *testing.T) {
+ const test_der_1 = `MIIDSzCCAjOgAwIBAgIUfIRObjWNUA4jxQ/0x8BOCvE2Vw4wDQYJKoZIhvcNAQELBQAwFjEUMBIGA1UEAwwLRWFzeS1SU0EgQ0EwHhcNMTkwODI4MTYyNTU5WhcNMjkwODI1MTYyNTU5WjAWMRQwEgYDVQQDDAtFYXN5LVJTQSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK5m5elxhQfMp/3aVJ4JnpN9PUSz6LlP6LePAPFU7gqohVVFVtDkChJAG3FNkNQNlieVTja/bgH9IcC6oKbROwdY1h0MvNV8AHHigvl03WuJD8g2ReVFXXwsnrPmKXCFzQyMI6TYk3m2gYrXsZOU1GLnfMRC3KAMRgE2F45twOs9hqG169YJ6mM2eQjzjCHWI6S2/iUYvYxRkCOlYUbLsMD/AhgAf1plzg6LPqNxtdlwxZnA0ytgkmhK67HtzJu0+ovUCsMv0RwcMhsEo9T8nyFAGt9XLZ63X5WpBCTUApaAUhnG0XnerjmUWb6eUWw4zev54sEfY5F3x002iQaW6cECAwEAAaOBkDCBjTAdBgNVHQ4EFgQU4CBUbZsS2GaNIkGRz/cBsD5ivjswUQYDVR0jBEowSIAU4CBUbZsS2GaNIkGRz/cBsD5ivjuhGqQYMBYxFDASBgNVBAMMC0Vhc3ktUlNBIENBghR8hE5uNY1QDiPFD/THwE4K8TZXDjAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAKB3V4HIzoiO/Ch6WMj9bLJ2FGbpkMrcb/Eq01hT5zcfKD66lVS1MlK+cRL446Z2b2KDP1oFyVs+qmrmtdwrWgD+nfe2sBmmIHo9m9KygMkEOfG3MghGTEcS+0cTKEcoHYWYyOqQh6jnedXY8Cdm4GM1hAc9MiL3/sqV8YCVSLNnkoNysmr06/rZ0MCUZPGUtRmfd0heWhrfzAKw2HLgX+RAmpOE2MZqWcjvqKGyaRiaZks4nJkP6521aC2Lgp0HhCz1j8/uQ5ldoDszCnu/iro0NAsNtudTMD+YoLQxLqdleIh6CW+illc2VdXwj7mn6J04yns9jfE2jRjW/yTLFuQ==`
+ type args struct {
+ d *caddyfile.Dispenser
+ }
+ tests := []struct {
+ name string
+ args args
+ expectedTLSConfig TLSConfig
+ wantErr bool
+ }{
+ {
+ name: "tls_trust_pool without a module argument returns an error",
+ args: args{
+ d: caddyfile.NewTestDispenser(
+ `http {
+ tls_trust_pool
+ }`),
+ },
+ wantErr: true,
+ },
+ {
+ name: "providing both 'tls_trust_pool' and 'tls_trusted_ca_certs' returns an error",
+ args: args{
+ d: caddyfile.NewTestDispenser(fmt.Sprintf(
+ `http {
+ tls_trust_pool inline %s
+ tls_trusted_ca_certs %s
+ }`, test_der_1, test_der_1)),
+ },
+ wantErr: true,
+ },
+ {
+ name: "setting 'tls_trust_pool' and 'tls_trusted_ca_certs' produces an error",
+ args: args{
+ d: caddyfile.NewTestDispenser(fmt.Sprintf(
+ `http {
+ tls_trust_pool inline {
+ trust_der %s
+ }
+ tls_trusted_ca_certs %s
+ }`, test_der_1, test_der_1)),
+ },
+ wantErr: true,
+ },
+ {
+ name: "using 'inline' tls_trust_pool loads the module successfully",
+ args: args{
+ d: caddyfile.NewTestDispenser(fmt.Sprintf(
+ `http {
+ tls_trust_pool inline {
+ trust_der %s
+ }
+ }
+ `, test_der_1)),
+ },
+ expectedTLSConfig: TLSConfig{CARaw: json.RawMessage(fmt.Sprintf(`{"provider":"inline","trusted_ca_certs":["%s"]}`, test_der_1))},
+ },
+ {
+ name: "setting 'tls_trusted_ca_certs' and 'tls_trust_pool' produces an error",
+ args: args{
+ d: caddyfile.NewTestDispenser(fmt.Sprintf(
+ `http {
+ tls_trusted_ca_certs %s
+ tls_trust_pool inline {
+ trust_der %s
+ }
+ }`, test_der_1, test_der_1)),
+ },
+ wantErr: true,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ ht := &HTTPTransport{}
+ if err := ht.UnmarshalCaddyfile(tt.args.d); (err != nil) != tt.wantErr {
+ t.Errorf("HTTPTransport.UnmarshalCaddyfile() error = %v, wantErr %v", err, tt.wantErr)
+ return
+ }
+ if !tt.wantErr && !reflect.DeepEqual(&tt.expectedTLSConfig, ht.TLS) {
+ t.Errorf("HTTPTransport.UnmarshalCaddyfile() = %v, want %v", ht, tt.expectedTLSConfig)
+ }
+ })
+ }
+}
diff --git a/modules/caddytls/tls.go b/modules/caddytls/tls.go
index 7e30299aa..2a05d5235 100644
--- a/modules/caddytls/tls.go
+++ b/modules/caddytls/tls.go
@@ -193,6 +193,13 @@ func (t *TLS) Provision(ctx caddy.Context) error {
if err != nil {
return fmt.Errorf("preparing 'ask' endpoint: %v", err)
}
+ perm := PermissionByHTTP{
+ Endpoint: t.Automation.OnDemand.Ask,
+ }
+ if err := perm.Provision(ctx); err != nil {
+ return fmt.Errorf("provisioning 'ask' module: %v", err)
+ }
+ t.Automation.OnDemand.permission = perm
}
// automation/management policies