fix: decode url param in relay rest API (#862)

* fix: decode url param in relay rest API

* Update cmd/waku/server/rest/relay.go

Co-authored-by: richΛrd <info@richardramos.me>

* chore: reuse common functions

---------

Co-authored-by: richΛrd <info@richardramos.me>
This commit is contained in:
Prem Chaitanya Prathi 2023-11-06 14:03:00 +05:30 committed by GitHub
parent 532a04013f
commit 25eb4d60a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 41 additions and 42 deletions

View File

@ -6,7 +6,6 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"net/http" "net/http"
"net/url"
"strings" "strings"
"github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5"
@ -327,24 +326,24 @@ func (s FilterService) getRandomFilterPeer(ctx context.Context, requestId []byte
} }
func (s *FilterService) getMessagesByContentTopic(w http.ResponseWriter, req *http.Request) { func (s *FilterService) getMessagesByContentTopic(w http.ResponseWriter, req *http.Request) {
contentTopic := s.topicFromPath(w, req, "contentTopic") contentTopic := topicFromPath(w, req, "contentTopic", s.log)
if contentTopic == "" { if contentTopic == "" {
return return
} }
pubsubTopic, err := protocol.GetPubSubTopicFromContentTopic(contentTopic) pubsubTopic, err := protocol.GetPubSubTopicFromContentTopic(contentTopic)
if err != nil { if err != nil {
s.writeGetMessageErr(w, fmt.Errorf("bad content topic"), http.StatusBadRequest) writeGetMessageErr(w, fmt.Errorf("bad content topic"), http.StatusBadRequest, s.log)
return return
} }
s.getMessages(w, req, pubsubTopic, contentTopic) s.getMessages(w, req, pubsubTopic, contentTopic)
} }
func (s *FilterService) getMessagesByPubsubTopic(w http.ResponseWriter, req *http.Request) { func (s *FilterService) getMessagesByPubsubTopic(w http.ResponseWriter, req *http.Request) {
contentTopic := s.topicFromPath(w, req, "contentTopic") contentTopic := topicFromPath(w, req, "contentTopic", s.log)
if contentTopic == "" { if contentTopic == "" {
return return
} }
pubsubTopic := s.topicFromPath(w, req, "pubsubTopic") pubsubTopic := topicFromPath(w, req, "pubsubTopic", s.log)
if pubsubTopic == "" { if pubsubTopic == "" {
return return
} }
@ -358,33 +357,8 @@ func (s *FilterService) getMessagesByPubsubTopic(w http.ResponseWriter, req *htt
func (s *FilterService) getMessages(w http.ResponseWriter, req *http.Request, pubsubTopic, contentTopic string) { func (s *FilterService) getMessages(w http.ResponseWriter, req *http.Request, pubsubTopic, contentTopic string) {
msgs, err := s.cache.getMessages(pubsubTopic, contentTopic) msgs, err := s.cache.getMessages(pubsubTopic, contentTopic)
if err != nil { if err != nil {
s.writeGetMessageErr(w, err, http.StatusNotFound) writeGetMessageErr(w, err, http.StatusNotFound, s.log)
return return
} }
writeResponse(w, msgs, http.StatusOK) writeResponse(w, msgs, http.StatusOK)
} }
func (s *FilterService) topicFromPath(w http.ResponseWriter, req *http.Request, field string) string {
cTopic := chi.URLParam(req, field)
if cTopic == "" {
errMissing := fmt.Errorf("missing %s", field)
s.writeGetMessageErr(w, errMissing, http.StatusBadRequest)
return ""
}
cTopic, err := url.QueryUnescape(cTopic)
if err != nil {
errInvalid := fmt.Errorf("invalid %s format", field)
s.writeGetMessageErr(w, errInvalid, http.StatusBadRequest)
return ""
}
return cTopic
}
func (s *FilterService) writeGetMessageErr(w http.ResponseWriter, err error, code int) {
// write status before the body
w.WriteHeader(code)
s.log.Error("get message", zap.Error(err))
if _, err := w.Write([]byte(err.Error())); err != nil {
s.log.Error("writing response", zap.Error(err))
}
}

View File

@ -68,7 +68,7 @@ func (c *filterCache) getMessages(pubsubTopic string, contentTopic string) ([]*p
defer c.mu.RUnlock() defer c.mu.RUnlock()
if c.data[pubsubTopic] == nil || c.data[pubsubTopic][contentTopic] == nil { if c.data[pubsubTopic] == nil || c.data[pubsubTopic][contentTopic] == nil {
return nil, fmt.Errorf("Not subscribed to pubsubTopic:%s contentTopic: %s", pubsubTopic, contentTopic) return nil, fmt.Errorf("not subscribed to pubsubTopic:%s contentTopic: %s", pubsubTopic, contentTopic)
} }
msgs := c.data[pubsubTopic][contentTopic] msgs := c.data[pubsubTopic][contentTopic]
c.data[pubsubTopic][contentTopic] = []*pb.WakuMessage{} c.data[pubsubTopic][contentTopic] = []*pb.WakuMessage{}

View File

@ -166,20 +166,17 @@ func (r *RelayService) postV1Subscriptions(w http.ResponseWriter, req *http.Requ
} }
func (r *RelayService) getV1Messages(w http.ResponseWriter, req *http.Request) { func (r *RelayService) getV1Messages(w http.ResponseWriter, req *http.Request) {
topic := chi.URLParam(req, "topic") topic := topicFromPath(w, req, "topic", r.log)
if topic == "" { if topic == "" {
w.WriteHeader(http.StatusBadRequest)
return return
} }
var err error
r.messagesMutex.Lock() r.messagesMutex.Lock()
defer r.messagesMutex.Unlock() defer r.messagesMutex.Unlock()
if _, ok := r.messages[topic]; !ok { if _, ok := r.messages[topic]; !ok {
w.WriteHeader(http.StatusNotFound) w.WriteHeader(http.StatusNotFound)
_, err = w.Write([]byte("not subscribed to topic")) _, err := w.Write([]byte("not subscribed to topic"))
r.log.Error("writing response", zap.Error(err)) r.log.Error("writing response", zap.Error(err))
return return
} }
@ -191,9 +188,8 @@ func (r *RelayService) getV1Messages(w http.ResponseWriter, req *http.Request) {
} }
func (r *RelayService) postV1Message(w http.ResponseWriter, req *http.Request) { func (r *RelayService) postV1Message(w http.ResponseWriter, req *http.Request) {
topic := chi.URLParam(req, "topic") topic := topicFromPath(w, req, "topic", r.log)
if topic == "" { if topic == "" {
w.WriteHeader(http.StatusBadRequest)
return return
} }
@ -205,7 +201,6 @@ func (r *RelayService) postV1Message(w http.ResponseWriter, req *http.Request) {
} }
defer req.Body.Close() defer req.Body.Close()
var err error
if topic == "" { if topic == "" {
topic = relay.DefaultWakuTopic topic = relay.DefaultWakuTopic
} }
@ -215,12 +210,12 @@ func (r *RelayService) postV1Message(w http.ResponseWriter, req *http.Request) {
return return
} }
if err = server.AppendRLNProof(r.node, message); err != nil { if err := server.AppendRLNProof(r.node, message); err != nil {
writeErrOrResponse(w, err, nil) writeErrOrResponse(w, err, nil)
return return
} }
_, err = r.node.Relay().Publish(req.Context(), message, relay.WithPubSubTopic(strings.Replace(topic, "\n", "", -1))) _, err := r.node.Relay().Publish(req.Context(), message, relay.WithPubSubTopic(strings.Replace(topic, "\n", "", -1)))
if err != nil { if err != nil {
r.log.Error("publishing message", zap.Error(err)) r.log.Error("publishing message", zap.Error(err))
} }

View File

@ -2,7 +2,12 @@ package rest
import ( import (
"encoding/json" "encoding/json"
"fmt"
"net/http" "net/http"
"net/url"
"github.com/go-chi/chi/v5"
"go.uber.org/zap"
) )
func writeErrOrResponse(w http.ResponseWriter, err error, value interface{}) { func writeErrOrResponse(w http.ResponseWriter, err error, value interface{}) {
@ -40,3 +45,28 @@ func writeResponse(w http.ResponseWriter, value interface{}, code int) {
w.WriteHeader(code) w.WriteHeader(code)
_, _ = w.Write(jsonResponse) _, _ = w.Write(jsonResponse)
} }
func topicFromPath(w http.ResponseWriter, req *http.Request, field string, logger *zap.Logger) string {
topic := chi.URLParam(req, field)
if topic == "" {
errMissing := fmt.Errorf("missing %s", field)
writeGetMessageErr(w, errMissing, http.StatusBadRequest, logger)
return ""
}
topic, err := url.QueryUnescape(topic)
if err != nil {
errInvalid := fmt.Errorf("invalid %s format", field)
writeGetMessageErr(w, errInvalid, http.StatusBadRequest, logger)
return ""
}
return topic
}
func writeGetMessageErr(w http.ResponseWriter, err error, code int, logger *zap.Logger) {
// write status before the body
w.WriteHeader(code)
logger.Error("get message", zap.Error(err))
if _, err := w.Write([]byte(err.Error())); err != nil {
logger.Error("writing response", zap.Error(err))
}
}