We are using Spring Cloud Gateway (MVC version) in front o a Rails service (let's call it mailbox
) and are struggling when the value of a query parameter includes the +
(plus) character. Here is an example:
?email=bob+test@mail.com
+
into a space.mailbox
, it encodes back the value, resulting in email=bob%20test@mail.com
mailbox
decodes it as email=bob test@mail.com
which makes it failAn alternative was to encode +
in the client, but then we have:
?email=bob%2Btest@mail.com
%2B
into +
.mailbox
, it encodes back the value but, given that +
is not considered special character, it stays as email=bob+test@mail.com
mailbox
decodes it as email=bob test@mail.com
which makes it failI can't find a way to either tell gateway not to decode the original request or force it to encode +
before sending the request to mailbox
. Is there any way to do that? Is there any other solution? I can't think of anything. It's like all the steps taken are okay (first decode, then encode), but the final result is wrong. I need mailbox
to receive an email with a +
in it, but I can't.
Thanks for your help!
We encountered the same issue and were able to work around the problem by manually encoding +
in the forwarded requests after the existing encoder has run.
This was achieved by using a customised ClientHttpRequestFactory
as follows:
@Configuration
class WebMvcConfiguration {
@Bean
fun clientHttpRequestFactory(): ClientHttpRequestFactory =
CustomClientHttpRequestFactory()
}
class CustomClientHttpRequestFactory : JdkClientHttpRequestFactory() {
override fun createRequest(uri: URI, httpMethod: HttpMethod): ClientHttpRequest {
val encodedURI = URI(customUriEncode(uri.toString()))
return super.createRequest(encodedURI, httpMethod)
}
private fun customUriEncode(str: String): String =
str.replace(oldValue = "+", newValue = "%2B")
}
We believe this to be safe, because both +
and %20
in the original request are decoded into
(a space) before it reaches the request factory, so will not be re-encoded back into %2B
.