swagger-api / swagger-api/swagger-codegen
Generated Java APIs incorrectly encode commas in certain query parameters
Nobody has claimed this yet.
- Dominant language
- Mustache
- Stars
- 17.8k
- Forks
- 6k
- PR merge metrics
- No merged PRs in 30d
Description
Description
For a query parameter of type "array" and collectionFormat "csv", the Java generated API percent-encodes the commas that separate the individual values. This is incorrect behaviour, as the commas are used as delimiters, not data, and should not be encoded.
For example, the following:
/test?param=a,b,c
becomes:
/test?param=a%2Cb%2Cc
Swagger-codegen version
2.2.0
Swagger declaration file content or url
The following Swagger spec demonstrates this behaviour:
{
"swagger": "2.0",
"info": {
"title": "test spec",
"version": "1.0"
},
"parameters": {
"testParam": {
"name": "test",
"in": "query",
"type": "array",
"items": {
"type": "string"
},
"collectionFormat": "csv"
}
},
"paths": {
"/test": {
"get": {
"description": "test get",
"parameters": [
{
"$ref": "#/parameters/testParam"
}
],
"references": {
}
}
}
}
}
Command line used for generation
C:\Users\mkourlas\Downloads\swagger-codegen-2.2.0>java -jar modules\swagger-code
gen-cli\target\swagger-codegen-cli.jar generate -Dlibrary=jersey1 -i swagger.jso
n -l java -o test\java
Steps to reproduce
- Generate and build the Java API for the above specification.
- Create a new DefaultApi instance.
- Call the
testGetfunction with several strings aListpassed to thetestparameter. - The API will send an HTTP request with a URI looking like the following:
/test?test=string1%2Cstring2%2Cstring3
This should instead be
/test?test=string1,string2,string3
Suggest a Fix
This is caused by the following parts of the generated code:
public void testGet(List<String> test) throws ApiException {
[...]
// query params
List<Pair> localVarQueryParams = new ArrayList<Pair>();
[...]
localVarQueryParams.addAll(apiClient.parameterToPairs("csv", "test", test));
[...]
apiClient.invokeAPI(localVarPath, "GET", localVarQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAccept, localVarContentType, localVarAuthNames, null);
}
private String buildUrl(String path, List<Pair> queryParams) {
final StringBuilder url = new StringBuilder();
url.append(basePath).append(path);
if (queryParams != null && !queryParams.isEmpty()) {
// support (constant) query string in `path`, e.g. "/posts?draft=1"
String prefix = path.contains("?") ? "&" : "?";
for (Pair param : queryParams) {
if (param.getValue() != null) {
if (prefix != null) {
url.append(prefix);
prefix = null;
} else {
url.append("&");
}
String value = parameterToString(param.getValue());
url.append(escapeString(param.getName())).append("=").append(escapeString(value));
}
}
}
}
The generated API can't just escape the entire parameter value in buildUrl. It should be escaping the individual comma-separated values as part of the parameterToPairs function while leaving the commas alone, and then simply appending the parameter value to the URL without escaping in buildUrl.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the generated Java client flow shown in the issue: parameterToPairs and ApiClient buildUrl, then reproduce the request using the supplied Swagger declaration and generation command. Done means csv query parameters preserve commas as delimiters while individual values remain correctly escaped.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- api
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100