使用 JMeter 在 HTTP POST 中发送转义空格

Sending escaped whitespaces in HTTP POST with JMeter

我在发送 HTTP POST 请求时遇到问题,该请求的参数值包含空格。 JMeter 将每个“”和“%20”替换为“+”。

这似乎与HTTP 实现有关,因为它仅在使用HttpClient3.1 和HttpClient4 时出现。 Java 实现发送经过编码和解码的空格。至少根据结果树监听。

我需要能够使用 HttpClient4,因为它似乎是我唯一可以获得 NTLM 授权的工具。任何关于在哪里寻找解决方案的指示都将受到赞赏。

更新:在 Richard Friedman 的帮助下找到了发送空格的方法。我最终编辑了负责调用编码的 HTTPHC4Impl.java 源代码。

while (args.hasNext()) {
    HTTPArgument arg = (HTTPArgument) args.next().getObjectValue();
    // The HTTPClient always urlencodes both name and value,
    // so if the argument is already encoded, we have to decode
    // it before adding it to the post request
    String parameterName = arg.getName();
    if (arg.isSkippable(parameterName)){
        continue;
    }
    String parameterValue = arg.getValue();
    if(!arg.isAlwaysEncoded()) {
        // The value is already encoded by the user
        // Must decode the value now, so that when the
        // httpclient encodes it, we end up with the same value
        // as the user had entered.
        parameterName = parameterName.replaceAll("\+", "__tempplus__");
        parameterValue = parameterValue.replaceAll("\+", "__tempplus__");
        parameterName = URLDecoder.decode(parameterName, urlContentEncoding);
        parameterValue = URLDecoder.decode(parameterValue, urlContentEncoding);
    }
    // Add the parameter, httpclient will urlencode it
    nvps.add(new BasicNameValuePair(parameterName, parameterValue));
}
//UrlEncodedFormEntity entity = new UrlEncodedFormEntity(nvps, urlContentEncoding);
StringBuilder asdf = new StringBuilder();
for (NameValuePair pair : nvps) {
    String name = URLEncoder.encode(pair.getName(), urlContentEncoding);
    name = name.replaceAll("\+", "%20");
    name = name.replaceAll("__tempplus__", "%2B");
    String value = URLEncoder.encode(pair.getValue(), urlContentEncoding);
    value = value.replaceAll("\+", "%20");
    value = value.replaceAll("__tempplus__", "%2B");
    asdf.append(name);
    asdf.append("=");
    asdf.append(value);
    asdf.append("&");
}
asdf.deleteCharAt(asdf.length()-1);
StringEntity entity = new StringEntity(asdf.toString(), urlContentEncoding);
post.setEntity(entity);

虽然这既快速又肮脏,但它确实完成了任务。基本上,加号在解码之前被替换为临时值,以免被误认为是空格。然后在编码加号转换为 %20 并将临时加号编码为 %2B 之后。

我在示例测试中看到了相同的行为。如果你想控制它们是否被编码并且仍然使用 HTTPClient,你必须检查 - 'Use multipart/form-data for POST'。

在 POST 期间通过 Java 实现,您可以控制是否对参数进行编码。但是,HTTPClient 将始终对不是多部分的 POST 的参数进行编码。

这在 HTTPHC4Impl.java 的源代码中有解释,它是 HTTP 请求 HTTPClient4 的采样器。

    while (args.hasNext()) {
    HTTPArgument arg = (HTTPArgument) args.next().getObjectValue();
    // The HTTPClient always urlencodes both name and value,
    // so if the argument is already encoded, we have to decode
    // it before adding it to the post request
    String parameterName = arg.getName();
    if (arg.isSkippable(parameterName)){
        continue;
    }
    String parameterValue = arg.getValue();
    if(!arg.isAlwaysEncoded()) {
        // The value is already encoded by the user
        // Must decode the value now, so that when the
        // httpclient encodes it, we end up with the same value
        // as the user had entered.
        parameterName = URLDecoder.decode(parameterName, urlContentEncoding);
        parameterValue = URLDecoder.decode(parameterValue, urlContentEncoding);
    }
    // Add the parameter, httpclient will urlencode it
    nvps.add(new BasicNameValuePair(parameterName, parameterValue));
}

您可以从此负载测试中获取 JMX File

如果您通过Body Data 传入数据,您可以控制内容并导致数据不被编码。

这是更新后的 JMX File and Test Results

  • 一个带参数的 HTTP 请求,显示问题
  • 第二个请求使用正文数据

您可以查看结果树以查看它在未编码的情况下传递数据。