commit 23fcb61d382136146c6aa10723e41789caeb6565
parent 78a90d5d629d3aa8ca85d6c5aa4ee6dd5f76642e
Author: Martin Schanzenbach <schanzen@gnunet.org>
Date: Tue, 22 Apr 2025 14:20:13 +0200
fix etag handling and binary body parsing
Diffstat:
1 file changed, 22 insertions(+), 12 deletions(-)
diff --git a/pkg/rest/mailbox.go b/pkg/rest/mailbox.go
@@ -28,6 +28,7 @@ import (
"log"
"net/http"
"os"
+ "strconv"
"strings"
"time"
@@ -187,20 +188,20 @@ func (m *Mailbox) getMessagesResponse(w http.ResponseWriter, r *http.Request) {
func (m *Mailbox) sendMessageResponse(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
var entry InboxEntry
- var body = make ([]byte, m.MessageBodyBytes)
+ var body = make([]byte, m.MessageBodyBytes)
if r.Body == nil {
http.Error(w, "No request body", 400)
return
}
- if r.ContentLength != m.MessageBodyBytes {
+ if r.ContentLength != m.MessageBodyBytes {
w.WriteHeader(http.StatusBadRequest)
return
- }
- _, err := r.Body.Read(body)
- if err != nil {
+ }
+ _, err := r.Body.Read(body)
+ if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
- }
+ }
tx := m.Db.Where("h_mailbox = ?", vars["h_mailbox"])
// FIXME max messages from config
// FIXME unclear if this is how the API is defined
@@ -208,7 +209,7 @@ func (m *Mailbox) sendMessageResponse(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusTooManyRequests)
return
}
- err = m.Db.First(&entry, "h_mailbox = ? AND body = ?", vars["h_mailbox"], body).Error
+ err = m.Db.First(&entry, "h_mailbox = ? AND body = ?", vars["h_mailbox"], body).Error
// FIXME actual cost
cost, _ := talerutil.ParseAmount("KUDOS:1")
if err != nil {
@@ -258,15 +259,20 @@ func (m *Mailbox) deleteMessagesResponse(w http.ResponseWriter, r *http.Request)
w.WriteHeader(http.StatusInternalServerError)
return
}
- etag_expected := r.Header.Get("If-Match")
- if etag_expected == "" {
+ etag_hdr := r.Header.Get("If-Match")
+ if etag_hdr == "" {
http.Error(w, "If-Match header missing", 400)
return
}
- if strings.Contains(etag_expected, ",") {
+ if strings.Contains(etag_hdr, ",") {
http.Error(w, "If-Match contains multiple values", 400)
return
}
+ etag_expected, err := strconv.Atoi(etag_hdr)
+ if err != nil {
+ http.Error(w, "If-Match contains malformed etag number", 400)
+ return
+ }
pkey, err := gnunetutil.DecodeStringToBinary(vars["mailbox"], 32)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
@@ -303,7 +309,11 @@ func (m *Mailbox) deleteMessagesResponse(w http.ResponseWriter, r *http.Request)
w.WriteHeader(http.StatusInternalServerError)
return
}
- if len(entries) < msg.Count {
+ if entries[0].ID != uint(etag_expected) {
+ w.WriteHeader(http.StatusPreconditionFailed)
+ return
+ }
+ if len(entries) != msg.Count {
w.WriteHeader(http.StatusNotFound)
return
}
@@ -360,7 +370,7 @@ func (m *Mailbox) Initialize(cfgfile string) {
if m.Cfg.Section("mailbox").Key("production").MustBool(false) {
fmt.Println("Production mode enabled")
}
- m.MessageBodyBytes = m.Cfg.Section("mailbox").Key("message_body_bytes").MustInt64(256)
+ m.MessageBodyBytes = m.Cfg.Section("mailbox").Key("message_body_bytes").MustInt64(256)
psqlconn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable",
m.Cfg.Section("mailbox-pq").Key("host").MustString("localhost"),
m.Cfg.Section("mailbox-pq").Key("port").MustInt64(5432),