rpc/server: add notification filters
And check state string correctness on unmarshaling.
This commit is contained in:
parent
2dc16c0694
commit
393ce1c230
5 changed files with 284 additions and 39 deletions
|
@ -366,8 +366,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()
|
||||
|
@ -1145,6 +1145,31 @@ 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 {
|
||||
switch event {
|
||||
case response.BlockEventID:
|
||||
if p.Type != request.BlockFilterT {
|
||||
return nil, response.ErrInvalidParams
|
||||
}
|
||||
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 {
|
||||
|
@ -1154,14 +1179,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
|
||||
}
|
||||
|
@ -1206,11 +1232,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
|
||||
}
|
||||
|
@ -1287,8 +1314,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