Hello world/Web server

From Rosetta Code
Revision as of 03:10, 2 July 2011 by rosettacode>Ledrug (→‎{{header|C}}: simplified code, dropped fork(), serving HTML5 (!))
Hello world/Web server is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.
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!

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

Starting a web browser or opening a new window with this URL is not part of the task. Also you do not need to bother serving proper HTML, as browsers generally do the right thing with simple text like this. Your program must however, start or implement a server that accepts multiple client connections and serves text as requested.

C

This is, um, slightly longer than what other languages would be. <lang C>#include <stdio.h>

  1. include <stdlib.h>
  2. include <unistd.h>
  3. include <sys/types.h>
  4. include <sys/socket.h>
  5. include <netinet/in.h>
  6. include <netdb.h>
  7. include <arpa/inet.h>
  8. 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>

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>

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