2023-03-28 11:02:53 +02:00
|
|
|
package proxy
|
|
|
|
|
|
|
|
import (
|
|
|
|
"net/http"
|
|
|
|
"net/url"
|
|
|
|
"sort"
|
|
|
|
|
2023-03-28 20:43:45 +02:00
|
|
|
"forge.cadoles.com/Cadoles/emissary/internal/proxy/wildcard"
|
2023-03-28 11:02:53 +02:00
|
|
|
"gitlab.com/wpetit/goweb/logger"
|
|
|
|
)
|
|
|
|
|
|
|
|
func RewriteHosts(mappings map[string]*url.URL) Middleware {
|
|
|
|
patterns := make([]string, len(mappings))
|
|
|
|
|
|
|
|
for p := range mappings {
|
|
|
|
patterns = append(patterns, p)
|
|
|
|
}
|
|
|
|
|
|
|
|
sort.Strings(patterns)
|
2023-03-28 20:43:45 +02:00
|
|
|
reverse(patterns)
|
2023-03-28 11:02:53 +02:00
|
|
|
|
|
|
|
return func(h http.Handler) http.Handler {
|
|
|
|
fn := func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
ctx := r.Context()
|
|
|
|
|
|
|
|
var match *url.URL
|
|
|
|
|
|
|
|
for _, p := range patterns {
|
|
|
|
logger.Debug(ctx, "matching host to pattern", logger.F("host", r.Host), logger.F("pattern", p))
|
|
|
|
|
|
|
|
if matches := wildcard.Match(r.Host, p); !matches {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
match = mappings[p]
|
|
|
|
break
|
|
|
|
}
|
|
|
|
|
|
|
|
if match == nil {
|
|
|
|
h.ServeHTTP(w, r)
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx = logger.With(ctx, logger.F("originalHost", r.Host))
|
|
|
|
r = r.WithContext(ctx)
|
|
|
|
|
|
|
|
originalURL := r.URL.String()
|
|
|
|
|
|
|
|
r.URL.Host = match.Host
|
|
|
|
r.URL.Scheme = match.Scheme
|
|
|
|
|
|
|
|
logger.Debug(ctx, "rewriting url", logger.F("from", originalURL), logger.F("to", r.URL.String()))
|
|
|
|
|
|
|
|
h.ServeHTTP(w, r)
|
|
|
|
}
|
|
|
|
|
|
|
|
return http.HandlerFunc(fn)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func WithRewriteHosts(mappings map[string]*url.URL) OptionFunc {
|
|
|
|
return func(o *Options) {
|
|
|
|
o.Middlewares = append(o.Middlewares, RewriteHosts(mappings))
|
|
|
|
}
|
|
|
|
}
|