mirror of
https://github.com/yusing/godoxy.git
synced 2025-06-09 13:02:33 +02:00
enable domain matching, removed unnecessary path_pattern check
This commit is contained in:
parent
58cfba7695
commit
3f9d73d784
5 changed files with 29 additions and 100 deletions
21
internal/net/http/serve_mux.go
Normal file
21
internal/net/http/serve_mux.go
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
package http
|
||||||
|
|
||||||
|
import "net/http"
|
||||||
|
|
||||||
|
type ServeMux struct {
|
||||||
|
*http.ServeMux
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewServeMux() ServeMux {
|
||||||
|
return ServeMux{http.NewServeMux()}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mux ServeMux) HandleFunc(pattern string, handler http.HandlerFunc) (err error) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
err = r.(error)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
mux.ServeMux.HandleFunc(pattern, handler)
|
||||||
|
return
|
||||||
|
}
|
|
@ -20,7 +20,7 @@ type ReverseProxyEntry struct { // real model after validation
|
||||||
Scheme route.Scheme `json:"scheme"`
|
Scheme route.Scheme `json:"scheme"`
|
||||||
URL net.URL `json:"url"`
|
URL net.URL `json:"url"`
|
||||||
NoTLSVerify bool `json:"no_tls_verify,omitempty"`
|
NoTLSVerify bool `json:"no_tls_verify,omitempty"`
|
||||||
PathPatterns route.PathPatterns `json:"path_patterns,omitempty"`
|
PathPatterns []string `json:"path_patterns,omitempty"`
|
||||||
HealthCheck *health.HealthCheckConfig `json:"healthcheck,omitempty"`
|
HealthCheck *health.HealthCheckConfig `json:"healthcheck,omitempty"`
|
||||||
LoadBalance *loadbalance.Config `json:"load_balance,omitempty"`
|
LoadBalance *loadbalance.Config `json:"load_balance,omitempty"`
|
||||||
Middlewares map[string]docker.LabelMap `json:"middlewares,omitempty"`
|
Middlewares map[string]docker.LabelMap `json:"middlewares,omitempty"`
|
||||||
|
@ -66,7 +66,6 @@ func validateRPEntry(m *route.RawEntry, s route.Scheme, errs *E.Builder) *Revers
|
||||||
|
|
||||||
host := E.Collect(errs, route.ValidateHost, m.Host)
|
host := E.Collect(errs, route.ValidateHost, m.Host)
|
||||||
port := E.Collect(errs, route.ValidatePort, m.Port)
|
port := E.Collect(errs, route.ValidatePort, m.Port)
|
||||||
pathPats := E.Collect(errs, route.ValidatePathPatterns, m.PathPatterns)
|
|
||||||
url := E.Collect(errs, url.Parse, fmt.Sprintf("%s://%s:%d", s, host, port))
|
url := E.Collect(errs, url.Parse, fmt.Sprintf("%s://%s:%d", s, host, port))
|
||||||
iwCfg := E.Collect(errs, idlewatcher.ValidateConfig, cont)
|
iwCfg := E.Collect(errs, idlewatcher.ValidateConfig, cont)
|
||||||
|
|
||||||
|
@ -80,7 +79,7 @@ func validateRPEntry(m *route.RawEntry, s route.Scheme, errs *E.Builder) *Revers
|
||||||
Scheme: s,
|
Scheme: s,
|
||||||
URL: net.NewURL(url),
|
URL: net.NewURL(url),
|
||||||
NoTLSVerify: m.NoTLSVerify,
|
NoTLSVerify: m.NoTLSVerify,
|
||||||
PathPatterns: pathPats,
|
PathPatterns: m.PathPatterns,
|
||||||
HealthCheck: m.HealthCheck,
|
HealthCheck: m.HealthCheck,
|
||||||
LoadBalance: lb,
|
LoadBalance: lb,
|
||||||
Middlewares: m.Middlewares,
|
Middlewares: m.Middlewares,
|
||||||
|
|
|
@ -102,9 +102,13 @@ func (r *HTTPRoute) Start(providerSubtask task.Task) E.Error {
|
||||||
case len(r.PathPatterns) == 1 && r.PathPatterns[0] == "/":
|
case len(r.PathPatterns) == 1 && r.PathPatterns[0] == "/":
|
||||||
r.handler = r.rp
|
r.handler = r.rp
|
||||||
default:
|
default:
|
||||||
mux := http.NewServeMux()
|
mux := gphttp.NewServeMux()
|
||||||
|
patErrs := E.NewBuilder("invalid path pattern(s)")
|
||||||
for _, p := range r.PathPatterns {
|
for _, p := range r.PathPatterns {
|
||||||
mux.HandleFunc(string(p), r.rp.HandlerFunc)
|
patErrs.Add(mux.HandleFunc(p, r.rp.HandlerFunc))
|
||||||
|
}
|
||||||
|
if err := patErrs.Error(); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
r.handler = mux
|
r.handler = mux
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
package types
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"regexp"
|
|
||||||
|
|
||||||
E "github.com/yusing/go-proxy/internal/error"
|
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
|
||||||
PathPattern string
|
|
||||||
PathPatterns = []PathPattern
|
|
||||||
)
|
|
||||||
|
|
||||||
var pathPattern = regexp.MustCompile(`^(/[-\w./]*({\$\})?|((GET|POST|DELETE|PUT|HEAD|OPTION) /[-\w./]*({\$\})?))$`)
|
|
||||||
|
|
||||||
var (
|
|
||||||
ErrEmptyPathPattern = errors.New("path must not be empty")
|
|
||||||
ErrInvalidPathPattern = errors.New("invalid path pattern")
|
|
||||||
)
|
|
||||||
|
|
||||||
func ValidatePathPattern(s string) (PathPattern, error) {
|
|
||||||
if len(s) == 0 {
|
|
||||||
return "", ErrEmptyPathPattern
|
|
||||||
}
|
|
||||||
if !pathPattern.MatchString(s) {
|
|
||||||
return "", fmt.Errorf("%w %q", ErrInvalidPathPattern, s)
|
|
||||||
}
|
|
||||||
return PathPattern(s), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ValidatePathPatterns(s []string) (PathPatterns, E.Error) {
|
|
||||||
if len(s) == 0 {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
errs := E.NewBuilder("invalid path patterns")
|
|
||||||
pp := make(PathPatterns, len(s))
|
|
||||||
for i, v := range s {
|
|
||||||
pattern, err := ValidatePathPattern(v)
|
|
||||||
if err != nil {
|
|
||||||
errs.Add(err)
|
|
||||||
} else {
|
|
||||||
pp[i] = pattern
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return pp, errs.Error()
|
|
||||||
}
|
|
|
@ -1,47 +0,0 @@
|
||||||
package types
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
U "github.com/yusing/go-proxy/internal/utils/testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
var validPatterns = []string{
|
|
||||||
"/",
|
|
||||||
"/index.html",
|
|
||||||
"/somepage/",
|
|
||||||
"/drive/abc.mp4",
|
|
||||||
"/{$}",
|
|
||||||
"/some-page/{$}",
|
|
||||||
"GET /",
|
|
||||||
"GET /static/{$}",
|
|
||||||
"GET /drive/abc.mp4",
|
|
||||||
"GET /drive/abc.mp4/{$}",
|
|
||||||
"POST /auth",
|
|
||||||
"DELETE /user/",
|
|
||||||
"PUT /storage/id/",
|
|
||||||
}
|
|
||||||
|
|
||||||
var invalidPatterns = []string{
|
|
||||||
"/$",
|
|
||||||
"/{$}{$}",
|
|
||||||
"/{$}/{$}",
|
|
||||||
"/index.html$",
|
|
||||||
"get /",
|
|
||||||
"GET/",
|
|
||||||
"GET /$",
|
|
||||||
"GET /drive/{$}/abc.mp4/",
|
|
||||||
"OPTION /config/{$}/abc.conf/{$}",
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPathPatternRegex(t *testing.T) {
|
|
||||||
for _, pattern := range validPatterns {
|
|
||||||
_, err := ValidatePathPattern(pattern)
|
|
||||||
U.ExpectNoError(t, err)
|
|
||||||
}
|
|
||||||
for _, pattern := range invalidPatterns {
|
|
||||||
_, err := ValidatePathPattern(pattern)
|
|
||||||
U.ExpectTrue(t, errors.Is(err, ErrInvalidPathPattern))
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Add table
Reference in a new issue