Loops and HTTP control server rework (#308)

- CRUD REST HTTP server
- `/v1` HTTP server prefix
- Retrocompatible with older routes (redirects to v1 or handles the requests directly)
- DNS, Updater and Openvpn refactored to have a REST-like state with new methods to change their states synchronously
- Openvpn, Unbound and Updater status, see #287
This commit is contained in:
Quentin McGaw
2020-12-19 20:10:34 -05:00
committed by GitHub
parent d60d629105
commit 4257581f55
30 changed files with 1191 additions and 438 deletions

View File

@@ -1,8 +1,8 @@
package server
import (
"fmt"
"net/http"
"strings"
"github.com/qdm12/gluetun/internal/dns"
"github.com/qdm12/gluetun/internal/models"
@@ -17,54 +17,33 @@ func newHandler(logger logging.Logger, logging bool,
unboundLooper dns.Looper,
updaterLooper updater.Looper,
) http.Handler {
return &handler{
logger: logger,
logging: logging,
buildInfo: buildInfo,
openvpnLooper: openvpnLooper,
unboundLooper: unboundLooper,
updaterLooper: updaterLooper,
}
handler := &handler{}
openvpn := newOpenvpnHandler(openvpnLooper, logger)
dns := newDNSHandler(unboundLooper, logger)
updater := newUpdaterHandler(updaterLooper, logger)
handler.v0 = newHandlerV0(logger, openvpnLooper, unboundLooper, updaterLooper)
handler.v1 = newHandlerV1(logger, buildInfo, openvpn, dns, updater)
handlerWithLog := withLogMiddleware(handler, logger, logging)
handler.setLogEnabled = handlerWithLog.setEnabled
return handlerWithLog
}
type handler struct {
logger logging.Logger
logging bool
buildInfo models.BuildInformation
openvpnLooper openvpn.Looper
unboundLooper dns.Looper
updaterLooper updater.Looper
v0 http.Handler
v1 http.Handler
setLogEnabled func(enabled bool)
}
func (h *handler) ServeHTTP(responseWriter http.ResponseWriter, request *http.Request) {
if h.logging {
h.logger.Info("HTTP %s %s", request.Method, request.RequestURI)
}
switch request.Method {
case http.MethodGet:
switch request.RequestURI {
case "/version":
h.getVersion(responseWriter)
responseWriter.WriteHeader(http.StatusOK)
case "/openvpn/actions/restart":
h.openvpnLooper.Restart()
responseWriter.WriteHeader(http.StatusOK)
case "/unbound/actions/restart":
h.unboundLooper.Restart()
responseWriter.WriteHeader(http.StatusOK)
case "/openvpn/portforwarded":
h.getPortForwarded(responseWriter)
case "/openvpn/settings":
h.getOpenvpnSettings(responseWriter)
case "/updater/restart":
h.updaterLooper.Restart()
responseWriter.WriteHeader(http.StatusOK)
default:
errString := fmt.Sprintf("Nothing here for %s %s", request.Method, request.RequestURI)
http.Error(responseWriter, errString, http.StatusBadRequest)
}
default:
errString := fmt.Sprintf("Nothing here for %s %s", request.Method, request.RequestURI)
http.Error(responseWriter, errString, http.StatusBadRequest)
func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
r.RequestURI = strings.TrimSuffix(r.RequestURI, "/")
if !strings.HasPrefix(r.RequestURI, "/v1/") && r.RequestURI != "/v1" {
h.v0.ServeHTTP(w, r)
return
}
r.RequestURI = strings.TrimPrefix(r.RequestURI, "/v1")
h.v1.ServeHTTP(w, r)
}