module Network.Wai.Middleware.MethodOverride (
    methodOverride,
) where

import Control.Monad (join)
import Network.Wai (Middleware, queryString, requestMethod)

-- | Overriding of HTTP request method via `_method` query string parameter.
--
-- This middleware only applies when the initial request method is POST.
-- Allows submitting of normal HTML forms, without worries of semantic
-- mismatches with the HTTP spec.
methodOverride :: Middleware
methodOverride :: Middleware
methodOverride Application
app Request
req =
    Application
app Request
req'
  where
    req' :: Request
req' =
        case (Request -> ByteString
requestMethod Request
req, Maybe (Maybe ByteString) -> Maybe ByteString
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join (Maybe (Maybe ByteString) -> Maybe ByteString)
-> Maybe (Maybe ByteString) -> Maybe ByteString
forall a b. (a -> b) -> a -> b
$ ByteString
-> [(ByteString, Maybe ByteString)] -> Maybe (Maybe ByteString)
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup ByteString
"_method" ([(ByteString, Maybe ByteString)] -> Maybe (Maybe ByteString))
-> [(ByteString, Maybe ByteString)] -> Maybe (Maybe ByteString)
forall a b. (a -> b) -> a -> b
$ Request -> [(ByteString, Maybe ByteString)]
queryString Request
req) of
            (ByteString
"POST", Just ByteString
m) -> Request
req{requestMethod = m}
            (ByteString, Maybe ByteString)
_ -> Request
req