我有使用wai的基本"hello world"应用程序设置,并且想使用wai-handler-devel,但我不确定如何去做它并且在wai项目中找不到它的任何使用示例.
{-# LANGUAGE OverloadedStrings #-}
import Network.Wai
import Network.HTTP.Types
import Network.Wai.Handler.Warp (run)
import Data.ByteString.Lazy.Char8 () -- Just for an orphan instance
app :: Application
app _ = return $ responseLBS
status200
[("Content-Type", "text/plain")]
"Hello, World!"
main :: IO ()
main = do
putStrLn $ "http://localhost:8080/"
run 8080 app
Run Code Online (Sandbox Code Playgroud)
我需要做些什么来让wai-handler-devel使用基本的wai应用程序?
注意:如果遇到"wai-handler-devel:command not found"的问题,可以在此处修复(https://gist.github.com/1499226)
我目前正在使用wai-middleware-static为我的服务器提供自定义页面.但是,我看到我的服务器favicon.ico
在每个页面加载时都收到了请求,以及我的每一个Web字体,所以我决定检查响应头上的缓存设置,发现没有.
wai-middleware-static返回一个Middleware
值,我认为这是对每个请求运行的中间件提供的函数的回调.有没有办法修改它以在响应头中添加以告诉浏览器缓存结果?
这是我的scotty应用程序,请注意我如何将请求记录到控制台:
{-# LANGUAGE OverloadedStrings #-}
import Web.Scotty
import Network.Wai.Middleware.RequestLogger
import Data.Monoid (mconcat)
main = scotty 3000 $ do
--log requests to console
middleware logStdoutDev
get "/:word" $ do
beam <- param "word"
html $ mconcat ["<h1>Scotty, ", beam, " me up!</h1>"]
Run Code Online (Sandbox Code Playgroud)
我的scotty app使用代理机制在nginx后面运行.这导致scotty应用程序像这样记录:
127.0.0.1 - - [27/Aug/2014:15:12:00 +0000] "GET / HTTP/1.0" 200 - ...
Run Code Online (Sandbox Code Playgroud)
我希望记录REAL IP ADDRESS.
我在我的Node.js/Express应用程序中遇到了同样的问题,我解决了这个问题:
我如何在Scotty中解决这个问题?
我想写一个web服务器,State
用wai
/ 将它的状态存储在monad中warp
.像这样的东西:
{-# LANGUAGE OverloadedStrings #-}
import Network.Wai
import Network.Wai.Handler.Warp
import Network.HTTP.Types
import Control.Monad.State
import Data.ByteString.Lazy.Char8
main = run 3000 app
text x = responseLBS
status200
[("Content-Type", "text/plain")]
x
app req = return $ text "Hello World"
app1 req = modify (+1) >>= return . text . pack . show
-- main1 = runStateT (run 3000 app1) 0
Run Code Online (Sandbox Code Playgroud)
当然,注释行不起作用.目的是将计数器存储在状态monad中,并在每个请求上显示其递增值.
另外,我如何获得线程安全?warp是顺序还是并行运行我的中间件?
有什么选择可用于州 - 除了IORef
我可以在这种情况下使用之外还有什么吗?
我理解国家给予安全,但似乎wai不允许国家.
我只需要一个可以从其他地方调用的简单的单线程RPC.Haxr
包需要一个单独的Web服务器,这是一个过度的.请参阅从Node.JS调用Haskell - 它没有任何建议,因此我使用Wai/Warp和Aeson编写了一个简单的服务器.但似乎WAI旨在支持并发实现,因此它使事情复杂化.
我正在使用warp,wai和acid-state在haskell中编写一个Web服务.截至目前,我有两个需要数据库交互的处理函数,后者给我带来了麻烦.
第一个是注册:
registerUser :: AcidState UserDatabase -> Maybe (Map.Map String String) -> Response
registerUser db maybeUserMap =
case maybeUserMap of
(Just u) -> let _ = fmap (\id -> update db (StoreUser (toString id) u)) (nextRandom)
in resPlain status200 "User Created."
Nothing -> resPlain status401 "Invalid user JSON."
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我设法IO
通过执行更新来避免感染响应let _ = ..
.
在登录功能(目前只返回用户地图)中,我无法避免IO
,因为我需要在响应中实际发回结果:
loginUser :: AcidState UserDatabase -> String -> Response
loginUser db username = do
maybeUserMap <- (query db (FetchUser username))
case maybeUserMap …
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用WAI编写一个简单的Fibonacci Web服务器,但我无法弄清楚类型.这段代码是我想要做的事情的本质,但它已经破碎了.该getQueryArg
函数返回一个Maybe ByteString
,我想在我的fibHandler
函数中使用它.
Maybe
我的fibHandler
?fmap
但我似乎无法做到正确.
{-# LANGUAGE OverloadedStrings #-}
import Network.Wai
import Network.HTTP.Types
import Network.Wai.Handler.Warp (run)
import Data.ByteString.Lazy.Char8 () -- Just for an orphan instance
import Control.Monad.IO.Class (liftIO)
import Data.Conduit
import Data.String.Utils
import Data.ByteString as BS (ByteString, putStrLn)
import Data.ByteString.Char8 as B (unpack)
import Data.Text as T (intercalate, pack, unpack)
app :: Application
app req
| rawPathInfo req == "/fib" = fibHandler req
| otherwise = notFoundHandler …
Run Code Online (Sandbox Code Playgroud) 我试图通过编写一个非常简单的会话管理器来了解中间件.
我需要SetCookie
在响应中添加标头.我看了看wai-extra
包裹,发现了wai-session
.
我正在使用wai-3.0.2,它似乎没有让我直接访问Response的类型构造函数,并且我发现模式匹配的所有示例都Response(..)
添加了标题.
你能为我指出正确的方向吗?
我正在尝试创建一个列出给定目录内容的网页,但是我遇到了一个奇怪的问题:当我在GHCi中逐行运行时,代码会生成所需的输出,但是当它在运行中执行时Scotty实例,它产生不同的(错误的)输出.以下是代码的相关部分:
serveDir :: String -> ActionM ()
serveDir p = do let path = prefix ++ p
entries <- liftIO $ getDirectoryContents path
fs <- liftIO $ filterM (doesFileExist . ((++) prefix)) entries
ds <- liftIO $ filterM (doesDirectoryExist . ((++) prefix)) entries
liftIO $ print path >> print entries >> print fs >> print ds
blaze $ renderDir fs ds
where prefix = "static/"
Run Code Online (Sandbox Code Playgroud)
(do
语句中的最后一行只是将它呈现为html.这有效,但正确的输出永远不会使它成为该函数)当我在GHCi中运行此函数的每一行时,我得到以下输出:
*Main> entries <- getDirectoryContents "static/stuff"
*Main> fs <- liftIO $ filterM (doesFileExist …
Run Code Online (Sandbox Code Playgroud) haskell ×8
haskell-wai ×8
haskell-warp ×2
scotty ×2
acid-state ×1
concurrency ×1
http ×1
state ×1
warp ×1
yesod ×1