GitHub user squarebracket opened a pull request:
https://github.com/apache/jmeter/pull/261
Clear querystring args on each call to setPath
I use the `HTTPSamplerBase` class as a base class for an HTTP sampler
class. I recently found a bug with the way handling of query strings is
implemented. Specifically, each call to `setPath()` on the sampler adds the
query string arguments to the current set of query string arguments. That means
calling `setPath()` multiple times accumulates all the query string arguments.
From the source code:
```java
//
src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java:453
public void setPath(String path, String contentEncoding) {
boolean fullUrl = path.startsWith(HTTP_PREFIX) ||
path.startsWith(HTTPS_PREFIX);
boolean getOrDelete = HTTPConstants.GET.equals(getMethod()) ||
HTTPConstants.DELETE.equals(getMethod());
if (!fullUrl && getOrDelete) {
int index = path.indexOf(QRY_PFX);
if (index > -1) {
setProperty(PATH, path.substring(0, index));
// Parse the arguments in querystring, assuming specified
encoding for values
parseArguments(path.substring(index + 1), contentEncoding);
} else {
setProperty(PATH, path);
}
} else {
setProperty(PATH, path);
}
}
```
As you can see, if there's a query string, it calls {{parseArguments}} to
set the query string. That function just adds every argument to the sampler's
arguments, whether it exists or not:
```java
//
src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java:1090
public void parseArguments(String queryString, String contentEncoding) {
String[] args = JOrphanUtils.split(queryString, QRY_SEP);
final boolean isDebug = log.isDebugEnabled();
for (String arg : args) {
if (isDebug) {
log.debug("Arg: " + arg);
}
// need to handle four cases:
// - string contains name=value
// - string contains name=
// - string contains name
// - empty string
String metaData; // records the existence of an equal sign
String name;
String value;
int length = arg.length();
int endOfNameIndex = arg.indexOf(ARG_VAL_SEP);
if (endOfNameIndex != -1) {// is there a separator?
// case of name=value, name=
metaData = ARG_VAL_SEP;
name = arg.substring(0, endOfNameIndex);
value = arg.substring(endOfNameIndex + 1, length);
} else {
metaData = "";
name = arg;
value = "";
}
if (name.length() > 0) {
if (isDebug) {
log.debug("Name: " + name + " Value: " + value + "
Metadata: " + metaData);
}
// If we know the encoding, we can decode the argument
value,
// to make it easier to read for the user
if (!StringUtils.isEmpty(contentEncoding)) {
addEncodedArgument(name, value, metaData,
contentEncoding);
} else {
// If we do not know the encoding, we just use the
encoded value
// The browser has already done the encoding, so save
the values as is
addNonEncodedArgument(name, value, metaData);
}
}
}
}
```
My solution is very simple -- just clear the arguments before the call to
`parseArguments`:
```java
//
src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java:453
public void setPath(String path, String contentEncoding) {
boolean fullUrl = path.startsWith(HTTP_PREFIX) ||
path.startsWith(HTTPS_PREFIX);
boolean getOrDelete = HTTPConstants.GET.equals(getMethod()) ||
HTTPConstants.DELETE.equals(getMethod());
if (!fullUrl && getOrDelete) {
int index = path.indexOf(QRY_PFX);
if (index > -1) {
setProperty(PATH, path.substring(0, index));
// Zero out the arguments, so we don't include query
strings from previous calls
getArguments().clear();
// Parse the arguments in querystring, assuming specified
encoding for values
parseArguments(path.substring(index + 1), contentEncoding);
} else {
setProperty(PATH, path);
}
} else {
setProperty(PATH, path);
}
}
```
You can merge this pull request into a Git repository by running:
$ git pull https://github.com/squarebracket/jmeter fix-httpsamplerbase
Alternatively you can review and apply these changes as the patch at:
https://github.com/apache/jmeter/pull/261.patch
To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:
This closes #261
----
commit ca84f7faac6df4ee73259c5b8ba22676f9361895
Author: Chuck Wilson <[email protected]>
Date: 2017-02-01T21:36:06Z
Clear querystring args on each call to setPath()
----
---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at [email protected] or file a JIRA ticket
with INFRA.
---