如何将HTML写入句柄?

时间:2016-08-24 21:33:00

标签: haskell

我正在尝试在遇到特定路径时将HTML写入页面:

import Control.Monad
import Data.Char
import System.IO
import Network
import Data.Time.LocalTime

data RequestType = GET | POST deriving (Show)
data Request = Request { rtype :: RequestType, path :: String, options :: [(String,String)] }
data Response = Response { version :: String, statuscode :: Int }

instance Show Response where
    show r = version(r) ++ " " ++ show(statuscode(r)) ++ " " ++ (case statuscode(r) of
        100 -> "Continue"
        200 -> "OK"
        404 -> "Not Found") ++ "\r\n\r\n"

-- respond function
respond :: Request -> Handle -> IO ()
respond request handle = do
    putStrLn $ show request
    let response = Response {version = "HTTP/1.1", statuscode = 200}
    hPutStr handle $ show(response)
    hPutStr handle $ "Haskell says " ++ (getMessage request)
    where getMessage r
            | (path r) == "/hello" = "<b>hello there!</b>" <-- HERE
            | otherwise = (path r)

我可以毫无错误地运行此代码,但是当我点击http:// {hostname} / hello时,我得到字符串<b>hello there!</b>,这意味着html将呈现为字符串。

如何将其渲染为html?

注意

我想使用vanilla Haskell这样做,这意味着没有第三方库。

1 个答案:

答案 0 :(得分:0)

您没有发出内容类型标头。没有Content-type标头 浏览器可能会将输出视为纯文本 - 而不是HTML。

如果您将代码更改为emit:

HTTP/1.1 200 OK
Content-type: text/html; charset=UTF-8

Haskell says: <b>hello there!</b>

它应该在浏览器中呈现为HTML。

这个SO答案有一个包含HTML的简单HTTP响应示例:

https://stackoverflow.com/a/26346025/866915

<强>更新

根据您的代码,这应该有效:

response :: Request -> Handle -> IO ()
response _ h = do
  hPutStr h "HTTP/1.1 200 OK\r\n"
  hPutStr h "Content-type: text/html; charset=UTF-8\r\n"
  hPutStr h "\r\n\r\n"
  hPutStr h "Haskell says: <b>hello there!</b>\n"

这假定您在发出响应后关闭句柄 表示响应的结束。另外,请注意您的Show实例 响应不是很有用,因为你必须添加更多 HTTP行之后但空白行之前的标题。

如果您发布了指向服务器代码的链接,我可以为您测试。