implement metadata before-connect (#2281)

* metadata spec update: disallow colon entirely

* refactor key validation

* implement metadata before-connect

* play the metadata in reg burst to all clients with the cap

* bump irctest

* remove all case normalization for keys

From spec discussion, we will most likely either require keys to be lowercase,
or else treat them as case-opaque, similar to message tag keys.
This commit is contained in:
Shivaram Lingamneni 2025-06-22 13:57:46 -04:00 committed by GitHub
parent a5e435a26b
commit 73e51333ad
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 199 additions and 59 deletions

View file

@ -839,6 +839,8 @@ func (session *Session) isSubscribedTo(key string) bool {
}
func (session *Session) SubscribeTo(keys ...string) ([]string, error) {
maxSubs := session.client.server.Config().Metadata.MaxSubs
session.client.stateMutex.Lock()
defer session.client.stateMutex.Unlock()
@ -848,8 +850,6 @@ func (session *Session) SubscribeTo(keys ...string) ([]string, error) {
var added []string
maxSubs := session.client.server.Config().Metadata.MaxSubs
for _, k := range keys {
if !session.metadataSubscriptions.Has(k) {
if len(session.metadataSubscriptions) > maxSubs {
@ -980,6 +980,30 @@ func (client *Client) SetMetadata(key string, value string, limit int) (updated
return updated, nil
}
func (client *Client) UpdateMetadataFromPrereg(preregData map[string]string, limit int) (updates map[string]string) {
updates = make(map[string]string, len(preregData))
client.stateMutex.Lock()
defer client.stateMutex.Unlock()
if client.metadata == nil {
client.metadata = make(map[string]string)
}
for k, v := range preregData {
// do not overwrite any existing keys
_, ok := client.metadata[k]
if ok {
continue
}
if len(client.metadata) >= limit {
return // we know this is a new key
}
client.metadata[k] = v
}
return
}
func (client *Client) ListMetadata() map[string]string {
client.stateMutex.RLock()
defer client.stateMutex.RUnlock()