mirror of
https://github.com/yusing/godoxy.git
synced 2025-07-21 20:04:03 +02:00
go version and deps update, fixed middlewares and metrics
- fixed "API JWT secret empty" warning output format - fixed metrics initialized when it should not - fixed middlewares.modifyRequest Host header not working properly
This commit is contained in:
parent
5214ae1760
commit
f97e3f65fe
13 changed files with 101 additions and 78 deletions
|
@ -1,5 +1,5 @@
|
||||||
# Stage 1: Builder
|
# Stage 1: Builder
|
||||||
FROM golang:1.23.2-alpine AS builder
|
FROM golang:1.23.3-alpine AS builder
|
||||||
RUN apk add --no-cache tzdata make
|
RUN apk add --no-cache tzdata make
|
||||||
|
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
|
|
|
@ -110,6 +110,10 @@ func main() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if common.APIJWTSecret == nil {
|
||||||
|
logging.Warn().Msg("API JWT secret is empty, authentication is disabled")
|
||||||
|
}
|
||||||
|
|
||||||
cfg.StartProxyProviders()
|
cfg.StartProxyProviders()
|
||||||
config.WatchChanges()
|
config.WatchChanges()
|
||||||
|
|
||||||
|
|
4
go.mod
4
go.mod
|
@ -1,6 +1,6 @@
|
||||||
module github.com/yusing/go-proxy
|
module github.com/yusing/go-proxy
|
||||||
|
|
||||||
go 1.23.2
|
go 1.23.3
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/coder/websocket v1.8.12
|
github.com/coder/websocket v1.8.12
|
||||||
|
@ -25,7 +25,7 @@ require (
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
github.com/cloudflare/cloudflare-go v0.108.0 // indirect
|
github.com/cloudflare/cloudflare-go v0.109.0 // indirect
|
||||||
github.com/containerd/log v0.1.0 // indirect
|
github.com/containerd/log v0.1.0 // indirect
|
||||||
github.com/distribution/reference v0.6.0 // indirect
|
github.com/distribution/reference v0.6.0 // indirect
|
||||||
github.com/docker/go-connections v0.5.0 // indirect
|
github.com/docker/go-connections v0.5.0 // indirect
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -8,8 +8,8 @@ github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK3
|
||||||
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/cloudflare/cloudflare-go v0.108.0 h1:C4Skfjd8I8X3uEOGmQUT4/iGyZcWdkIU7HwvMoLkEE0=
|
github.com/cloudflare/cloudflare-go v0.109.0 h1:Wjp+RfJD1lidIFUlrTBqUQnCBrUnmVsLxgzWYiURueg=
|
||||||
github.com/cloudflare/cloudflare-go v0.108.0/go.mod h1:m492eNahT/9MsN7Ppnoge8AaI7QhVFtEgVm3I9HJFeU=
|
github.com/cloudflare/cloudflare-go v0.109.0/go.mod h1:m492eNahT/9MsN7Ppnoge8AaI7QhVFtEgVm3I9HJFeU=
|
||||||
github.com/coder/websocket v1.8.12 h1:5bUXkEPPIbewrnkU8LTCLVaxi4N4J8ahufH2vlo4NAo=
|
github.com/coder/websocket v1.8.12 h1:5bUXkEPPIbewrnkU8LTCLVaxi4N4J8ahufH2vlo4NAo=
|
||||||
github.com/coder/websocket v1.8.12/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs=
|
github.com/coder/websocket v1.8.12/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs=
|
||||||
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
|
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
|
||||||
|
|
|
@ -48,12 +48,6 @@ var (
|
||||||
APIPasswordHash = HashPassword(GetEnvString("API_PASSWORD", "password"))
|
APIPasswordHash = HashPassword(GetEnvString("API_PASSWORD", "password"))
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
|
||||||
if APIJWTSecret == nil && GetArgs().Command == CommandStart {
|
|
||||||
log.Warn().Msg("API JWT secret is empty, authentication is disabled")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetEnv[T any](key string, defaultValue T, parser func(string) (T, error)) T {
|
func GetEnv[T any](key string, defaultValue T, parser func(string) (T, error)) T {
|
||||||
var value string
|
var value string
|
||||||
var ok bool
|
var ok bool
|
||||||
|
|
36
internal/metrics/labels.go
Normal file
36
internal/metrics/labels.go
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
package metrics
|
||||||
|
|
||||||
|
import "github.com/prometheus/client_golang/prometheus"
|
||||||
|
|
||||||
|
type (
|
||||||
|
HTTPRouteMetricLabels struct {
|
||||||
|
Service, Method, Host, Visitor, Path string
|
||||||
|
}
|
||||||
|
StreamRouteMetricLabels struct {
|
||||||
|
Service, Visitor string
|
||||||
|
}
|
||||||
|
HealthMetricLabels string
|
||||||
|
)
|
||||||
|
|
||||||
|
func (lbl *HTTPRouteMetricLabels) toPromLabels() prometheus.Labels {
|
||||||
|
return prometheus.Labels{
|
||||||
|
"service": lbl.Service,
|
||||||
|
"method": lbl.Method,
|
||||||
|
"host": lbl.Host,
|
||||||
|
"visitor": lbl.Visitor,
|
||||||
|
"path": lbl.Path,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lbl *StreamRouteMetricLabels) toPromLabels() prometheus.Labels {
|
||||||
|
return prometheus.Labels{
|
||||||
|
"service": lbl.Service,
|
||||||
|
"visitor": lbl.Visitor,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lbl HealthMetricLabels) toPromLabels() prometheus.Labels {
|
||||||
|
return prometheus.Labels{
|
||||||
|
"service": string(lbl),
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,23 +7,14 @@ import (
|
||||||
"github.com/yusing/go-proxy/internal/common"
|
"github.com/yusing/go-proxy/internal/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type RouteMetrics struct {
|
||||||
RouteMetrics struct {
|
HTTPReqTotal,
|
||||||
HTTPReqTotal,
|
HTTP2xx3xx,
|
||||||
HTTP2xx3xx,
|
HTTP4xx,
|
||||||
HTTP4xx,
|
HTTP5xx *Counter
|
||||||
HTTP5xx *Counter
|
HTTPReqElapsed *Gauge
|
||||||
HTTPReqElapsed *Gauge
|
HealthStatus *Gauge
|
||||||
HealthStatus *Gauge
|
}
|
||||||
}
|
|
||||||
HTTPRouteMetricLabels struct {
|
|
||||||
Service, Method, Host, Visitor, Path string
|
|
||||||
}
|
|
||||||
StreamRouteMetricLabels struct {
|
|
||||||
Service, Visitor string
|
|
||||||
}
|
|
||||||
HealthMetricLabels string
|
|
||||||
)
|
|
||||||
|
|
||||||
var rm RouteMetrics
|
var rm RouteMetrics
|
||||||
|
|
||||||
|
@ -38,29 +29,6 @@ func GetRouteMetrics() *RouteMetrics {
|
||||||
return &rm
|
return &rm
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lbl *HTTPRouteMetricLabels) toPromLabels() prometheus.Labels {
|
|
||||||
return prometheus.Labels{
|
|
||||||
"service": lbl.Service,
|
|
||||||
"method": lbl.Method,
|
|
||||||
"host": lbl.Host,
|
|
||||||
"visitor": lbl.Visitor,
|
|
||||||
"path": lbl.Path,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (lbl *StreamRouteMetricLabels) toPromLabels() prometheus.Labels {
|
|
||||||
return prometheus.Labels{
|
|
||||||
"service": lbl.Service,
|
|
||||||
"visitor": lbl.Visitor,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (lbl HealthMetricLabels) toPromLabels() prometheus.Labels {
|
|
||||||
return prometheus.Labels{
|
|
||||||
"service": string(lbl),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
if !common.PrometheusEnabled {
|
if !common.PrometheusEnabled {
|
||||||
return
|
return
|
|
@ -1,8 +1,14 @@
|
||||||
package metrics
|
package metrics
|
||||||
|
|
||||||
import "github.com/prometheus/client_golang/prometheus"
|
import (
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
"github.com/yusing/go-proxy/internal/common"
|
||||||
|
)
|
||||||
|
|
||||||
func InitRouterMetrics(getRPsCount func() int, getStreamsCount func() int) {
|
func InitRouterMetrics(getRPsCount func() int, getStreamsCount func() int) {
|
||||||
|
if !common.PrometheusEnabled {
|
||||||
|
return
|
||||||
|
}
|
||||||
prometheus.MustRegister(prometheus.NewGaugeFunc(prometheus.GaugeOpts{
|
prometheus.MustRegister(prometheus.NewGaugeFunc(prometheus.GaugeOpts{
|
||||||
Namespace: "entrypoint",
|
Namespace: "entrypoint",
|
||||||
Name: "num_reverse_proxies",
|
Name: "num_reverse_proxies",
|
||||||
|
|
|
@ -2,7 +2,6 @@ package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
|
@ -167,7 +166,10 @@ func patchReverseProxy(rpName string, rp *ReverseProxy, middlewares []*Middlewar
|
||||||
if rp.ModifyResponse != nil {
|
if rp.ModifyResponse != nil {
|
||||||
ori := rp.ModifyResponse
|
ori := rp.ModifyResponse
|
||||||
rp.ModifyResponse = func(res *http.Response) error {
|
rp.ModifyResponse = func(res *http.Response) error {
|
||||||
return errors.Join(mid.modifyResponse(res), ori(res))
|
if err := mid.modifyResponse(res); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return ori(res)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rp.ModifyResponse = mid.modifyResponse
|
rp.ModifyResponse = mid.modifyResponse
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
"github.com/yusing/go-proxy/internal/common"
|
"github.com/yusing/go-proxy/internal/common"
|
||||||
E "github.com/yusing/go-proxy/internal/error"
|
E "github.com/yusing/go-proxy/internal/error"
|
||||||
)
|
)
|
||||||
|
@ -22,11 +24,9 @@ var ModifyRequest = &Middleware{withOptions: NewModifyRequest}
|
||||||
|
|
||||||
func NewModifyRequest(optsRaw OptionsRaw) (*Middleware, E.Error) {
|
func NewModifyRequest(optsRaw OptionsRaw) (*Middleware, E.Error) {
|
||||||
mr := new(modifyRequest)
|
mr := new(modifyRequest)
|
||||||
var mrFunc RewriteFunc
|
mrFunc := mr.modifyRequest
|
||||||
if common.IsDebug {
|
if common.IsDebug {
|
||||||
mrFunc = mr.modifyRequestWithTrace
|
mrFunc = mr.modifyRequestWithTrace
|
||||||
} else {
|
|
||||||
mrFunc = mr.modifyRequest
|
|
||||||
}
|
}
|
||||||
mr.m = &Middleware{
|
mr.m = &Middleware{
|
||||||
impl: mr,
|
impl: mr,
|
||||||
|
@ -41,6 +41,9 @@ func NewModifyRequest(optsRaw OptionsRaw) (*Middleware, E.Error) {
|
||||||
|
|
||||||
func (mr *modifyRequest) modifyRequest(req *Request) {
|
func (mr *modifyRequest) modifyRequest(req *Request) {
|
||||||
for k, v := range mr.SetHeaders {
|
for k, v := range mr.SetHeaders {
|
||||||
|
if http.CanonicalHeaderKey(k) == "Host" {
|
||||||
|
req.Host = v
|
||||||
|
}
|
||||||
req.Header.Set(k, v)
|
req.Header.Set(k, v)
|
||||||
}
|
}
|
||||||
for k, v := range mr.AddHeaders {
|
for k, v := range mr.AddHeaders {
|
||||||
|
|
|
@ -9,7 +9,10 @@ import (
|
||||||
|
|
||||||
func TestSetModifyRequest(t *testing.T) {
|
func TestSetModifyRequest(t *testing.T) {
|
||||||
opts := OptionsRaw{
|
opts := OptionsRaw{
|
||||||
"set_headers": map[string]string{"User-Agent": "go-proxy/v0.5.0"},
|
"set_headers": map[string]string{
|
||||||
|
"User-Agent": "go-proxy/v0.5.0",
|
||||||
|
"Host": "test.example.com",
|
||||||
|
},
|
||||||
"add_headers": map[string]string{"Accept-Encoding": "test-value"},
|
"add_headers": map[string]string{"Accept-Encoding": "test-value"},
|
||||||
"hide_headers": []string{"Accept"},
|
"hide_headers": []string{"Accept"},
|
||||||
}
|
}
|
||||||
|
@ -28,6 +31,7 @@ func TestSetModifyRequest(t *testing.T) {
|
||||||
})
|
})
|
||||||
ExpectNoError(t, err)
|
ExpectNoError(t, err)
|
||||||
ExpectEqual(t, result.RequestHeaders.Get("User-Agent"), "go-proxy/v0.5.0")
|
ExpectEqual(t, result.RequestHeaders.Get("User-Agent"), "go-proxy/v0.5.0")
|
||||||
|
ExpectEqual(t, result.RequestHeaders.Get("Host"), "test.example.com")
|
||||||
ExpectTrue(t, slices.Contains(result.RequestHeaders.Values("Accept-Encoding"), "test-value"))
|
ExpectTrue(t, slices.Contains(result.RequestHeaders.Values("Accept-Encoding"), "test-value"))
|
||||||
ExpectEqual(t, result.RequestHeaders.Get("Accept"), "")
|
ExpectEqual(t, result.RequestHeaders.Get("Accept"), "")
|
||||||
})
|
})
|
||||||
|
|
|
@ -2,6 +2,7 @@ package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -15,10 +16,7 @@ const (
|
||||||
|
|
||||||
var SetXForwarded = &Middleware{
|
var SetXForwarded = &Middleware{
|
||||||
before: Rewrite(func(req *Request) {
|
before: Rewrite(func(req *Request) {
|
||||||
req.Header.Del("Forwarded")
|
delXForwarded(req)
|
||||||
req.Header.Del(xForwardedFor)
|
|
||||||
req.Header.Del(xForwardedHost)
|
|
||||||
req.Header.Del(xForwardedProto)
|
|
||||||
clientIP, _, err := net.SplitHostPort(req.RemoteAddr)
|
clientIP, _, err := net.SplitHostPort(req.RemoteAddr)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
req.Header.Set(xForwardedFor, clientIP)
|
req.Header.Set(xForwardedFor, clientIP)
|
||||||
|
@ -35,10 +33,18 @@ var SetXForwarded = &Middleware{
|
||||||
}
|
}
|
||||||
|
|
||||||
var HideXForwarded = &Middleware{
|
var HideXForwarded = &Middleware{
|
||||||
before: Rewrite(func(req *Request) {
|
before: Rewrite(delXForwarded),
|
||||||
req.Header.Del("Forwarded")
|
}
|
||||||
req.Header.Del(xForwardedFor)
|
|
||||||
req.Header.Del(xForwardedHost)
|
func delXForwarded(req *Request) {
|
||||||
req.Header.Del(xForwardedProto)
|
req.Header.Del("Forwarded")
|
||||||
}),
|
toRemove := make([]string, 0)
|
||||||
|
for k := range req.Header {
|
||||||
|
if strings.HasPrefix(k, "X-Forwarded-") {
|
||||||
|
toRemove = append(toRemove, k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, k := range toRemove {
|
||||||
|
req.Header.Del(k)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -174,16 +174,16 @@ func (mon *monitor) checkUpdateHealth() error {
|
||||||
logger.Debug().Msg(detail)
|
logger.Debug().Msg(detail)
|
||||||
notif.Notify(mon.service, "server is down")
|
notif.Notify(mon.service, "server is down")
|
||||||
}
|
}
|
||||||
if common.PrometheusEnabled {
|
}
|
||||||
go func() {
|
if common.PrometheusEnabled {
|
||||||
m := metrics.GetRouteMetrics()
|
go func() {
|
||||||
var up float64
|
m := metrics.GetRouteMetrics()
|
||||||
if healthy {
|
var up float64
|
||||||
up = 1
|
if healthy {
|
||||||
}
|
up = 1
|
||||||
m.HealthStatus.With(metrics.HealthMetricLabels(mon.service)).Set(up)
|
}
|
||||||
}()
|
m.HealthStatus.With(metrics.HealthMetricLabels(mon.service)).Set(up)
|
||||||
}
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
Loading…
Add table
Reference in a new issue