From 04f4d5c803ddeaf242fcf4d3d901763c9040f825 Mon Sep 17 00:00:00 2001 From: Ronald Holshausen Date: Fri, 28 Jul 2023 09:49:16 +1000 Subject: [PATCH] fix: Pact parser is removing quoting on Content-Type params #1538 --- .../au/com/dius/pact/core/model/HeaderParser.kt | 10 +++++++++- .../dius/pact/core/model/HeaderParserSpec.groovy | 14 ++++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/core/model/src/main/kotlin/au/com/dius/pact/core/model/HeaderParser.kt b/core/model/src/main/kotlin/au/com/dius/pact/core/model/HeaderParser.kt index e6e2fabb68..fbc5a34d1f 100644 --- a/core/model/src/main/kotlin/au/com/dius/pact/core/model/HeaderParser.kt +++ b/core/model/src/main/kotlin/au/com/dius/pact/core/model/HeaderParser.kt @@ -3,8 +3,15 @@ package au.com.dius.pact.core.model import au.com.dius.pact.core.support.Json import au.com.dius.pact.core.support.json.JsonValue import io.ktor.http.HeaderValue +import io.ktor.http.HeaderValueParam +import io.ktor.http.HeaderValueWithParameters import io.ktor.http.parseHeaderValue +class HeaderWithParameters( + content: String, + parameters: List +) : HeaderValueWithParameters(content, parameters) + object HeaderParser { private val SINGLE_VALUE_HEADERS = setOf("date", "accept-datetime", "if-modified-since", "if-unmodified-since", "expires", "retry-after") @@ -24,7 +31,8 @@ object HeaderParser { return if (headerValue.params.isEmpty()) { headerValue.value.trim() } else { - headerValue.value.trim() + ";" + headerValue.params.joinToString(";") { it.name + "=" + it.value } + val h = HeaderWithParameters(headerValue.value, headerValue.params) + h.toString() } } } diff --git a/core/model/src/test/groovy/au/com/dius/pact/core/model/HeaderParserSpec.groovy b/core/model/src/test/groovy/au/com/dius/pact/core/model/HeaderParserSpec.groovy index 4b642e7437..88b20007a3 100644 --- a/core/model/src/test/groovy/au/com/dius/pact/core/model/HeaderParserSpec.groovy +++ b/core/model/src/test/groovy/au/com/dius/pact/core/model/HeaderParserSpec.groovy @@ -1,6 +1,7 @@ package au.com.dius.pact.core.model import au.com.dius.pact.core.support.json.JsonValue +import spock.lang.Issue import spock.lang.Specification import spock.lang.Unroll @@ -20,8 +21,17 @@ class HeaderParserSpec extends Specification { desc | key | value | result 'simple header' | 'HeaderA' | 'A' | ['A'] 'date header' | 'date' | 'Sat, 24 Jul 2021 04:16:53 GMT' | ['Sat, 24 Jul 2021 04:16:53 GMT'] - 'header with parameter' | 'content-type' | 'text/html; charset=utf-8' | ['text/html;charset=utf-8'] + 'header with parameter' | 'content-type' | 'text/html; charset=utf-8' | ['text/html; charset=utf-8'] 'header with multiple values' | 'access-control-allow-methods' | 'POST, GET, PUT, HEAD, DELETE, OPTIONS, PATCH' | ['POST', 'GET', 'PUT', 'HEAD', 'DELETE', 'OPTIONS', 'PATCH'] - 'header with multiple values with parameters' | 'Accept' | ACCEPT | ['application/prs.hal-forms+json;q=1.0', 'application/hal+json;q=0.9', 'application/vnd.api+json;q=0.8', 'application/vnd.siren+json;q=0.8', 'application/vnd.collection+json;q=0.8', 'application/json;q=0.7', 'text/html;q=0.6', 'application/vnd.pactbrokerextended.v1+json;q=1.0'] + 'header with multiple values with parameters' | 'Accept' | ACCEPT | ['application/prs.hal-forms+json; q=1.0', 'application/hal+json; q=0.9', 'application/vnd.api+json; q=0.8', 'application/vnd.siren+json; q=0.8', 'application/vnd.collection+json; q=0.8', 'application/json; q=0.7', 'text/html; q=0.6', 'application/vnd.pactbrokerextended.v1+json; q=1.0'] + 'header with quoted values' | 'Content-Type' | 'multipart/related; type="application/json"; boundary=myBoundary' | ['multipart/related; type="application/json"; boundary=myBoundary'] + } + + @Issue('#1538') + def 'support quoted values as per RFC 1341'() { + expect: + HeaderParser.INSTANCE.fromJson('Accept', new JsonValue.StringValue( + 'application/hal+json;profile="https://api.example.de/examples+v1"')) == + ['application/hal+json; profile="https://api.example.de/examples+v1"'] } }