summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Smeding <tom@tomsmeding.com>2026-08-09 21:33:45 +0200
committerTom Smeding <tom@tomsmeding.com>2026-08-09 21:33:45 +0200
commitb00e6ef7d6c9ebf74ef35212ea144c8212cd18ed (patch)
treea99315ab496872ff5be34d526386182d89ede6ed
parent914e63f6bb46c3ff132c5f642cffcb72485551e0 (diff)
mini-http-server: Handle nonexistent files decently
-rw-r--r--mini-http-server/Network/HTTP/Server/Mini/Printer.hs14
-rw-r--r--mini-http-server/Network/HTTP/Server/Mini/Types.hs3
2 files changed, 14 insertions, 3 deletions
diff --git a/mini-http-server/Network/HTTP/Server/Mini/Printer.hs b/mini-http-server/Network/HTTP/Server/Mini/Printer.hs
index 77b88ce..442d768 100644
--- a/mini-http-server/Network/HTTP/Server/Mini/Printer.hs
+++ b/mini-http-server/Network/HTTP/Server/Mini/Printer.hs
@@ -5,19 +5,27 @@ import Data.ByteString (ByteString)
import Data.ByteString qualified as BS
import Data.ByteString.Lazy qualified as BSL
import Data.ByteString.Builder qualified as BSB
+import GHC.IO.Exception (IOException(..), IOErrorType(..))
import Network.Socket
import Network.Socket.ByteString
+import System.IO.Error (catchIOError)
import Network.HTTP.Server.Mini.Types
-import System.IO.Error (catchIOError)
sendResponse :: Socket -> Response -> IO ()
sendResponse conn (Response status hdrs (BodyLBS body)) =
sendResponseChunks conn status hdrs body
-sendResponse conn (Response status hdrs (BodyFile path)) =
+sendResponse conn (Response status hdrs (BodyFile path)) = do
-- lazy IO is fine here because the whole thing is traversed before the end of this function in sendMany
- sendResponseChunks conn status hdrs =<< BSL.readFile path
+ elazyContents <-
+ catchIOError (Right <$> BSL.readFile path)
+ (\e -> case ioe_type e of
+ NoSuchThing -> return (Left (status404, "File not found"))
+ _ -> return (Left (status500, "Something went wrong")))
+ case elazyContents of
+ Right lazyContents -> sendResponseChunks conn status hdrs lazyContents
+ Left (status', text) -> sendResponseChunks conn status' [] text
sendResponseChunks :: Socket -> Status -> [(Header, ByteString)] -> BSL.ByteString -> IO ()
sendResponseChunks conn (Status code reason) hdrs body =
diff --git a/mini-http-server/Network/HTTP/Server/Mini/Types.hs b/mini-http-server/Network/HTTP/Server/Mini/Types.hs
index 94e113f..42a1085 100644
--- a/mini-http-server/Network/HTTP/Server/Mini/Types.hs
+++ b/mini-http-server/Network/HTTP/Server/Mini/Types.hs
@@ -57,6 +57,9 @@ status200 = Status 200 "OK"
status404 :: Status
status404 = Status 404 "Not Found"
+status500 :: Status
+status500 = Status 500 "Internal Server Error"
+
responseLBS :: Status -> [(Header, ByteString)] -> LazyByteString -> Response
responseLBS status hdrs = Response status hdrs . BodyLBS