feat: initial commit
All checks were successful
Cadoles/bouncer/pipeline/head This commit looks good
All checks were successful
Cadoles/bouncer/pipeline/head This commit looks good
This commit is contained in:
90
internal/proxy/middleware/director/director.go
Normal file
90
internal/proxy/middleware/director/director.go
Normal file
@ -0,0 +1,90 @@
|
||||
package director
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"forge.cadoles.com/Cadoles/go-proxy"
|
||||
"forge.cadoles.com/Cadoles/go-proxy/wildcard"
|
||||
"forge.cadoles.com/cadoles/bouncer/internal/store"
|
||||
"github.com/pkg/errors"
|
||||
"gitlab.com/wpetit/goweb/logger"
|
||||
)
|
||||
|
||||
type Director struct {
|
||||
repo store.ProxyRepository
|
||||
}
|
||||
|
||||
func (d *Director) rewriteRequest(r *http.Request) error {
|
||||
ctx := r.Context()
|
||||
|
||||
proxies, err := d.getProxies(ctx)
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
var match *url.URL
|
||||
|
||||
MAIN:
|
||||
for _, p := range proxies {
|
||||
for _, from := range p.From {
|
||||
if matches := wildcard.Match(r.Host, from); !matches {
|
||||
continue
|
||||
}
|
||||
|
||||
match = p.To
|
||||
break MAIN
|
||||
}
|
||||
}
|
||||
|
||||
if match == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
r.URL.Host = match.Host
|
||||
r.URL.Scheme = match.Scheme
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Director) getProxies(ctx context.Context) ([]*store.Proxy, error) {
|
||||
headers, err := d.repo.QueryProxy(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
proxies := make([]*store.Proxy, len(headers))
|
||||
|
||||
for i, h := range headers {
|
||||
proxy, err := d.repo.GetProxy(ctx, h.ID)
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
proxies[i] = proxy
|
||||
}
|
||||
|
||||
return proxies, nil
|
||||
}
|
||||
|
||||
func (d *Director) Middleware() proxy.Middleware {
|
||||
return func(next http.Handler) http.Handler {
|
||||
fn := func(w http.ResponseWriter, r *http.Request) {
|
||||
if err := d.rewriteRequest(r); err != nil {
|
||||
logger.Error(r.Context(), "could not rewrite request", logger.E(errors.WithStack(err)))
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
next.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
return http.HandlerFunc(fn)
|
||||
}
|
||||
}
|
||||
|
||||
func New(repo store.ProxyRepository) *Director {
|
||||
return &Director{repo}
|
||||
}
|
Reference in New Issue
Block a user