Hello world/Web server: Difference between revisions

From Rosetta Code
Content added Content deleted
(→‎{{header|Python}}: Added `http.server` example.)
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(44 intermediate revisions by 25 users not shown)
Line 29: Line 29:
{{libheader|AWS}}
{{libheader|AWS}}
Uses many defaults, such as 5 max simultaneous connections.
Uses many defaults, such as 5 max simultaneous connections.
<lang ada>
<syntaxhighlight lang="ada">
with AWS; use AWS;
with AWS; use AWS;
with AWS.Response;
with AWS.Response;
Line 49: Line 49:
Server.Shutdown (TheServer);
Server.Shutdown (TheServer);
end HelloHTTP;
end HelloHTTP;
</syntaxhighlight>
</lang>


=={{header|Aime}}==
=={{header|Aime}}==
Goodbye, world! with random colors and socket polling:
Goodbye, world! with random colors and socket polling:
<lang aime>void
<syntaxhighlight lang="aime">void
serve(dispatch w, file s, list colors)
serve(dispatch w, file s, list colors)
{
{
Line 86: Line 86:


return 0;
return 0;
}</lang>
}</syntaxhighlight>
Or simply:
Or simply:
<lang aime>file i, o, s;
<syntaxhighlight lang="aime">file i, o, s;


tcpip_listen(s, 8080, 0);
tcpip_listen(s, 8080, 0);
Line 98: Line 98:
"<body><h1>Goodbye, world!</h1></body></html>\n");
"<body><h1>Goodbye, world!</h1></body></html>\n");
f_flush(o);
f_flush(o);
}</lang>
}</syntaxhighlight>

=={{header|Amazing Hopper}}==
VERSION 1: "Hopper" flavour:
<syntaxhighlight lang="amazing hopper">
// Hello world! mode Server

#include <hopper.h>
main:
fd=0,fdc=0,message=""
{"HTTP/1.1 200 OK\n","Content-Type: text/html; charset=UTF-8\n\n"}cat
{"<!DOCTYPE html><html><head><title>Bye-bye baby bye-bye</title>"},cat
{"<style>body { background-color: #111 },cat
{"h1 { font-size:4cm; text-align: center; color: black; text-shadow: 0 0 2mm red}</style>"}cat
{"</head><body><h1>Goodbye, world!</h1></body></html>\n"}cat,
mov(message)

/* Open socket in localhost (by default) */
/* Accept 5 conections (there are also 5 by default, if you put "any weá" there) */
{5,8080}socket (OPENTCPSRV), mov(fd)

/* accept conection & send message */
accept(fd), mov(fdc)
{message},send(fdc)

/* close all */
{fdc}socket(CLOSESOCK)
{fd}socket(CLOSESOCK)
exit(0)
</syntaxhighlight>
VERSION 2: "Hopper-BASIC" flavour
<syntaxhighlight lang="amazing hopper">
// Hello world! mode Server: desde el navegador, escriba localhost:8080

#include <hbasic.h>
Begin
Declare as Numeric (fd,fdc)
as Alpha (message,HEAD,head,body,form,html)
Let ( HEAD := Cat$("HTTP/1.1 200 OK\n","Content-Type: text/html; charset=UTF-8\n\n") + ("<!DOCTYPE html>\n") )

ParsNormal$("title","","Bye-bye baby bye-bye")(head)
ParsNormal$("style","","body { background-color: #111 } h1 { font-size:4cm; text-align: center; color: black; text-shadow: 0 0 2mm red}")(head)
ParsNormal$("head","",head)(html)
ParsNormal$("h1","","Goodbye, world!")(body)
ParsNormal$("body","",body)(html)
ParsNormal$("html","",html)(form)
Let( form := Cat$(HEAD,form))
Let( message := Tran$(">\n<","><", form) )
Print( message, Newl)

/* Open socket in localhost (by default) */
Let( fd := OpenServerTCP(3,8080) )

/* accept conection & send message */
Let( fdc := Accept(fd) )
Send(message,fdc)

/* close all */
CloseSocket(fdc)
CloseSocket(fd)
End
</syntaxhighlight>
{{out}}
<pre>Open your browser, and type in the navigation bar: "localhost: 8080": It will show "Goodbye World!" in huge letters and adorable lovecraftian colors!
</pre>


=={{header|AntLang}}==
=={{header|AntLang}}==
In plain AntLang:
In plain AntLang:
<lang AntLang>serv: httprun[8080; {"HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\n\r\nGoodbye, World!"}]</lang>
<syntaxhighlight lang="antlang">serv: httprun[8080; {"HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\n\r\nGoodbye, World!"}]</syntaxhighlight>


Using ALC:
Using ALC:
<lang AntLang>load["handlers.ant"]
<syntaxhighlight lang="antlang">load["handlers.ant"]
serv: httprun[8080; {httpwrap["Goodbye, World!"]}]</lang>
serv: httprun[8080; {httpwrap["Goodbye, World!"]}]</syntaxhighlight>


To close the server:
To close the server:
<lang AntLang>kill[serv]</lang>
<syntaxhighlight lang="antlang">kill[serv]</syntaxhighlight>

=={{header|Arturo}}==

<syntaxhighlight lang="rebol">serve.port:8080 [ GET "/" -> "Goodbye, World!" ]</syntaxhighlight>

{{out}}

If you navigate to "localhost:8080" through our web browser, we'll see the message:

<pre>Goodbye, World!</pre>


=={{header|AutoIt}}==
=={{header|AutoIt}}==
<syntaxhighlight lang="autoit">
<lang AutoIt>
TCPStartup()
TCPStartup()
$socket = TCPListen("0.0.0.0",8080)
$socket = TCPListen("0.0.0.0",8080)
Line 130: Line 209:
TCPCloseSocket($newConnection)
TCPCloseSocket($newConnection)
WEnd
WEnd
</syntaxhighlight>
</lang>


=={{header|AWK}}==
=={{header|AWK}}==
Line 137: Line 216:
[http://www.gnu.org/software/gawk/manual/gawkinet/gawkinet.html#Primitive-Service]
[http://www.gnu.org/software/gawk/manual/gawkinet/gawkinet.html#Primitive-Service]
(Documentation is licensed under GNU Free Documentation License, Version 1.3)
(Documentation is licensed under GNU Free Documentation License, Version 1.3)
<lang AWK>#!/usr/bin/gawk -f
<syntaxhighlight lang="awk">#!/usr/bin/gawk -f
BEGIN {
BEGIN {
RS = ORS = "\r\n"
RS = ORS = "\r\n"
Line 151: Line 230:
continue;
continue;
close(HttpService)
close(HttpService)
}</lang>
}</syntaxhighlight>


=={{header|BaCon}}==
=={{header|BASIC}}==
==={{header|BaCon}}===
<lang qbasic>' Define HTTP constants
Requires BaCon 4.2 or higher.
<syntaxhighlight lang="bacon">' Define HTTP constants
CONST New$ = CHR$(13) & NL$
CONST New$ = CHR$(13) & NL$
CONST Sep$ = CHR$(13) & NL$ & CHR$(13) & NL$
CONST Sep$ = CHR$(13) & NL$ & CHR$(13) & NL$
Line 165: Line 246:
' Ignore child signals to avoid zombie processes
' Ignore child signals to avoid zombie processes
SIGNAL SIG_IGN, SIGCHLD
SIGNAL SIG_IGN, SIGCHLD

' Open listening port
OPEN Ip$ & ":8080" FOR SERVER AS mynet


' Keep receiving requests
' Keep receiving requests
WHILE TRUE
WHILE TRUE


' Handle for newly incoming connection
' Open listening port
OPEN Ip$ & ":8080" FOR SERVER AS mynet
fd = ACCEPT(mynet)


' Incoming connection -> create background process
' Incoming connection -> create background process
Line 180: Line 264:
' Get the request
' Get the request
REPEAT
REPEAT
RECEIVE dat$ FROM mynet
RECEIVE dat$ FROM fd
PRINT dat$
PRINT dat$
UNTIL RIGHT$(dat$, 4) = Sep$
UNTIL RIGHT$(dat$, 4) = Sep$


' Reply that we're OK
' Reply that we're OK
SEND "HTTP/1.1 200 Ok" & New$ & "Content-Length: " & STR$(LEN(Msg$)) & Sep$ & Msg$ TO mynet
SEND "HTTP/1.1 200 Ok" & New$ & "Content-Length: " & STR$(LEN(Msg$)) & Sep$ & Msg$ TO fd


' Close connection
' Close connection
CLOSE SERVER mynet
CLOSE SERVER fd


' End this process
' End this process
END
ENDFORK

' We are in the parent
ELIF spawn > 0 THEN

' Close connection in parent
CLOSE SERVER mynet

ENDIF
ENDIF
WEND</syntaxhighlight>
WEND
</lang>


=={{header|BBC BASIC}}==
==={{header|BBC BASIC}}===
{{works with|BBC BASIC for Windows}}
{{works with|BBC BASIC for Windows}}
This explicitly supports multiple concurrent connections.
This explicitly supports multiple concurrent connections.
<lang bbcbasic> INSTALL @lib$+"SOCKLIB"
<syntaxhighlight lang="bbcbasic"> INSTALL @lib$+"SOCKLIB"
PROC_initsockets
PROC_initsockets
Line 267: Line 343:
WAIT 0
WAIT 0
UNTIL FALSE
UNTIL FALSE
END</lang>
END</syntaxhighlight>


=={{header|C}}==
=={{header|C}}==
This is, um, slightly longer than what other languages would be.
This is, um, slightly longer than what other languages would be.
<lang C>#include <stdio.h>
<syntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <unistd.h>
#include <unistd.h>
Line 324: Line 400:
close(client_fd);
close(client_fd);
}
}
}</lang>
}</syntaxhighlight>


=={{header|C++}}==
C version compiles as C++ (known for G++ on Linux)
=={{header|C sharp|C#}}==
=={{header|C sharp|C#}}==
<lang CSharp>using System.Text;
<syntaxhighlight lang="csharp">using System.Text;
using System.Net.Sockets;
using System.Net.Sockets;
using System.Net;
using System.Net;
Line 355: Line 429:
}
}
}
}
}</lang>
}</syntaxhighlight>
{{works with|NancyFX}}<lang CSharp>namespace Webserver
{{works with|NancyFX}}<syntaxhighlight lang="csharp">namespace Webserver
{
{
using System;
using System;
Line 381: Line 455:
}
}
}
}
}</lang>
}</syntaxhighlight>

=={{header|C++}}==
C version compiles as C++ (known for G++ on Linux)


=={{header|Clojure}}==
=={{header|Clojure}}==
Line 389: Line 466:


File: src/goodbye_world/handler.clj
File: src/goodbye_world/handler.clj
<lang clojure>(ns goodbye-world.handler
<syntaxhighlight lang="clojure">(ns goodbye-world.handler
(:require [compojure.core :refer :all]
(:require [compojure.core :refer :all]
[compojure.handler :as handler]
[compojure.handler :as handler]
Line 400: Line 477:


(def app
(def app
(handler/site app-routes))</lang>
(handler/site app-routes))</syntaxhighlight>


To start up the server on port 8080, run the following from the project's root:
To start up the server on port 8080, run the following from the project's root:
Line 410: Line 487:
Here's the example with a pre-built server:
Here's the example with a pre-built server:


<lang lisp>(ql:quickload :hunchentoot)
<syntaxhighlight lang="lisp">(ql:quickload :hunchentoot)
(defpackage :hello-web (:use :cl :hunchentoot))
(defpackage :hello-web (:use :cl :hunchentoot))
(in-package :hello-web)
(in-package :hello-web)
Line 416: Line 493:
(define-easy-handler (hello :uri "/") () "Goodbye, World!")
(define-easy-handler (hello :uri "/") () "Goodbye, World!")


(defparameter *server* (hunchentoot:start (make-instance 'hunchentoot:easy-acceptor :port 8080)))</lang>
(defparameter *server* (hunchentoot:start (make-instance 'hunchentoot:easy-acceptor :port 8080)))</syntaxhighlight>


----
----
Line 422: Line 499:
Here's an example of doing everything manually
Here's an example of doing everything manually


<lang lisp>(ql:quickload :usocket)
<syntaxhighlight lang="lisp">(ql:quickload :usocket)
(defpackage :hello-web-manual (:use :cl :usocket))
(defpackage :hello-web-manual (:use :cl :usocket))
(in-package :hello-web-manual)
(in-package :hello-web-manual)
Line 459: Line 536:
(loop for c in connections do (loop while (socket-close c))))))
(loop for c in connections do (loop while (socket-close c))))))


(serve 8080)</lang>
(serve 8080)</syntaxhighlight>


=={{header|Crystal}}==
=={{header|Crystal}}==


<lang crystal>
<syntaxhighlight lang="crystal">
require "http/server"
require "http/server"


server = HTTP::Server.new(8080) do |context|
server = HTTP::Server.new do |context|
context.response.print "Goodbye World"
context.response.print "Goodbye World"
end
end


server.listen
server.listen(8080)
</syntaxhighlight>
</lang>


=={{header|D}}==
=={{header|D}}==
Using sockets only, also shows use of heredoc syntax, std.array.replace,
Using sockets only, also shows use of heredoc syntax and std.array.replace.
''If you copy from this page, be careful with extraneous spaces on the empty lines in the heredoc''.
and casting to bool to satisfy the while conditional.


<syntaxhighlight lang="d">import std.socket, std.array;
<lang D>
import std.socket, std.array;


ushort port = 8080;
ushort port = 8080;
Line 489: Line 565:
Socket currSock;
Socket currSock;


while(cast(bool)(currSock = listener.accept())) {
while (null !is (currSock = listener.accept())) {
currSock.sendTo(replace(q"EOF
currSock.sendTo(replace(q"EOF
HTTP/1.1 200 OK
HTTP/1.1 200 OK
Line 495: Line 571:


<html>
<html>
<head><title>Hello, world!</title></head>
<head><title>Hello world</title></head>
<body>Hello, world!</body>
<body>Goodbye, World!</body>
</html>
</html>
EOF", "\n", "\r\n"));
EOF", "\n", "\r\n"));
Line 502: Line 578:
}
}
}
}
</syntaxhighlight>
</lang>


=={{header|Dart}}==
=={{header|Dart}}==
<lang d>import 'dart:io';
<syntaxhighlight lang="d">import 'dart:io';


main() async {
main() async {
Line 515: Line 591:
..close();
..close();
}
}
}</lang>
}</syntaxhighlight>


=={{header|Delphi}}==
=={{header|Delphi}}==
<lang Delphi>program HelloWorldWebServer;
<syntaxhighlight lang="delphi">program HelloWorldWebServer;


{$APPTYPE CONSOLE}
{$APPTYPE CONSOLE}
Line 567: Line 643:
lWebServer.Free;
lWebServer.Free;
end;
end;
end.</lang>
end.</syntaxhighlight>


=={{header|Dylan.NET|Dylan.NET}}==
=={{header|Dylan.NET|Dylan.NET}}==
<syntaxhighlight lang="dylan.net">
<lang Dylan.NET>
//compile with dylan.NET 11.5.1.2 or later!!
//compile with dylan.NET 11.5.1.2 or later!!
#refstdasm "mscorlib.dll"
#refstdasm "mscorlib.dll"
Line 607: Line 683:


end namespace
end namespace
</syntaxhighlight>
</lang>


=={{header|Erlang}}==
=={{header|Erlang}}==
Line 614: Line 690:
I fail to see how a longer time will serve any purpose.
I fail to see how a longer time will serve any purpose.


<syntaxhighlight lang="erlang">
<lang Erlang>
-module( hello_world_web_server ).
-module( hello_world_web_server ).


Line 636: Line 712:
timer:sleep( 30000 ),
timer:sleep( 30000 ),
httpd_stop( Pid ).
httpd_stop( Pid ).
</syntaxhighlight>
</lang>


=={{header|Fantom}}==
=={{header|Fantom}}==
<lang fantom>using web
<syntaxhighlight lang="fantom">using web
using wisp
using wisp


Line 663: Line 739:
while (true) {} // stay running
while (true) {} // stay running
}
}
}</lang>
}</syntaxhighlight>


=={{header|Fortran}}==
=={{header|Fortran}}==
There is no network library in fortran. Use C interoperability and some C compatible library or just start node.js simple web server:
There is no network library in fortran. Use C interoperability and some C compatible library or just start node.js simple web server:
<lang fortran>
<syntaxhighlight lang="fortran">
program http_example
program http_example
implicit none
implicit none
Line 682: Line 758:


end program http_example
end program http_example
</syntaxhighlight>
</lang>


=={{header|Free Pascal}}==
=={{header|Free Pascal}}==
<lang pascal>program HelloWorldServer;
<syntaxhighlight lang="pascal">program HelloWorldServer;
{$mode objfpc}{$H+}
{$mode objfpc}{$H+}
uses
uses
Line 726: Line 802:
Serv.Free;
Serv.Free;
end;
end;
end.</lang>
end.</syntaxhighlight>


