feat: support quoted message headers
This commit is contained in:
@@ -3727,6 +3727,13 @@ func validateMessageHeaders(head types.KVMap) error {
|
||||
return types.ErrMalformed
|
||||
}
|
||||
}
|
||||
if rawReply, ok := head["x-im-reply"]; ok {
|
||||
reply, err := normalizeIMReplyHeader(rawReply)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
head["x-im-reply"] = reply
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -3779,6 +3786,74 @@ func messageHeaderString(head types.KVMap, key string) (string, bool) {
|
||||
return text, text != ""
|
||||
}
|
||||
|
||||
func normalizeIMReplyHeader(value any) (map[string]any, error) {
|
||||
var reply map[string]any
|
||||
switch typed := value.(type) {
|
||||
case map[string]any:
|
||||
reply = typed
|
||||
case types.KVMap:
|
||||
reply = map[string]any(typed)
|
||||
case string:
|
||||
if strings.TrimSpace(typed) == "" {
|
||||
return nil, types.ErrMalformed
|
||||
}
|
||||
if err := json.Unmarshal([]byte(typed), &reply); err != nil {
|
||||
return nil, types.ErrMalformed
|
||||
}
|
||||
default:
|
||||
return nil, types.ErrMalformed
|
||||
}
|
||||
if reply == nil || !validIMReplySeq(reply["seq"]) {
|
||||
return nil, types.ErrMalformed
|
||||
}
|
||||
if text, ok := reply["type"].(string); !ok || strings.TrimSpace(text) == "" {
|
||||
return nil, types.ErrMalformed
|
||||
}
|
||||
if text, ok := reply["text"].(string); !ok || strings.TrimSpace(text) == "" {
|
||||
return nil, types.ErrMalformed
|
||||
}
|
||||
if from, ok := reply["from"]; ok {
|
||||
if text, ok := from.(string); !ok || strings.TrimSpace(text) == "" {
|
||||
return nil, types.ErrMalformed
|
||||
}
|
||||
}
|
||||
return reply, nil
|
||||
}
|
||||
|
||||
func validIMReplySeq(value any) bool {
|
||||
switch typed := value.(type) {
|
||||
case json.Number:
|
||||
_, err := typed.Int64()
|
||||
return err == nil
|
||||
case float64:
|
||||
return typed > 0 && typed == float64(int64(typed))
|
||||
case float32:
|
||||
return typed > 0 && typed == float32(int64(typed))
|
||||
case int:
|
||||
return typed > 0
|
||||
case int8:
|
||||
return typed > 0
|
||||
case int16:
|
||||
return typed > 0
|
||||
case int32:
|
||||
return typed > 0
|
||||
case int64:
|
||||
return typed > 0
|
||||
case uint:
|
||||
return typed > 0
|
||||
case uint8:
|
||||
return typed > 0
|
||||
case uint16:
|
||||
return typed > 0
|
||||
case uint32:
|
||||
return typed > 0
|
||||
case uint64:
|
||||
return typed > 0
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func validIMMessageHeaderToken(value string, max int) bool {
|
||||
value = strings.TrimSpace(value)
|
||||
if value == "" || len(value) > max {
|
||||
|
||||
Reference in New Issue
Block a user