【问题标题】:Binary data in body is corrupted when sending HTTP POST in JMeter在 JMeter 中发送 HTTP POST 时,正文中的二进制数据已损坏
【发布时间】:2021-05-24 08:26:46
【问题描述】:

我有一个带有 HTTP POST 端点的本地 Web 应用程序。 此端点接收从 SendGrid 发送的电子邮件。

我已将上一封电子邮件的正文保存为 requestBody.bin。

我正在尝试使用 JMeter 复制此 HTTP POST 请求。

我有这个 Beanshell 预处理器脚本:

FileInputStream in = new FileInputStream("C:\\Projects\\centaurjmeter\\src\\InboundEmails\\requestBody.bin");
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buffer = new byte[999024]; //Value of Content-Length from when I sent the actual email. So this should be more than enough just for the HTTP POST body.
for (int i; (i = in.read(buffer)) != -1; ) {
    bos.write(buffer, 0, i);
}
in.close();
byte[] requestBody = bos.toByteArray();
bos.close();

vars.put("requestBody", new String(requestBody, "ISO-8859-1"));

我在 HTTP POST 请求的正文中使用 ${requestBody}

这就是我的 JMeter 测试的样子:

在我的 HTTP POST 操作方法中,我将电子邮件的附件保存到文件中。

pdf 文件似乎略有损坏,每页仅显示部分文本。 .png 文件甚至无法打开。

我尝试过使用:

vars.put("requestBody", new String(requestBody));
vars.put("requestBody", new String(requestBody, "Windows-1252")); //ANSI
vars.put("requestBody", new String(requestBody, "ISO-8859-1")); //default encoding

但它们都不起作用。 “ISO-8859-1”导致的损坏最少,因为至少有一些文本出现在 pdf 中(但 .png 文件根本不起作用)。

我不能使用 HTTP 原始请求采样器,因为它不适用于 https。

如何从 requestBody.bin 获取字节并将它们正确发送到我的 HTTP POST 正文中?

更新

我阅读了https://stackoverflow.com/a/41892324/2063755 并尝试在“文件上传”选项卡中将 requestBody.bin 作为文件发送,但我得到的结果与使用 Beanshell 预处理器脚本相同。

更新

上面的链接实际上确实帮助我解决了这个问题。 我只需要添加这个额外的TE 标题:

【问题讨论】:

    标签: http encoding jmeter beanshell jmeter-5.0


    【解决方案1】:

    您需要确保在所有地方都应用相同的编码,我建议您坚持使用UTF-8

    1. 运行提供file.encoding=UTF-8 property 的JMeter,它可以添加到system.properties 文件中(位于JMeter 安装的“bin”文件夹中)

    2. Since JMeter 3.1 you should be using JSR223 Test Elements and Groovy language 用于编写脚本,因此您可以直接在 HTTP 请求采样器的“正文数据”选项卡中使用以下 __groovy() function

      ${__groovy(new File('C:\\Projects\\centaurjmeter\\src\\InboundEmails\\requestBody.bin').getText('UTF-8'),)}
      

      更多关于 JMeter 中 Groovy 脚本的信息:Apache Groovy - Why and How You Should Use It

    3. 假设一切顺利,您的“本地网络应用程序”应该会看到相同的文件,可以使用像 Wireshark 这样的第 3 方嗅探器工具对其进行双重检查。确保在您的应用中也使用 UTF-8 解析文件。

    【讨论】:

    • 您好 Dmitri T,感谢您的回答。你是什​​么意思使用 UTF-8 来解析文件? requestBody.bin 包含具有 multipart/form-data 内容类型的 HTTP POST 正文。然后,当 Web 应用程序接收到附件时,将读取附件并使用以下命令将其保存到 blob 存储中: var emailDataProvider = new InboundEmailMultipartStreamProvider(_storageConfig, hasInvalidSize);等待 Request.Content.ReadAsMultipartAsync(emailDataProvider);你是说我需要在保存附件时指定 UTF-8 吗?
    • 我收到了这个错误:Caused by: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: Script4.groovy: 1: Missing ')' @ line 1, column 10. new File('C:\Projects\centaurjmeter\src\InboundEmails\requestBody.bin').getText('UTF-8') 我已经确定我使用了你的代码行。
    • 很奇怪,将其更改为${__groovy(new File('C:/Projects/centaurjmeter/src/InboundEmails/requestBody.bin').getText('UTF-8'),)} 修复了它。
    • UTF-8 不起作用。我尝试了 Windows-1252 (ANSI),因为当我查看 requestBody.bin 文件时记事本显示 ANSI,但它也不起作用(两者都只显示空白 pdf)。然后我尝试了 ISO-8859-1,这显然是 HTTP 中的默认编码,它创建了一个带有一些可见文本的 pdf,但 .png 文件已损坏。
    • 我不认为 UTF-8 会起作用,因为它是二进制数据。原因是 UTF-8 需要一定的位组合。例如第 2、3、4 个字节的前两位必须为“10”,因此“01”等将是无效的 UTF-8。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-18
    • 1970-01-01
    • 1970-01-01
    • 2011-12-13
    • 1970-01-01
    • 1970-01-01
    • 2019-07-21
    相关资源
    最近更新 更多