Allow toggling HTTP interaction recording via CLI, environment, and Web UI

This commit is contained in:
Tobias Gesellchen
2026-02-14 12:39:39 +01:00
parent 133c07fefa
commit 9be1c7d588
9 changed files with 71 additions and 44 deletions
+1
View File
@@ -35,6 +35,7 @@ func (s *Server) HandleProxyRequest(w http.ResponseWriter, r *http.Request) {
lp := proxy.NewLoggingProxy(target.String(), s.proxyRedact)
lp.LogBody = s.proxyLogBody
lp.RecordEnabled = s.recordEnabled
lp.SetRecorder(s.recorder)
proxy := httputil.NewSingleHostReverseProxy(target)
+3
View File
@@ -351,6 +351,7 @@ func (s *Server) HandleGetProxySettings(w http.ResponseWriter, _ *http.Request)
if err := json.NewEncoder(w).Encode(map[string]bool{
"redact": s.proxyRedact,
"log_body": s.proxyLogBody,
"record": s.recordEnabled,
}); err != nil {
http.Error(w, "Failed to encode response", http.StatusInternalServerError)
return
@@ -377,6 +378,7 @@ func (s *Server) HandleUpdateProxySettings(w http.ResponseWriter, r *http.Reques
var settings struct {
Redact bool `json:"redact"`
LogBody bool `json:"log_body"`
Record bool `json:"record"`
}
if err := json.NewDecoder(r.Body).Decode(&settings); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
@@ -385,6 +387,7 @@ func (s *Server) HandleUpdateProxySettings(w http.ResponseWriter, r *http.Reques
s.proxyRedact = settings.Redact
s.proxyLogBody = settings.LogBody
s.recordEnabled = settings.Record
w.Header().Set("Content-Type", "application/json")
+1 -1
View File
@@ -12,7 +12,7 @@ import (
// RecordMiddleware returns a middleware that records "self" requests and responses.
func (s *Server) RecordMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if s.recorder == nil {
if s.recorder == nil || !s.recordEnabled {
next.ServeHTTP(w, r)
return
}
+22 -15
View File
@@ -14,25 +14,27 @@ import (
// Server handles HTTP requests for the SoundTouch service.
type Server struct {
ds *datastore.DataStore
sm *setup.Manager
serverURL string
proxyURL string
discovering bool
proxyRedact bool
proxyLogBody bool
recorder *proxy.Recorder
ds *datastore.DataStore
sm *setup.Manager
serverURL string
proxyURL string
discovering bool
proxyRedact bool
proxyLogBody bool
recordEnabled bool
recorder *proxy.Recorder
}
// NewServer creates a new SoundTouch service server.
func NewServer(ds *datastore.DataStore, sm *setup.Manager, serverURL string, proxyRedact, proxyLogBody bool) *Server {
func NewServer(ds *datastore.DataStore, sm *setup.Manager, serverURL string, proxyRedact, proxyLogBody, recordEnabled bool) *Server {
return &Server{
ds: ds,
sm: sm,
serverURL: serverURL,
proxyURL: serverURL,
proxyRedact: proxyRedact,
proxyLogBody: proxyLogBody,
ds: ds,
sm: sm,
serverURL: serverURL,
proxyURL: serverURL,
proxyRedact: proxyRedact,
proxyLogBody: proxyLogBody,
recordEnabled: recordEnabled,
}
}
@@ -41,6 +43,11 @@ func (s *Server) SetRecorder(r *proxy.Recorder) {
s.recorder = r
}
// GetRecordEnabled returns whether recording is enabled.
func (s *Server) GetRecordEnabled() bool {
return s.recordEnabled
}
// DiscoverDevices starts a background device discovery process.
//
//nolint:contextcheck
+1
View File
@@ -194,6 +194,7 @@
Proxy Logging:
<label><input type="checkbox" id="proxy-redact" onchange="updateProxySettings()"> Redact Sensitive Headers</label>
<label style="margin-left: 15px;"><input type="checkbox" id="proxy-log-body" onchange="updateProxySettings()"> Log Bodies</label>
<label style="margin-left: 15px;"><input type="checkbox" id="proxy-record" onchange="updateProxySettings()"> Record Interactions</label>
</div>
</div>
</div>
+10 -8
View File
@@ -20,6 +20,7 @@ async function fetchProxySettings() {
const settings = await response.json();
document.getElementById('proxy-redact').checked = settings.redact;
document.getElementById('proxy-log-body').checked = settings.log_body;
document.getElementById('proxy-record').checked = settings.record;
} catch (error) {
console.error('Failed to fetch proxy settings', error);
}
@@ -28,7 +29,8 @@ async function fetchProxySettings() {
async function updateProxySettings() {
const settings = {
redact: document.getElementById('proxy-redact').checked,
log_body: document.getElementById('proxy-log-body').checked
log_body: document.getElementById('proxy-log-body').checked,
record: document.getElementById('proxy-record').checked
};
try {
await fetch('/setup/proxy-settings', {
@@ -127,7 +129,7 @@ function openTab(evt, tabId) {
if (content) {
content.className += " active";
}
if (evt) {
evt.currentTarget.className += " active";
} else {
@@ -251,13 +253,13 @@ async function updateDeviceInfo(ip) {
if (row) {
const nameEl = row.querySelector('.col-name');
if (nameEl && info.name) nameEl.innerText = info.name;
const modelEl = row.querySelector('.col-model');
if (modelEl && info.type) modelEl.innerText = info.type;
const serialEl = row.querySelector('.col-serial');
if (serialEl && info.serialNumber) serialEl.innerText = info.serialNumber;
const firmwareEl = row.querySelector('.col-firmware');
if (firmwareEl && info.softwareVersion) firmwareEl.innerText = info.softwareVersion;
}
@@ -308,13 +310,13 @@ async function showSummary(ip) {
if (row) {
const nameEl = row.querySelector('.col-name');
if (nameEl && summary.device_name) nameEl.innerText = summary.device_name;
const modelEl = row.querySelector('.col-model');
if (modelEl && summary.device_model) modelEl.innerText = summary.device_model;
const serialEl = row.querySelector('.col-serial');
if (serialEl && summary.device_serial) serialEl.innerText = summary.device_serial;
const firmwareEl = row.querySelector('.col-firmware');
if (firmwareEl && summary.firmware_version) firmwareEl.innerText = summary.firmware_version;
}
+7 -6
View File
@@ -20,11 +20,12 @@ var sensitiveHeaders = []string{
// LoggingProxy wraps a ReverseProxy to provide instrumentation.
type LoggingProxy struct {
Proxy *httputil.ReverseProxy
Redact bool
LogBody bool
MaxBodySize int64
Recorder *Recorder
Proxy *httputil.ReverseProxy
Redact bool
LogBody bool
RecordEnabled bool
MaxBodySize int64
Recorder *Recorder
}
// NewLoggingProxy creates a lightweight logger for HTTP requests/responses.
@@ -89,7 +90,7 @@ func (lp *LoggingProxy) LogResponse(r *http.Response) {
log.Printf("[PROXY_RES] %d %s\n Headers:\n%s\n Body: %s", r.StatusCode, r.Request.URL.String(), headers, bodyStr)
if lp.Recorder != nil {
if lp.Recorder != nil && lp.RecordEnabled {
_ = lp.Recorder.Record("upstream", r.Request, r)
}
}