security: prevent send-on-close panic

Move channel sends into mutex lock to prevent channel closure from racing with the send.
Add a buffer to the event and inbox channels for backpressure management.
This commit is contained in:
Jay
2026-08-09 19:02:39 -04:00
parent 7e54a26aac
commit 22b385f240
+13 -19
View File
@@ -214,7 +214,7 @@ func (e *Embassy) send(url string, data []byte) error {
} }
func (e *Embassy) subscribeEventsLock(url string) <-chan PoolEvent { func (e *Embassy) subscribeEventsLock(url string) <-chan PoolEvent {
ch := make(chan PoolEvent) ch := make(chan PoolEvent, 256)
e.eventSubs[url] = ch e.eventSubs[url] = ch
return ch return ch
} }
@@ -229,7 +229,7 @@ func (e *Embassy) unsubscribeEventsLock(url string) {
} }
func (e *Embassy) subscribeInboxLock(url string) <-chan InboxMessage { func (e *Embassy) subscribeInboxLock(url string) <-chan InboxMessage {
ch := make(chan InboxMessage) ch := make(chan InboxMessage, 256)
e.inboxSubs[url] = ch e.inboxSubs[url] = ch
return ch return ch
} }
@@ -258,21 +258,18 @@ func (e *Embassy) routeEvents() {
continue continue
} }
e.mu.RLock() e.mu.Lock()
sub, ok := e.eventSubs[url] ch, ok := e.eventSubs[url]
e.mu.RUnlock()
if !ok { if !ok {
e.mu.Unlock()
continue continue
} }
select { ch <- PoolEvent{
case <-e.ctx.Done():
return
case sub <- PoolEvent{
URL: ev.URL, Kind: mapEmbassyEvent(ev.Kind), At: ev.At, Err: ev.Err, URL: ev.URL, Kind: mapEmbassyEvent(ev.Kind), At: ev.At, Err: ev.Err,
}:
} }
e.mu.Unlock()
} }
} }
} }
@@ -292,20 +289,17 @@ func (e *Embassy) routeInbox() {
continue continue
} }
e.mu.RLock() e.mu.Lock()
sub, ok := e.inboxSubs[url] ch, ok := e.inboxSubs[url]
e.mu.RUnlock()
if !ok { if !ok {
e.mu.Unlock()
continue continue
} }
select { ch <- InboxMessage{
case <-e.ctx.Done(): URL: ev.URL, Data: ev.Data, ReceivedAt: ev.ReceivedAt}
return e.mu.Unlock()
case sub <- InboxMessage{
URL: ev.URL, Data: ev.Data, ReceivedAt: ev.ReceivedAt}:
}
} }
} }
} }