=={{header|Frink}}==
Frink has a web server platform that runs in a Java servlet container called [https://frinklang.org/fspdocs.html Frink Server Pages] which should be used for real-world applications. However, the following is a simple single-threaded web server for the purposes of this task.
<syntaxhighlight lang="frink">ss = newJava["java.net.ServerSocket", 8080]
while true
{
sock = ss.accept[];
w = new Writer[sock.getOutputStream[]]
w.println["HTTP/1.1 200 OK"]
w.println["Content-Type: text/plain\n"]
w.println["Goodbye, World!"]
w.close[]
}</syntaxhighlight>


=={{header|FunL}}==
=={{header|FunL}}==
<lang funl>native java.io.PrintWriter
<syntaxhighlight lang="funl">native java.io.PrintWriter
native java.net.ServerSocket
native java.net.ServerSocket


Line 741: Line 831:
PrintWriter( socket.getOutputStream(), true ).println( 'hello world' )
PrintWriter( socket.getOutputStream(), true ).println( 'hello world' )
socket.shutdownOutput()
socket.shutdownOutput()
socket.close()</lang>
socket.close()</syntaxhighlight>


=={{header|Gastona}}==
=={{header|Gastona}}==
Line 747: Line 837:
following the server activity and also being able to quit it by closing the window.
following the server activity and also being able to quit it by closing the window.
But it is not stritctly needed, just the unit #listix# would do the job.
But it is not stritctly needed, just the unit #listix# would do the job.
<lang gastona>#javaj#
<syntaxhighlight lang="gastona">#javaj#


<frames> oConsole
<frames> oConsole
Line 760: Line 850:
// Goodbye world!
// Goodbye world!
//</body></html>
//</body></html>
</syntaxhighlight>
</lang>

=={{header|Genie}}==
<syntaxhighlight lang="genie">/**
* Based on https://wiki.gnome.org/Projects/Genie/GIONetworkingSample
* Based on an example of Jezra Lickter http://hoof.jezra.net/snip/nV
*
* valac --pkg gio-2.0 --pkg gee-0.8 webserver.gs
* ./webserver
*/
[indent=8]
uses
GLib
Gee

init
var ws = new WebServer()
ws.run()

struct Request
full_request : string
path : string
query : string

struct Response
status_code : string
content_type : string
data : string

class WebServer

def run()
port : uint16 = 8080
tss : ThreadedSocketService = new ThreadedSocketService(100)
ia : InetAddress = new InetAddress.any(SocketFamily.IPV4)
isaddr : InetSocketAddress = new InetSocketAddress(ia, port)
try
tss.add_address(isaddr, SocketType.STREAM, SocketProtocol.TCP, null, null);
except e : Error
stderr.printf("%s\n", e.message)
return
// add connection handler
tss.run.connect( connection_handler )

ml : MainLoop = new MainLoop()
tss.start()
stdout.printf("Serving on port %d\n", port)
ml.run()

def connection_handler ( conn : SocketConnection ) : bool
first_line : string = ""
size : size_t = 0;
request : Request = Request()
dis : DataInputStream = new DataInputStream (conn.input_stream)
dos : DataOutputStream = new DataOutputStream (conn.output_stream)
try
first_line = dis.read_line(out size)
// here you could analyze request information
var parts = first_line.split(" ");
if parts.length > 1 do request.full_request = parts[1]
except e : Error
stderr.printf("%s\n", e.message)
response : Response = Response()
response.status_code = "HTTP/1.1 200 OK\n"
response.content_type = "text/html"
response.data = "<html><body><h1>Goodbye, World!</h1></body></html>"
serve_response ( response, dos )
return false

def serve_response ( response : Response, dos : DataOutputStream )
try
dos.put_string (response.status_code)
dos.put_string ("Server: Genie Socket\n")
dos.put_string("Content-Type: %s\n".printf(response.content_type))
dos.put_string("Content-Length: %d\n".printf(response.data.length))
dos.put_string("\n");//this is the end of the return headers
dos.put_string(response.data)
except e : Error
stderr.printf("%s\n", e.message)</syntaxhighlight>

{{out}}
<pre>prompt$ valac --pkg gio-2.0 --pkg gee-0.8 webserver.gs
prompt$ ./webserver
Serving on port 8080</pre>
Showing
<pre>prompt$ curl http://localhost:8080
<html><body><h1>Goodbye, World!</h1></body></html></pre>


=={{header|Go}}==
=={{header|Go}}==
<lang go>package main
<syntaxhighlight lang="go">package main


import (
import (
Line 777: Line 953:
log.Fatal(http.ListenAndServe(":8080", nil))
log.Fatal(http.ListenAndServe(":8080", nil))
}
}
</syntaxhighlight>
</lang>


=={{header|Haskell}}==
=={{header|Haskell}}==
Line 784: Line 960:
using the [http://www.yesodweb.com/book/conduits conduit] stack:
using the [http://www.yesodweb.com/book/conduits conduit] stack:


<lang haskell>{-# LANGUAGE OverloadedStrings #-}
<syntaxhighlight lang="haskell">{-# LANGUAGE OverloadedStrings #-}


import Data.ByteString.Char8 ()
import Data.ByteString.Char8 ()
Line 792: Line 968:
main :: IO ()
main :: IO ()
main = runTCPServer (ServerSettings 8080 "127.0.0.1") $ const (yield response $$)
main = runTCPServer (ServerSettings 8080 "127.0.0.1") $ const (yield response $$)
where response = "HTTP/1.0 200 OK\nContent-Length: 16\n\nGoodbye, World!\n"</lang>
where response = "HTTP/1.0 200 OK\nContent-Length: 16\n\nGoodbye, World!\n"</syntaxhighlight>


Or using only "standard" features ([http://hackage.haskell.org/package/base base], [http://hackage.haskell.org/package/bytestring bytestring] and [http://hackage.haskell.org/package/network network] from the [http://hackage.haskell.org/platform/ Haskell Platform]):
Or using only "standard" features ([http://hackage.haskell.org/package/base base], [http://hackage.haskell.org/package/bytestring bytestring] and [http://hackage.haskell.org/package/network network] from the [http://hackage.haskell.org/platform/ Haskell Platform]):


<lang haskell>{-# LANGUAGE OverloadedStrings #-}
<syntaxhighlight lang="haskell">{-# LANGUAGE OverloadedStrings #-}


import Data.ByteString.Char8 ()
import Data.ByteString.Char8 ()
Line 810: Line 986:
loop s = forever $ forkIO . request . fst =<< accept s
loop s = forever $ forkIO . request . fst =<< accept s
request c = sendAll c response `finally` sClose c
request c = sendAll c response `finally` sClose c
response = "HTTP/1.0 200 OK\nContent-Length: 16\n\nGoodbye, World!\n"</lang>
response = "HTTP/1.0 200 OK\nContent-Length: 16\n\nGoodbye, World!\n"</syntaxhighlight>


Both works like this:
Both works like this:
Line 824: Line 1,000:
Or using warp ([http://hackage.haskell.org/package/warp warp] [https://wiki.haskell.org/Web/Servers#Warp warp example] [http://aosabook.org/en/posa/warp.html about warp]):
Or using warp ([http://hackage.haskell.org/package/warp warp] [https://wiki.haskell.org/Web/Servers#Warp warp example] [http://aosabook.org/en/posa/warp.html about warp]):


<lang haskell>{-# LANGUAGE OverloadedStrings #-}
<syntaxhighlight lang="haskell">{-# LANGUAGE OverloadedStrings #-}
import Network.Wai
import Network.Wai
Line 843: Line 1,019:
index x = responseBuilder status200 [("Content-Type", "text/plain")] $ mconcat $ map copyByteString
index x = responseBuilder status200 [("Content-Type", "text/plain")] $ mconcat $ map copyByteString
[ "Hello World!\n" ]</lang>
[ "Hello World!\n" ]</syntaxhighlight>


Work like this:
Work like this:
Line 868: Line 1,044:
=={{header|Io}}==
=={{header|Io}}==


<syntaxhighlight lang="io">
<lang io>
WebRequest := Object clone do(
WebRequest := Object clone do(
handleSocket := method(aSocket,
handleSocket := method(aSocket,
Line 884: Line 1,060:


WebServer start
WebServer start
</syntaxhighlight>
</lang>


=={{header|J}}==
=={{header|J}}==
Line 890: Line 1,066:
would be to [http://www.jsoftware.com/stable.htm download] [http://www.jsoftware.com/docs/help701/user/relhigh.htm j7], edit the jhs script to start on port 8080,
would be to [http://www.jsoftware.com/stable.htm download] [http://www.jsoftware.com/docs/help701/user/relhigh.htm j7], edit the jhs script to start on port 8080,
start jhs, visit http://127.0.0.1:8080/jijx then enter the text:
start jhs, visit http://127.0.0.1:8080/jijx then enter the text:
<lang j>'Goodbye, World!'</lang>
<syntaxhighlight lang="j">'Goodbye, World!'</syntaxhighlight>
This will compute the desired result and display it (actually, it will be displayed twice since the original string will also be displayed).
This will compute the desired result and display it (actually, it will be displayed twice since the original string will also be displayed).
This would be even simpler if you could just use the default jhs port (65001)...
This would be even simpler if you could just use the default jhs port (65001)...
Line 900: Line 1,076:
For example, here is a web server which ignores the client's request
For example, here is a web server which ignores the client's request
and always returns Goodbye, World:
and always returns Goodbye, World:
<lang j>hello=: verb define
<syntaxhighlight lang="j">hello=: verb define
8080 hello y NB. try to use port 8080 by default
8080 hello y NB. try to use port 8080 by default
:
:
Line 926: Line 1,102:
responseFor=: dyad define
responseFor=: dyad define
'HTTP/1.0 200 OK',CRLF,'Content-Type: text/plain',CRLF,CRLF,'Goodbye, World!',CRLF
'HTTP/1.0 200 OK',CRLF,'Content-Type: text/plain',CRLF,CRLF,'Goodbye, World!',CRLF
)</lang>
)</syntaxhighlight>
To deploy this server, once it has been defined, run
To deploy this server, once it has been defined, run
<lang j>hello''</lang>
<syntaxhighlight lang="j">hello''</syntaxhighlight>
This version works because reasonable http requests fit in a single tcp packet.
This version works because reasonable http requests fit in a single tcp packet.
(And note that the server waits for one tcp packet before responding.)
(And note that the server waits for one tcp packet before responding.)
Line 936: Line 1,112:
Multiple requests will be served in the order that they reach the server,
Multiple requests will be served in the order that they reach the server,
with a queue size limit of 50 waiting requests imposed by default in the <code>ServerSocket</code> class (may be changed by adding a second positive integer argument to the <code>ServerSocket</code> constructor).
with a queue size limit of 50 waiting requests imposed by default in the <code>ServerSocket</code> class (may be changed by adding a second positive integer argument to the <code>ServerSocket</code> constructor).
<lang java>import java.io.IOException;
<syntaxhighlight lang="java">import java.io.IOException;
import java.io.PrintWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.ServerSocket;
Line 951: Line 1,127:
}
}
}
}
}</lang>
}</syntaxhighlight>


=={{header|JavaScript}}==
=={{header|JavaScript}}==
Line 957: Line 1,133:
{{works with|Node.js}}
{{works with|Node.js}}


<lang javascript>var http = require('http');
<syntaxhighlight lang="javascript">var http = require('http');


http.createServer(function (req, res) {
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Goodbye, World!\n');
res.end('Goodbye, World!\n');
}).listen(8080, '127.0.0.1');</lang>
}).listen(8080, '127.0.0.1');</syntaxhighlight>


It scales:
It scales:
Line 994: Line 1,170:
=={{header|Julia}}==
=={{header|Julia}}==
Requires the HttpServer package to have previously been installed with 'Pkg.add("HttpServer")'
Requires the HttpServer package to have previously been installed with 'Pkg.add("HttpServer")'
<lang Julia>using HttpServer
<syntaxhighlight lang="julia">using HttpServer
server = Server() do req, res
server = Server() do req, res
"Goodbye, World!"
"Goodbye, World!"
end
end
run(server, 8080)
run(server, 8080)
</syntaxhighlight>
</lang>


=={{header|Kotlin}}==
=={{header|Kotlin}}==
{{trans|Java}}
{{trans|Java}}
<lang scala>import java.io.PrintWriter
<syntaxhighlight lang="scala">import java.io.PrintWriter
import java.net.ServerSocket
import java.net.ServerSocket


Line 1,013: Line 1,189:
sock.close()
sock.close()
}
}
}</lang>
}</syntaxhighlight>


=={{header|Lasso}}==
=={{header|Lasso}}==
Line 1,019: Line 1,195:
here's how you can create a basic multi-threaded webserver
here's how you can create a basic multi-threaded webserver
of your own to complete this request:
of your own to complete this request:
<lang lasso>local(server) = net_tcp
<syntaxhighlight lang="lasso">local(server) = net_tcp
handle => { #server->close }
handle => { #server->close }
#server->bind(8080) & listen & forEachAccept => {
#server->bind(8080) & listen & forEachAccept => {
Line 1,038: Line 1,214:
#con->writeBytes(bytes(#response))
#con->writeBytes(bytes(#response))
}
}
}</lang>
}</syntaxhighlight>


=={{header|Liberty BASIC}}==
=={{header|Liberty BASIC}}==
Line 1,044: Line 1,220:
but it's close relative ''Run BASIC'' is designed for serving webpages easily.
but it's close relative ''Run BASIC'' is designed for serving webpages easily.
The task becomes simply ..
The task becomes simply ..
<lang lb>print "hello world!" </lang>
<syntaxhighlight lang="lb">print "hello world!" </syntaxhighlight>

=={{header|Lua}}==
{{works with|lua|5.2.4}}
{{libheader|LuaSocket}}
<syntaxhighlight lang="lua">local socket = require "socket"
local headers = "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\nContent-Length: %d\r\n\r\n%s"
local content = "<!doctype html><html><title>Goodbye, World!</title><h1>Goodbye, World!"
local server = assert(socket.bind("localhost", 8080))
repeat
local client = server:accept()
local ok = client:send(string.format(headers, #content, content))
client:close()
until not client or not ok
server:close()</syntaxhighlight>

=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">listener =
SocketListen["127.0.0.1:8080",
Function[{assoc},
With[{client = assoc["SourceSocket"]},
WriteString[client,
"HTTP/1.0 200 OK\nContent-Length: 16\n\nGoodbye, World!\n"];
Close[client]]]]
SystemOpen["http://127.0.0.1:8080"]</syntaxhighlight>
Clean up:
<syntaxhighlight lang="mathematica">DeleteObject[listener];
Close[listener["Socket"]]</syntaxhighlight>

=={{header|min}}==
{{works with|min|0.37.0}}
<syntaxhighlight lang="min">{
(
{
{"text/plain; charset=utf-8" :content-type} :headers
"Goodbye, World!" :body
}
) :handler
8080 :port
} start-server</syntaxhighlight>


=={{header|Modula-2}}==
=={{header|Modula-2}}==
This is a CGI executable:
This is a CGI executable:
<lang>
<syntaxhighlight lang="text">
MODULE access;
MODULE access;


Line 1,060: Line 1,275:
WriteLn
WriteLn
END access.
END access.
</syntaxhighlight>
</lang>


=={{header|NetRexx}}==
=={{header|NetRexx}}==
{{Trans|Java}}
{{Trans|Java}}
<lang NetRexx>/* NetRexx */
<syntaxhighlight lang="netrexx">/* NetRexx */
options replace format comments java crossref symbols binary
options replace format comments java crossref symbols binary


Line 1,101: Line 1,316:
end listener
end listener
return
return
</syntaxhighlight>
</lang>


=={{header|Nim}}==
=={{header|Nim}}==
<lang nim>import asynchttpserver, asyncdispatch
<syntaxhighlight lang="nim">import asynchttpserver, asyncdispatch


proc cb(req: Request) {.async.} =
proc cb(req: Request) {.async.} =
Line 1,111: Line 1,326:
asyncCheck newAsyncHttpServer().serve(Port(8080), cb)
asyncCheck newAsyncHttpServer().serve(Port(8080), cb)
runForever()
runForever()
</syntaxhighlight>
</lang>


=={{header|Objeck}}==
=={{header|Objeck}}==
<lang objeck>
<syntaxhighlight lang="objeck">
use Net;
use Net;
use Concurrency;
use Concurrency;
Line 1,133: Line 1,348:
}
}
}
}
</syntaxhighlight>
</lang>


=={{header|OCaml}}==
=={{header|OCaml}}==
This code is derived from this [http://ocamlunix.forge.ocamlcore.org/sockets.html#htoc54 ocaml-unix documentation].
This code is derived from this [http://ocamlunix.forge.ocamlcore.org/sockets.html#htoc54 ocaml-unix documentation].
<lang ocaml>let try_finalise f x finally y =
<syntaxhighlight lang="ocaml">let try_finalise f x finally y =
let res = try f x with e -> finally y; raise e in
let res = try f x with e -> finally y; raise e in
finally y;
finally y;
Line 1,193: Line 1,408:


let _ =
let _ =
Unix.handle_unix_error server ()</lang>
Unix.handle_unix_error server ()</syntaxhighlight>


=={{header|Ol}}==
=={{header|Ol}}==
This sample sends 200 OK on any request and echoes the request headers.
This sample sends 200 OK on any request and echoes the request headers.
<lang ol>(import (lib http))
<syntaxhighlight lang="ol">(import (lib http))


(http:run 8080 (lambda (fd request headers send close)
(http:run 8080 (lambda (fd request headers send close)
Line 1,211: Line 1,426:
(close #t)
(close #t)
))
))
</syntaxhighlight>
</lang>


=={{header|Opa}}==
=={{header|Opa}}==
From [http://doc.opalang.org/index.html#_a_first_peek_at_opa Opa documentation]:
From [http://doc.opalang.org/index.html#_a_first_peek_at_opa Opa documentation]:
<lang ocaml>server = one_page_server("Hello", -> <>Goodbye, world</>)</lang>
<syntaxhighlight lang="ocaml">server = one_page_server("Hello", -> <>Goodbye, world</>)</syntaxhighlight>
Compile and run:
Compile and run:
<lang bash>opa file.opa --</lang>
<syntaxhighlight lang="bash">opa file.opa --</syntaxhighlight>


=={{header|Panda}}==
=={{header|Panda}}==
Using the command line client. Listen to port 8080. For each request a request object is returned, we ignore this and just use it to send message which will be the response.
Using the command line client. Listen to port 8080. For each request a request object is returned, we ignore this and just use it to send message which will be the response.


<lang panda>8080.port.listen.say("Hello world!")</lang>
<syntaxhighlight lang="panda">8080.port.listen.say("Hello world!")</syntaxhighlight>


=={{header|Perl}}==
=={{header|Perl}}==
<lang Perl>use Socket;
<syntaxhighlight lang="perl">use Socket;


my $port = 8080;
my $port = 8080;
Line 1,249: Line 1,464:
"<html><head><title>Goodbye, world!</title></head><body>Goodbye, world!</body></html>\r\n";
"<html><head><title>Goodbye, world!</title></head><body>Goodbye, world!</body></html>\r\n";
close CLIENT;
close CLIENT;
}</lang>
}</syntaxhighlight>
Various modules exist for using sockets, including the popular IO::Socket
Various modules exist for using sockets, including the popular IO::Socket
which provides a simpler and more friendly OO interface for the socket layer.
which provides a simpler and more friendly OO interface for the socket layer.
Here is the solution using this module:
Here is the solution using this module:
{{libheader|IO::Socket::INET}}
{{libheader|IO::Socket::INET}}
<lang Perl>use IO::Socket::INET;
<syntaxhighlight lang="perl">use IO::Socket::INET;


my $sock = new IO::Socket::INET ( LocalAddr => "127.0.0.1:8080",
my $sock = new IO::Socket::INET ( LocalAddr => "127.0.0.1:8080",
Line 1,265: Line 1,480:
"<html><head><title>Goodbye, world!</title></head><body>Goodbye, world!</body></html>\r\n";
"<html><head><title>Goodbye, world!</title></head><body>Goodbye, world!</body></html>\r\n";
close $client;
close $client;
}</lang>
}</syntaxhighlight>


Using Perl's glue power, provide a suicide note
Using Perl's glue power, provide a note
with visitor counter via netcat:
with visitor counter via netcat:
<lang Perl>while (++(our $vn)) {
<syntaxhighlight lang="perl">while (++(our $vn)) {
open NC, "|-", qw(nc -l -p 8080 -q 1);
open NC, "|-", qw(nc -l -p 8080 -q 1);
print NC "HTTP/1.0 200 OK\xd\xa",
print NC "HTTP/1.0 200 OK\xd\xa",
"Content-type: text/plain; charset=utf-8\xd\xa\xd\xa",
"Content-type: text/plain; charset=utf-8\x0d\x0a\x0d\x0a",
"Goodbye, World! (hello, visitor No. $vn!)\xd\xa";
"Goodbye, World! (hello, visitor No. $vn!)\x0d\x0a";
}</lang>
}</syntaxhighlight>


Here's another solution using Plack (may be found on CPAN):
Here's another solution using Plack (may be found on CPAN):
<lang Perl>use Plack::Runner;
<syntaxhighlight lang="perl">use Plack::Runner;
my $app = sub {
my $app = sub {
return [ 200,
return [ 200,
Line 1,286: Line 1,501:
my $runner = Plack::Runner->new;
my $runner = Plack::Runner->new;
$runner->parse_options('--host' => 'localhost', '--port' => 8080);
$runner->parse_options('--host' => 'localhost', '--port' => 8080);
$runner->run($app);</lang>
$runner->run($app);</syntaxhighlight>


When using plackup, then this may be compressed to one line:
When using plackup, then this may be compressed to one line:
<lang perl>my $app = sub { return [ 200, [ 'Content-Type' => 'text/html; charset=UTF-8' ], [ '<html><head><title>Goodbye, world!</title></head><body>Goodbye, world!</body></html>' ] ] };</lang>
<syntaxhighlight lang="perl">my $app = sub { return [ 200, [ 'Content-Type' => 'text/html; charset=UTF-8' ], [ '<html><head><title>Goodbye, world!</title></head><body>Goodbye, world!</body></html>' ] ] };</syntaxhighlight>
Use <lang Shell>plackup --host localhost --port 8080 script.psgi</lang> to start the webserver.
Use <syntaxhighlight lang="shell">plackup --host localhost --port 8080 script.psgi</syntaxhighlight> to start the webserver.


=={{header|Perl 6}}==
=={{header|Phix}}==
Windows only for now (should be relatively straightforward to get it working on linux)<br>
{{works with|Rakudo}}
Output as C, code is however a translation of a FASM example.
<lang perl6>my $listen = IO::Socket::INET.new(:listen, :localhost<localhost>, :localport(8080));
<!--<syntaxhighlight lang="phix">(notonline)-->
loop {
<span style="color: #000080;font-style:italic;">-- demo\rosetta\SimpleHttpServer.exw</span>
my $conn = $listen.accept;
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span>
my $req = $conn.get ;
<span style="color: #008080;">include</span> <span style="color: #000000;">builtins</span><span style="color: #0000FF;">\</span><span style="color: #000000;">sockets</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
$conn.print: "HTTP/1.0 200 OK\r\nContent-Type: text/plain; charset=UTF-8\r\n\r\nGoodbye, World!\r\n";
<span style="color: #008080;">constant</span> <span style="color: #000000;">MAX_QUEUE</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">100</span><span style="color: #0000FF;">,</span>
$conn.close;
<span style="color: #000000;">ESCAPE</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">#1B</span><span style="color: #0000FF;">,</span>
}</lang>
<span style="color: #000000;">response</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">substitute</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"""
Async:
HTTP/1.1 200 OK
<lang perl6>react {
Content-Type: text/html; charset=UTF-8
whenever IO::Socket::Async.listen('0.0.0.0', 8080) -> $conn {
whenever $conn.Supply.lines -> $line {
&lt;!DOCTYPE html&gt;
$conn.print: "HTTP/1.0 200 OK\r\nContent-Type: text/plain; charset=UTF-8\r\n\r\nGoodbye, World!\r\n";
&lt;html&gt;
$conn.close;
&lt;head&gt;
}
&lt;title&gt;Bye-bye baby bye-bye&lt;/title&gt;
&lt;style&gt;
body { background-color: #111 }
h1 { font-size:4cm; text-align: center; color: black;
text-shadow: 0 0 2mm red}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;h1&gt;Goodbye, world!&lt;/h1&gt;
&lt;/body&gt;
&lt;/html&gt;
"""</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\r\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"server started, open http://localhost:8080/ in browser or curl, press Esc or Q to quit\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">sock</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">socket</span><span style="color: #0000FF;">(</span><span style="color: #000000;">AF_INET</span><span style="color: #0000FF;">,</span><span style="color: #000000;">SOCK_STREAM</span><span style="color: #0000FF;">,</span><span style="color: #004600;">NULL</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">pSockAddr</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sockaddr_in</span><span style="color: #0000FF;">(</span><span style="color: #000000;">AF_INET</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">""</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8080</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">bind</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sock</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">pSockAddr</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">SOCKET_ERROR</span> <span style="color: #008080;">then</span> <span style="color: #7060A8;">crash</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"bind (%v)"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">get_socket_error</span><span style="color: #0000FF;">()})</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">listen</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sock</span><span style="color: #0000FF;">,</span><span style="color: #000000;">MAX_QUEUE</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">SOCKET_ERROR</span> <span style="color: #008080;">then</span> <span style="color: #7060A8;">crash</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"listen (%v)"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">get_socket_error</span><span style="color: #0000FF;">()})</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">while</span> <span style="color: #008080;">not</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">get_key</span><span style="color: #0000FF;">(),{</span><span style="color: #000000;">ESCAPE</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'q'</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'Q'</span><span style="color: #0000FF;">})</span> <span style="color: #008080;">do</span>
<span style="color: #0000FF;">{</span><span style="color: #004080;">integer</span> <span style="color: #000000;">code</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">select</span><span style="color: #0000FF;">({</span><span style="color: #000000;">sock</span><span style="color: #0000FF;">},{},{},</span><span style="color: #000000;">250000</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- (0.25s)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">code</span><span style="color: #0000FF;">=</span><span style="color: #000000;">SOCKET_ERROR</span> <span style="color: #008080;">then</span> <span style="color: #7060A8;">crash</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"select (%v)"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">get_socket_error</span><span style="color: #0000FF;">()})</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">code</span><span style="color: #0000FF;">></span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #000080;font-style:italic;">-- (not timeout)</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">peer</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">accept</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sock</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">ip</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">getsockaddr</span><span style="color: #0000FF;">(</span><span style="color: #000000;">peer</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">{</span><span style="color: #004080;">integer</span> <span style="color: #000000;">len</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">string</span> <span style="color: #000000;">request</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">recv</span><span style="color: #0000FF;">(</span><span style="color: #000000;">peer</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Client IP: %s\n%s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">ip_to_string</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ip</span><span style="color: #0000FF;">),</span><span style="color: #000000;">request</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">request</span><span style="color: #0000FF;">)></span><span style="color: #000000;">3</span> <span style="color: #008080;">and</span> <span style="color: #000000;">request</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">4</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">"GET "</span> <span style="color: #008080;">then</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">bytes_sent</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">send</span><span style="color: #0000FF;">(</span><span style="color: #000000;">peer</span><span style="color: #0000FF;">,</span><span style="color: #000000;">response</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d bytes successfully sent\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">bytes_sent</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #7060A8;">shutdown</span><span style="color: #0000FF;">(</span><span style="color: #000000;">peer</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">SD_SEND</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- tell curl it's over</span>
<span style="color: #000000;">peer</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">closesocket</span><span style="color: #0000FF;">(</span><span style="color: #000000;">peer</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- (as does this)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #000000;">sock</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">closesocket</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sock</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">WSACleanup</span><span style="color: #0000FF;">()</span>
<!--</syntaxhighlight>-->
{{Out}}
Server console, once you have opened http://localhost:8080 in your browser, or run curl http://localhost:8080
<pre>
server started, open http://localhost:8080/ in browser or curl, press Esc or Q to quit
Client IP: 127.0.0.1
GET / HTTP/1.1
Host: localhost:8080
User-Agent: curl/7.55.1
Accept: */*

352 bytes successfully sent
</pre>

=={{header|PHP}}==
<syntaxhighlight lang="php"><?php
// AF_INET6 for IPv6 // IP
$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die('Failed to create socket!');
// '127.0.0.1' to limit only to localhost // Port
socket_bind($socket, 0, 8080);
socket_listen($socket);

$msg = '<html><head><title>Goodbye, world!</title></head><body>Goodbye, world!</body></html>';

for (;;) {
// @ is used to stop PHP from spamming with error messages if there is no connection
if ($client = @socket_accept($socket)) {
socket_write($client, "HTTP/1.1 200 OK\r\n" .
"Content-length: " . strlen($msg) . "\r\n" .
"Content-Type: text/html; charset=UTF-8\r\n\r\n" .
$msg);
}
}
else usleep(100000); // limits CPU usage by sleeping after doing every request
}</lang>
}
?></syntaxhighlight>


=={{header|PicoLisp}}==
=={{header|PicoLisp}}==
Contents of the file "goodbye.l":
Contents of the file "goodbye.l":
<lang PicoLisp>(html 0 "Bye" NIL NIL
<syntaxhighlight lang="picolisp">(html 0 "Bye" NIL NIL
"Goodbye, World!" )</lang>
"Goodbye, World!" )</syntaxhighlight>
Start server:
Start server:
<pre>$ pil @lib/http.l @lib/xhtml.l -'server 8080 "goodbye.l"' -wait</pre>
<pre>$ pil @lib/http.l @lib/xhtml.l -'server 8080 "goodbye.l"' -wait</pre>

=={{header|Pike}}==

<syntaxhighlight lang="pike">
void handle_request(Protocols.HTTP.Server.Request request)
{
request->response_and_finish( ([ "data":"Goodbye, World!",
"type":"text/html" ]) );
}

int main()
{
Protocols.HTTP.Server.Port(handle_request, 8080);
return -1; // -1 is a special case that retirns control to the backend
}
</syntaxhighlight>

=={{header|Pony}}==
Using only in-built TCP listeners, not the HTTP server package
<syntaxhighlight lang="pony">
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
</syntaxhighlight>


=={{header|Prolog}}==
=={{header|Prolog}}==
Line 1,322: Line 1,677:
{{works with|YAP}}
{{works with|YAP}}


<lang Prolog>% The following modules are used in the main module to start a server.
<syntaxhighlight lang="prolog">% The following modules are used in the main module to start a server.
:- use_module(library(http/thread_httpd)).
:- use_module(library(http/thread_httpd)).
:- use_module(library(http/http_dispatch)).
:- use_module(library(http/http_dispatch)).
Line 1,339: Line 1,694:
% wrapped in <h1></h1> tags, "Goodbye, World!".
% wrapped in <h1></h1> tags, "Goodbye, World!".
say_goodbye(_Request) :- reply_html_page([title('Howdy')],
say_goodbye(_Request) :- reply_html_page([title('Howdy')],
[h1('Goodbye, World!')]).</lang>
[h1('Goodbye, World!')]).</syntaxhighlight>


=={{header|PureBasic}}==
=={{header|PureBasic}}==
<lang PureBasic>If InitNetwork() = 0
<syntaxhighlight lang="purebasic">If InitNetwork() = 0
MessageRequester("Error", "Can't initialize the network !")
MessageRequester("Error", "Can't initialize the network !")
End
End
Line 1,364: Line 1,719:
Else
Else
MessageRequester("Error", "Can't create the server (port in use ?).")
MessageRequester("Error", "Can't create the server (port in use ?).")
EndIf</lang>
EndIf</syntaxhighlight>


=={{header|PHP}}==
=={{header|Python}}==
Using the <code>wsgiref.simple_server</code> module (Python < 3.2).
<lang PHP><?php
// AF_INET6 for IPv6 // IP
$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die('Failed to create socket!');
// '127.0.0.1' to limit only to localhost // Port
socket_bind($socket, 0, 8080);
socket_listen($socket);

$msg = '<html><head><title>Goodbye, world!</title></head><body>Goodbye, world!</body></html>';

for (;;) {
// @ is used to stop PHP from spamming with error messages if there is no connection
if ($client = @socket_accept($socket)) {
socket_write($client, "HTTP/1.1 200 OK\r\n" .
"Content-length: " . strlen($msg) . "\r\n" .
"Content-Type: text/html; charset=UTF-8\r\n\r\n" .
$msg);
}
else usleep(100000); // limits CPU usage by sleeping after doing every request
}
?></lang>


<syntaxhighlight lang="python">from wsgiref.simple_server import make_server
=={{header|Python}}==
<lang Python>from wsgiref.simple_server import make_server


def app(environ, start_response):
def app(environ, start_response):
Line 1,396: Line 1,731:


server = make_server('127.0.0.1', 8080, app)
server = make_server('127.0.0.1', 8080, app)
server.serve_forever()</lang>
server.serve_forever()</syntaxhighlight>


Using the <code>http.server</code> module (Python 3).
Using the <code>http.server</code> module (Python 3).


<lang Python>import threading
<syntaxhighlight lang="python">import threading


from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
Line 1,435: Line 1,770:
except KeyboardInterrupt:
except KeyboardInterrupt:
pass
pass
</syntaxhighlight>
</lang>

=={{header|R}}==
<syntaxhighlight lang="rsplus">
library(httpuv)

runServer("0.0.0.0", 5000,
list(
call = function(req) {
list(status = 200L, headers = list('Content-Type' = 'text/html'), body = "Hello world!")
}
)
)


</syntaxhighlight>


=={{header|Racket}}==
=={{header|Racket}}==


<lang racket>
<syntaxhighlight lang="racket">
#lang racket
#lang racket
(require web-server/servlet web-server/servlet-env)
(require web-server/servlet web-server/servlet-env)
(define (start req) (response/xexpr "Goodbye, World!"))
(define (start req) (response/xexpr "Goodbye, World!"))
(serve/servlet start #:port 8080 #:servlet-path "/")
(serve/servlet start #:port 8080 #:servlet-path "/")
</syntaxhighlight>
</lang>

=={{header|Raku}}==
(formerly Perl 6)
{{works with|Rakudo}}
<syntaxhighlight lang="raku" line>my $listen = IO::Socket::INET.new(:listen, :localhost<localhost>, :localport(8080));
loop {
my $conn = $listen.accept;
my $req = $conn.get ;
$conn.print: "HTTP/1.0 200 OK\r\nContent-Type: text/plain; charset=UTF-8\r\n\r\nGoodbye, World!\r\n";
$conn.close;
}</syntaxhighlight>
Async:
<syntaxhighlight lang="raku" line>react {
whenever IO::Socket::Async.listen('0.0.0.0', 8080) -> $conn {
whenever $conn.Supply.lines -> $line {
$conn.print: "HTTP/1.0 200 OK\r\nContent-Type: text/plain; charset=UTF-8\r\n\r\nGoodbye, World!\r\n";
$conn.close;
}
}
}</syntaxhighlight>


=={{header|REALbasic}}==
=={{header|REALbasic}}==


<syntaxhighlight lang="vb">
<lang vb>
Class HTTPSock
Class HTTPSock
Inherits TCPSocket
Inherits TCPSocket
Line 1,481: Line 1,851:
End Sub
End Sub
End Class
End Class
</syntaxhighlight>
</lang>


=={{header|REXX}}==
=={{header|REXX}}==
Based on the UNIX Shell entry. Works with Regina, tested on GNU/Linux. Requires netcat as nc.
Based on the UNIX Shell entry. Works with Regina, tested on GNU/Linux. Requires netcat as nc.


<lang rexx>/* HTTP hello server */
<syntaxhighlight lang="rexx">/* HTTP hello server */
response.1 = 'HTTP/1.1 200 OK' || '0D0A'X,
response.1 = 'HTTP/1.1 200 OK' || '0D0A'X,
|| 'Connection: close' || '0D0A'X,
|| 'Connection: close' || '0D0A'X,
Line 1,497: Line 1,867:
DO FOREVER
DO FOREVER
ADDRESS SYSTEM 'nc -l 8080' WITH INPUT STEM response.
ADDRESS SYSTEM 'nc -l 8080' WITH INPUT STEM response.
END</lang>
END</syntaxhighlight>


=={{header|Ring}}==
=={{header|Ring}}==
<lang ring>
<syntaxhighlight lang="ring">
Load "guilib.ring"
Load "guilib.ring"


Line 1,558: Line 1,928:
close()
close()
}
}
</syntaxhighlight>
</lang>


=={{header|Ruby}}==
=={{header|Ruby}}==
Using the WEBrick module from Ruby's standard library.
Using the WEBrick module from Ruby's standard library.
<lang ruby>require 'webrick'
<syntaxhighlight lang="ruby">require 'webrick'
server = WEBrick::HTTPServer.new(:Port => 8080)
server = WEBrick::HTTPServer.new(:Port => 8080)
server.mount_proc('/') {|request, response| response.body = "Goodbye, World!"}
server.mount_proc('/') {|request, response| response.body = "Goodbye, World!"}
trap("INT") {server.shutdown}
trap("INT") {server.shutdown}
server.start</lang>
server.start</syntaxhighlight>


Same code without <code>trap</code>, in a single statement using <code>tap</code>.
Same code without <code>trap</code>, in a single statement using <code>tap</code>.
<lang Ruby>require 'webrick'
<syntaxhighlight lang="ruby">require 'webrick'
WEBrick::HTTPServer.new(:Port => 80).tap {|srv|
WEBrick::HTTPServer.new(:Port => 80).tap {|srv|
srv.mount_proc('/') {|request, response| response.body = "Goodbye, World!"}
srv.mount_proc('/') {|request, response| response.body = "Goodbye, World!"}
}.start</lang>
}.start</syntaxhighlight>


Using the [http://www.sinatrarb.com/ sinatra] gem:
Using the [http://www.sinatrarb.com/ sinatra] gem:
<lang ruby>require 'sinatra'
<syntaxhighlight lang="ruby">require 'sinatra'
get("/") { "Goodbye, World!" }</lang>
get("/") { "Goodbye, World!" }</syntaxhighlight>


=={{header|Run BASIC}}==
=={{header|Run BASIC}}==
<lang runbasic>html "Hello World!"</lang>
<syntaxhighlight lang="runbasic">html "Hello World!"</syntaxhighlight>


=={{header|Rust}}==
=={{header|Rust}}==
Basically no error handling. This web server will simply panic if there is any sort of error.
Basically no error handling. This web server will simply panic if there is any sort of error.
<lang rust>use std::net::{Shutdown, TcpListener};
<syntaxhighlight lang="rust">use std::net::{Shutdown, TcpListener};
use std::thread;
use std::thread;
use std::io::Write;
use std::io::Write;
Line 1,610: Line 1,980:
}
}
}
}
</syntaxhighlight>
</lang>

=={{header|Rye}}==
<syntaxhighlight lang="clojure">rye .needs { http }

new-server ":8080"
|handle "/" fn { r w } { write w "Goodbye, World!" }
|serve</syntaxhighlight>

=={{header|Salmon}}==
<syntaxhighlight lang="salmon">use "http.salm" : "http.si";

/* Don't do any logging. */
procedure log(...) { };

simple_http_server(8080, procedure(header, connection)
{ respond_text(connection, "Goodbye, World!"); });</syntaxhighlight>


=={{header|Scala}}==
=={{header|Scala}}==
{{libheader|Scala}}
{{libheader|Scala}}
{{Trans|Java}}It shows that Scala can simply embed XML fragments.
{{Trans|Java}}It shows that Scala can simply embed XML fragments.
<lang Scala>import java.io.PrintWriter
<syntaxhighlight lang="scala">import java.io.PrintWriter
import java.net.ServerSocket
import java.net.ServerSocket


Line 1,638: Line 2,024:
sock.close()
sock.close()
}
}
}</lang>
}</syntaxhighlight>

=={{header|Salmon}}==
<lang Salmon>use "http.salm" : "http.si";

/* Don't do any logging. */
procedure log(...) { };

simple_http_server(8080, procedure(header, connection)
{ respond_text(connection, "Goodbye, World!"); });</lang>


=={{header|Seed7}}==
=={{header|Seed7}}==
The code below was inspired by the example code for the function [http://seed7.sourceforge.net/libraries/listener.htm#openInetListener%28in_integer%29 openInetListener].
The code below was inspired by the example code for the function [http://seed7.sourceforge.net/libraries/listener.htm#openInetListener%28in_integer%29 openInetListener].


<lang Seed7>$ include "seed7_05.s7i";
<syntaxhighlight lang="seed7">$ include "seed7_05.s7i";
include "listener.s7i";
include "listener.s7i";


Line 1,670: Line 2,047:
close(sock);
close(sock);
end while;
end while;
end func;</lang>
end func;</syntaxhighlight>


=={{header|Sidef}}==
=={{header|Sidef}}==


Using the low-level ''Socket'' object:
Using the low-level ''Socket'' object:
<lang ruby>var port = 8080;
<syntaxhighlight lang="ruby">var port = 8080;
var protocol = Socket.getprotobyname("tcp");
var protocol = Socket.getprotobyname("tcp");
 
 
Line 1,698: Line 2,075:
"<body>Goodbye, world!</body></html>\r\n");
"<body>Goodbye, world!</body></html>\r\n");
client.close;
client.close;
}</lang>
}</syntaxhighlight>


A more friendly interface, using the ''IO::Socket::INET'' library:
A more friendly interface, using the ''IO::Socket::INET'' library:
<lang ruby>var inet = require('IO::Socket::INET');
<syntaxhighlight lang="ruby">var inet = require('IO::Socket::INET');


var sock = inet.new( LocalAddr => "127.0.0.1:8080",
var sock = inet.new( LocalAddr => "127.0.0.1:8080",
Line 1,714: Line 2,091:
"<body>Goodbye, world!</body></html>\r\n");
"<body>Goodbye, world!</body></html>\r\n");
client.close;
client.close;
}</lang>
}</syntaxhighlight>


=={{header|Smalltalk}}==
=={{header|Smalltalk}}==
{{works with|Smalltalk/X}}
{{works with|Smalltalk/X}}
starting server:
starting server:
<lang smalltalk>Smalltalk loadPackage:'stx:goodies/webServer'. "usually already loaded"
<syntaxhighlight lang="smalltalk">Smalltalk loadPackage:'stx:goodies/webServer'. "usually already loaded"
|myServer service|
|myServer service|


Line 1,732: Line 2,109:
service linkNames:#('/' ).
service linkNames:#('/' ).
service registerServiceOn: myServer.
service registerServiceOn: myServer.
myServer start.</lang>
myServer start.</syntaxhighlight>
Be aware that the above is an ad-hoc minimal scripting example.
Be aware that the above is an ad-hoc minimal scripting example.
Normally, a service subclass is used and
Normally, a service subclass is used and
Line 1,744: Line 2,121:
that includes a ZnServer class.
that includes a ZnServer class.
Here's the simplest solution to start a web server:
Here's the simplest solution to start a web server:
<syntaxhighlight lang="smalltalk">(ZnServer startDefaultOn: 1701)
<lang smalltalk>
(ZnServer startDefaultOn: 1701)
onRequestRespond: [ :request |
onRequestRespond: [ :request |
ZnResponse ok: (ZnEntity text: 'Hello World!') ].
ZnResponse ok: (ZnEntity text: 'Hello World!') ].</syntaxhighlight>
</lang>


To stop the server, use the following:
To stop the server, use the following:
<syntaxhighlight lang="smalltalk">ZnServer stopDefault.</syntaxhighlight>
<lang smalltalk>

ZnServer stopDefault.
=={{header|Standard ML}}==
</lang>
<syntaxhighlight lang="standard ml">
val txt = Word8VectorSlice.full (Byte.stringToBytes "hello world!" ) ;

fun serve listener portnr =
let
fun next () =
let
val (conn, conn_addr) = Socket.accept listener
in
case Posix.Process.fork () of
NONE =>
(
Socket.sendVec(conn, txt); Socket.close conn ;
OS.Process.exit OS.Process.success
)
| _ =>
(
Socket.close conn ;next ()
)
end
in (
Socket.Ctl.setREUSEADDR(listener, true);
Socket.bind(listener, INetSock.any portnr );
Socket.listen(listener, 9);
next ()
)
end handle x => (Socket.close listener; raise x)
;
</syntaxhighlight>
call - smlnj interpreter
- serve (INetSock.TCP.socket()) 8080 ;
result - shell
shell$ wget 127.0.0.1:8080
--2020-03-26 16:11:15-- htt p://127.0.0.1:8080/
Connecting to 127.0.0.1:8080... connected.
HTTP request sent, awaiting response... 200 No headers, assuming HTTP/0.9
Length: unspecified
Saving to: 'index.html'
index.html [ <=> ] 12 --.-KB/s in 0s
2020-03-26 16:11:15 (721 KB/s) - 'index.html' saved [12]
shell$ cat index.html
hello world!


=={{header|Tcl}}==
=={{header|Tcl}}==
===Tcl 8.x===
===Tcl 8.x===
This version is adapted from [http://wiki.tcl.tk/28414 the Tcler's Wiki].
This version is adapted from [http://wiki.tcl.tk/28414 the Tcler's Wiki].
<lang tcl>proc accept {chan addr port} {
<syntaxhighlight lang="tcl">proc accept {chan addr port} {
while {[gets $chan] ne ""} {}
while {[gets $chan] ne ""} {}
puts $chan "HTTP/1.1 200 OK\nConnection: close\nContent-Type: text/plain\n"
puts $chan "HTTP/1.1 200 OK\nConnection: close\nContent-Type: text/plain\n"
Line 1,765: Line 2,182:
}
}
socket -server accept 8080
socket -server accept 8080
vwait forever</lang>
vwait forever</syntaxhighlight>


===Jim Tcl===
===Jim Tcl===
Jim is a small footprint reimplementation of Tcl with modern features.
Jim is a small footprint reimplementation of Tcl with modern features.
<lang tcl>set s [socket stream.server 127.0.0.1:8080]
<syntaxhighlight lang="tcl">set s [socket stream.server 127.0.0.1:8080]
$s readable {
$s readable {
set client [$s accept]
set client [$s accept]
Line 1,776: Line 2,193:
$client close
$client close
}
}
vwait done</lang>
vwait done</syntaxhighlight>


=={{header|UNIX Shell}}==
=={{header|UNIX Shell}}==


<lang bash>while true; do { echo -e 'HTTP/1.1 200 OK\r\n'; echo 'Hello, World!'; } | nc -l 8080; done</lang>
<syntaxhighlight lang="bash">while true; do { echo -e 'HTTP/1.1 200 OK\r\n'; echo 'Hello, World!'; } | nc -l 8080; done</syntaxhighlight>


=={{header|Wart}}==
=={{header|Wart}}==


<lang python>with server_socket socket :port 4000
<syntaxhighlight lang="python">with server_socket socket :port 4000
accepting client :from socket
accepting client :from socket
making stdout outfile+fd.client
making stdout outfile+fd.client
Line 1,790: Line 2,207:
prn "Content-type: text/plain"
prn "Content-type: text/plain"
prn ""
prn ""
prn "Hello, world!"</lang>
prn "Hello, world!"</syntaxhighlight>


=={{header|Wren}}==
{{libheader|SpiderWren}}
<syntaxhighlight lang="wren">import "web" for Routes, App

Routes.GET("/") {
return "Goodbye, World!"
}

App.run(8080)</syntaxhighlight>

=={{header|X86-64 Assembly}}==
===UASM 2.52===
This SHOULD assemble on both Linux and Windows.
(Tested on Arch, Don't have windows installed atm :[)
<syntaxhighlight lang="asm">
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Crossplatform(?) Web Server example using UASM's OO Language extention
;;
;; Linux Build:
;; $ uasm -elf64 websrv.asm
;; $ gcc -o websrv websrv.o -no-pie
;; With MUSL libc
;; $ musl-gcc -o websrv websrv.o -e main -nostartfiles -no-pie
;;
;; Windows Build:
;; $ uasm64 -win64 websrv.asm
;; $ link /machine:x64 /subsystem:console /release websrv.obj
;; kernel32.lib msvcrt.lib ws2_32.lib
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

option casemap:none
option literals:on ;; Usually on by default buuuuuut...

WIN64 equ 1
LIN64 equ 3


ifndef __WEBSRV_CLASS__
__WEBSERV_CLASS__ equ 1

AF_INET equ 2
SOCK_STREAM equ 1
INADDR_ANY equ 0

in_addr struct
s_addr dd ?
in_addr ends

sockaddr struct
sa_family dw ?
sa_data db 14 dup (?)
sockaddr ends

sockaddr_in struct
sin_family dw ?
sin_port dw ?
sin_addr in_addr <?>
sin_zero db 8 dup (?)
sockaddr_in ends

WSADATA struct
wVersion dw ?
wHighVersion dw ?
iMaxSockets dw ?
iMaxUdpDg dw ?
szDescription db 256 dup (?)
szSystemStatus db 128 dup (?)
lpVendorInfo dq ?
WSADATA ends
;; Platform specific requirements etc..
if @Platform eq WIN64
;;include/includelibs can be used here. But this works too.
option dllimport:<kernel32>
ExitProcess proto ucode:dword
HeapAlloc proto fd:qword, flgs:dword, hlen:qword
HeapFree proto fd:qword, flgs:dword, lpmem:qword
GetProcessHeap proto
option dllimport:<msvcrt>
printf proto fmt:qword, args:VARARG
strlen proto buff:qword
option dllimport:<ws2_32>
WSAStartup proto ver:word, wsa:qword
WSACleanup proto wsa:qword
closesocket proto fd:dword
socket proto d:dword, s:dword, prtl:dword
bind proto fd:dword, saddr:qword, slen:dword
listen proto fd:dword, blog:dword
accept proto fd:dword, caddr:qword, slen:qword
send proto fd:dword, buff:qword, blen:dword, flgs:dword
option dllimport:none
exit equ ExitProcess
close equ closesocket
elseif @Platform eq LIN64
;; Required proto from Libc stuff.
malloc proto SYSTEMV mem:qword ;; Required by the class macros.
free proto SYSTEMV mem:qword ;; It uses HeapAlloc on windows.
printf proto SYSTEMV fmt:qword, args:VARARG
strlen proto SYSTEMV buff:qword
socket proto SYSTEMV d:dword, s:dword, prtl:dword
bind proto SYSTEMV fd:dword, saddr:qword, slen:dword
listen proto SYSTEMV fd:dword, blog:dword
accept proto SYSTEMV fd:dword, saddr:qword, slen:qword
send proto SYSTEMV fd:dword, buff:qword, blen:dword, flgs:dword
close proto SYSTEMV fd:dword
exit proto SYSTEMV uexit:dword
else
;; Could do some OSX or w/e specific crap, but I don't use
;; a Mac so, I dunno shit about it's API :]
endif

;; Class definitions etc..
CLASS websrv
;; Class Method definitions
CMETHOD serve
ENDMETHODS
;; Class Variables.
if @Platform eq WIN64
wsa WSADATA <?>
endif
tmpl db "[websrv->%s] - %s",10,0
http db "HTTP/1.1 200 OK",13,10,
"Content-Type: text/html; charset=UTF-8",13,10,13,10,
"<html><head><title>Goodbye</title></head><body>Goodbye, World!</body></html>",0
sock dd 0
port dw 8080
ENDCLASS
pwebsrv typedef ptr websrv

;; Method implementation..
; Syntax:
; METHOD ClassName, MethodName, <ReturnType>, <USE extra regs for ret>, args..
METHOD websrv, Init, <VOIDARG>, <>
local x:sockaddr_in

mov rbx, thisPtr ;; Force the ThisPtr reference reg to be RBX 'cause of windoze
assume rbx:ptr websrv ;; its default is RCX, and RDI on linux. *shrugs*
invoke printf, addr [rbx].tmpl,CSTR("init"), CSTR("Starting...")
if @Platform eq WIN64
invoke WSAStartup, 200h, addr [rbx].wsa
endif
invoke socket, AF_INET, SOCK_STREAM, 0
.if rax == -1
invoke printf, addr [rbx].tmpl, CSTR("init:ERROR"), CSTR("Socket() returned < 0")
mov rax, rbx
ret
.endif
mov [rbx].sock, eax
invoke printf, CSTR("[websrv->init:socket] - %d",10), eax
mov x.sin_family, AF_INET
mov x.sin_addr.s_addr, INADDR_ANY
mov ax, [rbx].port
xchg al,ah
mov x.sin_port, ax
invoke bind, [rbx].sock, addr x, sizeof(x)
.if eax == -1
invoke printf, addr [rbx].tmpl, CSTR("init:ERROR") , CSTR("Bind failed.")
xor eax, eax
mov [rbx].sock, 0
mov rax, rbx
ret
.endif
invoke printf, addr [rbx].tmpl, CSTR("init"), CSTR("Bind successful.")
mov rax, rbx
assume rbx: nothing
ret
ENDMETHOD

METHOD websrv, serve, <VOIDARG>, <>
local tmp:qword
local cfd:dword
local x:sockaddr

mov rbx, thisPtr
assume rbx:ptr websrv
.if [rbx].sock == 0
ret
.endif
invoke printf, addr [rbx].tmpl,CSTR("serve"), CSTR("Listening for incomming connections")
invoke listen, [rbx].sock, 5
.if rax == -1
invoke printf, addr [rbx].tmpl, CSTR("serve:ERROR"), CSTR("Listen() returned -1")
ret
.endif

.while(1)
mov tmp, sizeof(x)
invoke accept, [rbx].sock, addr x, addr tmp
.if eax == -1
invoke printf, addr [rbx].tmpl, CSTR("serve:ERROR"), CSTR("Accept() returned -1")
ret
.endif
mov cfd, eax
invoke printf, addr [rbx].tmpl, CSTR("serve"), CSTR("Connection established.")
invoke strlen, addr [rbx].http
invoke send, cfd, addr [rbx].http, eax , 0
invoke close, cfd
.endw
assume rbx:nothing
ret
ENDMETHOD

METHOD websrv, Destroy, <VOIDARG>, <>
mov rbx, thisPtr
assume rbx:ptr websrv
invoke printf, addr [rbx].tmpl,CSTR("destroy"), CSTR("Calling Close and exit.")
invoke close, [rbx].sock
if @Platform eq WIN64
invoke WSACleanup, addr [rbx].wsa
endif
assume rbx:nothing
invoke exit, 0
ret
ENDMETHOD
endif ;; __WEBSRV_CLASS__

;; Start of main run code...
.code
main proc
local server:ptr websrv

mov server, _NEW(websrv)
server->serve()
_DELETE(server)
ret
main endp
end
</syntaxhighlight>


=={{header|zkl}}==
=={{header|zkl}}==
A threaded web server that returns "Goodbye, World!" for every request
A threaded web server that returns "Goodbye, World!" for every request
<lang zkl>const PORT=8080;
<syntaxhighlight lang="zkl">const PORT=8080;
const SERVLET_THREADS=4;
const SERVLET_THREADS=4;


Line 1,840: Line 2,486:
println("HTTP server started at http://",
println("HTTP server started at http://",
serverSocket.hostname, ":", serverSocket.port);
serverSocket.hostname, ":", serverSocket.port);
serverSocket.listen(jobPipe);</lang>
serverSocket.listen(jobPipe);</syntaxhighlight>

Latest revision as of 19:00, 9 December 2023

Task
Hello world/Web server
You are encouraged to solve this task according to the task description, using any language you may know.

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.

Ada

Library: AWS

Uses many defaults, such as 5 max simultaneous connections.

with AWS; use AWS;
with AWS.Response;
with AWS.Server;
with AWS.Status;
with Ada.Text_IO; use Ada.Text_IO;
procedure HelloHTTP is
   function CB (Request : Status.Data) return Response.Data is
      pragma Unreferenced (Request);
   begin
      return Response.Build ("text/html", "Hello world!");
   end CB;
   TheServer : Server.HTTP;
   ch : Character;
begin
   Server.Start (TheServer, "Rosettacode",
      Callback => CB'Unrestricted_Access, Port => 8080);
   Put_Line ("Press any key to quit."); Get_Immediate (ch);
   Server.Shutdown (TheServer);
end HelloHTTP;

Aime

Goodbye, world! with random colors and socket polling:

void
serve(dispatch w, file s, list colors)
{
    file i, o;
    date d;

    accept(i, o, s, 0);
    f_(o, "HTTP/1.1 200 OK\n"
"Content-Type: text/html; charset=UTF-8\n\n"
"<!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 ", colors[drand(3)], "}</style></head>"
"<body><h1>Goodbye, world!</h1></body></html>\n");

    # chrome won't show the page if we close right away.  we'll close in 2s.
    d.now;
    d.offset(2, 0);
    w_schedule(w, d, f_close, i);
}


integer
main(void)
{
    dispatch w;
    file s;

    tcpip_listen(s, 8080, 0);
    w_watch(w, s, serve, w, s, list("blue", "green", "red", "yellow"));
    w_press(w);

    return 0;
}

Or simply:

file i, o, s;

tcpip_listen(s, 8080, 0);
while (1) {
    accept(i, o, s, 0);
    f_(o, "HTTP/1.1 200 OK\n"
"Content-Type: text/html; charset=UTF-8\n\n"
"<!DOCTYPE html><html><head><title>baby bye-bye</title></head>"
"<body><h1>Goodbye, world!</h1></body></html>\n");
    f_flush(o);
}

Amazing Hopper

VERSION 1: "Hopper" flavour:

// Hello world! mode Server

#include <hopper.h>
main:
   fd=0,fdc=0,message=""
   
   {"HTTP/1.1 200 OK\n","Content-Type: text/html; charset=UTF-8\n\n"}cat
   {"<!DOCTYPE html><html><head><title>Bye-bye baby bye-bye</title>"},cat
   {"<style>body { background-color: #111 },cat
   {"h1 { font-size:4cm; text-align: center; color: black; text-shadow: 0 0 2mm red}</style>"}cat
   {"</head><body><h1>Goodbye, world!</h1></body></html>\n"}cat,
   mov(message)

/* Open socket in localhost (by default) */
/* Accept 5 conections (there are also 5 by default, if you put "any weá" there) */
   {5,8080}socket (OPENTCPSRV), mov(fd)

/* accept conection & send message */
   accept(fd), mov(fdc)
   {message},send(fdc)

/* close all */
   {fdc}socket(CLOSESOCK)
   {fd}socket(CLOSESOCK)
   
exit(0)

VERSION 2: "Hopper-BASIC" flavour

// Hello world! mode Server: desde el navegador, escriba localhost:8080

#include <hbasic.h>
Begin
   Declare as Numeric (fd,fdc)
           as Alpha (message,HEAD,head,body,form,html)
   
   Let ( HEAD := Cat$("HTTP/1.1 200 OK\n","Content-Type: text/html; charset=UTF-8\n\n") + ("<!DOCTYPE html>\n") )

   ParsNormal$("title","","Bye-bye baby bye-bye")(head)
   ParsNormal$("style","","body { background-color: #111 } h1 { font-size:4cm; text-align: center; color: black; text-shadow: 0 0 2mm red}")(head)
   ParsNormal$("head","",head)(html)
   ParsNormal$("h1","","Goodbye, world!")(body)
   ParsNormal$("body","",body)(html)
   
   ParsNormal$("html","",html)(form)
   Let( form := Cat$(HEAD,form))
   
   Let( message := Tran$(">\n<","><", form) )
   Print( message, Newl)

/* Open socket in localhost (by default) */
   Let( fd := OpenServerTCP(3,8080) )

/* accept conection & send message */
   Let( fdc := Accept(fd) )
   Send(message,fdc)

/* close all */
   CloseSocket(fdc)
   CloseSocket(fd)
End
Output:
Open your browser, and type in the navigation bar: "localhost: 8080": It will show "Goodbye World!" in huge letters and adorable lovecraftian colors!

AntLang

In plain AntLang:

serv: httprun[8080; {"HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\n\r\nGoodbye, World!"}]

Using ALC:

load["handlers.ant"]
serv: httprun[8080; {httpwrap["Goodbye, World!"]}]

To close the server:

kill[serv]

Arturo

serve.port:8080 [ GET "/" -> "Goodbye, World!" ]
Output:

If you navigate to "localhost:8080" through our web browser, we'll see the message:

Goodbye, World!

AutoIt

TCPStartup()
$socket = TCPListen("0.0.0.0",8080)
$string = "Goodbye, World!"
While 1
   Do
	  $newConnection = TCPAccept($socket)
	  Sleep(1)
   Until $newConnection <> -1
   $content = TCPRecv($newConnection, 2048)
   If StringLen($content) > 0 Then
	  TCPSend($newConnection, Binary("HTTP/1.1 200 OK" & @CRLF))
	  TCPSend($newConnection, Binary("Content-Type: text/html" & @CRLF))
	  TCPSend($newConnection, Binary("Content-Length: "& BinaryLen($string) & @CRLF & @CRLF))
	  TCPSend($newConnection, $string)
   EndIf
   TCPCloseSocket($newConnection)
WEnd

AWK

With GNU AWK (gawk) a simple web server can be implemented.
The example is taken from [1] (Documentation is licensed under GNU Free Documentation License, Version 1.3)

#!/usr/bin/gawk -f
     BEGIN {
       RS = ORS = "\r\n"
       HttpService = "/inet/tcp/8080/0/0"
       Hello = "<HTML><HEAD>" \
               "<TITLE>A Famous Greeting</TITLE></HEAD>" \
               "<BODY><H1>Hello, world</H1></BODY></HTML>"
       Len = length(Hello) + length(ORS)
       print "HTTP/1.0 200 OK"          |& HttpService
       print "Content-Length: " Len ORS |& HttpService
       print Hello                      |& HttpService
       while ((HttpService |& getline) > 0)
          continue;
       close(HttpService)
     }

BASIC

BaCon

Requires BaCon 4.2 or higher.

' Define HTTP constants
CONST New$ = CHR$(13) & NL$
CONST Sep$ = CHR$(13) & NL$ & CHR$(13) & NL$
CONST Msg$ = "<html><head>BaCon web greeting</head><body><h2>Goodbye, World!</h2></body></html>"

' Get our IP
Ip$ = "localhost"
PRINT "Connect from browser '", Ip$, ":8080'."

' Ignore child signals to avoid zombie processes
SIGNAL SIG_IGN, SIGCHLD

' Open listening port
OPEN Ip$ & ":8080" FOR SERVER AS mynet

' Keep receiving requests
WHILE TRUE

    ' Handle for newly incoming connection
    fd = ACCEPT(mynet)

    ' Incoming connection -> create background process
    spawn = FORK

    ' We are in the child
    IF spawn = 0 THEN

        ' Get the request
        REPEAT
            RECEIVE dat$ FROM fd
            PRINT dat$
        UNTIL RIGHT$(dat$, 4) = Sep$

        ' Reply that we're OK
        SEND "HTTP/1.1 200 Ok" & New$ & "Content-Length: " & STR$(LEN(Msg$)) & Sep$ & Msg$ TO fd

        ' Close connection
        CLOSE SERVER fd

        ' End this process
        ENDFORK
    ENDIF
WEND

BBC BASIC

This explicitly supports multiple concurrent connections.

      INSTALL @lib$+"SOCKLIB"
      PROC_initsockets
      
      maxSess% = 8
      DIM sock%(maxSess%-1), rcvd$(maxSess%-1), Buffer% 255
      
      ON ERROR PRINT REPORT$ : PROC_exitsockets : END
      ON CLOSE PROC_exitsockets : QUIT
      
      port$ = "8080"
      host$ = FN_gethostname
      PRINT "Host name is " host$
      
      listen% = FN_tcplisten(host$, port$)
      PRINT "Listening on port ";port$
      
      REPEAT
        socket% = FN_check_connection(listen%)
        IF socket% THEN
          FOR i% = 0 TO maxSess%-1
            IF sock%(i%) = 0 THEN
              sock%(i%) = socket%
              rcvd$(i%) = ""
              PRINT "Connection on socket "; sock%(i%) " opened"
              EXIT FOR
            ENDIF
          NEXT i%
          listen% = FN_tcplisten(host$, port$)
        ENDIF
        
        FOR i% = 0 TO maxSess%-1
          IF sock%(i%) THEN
            res% = FN_readsocket(sock%(i%), Buffer%, 256)
            IF res% >= 0 THEN
              Buffer%?res% = 0
              rcvd$(i%) += $$Buffer%
              IF LEFT$(rcvd$(i%),4) = "GET " AND ( \
              \ RIGHT$(rcvd$(i%),4) = CHR$13+CHR$10+CHR$13+CHR$10 OR \
              \ RIGHT$(rcvd$(i%),4) = CHR$10+CHR$13+CHR$10+CHR$13 OR \
              \ RIGHT$(rcvd$(i%),2) = CHR$10+CHR$10 ) THEN
                rcvd$(i%) = ""
                IF FN_writelinesocket(sock%(i%), "HTTP/1.0 200 OK")
                IF FN_writelinesocket(sock%(i%), "Content-type: text/html")
                IF FN_writelinesocket(sock%(i%), "")
                IF FN_writelinesocket(sock%(i%), "<html><head><title>Hello World!</title></head>")
                IF FN_writelinesocket(sock%(i%), "<body><h1>Hello World!</h1>")
                IF FN_writelinesocket(sock%(i%), "</body></html>")
                PROC_closesocket(sock%(i%))
                PRINT "Connection on socket " ; sock%(i%) " closed (local)"
                sock%(i%) = 0
              ENDIF
            ELSE
              PROC_closesocket(sock%(i%))
              PRINT "Connection on socket " ; sock%(i%) " closed (remote)"
              sock%(i%) = 0
            ENDIF
          ENDIF
        NEXT i%
        
        WAIT 0
      UNTIL FALSE
      END

C

This is, um, slightly longer than what other languages would be.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <err.h>

char response[] = "HTTP/1.1 200 OK\r\n"
"Content-Type: text/html; charset=UTF-8\r\n\r\n"
"<!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>\r\n";

int main()
{
  int one = 1, client_fd;
  struct sockaddr_in svr_addr, cli_addr;
  socklen_t sin_len = sizeof(cli_addr);

  int sock = socket(AF_INET, SOCK_STREAM, 0);
  if (sock < 0)
    err(1, "can't open socket");

  setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int));

  int port = 8080;
  svr_addr.sin_family = AF_INET;
  svr_addr.sin_addr.s_addr = INADDR_ANY;
  svr_addr.sin_port = htons(port);

  if (bind(sock, (struct sockaddr *) &svr_addr, sizeof(svr_addr)) == -1) {
    close(sock);
    err(1, "Can't bind");
  }

  listen(sock, 5);
  while (1) {
    client_fd = accept(sock, (struct sockaddr *) &cli_addr, &sin_len);
    printf("got connection\n");

    if (client_fd == -1) {
      perror("Can't accept");
      continue;
    }

    write(client_fd, response, sizeof(response) - 1); /*-1:'\0'*/
    close(client_fd);
  }
}

C#

using System.Text;
using System.Net.Sockets;
using System.Net;

namespace WebServer
{
    class GoodByeWorld
    {        
        static void Main(string[] args)
        {
            const string msg = "<html>\n<body>\nGoodbye, world!\n</body>\n</html>\n";        
            const int port = 8080;
            bool serverRunning = true;

            TcpListener tcpListener = new TcpListener(IPAddress.Any, port);
            tcpListener.Start();

            while (serverRunning)
            {
                Socket socketConnection = tcpListener.AcceptSocket();
                byte[] bMsg = Encoding.ASCII.GetBytes(msg.ToCharArray(), 0, (int)msg.Length);
                socketConnection.Send(bMsg);
                socketConnection.Disconnect(true);
            }
        }
    }
}
Works with: NancyFX
namespace Webserver
{
  using System;
  using Nancy;
  using Nancy.Hosting.Self;

  public class HelloWorldModule : NancyModule
  {
    public HelloWorldModule()
    {
      this.Get["/"] = parameters => "Goodbye, world!";
    }

    public static void Main()
    {
      var uri = new Uri("http://localhost:8080");
      using (var host = new NancyHost(uri))
      {
        host.Start();
        Console.WriteLine("Web server is now running!");
        Console.WriteLine("Press 'Enter' to exit.");
        Console.ReadLine();
      }
    }
  }
}

C++

C version compiles as C++ (known for G++ on Linux)

Clojure

Taken from: Compojure's Getting Started doc.

> lein new compojure goodbye-world

File: src/goodbye_world/handler.clj

(ns goodbye-world.handler
  (:require [compojure.core :refer :all]
            [compojure.handler :as handler]
            [compojure.route :as route]))

(defroutes app-routes
  (GET "/" [] "Goodbye, World!")
  (route/resources "/")
  (route/not-found "Not Found"))

(def app
  (handler/site app-routes))

To start up the server on port 8080, run the following from the project's root:

> lein ring server-headless 8080

Common Lisp

Here's the example with a pre-built server:

(ql:quickload :hunchentoot)
(defpackage :hello-web (:use :cl :hunchentoot))
(in-package :hello-web)

(define-easy-handler (hello :uri "/") () "Goodbye, World!")

(defparameter *server* (hunchentoot:start (make-instance 'hunchentoot:easy-acceptor :port 8080)))

Here's an example of doing everything manually

(ql:quickload :usocket)
(defpackage :hello-web-manual (:use :cl :usocket))
(in-package :hello-web-manual)

(defun crlf (&optional (stream *standard-output*))
  (write-char #\return stream)
  (write-char #\linefeed stream)
  (values))

(defun ln (string &optional (stream *standard-output*))
  (write-string string stream)
  (crlf stream))

(defun read-all (stream)
  (loop for char = (read-char-no-hang stream nil :eof)
     until (or (null char) (eq char :eof)) collect char into msg
     finally (return (values msg char))))

(defun serve (port &optional (log-stream *standard-output*))
  (let ((connections (list (socket-listen "127.0.0.1" port :reuse-address t))))
    (unwind-protect
	 (loop 
	    (loop for ready in (wait-for-input connections :ready-only t)
	       do (if (typep ready 'stream-server-usocket)
		      (push (socket-accept ready) connections)
		      (let* ((stream (socket-stream ready)))
			(read-all stream)
			(format log-stream "Got message...~%")
			(mapc (lambda (line) (ln line stream))
			      (list "HTTP/1.1 200 OK"
				    "Content-Type: text/plain; charset=UTF-8"
				    ""
				    "Hello world!"))
			(socket-close ready)
			(setf connections (remove ready connections))))))
      (loop for c in connections do (loop while (socket-close c))))))

(serve 8080)

Crystal

require "http/server"

server = HTTP::Server.new do |context|
    context.response.print "Goodbye World"
end

server.listen(8080)

D

Using sockets only, also shows use of heredoc syntax and std.array.replace. If you copy from this page, be careful with extraneous spaces on the empty lines in the heredoc.

import std.socket, std.array;

ushort port = 8080;

void main() {
  Socket listener = new TcpSocket;
  listener.bind(new InternetAddress(port));
  listener.listen(10);

  Socket currSock;

  while (null !is (currSock = listener.accept())) {
    currSock.sendTo(replace(q"EOF
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8

<html>
  <head><title>Hello world</title></head>
  <body>Goodbye, World!</body>
</html>
EOF", "\n", "\r\n"));
    currSock.close();
  }
}

Dart

import 'dart:io';

main() async {
  var server = await HttpServer.bind('127.0.0.1', 8080);
  
  await for (HttpRequest request in server) {
    request.response
      ..write('Hello, world')
      ..close();
  }
}

Delphi

program HelloWorldWebServer;

{$APPTYPE CONSOLE}

uses SysUtils, IdContext, IdCustomHTTPServer, IdHTTPServer;

type
  TWebServer = class
  private
    FHTTPServer: TIdHTTPServer;
  public
    constructor Create;
    destructor Destroy; override;
    procedure HTTPServerCommandGet(AContext: TIdContext;
      ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
  end;

constructor TWebServer.Create;
begin
  FHTTPServer := TIdHTTPServer.Create(nil);
  FHTTPServer.DefaultPort := 8080;
  FHTTPServer.OnCommandGet := HTTPServerCommandGet;
  FHTTPServer.Active := True;
end;

destructor TWebServer.Destroy;
begin
  FHTTPServer.Active := False;
  FHTTPServer.Free;
  inherited Destroy;
end;

procedure TWebServer.HTTPServerCommandGet(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
  AResponseInfo.ContentText := 'Goodbye, World!';
end;

var
  lWebServer: TWebServer;
begin
  lWebServer := TWebServer.Create;
  try
    Writeln('Delphi Hello world/Web server ');
    Writeln('Press Enter to quit');
    Readln;
  finally
    lWebServer.Free;
  end;
end.

Dylan.NET

//compile with dylan.NET 11.5.1.2 or later!!
#refstdasm "mscorlib.dll"
#refstdasm "System.dll"

import System.Text
import System.Net.Sockets
import System.Net

assembly helloweb exe
ver 1.1.0.0

namespace WebServer

    class public GoodByeWorld
           
        method public static void main(var args as string[])
        
            var msg as string = c"<html>\n<body>\nGoodbye, world!\n</body>\n</html>\n"        
            var port as integer = 8080
            var serverRunning as boolean = true

            var tcpListener as TcpListener = new TcpListener(IPAddress::Any, port)
            tcpListener::Start()

            do while serverRunning
                var socketConnection as Socket = tcpListener::AcceptSocket()
                var bMsg as byte[] = Encoding::get_ASCII()::GetBytes(msg::ToCharArray(), 0, msg::get_Length())
                socketConnection::Send(bMsg)
                socketConnection::Disconnect(true)
            end do
        
        end method

    end class

end namespace

Erlang

Using builtin HTTP server with call back to do/1. It only lasts 30 seconds (30000 milliseconds), then it is stopped. I fail to see how a longer time will serve any purpose.

-module( hello_world_web_server ).

-export( [do/1, httpd_start/2, httpd_stop/1, task/0] ).

do( _Data ) ->
  {proceed, [{response,{200,"Goodbye, World!"}}]}.

httpd_start( Port, Module ) ->
  Arguments = [{bind_address, "localhost"}, {port, Port}, {ipfamily, inet},
    {modules, [Module]},
    {server_name,erlang:atom_to_list(Module)}, {server_root,"."}, {document_root,"."}],
  {ok, Pid} = inets:start( httpd, Arguments, stand_alone ),
  Pid.
  
httpd_stop( Pid ) ->
  inets:stop( stand_alone, Pid ).

task() ->
  Pid = httpd_start( 8080, ?MODULE ),
  timer:sleep( 30000 ),
  httpd_stop( Pid ).

Fantom

using web
using wisp

const class HelloMod : WebMod // provides the content
{
  override Void onGet ()
  {
    res.headers["Content-Type"] = "text/plain; charset=utf-8"
    res.out.print ("Goodbye, World!")
  }
}

class HelloWeb
{
  Void main ()
  {
    WispService // creates the web service
    {
      port = 8080
      root = HelloMod()
    }.start

    while (true) {} // stay running
  }
}

Fortran

There is no network library in fortran. Use C interoperability and some C compatible library or just start node.js simple web server:

program http_example
   implicit none
   character (len=:), allocatable :: code
   character (len=:), allocatable :: command
   logical :: waitForProcess

   ! Execute a Node.js code
   code = "const http = require('http'); http.createServer((req, res) => &
   {res.end('Hello World from a Node.js server started from Fortran!')}).listen(8080);"

   command = 'node -e "' // code // '"'
   call execute_command_line (command, wait=waitForProcess)

end program http_example

Free Pascal

program HelloWorldServer;
{$mode objfpc}{$H+}
uses
  Classes, fphttpserver;

Type
  TTestHTTPServer = Class(TFPHTTPServer)
  public
    procedure HandleRequest(Var ARequest: TFPHTTPConnectionRequest;
                            Var AResponse : TFPHTTPConnectionResponse); override;
  end;

Var
  Serv : TTestHTTPServer;

procedure TTestHTTPServer.HandleRequest(var ARequest: TFPHTTPConnectionRequest;
  var AResponse: TFPHTTPConnectionResponse);
Var
  F : TStringStream;
begin
  F:=TStringStream.Create('Hello,World!');
  try
    AResponse.ContentLength:=F.Size;
    AResponse.ContentStream:=F;
    AResponse.SendContent;
    AResponse.ContentStream:=Nil;
  finally
    F.Free;
  end;
end;

begin
  Serv:=TTestHTTPServer.Create(Nil);
  try
    Serv.Threaded:=False;
    Serv.Port:=8080;
    Serv.AcceptIdleTimeout:=1000;
    Serv.Active:=True;
  finally
    Serv.Free;
  end;
end.


Frink

Frink has a web server platform that runs in a Java servlet container called Frink Server Pages which should be used for real-world applications. However, the following is a simple single-threaded web server for the purposes of this task.

ss = newJava["java.net.ServerSocket", 8080]
while true
{
   sock = ss.accept[];
   w = new Writer[sock.getOutputStream[]]
   w.println["HTTP/1.1 200 OK"]
   w.println["Content-Type: text/plain\n"]
   w.println["Goodbye, World!"]
   w.close[]
}

FunL

native java.io.PrintWriter
native java.net.ServerSocket

val port = 8080
val listener = ServerSocket( port )

printf( 'Listening at port %1$d\n', port )

forever
  socket = listener.accept()
  PrintWriter( socket.getOutputStream(), true ).println( 'hello world' )
  socket.shutdownOutput()
  socket.close()

Gastona

A minimal graphical user interface, a console, is included to allow following the server activity and also being able to quit it by closing the window. But it is not stritctly needed, just the unit #listix# would do the job.

#javaj#

   <frames> oConsole

#listix#

   <main> 
      MICOHTTP, START, myServer, 8080
   
   <GET />
      //<html><body>
      //  Goodbye world!
      //</body></html>

Genie

/**
 * Based on https://wiki.gnome.org/Projects/Genie/GIONetworkingSample
 * Based on an example of Jezra Lickter http://hoof.jezra.net/snip/nV
 *
 * valac --pkg gio-2.0 --pkg gee-0.8 webserver.gs
 * ./webserver 
 */
[indent=8]
uses
        GLib
        Gee

init
        var ws = new WebServer()
        ws.run()

struct Request
        full_request : string
        path : string
        query : string

struct Response
        status_code : string
        content_type : string
        data : string

class WebServer

        def run()
                port : uint16 = 8080
                tss : ThreadedSocketService = new ThreadedSocketService(100)
                ia : InetAddress = new InetAddress.any(SocketFamily.IPV4)
                isaddr : InetSocketAddress = new InetSocketAddress(ia, port)
                try
                        tss.add_address(isaddr, SocketType.STREAM, SocketProtocol.TCP, null, null);
                except e : Error
                        stderr.printf("%s\n", e.message)
                        return
                // add connection handler
                tss.run.connect( connection_handler )

                ml : MainLoop = new MainLoop()
                tss.start()
                stdout.printf("Serving on port %d\n", port)
                ml.run()

        def connection_handler ( conn : SocketConnection ) : bool
                first_line : string = ""
                size : size_t = 0;
                request : Request = Request()
                dis : DataInputStream = new DataInputStream (conn.input_stream)
                dos : DataOutputStream = new DataOutputStream (conn.output_stream)
                try
                        first_line = dis.read_line(out size)
                        // here you could analyze request information
                        var parts = first_line.split(" ");
                        if parts.length > 1 do request.full_request = parts[1]
                except e : Error
                        stderr.printf("%s\n", e.message)
                response : Response = Response()
                response.status_code = "HTTP/1.1 200 OK\n"
                response.content_type = "text/html"
                response.data = "<html><body><h1>Goodbye, World!</h1></body></html>"
                serve_response ( response, dos )
                return false

        def serve_response ( response : Response, dos : DataOutputStream )
                try
                        dos.put_string (response.status_code)
                        dos.put_string ("Server: Genie Socket\n")
                        dos.put_string("Content-Type: %s\n".printf(response.content_type))
                        dos.put_string("Content-Length: %d\n".printf(response.data.length))
                        dos.put_string("\n");//this is the end of the return headers
                        dos.put_string(response.data)
                except e : Error
                        stderr.printf("%s\n", e.message)
Output:
prompt$ valac --pkg gio-2.0 --pkg gee-0.8 webserver.gs
prompt$ ./webserver
Serving on port 8080

Showing

prompt$ curl http://localhost:8080
<html><body><h1>Goodbye, World!</h1></body></html>

Go

package main

import (
  "fmt"
  "log"
  "net/http"
)

func main() {
  http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
    fmt.Fprintln(w, "Goodbye, World!")
  })
  log.Fatal(http.ListenAndServe(":8080", nil))
}

Haskell

Lightweightly concurrent "hello world" web server using the conduit stack:

{-# LANGUAGE OverloadedStrings #-}

import Data.ByteString.Char8 ()
import Data.Conduit ( ($$), yield )
import Data.Conduit.Network ( ServerSettings(..), runTCPServer )

main :: IO ()
main = runTCPServer (ServerSettings 8080 "127.0.0.1") $ const (yield response $$)
  where response = "HTTP/1.0 200 OK\nContent-Length: 16\n\nGoodbye, World!\n"

Or using only "standard" features (base, bytestring and network from the Haskell Platform):

{-# LANGUAGE OverloadedStrings #-}

import Data.ByteString.Char8 ()
import Network hiding ( accept )
import Network.Socket ( accept )
import Network.Socket.ByteString ( sendAll )
import Control.Monad ( forever )
import Control.Exception ( bracket, finally )
import Control.Concurrent ( forkIO )

main :: IO ()
main = bracket (listenOn $ PortNumber 8080) sClose loop where
  loop s = forever $ forkIO . request . fst =<< accept s
  request c = sendAll c response `finally` sClose c
  response = "HTTP/1.0 200 OK\nContent-Length: 16\n\nGoodbye, World!\n"

Both works like this:

$ curl http://localhost:8080/
Goodbye, World!
# httperf --port=8080 --num-conns=10000
Request rate: 4549.5 req/s (0.2 ms/req)
# httperf --port=8080 --num-conns=10000 --num-calls=2
Request rate: 8202.5 req/s (0.1 ms/req)
Errors: total 10000 client-timo 0 socket-timo 0 connrefused 0 connreset 10000

Or using warp (warp warp example about warp):

{-# LANGUAGE OverloadedStrings #-}
 
import Network.Wai
import Network.Wai.Handler.Warp
import Network.HTTP.Types (status200)
import Blaze.ByteString.Builder (copyByteString)
import qualified Data.ByteString.UTF8 as BU
import Data.Monoid
 
main = do
    let port = 8080
    putStrLn $ "Listening on port " ++ show port
    run port app
 
app req respond = respond $
    case pathInfo req of
        x -> index x
 
index x = responseBuilder status200 [("Content-Type", "text/plain")] $ mconcat $ map copyByteString
    [ "Hello World!\n" ]

Work like this:

$ curl http://localhost:8080/
Hello World!
#httperf --server localhost --port 8080 --num-conns 10000 --num-calls 100
Request rate: 43565.8 req/s (0.0 ms/req)
#httperf --server localhost --port 8080 --num-conns 100000 --num-calls 200
Request rate: 43902.9 req/s (0.0 ms/req)

without any errors

Comparing to nginx:

# httperf --num-conns=10000
Request rate: 3613.2 req/s (0.3 ms/req)
# httperf --num-conns=10000 --num-calls=10
Request rate: 9952.6 req/s (0.1 ms/req)
# httperf --num-conns=10000 --num-calls=100
Request rate: 12341.0 req/s (0.1 ms/req)

which serve without any errors.

Io

WebRequest := Object clone do(
    handleSocket := method(aSocket,
      aSocket streamWrite("Goodbye, World!")
      aSocket close
    )
)

WebServer := Server clone do(
    setPort(8080)
    handleSocket := method(aSocket,
        WebRequest clone asyncSend(handleSocket(aSocket))
    )
)

WebServer start

J

If the desire is to use the browser as a gui, the easiest thing to do would be to download j7, edit the jhs script to start on port 8080, start jhs, visit http://127.0.0.1:8080/jijx then enter the text:

'Goodbye, World!'

This will compute the desired result and display it (actually, it will be displayed twice since the original string will also be displayed). This would be even simpler if you could just use the default jhs port (65001)... Alternatively, a jhs form could be used (but this would not have the exact url structure specified).

However, if the desire is to implement the task exactly, any of approaches at j:JWebServer might be used.

For example, here is a web server which ignores the client's request and always returns Goodbye, World:

hello=: verb define
 8080 hello y NB. try to use port 8080 by default
:
 port=: x
 require 'socket'
 coinsert 'jsocket'
 sdclose ; sdcheck sdgetsockets ''
 server=: {. ; sdcheck sdsocket ''
 sdcheck sdbind server; AF_INET; ''; port
 sdcheck sdlisten server, 1
 while. 1 do.
  while. 
    server e. ready=: >{. sdcheck sdselect (sdcheck sdgetsockets ''),'';'';<1e3
  do. 
    sdcheck sdaccept server
  end.
  for_socket. ready do.
   request=: ; sdcheck sdrecv socket, 65536 0
   sdcheck (socket responseFor request) sdsend socket, 0
   sdcheck sdclose socket
  end.
 end.
)

responseFor=: dyad define
 'HTTP/1.0 200 OK',CRLF,'Content-Type: text/plain',CRLF,CRLF,'Goodbye, World!',CRLF
)

To deploy this server, once it has been defined, run

hello''

This version works because reasonable http requests fit in a single tcp packet. (And note that the server waits for one tcp packet before responding.) If parsing of the request is desired, one of the more complicated implementations at j:JWebServer should be used instead (but that's not really relevant for this task, except perhaps to require complete headers before responding, with broken browsers which send multiple tcp packets for the request).

Java

Multiple requests will be served in the order that they reach the server, with a queue size limit of 50 waiting requests imposed by default in the ServerSocket class (may be changed by adding a second positive integer argument to the ServerSocket constructor).

import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class HelloWorld{
  public static void main(String[] args) throws IOException{
    ServerSocket listener = new ServerSocket(8080);
    while(true){
      Socket sock = listener.accept();
      new PrintWriter(sock.getOutputStream(), true).
                println("Goodbye, World!");
      sock.close();
    }
  }
}

JavaScript

Works with: Node.js
var http = require('http');

http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Goodbye, World!\n');
}).listen(8080, '127.0.0.1');

It scales:

$ curl http://localhost:8080/
Goodbye, World!
# httperf --port=8080 --num-conns=10000
Request rate: 1813.1 req/s (0.6 ms/req)
# httperf --port=8080 --num-conns=10000 --num-calls=10
Request rate: 4869.1 req/s (0.2 ms/req)
# httperf --port=8080 --num-conns=10000 --num-calls=100
Request rate: 5689.0 req/s (0.2 ms/req)

with no errors.

Jsish

One wrinkle in this sample use of the Jsi_Websrv module that ships with Jsi. A request needs page and not just the port.

Output:
prompt$ jsish
# require('Jsi_Websrv');
1.01
# Jsi_Websrv('', {server:true, port:8080, pageStr:'Goodbye, World!'});

...other terminal...

prompt$ curl http://localhost:8080/page
Goodbye, World!prompt$ curl http://localhost:8080/page
Goodbye, World!

Julia

Requires the HttpServer package to have previously been installed with 'Pkg.add("HttpServer")'

using HttpServer
server = Server() do req, res
    "Goodbye, World!"
end
run(server, 8080)

Kotlin

Translation of: Java
import java.io.PrintWriter
import java.net.ServerSocket

fun main(args: Array<String>) {
    val listener = ServerSocket(8080)
    while(true) {
        val sock = listener.accept()
        PrintWriter(sock.outputStream, true).println("Goodbye, World!")
        sock.close()
    }
}

Lasso

While Lasso has a built-in webserver you can use, here's how you can create a basic multi-threaded webserver of your own to complete this request:

local(server) = net_tcp
handle => { #server->close }
#server->bind(8080) & listen & forEachAccept => {
   local(con) = #1

   split_thread => {
      handle => { #con->close }
      local(request) = ''
      // Read in the request in chunks until you have it all
      {
         #request->append(#con->readSomeBytes(8096))
         not #request->contains('\r\n\r\n')? currentCapture->restart
      }()

      local(response) = 'HTTP/1.1 200 OK\r\n\
            Content-Type: text/html; charset=UTF-8\r\n\r\n\
            Goodbye, World!'
      #con->writeBytes(bytes(#response))
   }
}

Liberty BASIC

This is difficult, although possible, in Liberty BASIC, but it's close relative Run BASIC is designed for serving webpages easily. The task becomes simply ..

print "hello world!"

Lua

Works with: lua version 5.2.4
Library: LuaSocket
local socket = require "socket"
local headers = "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\nContent-Length: %d\r\n\r\n%s"
local content = "<!doctype html><html><title>Goodbye, World!</title><h1>Goodbye, World!"
local server = assert(socket.bind("localhost", 8080))
repeat
   local client = server:accept()
   local ok = client:send(string.format(headers, #content, content))
   client:close()
until not client or not ok
server:close()

Mathematica/Wolfram Language

listener = 
 SocketListen["127.0.0.1:8080", 
  Function[{assoc}, 
   With[{client = assoc["SourceSocket"]}, 
    WriteString[client, 
     "HTTP/1.0 200 OK\nContent-Length: 16\n\nGoodbye, World!\n"]; 
    Close[client]]]]
SystemOpen["http://127.0.0.1:8080"]

Clean up:

DeleteObject[listener];
Close[listener["Socket"]]

min

Works with: min version 0.37.0
{
  (
    {
      {"text/plain; charset=utf-8" :content-type} :headers
      "Goodbye, World!" :body
    }
  ) :handler
  8080 :port
} start-server

Modula-2

This is a CGI executable:

MODULE access;

FROM  InOut   IMPORT  WriteString, WriteLn;

BEGIN
   WriteString ("Content-Type : text/plain");
   WriteLn;
   WriteLn;
   WriteString ("Hello web wide world.");
   WriteLn
END access.

NetRexx

Translation of: Java
/* NetRexx */
options replace format comments java crossref symbols binary

class RHelloWorldWebServer public

  properties public constant
    isTrue = boolean (1 == 1)
    isFalse = boolean (1 \== 1)
    greeting1 = "Goodbye, World!"
    greeting2 = '' -
      || 'HTTP/1.1 200 OK\r\n' -
      || 'Content-Type: text/html; charset=UTF-8\r\n\r\n' -
      || '<?xml version="1.0" encoding="UTF-8"?>\r\n' -
      || '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\r\n' -
      || '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\r\n' -
      || '<header>\r\n' -
      || '<title>Hello</title>\r\n' -
      || '<style type="text/css">body {font-family: sans-serif;}</style>\r\n' -
      || '</header>\r\n' -
      || '<body>\r\n' -
      || '<h2 style="text-align: center;">' || greeting1 || '</h2>\r\n' -
      || '</body>\r\n' -
      || '</html>\r\n' -
      || ''

  properties static inheritable
    terminate = isFalse -- TODO: provide a less draconian means to terminate the listener loop

  method main(args = String[]) public static signals IOException
    listener = ServerSocket(8080)
    loop label listener forever
      if terminate then leave listener
      sock = listener.accept()
      PrintWriter(sock.getOutputStream(), isTrue).println(greeting2)
      sock.close()
      end listener
    return

Nim

import asynchttpserver, asyncdispatch

proc cb(req: Request) {.async.} =
  await req.respond(Http200, "Hello, World!")

asyncCheck newAsyncHttpServer().serve(Port(8080), cb)
runForever()

Objeck

use Net;
use Concurrency;

bundle Default {
  class GoodByeWorld {
    function : Main(args : String[]) ~ Nil {
      server := TCPSocketServer->New(8080);
      if(server->Listen(5)) {
        while(true) {
          client := server->Accept();
          client->WriteString("<html>\n<body>\nGoodbye, world!\n</body>\n</html>\n");
          client->Close();
        };
      };
      server->Close();
    }
  }
}

OCaml

This code is derived from this ocaml-unix documentation.

let try_finalise f x finally y =
  let res = try f x with e -> finally y; raise e in
  finally y;
  res

let rec restart_on_EINTR f x =
  try f x with Unix.Unix_error (Unix.EINTR, _, _) -> restart_on_EINTR f x

let double_fork_treatment server service (client_descr, _ as client) =
  let treat () =
    match Unix.fork () with
    | 0 ->
        if Unix.fork () <> 0 then exit 0;
        Unix.close server; service client; exit 0
    | k ->
        ignore (restart_on_EINTR (Unix.waitpid []) k)
  in
  try_finalise treat () Unix.close client_descr

let install_tcp_server_socket addr =
  let s = Unix.socket Unix.PF_INET Unix.SOCK_STREAM 0 in
  try
    Unix.bind s addr;
    Unix.listen s 10;
    s
  with e -> Unix.close s; raise e

let tcp_server treat_connection addr =
  ignore (Sys.signal Sys.sigpipe Sys.Signal_ignore);
  let server_sock = install_tcp_server_socket addr in
  while true do
    let client = restart_on_EINTR Unix.accept server_sock in 
    treat_connection server_sock client 
  done

let server () =
  let port = 8080 in
  let host = (Unix.gethostbyname (Unix.gethostname())).Unix.h_addr_list.(0) in 
  let addr = Unix.ADDR_INET (host, port) in
  let treat sock (client_sock, client_addr as client) =
    let service (s, _) =
      let response = "\
        HTTP/1.1 200 OK\r\n\
        Content-Type: text/html; charset=UTF-8\r\n\r\n\
        <html><head><title>Goodbye, world!</title>\
        <style>body { background-color: #0FF }\
        h1 { font-size:3em; color: black; }</style></head>\
        <body><h1>Goodbye, world!</h1></body></html>\r\n"
      in
      Unix.write s response 0 (String.length response);
    in
    double_fork_treatment sock service client
  in
  tcp_server treat addr

let _ =
  Unix.handle_unix_error server ()

Ol

This sample sends 200 OK on any request and echoes the request headers.

(import (lib http))

(http:run 8080 (lambda (fd request headers send close)
   (send "HTTP/1.0 200 OK\n"
         "Connection: close\n"
         "Content-Type: text/html; charset=UTF-8\n"
         "Server: " (car *version*) "/" (cdr *version*)
         "\n\n"

         "<h1>Goodbye, World!</h1>"
         (ref request 1) ": " (ref request 2)
         "<hr><small>" headers "</small>")
   (close #t)
))

Opa

From Opa documentation:

server = one_page_server("Hello", -> <>Goodbye, world</>)

Compile and run:

opa file.opa --

Panda

Using the command line client. Listen to port 8080. For each request a request object is returned, we ignore this and just use it to send message which will be the response.

8080.port.listen.say("Hello world!")

Perl

use Socket;

my $port = 8080;
my $protocol = getprotobyname( "tcp" );

socket( SOCK, PF_INET, SOCK_STREAM, $protocol ) or die "couldn't open a socket: $!";
  # PF_INET to indicate that this socket will connect to the internet domain
  # SOCK_STREAM indicates a TCP stream, SOCK_DGRAM would indicate UDP communication
  
setsockopt( SOCK, SOL_SOCKET, SO_REUSEADDR, 1 ) or die "couldn't set socket options: $!";
  # SOL_SOCKET to indicate that we are setting an option on the socket instead of the protocol
  # mark the socket reusable

bind( SOCK, sockaddr_in($port, INADDR_ANY) ) or die "couldn't bind socket to port $port: $!";
  # bind our socket to $port, allowing any IP to connect

listen( SOCK, SOMAXCONN ) or die "couldn't listen to port $port: $!";
  # start listening for incoming connections

while( accept(CLIENT, SOCK) ){
  print CLIENT "HTTP/1.1 200 OK\r\n" .
               "Content-Type: text/html; charset=UTF-8\r\n\r\n" .
               "<html><head><title>Goodbye, world!</title></head><body>Goodbye, world!</body></html>\r\n";
  close CLIENT;
}

Various modules exist for using sockets, including the popular IO::Socket which provides a simpler and more friendly OO interface for the socket layer. Here is the solution using this module:

use IO::Socket::INET;

my $sock = new IO::Socket::INET ( LocalAddr => "127.0.0.1:8080",
                                  Listen    => 1,
                                  Reuse     => 1, ) or die "Could not create socket: $!";

while( my $client = $sock->accept() ){
  print $client "HTTP/1.1 200 OK\r\n" .
                "Content-Type: text/html; charset=UTF-8\r\n\r\n" .
                "<html><head><title>Goodbye, world!</title></head><body>Goodbye, world!</body></html>\r\n";
  close $client;
}

Using Perl's glue power, provide a note with visitor counter via netcat:

while (++(our $vn)) {
  open NC, "|-", qw(nc -l -p 8080 -q 1);
  print NC "HTTP/1.0 200 OK\xd\xa",
      "Content-type: text/plain; charset=utf-8\x0d\x0a\x0d\x0a",
      "Goodbye, World! (hello, visitor No. $vn!)\x0d\x0a";
}

Here's another solution using Plack (may be found on CPAN):

use Plack::Runner;
my $app = sub {
    return [ 200,
       [ 'Content-Type' => 'text/html; charset=UTF-8' ],
       [ '<html><head><title>Goodbye, world!</title></head><body>Goodbye, world!</body></html>' ]
     ]
};
my $runner = Plack::Runner->new;
$runner->parse_options('--host' => 'localhost', '--port' => 8080);
$runner->run($app);

When using plackup, then this may be compressed to one line:

my $app = sub { return [ 200, [ 'Content-Type' => 'text/html; charset=UTF-8' ], [ '<html><head><title>Goodbye, world!</title></head><body>Goodbye, world!</body></html>' ] ] };

Use

plackup --host localhost --port 8080 script.psgi

to start the webserver.

Phix

Windows only for now (should be relatively straightforward to get it working on linux)
Output as C, code is however a translation of a FASM example.

-- 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()
Output:

Server console, once you have opened http://localhost:8080 in your browser, or run curl http://localhost:8080

server started, open http://localhost:8080/ in browser or curl, press Esc or Q to quit
Client IP: 127.0.0.1
GET / HTTP/1.1
Host: localhost:8080
User-Agent: curl/7.55.1
Accept: */*

352 bytes successfully sent

PHP

<?php
                     // AF_INET6 for IPv6  // IP
$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die('Failed to create socket!');
                  // '127.0.0.1' to limit only to localhost // Port
socket_bind($socket, 0,                                        8080);
socket_listen($socket);

$msg = '<html><head><title>Goodbye, world!</title></head><body>Goodbye, world!</body></html>';

for (;;) {
    // @ is used to stop PHP from spamming with error messages if there is no connection
    if ($client = @socket_accept($socket)) {
        socket_write($client, "HTTP/1.1 200 OK\r\n" .
               "Content-length: " . strlen($msg) . "\r\n" .
               "Content-Type: text/html; charset=UTF-8\r\n\r\n" .
               $msg);
    }
    else usleep(100000); // limits CPU usage by sleeping after doing every request
}
?>

PicoLisp

Contents of the file "goodbye.l":

(html 0 "Bye" NIL NIL
   "Goodbye, World!" )

Start server:

$ pil @lib/http.l @lib/xhtml.l -'server 8080 "goodbye.l"' -wait

Pike

void handle_request(Protocols.HTTP.Server.Request request)
{
    request->response_and_finish( ([ "data":"Goodbye, World!",
                                     "type":"text/html" ]) );
}

int main()
{
    Protocols.HTTP.Server.Port(handle_request, 8080);
    return -1; // -1 is a special case that retirns control to the backend
}

Pony

Using only in-built TCP listeners, not the HTTP server package

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

Prolog

Works with: SWI Prolog
Works with: YAP
% The following modules are used in the main module to start a server.
:- use_module(library(http/thread_httpd)).
:- use_module(library(http/http_dispatch)).

% The following module is used in every module that describes a page.
:- use_module(library(http/html_write)).

% Main entry point: starts the server on port 8080.
server :- http_server(http_dispatch, [port(8080)]).

% Defines the handler for the root URI /.
:- http_handler('/', say_goodbye, []).

% Defines the actual page content.
% In this case we're returning a page with the title "Howdy" and the content,
% wrapped in <h1></h1> tags, "Goodbye, World!".
say_goodbye(_Request) :- reply_html_page([title('Howdy')],
                                   [h1('Goodbye, World!')]).

PureBasic

If InitNetwork() = 0
  MessageRequester("Error", "Can't initialize the network !")
  End
EndIf

Port = 8080

If CreateNetworkServer(0, Port)
  Repeat
    Delay(1)
    SEvent = NetworkServerEvent()
    If SEvent
      ClientID = EventClient()
      Select SEvent
        Case #PB_NetworkEvent_Data
          SendNetworkData(ClientID,@"Goodbye, World!",Len("Goodbye, World!"))
          CloseNetworkConnection(ClientID)
      EndSelect
    EndIf
  ForEver
Else
  MessageRequester("Error", "Can't create the server (port in use ?).")
EndIf

Python

Using the wsgiref.simple_server module (Python < 3.2).

from wsgiref.simple_server import make_server

def app(environ, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    yield b"<h1>Goodbye, World!</h1>"

server = make_server('127.0.0.1', 8080, app)
server.serve_forever()

Using the http.server module (Python 3).

import threading

from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer


class HelloHTTPRequestHandler(BaseHTTPRequestHandler):

  message = 'Hello World! 今日は'

  def do_GET(self):
    self.send_response(200)
    self.send_header('Content-type', 'text/html; charset=UTF-8')
    self.end_headers()
    self.wfile.write(self.message.encode('utf-8'))
    self.close_connection = True


def serve(addr, port):
  with ThreadingHTTPServer((addr, port), HelloHTTPRequestHandler) as server:
    server.serve_forever(poll_interval=None)


if __name__ == '__main__':

  addr, port = ('localhost', 80)

  threading.Thread(target=serve, args=(addr, port), daemon=True).start()

  try:
    while True:
      # handle Ctrl+C
      input()

  except KeyboardInterrupt:
    pass

R

library(httpuv)

runServer("0.0.0.0", 5000,
	list(
		call = function(req) {
		  list(status = 200L,	headers = list('Content-Type' = 'text/html'), body = "Hello world!")
	        }
	)
)

Racket

#lang racket
(require web-server/servlet web-server/servlet-env)
(define (start req) (response/xexpr "Goodbye, World!"))
(serve/servlet start #:port 8080 #:servlet-path "/")

Raku

(formerly Perl 6)

Works with: Rakudo
my $listen = IO::Socket::INET.new(:listen, :localhost<localhost>, :localport(8080));
loop {
    my $conn = $listen.accept;
    my $req =  $conn.get ;
    $conn.print: "HTTP/1.0 200 OK\r\nContent-Type: text/plain; charset=UTF-8\r\n\r\nGoodbye, World!\r\n";
    $conn.close;
}

Async:

react {
    whenever IO::Socket::Async.listen('0.0.0.0', 8080) -> $conn {
        whenever $conn.Supply.lines -> $line {
            $conn.print: "HTTP/1.0 200 OK\r\nContent-Type: text/plain; charset=UTF-8\r\n\r\nGoodbye, World!\r\n";
            $conn.close;
        }
    }
}

REALbasic

Class HTTPSock
Inherits TCPSocket
  Event Sub DataAvailable()
    Dim headers As New InternetHeaders
    headers.AppendHeader("Content-Length", Str(LenB("Goodbye, World!")))
    headers.AppendHeader("Content-Type", "text/plain")
    headers.AppendHeader("Content-Encoding", "identity")
    headers.AppendHeader("Connection", "close")
    Dim data As String = "HTTP/1.1 200 OK" + EndOfLine.Windows + headers.Source + EndOfLine.Windows + EndOfLine.Windows + "Goodbye, World!"
    Me.Write(data)
    Me.Close
  End Sub
End Class

Class HTTPServ
Inherits ServerSocket
  Event Sub AddSocket() As TCPSocket
    Return New HTTPSock
  End Sub
End Class

Class App
Inherits Application
  Event Sub Run(Args() As String)
    Dim sock As New HTTPServ
    sock.Port = 8080
    sock.Listen()
    While True
      App.DoEvents
    Wend
  End Sub
End Class

REXX

Based on the UNIX Shell entry. Works with Regina, tested on GNU/Linux. Requires netcat as nc.

/* HTTP hello server */
response.1 = 'HTTP/1.1 200 OK' || '0D0A'X,
          || 'Connection: close' || '0D0A'X,
          || 'Content-Type: text/html' || '0D0A0D0A'X
response.2 = '<!DOCTYPE html>' || '0A'X,
          || '<html><head><title>Hello, Rosetta</title></head>' || '0A'X,
          || '<body><h2>Goodbye, World!</h2></body>' || '0A'X,
          || '<!-- Shout out from the Rosetta Code programming chrestomathy --></html>' || '0A'X

DO FOREVER
    ADDRESS SYSTEM 'nc -l 8080' WITH INPUT STEM response.
END

Ring

Load "guilib.ring"

cResponse = "HTTP/1.1 200 OK\r\n" +
               "Content-Type: text/html\r\n\r\n" +
               "<html><head><title>Goodbye, world!</title></head>" +
               "<body>Goodbye, world!</body></html>"

cResponse = substr(cResponse,"\r\n",char(13)+char(10))

new qApp {
	oServer = new Server { Server() }
	exec()
}

Class Server

        win1 lineedit1
        oTcpServer oTcpClient
        cOutput = ""

        func server

                win1 = new qwidget()

                lineedit1 = new qtextedit(win1) {
                        setGeometry(150,50,200,300)
                }

                win1 {
                        setwindowtitle("Server")
                        setgeometry(450,100,400,400)
                        show()
                }

                oTcpServer = new qTcpServer(win1) {		
                        setNewConnectionEvent("oServer.pNewConnection()")
                        oHostAddress = new qHostAddress()
                        oHostAddress.SetAddress("127.0.0.1")
                        listen(oHostAddress,8080)
                }
                cOutput = "Server Started" + nl +
                           "listen to port 8080" + nl

                lineedit1.settext(cOutput)

        Func pNewConnection

                oTcpClient = oTcpServer.nextPendingConnection()
                while not oTcpClient.waitForReadyRead(100) end
                cOutput += "Accept Connection" + nl
                lineedit1.settext(cOutput)
                oTcpClient {
                        write(cResponse,len(cResponse))
                        flush()
                        waitforbyteswritten(300000)
                        close()
                }

Ruby

Using the WEBrick module from Ruby's standard library.

require 'webrick'
server = WEBrick::HTTPServer.new(:Port => 8080)
server.mount_proc('/') {|request, response| response.body = "Goodbye, World!"}
trap("INT") {server.shutdown}
server.start

Same code without trap, in a single statement using tap.

require 'webrick'
WEBrick::HTTPServer.new(:Port => 80).tap {|srv|
    srv.mount_proc('/') {|request, response| response.body = "Goodbye, World!"}
}.start

Using the sinatra gem:

require 'sinatra'
get("/") { "Goodbye, World!" }

Run BASIC

html "Hello World!"

Rust

Basically no error handling. This web server will simply panic if there is any sort of error.

use std::net::{Shutdown, TcpListener};
use std::thread;
use std::io::Write;

const RESPONSE: &'static [u8] = b"HTTP/1.1 200 OK\r
Content-Type: text/html; charset=UTF-8\r\n\r
<!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>\r";


fn main() {
    let listener = TcpListener::bind("127.0.0.1:8080").unwrap();

    for stream in listener.incoming() {
        thread::spawn(move || {
            let mut stream = stream.unwrap();
            match stream.write(RESPONSE) {
                Ok(_) => println!("Response sent!"),
                Err(e) => println!("Failed sending response: {}!", e),
            }
            stream.shutdown(Shutdown::Write).unwrap();
        });
    }
}

Rye

rye .needs { http }

new-server ":8080" 
|handle "/" fn { r w } { write w "Goodbye, World!" } 
|serve

Salmon

use "http.salm" : "http.si";

/* Don't do any logging. */
procedure log(...) { };

simple_http_server(8080, procedure(header, connection)
  { respond_text(connection, "Goodbye, World!"); });

Scala

Library: Scala
Translation of: Java

It shows that Scala can simply embed XML fragments.

import java.io.PrintWriter
import java.net.ServerSocket

object HelloWorld extends App {

  val text =
    <HTML>
      <HEAD>
        <TITLE>Hello world </TITLE>
      </HEAD>
      <BODY LANG="en-US" BGCOLOR="#e6e6ff" DIR="LTR">
        <P ALIGN="CENTER"> <FONT FACE="Arial, sans-serif" SIZE="6">Goodbye, World!</FONT> </P>
      </BODY>
    </HTML>
val port = 8080
  val listener = new ServerSocket(port)
   printf("Listening at port %1$d", port)

  while (true) {
    val sock = listener.accept()
    new PrintWriter(sock.getOutputStream(), true).println(text)
    sock.close()
  }
}

Seed7

The code below was inspired by the example code for the function openInetListener.

$ include "seed7_05.s7i";
  include "listener.s7i";

const proc: main is func
  local
    var listener: aListener is listener.value;
    var file: sock is STD_NULL;
  begin
    aListener := openInetListener(8080);
    listen(aListener, 10);
    while TRUE do
      sock := accept(aListener);
      write(sock, "HTTP/1.1 200 OK\r\n\
                  \Content-Type: text/html; charset=UTF-8\r\n\
                  \\r\n\
                  \<html><body>Hello, world!</body></html>\n");
      close(sock);
    end while;
  end func;

Sidef

Using the low-level Socket object:

var port = 8080;
var protocol = Socket.getprotobyname("tcp");
 
var sock = (Socket.open(Socket.PF_INET, Socket.SOCK_STREAM, protocol) || die "couldn't open a socket: #{$!}");
  # PF_INET to indicate that this socket will connect to the internet domain
  # SOCK_STREAM indicates a TCP stream, SOCK_DGRAM would indicate UDP communication
 
sock.setsockopt(Socket.SOL_SOCKET, Socket.SO_REUSEADDR, 1) || die "couldn't set socket options: #{$!}";
  # SOL_SOCKET to indicate that we are setting an option on the socket instead of the protocol
  # mark the socket reusable
 
sock.bind(Socket.sockaddr_in(port, Socket.INADDR_ANY)) || die "couldn't bind socket to port #{port}: #{$!}";
  # bind our socket to $port, allowing any IP to connect
 
sock.listen(Socket.SOMAXCONN) || die "couldn't listen to port #{port}: #{$!}";
  # start listening for incoming connections
 
while (var client = sock.accept) {
  client.print ("HTTP/1.1 200 OK\r\n" +
               "Content-Type: text/html; charset=UTF-8\r\n\r\n" +
               "<html><head><title>Goodbye, world!</title></head>" +
               "<body>Goodbye, world!</body></html>\r\n");
  client.close;
}

A more friendly interface, using the IO::Socket::INET library:

var inet = require('IO::Socket::INET');

var sock = inet.new( LocalAddr => "127.0.0.1:8080",
                     Listen    => 1,
                     Reuse     => 1,
            );

while (var client = sock.accept) {
    client.print ("HTTP/1.1 200 OK\r\n" +
                "Content-Type: text/html; charset=UTF-8\r\n\r\n" +
                "<html><head><title>Goodbye, world!</title></head>" +
                "<body>Goodbye, world!</body></html>\r\n");
    client.close;
}

Smalltalk

Works with: Smalltalk/X

starting server:

Smalltalk loadPackage:'stx:goodies/webServer'. "usually already loaded"
|myServer service|

myServer := HTTPServer startServerOnPort:8082.
service := HTTPPluggableActionService new.
service 
    register:[:request | 
        self halt: 'debugging'. 
        request reply:'<HTML><BODY><H1>Hello World</H1></BODY></HTML>'
    ] 
    as:'hello'.
service linkNames:#('/' ).
service registerServiceOn: myServer.
myServer start.

Be aware that the above is an ad-hoc minimal scripting example. Normally, a service subclass is used and response handlers are defined as methods of it (not as action blocks). Also, services and HTML generation is usually done using a framework (at least DOM-based, but usually a higher level toolkit). Especially take a look at smalltalk frameworks like Aida, Seaside, VisualWave etc.

Pharo Smalltalk

Pharo ships with the Zinc HTTP Component frameworks that includes a ZnServer class. Here's the simplest solution to start a web server:

(ZnServer startDefaultOn: 1701)
   onRequestRespond: [ :request | 
      ZnResponse ok: (ZnEntity text: 'Hello World!') ].

To stop the server, use the following:

ZnServer stopDefault.

Standard ML

val txt = Word8VectorSlice.full (Byte.stringToBytes  "hello world!"   ) ;

fun serve listener portnr =
 let
  fun next () =
   let
    val (conn, conn_addr) = Socket.accept listener
   in
    case  Posix.Process.fork () of
        NONE   =>
             (
	      Socket.sendVec(conn, txt); Socket.close conn ;
              OS.Process.exit OS.Process.success 
             )
       | _     =>
             (
	      Socket.close conn ;next ()
	     )
    end 
  in (
   Socket.Ctl.setREUSEADDR(listener, true);
   Socket.bind(listener, INetSock.any portnr );
   Socket.listen(listener, 9);
   next ()
   )
  end               handle x => (Socket.close listener; raise x)
;

call - smlnj interpreter

- serve (INetSock.TCP.socket()) 8080 ;

result - shell

shell$ wget 127.0.0.1:8080 
--2020-03-26 16:11:15--  htt p://127.0.0.1:8080/
Connecting to 127.0.0.1:8080... connected.
HTTP request sent, awaiting response... 200 No headers, assuming HTTP/0.9
Length: unspecified
Saving to: 'index.html'
index.html              [ <=>                ]      12  --.-KB/s    in 0s      
2020-03-26 16:11:15 (721 KB/s) - 'index.html' saved [12]
shell$ cat index.html 
hello world!

Tcl

Tcl 8.x

This version is adapted from the Tcler's Wiki.

proc accept {chan addr port} {
    while {[gets $chan] ne ""} {}
    puts $chan "HTTP/1.1 200 OK\nConnection: close\nContent-Type: text/plain\n"
    puts $chan "Goodbye, World!"
    close $chan
}
socket -server accept 8080
vwait forever

Jim Tcl

Jim is a small footprint reimplementation of Tcl with modern features.

set s [socket stream.server 127.0.0.1:8080]
$s readable {
    set client [$s accept]
    $client puts "HTTP/1.1 200 OK\nConnection: close\nContent-Type: text/plain\n"
    $client puts "Hello, World!\n"
    $client close
}
vwait done

UNIX Shell

while true; do { echo -e 'HTTP/1.1 200 OK\r\n'; echo 'Hello, World!'; } | nc -l 8080; done

Wart

with server_socket socket :port 4000
  accepting client :from socket
    making stdout outfile+fd.client
      prn "HTTP/1.0 200 OK"
      prn "Content-type: text/plain"
      prn ""
      prn "Hello, world!"

Wren

Library: SpiderWren
import "web" for Routes, App

Routes.GET("/") {
    return "Goodbye, World!"
}

App.run(8080)

X86-64 Assembly

UASM 2.52

This SHOULD assemble on both Linux and Windows. (Tested on Arch, Don't have windows installed atm :[)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Crossplatform(?) Web Server example using UASM's OO Language extention
;;
;; Linux Build:
;;   $ uasm -elf64 websrv.asm
;;   $ gcc -o websrv websrv.o -no-pie
;;  With MUSL libc
;;   $ musl-gcc -o websrv websrv.o -e main -nostartfiles -no-pie
;;
;; Windows Build: 
;;   $ uasm64 -win64 websrv.asm
;;   $ link /machine:x64 /subsystem:console /release websrv.obj 
;;         kernel32.lib msvcrt.lib ws2_32.lib
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

option casemap:none
option literals:on          ;; Usually on by default buuuuuut...

WIN64   equ 1
LIN64   equ 3


ifndef __WEBSRV_CLASS__
__WEBSERV_CLASS__   equ 1

    AF_INET     equ 2
    SOCK_STREAM equ 1
    INADDR_ANY  equ 0

    in_addr struct
        s_addr  dd ?
    in_addr ends

    sockaddr struct
        sa_family   dw ?
        sa_data     db 14 dup (?)
    sockaddr ends

    sockaddr_in struct
        sin_family  dw ?
        sin_port    dw ?
        sin_addr    in_addr <?>
        sin_zero    db 8 dup (?)
    sockaddr_in ends

    WSADATA struct
        wVersion        dw ?
        wHighVersion    dw ?
        iMaxSockets     dw ?
        iMaxUdpDg       dw ?
        szDescription   db 256 dup (?)
        szSystemStatus  db 128 dup (?)
        lpVendorInfo    dq ?
    WSADATA ends
    
    ;; Platform specific requirements etc..
    if @Platform eq WIN64
        ;;include/includelibs can be used here. But this works too.
        option dllimport:<kernel32>
            ExitProcess     proto ucode:dword
            HeapAlloc       proto fd:qword, flgs:dword, hlen:qword
            HeapFree        proto fd:qword, flgs:dword, lpmem:qword
            GetProcessHeap  proto
        option dllimport:<msvcrt>
            printf      proto fmt:qword, args:VARARG
            strlen      proto buff:qword
        option dllimport:<ws2_32>
            WSAStartup  proto ver:word, wsa:qword
            WSACleanup  proto wsa:qword
            closesocket proto fd:dword
            socket      proto d:dword, s:dword, prtl:dword
            bind        proto fd:dword, saddr:qword, slen:dword
            listen      proto fd:dword, blog:dword
            accept      proto fd:dword, caddr:qword, slen:qword
            send        proto fd:dword, buff:qword, blen:dword, flgs:dword
        option dllimport:none
        exit    equ ExitProcess
        close   equ closesocket
    elseif @Platform eq LIN64
        ;; Required proto from Libc stuff.
        malloc  proto SYSTEMV mem:qword         ;; Required by the class macros.
        free    proto SYSTEMV mem:qword         ;; It uses HeapAlloc on windows.
        printf  proto SYSTEMV fmt:qword, args:VARARG
        strlen  proto SYSTEMV buff:qword
        socket  proto SYSTEMV d:dword, s:dword, prtl:dword
        bind    proto SYSTEMV fd:dword, saddr:qword, slen:dword
        listen  proto SYSTEMV fd:dword, blog:dword
        accept  proto SYSTEMV fd:dword, saddr:qword, slen:qword
        send    proto SYSTEMV fd:dword, buff:qword, blen:dword, flgs:dword
        close   proto SYSTEMV fd:dword
        exit    proto SYSTEMV uexit:dword
    else
        ;; Could do some OSX or w/e specific crap, but I don't use
        ;; a Mac so, I dunno shit about it's API :]
    endif

    ;; Class definitions etc..
    CLASS websrv
        ;; Class Method definitions
        CMETHOD serve
    ENDMETHODS
        ;; Class Variables.
        if @Platform eq WIN64
            wsa  WSADATA <?>
        endif
        tmpl    db  "[websrv->%s] - %s",10,0
        http    db  "HTTP/1.1 200 OK",13,10,
                    "Content-Type: text/html; charset=UTF-8",13,10,13,10,
                    "<html><head><title>Goodbye</title></head><body>Goodbye, World!</body></html>",0
        sock    dd 0
        port    dw 8080
    ENDCLASS
    
    pwebsrv typedef ptr websrv

    ;; Method implementation..
    ;   Syntax:
    ;       METHOD ClassName, MethodName, <ReturnType>, <USE extra regs for ret>, args..
    METHOD websrv, Init, <VOIDARG>, <>
        local x:sockaddr_in

        mov rbx, thisPtr            ;; Force the ThisPtr reference reg to be RBX 'cause of windoze
        assume rbx:ptr websrv       ;; its default is RCX, and RDI on linux. *shrugs*
        invoke printf, addr [rbx].tmpl,CSTR("init"), CSTR("Starting...")
        if @Platform eq WIN64
            invoke WSAStartup, 200h, addr [rbx].wsa
        endif        
        invoke socket, AF_INET, SOCK_STREAM, 0
        .if rax == -1
            invoke printf, addr [rbx].tmpl, CSTR("init:ERROR"), CSTR("Socket() returned < 0")
            mov rax, rbx
            ret
        .endif
        mov [rbx].sock, eax
        invoke printf, CSTR("[websrv->init:socket] - %d",10), eax
        mov x.sin_family, AF_INET
        mov x.sin_addr.s_addr, INADDR_ANY
        mov ax, [rbx].port
        xchg al,ah
        mov x.sin_port, ax
        invoke bind, [rbx].sock, addr x, sizeof(x)
        .if eax == -1
            invoke printf, addr [rbx].tmpl, CSTR("init:ERROR") , CSTR("Bind failed.")
            xor eax, eax
            mov [rbx].sock, 0
            mov rax, rbx
            ret
        .endif
        invoke printf, addr [rbx].tmpl, CSTR("init"), CSTR("Bind successful.")
        mov rax, rbx
        assume rbx: nothing
        ret
    ENDMETHOD

    METHOD websrv, serve, <VOIDARG>, <>
        local tmp:qword
        local cfd:dword
        local x:sockaddr

        mov rbx, thisPtr
        assume rbx:ptr websrv
        .if [rbx].sock == 0
            ret
        .endif
        invoke printf, addr [rbx].tmpl,CSTR("serve"), CSTR("Listening for incomming connections")
        invoke listen, [rbx].sock, 5
        .if rax == -1
            invoke printf, addr [rbx].tmpl, CSTR("serve:ERROR"), CSTR("Listen() returned -1")
            ret
        .endif

        .while(1)
            mov tmp, sizeof(x)
            invoke accept, [rbx].sock, addr x, addr tmp
            .if eax == -1
                invoke printf, addr [rbx].tmpl, CSTR("serve:ERROR"), CSTR("Accept() returned -1")
                ret
            .endif
            mov cfd, eax
            invoke printf, addr [rbx].tmpl, CSTR("serve"), CSTR("Connection established.")
            invoke strlen, addr [rbx].http
            invoke send, cfd, addr [rbx].http, eax , 0
            invoke close, cfd
        .endw    
        assume rbx:nothing
        ret
    ENDMETHOD

    METHOD websrv, Destroy, <VOIDARG>, <>
        mov rbx, thisPtr
        assume rbx:ptr websrv
        invoke printf, addr [rbx].tmpl,CSTR("destroy"), CSTR("Calling Close and exit.")
        invoke close,  [rbx].sock
        if @Platform eq WIN64
            invoke WSACleanup, addr [rbx].wsa
        endif
        assume rbx:nothing
        invoke exit, 0
        ret
    ENDMETHOD
endif                       ;; __WEBSRV_CLASS__

;; Start of main run code...
.code
main proc
    local server:ptr websrv

    mov server, _NEW(websrv)
    server->serve()
    _DELETE(server)
    ret
main endp
end

zkl

A threaded web server that returns "Goodbye, World!" for every request

const PORT=8080;
const SERVLET_THREADS=4;

    // A class to process requests from clients (eg browsers)
    // in a thread. Requests are received via a pipe, which feeds
    // all Servlet threads.
class Servlet{
   fcn init(jobPipe){ self.launch(jobPipe); }
   fcn liftoff(jobPipe){
      while(1){    // read request, write response, repeat
         socket:=jobPipe.read();
         if(socket.wait(60) != 1)	// what is Chrome doing?
            { socket.close(); continue; }
         if (request:=socket.read()) 
	    try{ processRequest(request,socket); } catch{}
      }
   }
   fcn splashdown(h,e){ println("Servlet died before its time"); }
}

fcn processRequest(request,socket){
   response:=responseHeader();
   response+="Goodbye, World!";
   socket.write(response); socket.close();    // no Keep-Alive
}

fcn responseHeader(status=200,reason="OK"){
  String(
   "HTTP/1.0 ",status," ",reason,"\r\n",
   Time.Date.httpDate(),"\r\n"
   "Server: ZTWS (zkl)\r\n"
   "Connection: close\r\n"
   "Content-Type: text/html; charset=UTF-8\r\n"
   "\r\n")
}

      //////////////////// Start the server ///////////////////////
var jobPipe=Thread.Pipe();    // a queue of requests
do(SERVLET_THREADS){ Servlet(jobPipe) }  // start threads

    // Create the HTTP server listen socket
    // Sits here forever passing client HTTP connects to Servlets
serverSocket:=Network.TCPServerSocket.open(PORT);
println("HTTP server started at http://", 
    serverSocket.hostname, ":", serverSocket.port);
serverSocket.listen(jobPipe);