You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
246 lines
7.6 KiB
246 lines
7.6 KiB
#!/bin/sh
|
|
|
|
stage() {
|
|
STAGE="$1"
|
|
echo
|
|
echo starting stage: $STAGE
|
|
}
|
|
|
|
end_stage() {
|
|
if [ $? -ne 0 ]; then
|
|
>&2 echo error at \'$STAGE\'
|
|
exit 1
|
|
fi
|
|
echo finished stage: $STAGE ✓
|
|
echo
|
|
}
|
|
|
|
|
|
module() {
|
|
mkdir -p /caddy
|
|
cd /caddy # build dir
|
|
cat > go.mod <<EOF
|
|
module caddy
|
|
|
|
go 1.13
|
|
|
|
require (
|
|
github.com/caddyserver/caddy v1.0.5
|
|
github.com/captncraig/caddy-realip v0.0.0-20190710144553-6df827e22ab8
|
|
github.com/captncraig/cors v0.0.0-20190703115713-e80254a89df1
|
|
github.com/echocat/caddy-filter v0.14.0
|
|
github.com/epicagency/caddy-expires v1.1.1
|
|
github.com/go-acme/lego/v3 v3.7.0
|
|
github.com/hacdias/caddy-minify v1.0.2
|
|
github.com/nicolasazrak/caddy-cache v0.3.4
|
|
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect
|
|
)
|
|
EOF
|
|
# main and telemetry
|
|
cat > main.go <<EOF
|
|
package main
|
|
|
|
import (
|
|
"net/http"
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
"github.com/caddyserver/caddy"
|
|
"github.com/caddyserver/caddy/caddy/caddymain"
|
|
"github.com/caddyserver/caddy/caddyhttp/httpserver"
|
|
"github.com/captncraig/cors"
|
|
// plug in plugins here, for example:
|
|
// _ "import/path/here"
|
|
"errors"
|
|
|
|
"github.com/caddyserver/caddy/caddytls"
|
|
"github.com/go-acme/lego/v3/providers/dns/dnspod"
|
|
_ "github.com/echocat/caddy-filter"
|
|
_ "github.com/nicolasazrak/caddy-cache"
|
|
_ "github.com/hacdias/caddy-minify"
|
|
_ "github.com/epicagency/caddy-expires"
|
|
_ "github.com/captncraig/caddy-realip"
|
|
)
|
|
|
|
func main() {
|
|
caddytls.RegisterDNSProvider("dnspod", NewDNSProvider)
|
|
caddy.RegisterPlugin("cors", caddy.Plugin{
|
|
ServerType: "http",
|
|
Action: setup,
|
|
})
|
|
// optional: disable telemetry
|
|
caddymain.EnableTelemetry = false
|
|
caddymain.Run()
|
|
}
|
|
|
|
func NewDNSProvider(credentials ...string) (caddytls.ChallengeProvider, error) {
|
|
switch len(credentials) {
|
|
case 0:
|
|
return dnspod.NewDNSProvider()
|
|
case 1:
|
|
config := dnspod.NewDefaultConfig()
|
|
config.LoginToken = credentials[0]
|
|
return dnspod.NewDNSProviderConfig(config)
|
|
default:
|
|
return nil, errors.New("invalid credentials length")
|
|
}
|
|
}
|
|
|
|
type corsRule struct {
|
|
Conf *cors.Config
|
|
Path string
|
|
}
|
|
|
|
func setup(c *caddy.Controller) error {
|
|
rules, err := parseRules(c)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
siteConfig := httpserver.GetConfig(c)
|
|
siteConfig.AddMiddleware(func(next httpserver.Handler) httpserver.Handler {
|
|
return httpserver.HandlerFunc(func(w http.ResponseWriter, r *http.Request) (int, error) {
|
|
for _, rule := range rules {
|
|
if httpserver.Path(r.URL.Path).Matches(rule.Path) {
|
|
rule.Conf.HandleRequest(w, r)
|
|
if cors.IsPreflight(r) {
|
|
return 200, nil
|
|
}
|
|
break
|
|
}
|
|
}
|
|
return next.ServeHTTP(w, r)
|
|
})
|
|
})
|
|
return nil
|
|
}
|
|
|
|
func parseRules(c *caddy.Controller) ([]*corsRule, error) {
|
|
rules := []*corsRule{}
|
|
|
|
for c.Next() {
|
|
rule := &corsRule{Path: "/", Conf: cors.Default()}
|
|
args := c.RemainingArgs()
|
|
|
|
anyOrigins := false
|
|
if len(args) > 0 {
|
|
rule.Path = args[0]
|
|
}
|
|
for i := 1; i < len(args); i++ {
|
|
if !anyOrigins {
|
|
rule.Conf.AllowedOrigins = nil
|
|
}
|
|
rule.Conf.AllowedOrigins = append(rule.Conf.AllowedOrigins, strings.Split(args[i], ",")...)
|
|
anyOrigins = true
|
|
}
|
|
for c.NextBlock() {
|
|
switch c.Val() {
|
|
case "origin":
|
|
if !anyOrigins {
|
|
rule.Conf.AllowedOrigins = nil
|
|
}
|
|
args := c.RemainingArgs()
|
|
for _, domain := range args {
|
|
rule.Conf.AllowedOrigins = append(rule.Conf.AllowedOrigins, strings.Split(domain, ",")...)
|
|
}
|
|
anyOrigins = true
|
|
case "origin_regexp":
|
|
if arg, err := singleArg(c, "origin_regexp"); err != nil {
|
|
return nil, err
|
|
} else {
|
|
r, err := regexp.Compile(arg)
|
|
|
|
if err != nil {
|
|
return nil, c.Errf("could no compile regexp: %s", err)
|
|
}
|
|
|
|
if !anyOrigins {
|
|
rule.Conf.AllowedOrigins = nil
|
|
anyOrigins = true
|
|
}
|
|
|
|
rule.Conf.OriginRegexps = append(rule.Conf.OriginRegexps, r)
|
|
}
|
|
case "methods":
|
|
if arg, err := singleArg(c, "methods"); err != nil {
|
|
return nil, err
|
|
} else {
|
|
rule.Conf.AllowedMethods = arg
|
|
}
|
|
case "allow_credentials":
|
|
if arg, err := singleArg(c, "allow_credentials"); err != nil {
|
|
return nil, err
|
|
} else {
|
|
var b bool
|
|
if arg == "true" {
|
|
b = true
|
|
} else if arg != "false" {
|
|
return nil, c.Errf("allow_credentials must be true or false.")
|
|
}
|
|
rule.Conf.AllowCredentials = &b
|
|
}
|
|
case "max_age":
|
|
if arg, err := singleArg(c, "max_age"); err != nil {
|
|
return nil, err
|
|
} else {
|
|
i, err := strconv.Atoi(arg)
|
|
if err != nil {
|
|
return nil, c.Err("max_age must be valid int")
|
|
}
|
|
rule.Conf.MaxAge = i
|
|
}
|
|
case "allowed_headers":
|
|
if arg, err := singleArg(c, "allowed_headers"); err != nil {
|
|
return nil, err
|
|
} else {
|
|
rule.Conf.AllowedHeaders = arg
|
|
}
|
|
case "exposed_headers":
|
|
if arg, err := singleArg(c, "exposed_headers"); err != nil {
|
|
return nil, err
|
|
} else {
|
|
rule.Conf.ExposedHeaders = arg
|
|
}
|
|
default:
|
|
return nil, c.Errf("Unknown cors config item: %s", c.Val())
|
|
}
|
|
}
|
|
rules = append(rules, rule)
|
|
}
|
|
return rules, nil
|
|
}
|
|
|
|
func singleArg(c *caddy.Controller, desc string) (string, error) {
|
|
args := c.RemainingArgs()
|
|
if len(args) != 1 {
|
|
return "", c.Errf("%s expects exactly one argument", desc)
|
|
}
|
|
return args[0], nil
|
|
}
|
|
EOF
|
|
|
|
# setup module
|
|
# go mod init caddy
|
|
go get github.com/caddyserver/caddy
|
|
}
|
|
|
|
# check for modules support
|
|
# export GO111MODULE=on
|
|
|
|
# add plugins and telemetry
|
|
stage "customising plugins and telemetry"
|
|
module
|
|
end_stage
|
|
|
|
# build
|
|
stage "building caddy"
|
|
go build -o caddy
|
|
end_stage
|
|
|
|
# copy binary
|
|
stage "copying binary"
|
|
mkdir -p /install \
|
|
&& mv caddy /install \
|
|
&& /install/caddy -version
|
|
end_stage
|
|
|
|
echo "installed caddy version at /install/caddy" |