我希望能够使用请求主体的内容作为缓存键的一部分。
我当前的代码如下所示:
caching app req respond =
-- Request Body is consumed here
cacheKey <- strictRequestBody req
-- the req object is no more usable as body was consumed
maybe (app req (addToCacheAndRespond cacheKey))
(sendResponse . responseFromCachedValue)
(lookup cacheKey cacheContainer)我看不到任何解决方案。如何从cacheKey和req对象复制请求或生成另一个请求?
或者事件更好,还有其他更好的解决方案吗?
作为加分,有人能告诉我将Wai应用程序的类型从Request -> IO Response改为Request -> (Response -> IO ResponseReceived) -> IO ResponseReceived的基本原理吗?
发布于 2015-12-01 22:45:56
我最终以requestLogger为例,找到了如何做到这一点:
http://haddock.stackage.org/lts-3.15/wai-extra-3.0.13/src/Network.Wai.Middleware.RequestLogger.html#logStdout
主要是你需要复制回请求正文...
getRequestBody :: Request -> IO (Request, [S8.ByteString])
getRequestBody req = do
let loop front = do
bs <- requestBody req
if S8.null bs
then return $ front []
else loop $ front . (bs:)
body <- loop id
-- logging the body here consumes it, so fill it back up
-- obviously not efficient, but this is the development logger
--
-- Note: previously, we simply used CL.sourceList. However,
-- that meant that you could read the request body in twice.
-- While that in itself is not a problem, the issue is that,
-- in production, you wouldn't be able to do this, and
-- therefore some bugs wouldn't show up during testing. This
-- implementation ensures that each chunk is only returned
-- once.
ichunks <- newIORef body
let rbody = atomicModifyIORef ichunks $ \chunks ->
case chunks of
[] -> ([], S8.empty)
x:y -> (y, x)
let req' = req { requestBody = rbody }
return (req', body)https://stackoverflow.com/questions/34021617
复制相似问题