fix: stop redirecting DERP and replicasync http requests (#10752)

Fixes an issue where setting CODER_REDIRECT_TO_ACCESS_URL breaks use of multiple Coder server replicas for DERP traffic.
This commit is contained in:
Spike Curtis
2023-11-20 14:46:59 +04:00
committed by GitHub
parent 5c48cb4447
commit 5173bce5cc
5 changed files with 123 additions and 13 deletions
+14 -1
View File
@@ -7,6 +7,7 @@ import (
"errors"
"fmt"
"net/http"
"net/url"
"os"
"strings"
"sync"
@@ -274,7 +275,19 @@ func (m *Manager) syncReplicas(ctx context.Context) error {
wg.Add(1)
go func(peer database.Replica) {
defer wg.Done()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, peer.RelayAddress, nil)
ra, err := url.Parse(peer.RelayAddress)
if err != nil {
m.logger.Warn(ctx, "could not parse relay address",
slog.F("relay_address", peer.RelayAddress), slog.Error(err))
return
}
target, err := ra.Parse("/derp/latency-check")
if err != nil {
m.logger.Warn(ctx, "could not resolve /derp/latency-check endpoint",
slog.F("relay_address", peer.RelayAddress), slog.Error(err))
return
}
req, err := http.NewRequestWithContext(ctx, http.MethodGet, target.String(), nil)
if err != nil {
m.logger.Warn(ctx, "create http request for relay probe",
slog.F("relay_address", peer.RelayAddress), slog.Error(err))
+30 -12
View File
@@ -7,6 +7,7 @@ import (
"net/http"
"net/http/httptest"
"sync"
"sync/atomic"
"testing"
"time"
@@ -55,9 +56,9 @@ func TestReplica(t *testing.T) {
// Ensures that the replica reports a successful status for
// accessing all of its peers.
t.Parallel()
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}))
dh := &derpyHandler{}
defer dh.requireOnlyDERPPaths(t)
srv := httptest.NewServer(dh)
defer srv.Close()
db, pubsub := dbtestutil.NewDB(t)
peer, err := db.InsertReplica(context.Background(), database.InsertReplicaParams{
@@ -98,9 +99,9 @@ func TestReplica(t *testing.T) {
ServerName: "hello.org",
RootCAs: pool,
}
srv := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}))
dh := &derpyHandler{}
defer dh.requireOnlyDERPPaths(t)
srv := httptest.NewUnstartedServer(dh)
srv.TLS = tlsConfig
srv.StartTLS()
defer srv.Close()
@@ -167,9 +168,9 @@ func TestReplica(t *testing.T) {
server, err := replicasync.New(ctx, slogtest.Make(t, nil), db, pubsub, nil)
require.NoError(t, err)
defer server.Close()
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}))
dh := &derpyHandler{}
defer dh.requireOnlyDERPPaths(t)
srv := httptest.NewServer(dh)
defer srv.Close()
peer, err := db.InsertReplica(ctx, database.InsertReplicaParams{
ID: uuid.New(),
@@ -221,9 +222,9 @@ func TestReplica(t *testing.T) {
db := dbmem.New()
pubsub := pubsub.NewInMemory()
logger := slogtest.Make(t, nil)
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}))
dh := &derpyHandler{}
defer dh.requireOnlyDERPPaths(t)
srv := httptest.NewServer(dh)
defer srv.Close()
var wg sync.WaitGroup
count := 20
@@ -255,3 +256,20 @@ func TestReplica(t *testing.T) {
wg.Wait()
})
}
type derpyHandler struct {
atomic.Uint32
}
func (d *derpyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/derp/latency-check" {
w.WriteHeader(http.StatusNotFound)
d.Add(1)
return
}
w.WriteHeader(http.StatusUpgradeRequired)
}
func (d *derpyHandler) requireOnlyDERPPaths(t *testing.T) {
require.Equal(t, uint32(0), d.Load())
}