crossroads

Git mirror of https://crossroads.e-tunity.com/
git clone git://git.finwo.net/app/crossroads
Log | Files | Refs

chunkedserver (2468B)


      1 #!/usr/bin/perl
      2 
      3 use strict;
      4 use Socket;
      5 use POSIX;
      6 
      7 # Verbose messaging
      8 sub msg {
      9     print STDERR ("chunkedserver: ", @_);
     10 }
     11 
     12 # Child process catcher
     13 sub reaper {
     14     while ((my $waitedpid = waitpid(-1,WNOHANG)) > 0) {
     15         msg ("Child $waitedpid done",
     16              ($? ? " with exit $?" : ''),
     17              "\n");
     18     }
     19     $SIG{CHLD} = \&reaper;
     20 }
     21 
     22 # Connection handler
     23 sub handleconnection () {
     24     my $pid;
     25 
     26     # Daemonize
     27     if (!defined ($pid = fork())) {
     28         msg ("Can't fork: $!\n");
     29         return;
     30     } elsif ($pid) {
     31         # Parent branch
     32         msg ("Connection handler started as pid $pid\n");
     33         return;
     34     }
     35 
     36     # Child branch
     37     while (defined (my $line = <Client>)) {
     38 	chomp ($line);
     39 	$line =~ s/\r//;
     40 	last if ($line eq '');
     41 	msg ("Client says: [$line]\n");
     42     }
     43 
     44     msg ("Sending response\n");
     45     print Client ("HTTP/1.1 200 OK\r\n",
     46 		  "Connection: close\r\n",
     47 		  "Transfer-Encoding: chunked\r\n",
     48 		  "Content-Type: text/plain\r\n",
     49 		  "\r\n",
     50 		  "5\r\n",
     51 		  "Hello\r\n",
     52 		  "1\r\n",
     53 		  " \r\n",
     54 		  "5\r\n",
     55 		  "World\r\n",
     56 		  "2\r\n",
     57 		  "!\n\r\n",
     58 		  "0\r\n",
     59 		  "\r\n");
     60     exit (0);
     61 }
     62 
     63 # Daemon server
     64 sub serve ($) {
     65     my $port = shift;
     66     
     67     # Create the tcp service.
     68     socket (Server, PF_INET, SOCK_STREAM, getprotobyname ('tcp'))
     69       or die ("Can't create chunkedserver socket: $!\n");
     70     setsockopt (Server, SOL_SOCKET, SO_REUSEADDR, pack("l", 1))
     71       or die ("Can't set socket options: $!\n");
     72     bind (Server, sockaddr_in ($port, INADDR_ANY))
     73       or die ("Can't bind to port: $!\n");
     74     listen (Server, SOMAXCONN)
     75       or die ("Can't listen to socket: $!\n");
     76     msg ("Chunkedserver started on port $port.\n");
     77     
     78     $SIG{CHLD} = \&reaper;
     79     $SIG{INT} = sub {
     80         msg ("Interrupt caught, terminating..\n");
     81         exit(0);
     82     };
     83     
     84     while (1) {
     85         for (my $waitedpid = 0;
     86              (my $paddr = accept (Client, Server)) || $waitedpid;
     87              $waitedpid = 0, close (Client)) {
     88             next if ($waitedpid and not $paddr);
     89             my ($port, $iaddr) = sockaddr_in ($paddr);
     90             my $name = gethostbyaddr ($iaddr, AF_INET);
     91             
     92             msg ("Connection from $name/", inet_ntoa ($iaddr), ":$port\n");
     93             
     94             handleconnection ();
     95         }
     96     }
     97 }
     98 
     99 # Main starts here
    100 if ($#ARGV != 1) {
    101     die <<"ENDUSAGE";
    102    
    103 Usage: chunkedserver nsec portnr
    104 
    105 ENDUSAGE
    106 }
    107 
    108 alarm (shift (@ARGV));
    109 serve (shift (@ARGV));
    110