Derpyderp
This commit is contained in:
parent
e9f3edb76b
commit
27910772f0
1 changed files with 62 additions and 17 deletions
|
@ -298,7 +298,7 @@ func (s *Server) handleInternal(w http.ResponseWriter, r *http.Request, v *visit
|
||||||
} else if (r.Method == http.MethodPut || r.Method == http.MethodPost) && r.URL.Path == "/" {
|
} else if (r.Method == http.MethodPut || r.Method == http.MethodPost) && r.URL.Path == "/" {
|
||||||
return s.limitRequests(s.transformBodyJSON(s.authWrite(s.handlePublish)))(w, r, v)
|
return s.limitRequests(s.transformBodyJSON(s.authWrite(s.handlePublish)))(w, r, v)
|
||||||
} else if r.Method == http.MethodPost && r.URL.Path == matrixPushPath {
|
} else if r.Method == http.MethodPost && r.URL.Path == matrixPushPath {
|
||||||
return s.limitRequests(s.transformMatrixJSON(s.authWrite(s.handlePublish)))(w, r, v)
|
return s.limitRequests(s.transformMatrixJSON(s.authWrite(s.handlePublishMatrix)))(w, r, v)
|
||||||
} else if (r.Method == http.MethodPut || r.Method == http.MethodPost) && topicPathRegex.MatchString(r.URL.Path) {
|
} else if (r.Method == http.MethodPut || r.Method == http.MethodPost) && topicPathRegex.MatchString(r.URL.Path) {
|
||||||
return s.limitRequests(s.authWrite(s.handlePublish))(w, r, v)
|
return s.limitRequests(s.authWrite(s.handlePublish))(w, r, v)
|
||||||
} else if r.Method == http.MethodGet && publishPathRegex.MatchString(r.URL.Path) {
|
} else if r.Method == http.MethodGet && publishPathRegex.MatchString(r.URL.Path) {
|
||||||
|
@ -428,25 +428,25 @@ func (s *Server) handleFile(w http.ResponseWriter, r *http.Request, v *visitor)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) handlePublish(w http.ResponseWriter, r *http.Request, v *visitor) error {
|
func (s *Server) handlePublishWithoutResponse(r *http.Request, v *visitor) (*message, error) {
|
||||||
t, err := s.topicFromPath(r.URL.Path)
|
t, err := s.topicFromPath(r.URL.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
body, err := util.Peek(r.Body, s.config.MessageLimit)
|
body, err := util.Peek(r.Body, s.config.MessageLimit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
m := newDefaultMessage(t.ID, "")
|
m := newDefaultMessage(t.ID, "")
|
||||||
cache, firebase, email, unifiedpush, err := s.parsePublishParams(r, v, m)
|
cache, firebase, email, unifiedpush, err := s.parsePublishParams(r, v, m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
if m.PollID != "" {
|
if m.PollID != "" {
|
||||||
m = newPollRequestMessage(t.ID, m.PollID)
|
m = newPollRequestMessage(t.ID, m.PollID)
|
||||||
}
|
}
|
||||||
if err := s.handlePublishBody(r, v, m, body, unifiedpush); err != nil {
|
if err := s.handlePublishBody(r, v, m, body, unifiedpush); err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
if m.Message == "" {
|
if m.Message == "" {
|
||||||
m.Message = emptyMessageBody
|
m.Message = emptyMessageBody
|
||||||
|
@ -459,7 +459,7 @@ func (s *Server) handlePublish(w http.ResponseWriter, r *http.Request, v *visito
|
||||||
}
|
}
|
||||||
if !delayed {
|
if !delayed {
|
||||||
if err := t.Publish(v, m); err != nil {
|
if err := t.Publish(v, m); err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
if s.firebaseClient != nil && firebase {
|
if s.firebaseClient != nil && firebase {
|
||||||
go s.sendToFirebase(v, m)
|
go s.sendToFirebase(v, m)
|
||||||
|
@ -475,17 +475,44 @@ func (s *Server) handlePublish(w http.ResponseWriter, r *http.Request, v *visito
|
||||||
}
|
}
|
||||||
if cache {
|
if cache {
|
||||||
if err := s.messageCache.AddMessage(m); err != nil {
|
if err := s.messageCache.AddMessage(m); err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
s.mu.Lock()
|
||||||
|
s.messages++
|
||||||
|
s.mu.Unlock()
|
||||||
|
return m, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) handlePublish(w http.ResponseWriter, r *http.Request, v *visitor) error {
|
||||||
|
m, err := s.handlePublishWithoutResponse(r, v)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
w.Header().Set("Access-Control-Allow-Origin", "*") // CORS, allow cross-origin requests
|
w.Header().Set("Access-Control-Allow-Origin", "*") // CORS, allow cross-origin requests
|
||||||
if err := json.NewEncoder(w).Encode(m); err != nil {
|
if err := json.NewEncoder(w).Encode(m); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
s.mu.Lock()
|
return nil
|
||||||
s.messages++
|
}
|
||||||
s.mu.Unlock()
|
|
||||||
|
func (s *Server) handlePublishMatrix(w http.ResponseWriter, r *http.Request, v *visitor) error {
|
||||||
|
pushKey := r.Header.Get("X-Matrix-Pushkey")
|
||||||
|
if pushKey == "" {
|
||||||
|
return errHTTPBadRequestMatrixMessageInvalid
|
||||||
|
}
|
||||||
|
response := &matrixResponse{
|
||||||
|
Rejected: make([]string, 0),
|
||||||
|
}
|
||||||
|
_, err := s.handlePublishWithoutResponse(r, v)
|
||||||
|
if err != nil {
|
||||||
|
response.Rejected = append(response.Rejected, pushKey)
|
||||||
|
}
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
if err := json.NewEncoder(w).Encode(response); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1301,6 +1328,10 @@ type matrixDevice struct {
|
||||||
PushKey string `json:"pushkey"`
|
PushKey string `json:"pushkey"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type matrixResponse struct {
|
||||||
|
Rejected []string `json:"rejected"`
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Server) transformMatrixJSON(next handleFunc) handleFunc {
|
func (s *Server) transformMatrixJSON(next handleFunc) handleFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request, v *visitor) error {
|
return func(w http.ResponseWriter, r *http.Request, v *visitor) error {
|
||||||
if s.config.BaseURL == "" {
|
if s.config.BaseURL == "" {
|
||||||
|
@ -1314,26 +1345,40 @@ func (s *Server) transformMatrixJSON(next handleFunc) handleFunc {
|
||||||
var m matrixMessage
|
var m matrixMessage
|
||||||
if err := json.NewDecoder(body).Decode(&m); err != nil {
|
if err := json.NewDecoder(body).Decode(&m); err != nil {
|
||||||
return errHTTPBadRequestMatrixMessageInvalid
|
return errHTTPBadRequestMatrixMessageInvalid
|
||||||
} else if m.Notification == nil || len(m.Notification.Devices) == 0 {
|
} else if m.Notification == nil || len(m.Notification.Devices) == 0 || m.Notification.Devices[0].PushKey == "" {
|
||||||
return errHTTPBadRequestMatrixMessageInvalid
|
|
||||||
} else if !strings.HasPrefix(m.Notification.Devices[0].PushKey, s.config.BaseURL+"/") {
|
|
||||||
return errHTTPBadRequestMatrixMessageInvalid
|
return errHTTPBadRequestMatrixMessageInvalid
|
||||||
}
|
}
|
||||||
u, err := url.Parse(m.Notification.Devices[0].PushKey)
|
pushKey := m.Notification.Devices[0].PushKey
|
||||||
|
if !strings.HasPrefix(pushKey, s.config.BaseURL+"/") {
|
||||||
|
return matrixError(w, pushKey, errHTTPBadRequestMatrixMessageInvalid)
|
||||||
|
}
|
||||||
|
u, err := url.Parse(pushKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errHTTPBadRequestMatrixMessageInvalid
|
return matrixError(w, pushKey, errHTTPBadRequestMatrixMessageInvalid)
|
||||||
}
|
}
|
||||||
r.URL.Path = u.Path
|
r.URL.Path = u.Path
|
||||||
r.URL.RawQuery = u.RawQuery
|
r.URL.RawQuery = u.RawQuery
|
||||||
r.RequestURI = u.RequestURI()
|
r.RequestURI = u.RequestURI()
|
||||||
r.Body = io.NopCloser(bytes.NewReader(body.PeekedBytes))
|
r.Body = io.NopCloser(bytes.NewReader(body.PeekedBytes))
|
||||||
|
r.Header.Set("X-Matrix-Pushkey", pushKey)
|
||||||
if err := next(w, r, v); err != nil {
|
if err := next(w, r, v); err != nil {
|
||||||
return nil
|
return matrixError(w, pushKey, errHTTPBadRequestMatrixMessageInvalid)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func matrixError(w http.ResponseWriter, pushKey string, err error) error {
|
||||||
|
log.Debug("Matrix message with push key %s rejected: %s", pushKey, err.Error())
|
||||||
|
response := &matrixResponse{
|
||||||
|
Rejected: []string{pushKey},
|
||||||
|
}
|
||||||
|
if err := json.NewEncoder(w).Encode(response); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue