Hello world/Web server
The browser is the new GUI!
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
You are encouraged to solve this task according to the task description, using any language you may know.
The task is to 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.
C
This is, um, slightly longer than what other languages would be. <lang C>#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>
Goodbye, world!
</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); } }</lang>
Delphi
<lang 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.</lang>
Fantom
<lang 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 }
} </lang>
Go
<lang go>package main
import (
"http" "fmt"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { fmt.Fprintln(w, "Goodbye, World!") }) if err := http.ListenAndServe(":8080", nil); err != nil { fmt.Println(err) }
}</lang>
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).
<lang java>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(); } } }</lang>
OCaml
This code is derived from this ocaml-unix documentation.
<lang ocaml>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>
Goodbye, world!
</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 ()</lang>
Perl
<lang 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;
}</lang>
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:
<lang Perl>use IO::Socket::INET;
my $sock = new IO::Socket::INET ( LocalHost => "127.0.0.1",
LocalPort => "8080", Proto => "tcp", 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;
}</lang>
Using Perl's glue power, provide a suicide note with visitor counter via netcat:<lang Perl>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\xd\xa\xd\xa", "Goodbye, World! (hello, visitor No. $vn!)\xd\xa"; }</lang>
PicoLisp
Contents of the file "goodbye.l": <lang PicoLisp>(html 0 "Bye" NIL NIL
"Goodbye, World!" )</lang>
Start server:
$ pil @lib/http.l @lib/xhtml.l -'server 8080 "goodbye.l"' -wait
PureBasic
<lang 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 </lang>
PHP
<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); } usleep(100000); // limits CPU usage by sleeping after doing every request
}</lang>
Python
<lang Python>def app(environ, start_response):
start_response('200 OK', []) yield "Goodbye, World!"
if __name__ == '__main__':
from wsgiref.simple_server import make_server server = make_server('127.0.0.1', 8080, app) server.serve_forever()</lang>
Ruby
Using the WEBrick module from Ruby's standard library.
<lang ruby>require 'webrick' server = WEBrick::HTTPServer.new(:Port => 8080) server.mount_proc('/') {|request, response| response.body = "Goodbye, World!"} trap("INT") {server.shutdown} server.start</lang>
Tcl
This version is adapted from the Tcler's Wiki. <lang tcl>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</lang>