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.




-- demo\rosetta\SimpleHttpServer.exw
without js
include builtins\sockets.e
constant MAX_QUEUE      = 100,
         ESCAPE         = #1B,
         response = substitute("""
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
 
<!DOCTYPE html>
<html>
 <head>
  <title>Bye-bye baby bye-bye</title>
  <style>
   body { background-color: #111 }
   h1 { font-size:4cm; text-align: center; color: black;
        text-shadow: 0 0 2mm red}
  </style>
 </head>
 <body>
  <h1>Goodbye, world!</h1>
 </body>
</html>
 
""","\n","\r\n")
 
puts(1,"server started, open http://localhost:8080/ in browser or curl, press Esc or Q to quit\n")
atom sock = socket(AF_INET,SOCK_STREAM,NULL),
     pSockAddr = sockaddr_in(AF_INET, "", 8080)
if bind(sock, pSockAddr)=SOCKET_ERROR then crash("bind (%v)",{get_socket_error()}) end if
if listen(sock,MAX_QUEUE)=SOCKET_ERROR then crash("listen (%v)",{get_socket_error()}) end if
while not find(get_key(),{ESCAPE,'q','Q'}) do
    {integer code} = select({sock},{},{},250000)    -- (0.25s)
    if code=SOCKET_ERROR then crash("select (%v)",{get_socket_error()}) end if
    if code>0 then  -- (not timeout)
        atom peer = accept(sock),
             ip = getsockaddr(peer)
        {integer len, string request} = recv(peer)
        printf(1,"Client IP: %s\n%s\n",{ip_to_string(ip),request})
        if length(request)>3 and request[1..4]="GET " then
            integer bytes_sent = send(peer,response)
            printf(1,"%d bytes successfully sent\n",bytes_sent)
        end if
        shutdown(peer, SD_SEND) -- tell curl it's over
        peer = closesocket(peer)  --    (as does this)
    end if
end while
sock = closesocket(sock)
WSACleanup()
