diff --git a/hedera-mirror-rest/__tests__/requestHandler.test.js b/hedera-mirror-rest/__tests__/requestHandler.test.js index de199de3f35..829e571bfed 100644 --- a/hedera-mirror-rest/__tests__/requestHandler.test.js +++ b/hedera-mirror-rest/__tests__/requestHandler.test.js @@ -51,4 +51,15 @@ describe('qs tests', () => { 'token.id': ['2', '8', 'gt:4', 'gte:6', '10'], }); }); + + test('requestQueryParser for single lowercased query param values', () => { + const val = requestQueryParser('order=ASC&result=SUCCESS'); + expect(val.order).toStrictEqual('asc'); + expect(val.result).toStrictEqual('success'); + }); + + test('requestQueryParser for multiple lowercased query param keys and values', () => { + const val = requestQueryParser('order=ASC&ORder=ASC'); + expect(val.order).toStrictEqual(['asc', 'asc']); + }); }); diff --git a/hedera-mirror-rest/__tests__/specs/transactions/all-params.json b/hedera-mirror-rest/__tests__/specs/transactions/all-params.json index c8b5d9e749a..2d66bf97d4a 100644 --- a/hedera-mirror-rest/__tests__/specs/transactions/all-params.json +++ b/hedera-mirror-rest/__tests__/specs/transactions/all-params.json @@ -74,8 +74,8 @@ { "urls": [ "/api/v1/transactions?timestamp=1565779209.711927001&account.id=0.0.9&type=credit&result=success&order=asc", - "/api/v1/transactions?timestamp=1565779209.711927001&account.id=0.0.9&type=credit&result=SUCCESS&order=ASC", - "/api/v1/transactions?timestamp=1565779209.711927001&account.id=0.0.9&type=credit&result=SucCess&order=AsC" + "/api/v1/transactions?timestamp=1565779209.711927001&account.id=0.0.9&type=credit&result=SUCCESS&order=ASC&result=SUCCESS&order=ASC", + "/api/v1/transactions?timestamp=1565779209.711927001&account.id=0.0.9&type=credit&result=SucCess&order=AsC&Result=SUCCESS&oRder=ASC" ], "responseStatus": 200, "responseJson": { diff --git a/hedera-mirror-rest/middleware/requestHandler.js b/hedera-mirror-rest/middleware/requestHandler.js index 6dfac144518..8a3e5c27872 100644 --- a/hedera-mirror-rest/middleware/requestHandler.js +++ b/hedera-mirror-rest/middleware/requestHandler.js @@ -35,7 +35,7 @@ const requestLogger = async (req, res, next) => { }; /** - * Manage request query params to support case insensitive keys + * Manage request query params to support case insensitive keys and some values (queryCanonicalizationMap above). * Express default query parser uses qs, other option is querystring, both are case sensitive * Parse using default qs logic and use to populate a new map in which all keys are lowercased * @param queryString @@ -62,8 +62,7 @@ const requestQueryParser = (queryString) => { const caseInsensitiveQueryString = {}; for (const [key, value] of Object.entries(parsedQueryString)) { const lowerKey = key.toLowerCase(); - const canonicalizationFunc = queryCanonicalizationMap[lowerKey]; - const canonicalValue = canonicalizationFunc ? canonicalizationFunc(value) : value; + const canonicalValue = canonicalizeValue(lowerKey, value); if (lowerKey in caseInsensitiveQueryString) { // handle repeated values, merge into an array caseInsensitiveQueryString[lowerKey] = merge(caseInsensitiveQueryString[lowerKey], canonicalValue); @@ -75,4 +74,13 @@ const requestQueryParser = (queryString) => { return caseInsensitiveQueryString; }; +const canonicalizeValue = (key, value) => { + const canonicalizationFunc = queryCanonicalizationMap[key]; + if (canonicalizationFunc === undefined) { + return value; + } + + return Array.isArray(value) ? value.map((v) => canonicalizationFunc(v)) : canonicalizationFunc(value); +}; + export {requestLogger, requestQueryParser};