WEB 调试代理应用程序

适用于windows,mac OS和Linux

协议缓冲

背景

引用协议缓冲网站:

协议缓冲区是Google的语言中立、平台中立、可扩展的结构化数据序列化机制--想想XML,但更小、更快、更简单。你只需定义一次你想要的数据的结构化方式,然后可以使用生成的特殊源代码轻松地使用各种语言(Java,C ++或Python)在各种数据流之间来回写入和读取结构化数据。

协议缓冲序列化格式是一种二进制编码格式,不易被人阅读。由于协议缓冲消息通常通过HTTP进行交换,我们已经添加了完整的支持,以人类可读的方式查看和编辑协议缓冲消息。

Charles当前支持协议缓冲2.4.1版本,该版本在很大程度上与早期版本向后兼容。

概览

当“内容类型”标头的文档类型为application / x-protobuf或application / x-google-protobuf时,Charles识别出HTTP请求或响应包含协议缓冲消息。 在查看内容时,两个新的HTTP正文内容查看器变为可用,即Protobuf文本查看器和Protobuf结构化查看器。

为了让这些查看器能够显示消息内容,它们需要访问HTTP正文内容中包含的消息的协议缓冲描述符。Charles在内容类型中寻找desc和messageType参数,以发现FileDescriptorSet(*.desc文件)的位置和完全限定的消息类型名称,然后使用这些参数来检索和加载消息的适当描述符。协议缓冲区FileDescriptorSet可以由协议缓冲编译器(protoc)使用-o或-descriptor_set_out选项从一个*.proto文件中生成,例如protoc -oModel.desc Model.proto。

最后,HTTP主体内容可能包含一个单一的消息或一个消息列表,这些消息已经使用标准的协议缓冲长度定界格式序列化。为了确定HTTP正文是包含一个单一的消息还是一个分隔的消息列表,在内容类型中需要寻找一个可选的分隔参数。这个参数必须存在,并且其值为真实,以表示已经发送了一个分隔的消息列表。当一个分隔的消息列表被发送后,所有的消息必须是相同的消息类型。

这意味着一个完整的“内容类型”标头将看起来像:Content-Type: application/x-protobuf; desc="http://localhost/Model.desc"; messageType="com.xk72.sample.PurchaseOrder"; delimited=true。

加载FileDescriptorSet

Charles希望“内容类型”标头的desc参数包含一个有效的链接,指向协议缓冲消息的FileDescriptorSet位置。这可以是任何有效的链接,但通常是一个文件或http链接。Charles每次选择一个Protobuf查看器显示HTTP正文内容时,都会尝试检索FileDescriptorSet,这意味着desc链接直到需要时才会被解析,这在Charles记录大量协议缓冲事务时至关重要。

FileDescriptorSet缓存

通常,您仍然会使用相同的协议缓冲消息类型来获得许多事务,因此Charles会基于对HTTP链接的标准HTTP 1.1缓存和对文件链接的最后修改的时间戳来实现FileDescriptorSet的缓存。

这意味着您可以通过确保正在提供文件的网页服务器设置适当的HTTP 1.1缓存和/或验证(Last-Modified和ETag)标头来确保FileDescriptorSet加载的性能。 通过设置适当的HTTP 1.1无缓存标头,也可以有效地禁用缓存。

如果FileDescriptorSet响应中不存在HTTP缓存或验证标头,则Charles将为缓存的FileDescriptorSets计算其自己的启发式到期时间。 Charles缓存这些资源的时间长度可以在Charles的“偏好设置”->“查看器”对话框中配置,默认为5分钟。 可以将其设置为0以禁用启发式缓存。

请注意,此缓存仅用于解析desc链接,它不会以任何方式改变Charles关于所记录的HTTP事务的行为。

Protobuf文本查看器

Protobuf文本正文内容查看器显示协议缓冲区消息的默认文本表示形式。 此格式与协议缓冲区发行版随附的Java API,google.protobuf.text_format.h C ++ API或google.protobuf.text_format Python模块中的com.google.protobuf.TextFormat执行的格式相同。

显示消息的分隔列表时,每条消息都由文本定界符分隔:> --------------------------------下一页 信息 -------------------- <

Protobuf查看器

基本消息显示

Protobuf正文内容查看器显示了协议缓冲消息的树状结构视图,显示了带有所有字段和子消息的消息的完整层次结构。

在结构化查看器中,第一列显示协议缓冲区消息定义的树状结构中每个字段的定义字段名。

第二列显示字段的类型:
  • 标量字段被赋予了它们的.proto类型名称,如string, uint32, bool, sfixed64等。
  • 列举标记有完全限定类型名称,该列举名称以Enum为前缀
  • 消息类型字段被赋予了消息的完全限定类型名称。
  • 任何重复的字段都以"重复"为前缀,例如:重复字符串。
第三列显示有关字段值的信息。
  • 标量字段具有所显示值的文本表示形式
  • 列举具有所显示值的定义名称
  • 重复字段显示该字段存在的重复次数
键入的消息和重复字段可以被扩展以显示它们所封装的单个字段或重复字段。请注意,对于字符串字段,显示的不是文字字符串值,而是其编码以支持表示不可打印的字符。 所使用的编码是C代码中用于字符串文字的格式,因此换行符变为\ n,制表符变为\ t,依此类推。

可以双击任何字段以打开一个弹出对话框,其中包含该字段的值的字符串表示形式。 当字段内容太大而无法轻松显示在表中时,此功能很有用。 同样,双击消息类型字段时,将显示该字段中包含的所有消息内容,包括其所有子字段。

处理缺失的可选字段

