Python3 基于服务器无法解析 http 正文中的 protobuf

Python3 based server fail to parse protobuf in http body

我实现了以下基于 protobuf 的协议

message singleConfig {
  string configName = 1;
  string configValue = 2;
}

message currentConfig {
  repeated singleConfig conf = 1;
}

message HttpRequest {
  string osVersion = 1;
  string productVersion = 2;
  currentConfig config = 3;
}

在我的 http python 服务器上,我希望从 body 获得符合此协议的 http post 请求。

因此,在传入的 http post 请求中,主体内容到达并且似乎有效(我可以从文本中识别字段的值)

b'2@\n\x0611.5.1\x12\x061.0(1)\x1a.\n,\n\x08file.json\x12 ecf1c21c77a419f8f7dbfb714a806166'

这是解析 http 请求的代码。请注意 ParseFromString 接受 'bytes' 格式的输入。解析无一例外地完成,所以我认为一切顺利...

message = HttpRequest()
message.ParseFromString(data)

但是,尝试访问 protobuf 结构中的每个字段都会显示空值:

message.osVersion
''

知道解析出了什么问题吗?

我认为您传入的内容不正确:

from google.protobuf.message import DecodeError

import test_pb2


b = b"2@\n\x0611.5.1\x12\x061.0(1)\x1a.\n,\n\x08file.json\x12 ecf1c21c77a419f8f7dbfb714a806166"

m = test_pb2.HttpRequest()

try:
    m.ParseFromString(b)
except DecodeError as err:
    print(err)

产量:Error parsing message

但是:

import requests
import test_pb2


m = test_pb2.HttpRequest()
m.osVersion="osVersion"
m.productVersion="productVersion"

c = m.config.conf.add()
c.configName="configName"
c.configValue="configValue"

print(m)

s = m.SerializeToString()

print(s)
print(s.hex())

url = "https://en22tibjys2gf.x.pipedream.net"

requests.post(url,data=s)

产量:

osVersion: "osVersion"
productVersion: "productVersion"
config {
  conf {
    configName: "configName"
    configValue: "configValue"
  }
}

b'\n\tosVersion\x12\x0eproductVersion\x1a\x1b\n\x19\n\nconfigName\x12\x0bconfigValue'
0a096f7356657273696f6e120e70726f6475637456657273696f6e1a1b0a190a0a636f6e6669674e616d65120b636f6e66696756616c7565

而且,如果您检查 request.bin URL,您会看到原始主体是:

0000000 0a 09 6f 73 56 65 72 73 69 6f 6e 12 0e 70 72 6f 
0000010 64 75 63 74 56 65 72 73 69 6f 6e 1a 1b 0a 19 0a 
0000020 0a 63 6f 6e 66 69 67 4e 61 6d 65 12 0b 63 6f 6e 
0000030 66 69 67 56 61 6c 75 65 

发送的十六进制 (0a096f7...7565) 与 request.bin 服务收到的相匹配。

您也可以将 (0a096f7...) 粘贴到 Marc Gravell 的 protobuf decoder