Compare commits

...

15 Commits

Author SHA1 Message Date
Mohammed Al Sahaf
d8bcafd316
Merge 0896d92d030a39a50a2e5193bb553613b7536308 into eacd7720e99f51b6d2dd340849897c0ff812b8c8 2025-03-03 16:41:39 -05:00
dependabot[bot]
eacd7720e9
build(deps): bump github.com/go-jose/go-jose/v3 from 3.0.3 to 3.0.4 (#6871)
Bumps [github.com/go-jose/go-jose/v3](https://github.com/go-jose/go-jose) from 3.0.3 to 3.0.4.
- [Release notes](https://github.com/go-jose/go-jose/releases)
- [Changelog](https://github.com/go-jose/go-jose/blob/main/CHANGELOG.md)
- [Commits](https://github.com/go-jose/go-jose/compare/v3.0.3...v3.0.4)

---
updated-dependencies:
- dependency-name: github.com/go-jose/go-jose/v3
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-03 14:02:16 -07:00
Mohammed Al Sahaf
02e348f911
chore: upgrade cobra (#6868)
Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>
2025-03-03 13:49:17 -07:00
Matthew Holt
ca37c0b05f Fix typo in TLS group x25519mlkem768 2025-03-03 10:26:42 -07:00
Mohammed Al Sahaf
0896d92d03
Merge branch 'master' into forward-proxy 2025-02-09 03:02:03 +03:00
Mohammed Al Sahaf
00fc4cc90b
Merge branch 'master' into forward-proxy 2025-01-07 12:44:05 +03:00
Mohammed Al Sahaf
e674e20c01
Merge branch 'master' into forward-proxy 2024-12-29 12:26:13 +03:00
Mohammed Al Sahaf
b8a9870410
adapt ForwardProxyURL to use the NetworkProxyRaw
Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>
2024-08-28 00:47:04 +03:00
Mohammed Al Sahaf
908fa5e103
Apply suggestions from code review
Co-authored-by: Francis Lavoie <lavofr@gmail.com>
2024-08-27 10:48:59 +03:00
Mohammed Al Sahaf
38bb05c6c6
address feedbcak 2024-08-26 17:46:27 +00:00
Mohammed Al Sahaf
18cd1c0525
add caddyfile implementation
Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>
2024-08-24 15:54:19 +03:00
Mohammed Al Sahaf
6836afbd28
Merge branch 'master' into forward-proxy 2024-08-24 14:15:10 +03:00
Mohammed Al Sahaf
32d1c5e1bf
Merge branch 'master' into forward-proxy 2024-08-23 17:02:05 +03:00
Mohammed Al Sahaf
54367746a3 move modules around
Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>
2024-06-15 14:16:26 +03:00
Mohammed Al Sahaf
62c711c66e
core: add modular network_proxy support
Co-authored-by: @ImpostorKeanu
Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>
2024-06-15 02:08:17 +03:00
12 changed files with 363 additions and 25 deletions

View File

@ -0,0 +1,41 @@
:8884
reverse_proxy 127.0.0.1:65535 {
transport http {
forward_proxy_url http://localhost:8080
}
}
----------
{
"apps": {
"http": {
"servers": {
"srv0": {
"listen": [
":8884"
],
"routes": [
{
"handle": [
{
"handler": "reverse_proxy",
"transport": {
"network_proxy": {
"from": "url",
"url": "http://localhost:8080"
},
"protocol": "http"
},
"upstreams": [
{
"dial": "127.0.0.1:65535"
}
]
}
]
}
]
}
}
}
}
}

View File

@ -0,0 +1,40 @@
:8884
reverse_proxy 127.0.0.1:65535 {
transport http {
network_proxy none
}
}
----------
{
"apps": {
"http": {
"servers": {
"srv0": {
"listen": [
":8884"
],
"routes": [
{
"handle": [
{
"handler": "reverse_proxy",
"transport": {
"network_proxy": {
"from": "none"
},
"protocol": "http"
},
"upstreams": [
{
"dial": "127.0.0.1:65535"
}
]
}
]
}
]
}
}
}
}
}

View File

@ -0,0 +1,41 @@
:8884
reverse_proxy 127.0.0.1:65535 {
transport http {
network_proxy url http://localhost:8080
}
}
----------
{
"apps": {
"http": {
"servers": {
"srv0": {
"listen": [
":8884"
],
"routes": [
{
"handle": [
{
"handler": "reverse_proxy",
"transport": {
"network_proxy": {
"from": "url",
"url": "http://localhost:8080"
},
"protocol": "http"
},
"upstreams": [
{
"dial": "127.0.0.1:65535"
}
]
}
]
}
]
}
}
}
}
}

8
go.mod
View File

@ -22,8 +22,8 @@ require (
github.com/smallstep/certificates v0.26.1
github.com/smallstep/nosql v0.6.1
github.com/smallstep/truststore v0.13.0
github.com/spf13/cobra v1.8.1
github.com/spf13/pflag v1.0.5
github.com/spf13/cobra v1.9.1
github.com/spf13/pflag v1.0.6
github.com/stretchr/testify v1.9.0
github.com/tailscale/tscert v0.0.0-20240608151842-d3f834017e53
github.com/yuin/goldmark v1.7.8
@ -53,7 +53,7 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/francoispqt/gojay v1.2.13 // indirect
github.com/fxamacker/cbor/v2 v2.6.0 // indirect
github.com/go-jose/go-jose/v3 v3.0.3 // indirect
github.com/go-jose/go-jose/v3 v3.0.4 // indirect
github.com/go-kit/log v0.2.1 // indirect
github.com/google/certificate-transparency-go v1.1.8-0.20240110162603-74a5dd331745 // indirect
github.com/google/go-tpm v0.9.0 // indirect
@ -89,7 +89,7 @@ require (
github.com/cespare/xxhash v1.1.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0
github.com/chzyer/readline v1.5.1 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect
github.com/dgraph-io/badger v1.6.2 // indirect
github.com/dgraph-io/badger/v2 v2.2007.4 // indirect
github.com/dgraph-io/ristretto v0.2.0 // indirect

16
go.sum
View File

@ -121,8 +121,8 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@ -160,8 +160,8 @@ github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aev
github.com/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s=
github.com/go-chi/chi/v5 v5.0.12/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k=
github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ=
github.com/go-jose/go-jose/v3 v3.0.4 h1:Wp5HA7bLQcKnf6YYao/4kpRpVMp/yf6+pJKV8WFSaNY=
github.com/go-jose/go-jose/v3 v3.0.4/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ=
github.com/go-kit/kit v0.4.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.13.0 h1:OoneCcHKHQ03LfBpoQCUfCluwd2Vt3ohz+kvbJneZAU=
github.com/go-kit/kit v0.13.0/go.mod h1:phqEHMMUbyrCFCTgH48JueqrM3md2HcAZ8N3XE4FKDg=
@ -469,12 +469,12 @@ github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU
github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w=
github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU=
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=

View File

@ -33,6 +33,7 @@ import (
"github.com/caddyserver/caddy/v2/modules/caddyhttp/headers"
"github.com/caddyserver/caddy/v2/modules/caddyhttp/rewrite"
"github.com/caddyserver/caddy/v2/modules/caddytls"
"github.com/caddyserver/caddy/v2/modules/internal/network"
)
func init() {
@ -979,7 +980,9 @@ func (h *Handler) FinalizeUnmarshalCaddyfile(helper httpcaddyfile.Helper) error
// read_buffer <size>
// write_buffer <size>
// max_response_header <size>
// forward_proxy_url <url>
// network_proxy <module> {
// ...
// }
// dial_timeout <duration>
// dial_fallback_delay <duration>
// response_header_timeout <duration>
@ -990,6 +993,9 @@ func (h *Handler) FinalizeUnmarshalCaddyfile(helper httpcaddyfile.Helper) error
// tls_insecure_skip_verify
// tls_timeout <duration>
// tls_trusted_ca_certs <cert_files...>
// tls_trust_pool <module> {
// ...
// }
// tls_server_name <sni>
// tls_renegotiation <level>
// tls_except_ports <ports...>
@ -1068,10 +1074,24 @@ func (h *HTTPTransport) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
}
case "forward_proxy_url":
caddy.Log().Warn("The 'forward_proxy_url' field is deprecated. Use 'network_proxy url <url>' instead.")
if !d.NextArg() {
return d.ArgErr()
}
h.ForwardProxyURL = d.Val()
u := network.ProxyFromURL{URL: d.Val()}
h.NetworkProxyRaw = caddyconfig.JSONModuleObject(u, "from", "url", nil)
case "network_proxy":
if !d.NextArg() {
return d.ArgErr()
}
modStem := d.Val()
modID := "caddy.network_proxy.source." + modStem
unm, err := caddyfile.UnmarshalModule(d, modID)
if err != nil {
return err
}
h.NetworkProxyRaw = caddyconfig.JSONModuleObject(unm, "from", modStem, nil)
case "dial_timeout":
if !d.NextArg() {

View File

@ -24,7 +24,6 @@ import (
weakrand "math/rand"
"net"
"net/http"
"net/url"
"os"
"reflect"
"slices"
@ -38,8 +37,10 @@ import (
"golang.org/x/net/http2"
"github.com/caddyserver/caddy/v2"
"github.com/caddyserver/caddy/v2/caddyconfig"
"github.com/caddyserver/caddy/v2/modules/caddyhttp"
"github.com/caddyserver/caddy/v2/modules/caddytls"
"github.com/caddyserver/caddy/v2/modules/internal/network"
)
func init() {
@ -90,6 +91,7 @@ type HTTPTransport struct {
// forward_proxy_url -> upstream
//
// Default: http.ProxyFromEnvironment
// DEPRECATED: Use NetworkProxyRaw|`network_proxy` instead. Subject to removal.
ForwardProxyURL string `json:"forward_proxy_url,omitempty"`
// How long to wait before timing out trying to connect to
@ -141,6 +143,22 @@ type HTTPTransport struct {
// The pre-configured underlying HTTP transport.
Transport *http.Transport `json:"-"`
// The module that provides the network (forward) proxy
// URL that the HTTP transport will use to proxy
// requests to the upstream. See [http.Transport.Proxy](https://pkg.go.dev/net/http#Transport.Proxy)
// for information regarding supported protocols.
//
// Providing a value to this parameter results in requests
// flowing through the reverse_proxy in the following way:
//
// User Agent ->
// reverse_proxy ->
// [proxy provided by the module] -> upstream
//
// If nil, defaults to reading the `HTTP_PROXY`,
// `HTTPS_PROXY`, and `NO_PROXY` environment variables.
NetworkProxyRaw json.RawMessage `json:"network_proxy,omitempty" caddy:"namespace=caddy.network_proxy.source inline_key=from"`
h2cTransport *http2.Transport
h3Transport *http3.Transport // TODO: EXPERIMENTAL (May 2024)
}
@ -328,16 +346,22 @@ func (h *HTTPTransport) NewTransport(caddyCtx caddy.Context) (*http.Transport, e
}
// negotiate any HTTP/SOCKS proxy for the HTTP transport
var proxy func(*http.Request) (*url.URL, error)
proxy := http.ProxyFromEnvironment
if h.ForwardProxyURL != "" {
pUrl, err := url.Parse(h.ForwardProxyURL)
if err != nil {
return nil, fmt.Errorf("failed to parse transport proxy url: %v", err)
caddyCtx.Logger().Warn("forward_proxy_url is deprecated; use network_proxy instead")
u := network.ProxyFromURL{URL: h.ForwardProxyURL}
h.NetworkProxyRaw = caddyconfig.JSONModuleObject(u, "from", "url", nil)
}
caddyCtx.Logger().Info("setting transport proxy url", zap.String("url", h.ForwardProxyURL))
proxy = http.ProxyURL(pUrl)
if len(h.NetworkProxyRaw) != 0 {
proxyMod, err := caddyCtx.LoadModule(h, "ForwardProxyRaw")
if err != nil {
return nil, fmt.Errorf("failed to load network_proxy module: %v", err)
}
if m, ok := proxyMod.(caddy.ProxyFuncProducer); ok {
proxy = m.ProxyFunc()
} else {
proxy = http.ProxyFromEnvironment
return nil, fmt.Errorf("network_proxy module is not `(func(*http.Request) (*url.URL, error))``")
}
}
rt := &http.Transport{

View File

@ -106,6 +106,9 @@ type ACMEIssuer struct {
// be used. EXPERIMENTAL: Subject to change.
CertificateLifetime caddy.Duration `json:"certificate_lifetime,omitempty"`
// Forward proxy module
NetworkProxyRaw json.RawMessage `json:"network_proxy,omitempty" caddy:"namespace=caddy.network_proxy.source inline_key=from"`
rootPool *x509.CertPool
logger *zap.Logger
@ -179,7 +182,7 @@ func (iss *ACMEIssuer) Provision(ctx caddy.Context) error {
}
var err error
iss.template, err = iss.makeIssuerTemplate()
iss.template, err = iss.makeIssuerTemplate(ctx)
if err != nil {
return err
}
@ -187,7 +190,7 @@ func (iss *ACMEIssuer) Provision(ctx caddy.Context) error {
return nil
}
func (iss *ACMEIssuer) makeIssuerTemplate() (certmagic.ACMEIssuer, error) {
func (iss *ACMEIssuer) makeIssuerTemplate(ctx caddy.Context) (certmagic.ACMEIssuer, error) {
template := certmagic.ACMEIssuer{
CA: iss.CA,
TestCA: iss.TestCA,
@ -201,6 +204,18 @@ func (iss *ACMEIssuer) makeIssuerTemplate() (certmagic.ACMEIssuer, error) {
Logger: iss.logger,
}
if len(iss.NetworkProxyRaw) != 0 {
proxyMod, err := ctx.LoadModule(iss, "ForwardProxyRaw")
if err != nil {
return template, fmt.Errorf("failed to load network_proxy module: %v", err)
}
if m, ok := proxyMod.(caddy.ProxyFuncProducer); ok {
template.HTTPProxy = m.ProxyFunc()
} else {
return template, fmt.Errorf("network_proxy module is not `(func(*http.Request) (*url.URL, error))``")
}
}
if iss.Challenges != nil {
if iss.Challenges.HTTP != nil {
template.DisableHTTPChallenge = iss.Challenges.HTTP.Disabled

View File

@ -0,0 +1,3 @@
package caddytls
import _ "github.com/caddyserver/caddy/v2/modules/internal/network"

View File

@ -85,7 +85,7 @@ func getOptimalDefaultCipherSuites() []uint16 {
// or key exchange mechanisms ("curves" traditionally).
// https://golang.org/pkg/crypto/tls/#CurveID
var SupportedCurves = map[string]tls.CurveID{
"X25519mlkem768": tls.X25519MLKEM768,
"x25519mlkem768": tls.X25519MLKEM768,
"x25519": tls.X25519,
"secp256r1": tls.CurveP256,
"secp384r1": tls.CurveP384,

View File

@ -0,0 +1,144 @@
package network
import (
"errors"
"net/http"
"net/url"
"strings"
"go.uber.org/zap"
"github.com/caddyserver/caddy/v2"
"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
)
func init() {
caddy.RegisterModule(ProxyFromURL{})
caddy.RegisterModule(ProxyFromNone{})
}
// The "url" proxy source uses the defined URL as the proxy
type ProxyFromURL struct {
URL string `json:"url"`
ctx caddy.Context
logger *zap.Logger
}
// CaddyModule implements Module.
func (p ProxyFromURL) CaddyModule() caddy.ModuleInfo {
return caddy.ModuleInfo{
ID: "caddy.network_proxy.source.url",
New: func() caddy.Module {
return &ProxyFromURL{}
},
}
}
func (p *ProxyFromURL) Provision(ctx caddy.Context) error {
p.ctx = ctx
p.logger = ctx.Logger()
return nil
}
// Validate implements Validator.
func (p ProxyFromURL) Validate() error {
if _, err := url.Parse(p.URL); err != nil {
return err
}
return nil
}
// ProxyFunc implements ProxyFuncProducer.
func (p ProxyFromURL) ProxyFunc() func(*http.Request) (*url.URL, error) {
if strings.Contains(p.URL, "{") && strings.Contains(p.URL, "}") {
// courtesy of @ImpostorKeanu: https://github.com/caddyserver/caddy/pull/6397
return func(r *http.Request) (*url.URL, error) {
// retrieve the replacer from context.
repl, ok := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
if !ok {
err := errors.New("failed to obtain replacer from request")
p.logger.Error(err.Error())
return nil, err
}
// apply placeholders to the value
// note: h.ForwardProxyURL should never be empty at this point
s := repl.ReplaceAll(p.URL, "")
if s == "" {
p.logger.Error("network_proxy URL was empty after applying placeholders",
zap.String("initial_value", p.URL),
zap.String("final_value", s),
zap.String("hint", "check for invalid placeholders"))
return nil, errors.New("empty value for network_proxy URL")
}
// parse the url
pUrl, err := url.Parse(s)
if err != nil {
p.logger.Warn("failed to derive transport proxy from network_proxy URL")
pUrl = nil
} else if pUrl.Host == "" || strings.Split("", pUrl.Host)[0] == ":" {
// url.Parse does not return an error on these values:
//
// - http://:80
// - pUrl.Host == ":80"
// - /some/path
// - pUrl.Host == ""
//
// Super edge cases, but humans are human.
err = errors.New("supplied network_proxy URL is missing a host value")
pUrl = nil
} else {
p.logger.Debug("setting transport proxy url", zap.String("url", s))
}
return pUrl, err
}
}
return func(r *http.Request) (*url.URL, error) {
return url.Parse(p.URL)
}
}
// UnmarshalCaddyfile implements caddyfile.Unmarshaler.
func (p *ProxyFromURL) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
d.Next()
d.Next()
p.URL = d.Val()
return nil
}
// The "none" proxy source module disables the use of network proxy.
type ProxyFromNone struct{}
func (p ProxyFromNone) CaddyModule() caddy.ModuleInfo {
return caddy.ModuleInfo{
ID: "caddy.network_proxy.source.none",
New: func() caddy.Module {
return &ProxyFromNone{}
},
}
}
// UnmarshalCaddyfile implements caddyfile.Unmarshaler.
func (p ProxyFromNone) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
return nil
}
// ProxyFunc implements ProxyFuncProducer.
func (p ProxyFromNone) ProxyFunc() func(*http.Request) (*url.URL, error) {
return nil
}
var (
_ caddy.Module = ProxyFromURL{}
_ caddy.Provisioner = &ProxyFromURL{}
_ caddy.Validator = ProxyFromURL{}
_ caddy.ProxyFuncProducer = ProxyFromURL{}
_ caddyfile.Unmarshaler = &ProxyFromURL{}
_ caddy.Module = ProxyFromNone{}
_ caddy.ProxyFuncProducer = ProxyFromNone{}
_ caddyfile.Unmarshaler = ProxyFromNone{}
)

10
network.go Normal file
View File

@ -0,0 +1,10 @@
package caddy
import (
"net/http"
"net/url"
)
type ProxyFuncProducer interface {
ProxyFunc() func(*http.Request) (*url.URL, error)
}