Http Server in F#

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

open System
open System.Net
open System.IO

// A fundamental concept in HTTP servers is handlers. In F#, we can use functions
// as handlers. These functions take HttpListenerContext as an argument.

let hello (context: HttpListenerContext) =
    // We use the Response property of the context to send our response.
    // Here our simple response is just "hello\n".
    let response = context.Response
    let output = response.OutputStream
    let writer = new StreamWriter(output)
    writer.WriteAsync("hello\n") |> Async.AwaitTask |> Async.RunSynchronously
    writer.Close()

let headers (context: HttpListenerContext) =
    // This handler does something a little more sophisticated by reading all
    // the HTTP request headers and echoing them into the response body.
    let request = context.Request
    let response = context.Response
    let output = response.OutputStream
    let writer = new StreamWriter(output)
    
    for header in request.Headers.AllKeys do
        writer.WriteAsync(sprintf "%s: %s\n" header (request.Headers.[header])) 
        |> Async.AwaitTask 
        |> Async.RunSynchronously
    
    writer.Close()

[<EntryPoint>]
let main argv =
    // We set up our HTTP server and register our handlers on server routes.
    let listener = new HttpListener()
    listener.Prefixes.Add("http://localhost:8090/")
    listener.Start()
    
    printfn "Listening on http://localhost:8090/"
    
    // We use an infinite loop to keep the server running and handle requests.
    while true do
        let context = listener.GetContext()
        match context.Request.Url.LocalPath with
        | "/hello" -> hello context
        | "/headers" -> headers context
        | _ -> 
            let response = context.Response
            response.StatusCode <- 404
            response.Close()
    
    0 // Return an integer exit code

This F# code sets up a basic HTTP server that listens on port 8090. It defines two handler functions, hello and headers, which respond to requests on the /hello and /headers routes respectively.

To run the server:

  1. Save this code in a file, for example HttpServer.fs.
  2. Compile the code:
$ fsharpc HttpServer.fs
  1. Run the compiled program:
$ mono HttpServer.exe

The server will start and listen on http://localhost:8090/.

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

$ curl http://localhost:8090/hello
hello

$ curl http://localhost:8090/headers
User-Agent: curl/7.68.0
Host: localhost:8090
Accept: */*

This example demonstrates how to create a simple HTTP server in F#, handling different routes and processing request headers. The structure is similar to the original, but adapted to F#’s syntax and the .NET framework’s HttpListener class.