Haskell: URL encoding for post data
Asked Answered
S

3

5

I've been looking at Network.HTTP, but can't find a way to create properly URL encoded key/value pairs.

How can I generate the post data required from [(key, value)] pair list for example? I imagine something like this already exists (perhaps hidden in the Network.HTTP package) but I can't find it, and I'd rather not re-invent the wheel.

Simulcast answered 31/7, 2012 at 2:56 Comment(0)
T
8

Take a look at urlEncodeVars.

urlEncodeVars :: [(String, String)] -> String
ghci> urlEncodeVars [("language", "Haskell"), ("greeting", "Hello, world!")]
"language=Haskell&greeting=Hello%2C%20world%21"
Trisyllable answered 31/7, 2012 at 2:59 Comment(1)
Oops, missed that one. Thanks!Simulcast
S
5

If you are trying to HTTP POST data x-www-form-urlencoded, urlEncodeVars may not be the right choice. The urlEncodeVars function does not conform to the application/x-www-form-urlencoded encoding algorithm in two ways worth noting:

  • it encodes a space as %20 instead of +
  • it encodes * as %2A instead of *

Note the comment alongside the function in Network.HTTP.Base:

-- Encode form variables, useable in either the
-- query part of a URI, or the body of a POST request.
-- I have no source for this information except experience,
-- this sort of encoding worked fine in CGI programming.

For an example of a conformant encoding, see this function in the hspec-wai package.

Semantic answered 3/5, 2016 at 15:42 Comment(0)
T
0

I recommend trying wreq for this. It provides FormParm data type, so you would want to convert your key-value pairs into [FormParm]. Then you can use something like this:

import qualified Data.ByteString.Char8 as C8
import Network.Wreq (post)
import Network.Wreq.Types (FormParam(..))

myPost = post url values where
  values :: [FormParam]
  values = [C8.pack "key" := ("value" :: String)]
  url = "https://some.domain.name"
Twombly answered 1/12, 2019 at 22:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.