Skip to content

Commit

Permalink
refactor: improve http client
Browse files Browse the repository at this point in the history
  • Loading branch information
Marco98 committed Jul 22, 2024
1 parent 3a8ba71 commit 89e1858
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 36 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ WIP
listen_port: 8080
tls_cert_file: server.crt
tls_key_file: server.key
tls_ignore_cert: true
server_timeout_read: 5 # Default 600
server_timeout_write: 10 # Default 600
# hooks
hide_repowarn: true
passthroughauth: true
# connectivity
check_interval: 5
ignore_cert: true
username: svc_pveportal
password: insecure
# clusters
Expand Down
2 changes: 1 addition & 1 deletion pkg/config/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ func parseConfig(yaml *YamlConfig) (*Config, error) {
Name: hv.Name,
Endpoint: ep,
Online: false,
IgnoreCert: defaultbool(lastbool(yaml.IgnoreCert, cv.IgnoreCert, hv.IgnoreCert), false),
HideRepowarn: defaultbool(lastbool(yaml.HideRepowarn, cv.HideRepowarn, hv.HideRepowarn), false),
Username: user,
Password: pass,
Expand All @@ -75,6 +74,7 @@ func parseConfig(yaml *YamlConfig) (*Config, error) {
SessionTime: sessionTime,
TLSCertFile: yaml.TLSCertFile,
TLSKeyFile: yaml.TLSKeyFile,
TLSIgnoreCert: defaultbool(yaml.TLSIgnoreCert, false),
ServerTimeoutWrite: defaultint(yaml.ServerTimeoutWrite, 600),
ServerTimeoutRead: defaultint(yaml.ServerTimeoutRead, 600),
}, nil
Expand Down
5 changes: 2 additions & 3 deletions pkg/config/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ type YamlConfig struct {
ListenPort uint16 `yaml:"listen_port"`
TLSCertFile string `yaml:"tls_cert_file"`
TLSKeyFile string `yaml:"tls_key_file"`
TLSIgnoreCert *bool `yaml:"tls_ignore_cert"`
ServerTimeoutWrite *int `yaml:"server_timeout_write"`
ServerTimeoutRead *int `yaml:"server_timeout_read"`
Clusters []YamlCluster `yaml:"clusters"`
PassthroughAuth *bool `yaml:"passthroughauth"`
SessionTime string `yaml:"sessiontime"`
// inheritable
IgnoreCert *bool `yaml:"ignore_cert"`
HideRepowarn *bool `yaml:"hide_repowarn"`
Username string `yaml:"username"`
Password string `yaml:"password"`
Expand All @@ -28,7 +28,6 @@ type YamlCluster struct {
Name string `yaml:"name"`
Hosts []YamlHost `yaml:"hosts"`
// inheritable
IgnoreCert *bool `yaml:"ignore_cert"`
HideRepowarn *bool `yaml:"hide_repowarn"`
Username string `yaml:"username"`
Password string `yaml:"password"`
Expand All @@ -39,7 +38,6 @@ type YamlHost struct {
Name string `yaml:"name"`
Endpoint string `yaml:"endpoint"`
// inheritable
IgnoreCert *bool `yaml:"ignore_cert"`
HideRepowarn *bool `yaml:"hide_repowarn"`
Username string `yaml:"username"`
Password string `yaml:"password"`
Expand All @@ -52,6 +50,7 @@ type Config struct {
SessionTime time.Duration
TLSCertFile string
TLSKeyFile string
TLSIgnoreCert bool
Clusters []Cluster
ServerTimeoutWrite int
ServerTimeoutRead int
Expand Down
10 changes: 1 addition & 9 deletions pkg/proxy/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,6 @@ func (p *Proxy) proxyHandler() func(w http.ResponseWriter, r *http.Request) {
}

func (p *Proxy) proxyRequest(cluster string, host *config.Host, w http.ResponseWriter, r *http.Request) error {
client := &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
TLSClientConfig: &tls.Config{
InsecureSkipVerify: host.IgnoreCert, //nolint:gosec,G402
},
},
}
tgturl := *r.URL
tgturl.Scheme = host.Endpoint.Scheme
tgturl.Host = host.Endpoint.Host
Expand All @@ -103,7 +95,7 @@ func (p *Proxy) proxyRequest(cluster string, host *config.Host, w http.ResponseW
return err
}
}
resp, err := client.Do(req)
resp, err := p.httpClient.Do(req)
if err != nil {
return err
}
Expand Down
18 changes: 11 additions & 7 deletions pkg/proxy/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,20 @@ func Run(www embed.FS) error {
if err != nil {
return err
}
fs := http.FileServer(http.FS(htmlContent))
http.HandleFunc(fmt.Sprintf("%sapi/clusters", localHTTPDir), listClusters(cfg.Clusters))
http.HandleFunc(fmt.Sprintf("%sapi/switchcluster", localHTTPDir), switchCluster())
http.Handle(localHTTPDir, http.StripPrefix(localHTTPDir, fs))
prx := NewProxy(cfg)
handler := prx.proxyHandler()
http.HandleFunc("/", handler)
prx, err := NewProxy(cfg)
if err != nil {
return err
}
defer prx.close()
tlscfg, err := prx.parseTLSConfig()
if err != nil {
return err
}
fs := http.FileServer(http.FS(htmlContent))
http.HandleFunc(fmt.Sprintf("%sapi/clusters", localHTTPDir), listClusters(cfg.Clusters))
http.HandleFunc(fmt.Sprintf("%sapi/switchcluster", localHTTPDir), switchCluster())
http.Handle(localHTTPDir, http.StripPrefix(localHTTPDir, fs))
http.HandleFunc("/", prx.proxyHandler())
srv := &http.Server{
ReadTimeout: time.Duration(cfg.ServerTimeoutRead) * time.Second,
WriteTimeout: time.Duration(cfg.ServerTimeoutWrite) * time.Second,
Expand Down Expand Up @@ -122,6 +125,7 @@ func (p *Proxy) parseTLSConfig() (*tls.Config, error) {
return &tls.Config{
Certificates: []tls.Certificate{crt},
MinVersion: tls.VersionTLS12,
KeyLogWriter: p.sslKeyLogFile,
}, nil
}

Expand Down
53 changes: 39 additions & 14 deletions pkg/proxy/sessions.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"fmt"
"io"
"net/http"
"os"
"sync"
"time"

Expand All @@ -18,16 +19,48 @@ import (
)

type Proxy struct {
config *config.Config
sessions map[uuid.UUID]map[string]http.Cookie
sessionsLock *sync.RWMutex
config *config.Config
sessions map[uuid.UUID]map[string]http.Cookie
sessionsLock *sync.RWMutex
httpClient *http.Client
sslKeyLogFile io.WriteCloser
}

func NewProxy(config *config.Config) *Proxy {
return &Proxy{
func NewProxy(config *config.Config) (*Proxy, error) {
transport := &http.Transport{
Proxy: http.ProxyFromEnvironment,
TLSClientConfig: &tls.Config{
InsecureSkipVerify: config.TLSIgnoreCert, //nolint:gosec,G402
},
ForceAttemptHTTP2: true,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
}
p := &Proxy{
sessions: make(map[uuid.UUID]map[string]http.Cookie),
sessionsLock: &sync.RWMutex{},
config: config,
httpClient: &http.Client{
Transport: transport,
},
}
path := os.Getenv("SSLKEYLOGFILE")
if len(path) != 0 {
var err error
p.sslKeyLogFile, err = os.OpenFile(path, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0o600)
if err != nil {
return nil, fmt.Errorf("could not open SSLKEYLOGFILE: %w", err)
}
transport.TLSClientConfig.KeyLogWriter = p.sslKeyLogFile
}
return p, nil
}

func (p *Proxy) close() {
if p.sslKeyLogFile != nil {
p.sslKeyLogFile.Close()
}
}

Expand Down Expand Up @@ -66,14 +99,6 @@ func (p *Proxy) multiAuth(log logrus.FieldLogger, w http.ResponseWriter, r *http
resps := make(map[string]http.Response)
for _, v := range p.config.Clusters {
host := getHealthyHost(v.Hosts)
client := &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
TLSClientConfig: &tls.Config{
InsecureSkipVerify: host.IgnoreCert, //nolint:gosec,G402
},
},
}
tgturl := *r.URL
tgturl.Scheme = host.Endpoint.Scheme
tgturl.Host = host.Endpoint.Host
Expand All @@ -87,7 +112,7 @@ func (p *Proxy) multiAuth(log logrus.FieldLogger, w http.ResponseWriter, r *http
continue
}
p.copyHeaders(r.Header, req.Header)
resp, err := client.Do(req)
resp, err := p.httpClient.Do(req)
if err != nil {
log.WithError(err).Error("failed multiauth")
continue
Expand Down
2 changes: 1 addition & 1 deletion res/pveportal.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
listen_port: 80
# tls_cert_file: server.crt
# tls_key_file: server.key
tls_ignore_cert: true

# hooks
hide_repowarn: true
passthroughauth: true

# connectivity
check_interval: 5
ignore_cert: true
username: dummy
password: dummy

Expand Down

0 comments on commit 89e1858

Please sign in to comment.