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

    We can make it a lot more performant, shorter, and also safer by using lazy byte strings:

    {- cabal:
    build-depends: base, network, network-run, bytestring
    -}
    
    {-# LANGUAGE OverloadedStrings #-}
    
    import Network.Run.TCP (runTCPServer)
    import qualified Network.Socket.ByteString.Lazy as Net
    import qualified Data.ByteString.Lazy.Char8 as Str
    
    main = runTCPServer (Just "127.0.0.1") "9999" $ \s -> do
      request <- Net.getContents s
      case Str.words (Str.takeWhile (/= '\r') request) of
        ["GET", resource, "HTTP/1.1"] -> do
          let path = Str.concat
                [ "htdocs/"
                , Str.dropWhile (== '/') resource
                , if Str.last resource == '/' then "index.html" else ""
                ]
          page <- Str.readFile (Str.unpack path)
          Net.sendAll s ("HTTP/1.1 200 OK\r\n\r\n" <> page)
        _ -> error "todo"