diff --git a/internal/server/handler.go b/internal/server/handler.go index 92cdf7b9..b276940f 100644 --- a/internal/server/handler.go +++ b/internal/server/handler.go @@ -25,13 +25,14 @@ func newHandler(ctx context.Context, logger Logger, logging bool, handler := &handler{} vpn := newVPNHandler(ctx, vpnLooper, storage, ipv6Supported, logger) - openvpn := newOpenvpnHandler(ctx, vpnLooper, pfGetter, logger) + openvpn := newOpenvpnHandler(ctx, vpnLooper, logger) dns := newDNSHandler(ctx, dnsLooper, logger) updater := newUpdaterHandler(ctx, updaterLooper, logger) publicip := newPublicIPHandler(publicIPLooper, logger) + portForward := newPortForwardHandler(ctx, pfGetter, logger) handler.v0 = newHandlerV0(ctx, logger, vpnLooper, dnsLooper, updaterLooper) - handler.v1 = newHandlerV1(logger, buildInfo, vpn, openvpn, dns, updater, publicip) + handler.v1 = newHandlerV1(logger, buildInfo, vpn, openvpn, dns, updater, publicip, portForward) authMiddleware, err := auth.New(authSettings, logger) if err != nil { diff --git a/internal/server/handlerv0.go b/internal/server/handlerv0.go index 422cf558..af3773af 100644 --- a/internal/server/handlerv0.go +++ b/internal/server/handlerv0.go @@ -52,7 +52,7 @@ func (h *handlerV0) ServeHTTP(w http.ResponseWriter, r *http.Request) { h.logger.Warn(err.Error()) } case "/openvpn/portforwarded": - http.Redirect(w, r, "/v1/openvpn/portforwarded", http.StatusPermanentRedirect) + http.Redirect(w, r, "/v1/portforward", http.StatusPermanentRedirect) case "/openvpn/settings": http.Redirect(w, r, "/v1/openvpn/settings", http.StatusPermanentRedirect) case "/updater/restart": diff --git a/internal/server/handlerv1.go b/internal/server/handlerv1.go index c97e0cfb..32a2fde1 100644 --- a/internal/server/handlerv1.go +++ b/internal/server/handlerv1.go @@ -10,27 +10,29 @@ import ( ) func newHandlerV1(w warner, buildInfo models.BuildInformation, - vpn, openvpn, dns, updater, publicip http.Handler, + vpn, openvpn, dns, updater, publicip, portForward http.Handler, ) http.Handler { return &handlerV1{ - warner: w, - buildInfo: buildInfo, - vpn: vpn, - openvpn: openvpn, - dns: dns, - updater: updater, - publicip: publicip, + warner: w, + buildInfo: buildInfo, + vpn: vpn, + openvpn: openvpn, + dns: dns, + updater: updater, + publicip: publicip, + portForward: portForward, } } type handlerV1 struct { - warner warner - buildInfo models.BuildInformation - vpn http.Handler - openvpn http.Handler - dns http.Handler - updater http.Handler - publicip http.Handler + warner warner + buildInfo models.BuildInformation + vpn http.Handler + openvpn http.Handler + dns http.Handler + updater http.Handler + publicip http.Handler + portForward http.Handler } func (h *handlerV1) ServeHTTP(w http.ResponseWriter, r *http.Request) { @@ -47,6 +49,8 @@ func (h *handlerV1) ServeHTTP(w http.ResponseWriter, r *http.Request) { h.updater.ServeHTTP(w, r) case strings.HasPrefix(r.RequestURI, "/publicip"): h.publicip.ServeHTTP(w, r) + case strings.HasPrefix(r.RequestURI, "/portforward"): + h.portForward.ServeHTTP(w, r) default: errString := fmt.Sprintf("%s %s not found", r.Method, r.RequestURI) http.Error(w, errString, http.StatusBadRequest) diff --git a/internal/server/middlewares/auth/middleware.go b/internal/server/middlewares/auth/middleware.go index 3478ccdb..39e79d6a 100644 --- a/internal/server/middlewares/auth/middleware.go +++ b/internal/server/middlewares/auth/middleware.go @@ -37,6 +37,7 @@ func New(settings Settings, debugLogger DebugLogger) ( http.MethodGet + " /v1/updater/status": {}, http.MethodPut + " /v1/updater/status": {}, http.MethodGet + " /v1/publicip/ip": {}, + http.MethodGet + " /v1/portforward": {}, }, logger: debugLogger, } diff --git a/internal/server/middlewares/auth/settings.go b/internal/server/middlewares/auth/settings.go index 60edbe89..b9630b2e 100644 --- a/internal/server/middlewares/auth/settings.go +++ b/internal/server/middlewares/auth/settings.go @@ -35,6 +35,7 @@ func (s *Settings) SetDefaults() { http.MethodGet + " /v1/updater/status", http.MethodPut + " /v1/updater/status", http.MethodGet + " /v1/publicip/ip", + http.MethodGet + " /v1/portforward", }, }}) } @@ -131,4 +132,5 @@ var validRoutes = map[string]struct{}{ //nolint:gochecknoglobals http.MethodGet + " /v1/updater/status": {}, http.MethodPut + " /v1/updater/status": {}, http.MethodGet + " /v1/publicip/ip": {}, + http.MethodGet + " /v1/portforward": {}, } diff --git a/internal/server/openvpn.go b/internal/server/openvpn.go index 3e25c5fe..66a9a620 100644 --- a/internal/server/openvpn.go +++ b/internal/server/openvpn.go @@ -10,13 +10,10 @@ import ( "github.com/qdm12/gluetun/internal/constants/vpn" ) -func newOpenvpnHandler(ctx context.Context, looper VPNLooper, - pfGetter PortForwardedGetter, w warner, -) http.Handler { +func newOpenvpnHandler(ctx context.Context, looper VPNLooper, w warner) http.Handler { return &openvpnHandler{ ctx: ctx, looper: looper, - pf: pfGetter, warner: w, } } @@ -24,7 +21,6 @@ func newOpenvpnHandler(ctx context.Context, looper VPNLooper, type openvpnHandler struct { ctx context.Context //nolint:containedctx looper VPNLooper - pf PortForwardedGetter warner warner } @@ -47,10 +43,10 @@ func (h *openvpnHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { default: errMethodNotSupported(w, r.Method) } - case "/portforwarded": + case "/portforwarded": // TODO v4 remove switch r.Method { case http.MethodGet: - h.getPortForwarded(w) + http.Redirect(w, r, "/v1/portforward", http.StatusMovedPermanently) default: errMethodNotSupported(w, r.Method) } @@ -122,23 +118,3 @@ func (h *openvpnHandler) getSettings(w http.ResponseWriter) { return } } - -func (h *openvpnHandler) getPortForwarded(w http.ResponseWriter) { - ports := h.pf.GetPortsForwarded() - encoder := json.NewEncoder(w) - var data any - switch len(ports) { - case 0: - data = portWrapper{Port: 0} // TODO v4 change to portsWrapper - case 1: - data = portWrapper{Port: ports[0]} // TODO v4 change to portsWrapper - default: - data = portsWrapper{Ports: ports} - } - - err := encoder.Encode(data) - if err != nil { - h.warner.Warn(err.Error()) - w.WriteHeader(http.StatusInternalServerError) - } -} diff --git a/internal/server/portforward.go b/internal/server/portforward.go new file mode 100644 index 00000000..b751efa0 --- /dev/null +++ b/internal/server/portforward.go @@ -0,0 +1,52 @@ +package server + +import ( + "context" + "encoding/json" + "net/http" +) + +func newPortForwardHandler(ctx context.Context, + portForward PortForwardedGetter, warner warner, +) http.Handler { + return &portForwardHandler{ + ctx: ctx, + portForward: portForward, + warner: warner, + } +} + +type portForwardHandler struct { + ctx context.Context //nolint:containedctx + portForward PortForwardedGetter + warner warner +} + +func (h *portForwardHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + switch r.Method { + case http.MethodGet: + h.getPortForwarded(w) + default: + errMethodNotSupported(w, r.Method) + } +} + +func (h *portForwardHandler) getPortForwarded(w http.ResponseWriter) { + ports := h.portForward.GetPortsForwarded() + encoder := json.NewEncoder(w) + var data any + switch len(ports) { + case 0: + data = portWrapper{Port: 0} // TODO v4 change to portsWrapper + case 1: + data = portWrapper{Port: ports[0]} // TODO v4 change to portsWrapper + default: + data = portsWrapper{Ports: ports} + } + + err := encoder.Encode(data) + if err != nil { + h.warner.Warn(err.Error()) + w.WriteHeader(http.StatusInternalServerError) + } +}