Skip to content

Commit 8fc88e1

Browse files
Thomas StrombergThomas Stromberg
authored andcommitted
audit for reliability, security, simplicity
1 parent d41de48 commit 8fc88e1

File tree

3 files changed

+248
-278
lines changed

3 files changed

+248
-278
lines changed

cmd/server/main.go

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,13 @@ import (
2323
)
2424

2525
const (
26-
readTimeout = 10 * time.Second
27-
writeTimeout = 10 * time.Second
28-
idleTimeout = 120 * time.Second
29-
maxHeaderBytes = 20 // Max header size multiplier (1 << 20 = 1MB)
30-
minTokenLength = 40 // Minimum GitHub token length
31-
maxTokenLength = 255 // Maximum GitHub token length
26+
readTimeout = 10 * time.Second
27+
writeTimeout = 10 * time.Second
28+
idleTimeout = 120 * time.Second
29+
maxHeaderBytes = 20 // Max header size multiplier (1 << 20 = 1MB)
30+
minTokenLength = 40 // Minimum GitHub token length
31+
maxTokenLength = 255 // Maximum GitHub token length
32+
minMaskHeaderLength = 20 // Minimum header length before we show full "[REDACTED]"
3233
)
3334

3435
var (
@@ -46,7 +47,7 @@ var (
4647
debugHeaders = flag.Bool("debug-headers", false, "Log request headers for debugging (security warning: may log sensitive data)")
4748
)
4849

49-
//nolint:funlen,lll // Main function orchestrates entire server setup and cannot be split without losing clarity
50+
//nolint:funlen,gocognit,lll,revive,maintidx // Main function orchestrates entire server setup and cannot be split without losing clarity
5051
func main() {
5152
flag.Parse()
5253

@@ -194,6 +195,7 @@ func main() {
194195

195196
// Pre-validate authentication before WebSocket upgrade
196197
authHeader := r.Header.Get("Authorization")
198+
//nolint:nestif // Auth validation logic is necessarily complex for detailed error reporting
197199
if !wsHandler.PreValidateAuth(r) {
198200
// Determine specific failure reason for better debugging
199201
reason := "missing"
@@ -210,10 +212,10 @@ func main() {
210212
}
211213
}
212214

213-
// Mask token for security (show only length and prefix if present)
215+
// Mask token for security (show only length if present)
214216
authHeaderLog := "missing"
215217
if authHeader != "" {
216-
if len(authHeader) > 20 {
218+
if len(authHeader) > minMaskHeaderLength {
217219
authHeaderLog = fmt.Sprintf("Bearer [REDACTED len=%d]", len(authHeader)-7)
218220
} else {
219221
authHeaderLog = "[REDACTED]"

pkg/client/client.go

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,14 +76,16 @@ type Config struct {
7676
// - Server sends pings; client responds with pongs
7777
// - Client also sends pings; server responds with pongs
7878
// - Both sides use read timeouts to detect dead connections
79+
//
80+
//nolint:govet // Field alignment optimization would reduce readability
7981
type Client struct {
82+
mu sync.RWMutex
83+
config Config
8084
logger *slog.Logger
8185
ws *websocket.Conn
8286
stopCh chan struct{}
8387
stoppedCh chan struct{}
84-
config Config
8588
writeCh chan any // Channel for serializing all writes
86-
mu sync.RWMutex
8789
eventCount int
8890
retries int
8991
}
@@ -231,6 +233,8 @@ func (c *Client) Stop() {
231233
}
232234

233235
// connect establishes a WebSocket connection and handles events.
236+
//
237+
//nolint:gocognit,funlen,maintidx // Connection lifecycle orchestration is inherently complex
234238
func (c *Client) connect(ctx context.Context) error {
235239
c.logger.Info("Establishing WebSocket connection")
236240

@@ -339,12 +343,21 @@ func (c *Client) connect(ctx context.Context) error {
339343
}
340344

341345
// Check response type
342-
responseType, _ := firstResponse[msgTypeField].(string) //nolint:errcheck // type assertion, not error
346+
responseType, ok := firstResponse[msgTypeField].(string)
347+
if !ok {
348+
responseType = ""
349+
}
343350

344351
// Handle error response
345352
if responseType == "error" {
346-
errorCode, _ := firstResponse["error"].(string) //nolint:errcheck // type assertion, not error
347-
message, _ := firstResponse["message"].(string) //nolint:errcheck // type assertion, not error
353+
errorCode, ok := firstResponse["error"].(string)
354+
if !ok {
355+
errorCode = ""
356+
}
357+
message, ok := firstResponse["message"].(string)
358+
if !ok {
359+
message = ""
360+
}
348361
c.logger.Error(separatorLine)
349362
c.logger.Error("SUBSCRIPTION REJECTED BY SERVER!", "error_code", errorCode, "message", message)
350363
c.logger.Error(separatorLine)
@@ -531,7 +544,10 @@ func (c *Client) readEvents(ctx context.Context, ws *websocket.Conn) error {
531544
}
532545

533546
// Check message type
534-
responseType, _ := response[msgTypeField].(string) //nolint:errcheck // type assertion, not error
547+
responseType, ok := response[msgTypeField].(string)
548+
if !ok {
549+
responseType = ""
550+
}
535551

536552
// Handle ping messages from server
537553
if responseType == "ping" {

0 commit comments

Comments
 (0)