[Rust Server] fix handling of special characters in path param names (#4897)

* test for hyphen in path parameter name

* fix handling of hyphens in path parameter names
This commit is contained in:
aandyl
2020-01-16 23:44:23 -08:00
committed by William Cheng
parent f48325ac45
commit 67d23fcf7e
12 changed files with 283 additions and 47 deletions

View File

@@ -552,6 +552,16 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
Map<String, Schema> definitions = ModelUtils.getSchemas(this.openAPI);
CodegenOperation op = super.fromOperation(path, httpMethod, operation, servers);
String pathFormatString = op.path;
for (CodegenParameter param : op.pathParams) {
// Replace {baseName} with {paramName} for format string
String paramSearch = "{" + param.baseName + "}";
String paramReplace = "{" + param.paramName + "}";
pathFormatString = pathFormatString.replace(paramSearch, paramReplace);
}
op.vendorExtensions.put("pathFormatString", pathFormatString);
// The Rust code will need to contain a series of regular expressions.
// For performance, we'll construct these at start-of-day and re-use
// them. That means we need labels for them.
@@ -584,10 +594,18 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
}
// Don't prefix with '^' so that the templates can put the
// basePath on the front.
pathSetEntry.put("pathRegEx", op.path.replace("{", "(?P<").replace("}", ">[^/?#]*)") + "$");
String pathRegEx = op.path;
for (CodegenParameter param : op.pathParams) {
// Replace {baseName} with (?P<paramName>[^/?#]*) for regex
String paramSearch = "{" + param.baseName + "}";
String paramReplace = "(?P<" + param.paramName + ">[^/?#]*)";
pathRegEx = pathRegEx.replace(paramSearch, paramReplace);
}
pathSetEntry.put("pathRegEx", pathRegEx + "$");
pathSetMap.put(pathId, pathSetEntry);
}
op.vendorExtensions.put("operation_id", underscore(op.operationId));
op.vendorExtensions.put("uppercase_operation_id", underscore(op.operationId).toUpperCase(Locale.ROOT));
op.vendorExtensions.put("path", op.path.replace("{", ":").replace("}", ""));

View File

@@ -262,8 +262,8 @@ impl<F, C> Api<C> for Client<F> where
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}
fn {{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}(&self{{#allParams}}, param_{{{paramName}}}: {{^required}}Option<{{/required}}{{#isListContainer}}&{{/isListContainer}}{{{dataType}}}{{^required}}>{{/required}}{{/allParams}}, context: &C) -> Box<dyn Future<Item={{{operationId}}}Response, Error=ApiError>> {
let mut uri = format!(
"{}{{{basePathWithoutHost}}}{{path}}",
self.base_path{{#pathParams}}, {{{baseName}}}=utf8_percent_encode(&param_{{{paramName}}}.to_string(), ID_ENCODE_SET){{/pathParams}}
"{}{{{basePathWithoutHost}}}{{#vendorExtensions}}{{pathFormatString}}{{/vendorExtensions}}",
self.base_path{{#pathParams}}, {{{paramName}}}=utf8_percent_encode(&param_{{{paramName}}}.to_string(), ID_ENCODE_SET){{/pathParams}}
);
let mut query_string = self::url::form_urlencoded::Serializer::new("".to_owned());

View File

@@ -195,12 +195,12 @@ where
{{/hasPathParams}}
{{/vendorExtensions}}
{{#pathParams}}
let param_{{{paramName}}} = match percent_encoding::percent_decode(path_params["{{{baseName}}}"].as_bytes()).decode_utf8() {
let param_{{{paramName}}} = match percent_encoding::percent_decode(path_params["{{{paramName}}}"].as_bytes()).decode_utf8() {
Ok(param_{{{paramName}}}) => match param_{{{paramName}}}.parse::<{{{dataType}}}>() {
Ok(param_{{{paramName}}}) => param_{{{paramName}}},
Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse path parameter {{{baseName}}}: {:?}", e)))),
},
Err(_) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["{{{baseName}}}"]))))
Err(_) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["{{{paramName}}}"]))))
};
{{/pathParams}}
{{#headerParams}}

View File

@@ -946,6 +946,25 @@ paths:
description: successful operation
schema:
$ref: '#/definitions/Client'
/fake/hyphenParam/{hyphen-param}:
get:
tags:
- fake
description: To test hyphen in path parameter name
operationId: hyphenParam
consumes:
- application/json
produces:
- application/json
parameters:
- name: hyphen-param
in: path
description: Parameter with hyphen in name
required: true
type: string
responses:
200:
description: Success
securityDefinitions:
petstore_auth:
type: oauth2