mirror of
https://github.com/caddyserver/caddy.git
synced 2025-01-13 22:51:08 -05:00
httpserver: Added function to register directive at runtime (dev only)
This function should not be used outside of development. It destroys the absolute ordering and guarantees of correctness. Multiple uses of it may work fine, but maybe not if they overlap, causing non-deterministic builds which is bad. However, this can be convenient when developing a plugin by calling it from an init() function, since you don't have to modify the Caddy source code just to try your plugin.
This commit is contained in:
parent
fd3008459e
commit
5a691fbaf5
2 changed files with 78 additions and 0 deletions
|
@ -6,6 +6,7 @@ import (
|
|||
"log"
|
||||
"net"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
@ -326,6 +327,63 @@ func standardizeAddress(str string) (Address, error) {
|
|||
return Address{Original: input, Scheme: u.Scheme, Host: host, Port: port, Path: u.Path}, err
|
||||
}
|
||||
|
||||
// RegisterDevDirective splices name into the list of directives
|
||||
// immediately before another directive. This function is ONLY
|
||||
// for plugin development purposes! NEVER use it for a plugin
|
||||
// that you are not currently building. If before is empty,
|
||||
// the directive will be appended to the end of the list.
|
||||
//
|
||||
// It is imperative that directives execute in the proper
|
||||
// order, and hard-coding the list of directives guarantees
|
||||
// a correct, absolute order every time. This function is
|
||||
// convenient when developing a plugin, but it does not
|
||||
// guarantee absolute ordering. Multiple plugins registering
|
||||
// directives with this function will lead to non-
|
||||
// deterministic builds and buggy software.
|
||||
//
|
||||
// Directive names must be lower-cased and unique. Any errors
|
||||
// here are fatal, and even successful calls print a message
|
||||
// to stdout as a reminder to use it only in development.
|
||||
func RegisterDevDirective(name, before string) {
|
||||
if name == "" {
|
||||
fmt.Println("[FATAL] Cannot register empty directive name")
|
||||
os.Exit(1)
|
||||
}
|
||||
if strings.ToLower(name) != name {
|
||||
fmt.Printf("[FATAL] %s: directive name must be lowercase\n", name)
|
||||
os.Exit(1)
|
||||
}
|
||||
for _, dir := range directives {
|
||||
if dir == name {
|
||||
fmt.Printf("[FATAL] %s: directive name already exists\n", name)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
if before == "" {
|
||||
directives = append(directives, name)
|
||||
} else {
|
||||
var found bool
|
||||
for i, dir := range directives {
|
||||
if dir == before {
|
||||
directives = append(directives[:i], append([]string{name}, directives[i:]...)...)
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
fmt.Printf("[FATAL] %s: directive not found\n", before)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
msg := fmt.Sprintf("Registered directive '%s' ", name)
|
||||
if before == "" {
|
||||
msg += "at end of list"
|
||||
} else {
|
||||
msg += fmt.Sprintf("before '%s'", before)
|
||||
}
|
||||
fmt.Printf("[DEV NOTICE] %s\n", msg)
|
||||
}
|
||||
|
||||
// directives is the list of all directives known to exist for the
|
||||
// http server type, including non-standard (3rd-party) directives.
|
||||
// The ordering of this list is important.
|
||||
|
|
|
@ -137,3 +137,23 @@ func TestInspectServerBlocksWithCustomDefaultPort(t *testing.T) {
|
|||
t.Errorf("Expected the port on the address to be set, but got: %#v", addr)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDirectivesList(t *testing.T) {
|
||||
for i, dir1 := range directives {
|
||||
if dir1 == "" {
|
||||
t.Errorf("directives[%d]: empty directive name", i)
|
||||
continue
|
||||
}
|
||||
if got, want := dir1, strings.ToLower(dir1); got != want {
|
||||
t.Errorf("directives[%d]: %s should be lower-cased", i, dir1)
|
||||
continue
|
||||
}
|
||||
for j := i + 1; j < len(directives); j++ {
|
||||
dir2 := directives[j]
|
||||
if dir1 == dir2 {
|
||||
t.Errorf("directives[%d] (%s) is a duplicate of directives[%d] (%s)",
|
||||
j, dir2, i, dir1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue