Hello world/Web server: Difference between revisions
(added omit from ML/I) |
|||
Line 275:
{{omit from|Locomotive Basic|No sockets}}
{{omit from|Lotus 123 Macro Scripting}}
{{omit from|ML/I|No sockets}}
{{omit from|ZX Spectrum Basic|No sockets}}
|
Revision as of 10:26, 13 August 2011
You are encouraged to solve this task according to the task description, using any language you may know.
The browser is the new GUI!
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;
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>
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>
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>
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>