mirror of
https://github.com/gesellix/Bose-SoundTouch.git
synced 2026-08-24 14:47:23 +00:00
fix: golangci-lint issues
This commit is contained in:
+110
-80
@@ -4,6 +4,7 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
@@ -23,13 +24,54 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
config := loadConfig()
|
||||
ds := initDataStore(config.dataDir)
|
||||
cm := initCertificateManager(config.dataDir)
|
||||
sm := setup.NewManager(config.serverURL, ds, cm)
|
||||
server := handlers.NewServer(ds, sm, config.serverURL, config.redact, config.logBody)
|
||||
|
||||
tlsConfig, err := cm.GetServerTLSConfig(config.domains)
|
||||
if err != nil {
|
||||
log.Printf("Warning: Failed to setup TLS: %v", err)
|
||||
}
|
||||
|
||||
pyProxy := setupPythonProxy(config.targetURL, config.redact, config.logBody)
|
||||
|
||||
startDeviceDiscovery(server)
|
||||
|
||||
r := setupRouter(server, pyProxy)
|
||||
|
||||
log.Printf("Go service starting on %s, proxying to %s", config.serverURL, config.targetURL)
|
||||
|
||||
if tlsConfig != nil {
|
||||
startHTTPSServer(config.httpsAddr, r, tlsConfig, config.httpsServerURL)
|
||||
}
|
||||
|
||||
log.Fatal(http.ListenAndServe(config.addr, r))
|
||||
}
|
||||
|
||||
type serviceConfig struct {
|
||||
port string
|
||||
bindAddr string
|
||||
addr string
|
||||
targetURL string
|
||||
dataDir string
|
||||
serverURL string
|
||||
httpsServerURL string
|
||||
httpsAddr string
|
||||
redact bool
|
||||
logBody bool
|
||||
domains []string
|
||||
}
|
||||
|
||||
func loadConfig() serviceConfig {
|
||||
port := os.Getenv("PORT")
|
||||
if port == "" {
|
||||
port = "8000"
|
||||
}
|
||||
|
||||
bindAddr := os.Getenv("BIND_ADDR")
|
||||
// If BIND_ADDR is explicitly set, use it. Otherwise, bind to all interfaces (IPv4 and IPv6).
|
||||
|
||||
addr := bindAddr + ":" + port
|
||||
if bindAddr == "" {
|
||||
addr = ":" + port
|
||||
@@ -40,24 +82,13 @@ func main() {
|
||||
targetURL = "http://localhost:8001"
|
||||
}
|
||||
|
||||
target, err := url.Parse(targetURL)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to parse target URL: %v", err)
|
||||
}
|
||||
|
||||
dataDir := os.Getenv("DATA_DIR")
|
||||
if dataDir == "" {
|
||||
dataDir = "data"
|
||||
}
|
||||
|
||||
ds := datastore.NewDataStore(dataDir)
|
||||
if err := ds.Initialize(); err != nil {
|
||||
log.Printf("Warning: Failed to initialize datastore: %v", err)
|
||||
}
|
||||
|
||||
serverURL := os.Getenv("SERVER_URL")
|
||||
if serverURL == "" {
|
||||
// Try to guess the server URL
|
||||
hostname, _ := os.Hostname()
|
||||
if hostname == "" {
|
||||
hostname = "localhost"
|
||||
@@ -66,41 +97,8 @@ func main() {
|
||||
serverURL = "http://" + strings.ToLower(hostname) + ":" + port
|
||||
}
|
||||
|
||||
httpsServerURL := os.Getenv("HTTPS_SERVER_URL")
|
||||
if httpsServerURL == "" {
|
||||
// Guess HTTPS server URL
|
||||
hostname, _ := os.Hostname()
|
||||
if hostname == "" {
|
||||
hostname = "localhost"
|
||||
}
|
||||
|
||||
// Re-fetch httpsPort as it is defined later in the code, but let's move it up or just use the logic
|
||||
guessHTTPSPort := os.Getenv("HTTPS_PORT")
|
||||
if guessHTTPSPort == "" {
|
||||
guessHTTPSPort = "8443"
|
||||
}
|
||||
|
||||
httpsServerURL = "https://" + strings.ToLower(hostname) + ":" + guessHTTPSPort
|
||||
}
|
||||
|
||||
cm := crypto.NewCertificateManager(filepath.Join(dataDir, "certs"))
|
||||
if err := cm.EnsureCA(); err != nil {
|
||||
log.Printf("Warning: Failed to ensure CA: %v", err)
|
||||
}
|
||||
|
||||
sm := setup.NewManager(serverURL, ds, cm)
|
||||
|
||||
redact := os.Getenv("REDACT_PROXY_LOGS") != "false"
|
||||
logBody := os.Getenv("LOG_PROXY_BODY") == "true"
|
||||
|
||||
server := handlers.NewServer(ds, sm, serverURL, redact, logBody)
|
||||
|
||||
// Phase 11: Setup HTTPS if CA and certificates are available
|
||||
httpsPort := os.Getenv("HTTPS_PORT")
|
||||
if httpsPort == "" {
|
||||
// We don't default to 443 because it usually requires root,
|
||||
// and we want the service to start out-of-the-box for developers.
|
||||
// However, 443 is needed for the device to connect via /etc/hosts without a port.
|
||||
httpsPort = "8443"
|
||||
}
|
||||
|
||||
@@ -109,6 +107,16 @@ func main() {
|
||||
httpsAddr = ":" + httpsPort
|
||||
}
|
||||
|
||||
httpsServerURL := os.Getenv("HTTPS_SERVER_URL")
|
||||
if httpsServerURL == "" {
|
||||
hostname, _ := os.Hostname()
|
||||
if hostname == "" {
|
||||
hostname = "localhost"
|
||||
}
|
||||
|
||||
httpsServerURL = "https://" + strings.ToLower(hostname) + ":" + httpsPort
|
||||
}
|
||||
|
||||
hostname, _ := os.Hostname()
|
||||
if hostname == "" {
|
||||
hostname = "localhost"
|
||||
@@ -128,22 +136,51 @@ func main() {
|
||||
"127.0.0.1",
|
||||
}
|
||||
|
||||
tlsConfig, err := cm.GetServerTLSConfig(domains)
|
||||
return serviceConfig{
|
||||
port: port,
|
||||
bindAddr: bindAddr,
|
||||
addr: addr,
|
||||
targetURL: targetURL,
|
||||
dataDir: dataDir,
|
||||
serverURL: serverURL,
|
||||
httpsServerURL: httpsServerURL,
|
||||
httpsAddr: httpsAddr,
|
||||
redact: os.Getenv("REDACT_PROXY_LOGS") != "false",
|
||||
logBody: os.Getenv("LOG_PROXY_BODY") == "true",
|
||||
domains: domains,
|
||||
}
|
||||
}
|
||||
|
||||
func initDataStore(dataDir string) *datastore.DataStore {
|
||||
ds := datastore.NewDataStore(dataDir)
|
||||
if err := ds.Initialize(); err != nil {
|
||||
log.Printf("Warning: Failed to initialize datastore: %v", err)
|
||||
}
|
||||
|
||||
return ds
|
||||
}
|
||||
|
||||
func initCertificateManager(dataDir string) *crypto.CertificateManager {
|
||||
cm := crypto.NewCertificateManager(filepath.Join(dataDir, "certs"))
|
||||
if err := cm.EnsureCA(); err != nil {
|
||||
log.Printf("Warning: Failed to ensure CA: %v", err)
|
||||
}
|
||||
|
||||
return cm
|
||||
}
|
||||
|
||||
func setupPythonProxy(targetURL string, redact, logBody bool) *httputil.ReverseProxy {
|
||||
target, err := url.Parse(targetURL)
|
||||
if err != nil {
|
||||
log.Printf("Warning: Failed to setup TLS: %v", err)
|
||||
log.Fatalf("Failed to parse target URL: %v", err)
|
||||
}
|
||||
|
||||
pyProxy := httputil.NewSingleHostReverseProxy(target)
|
||||
pyProxy.ModifyResponse = func(res *http.Response) error {
|
||||
// Generic Header Preservation:
|
||||
// Go's net/http canonicalizes headers (e.g., ETag becomes Etag).
|
||||
// We ensure ETag specifically uses uppercase 'T' as some Bose devices are case-sensitive.
|
||||
if etags, ok := res.Header["Etag"]; ok {
|
||||
delete(res.Header, "Etag")
|
||||
res.Header["ETag"] = etags
|
||||
}
|
||||
// Also restore other potentially sensitive headers if needed, but for now we focus on ETag
|
||||
// as it's the most common culprit.
|
||||
|
||||
currentLp := proxy.NewLoggingProxy(target.String(), redact)
|
||||
currentLp.LogBody = logBody
|
||||
@@ -151,6 +188,7 @@ func main() {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
originalPyDirector := pyProxy.Director
|
||||
pyProxy.Director = func(req *http.Request) {
|
||||
originalPyDirector(req)
|
||||
@@ -160,22 +198,23 @@ func main() {
|
||||
currentLp.LogRequest(req)
|
||||
}
|
||||
|
||||
// Phase 5: Device Discovery
|
||||
return pyProxy
|
||||
}
|
||||
|
||||
func startDeviceDiscovery(server *handlers.Server) {
|
||||
go func() {
|
||||
for {
|
||||
server.DiscoverDevices(context.Background())
|
||||
time.Sleep(5 * time.Minute)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func setupRouter(server *handlers.Server, pyProxy *httputil.ReverseProxy) *chi.Mux {
|
||||
r := chi.NewRouter()
|
||||
|
||||
// Update HTTPS server handler if it was initialized
|
||||
// (Deferred logic in Phase 11 will use this 'r')
|
||||
r.Use(middleware.Logger)
|
||||
r.Use(middleware.Recoverer)
|
||||
|
||||
// Phase 2: Root endpoint implemented in Go
|
||||
r.Get("/", server.HandleRoot)
|
||||
r.Get("/health", server.HandleHealth)
|
||||
r.Get("/favicon.ico", func(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -183,11 +222,9 @@ func main() {
|
||||
server.HandleMedia()(w, r)
|
||||
})
|
||||
|
||||
// Phase 2: Static file serving for /media and /web
|
||||
r.Get("/media/*", server.HandleMedia())
|
||||
r.Get("/web/*", server.HandleWeb())
|
||||
|
||||
// Phase 3: BMX endpoints
|
||||
r.Route("/bmx", func(r chi.Router) {
|
||||
r.Get("/registry/v1/services", server.HandleBMXRegistry)
|
||||
r.Get("/tunein/v1/playback/station/{stationID}", server.HandleTuneInPlayback)
|
||||
@@ -196,7 +233,6 @@ func main() {
|
||||
r.Post("/orion/v1/playback/station/{data}", server.HandleOrionPlayback)
|
||||
})
|
||||
|
||||
// Phase 4: Marge endpoints
|
||||
r.Route("/marge", func(r chi.Router) {
|
||||
r.Get("/streaming/sourceproviders", server.HandleMargeSourceProviders)
|
||||
r.Get("/accounts/{account}/full", server.HandleMargeAccountFull)
|
||||
@@ -212,16 +248,13 @@ func main() {
|
||||
r.Post("/streaming/support/customersupport", server.HandleMargeCustomerSupport)
|
||||
})
|
||||
|
||||
// Phase 10: Stats endpoints
|
||||
r.Route("/streaming/stats", func(r chi.Router) {
|
||||
r.Post("/usage", server.HandleUsageStats)
|
||||
r.Post("/error", server.HandleErrorStats)
|
||||
})
|
||||
|
||||
// Proxy route integrated into main router
|
||||
r.Get("/proxy/*", server.HandleProxyRequest)
|
||||
|
||||
// Phase 7: Setup and Discovery endpoints
|
||||
r.Route("/setup", func(r chi.Router) {
|
||||
r.Get("/devices", server.HandleListDiscoveredDevices)
|
||||
r.Post("/discover", server.HandleTriggerDiscovery)
|
||||
@@ -241,28 +274,25 @@ func main() {
|
||||
r.Get("/devices/{deviceId}/events", server.HandleGetDeviceEvents)
|
||||
})
|
||||
|
||||
// Delegation Logic: Proxy everything else to Python
|
||||
r.NotFound(func(w http.ResponseWriter, r *http.Request) {
|
||||
pyProxy.ServeHTTP(w, r)
|
||||
})
|
||||
|
||||
log.Printf("Go service starting on %s, proxying to %s", serverURL, targetURL)
|
||||
return r
|
||||
}
|
||||
|
||||
if tlsConfig != nil {
|
||||
httpsServer := &http.Server{
|
||||
Addr: httpsAddr,
|
||||
Handler: r,
|
||||
TLSConfig: tlsConfig,
|
||||
}
|
||||
|
||||
log.Printf("Go service starting HTTPS on %s", httpsServerURL)
|
||||
|
||||
go func() {
|
||||
if err := httpsServer.ListenAndServeTLS("", ""); err != nil && err != http.ErrServerClosed {
|
||||
log.Printf("HTTPS server error: %v", err)
|
||||
}
|
||||
}()
|
||||
func startHTTPSServer(httpsAddr string, r http.Handler, tlsConfig *tls.Config, httpsServerURL string) {
|
||||
httpsServer := &http.Server{
|
||||
Addr: httpsAddr,
|
||||
Handler: r,
|
||||
TLSConfig: tlsConfig,
|
||||
}
|
||||
|
||||
log.Fatal(http.ListenAndServe(addr, r))
|
||||
log.Printf("Go service starting HTTPS on %s", httpsServerURL)
|
||||
|
||||
go func() {
|
||||
if err := httpsServer.ListenAndServeTLS("", ""); err != nil && err != http.ErrServerClosed {
|
||||
log.Printf("HTTPS server error: %v", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Package crypto provides tools for managing Root CAs and generating SSL certificates.
|
||||
package crypto
|
||||
|
||||
import (
|
||||
@@ -164,8 +165,8 @@ func (cm *CertificateManager) GenerateCA() error {
|
||||
}
|
||||
|
||||
certPath := cm.GetCACertPath()
|
||||
if err := os.MkdirAll(cm.CertsDir, 0755); err != nil {
|
||||
return err
|
||||
if mkdirErr := os.MkdirAll(cm.CertsDir, 0755); mkdirErr != nil {
|
||||
return mkdirErr
|
||||
}
|
||||
|
||||
certOut, err := os.Create(certPath)
|
||||
@@ -173,8 +174,8 @@ func (cm *CertificateManager) GenerateCA() error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}); err != nil {
|
||||
return err
|
||||
if encodeErr := pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}); encodeErr != nil {
|
||||
return encodeErr
|
||||
}
|
||||
|
||||
certOut.Close()
|
||||
|
||||
@@ -330,21 +330,27 @@ func (s *Server) HandleTestHostsRedirection(w http.ResponseWriter, r *http.Reque
|
||||
if err != nil {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK) // Return 200 but ok: false so UI can show the output
|
||||
_ = json.NewEncoder(w).Encode(map[string]interface{}{
|
||||
|
||||
if encodeErr := json.NewEncoder(w).Encode(map[string]interface{}{
|
||||
"ok": false,
|
||||
"message": err.Error(),
|
||||
"output": output,
|
||||
})
|
||||
}); encodeErr != nil {
|
||||
http.Error(w, "Failed to encode response", http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_ = json.NewEncoder(w).Encode(map[string]interface{}{
|
||||
|
||||
if encodeErr := json.NewEncoder(w).Encode(map[string]interface{}{
|
||||
"ok": true,
|
||||
"message": "Hosts redirection test successful",
|
||||
"output": output,
|
||||
})
|
||||
}); encodeErr != nil {
|
||||
http.Error(w, "Failed to encode response", http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
|
||||
// HandleTestConnection performs a connection check from the device to the server.
|
||||
@@ -367,19 +373,25 @@ func (s *Server) HandleTestConnection(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK) // Return 200 but ok: false so UI can show the output
|
||||
_ = json.NewEncoder(w).Encode(map[string]interface{}{
|
||||
|
||||
if encodeErr := json.NewEncoder(w).Encode(map[string]interface{}{
|
||||
"ok": false,
|
||||
"message": err.Error(),
|
||||
"output": output,
|
||||
})
|
||||
}); encodeErr != nil {
|
||||
http.Error(w, "Failed to encode response", http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_ = json.NewEncoder(w).Encode(map[string]interface{}{
|
||||
|
||||
if encodeErr := json.NewEncoder(w).Encode(map[string]interface{}{
|
||||
"ok": true,
|
||||
"message": "Connection test successful",
|
||||
"output": output,
|
||||
})
|
||||
}); encodeErr != nil {
|
||||
http.Error(w, "Failed to encode response", http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
|
||||
+69
-51
@@ -706,32 +706,56 @@ func (m *Manager) TestHostsRedirection(deviceIP, targetURL string) (string, erro
|
||||
client := m.NewSSH(deviceIP)
|
||||
rwCmd := "(rw || mount -o remount,rw /)"
|
||||
|
||||
// 1. Parse targetURL to get IP for /etc/hosts
|
||||
parsedURL, err := url.Parse(targetURL)
|
||||
hostIP, parsedURL, err := m.parseTargetURLAndResolveIP(targetURL, client)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to parse target URL: %w", err)
|
||||
return "", err
|
||||
}
|
||||
|
||||
hostName := parsedURL.Hostname()
|
||||
if hostName == "" || hostName == "localhost" {
|
||||
return "", fmt.Errorf("target URL must contain a valid IP or hostname (got %s)", hostName)
|
||||
}
|
||||
|
||||
hostIP := m.resolveIP(hostName, client)
|
||||
|
||||
testDomain := TestDomain
|
||||
testEntry := fmt.Sprintf("%s\t%s", hostIP, testDomain)
|
||||
|
||||
// 2. Add temporary entry to /etc/hosts
|
||||
if addErr := m.addTemporaryHostEntry(client, deviceIP, testDomain, testEntry, rwCmd); addErr != nil {
|
||||
return "", addErr
|
||||
}
|
||||
|
||||
defer m.cleanupTemporaryHostEntry(client, testDomain, rwCmd)
|
||||
|
||||
output, err := m.runHTTPRedirectionTest(client, parsedURL, testDomain)
|
||||
if err != nil {
|
||||
return output, err
|
||||
}
|
||||
|
||||
httpsOutput, httpsErr := m.runHTTPSRedirectionTest(client, testDomain)
|
||||
|
||||
combinedOutput := output + "\n---\n" + httpsOutput
|
||||
if httpsErr != nil {
|
||||
return combinedOutput, fmt.Errorf("hosts redirection HTTPS test failed: %w", httpsErr)
|
||||
}
|
||||
|
||||
return combinedOutput, nil
|
||||
}
|
||||
|
||||
func (m *Manager) parseTargetURLAndResolveIP(targetURL string, client SSHClient) (string, *url.URL, error) {
|
||||
parsedURL, err := url.Parse(targetURL)
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("failed to parse target URL: %w", err)
|
||||
}
|
||||
|
||||
hostName := parsedURL.Hostname()
|
||||
if hostName == "" || hostName == "localhost" {
|
||||
return "", nil, fmt.Errorf("target URL must contain a valid IP or hostname (got %s)", hostName)
|
||||
}
|
||||
|
||||
return m.resolveIP(hostName, client), parsedURL, nil
|
||||
}
|
||||
|
||||
func (m *Manager) addTemporaryHostEntry(client SSHClient, deviceIP, testDomain, testEntry, rwCmd string) error {
|
||||
hostsContent, err := client.Run("cat /etc/hosts")
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to read /etc/hosts: %w", err)
|
||||
return fmt.Errorf("failed to read /etc/hosts: %w", err)
|
||||
}
|
||||
|
||||
if strings.Contains(hostsContent, testDomain) {
|
||||
// Even if it's there, let's make sure it's correct (pointing to the current hostIP)
|
||||
// but for now, if it's there, we just assume it's okay or from a previous failed cleanup.
|
||||
// Let's remove it and re-add to be sure.
|
||||
lines := strings.Split(hostsContent, "\n")
|
||||
|
||||
var newLines []string
|
||||
@@ -749,47 +773,45 @@ func (m *Manager) TestHostsRedirection(deviceIP, targetURL string) (string, erro
|
||||
}
|
||||
|
||||
_, _ = client.Run(rwCmd)
|
||||
// Ensure hostsContent ends with a newline if not empty
|
||||
|
||||
if hostsContent != "" && !strings.HasSuffix(hostsContent, "\n") {
|
||||
hostsContent += "\n"
|
||||
}
|
||||
|
||||
newHostsContent := hostsContent + testEntry + "\n"
|
||||
if err := client.UploadContent([]byte(newHostsContent), "/etc/hosts"); err != nil {
|
||||
return "", fmt.Errorf("failed to add test entry to /etc/hosts: %w", err)
|
||||
if uploadErr := client.UploadContent([]byte(newHostsContent), "/etc/hosts"); uploadErr != nil {
|
||||
return fmt.Errorf("failed to add test entry to /etc/hosts: %w", uploadErr)
|
||||
}
|
||||
|
||||
fmt.Printf("Updated /etc/hosts on %s with test entry:\n%s\n", deviceIP, newHostsContent)
|
||||
|
||||
defer func() {
|
||||
// Clean up test entry
|
||||
currentContent, _ := client.Run("cat /etc/hosts")
|
||||
lines := strings.Split(currentContent, "\n")
|
||||
return nil
|
||||
}
|
||||
|
||||
var newLines []string
|
||||
func (m *Manager) cleanupTemporaryHostEntry(client SSHClient, testDomain, rwCmd string) {
|
||||
currentContent, _ := client.Run("cat /etc/hosts")
|
||||
lines := strings.Split(currentContent, "\n")
|
||||
|
||||
for _, line := range lines {
|
||||
if line != "" && !strings.Contains(line, testDomain) {
|
||||
newLines = append(newLines, line)
|
||||
}
|
||||
var newLines []string
|
||||
|
||||
for _, line := range lines {
|
||||
if line != "" && !strings.Contains(line, testDomain) {
|
||||
newLines = append(newLines, line)
|
||||
}
|
||||
}
|
||||
|
||||
finalContent := strings.Join(newLines, "\n")
|
||||
if len(newLines) > 0 {
|
||||
finalContent += "\n"
|
||||
}
|
||||
finalContent := strings.Join(newLines, "\n")
|
||||
if len(newLines) > 0 {
|
||||
finalContent += "\n"
|
||||
}
|
||||
|
||||
_, _ = client.Run(rwCmd)
|
||||
_ = client.UploadContent([]byte(finalContent), "/etc/hosts")
|
||||
}()
|
||||
_, _ = client.Run(rwCmd)
|
||||
_ = client.UploadContent([]byte(finalContent), "/etc/hosts")
|
||||
}
|
||||
|
||||
// 3. Test connection to the fake domain
|
||||
// 3a. HTTP (for simplicity of redirection test)
|
||||
// We use the health check endpoint on the same port but with the fake domain
|
||||
func (m *Manager) runHTTPRedirectionTest(client SSHClient, parsedURL *url.URL, testDomain string) (string, error) {
|
||||
httpTestURL := fmt.Sprintf("http://%s:%s/health", testDomain, parsedURL.Port())
|
||||
if parsedURL.Port() == "" {
|
||||
httpTestURL = fmt.Sprintf("http://%s/health", testDomain)
|
||||
} else if parsedURL.Port() == "80" {
|
||||
if parsedURL.Port() == "" || parsedURL.Port() == "80" {
|
||||
httpTestURL = fmt.Sprintf("http://%s/health", testDomain)
|
||||
}
|
||||
|
||||
@@ -800,7 +822,10 @@ func (m *Manager) TestHostsRedirection(deviceIP, targetURL string) (string, erro
|
||||
return output, fmt.Errorf("hosts redirection HTTP test failed: %w", err)
|
||||
}
|
||||
|
||||
// 3b. HTTPS (to verify TLS reachability)
|
||||
return output, nil
|
||||
}
|
||||
|
||||
func (m *Manager) runHTTPSRedirectionTest(client SSHClient, testDomain string) (string, error) {
|
||||
httpsPort := os.Getenv("HTTPS_PORT")
|
||||
if httpsPort == "" {
|
||||
httpsPort = "8443"
|
||||
@@ -811,16 +836,14 @@ func (m *Manager) TestHostsRedirection(deviceIP, targetURL string) (string, erro
|
||||
httpsTestURL = fmt.Sprintf("https://%s/health", testDomain)
|
||||
}
|
||||
|
||||
// We now include the testDomain in our SSL certificate.
|
||||
// We use the local CA certificate to verify the connection.
|
||||
caPEM, err := os.ReadFile(m.Crypto.GetCACertPath())
|
||||
if err != nil {
|
||||
return output, fmt.Errorf("failed to read CA cert for HTTPS test: %w", err)
|
||||
return "", fmt.Errorf("failed to read CA cert for HTTPS test: %w", err)
|
||||
}
|
||||
|
||||
caPath := "/tmp/soundtouch-test-ca.crt"
|
||||
if err := client.UploadContent(caPEM, caPath); err != nil {
|
||||
return output, fmt.Errorf("failed to upload temporary CA for HTTPS test: %w", err)
|
||||
return "", fmt.Errorf("failed to upload temporary CA for HTTPS test: %w", err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
@@ -829,12 +852,7 @@ func (m *Manager) TestHostsRedirection(deviceIP, targetURL string) (string, erro
|
||||
|
||||
httpsCmd := fmt.Sprintf("curl -v -s -L --cacert %s %s", caPath, httpsTestURL)
|
||||
|
||||
httpsOutput, httpsErr := client.Run(httpsCmd)
|
||||
if httpsErr != nil {
|
||||
return output + "\n---\n" + httpsOutput, fmt.Errorf("hosts redirection HTTPS test failed: %w", httpsErr)
|
||||
}
|
||||
|
||||
return output + "\n---\n" + httpsOutput, nil
|
||||
return client.Run(httpsCmd)
|
||||
}
|
||||
|
||||
// TestConnection performs a connection check from the device to the server.
|
||||
|
||||
Reference in New Issue
Block a user