I am trying to receive a confirmation from AWS' SNS system. It sends a message through a POST to a webserver and I'm receiving it using Suave.
When I get the message, the form field is truncated, I am receiving:
"{\n \"Type\" : \"SubscriptionConfirmation\",\n \"MessageId\" : \"13dd68fa-2720-419a-8d8a-edc9f4466ea3\",\n \"Token\" : \"2336412f37fb687f5d51e6e2425e90ccf23f36200405c1942ea85f0874b382c47327c4bfd63203eace5240bb7b253428af362a04a61c8f98ab1718c679e9e27594529615adf5d86729374cce472768b91622851aced957c1dcddf21e3d82b48f5ff528c8dbc911179a3f26126a8d7f00\",\n \"TopicArn\" : \"arn:aws:sns:ap-northeast-1:960544703730:igorbot\",\n \"Message\" : \"You have chosen to subscribe to the topic arn:aws:sns:ap-northeast-1:960544703730:igorbot.\\nTo confirm the subscription, visit the SubscribeURL included in this message.\",\n \"SubscribeURL\" : \"https://sns.ap-northeast-1.amazonaws.com/?Action",
"ConfirmSubscription"
so it's an unfinished json...
but when I look at the rawForm field, I get the whole message:
{
"Type" : "SubscriptionConfirmation",
"MessageId" : "0645c009-f4fa-4fb7-9c94-127e98f5eb76",
"Token" : "2336412f37fb687f5d51e6e2425e90ccf23f36200406641a9f63b753dad1d31c61da2ebeea8cdaeed2e3c04f701bd08e2d2c9cac65676979e43c1089a96779f9b57a0e0f072013333db51472ca43c1e6a0854cf3af6769d95c7911d74c9e2bec22db93de90e537d480070891ddaaa548",
"TopicArn" : "arn:aws:sns:ap-northeast-1:960544703730:igorbot",
"Message" : "You have chosen to subscribe to the topic arn:aws:sns:ap-northeast-1:960544703730:igorbot.\nTo confirm the subscription, visit the SubscribeURL included in this message.",
"SubscribeURL" : "https://sns.ap-northeast-1.amazonaws.com/?Action=ConfirmSubscription&TopicArn=arn:aws:sns:ap-northeast-1:960544703730:igorbot&Token=2336412f37fb687f5d51e6e2425e90ccf23f36200406641a9f63b753dad1d31c61da2ebeea8cdaeed2e3c04f701bd08e2d2c9cac65676979e43c1089a96779f9b57a0e0f072013333db51472ca43c1e6a0854cf3af6769d95c7911d74c9e2bec22db93de90e537d480070891ddaaa548",
"Timestamp" : "2021-03-13T20:36:21.918Z",
"SignatureVersion" : "1",
"Signature" : "FBnpuGtkZmzox+5ryo1/4k1hgwmoeuvcptQ2dOyyneShVHovmdemMqo9JFTzbBFelTN7FMojX/sIjFs2dZoQYeqEgsQW9WqCiEstDQu0toHn7KKxapzIoGfjfh6Rikfy8Liv88RRNLC2DLtxWW2JWr5Mmwkjtro/pm7vyJhfp5G4qcAB3gtBOtVm+XOAai6rY7obcMojkmMr4jDd9UqutV6imyYDCH+PvUCnc7aKg6p4EmZO33VlRibIPa5PiN1Sj/mmNhyoeR4pGu+0Jci+utvonXaYPgtlDuEyoVcgUQ6lki1xiclIRpDm4FvOL5tvUSq+Jdjz3prlNDNM8AuQpQ==",
"SigningCertURL" : "https://sns.ap-northeast-1.amazonaws.com/SimpleNotificationService-010a507c1833636cd94bdb98bd93083a.pem"
}
At first I thought the output was truncated, but then I narrowed it down. Posting this line:
{
"SubscribeURL" : "https://sns.ap-northeast-1.amazonaws.com/?Action=ConfirmSubscription&TopicArn=arn:aws:sns:ap-northeast-1:960544703730:igorbot&Token=2336412f37fb687f5d51e6e2425e90ccf23f36200406641a9f63b753dad1d31c61da2ebeea8cdaeed2e3c04f701bd08e2d2c9cac65676979e43c1089a96779f9b57a0e0f072013333db51472ca43c1e6a0854cf3af6769d95c7911d74c9e2bec22db93de90e537d480070891ddaaa548"
}
will fail and get truncated at the first '=' sign. Then:
{
"SubscribeURL" : "abc=3"
}
will cause Suave to fail. When sent as form data, it will not be converted to a string properly.
Is there any setting related to encoding, etc that would allow to prevent this? (since I can't ask AWS to escape all their '=' signs)
JSON and form data (application/x-www-form-urlencoded
, to be specific) have different syntax. Form data looks like key1=value1&key2=value2
, so Suave is breaking the string on &
and =
in order to parse it.
You can parse JSON using mapJson
instead. Something like this should work:
open System.Runtime.Serialization
open Suave
open Suave.Json
[<DataContract>]
type Subscription =
{
[<field: DataMember(Name = "SubscribeURL")>]
SubscribeUrl : string;
}
[<EntryPoint>]
let main argv =
let app = mapJson (fun sub -> sprintf "URL: %s" sub.SubscribeUrl)
startWebServer defaultConfig app
0