emissary/internal/agent/controller/proxy/reverse_proxy.go

79 lines
1.4 KiB
Go

package proxy
import (
"context"
"net/http"
"net/http/httputil"
"net/url"
"github.com/pkg/errors"
"gitlab.com/wpetit/goweb/logger"
)
type ReverseProxy struct {
addr string
target string
server *http.Server
}
func (p *ReverseProxy) Start(ctx context.Context, addr, target string) error {
alreadyRunning := p.server != nil && target == p.target && addr == p.target
if alreadyRunning {
return nil
}
if p.server != nil {
if err := p.Stop(); err != nil {
return errors.WithStack(err)
}
}
server := &http.Server{
Addr: addr,
}
url, err := url.Parse(target)
if err != nil {
return errors.WithStack(err)
}
proxy := httputil.NewSingleHostReverseProxy(url)
server.Handler = proxy
p.server = server
p.addr = addr
p.target = target
go func() {
if err := server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
logger.Error(ctx, "error while listening", logger.E(errors.WithStack(err)))
}
if err := p.Stop(); err != nil {
logger.Error(ctx, "error while stopping gateway", logger.E(errors.WithStack(err)))
}
}()
return nil
}
func (p *ReverseProxy) Stop() error {
if p.server == nil {
return nil
}
if err := p.server.Close(); err != nil && !errors.Is(err, http.ErrServerClosed) {
return errors.WithStack(err)
}
p.server = nil
return nil
}
func NewReverseProxy() *ReverseProxy {
return &ReverseProxy{}
}