module Hack.Middleware.Jsonp (jsonp) where
import Hack
import Web.Encodings (decodeUrlPairs)
import Data.ByteString.Class (toLazyByteString)
import qualified Data.ByteString.Lazy as BS
import Data.Maybe (fromMaybe)
import Data.List (isInfixOf)
jsonp :: Middleware
jsonp app env = do
let accept = fromMaybe "" $ lookup "Accept" $ http env
let gets = decodeUrlPairs $ queryString env
let callback :: Maybe String
callback =
if "text/javascript" `isInfixOf` accept
then lookup "callback" gets
else Nothing
let env' =
case callback of
Nothing -> env
Just _ -> env
{ http = changeVal "Accept"
"application/json"
$ http env
}
res <- app env'
let ctype = fromMaybe "" $ lookup "Content-Type" $ headers res
case callback of
Nothing -> return res
Just c ->
case ctype of
"application/json" -> return $ res
{ headers = changeVal "Content-Type"
"text/javascript"
$ headers res
, body = BS.concat
[ toLazyByteString c
, toLazyByteString "("
, body res
, toLazyByteString ")"
]
}
_ -> return res
changeVal :: String -> String -> [(String, String)] -> [(String, String)]
changeVal key val old = (key, val) : filter (\(k, _) -> k /= key) old