Http Server in Idris

Here’s the translation of the HTTP Server example from Go to Idris, formatted in Markdown suitable for Hugo:

import Network.Socket
import Network.Socket.Data
import Control.Monad.Trans
import System

-- A fundamental concept in HTTP servers is handlers. A handler is a function
-- that processes an HTTP request and generates a response.

hello : Socket -> IO ()
hello sock = do
  send sock "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\nhello\n" 
  pure ()

headers : Socket -> IO ()
headers sock = do
  -- This handler does something a little more sophisticated by reading all the HTTP request
  -- headers and echoing them into the response body.
  -- Note: In a real-world scenario, you'd parse the request headers here.
  let response = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\nHeaders would be displayed here\n"
  send sock response
  pure ()

handleClient : Socket -> IO ()
handleClient sock = do
  -- In a real-world scenario, you'd parse the request here and call the appropriate handler
  hello sock
  close sock

main : IO ()
main = do
  -- We set up our server to listen on port 8090
  Right sock <- bind (Just "localhost") 8090
  listen sock 5

  putStrLn "Server listening on port 8090"

  -- Accept and handle client connections
  forever $ do
    (csock, _) <- accept sock
    handleClient csock

  close sock

This Idris code creates a basic HTTP server that listens on port 8090. Here’s a breakdown of what the code does:

  1. We import necessary modules for network operations and IO.

  2. We define two handler functions: hello and headers. These are simplified versions of HTTP handlers that send basic responses.

  3. The handleClient function is called for each client connection. In this simple example, it always calls the hello handler.

  4. In the main function, we:

    • Bind the server to localhost on port 8090
    • Start listening for connections
    • Enter an infinite loop to accept and handle client connections

Note that this is a very basic implementation. Idris doesn’t have a built-in HTTP server library like Go’s net/http, so we’re working at a lower level with sockets. In a real-world scenario, you’d want to use a more robust HTTP server library or implement proper HTTP request parsing and routing.

To run the server:

$ idris -o http-server http-server.idr
$ ./http-server
Server listening on port 8090

You can then access the server using a web browser or curl:

$ curl localhost:8090
hello

This example demonstrates how to create a basic network server in Idris. While it doesn’t have the same level of HTTP support out-of-the-box as Go, it shows how you can build network applications using Idris’s lower-level socket operations.