forward :: BE.Manager -> W.Application
forward mgr req resp = do
  let beReq =
        BE.defaultRequest
          { BE.method = W.requestMethod req
          , BE.path = W.rawPathInfo req
          , BE.queryString = W.rawQueryString req
          , BE.requestHeaders = modifyRequestHeaders $ W.requestHeaders req
          , BE.redirectCount = 0
          , BE.decompress = const False
          , BE.requestBody =
              case W.requestBodyLength req of
                W.ChunkedBody ->
                  requestBodySourceChunkedIO (sourceRequestBody req)
                W.KnownLength l ->
                  requestBodySourceIO (fromIntegral l) (sourceRequestBody req)
          }
      msg =
        unpack (BE.method beReq <> " " <> BE.path beReq <> BE.queryString beReq)
  Log.debug $ "BACKEND <<< " ++ msg ++ " " ++ show (BE.requestHeaders beReq)
  BE.withResponse beReq mgr $ \res -> do
    let status = BE.responseStatus res
        headers = BE.responseHeaders res
        body =
          mapOutput (Chunk . fromByteString) . bodyReaderSource $
          BE.responseBody res
        logging =
          if statusCode status `elem` [400, 500]
            then Log.warn
            else Log.debug
    logging $
      "BACKEND >>> " ++
      show (statusCode status) ++ " on " ++ msg ++ " " ++ show headers ++ "\n"
    resp $ responseSource status (modifyResponseHeaders headers) body
forward :: BE.Manager -> W.Application
forward mgr req resp = do
  let beReq =
        BE.defaultRequest
          { BE.method = W.requestMethod req
          , BE.path = W.rawPathInfo req
          , BE.queryString = W.rawQueryString req
          , BE.requestHeaders = modifyRequestHeaders $ W.requestHeaders req
          , BE.redirectCount = 0
          , BE.decompress = const False
          , BE.requestBody =
              case W.requestBodyLength req of
                W.ChunkedBody ->
                  requestBodySourceChunkedIO (sourceRequestBody req)
                W.KnownLength l ->
                  requestBodySourceIO (fromIntegral l) (sourceRequestBody req)
          }
      msg =
        unpack (BE.method beReq <> " " <> BE.path beReq <> BE.queryString beReq)
  Log.debug $ "BACKEND <<< " ++ msg ++ " " ++ show (BE.requestHeaders beReq)
  BE.withResponse beReq mgr $ \res -> do
    let status = BE.responseStatus res
        headers = BE.responseHeaders res
        body =
          mapOutput (Chunk . fromByteString) . bodyReaderSource $
          BE.responseBody res
        logging =
          if statusCode status `elem` [400, 500]
            then Log.warn
            else Log.debug
    logging $
      "BACKEND >>> " ++
      show (statusCode status) ++ " on " ++ msg ++ " " ++ show headers ++ "\n"
    resp $ responseSource status (modifyResponseHeaders headers) body
forward mgr req resp = do
  let beReq =
        BE.defaultRequest
          { BE.method = W.requestMethod req
          , BE.path = W.rawPathInfo req
          , BE.queryString = W.rawQueryString req
          , BE.requestHeaders = modifyRequestHeaders $ W.requestHeaders req
          , BE.redirectCount = 0
          , BE.decompress = const False
          , BE.requestBody =
              case W.requestBodyLength req of
                W.ChunkedBody ->
                  requestBodySourceChunkedIO (sourceRequestBody req)
                W.KnownLength l ->
                  requestBodySourceIO (fromIntegral l) (sourceRequestBody req)
          }
      msg =
        unpack (BE.method beReq <> " " <> BE.path beReq <> BE.queryString beReq)
  Log.debug $ "BACKEND <<< " ++ msg ++ " " ++ show (BE.requestHeaders beReq)
  BE.withResponse beReq mgr $ \res -> do
    let status = BE.responseStatus res
        headers = BE.responseHeaders res
        body =
          mapOutput (Chunk . fromByteString) . bodyReaderSource $
          BE.responseBody res
        logging =
          if statusCode status `elem` [400, 500]
            then Log.warn
            else Log.debug
    logging $
      "BACKEND >>> " ++
      show (statusCode status) ++ " on " ++ msg ++ " " ++ show headers ++ "\n"
    resp $ responseSource status (modifyResponseHeaders headers) body