JMeter中__digest函数如何按RFC3230规范引用消息体生成digest头
按RFC3230规范在JMeter中配置Digest请求头的操作方法
核心规范对齐逻辑
RFC3230对Digest请求头的格式要求非常明确:头值为Digest: <标准算法标识>=<对*原始请求体*计算后得到的Base64编码摘要值>,网上流传的直接把__digest输出的十六进制串当摘要值的写法,完全不符合规范,直接用大概率通不过服务端校验。
分步操作流程
- 第一步:提前获取和实际发送完全一致的原始请求体
不能直接在HTTP Header Manager中直接引用请求体相关变量,因为Header组件的执行时机早于请求体参数的渲染流程,直接引用大概率拿到空值、旧值或者被转义的内容。
需要在目标HTTP请求下添加JSR223 PreProcessor,在其中把最终要发送的原始请求体内容存为独立变量,参考代码:
注意这里取到的内容必须和最终通过网络发出去的字节逐字符一致,不能有额外的前后换行、编码转换或者参数截断,否则计算出的摘要会和服务端校验的结果不匹配。// 取当前请求实际渲染完成、即将发送的请求体字符串 def finalRequestBody = sampler.getRawPostBodyAsString() // 存为自定义变量,供后续Digest计算使用 vars.put("raw_send_body", finalRequestBody) - 第二步:正确配置__digest函数参数
你参考的${__digest(MD5,${message-body},,,)}默认输出小写十六进制格式的摘要,不符合RFC3230要求的“对摘要原始二进制值做Base64编码”的规则。
需要调整函数参数:把__digest控制输出格式的参数设为false,让函数输出原始摘要的二进制字符串而非十六进制字符,再外层套一层__base64Encode函数做编码。 - 第三步:拼接符合规范的请求头
在HTTP Header Manager中添加名称为Digest的请求头,值按照格式拼接即可,MD5算法的完整引用示例为:Digest: MD5=${__base64Encode(${__digest(MD5,${raw_send_body},,false,)}),}
常见踩坑提醒
- 算法标识必须和RFC3230的官方注册名完全一致,比如使用SHA-256算法时要写全
SHA-256,不要简写为SHA256,否则服务端会无法识别算法类型 - 不要对计算摘要用的请求体内容做额外的格式化、压缩、转义操作,任何和实际发送内容的差异都会导致摘要校验失败
- 如果请求开启了Chunked分块传输,要确保PreProcessor取的是拼接完成的完整请求体内容,不是单块的片段
内容的提问来源于stack exchange,提问作者Kamil
相关产品推荐
相关产品推荐

