Suave Web 服务器的表单数据不正确

Form data is not correct with Suave web server

我正在尝试接收来自 AWS 的 SNS 系统的确认。 它通过 POST 向网络服务器发送一条消息,我正在使用 Suave 接收它。

当我收到消息时,表单 字段被截断,我收到:

"{\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"

所以这是一个未完成的 json...

但是当我查看 rawForm 字段时,我得到了完整的消息:

{
  "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"
}

起初我以为输出被截断了,但后来我缩小了范围。发布此行:

{
  "SubscribeURL" : "https://sns.ap-northeast-1.amazonaws.com/?Action=ConfirmSubscription&TopicArn=arn:aws:sns:ap-northeast-1:960544703730:igorbot&Token=2336412f37fb687f5d51e6e2425e90ccf23f36200406641a9f63b753dad1d31c61da2ebeea8cdaeed2e3c04f701bd08e2d2c9cac65676979e43c1089a96779f9b57a0e0f072013333db51472ca43c1e6a0854cf3af6769d95c7911d74c9e2bec22db93de90e537d480070891ddaaa548"
}

将失败并在第一个“=”符号处被截断。那么:

{
  "SubscribeURL" : "abc=3"
}

将导致 Suave 失败。作为表单数据发送时,将无法正确转换为字符串。

是否有任何与编码等相关的设置可以防止这种情况发生? (因为我不能要求 AWS 转义他们所有的“=”符号)

JSON 和表单数据(application/x-www-form-urlencoded,具体而言)具有不同的语法。表单数据看起来像 key1=value1&key2=value2,因此 Suave 在 &= 上断开字符串以解析它。

您可以使用 mapJson 来解析 JSON。这样的事情应该有效:

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