rpc/server: add notification filters
And check state string correctness on unmarshaling.
This commit is contained in:
parent
78716c5335
commit
8f55f0ac76
4 changed files with 192 additions and 33 deletions
|
@ -365,8 +365,8 @@ requestloop:
|
|||
s.subsLock.Lock()
|
||||
delete(s.subscribers, subscr)
|
||||
for _, e := range subscr.feeds {
|
||||
if e != response.InvalidEventID {
|
||||
s.unsubscribeFromChannel(e)
|
||||
if e.event != response.InvalidEventID {
|
||||
s.unsubscribeFromChannel(e.event)
|
||||
}
|
||||
}
|
||||
s.subsLock.Unlock()
|
||||
|
@ -1146,6 +1146,32 @@ func (s *Server) subscribe(reqParams request.Params, sub *subscriber) (interface
|
|||
if err != nil || event == response.MissedEventID {
|
||||
return nil, response.ErrInvalidParams
|
||||
}
|
||||
// Optional filter.
|
||||
var filter interface{}
|
||||
p, ok = reqParams.Value(1)
|
||||
if ok {
|
||||
// It doesn't accept filters.
|
||||
if event == response.BlockEventID {
|
||||
return nil, response.ErrInvalidParams
|
||||
}
|
||||
|
||||
switch event {
|
||||
case response.TransactionEventID:
|
||||
if p.Type != request.TxFilterT {
|
||||
return nil, response.ErrInvalidParams
|
||||
}
|
||||
case response.NotificationEventID:
|
||||
if p.Type != request.NotificationFilterT {
|
||||
return nil, response.ErrInvalidParams
|
||||
}
|
||||
case response.ExecutionEventID:
|
||||
if p.Type != request.ExecutionFilterT {
|
||||
return nil, response.ErrInvalidParams
|
||||
}
|
||||
}
|
||||
filter = p.Value
|
||||
}
|
||||
|
||||
s.subsLock.Lock()
|
||||
defer s.subsLock.Unlock()
|
||||
select {
|
||||
|
@ -1155,14 +1181,15 @@ func (s *Server) subscribe(reqParams request.Params, sub *subscriber) (interface
|
|||
}
|
||||
var id int
|
||||
for ; id < len(sub.feeds); id++ {
|
||||
if sub.feeds[id] == response.InvalidEventID {
|
||||
if sub.feeds[id].event == response.InvalidEventID {
|
||||
break
|
||||
}
|
||||
}
|
||||
if id == len(sub.feeds) {
|
||||
return nil, response.NewInternalServerError("maximum number of subscriptions is reached", nil)
|
||||
}
|
||||
sub.feeds[id] = event
|
||||
sub.feeds[id].event = event
|
||||
sub.feeds[id].filter = filter
|
||||
s.subscribeToChannel(event)
|
||||
return strconv.FormatInt(int64(id), 10), nil
|
||||
}
|
||||
|
@ -1207,11 +1234,12 @@ func (s *Server) unsubscribe(reqParams request.Params, sub *subscriber) (interfa
|
|||
}
|
||||
s.subsLock.Lock()
|
||||
defer s.subsLock.Unlock()
|
||||
if len(sub.feeds) <= id || sub.feeds[id] == response.InvalidEventID {
|
||||
if len(sub.feeds) <= id || sub.feeds[id].event == response.InvalidEventID {
|
||||
return nil, response.ErrInvalidParams
|
||||
}
|
||||
event := sub.feeds[id]
|
||||
sub.feeds[id] = response.InvalidEventID
|
||||
event := sub.feeds[id].event
|
||||
sub.feeds[id].event = response.InvalidEventID
|
||||
sub.feeds[id].filter = nil
|
||||
s.unsubscribeFromChannel(event)
|
||||
return true, nil
|
||||
}
|
||||
|
@ -1288,8 +1316,8 @@ chloop:
|
|||
if sub.overflown.Load() {
|
||||
continue
|
||||
}
|
||||
for _, subID := range sub.feeds {
|
||||
if subID == resp.Event {
|
||||
for i := range sub.feeds {
|
||||
if sub.feeds[i].Matches(&resp) {
|
||||
if msg == nil {
|
||||
b, err = json.Marshal(resp)
|
||||
if err != nil {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue