|
@@ -21,36 +21,30 @@ const (
|
|
|
mongoSectionKindDocs = 1 // Section 1: Document sequence (actual data)
|
|
mongoSectionKindDocs = 1 // Section 1: Document sequence (actual data)
|
|
|
|
|
|
|
|
// 默认操作类型
|
|
// 默认操作类型
|
|
|
- unknownOpType = "unknown"
|
|
|
|
|
invalidDataResult = "<truncated>"
|
|
invalidDataResult = "<truncated>"
|
|
|
- separator = "|"
|
|
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
// ParseMongo 解析 MongoDB Wire Protocol (OP_MSG) 的 payload
|
|
// ParseMongo 解析 MongoDB Wire Protocol (OP_MSG) 的 payload
|
|
|
// 返回格式:opType|section0 或 opType|section0@[section1]
|
|
// 返回格式:opType|section0 或 opType|section0@[section1]
|
|
|
func ParseMongo(payload []byte) string {
|
|
func ParseMongo(payload []byte) string {
|
|
|
|
|
|
|
|
- //unknown|<truncated>
|
|
|
|
|
- invalidResult := fmt.Sprintf("%s%s%s", unknownOpType, separator, invalidDataResult)
|
|
|
|
|
-
|
|
|
|
|
minLength := mongoHeaderLength + mongoFlagBitsLength + mongoSectionKindLength + 4 // +4 for BSON length
|
|
minLength := mongoHeaderLength + mongoFlagBitsLength + mongoSectionKindLength + 4 // +4 for BSON length
|
|
|
if len(payload) < minLength {
|
|
if len(payload) < minLength {
|
|
|
- return invalidResult
|
|
|
|
|
|
|
+ return invalidDataResult
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 验证是否为 OP_MSG
|
|
// 验证是否为 OP_MSG
|
|
|
opCode := binary.LittleEndian.Uint32(payload[mongoOpCodeOffset:])
|
|
opCode := binary.LittleEndian.Uint32(payload[mongoOpCodeOffset:])
|
|
|
if opCode != MongoOpMSG {
|
|
if opCode != MongoOpMSG {
|
|
|
- return invalidResult
|
|
|
|
|
|
|
+ return invalidDataResult
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 跳过 header (16 bytes) + flag_bits (4 bytes)
|
|
// 跳过 header (16 bytes) + flag_bits (4 bytes)
|
|
|
offset := mongoHeaderLength + mongoFlagBitsLength
|
|
offset := mongoHeaderLength + mongoFlagBitsLength
|
|
|
|
|
|
|
|
- var section0 string // 命令元数据
|
|
|
|
|
- var section0Raw []byte // Section 0 原始 BSON 数据(用于提取操作类型)
|
|
|
|
|
- var section1 string // 文档数据
|
|
|
|
|
- opType := unknownOpType // 操作类型(insert/update/find等),默认为 unknown
|
|
|
|
|
|
|
+ var section0 string // 命令元数据
|
|
|
|
|
+ var section0Raw []byte // Section 0 原始 BSON 数据(用于提取操作类型)
|
|
|
|
|
+ var section1 string // 文档数据
|
|
|
|
|
|
|
|
// 解析所有 sections
|
|
// 解析所有 sections
|
|
|
for offset < len(payload) {
|
|
for offset < len(payload) {
|
|
@@ -74,11 +68,11 @@ func ParseMongo(payload []byte) string {
|
|
|
|
|
|
|
|
// Section 0 是必需的,解析失败则提前返回
|
|
// Section 0 是必需的,解析失败则提前返回
|
|
|
if section0 == "" {
|
|
if section0 == "" {
|
|
|
- return invalidResult
|
|
|
|
|
|
|
+ return invalidDataResult
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 提取操作类型(BSON 文档的第一个字段名)
|
|
|
|
|
- opType = extractMongoOpType(section0Raw)
|
|
|
|
|
|
|
+ /*// 提取操作类型(BSON 文档的第一个字段名)
|
|
|
|
|
+ cmd = extractMongoOpType(section0Raw)*/
|
|
|
|
|
|
|
|
offset += bsonLen
|
|
offset += bsonLen
|
|
|
|
|
|
|
@@ -106,7 +100,7 @@ func ParseMongo(payload []byte) string {
|
|
|
identifierEnd = i + 1
|
|
identifierEnd = i + 1
|
|
|
break
|
|
break
|
|
|
}
|
|
}
|
|
|
- if i > 100 { // 防止无限循环
|
|
|
|
|
|
|
+ if i > 20 { // 防止无限循环,identifier一般不会超过20个字节
|
|
|
break
|
|
break
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -128,8 +122,8 @@ func ParseMongo(payload []byte) string {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 构建返回结果 格式:
|
|
// 构建返回结果 格式:
|
|
|
- // - 有 section1: "opType|section0@[section1]" (例: insert|{"insert":"users"}@[{"name":"Alice"}, ...])
|
|
|
|
|
- // - 无 section1: "opType|section0" (例: find|{"find":"users","filter":{...}})
|
|
|
|
|
|
|
+ // - 有 section1: "section0@[section1]" (例: {"insert":"users"}@[{"name":"Alice"}, ...])
|
|
|
|
|
+ // - 无 section1: "section0" (例: {"find":"users","filter":{...}})
|
|
|
var baseResult string
|
|
var baseResult string
|
|
|
if section1 != "" {
|
|
if section1 != "" {
|
|
|
// 同时包含命令和文档(批量操作)
|
|
// 同时包含命令和文档(批量操作)
|
|
@@ -139,13 +133,12 @@ func ParseMongo(payload []byte) string {
|
|
|
baseResult = section0
|
|
baseResult = section0
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 拼接操作类型并返回
|
|
|
|
|
- return fmt.Sprintf("%s%s%s", opType, separator, baseResult)
|
|
|
|
|
|
|
+ return baseResult
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// extractMongoOpType 从 Section 0 的 BSON 文档中提取操作类型
|
|
// extractMongoOpType 从 Section 0 的 BSON 文档中提取操作类型
|
|
|
// BSON 格式:[4 bytes: length] + [1 byte: type] + [cstring: field name] + [value] + ... + [0x00]
|
|
// BSON 格式:[4 bytes: length] + [1 byte: type] + [cstring: field name] + [value] + ... + [0x00]
|
|
|
-func extractMongoOpType(bsonData []byte) string {
|
|
|
|
|
|
|
+/*func extractMongoOpType(bsonData []byte) string {
|
|
|
if len(bsonData) < 5 {
|
|
if len(bsonData) < 5 {
|
|
|
return ""
|
|
return ""
|
|
|
}
|
|
}
|
|
@@ -179,7 +172,7 @@ func extractMongoOpType(bsonData []byte) string {
|
|
|
return ""
|
|
return ""
|
|
|
}
|
|
}
|
|
|
return opType
|
|
return opType
|
|
|
-}
|
|
|
|
|
|
|
+}*/
|
|
|
|
|
|
|
|
// parseBSONDocuments 解析连续的 BSON 文档
|
|
// parseBSONDocuments 解析连续的 BSON 文档
|
|
|
func parseBSONDocuments(data []byte) []string {
|
|
func parseBSONDocuments(data []byte) []string {
|