From a1fe762d8008843d905e4928f56773af5d6de706 Mon Sep 17 00:00:00 2001 From: "Dr. Ernie Prabhakar" Date: Fri, 26 Jan 2024 20:40:55 -0800 Subject: [PATCH] parse duplicate values in/out of arrays --- .../nextflow/quilt/jep/QuiltParser.groovy | 47 ++++++++++++++++--- .../nextflow/quilt/jep/QuiltParserTest.groovy | 13 +++++ 2 files changed, 53 insertions(+), 7 deletions(-) diff --git a/plugins/nf-quilt/src/main/nextflow/quilt/jep/QuiltParser.groovy b/plugins/nf-quilt/src/main/nextflow/quilt/jep/QuiltParser.groovy index fd159ec4..b4c71f6e 100644 --- a/plugins/nf-quilt/src/main/nextflow/quilt/jep/QuiltParser.groovy +++ b/plugins/nf-quilt/src/main/nextflow/quilt/jep/QuiltParser.groovy @@ -1,3 +1,4 @@ +/* groovylint-disable Instanceof */ /* * Copyright 2022, Quilt Data Inc * @@ -75,18 +76,50 @@ class QuiltParser { return new QuiltParser(uri.authority, pkg, path, options, metadata) } - static Map parseQuery(String query) { + static String decode(String str) { + return URLDecoder.decode(str, StandardCharsets.UTF_8) + } + + static String encode(String str) { + return URLEncoder.encode(str, StandardCharsets.UTF_8) + } + + static Map parseQuery(String query) { if (!query) { return [:] } // skip for urls without query params - final queryParams = query.split('&') - return queryParams.collectEntries { params -> params.split('=').collect { param -> URLDecoder.decode(param) } } + def params = query.split('&') + def result = [:] + params.each { param -> + def keyValue = param.split('=') + if (keyValue.size() == 2) { + String key = decode(keyValue[0]) + String value = decode(keyValue[1]) + if (result.containsKey(key)) { + if (result[key] instanceof List) { + result[key].add(value) + } else { + result[key] = [result[key], value] + } + } else { + result[key] = value + } + } + + } + return result + } + + static String encodePair(String key, String value) { + return "${QuiltParser.encode(key)}=${QuiltParser.encode(value)}" } static String unparseQuery(Map query) { if (!query) { return '' } // skip for urls without query params - List params = query.collect { key, val -> - String k = URLEncoder.encode(key, StandardCharsets.UTF_8) - String v = URLEncoder.encode(val.toString(), StandardCharsets.UTF_8) - "${k}=${v}".toString() + List params = query.collect { key, value -> + if (value instanceof List) { + value.collect { QuiltParser.encodePair(key, it.toString()) }.join('&') + } else { + QuiltParser.encodePair(key, value.toString()) + } } return params.join('&') } diff --git a/plugins/nf-quilt/src/test/nextflow/quilt/jep/QuiltParserTest.groovy b/plugins/nf-quilt/src/test/nextflow/quilt/jep/QuiltParserTest.groovy index e0dcc4d8..0d570e14 100644 --- a/plugins/nf-quilt/src/test/nextflow/quilt/jep/QuiltParserTest.groovy +++ b/plugins/nf-quilt/src/test/nextflow/quilt/jep/QuiltParserTest.groovy @@ -123,4 +123,17 @@ class QuiltParserTest extends QuiltSpecification { unparsed.replace('%2f', '/') == fullURL } + void 'should collect array parameters from query string'() { + when: + String query = 'key=val1,val2&quay=vale1&quay=vale2' + Map result = QuiltParser.parseQuery(query) + println "QuiltParserTest[$query] -> ${result}" + String unparsed = QuiltParser.unparseQuery(result) + + then: + result['key'] == 'val1,val2' + result['quay'] == ['vale1', 'vale2'] + unparsed == query.replace(',', '%2C') + } + }