对于协议缓冲消息,消息定义中定义为可选的字段不必包含在消息中。 在这种情况下,该字段在消息中不明确存在,它仍然具有隐含的值。 如果为消息定义中的字段定义了一个默认值,则它将是默认值,否则它将获得其类型的常规默认值,例如 数字类型为0,布尔类型为虚假,字符串类型为空字符串。

通常,这些未指定的字段是隐藏的,因为假定它们没有什么用处。 这包括隐藏具有0个重复的重复字段。 您可以将查看器配置为在Charles的“偏好设置”->“查看器”对话框中显示这些未指定的字段。

当显示未指定的字段时,它们的字段名称,类型信息和隐含或默认值在查看器中以斜体显示。

未知字段

对于协议缓冲消息,可以获取消息内容中的未知字段,这通常发生在消息定义已更改,并且包含消息定义中不再存在的包含字段的旧消息被解析时。

发生这种情况时,结构化查看器会在消息层次结构中显示一个“未知字段”子节点,可以将其展开以查看与该未知字段有关的可用信息。 因为通常无法在消息定义中找到这些字段的元数据,所以您只能看到该字段的数字标签,序列化的导线类型和序列化的值。 可能的电线类型为:
  • Varint编码
  • 32位
  • 64位
  • 长度定界
请参阅协议缓冲编码文档,了解从.proto标量类型到这些线型的映射以及如何解码序列化的值。

未知信息

在某些情况下,消息的协议缓冲描述符不可用。例如,当在“内容类型”标头中没有指定desc或messageType参数时,或者在解析desc参数中提供的链接时出现错误,就会发生这种情况。

发生这种情况时,协议缓冲消息将解析为未知消息,实际上这意味着消息中的所有字段都变为未知字段,并且仅显示我们可以从有线格式中找到的关于它们的最少信息。 查看器中还会显示导致将消息解析为未知消息的错误,希望让您可以修复引起问题的所有内容。

配置选项

协议缓冲功能的某些方面是用户可配置的。 这些选项在“偏好设置”对话框的“查看器”部分中可用。 “偏好设置”对话框是从“编辑”菜单(或Mac OS X上的Charles菜单)激活的。
  • 隐藏未指定字段 - 当选择了协议缓冲区消息中未指定的可选字段时,当该消息在结构化查看器中显示时,这些字段将被隐藏;当未选择时,未指定的字段将与它们的默认值或隐含值一起以斜体显示。
  • 缓存Protobuf描述符 - 启用缓存区中协议缓冲描述符的缓存,当不选择描述符时,描述符将不会被缓存。
  • 启发式缓存TTL - 当启用缓存时,这是用于从没有指定HTTP缓存标头的HTTP链接中检索描述符的缓存TTL或过期时间,当没有明确的HTTP缓存标头时,设置为0则永不缓存。
  • 清除缓存资源 - 点击该按钮,立即清除所有缓存的协议缓冲描述符。

对比信息

当您在结构视图或序列视图中恰好选择了两个事务时,可以使用右键单击上下文菜单中的“比较命令”比较它们的内容。

当两个事务都包含协议缓冲消息以及通常可用的标准比较查看器时,您可以选择使用Protobuf文本查看器或Protobuf结构化查看器来查看事务之间的比较。

编辑信息

当编辑一个HTTP请求的内容时,也可以使用Protobuf Text Viewer和Protobuf Structured Viewer。当您选择编辑一个HTTP请求时,如果它被识别为一个协议缓冲请求(通过具有application/x-protobuf或application/x-google-protobuf的内容类型),那么两个protobuf特定的查看器将作为编辑请求内容的选项。

Protobuf文本查看器-编辑模式

在编辑模式下,Protobuf文本查看器仅允许您编辑协议缓冲消息的可读文本。这个文本是通过使用标准的协议缓冲库API,即Java API中的com.google.protobuf.TextFormat,google.protobuf.text_format.h C++ API或thegoogle.protobuf.text_format Python模块,生成并重新解析(编辑后)成一个序列化的协议缓冲消息。

您可能需要注意安装启用的一个奇怪的地方是,如果原始消息包含未知字段,这些字段会在协议缓冲文本格式化器生成的文本中表示出来,但当试图重新解析文本时,它们会导致一个错误(*消息类型XXX没有名为YYY*的字段)。这意味着当您编辑时,需要手动从文本中删除它们。

在编辑消息的定界列表时,编辑器期望文本定界符> --------------------------------下一条消息- ------------------------------ <每个消息之间。 您可以添加或删除此定界符的实例,以从列表中添加或删除消息。

Protobuf 查看器 - 编辑模式

编辑模式下的Protobuf查看器以Protobuf结构化视图中描述的相同结构化视图显示当前消息内容。一个关键的区别是,所有定义的字段总是被显示出来,不管它们当前是否被填充。为消息定义的但当前没有填充的字段会以斜体显示。这样就可以很容易地看到消息中可能存在的字段,并为这些字段设置值。

任何标量字段的值都可以通过简单地双击值列来设置(双击行上的其他地方会打开一个包含字段值的对话框,这个功能对于查看非常大的值很有用)。标量字段可以通过右击字段并选择 "清除值 "来清除(变成一个不在信息中填充的字段)。

同样,可以通过右键单击字段并选择清除整个消息来清除消息值字段。未填充的消息值字段的处理方式与标量字段非常相似,它们以斜体显示,并以其默认或隐含的值填充。一旦未填充消息的任何子字段被明确设置,那么该消息将成为一个具体的、明确定义的值。

重复的字段可以通过右键单击字段并选择添加重复,或在右键单击现有重复时使用 "插入前 "或 "插入后 "命令添加新的重复。也有删除重复选项。