PUT/POST as JSON, relates to #133

pull/173/head
Philipp Heckel 2022-03-15 16:00:59 -04:00
parent 53375ff559
commit 37d4d5d647
2 changed files with 55 additions and 0 deletions

View File

@ -263,6 +263,8 @@ func (s *Server) handle(w http.ResponseWriter, r *http.Request) {
func (s *Server) handleInternal(w http.ResponseWriter, r *http.Request, v *visitor) error { func (s *Server) handleInternal(w http.ResponseWriter, r *http.Request, v *visitor) error {
if r.Method == http.MethodGet && r.URL.Path == "/" { if r.Method == http.MethodGet && r.URL.Path == "/" {
return s.handleHome(w, r) return s.handleHome(w, r)
} else if (r.Method == http.MethodPut || r.Method == http.MethodPost) && r.URL.Path == "/" {
return s.limitRequests(s.fromMessageJSON(s.authWrite(s.handlePublish)))(w, r, v)
} else if r.Method == http.MethodGet && r.URL.Path == "/example.html" { } else if r.Method == http.MethodGet && r.URL.Path == "/example.html" {
return s.handleExample(w, r) return s.handleExample(w, r)
} else if r.Method == http.MethodHead && r.URL.Path == "/" { } else if r.Method == http.MethodHead && r.URL.Path == "/" {
@ -1093,6 +1095,47 @@ func (s *Server) limitRequests(next handleFunc) handleFunc {
} }
} }
func (s *Server) fromMessageJSON(next handleFunc) handleFunc {
return func(w http.ResponseWriter, r *http.Request, v *visitor) error {
body, err := util.Peak(r.Body, s.config.MessageLimit)
if err != nil {
return err
}
defer r.Body.Close()
var m publishMessage
if err := json.NewDecoder(body).Decode(&m); err != nil {
return err
}
if !topicRegex.MatchString(m.Topic) {
return errors.New("invalid message")
}
if m.Message == "" {
m.Message = emptyMessageBody
}
r.URL.Path = "/" + m.Topic
r.Body = io.NopCloser(strings.NewReader(m.Message))
if m.Title != "" {
r.Header.Set("X-Title", m.Title)
}
if m.Priority != "" {
r.Header.Set("X-Priority", m.Priority)
}
if m.Tags != "" {
r.Header.Set("X-Tags", m.Tags)
}
if m.Attach != "" {
r.Header.Set("X-Attach", m.Attach)
}
if m.Filename != "" {
r.Header.Set("X-Filename", m.Filename)
}
if m.Click != "" {
r.Header.Set("X-Click", m.Click)
}
return next(w, r, v)
}
}
func (s *Server) authWrite(next handleFunc) handleFunc { func (s *Server) authWrite(next handleFunc) handleFunc {
return s.withAuth(next, auth.PermissionWrite) return s.withAuth(next, auth.PermissionWrite)
} }

View File

@ -42,6 +42,18 @@ type attachment struct {
Owner string `json:"-"` // IP address of uploader, used for rate limiting Owner string `json:"-"` // IP address of uploader, used for rate limiting
} }
// publishMessage is used as input when publishing as JSON
type publishMessage struct {
Topic string `json:"topic"`
Title string `json:"title"`
Message string `json:"message"`
Priority string `json:"priority"`
Tags string `json:"tags"`
Click string `json:"click"`
Attach string `json:"attach"`
Filename string `json:"filename"`
}
// messageEncoder is a function that knows how to encode a message // messageEncoder is a function that knows how to encode a message
type messageEncoder func(msg *message) (string, error) type messageEncoder func(msg *message) (string, error)