Skip to content

Commit

Permalink
NOISSUE - Forward /health and /metrics endpoints (absmach#63)
Browse files Browse the repository at this point in the history
* fix(mproxy): Rename PathPrefix field and CleanPathPrefix function

Updates configuration and HTTP handling in the mproxy package by renaming PathPrefix field and a CleanPathPrefix function.

Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>

* chore(mproxy): update dependencies

Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>

* feat(http): add direct serving of metrics and health endpoints

Adds a feature to serve metrics and health endpoints directly without proxying. This ensures that metrics and health checks are handled efficiently.

Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>

* docs(mproxy): update readme

Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>

* fix(linter): remove redundant linter settings

`WARN [linters_context] gocritic: no need to enable check "captLocal": it's already enabled` This applies to the removed linters

Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>

* fix(mproxy): use `HasPrefix` rather than full match for pathPrefix

Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>

---------

Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>
  • Loading branch information
rodneyosodo authored Apr 30, 2024
1 parent b69aa82 commit 27dad4c
Show file tree
Hide file tree
Showing 13 changed files with 133 additions and 145 deletions.
8 changes: 4 additions & 4 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ MPROXY_MQTT_WS_WITH_TLS_KEY_FILE=ssl/certs/server.key
MPROXY_MQTT_WS_WITH_TLS_SERVER_CA_FILE=ssl/certs/ca.crt

MPROXY_MQTT_WS_WITH_MTLS_ADDRESS=:8085
MPROXY_MQTT_WS_WITH_MTLS_PREFIX_PATH=/mqtt
MPROXY_MQTT_WS_WITH_MTLS_PATH_PREFIX=/mqtt
MPROXY_MQTT_WS_WITH_MTLS_TARGET=ws://localhost:8000/
MPROXY_MQTT_WS_WITH_MTLS_CERT_FILE=ssl/certs/server.crt
MPROXY_MQTT_WS_WITH_MTLS_KEY_FILE=ssl/certs/server.key
Expand All @@ -36,18 +36,18 @@ MPROXY_MQTT_WS_WITH_MTLS_CERT_VERIFICATION_METHODS=ocsp
MPROXY_MQTT_WS_WITH_MTLS_OCSP_RESPONDER_URL=http://localhost:8080/ocsp

MPROXY_HTTP_WITHOUT_TLS_ADDRESS=:8086
MPROXY_HTTP_WITHOUT_TLS_PREFIX_PATH=/messages
MPROXY_HTTP_WITHOUT_TLS_PATH_PREFIX=/messages
MPROXY_HTTP_WITHOUT_TLS_TARGET=http://localhost:8888/

MPROXY_HTTP_WITH_TLS_ADDRESS=:8087
MPROXY_HTTP_WITH_TLS_PREFIX_PATH=/messages
MPROXY_HTTP_WITH_TLS_PATH_PREFIX=/messages
MPROXY_HTTP_WITH_TLS_TARGET=http://localhost:8888/
MPROXY_HTTP_WITH_TLS_CERT_FILE=ssl/certs/server.crt
MPROXY_HTTP_WITH_TLS_KEY_FILE=ssl/certs/server.key
MPROXY_HTTP_WITH_TLS_SERVER_CA_FILE=ssl/certs/ca.crt

MPROXY_HTTP_WITH_MTLS_ADDRESS=:8088
MPROXY_HTTP_WITH_MTLS_PREFIX_PATH=/messages
MPROXY_HTTP_WITH_MTLS_PATH_PREFIX=/messages
MPROXY_HTTP_WITH_MTLS_TARGET=http://localhost:8888/
MPROXY_HTTP_WITH_MTLS_CERT_FILE=ssl/certs/server.crt
MPROXY_HTTP_WITH_MTLS_KEY_FILE=ssl/certs/server.key
Expand Down
3 changes: 0 additions & 3 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ linters-settings:
no-extra-aliases: false
gocritic:
enabled-checks:
- captLocal
- singleCaseSwitch
- switchTrue
- importShadow
- httpNoBody
- paramTypeCombine
Expand Down
164 changes: 78 additions & 86 deletions README.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (
"github.com/absmach/mproxy/pkg/mqtt"
"github.com/absmach/mproxy/pkg/mqtt/websocket"
"github.com/absmach/mproxy/pkg/session"
"github.com/caarlos0/env/v10"
"github.com/caarlos0/env/v11"
"github.com/joho/godotenv"
"golang.org/x/sync/errgroup"
)
Expand Down
8 changes: 4 additions & 4 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import (
"crypto/tls"

mptls "github.com/absmach/mproxy/pkg/tls"
"github.com/caarlos0/env/v10"
"github.com/caarlos0/env/v11"
)

type Config struct {
Address string `env:"ADDRESS" envDefault:""`
PrefixPath string `env:"PREFIX_PATH" envDefault:""`
Target string `env:"TARGET" envDefault:""`
Address string `env:"ADDRESS" envDefault:""`
PathPrefix string `env:"PATH_PREFIX" envDefault:""`
Target string `env:"TARGET" envDefault:""`
TLSConfig *tls.Config
}

Expand Down
10 changes: 5 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ go 1.21
toolchain go1.21.4

require (
github.com/caarlos0/env/v10 v10.0.0
github.com/caarlos0/env/v11 v11.0.0
github.com/eclipse/paho.mqtt.golang v1.4.3
github.com/google/uuid v1.5.0
github.com/google/uuid v1.6.0
github.com/gorilla/websocket v1.5.1
github.com/joho/godotenv v1.5.1
golang.org/x/crypto v0.21.0
golang.org/x/sync v0.6.0
golang.org/x/crypto v0.22.0
golang.org/x/sync v0.7.0
)

require golang.org/x/net v0.23.0 // indirect
require golang.org/x/net v0.24.0 // indirect
12 changes: 10 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
github.com/caarlos0/env/v10 v10.0.0 h1:yIHUBZGsyqCnpTkbjk8asUlx6RFhhEs+h7TOBdgdzXA=
github.com/caarlos0/env/v10 v10.0.0/go.mod h1:ZfulV76NvVPw3tm591U4SwL3Xx9ldzBP9aGxzeN7G18=
github.com/caarlos0/env/v11 v11.0.0 h1:ZIlkOjuL3xoZS0kmUJlF74j2Qj8GMOq3CDLX/Viak8Q=
github.com/caarlos0/env/v11 v11.0.0/go.mod h1:2RC3HQu8BQqtEK3V4iHPxj0jOdWdbPpWJ6pOueeU1xM=
github.com/eclipse/paho.mqtt.golang v1.4.3 h1:2kwcUGn8seMUfWndX0hGbvH8r7crgcJguQNCyp70xik=
github.com/eclipse/paho.mqtt.golang v1.4.3/go.mod h1:CSYvoAlsMkhYOXh/oKyxa8EcBci6dVkLCbo5tTC1RIE=
github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU=
github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
24 changes: 11 additions & 13 deletions pkg/http/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,13 @@ const contentType = "application/json"
var ErrMissingAuthentication = errors.New("missing authorization")

func (p Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != p.config.PrefixPath {
// Metrics and health endpoints are served directly.
if r.URL.Path == "/metrics" || r.URL.Path == "/health" {
p.target.ServeHTTP(w, r)
return
}

if !strings.HasPrefix(r.URL.Path, p.config.PathPrefix) {
http.NotFound(w, r)
return
}
Expand Down Expand Up @@ -96,14 +102,6 @@ type Proxy struct {
}

func NewProxy(config mproxy.Config, handler session.Handler, logger *slog.Logger) (Proxy, error) {
config.PrefixPath = strings.TrimSpace(config.PrefixPath)
switch {
case config.PrefixPath != "" && config.PrefixPath[0] != '/':
config.PrefixPath = "/" + config.PrefixPath
case config.PrefixPath == "":
config.PrefixPath = "/"
}

target, err := url.Parse(config.Target)
if err != nil {
return Proxy{}, err
Expand All @@ -128,13 +126,13 @@ func (p Proxy) Listen(ctx context.Context) error {
}
status := mptls.SecurityStatus(p.config.TLSConfig)

p.logger.Info(fmt.Sprintf("HTTP proxy server started at %s%s with %s", p.config.Address, p.config.PrefixPath, status))
p.logger.Info(fmt.Sprintf("HTTP proxy server started at %s%s with %s", p.config.Address, p.config.PathPrefix, status))

var server http.Server
g, ctx := errgroup.WithContext(ctx)

mux := http.NewServeMux()
mux.Handle(p.config.PrefixPath, p)
mux.Handle(p.config.PathPrefix, p)
server.Handler = mux

g.Go(func() error {
Expand All @@ -146,9 +144,9 @@ func (p Proxy) Listen(ctx context.Context) error {
return server.Close()
})
if err := g.Wait(); err != nil {
p.logger.Info(fmt.Sprintf("HTTP proxy server at %s%s with %s exiting with errors", p.config.Address, p.config.PrefixPath, status), slog.String("error", err.Error()))
p.logger.Info(fmt.Sprintf("HTTP proxy server at %s%s with %s exiting with errors", p.config.Address, p.config.PathPrefix, status), slog.String("error", err.Error()))
} else {
p.logger.Info(fmt.Sprintf("HTTP proxy server at %s%s with %s exiting...", p.config.Address, p.config.PrefixPath, status))
p.logger.Info(fmt.Sprintf("HTTP proxy server at %s%s with %s exiting...", p.config.Address, p.config.PathPrefix, status))
}
return nil
}
17 changes: 5 additions & 12 deletions pkg/mqtt/websocket/websocket.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,6 @@ type Proxy struct {

// New - creates new WS proxy.
func New(config mproxy.Config, handler session.Handler, interceptor session.Interceptor, logger *slog.Logger) *Proxy {
config.PrefixPath = strings.TrimSpace(config.PrefixPath)
switch {
case config.PrefixPath != "" && config.PrefixPath[0] != '/':
config.PrefixPath = "/" + config.PrefixPath
case config.PrefixPath == "":
config.PrefixPath = "/"
}
return &Proxy{
config: config,
handler: handler,
Expand All @@ -57,7 +50,7 @@ var upgrader = websocket.Upgrader{
}

func (p Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != p.config.PrefixPath {
if !strings.HasPrefix(r.URL.Path, p.config.PathPrefix) {
http.NotFound(w, r)
return
}
Expand Down Expand Up @@ -118,24 +111,24 @@ func (p Proxy) Listen(ctx context.Context) error {
g, ctx := errgroup.WithContext(ctx)

mux := http.NewServeMux()
mux.Handle(p.config.PrefixPath, p)
mux.Handle(p.config.PathPrefix, p)
server.Handler = mux

g.Go(func() error {
return server.Serve(l)
})
status := mptls.SecurityStatus(p.config.TLSConfig)

p.logger.Info(fmt.Sprintf("MQTT websocket proxy server started at %s%s with %s", p.config.Address, p.config.PrefixPath, status))
p.logger.Info(fmt.Sprintf("MQTT websocket proxy server started at %s%s with %s", p.config.Address, p.config.PathPrefix, status))

g.Go(func() error {
<-ctx.Done()
return server.Close()
})
if err := g.Wait(); err != nil {
p.logger.Info(fmt.Sprintf("MQTT websocket proxy server at %s%s with %s exiting with errors", p.config.Address, p.config.PrefixPath, status), slog.String("error", err.Error()))
p.logger.Info(fmt.Sprintf("MQTT websocket proxy server at %s%s with %s exiting with errors", p.config.Address, p.config.PathPrefix, status), slog.String("error", err.Error()))
} else {
p.logger.Info(fmt.Sprintf("MQTT websocket proxy server at %s%s with %s exiting...", p.config.Address, p.config.PrefixPath, status))
p.logger.Info(fmt.Sprintf("MQTT websocket proxy server at %s%s with %s exiting...", p.config.Address, p.config.PathPrefix, status))
}
return nil
}
10 changes: 5 additions & 5 deletions pkg/tls/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ package tls

import (
"github.com/absmach/mproxy/pkg/tls/verifier"
"github.com/caarlos0/env/v10"
"github.com/caarlos0/env/v11"
)

type Config struct {
CertFile string `env:"CERT_FILE" envDefault:""`
KeyFile string `env:"KEY_FILE" envDefault:""`
ServerCAFile string `env:"SERVER_CA_FILE" envDefault:""`
ClientCAFile string `env:"CLIENT_CA_FILE" envDefault:""`
CertFile string `env:"CERT_FILE" envDefault:""`
KeyFile string `env:"KEY_FILE" envDefault:""`
ServerCAFile string `env:"SERVER_CA_FILE" envDefault:""`
ClientCAFile string `env:"CLIENT_CA_FILE" envDefault:""`
Validator verifier.Validator
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/tls/verifications.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"github.com/absmach/mproxy/pkg/tls/verifier"
"github.com/absmach/mproxy/pkg/tls/verifier/crl"
"github.com/absmach/mproxy/pkg/tls/verifier/ocsp"
"github.com/caarlos0/env/v10"
"github.com/caarlos0/env/v11"
)

// ErrInvalidCertVerification represents an error during the cert verification
Expand Down
12 changes: 6 additions & 6 deletions pkg/tls/verifier/crl/crl.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
"time"

"github.com/absmach/mproxy/pkg/tls/verifier"
"github.com/caarlos0/env/v10"
"github.com/caarlos0/env/v11"
)

var (
Expand All @@ -40,11 +40,11 @@ var (
)

type config struct {
CRLDepth uint `env:"CRL_DEPTH" envDefault:"1"`
OfflineCRLFile string `env:"OFFLINE_CRL_FILE" envDefault:""`
OfflineCRLIssuerCertFile string `env:"OFFLINE_CRL_ISSUER_CERT_FILE" envDefault:""`
CRLDistributionPoints url.URL `env:"CRL_DISTRIBUTION_POINTS" envDefault:""`
CRLDistributionPointsIssuerCertFile string `env:"CRL_DISTRIBUTION_POINTS_ISSUER_CERT_FILE " envDefault:""`
CRLDepth uint `env:"CRL_DEPTH" envDefault:"1"`
OfflineCRLFile string `env:"OFFLINE_CRL_FILE" envDefault:""`
OfflineCRLIssuerCertFile string `env:"OFFLINE_CRL_ISSUER_CERT_FILE" envDefault:""`
CRLDistributionPoints url.URL `env:"CRL_DISTRIBUTION_POINTS" envDefault:""`
CRLDistributionPointsIssuerCertFile string `env:"CRL_DISTRIBUTION_POINTS_ISSUER_CERT_FILE" envDefault:""`
}

var _ verifier.Verifier = (*config)(nil)
Expand Down
6 changes: 3 additions & 3 deletions pkg/tls/verifier/ocsp/ocsp.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
"net/url"

"github.com/absmach/mproxy/pkg/tls/verifier"
"github.com/caarlos0/env/v10"
"github.com/caarlos0/env/v11"
"golang.org/x/crypto/ocsp"
)

Expand All @@ -42,8 +42,8 @@ var (
)

type config struct {
OCSPDepth uint `env:"OCSP_DEPTH" envDefault:"0"`
OCSPResponderURL url.URL `env:"OCSP_RESPONDER_URL" envDefault:""`
OCSPDepth uint `env:"OCSP_DEPTH" envDefault:"0"`
OCSPResponderURL url.URL `env:"OCSP_RESPONDER_URL" envDefault:""`
}

var _ verifier.Verifier = (*config)(nil)
Expand Down

0 comments on commit 27dad4c

Please sign in to comment.