-
Notifications
You must be signed in to change notification settings - Fork 134
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Network.Wai.Middleware.MethodOverride not supported #7
Comments
It appears that this is supported but MethodOverride only handles query parameters, however, while testing it seems that mkEnv doesn't handle encoded parameters from other StdMethod types than POST: mkEnv :: StdMethod -> Request -> [Param] -> ResourceT IO ActionEnv
mkEnv method req captures = do
b <- BL.fromChunks <$> lazyConsume (requestBody req)
let parameters = captures ++ formparams ++ queryparams
formparams = case (method, lookup "Content-Type" [(CI.mk k, CI.mk v) | (k,v) <- requestHeaders req]) of
(POST, Just "application/x-www-form-urlencoded") -> parseEncodedParams $ mconcat $ BL.toChunks b
_ -> []
queryparams = parseEncodedParams $ rawQueryString req
return $ Env req parameters b I'm not sure of the best way to generalize this, but people will probably want to be able to send parameters through the usual means. As a test I used a wildcard to capture all form-encoded parameters in mkEnv and this appears to work: let parameters = captures ++ formparams ++ queryparams
formparams = case (method, lookup "Content-Type" [(CI.mk k, CI.mk v) | (k,v) <- requestHeaders req]) of
(_, Just "application/x-www-form-urlencoded") -> parseEncodedParams $ mconcat $ BL.toChunks b
_ -> [] I have not tested if this breaks existing functionality at this point. |
Yes, MethodOverride only works with query parameters, so your html would need to be: <form method="POST" action="/update?_method=PUT">
<input type="text" name="nickname" />
<input type="submit" />
</form> Unfortunately, this is someone else's package, but I'm sure they would accept a patch if you found a clean way to look for "_method" in the form parameters. As for mkEnv: yes this is very incomplete. There are several ways to encode form data, especially once you get to files and multipart data. I've only implemented the most basic method here because that is all I've needed so far. ;-) Ideally, I'd rather form data get parsed in middleware, and attached to the request object on the way in. The WAI Request object has a Vault, which is probably where we'd store this. Then mkEnv could just look there. I might take a crack at this later tonight, depending on how much else I get done today. :-P |
Thanks Andrew. I agree that this would be best handled with middleware. It should probably be included in wai-extra, then as you say, mkEnv can just pull the values out of the vault. I've begun adding a middleware to wai-extra that will parse application/x-www-form-urlencoded data similar to how Scotty does, however, I'm not experienced with the other encodings you mentioned. What should I be looking out for? Are there any existing libraries I can use that you know of? |
Network.Wai.Middleware.MethodOverride allows you to override the restful method of an HTML form. For example, you could update a field and handle it as a PUT in your routes with the following HTML:
The following Scotty application fails to accept overridden PUT requests and instead interprets them as POST. In other words, the middleware fails to have the results of the rewritten request passed to the rest of the application:
The text was updated successfully, but these errors were encountered: