I'm having trouble with sending an HTTP POST request with a parameter that has a value that includes a whitespace. JMeter replaces every " " and "%20" with a "+".
It seems to have something to do with the HTTP implementation as it occurs only when using HttpClient3.1 and HttpClient4. The Java implementation sends whitespaces encoded and decoded. At least according to the results tree listener.
I need to be able to use the HttpClient4 however since it seems to be the only one that I can get NTLM authorization to work. Any pointers on where to look for a resolution are appreciated.
Update: found a way to send whitespaces with the help from Richard Friedman. I ended up editing the HTTPHC4Impl.java source code which was responsible for calling the encoding.
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);
While this was quick and dirty, it did accomplish the task. Basically the plus signs are replaced to a temporary value before decoding as to not get mistaken for whitespaces. Then after encoding plus signs get converted to %20 and the temporary plus signs are encoded to %2B.