CloudwatchException triggered by default content-type header
Closed this issue · 6 comments
Looks like when Cloudwatch is trying to POST some metrics it fails because the default content-type is set to application/x-www-form-urlencoded
.
software.amazon.awssdk.services.cloudwatch.model.CloudWatchException: When Content-Type:application/x-www-form-urlencoded, URL cannot include query-string parameters (after '?'): '/?Action=PutMetricData&Version=2010-08-01&Namespace=...
This is a POST
to https://monitoring.us-west-2.amazonaws.com?Action=PutMetricData&Version=2010-08-...
Seems to fall through this code with the final None
condition:
private def contentTypeHeaderToContentType(headers: List[HttpHeader]): ContentType = {
headers.find(_.lowercaseName() == "content-type").map(_.value()) match {
case Some("application/x-amz-json-1.0") => AkkaHttpClient.xAmzJson
case Some("application/x-amz-json-1.1") => AkkaHttpClient.xAmzJson11
case Some("application/x-www-form-urlencoded; charset=UTF-8") => AkkaHttpClient.formUrlEncoded
case Some("application/x-www-form-urlencoded") => AkkaHttpClient.formUrlEncoded
case Some("application/xml") => AkkaHttpClient.applicationXml
case Some(s) => tryCreateCustomContentType(s)
case None => AkkaHttpClient.formUrlEncoded
}
}
This looks interesting. Thanks for reporting.
I will have a look at this, I probably have time this friday.
Do you know what the expected content-type this request has or what is expected?
So it didn't seem that there was a content-type defined in the original request so I just changed the default to
case None => ContentTypes.`application/octet-stream`
Which seems to be the default when using a bytestream entity and it started working. Not sure if that is a general enough solution though.
Thanks for the investigation.
I remembered that there were some different behaviors between the aws standard http client and how Akka-http works with headers, especially with request signing in the mix.
I will investigate more, if using application/octet-stream
is fine or if this will break anything else if used as a default.
@AdrianMF I looked a bit more at this issue. Until now, I was not able to reproduce it on my side.
Does the error happen for every request or was it more like a one off request? If yes, do you know what was maybe "special" for this failing request?
Also, I found out that the request use application/x-www-form-urlencoded
as the content-type. I debugged a test case I wrote and saw that the case case Some("application/x-www-form-urlencoded")
matched.
So I think its a specific request to Cloudwatch, we are doing some Kinesis streams with the AWS API and when it tries to make a request to cloudwatch, the original request doesn't include a content-type so the fallback is application/x-www-form-urlencoded and that is what causes the error because the request include URL query params. I guess AWS is validating the content-type against the URL params. Unfortunately I'm not sure I can easily hook into the original request to add a content-type