• jaror@kbin.socialOP
    link
    fedilink
    arrow-up
    0
    ·
    7 months ago

    Actually, if you combine network with network-run then it is the right level of abstraction:

    {- cabal:
    build-depends: base, network, network-run, monad-loops
    -}
    
    import Network.Run.TCP
    import Network.Socket
    import System.IO
    import Control.Monad.Loops
    
    main = runTCPServer (Just "127.0.0.1") "9999" talk where
      talk s = do
        h <- socketToHandle s ReadWriteMode
        l <- hGetLine h
        case words l of
          ["GET", resource, "HTTP/1.1"] -> do
            whileM_ (("\r" /=) <$> hGetLine h) (pure ())
            let path = concat
                  [ "htdocs/"
                  , dropWhile (== '/') resource
                  , if last resource == '/' then "index.html" else ""
                  ]
            hPutStr h "HTTP/1.1 200 OK\r\n\r\n"
            hPutStr h =<< readFile path
            hClose h
          _ -> error "todo"