package ws import ( "fmt" "time" ) // SessionConfig bounds connection memory and I/O. Zero fields use defaults; // DisableHeartbeat explicitly disables automatic ping/pong deadlines. type SessionConfig struct { MaxMessageBytes int64 `json:"maxMessageBytes"` ReadQueueSize int `json:"readQueueSize"` ReadQueueBytes int64 `json:"readQueueBytes"` WriteQueueSize int `json:"writeQueueSize"` WriteQueueBytes int64 `json:"writeQueueBytes"` WriteTimeout time.Duration `json:"writeTimeout"` PingInterval time.Duration `json:"pingInterval"` PongTimeout time.Duration `json:"pongTimeout"` CloseTimeout time.Duration `json:"closeTimeout"` DisableHeartbeat bool `json:"disableHeartbeat"` } func DefaultSessionConfig() SessionConfig { return SessionConfig{MaxMessageBytes: 1 << 20, ReadQueueSize: 64, ReadQueueBytes: 4 << 20, WriteQueueSize: 64, WriteQueueBytes: 4 << 20, WriteTimeout: 10 * time.Second, PingInterval: 30 * time.Second, PongTimeout: 60 * time.Second, CloseTimeout: 5 * time.Second} } func (c SessionConfig) defaults() SessionConfig { d := DefaultSessionConfig() if c.MaxMessageBytes == 0 { c.MaxMessageBytes = d.MaxMessageBytes } if c.ReadQueueSize == 0 { c.ReadQueueSize = d.ReadQueueSize } if c.ReadQueueBytes == 0 { c.ReadQueueBytes = d.ReadQueueBytes } if c.WriteQueueSize == 0 { c.WriteQueueSize = d.WriteQueueSize } if c.WriteQueueBytes == 0 { c.WriteQueueBytes = d.WriteQueueBytes } if c.WriteTimeout == 0 { c.WriteTimeout = d.WriteTimeout } if c.PingInterval == 0 { c.PingInterval = d.PingInterval } if c.PongTimeout == 0 { c.PongTimeout = d.PongTimeout } if c.CloseTimeout == 0 { c.CloseTimeout = d.CloseTimeout } return c } func (c SessionConfig) Validate() error { if c.MaxMessageBytes < 0 || c.MaxMessageBytes > 1<<30 || c.ReadQueueSize < 0 || c.ReadQueueSize > 65536 || c.ReadQueueBytes < 0 || c.ReadQueueBytes > 1<<30 || c.WriteQueueSize < 0 || c.WriteQueueSize > 65536 || c.WriteQueueBytes < 0 || c.WriteQueueBytes > 1<<30 { return fmt.Errorf("ws: message and queue limits must be nonnegative and bounded") } if c.WriteTimeout < 0 || c.PingInterval < 0 || c.PongTimeout < 0 || c.CloseTimeout < 0 { return fmt.Errorf("ws: timeouts must be nonnegative") } if c.WriteTimeout > 24*time.Hour || c.PingInterval > 24*time.Hour || c.PongTimeout > 24*time.Hour || c.CloseTimeout > 24*time.Hour { return fmt.Errorf("ws: timeout exceeds 24 hours") } c = c.defaults() if !c.DisableHeartbeat && c.PongTimeout <= c.PingInterval { return fmt.Errorf("ws: pongTimeout must exceed pingInterval") } return nil } func normalizeSessionConfig(c SessionConfig) (SessionConfig, error) { if err := c.Validate(); err != nil { return SessionConfig{}, err } return c.defaults(), nil }