2

キャッシュキーの一部として使用されるリクエストの本文のコンテンツを使用できるようにしたいと考えています。

私の現在のコードは次のようになります。

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

4

1 に答える 1

2

例として 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)
于 2015-12-01T14:45:56.303 に答える