Closed thomasd3 closed 3 years ago
Hi, If your intent is to post JSON data you should use the bytes in rawForm
.
I'm using AWS' SNS system, so AWS will send a JSON message first, then after that it is whatever gets posted by the client on the other side, which is not necessarily JSON, but there will be symbols like & and = in the form field.
So is Suave always trying to decode what is in the form? in that case, we can't use that field for 'free/random' strings but need to get the bytes from the raw field, correct?
I do not follow exactly the issue and suspect there is some misunderstanding.
Either a JSON payload is posted to the server and you will get it via rawForm ; or a x-www-form-urlencoded encoded payload which you will get via the form dictionary.
If you place JSON data inside a form field it still should work because the browser will url encode the JSON data. If you are posting programmatically you SHOULD url encode the fields data otherwise it wouldn't be valid http.
Perhaps sharing a sample of your code will help clarify the issue.
The pipeline is the following: there are a few clients posting data to AWS' SNS system (it's just a fast queue) and AWS will forward that data as a POST command wherever we tell it. The source data is a few strings with numerical values next to them (like x 30; y 17) with occasionally some text messages as well so it's not JSON. But some of the text strings will have '=' in them for example.
The issue is that AWS will also send JSON formatted messages to confirm subscription / un-subscription and the only way to know that the upcoming message is from AWS, vs. a client, is because AWS will set a header value indicating the origin of the payload.
So the data is a mix of Json / non Json data based on the presence of a value in the headers.
For this reason I can't say that the form data will decode as a Json, or use the custom decoder because it depends on the header value. What surprised me is that I expected that the form field would contain 'whatever' was sent, but it looks like it is processed.
it depends on the header value.
You can look at the headers and decide how to proceed.
let app : WebPart =
context(fun ctx ->
match ctx.request.header "content-encoding" with
| Choice1Of2 "application/json" ->
// do something with ctx.request.rawForm
| Choice1Of2 "application/x-www-form-urlencoded" ->
// use the request.form dictionary
| _ ->
failwith "Unsupported content enconding"
)
Also to note that Suave only parses on demand if you access the form dictionary. This could be improved.
Thanks, this is clear now. I think the issue stems from the fact that I didn't realize that the form field was a dictionary at the beginning and I stayed stuck on that issue. It's my first time using Suave, so there is a lot to ingest at once :D
If you create a POST message and put this string in the form field:
Suave's form field will contain a truncated version, while the rawForm will have the full version.
for more details, see: https://stackoverflow.com/questions/66618622/form-data-is-not-correct-with-suave-web-server