The browser is the new GUI !



Task

Serve our standard text   Goodbye, World!   to   http://localhost:8080/   so that it can be viewed with a web browser.

The provided solution must start or implement a server that accepts multiple client connections and serves text as requested.

Note that starting a web browser or opening a new window with this URL
is not part of the task.

Additionally, it is permissible to serve the provided page as a plain text file (there is no requirement to serve properly formatted HTML here).

The browser will generally do the right thing with simple text like this.




 
use "net"
 
actor Main
  new create(env: Env) =>
    try TCPListener(env.root as AmbientAuth,
                Listener,
                "127.0.0.1", "8080")
    else env.err.print("unable to use the network")
    end
 
// Boilerplate code, create a TCP listener on a socket
class Listener is TCPListenNotify
 
  new iso create() => None
 
  fun ref listening(_: TCPListener ref) => None
 
  fun ref not_listening(listen: TCPListener ref) => listen.close()
 
  fun ref connected(listen: TCPListener ref): TCPConnectionNotify iso^ =>
    Server
 
 
// HTTP server that handles the TCP connections
class val Server is TCPConnectionNotify
 
  // Empty ctor
  new iso create() => None
 
  // Impl for when server accepts the client request
  fun accepted(_: TCPConnection ref) => None
 
  // Impl for when server receives client data
  fun ref received(conn: TCPConnection ref, _: Array[U8] iso, _: USize)
  : Bool
  =>
    // handle request
    conn.write("HTTP/1.1 200 OK\r\n\r\n")
    conn.write("<html><body><p>")
    conn.write("Goodbye, World!")
    conn.write("</p></body></html>")
    conn.dispose()
    false
 
  // Impl for when client closes the connection
  fun ref closed(conn: TCPConnection ref) => conn.dispose()
 
  // Impl for when client fails to connect to all possible addresses for the server
  fun ref connect_failed(_: TCPConnection ref) => None
 