Annotation of loncom/lonhttpd, revision 1.1

1.1     ! www         1: #!/usr/bin/perl
        !             2: # The LearningOnline Network with CAPA
        !             3: # lonhttpd server (port 8080)
        !             4: # based on
        !             5: # TinyHTTPD - a minimum-functional HTTP server written in -*- Perl -*-
        !             6: # -ot.0894
        !             7: # $Id: lonhttpd,v 1.3 2002/10/29 19:37:32 www Exp $
        !             8: 
        !             9: # Currently supported: HTTP 1.0/1.1 GET and POST queries
        !            10: # File types of .html and .gif
        !            11: 
        !            12: $ENV{'SERVER_SOFTWARE'}="TinyHTTPD $Revision: 1.3 $ -ot.0894 (LON-CAPA)";
        !            13: 
        !            14: 
        !            15: use POSIX;
        !            16: 
        !            17: $pid=fork;
        !            18: exit if $pid;
        !            19: die "Could not fork: $!" unless defined($pid);
        !            20: POSIX::setsid() or die "Can't start new session: $!";
        !            21: open (PIDSAVE,">/home/httpd/perl/logs/lonhttpd.pid");
        !            22: print PIDSAVE "$$\n";
        !            23: close(PIDSAVE);
        !            24: 
        !            25: sub REAPER {
        !            26:     1 until (-1==waitpid(-1,WNOHANG));
        !            27:     $SIG{CHLD}=\&REAPER;
        !            28: }
        !            29: 
        !            30: $SIG{CHLD}=\&REAPER;
        !            31: 
        !            32: ## Configuration section
        !            33: $port=8080;			# Port on which we listen
        !            34: $htmldir="/home/httpd/html/";	# Base directory for HTML files
        !            35: 
        !            36: # the following substitutes "require 'sys/socket.ph';" on ultrix
        !            37: # Check if the definitions are correct with /usr/include/sys/socket.h
        !            38: $AF_INET=2; $PF_INET=$AF_INET; $SOCK_STREAM=1;
        !            39: 
        !            40: # Messages
        !            41: %errors=
        !            42:     (
        !            43:      "403", "Forbidden",
        !            44:      "404", "Not Found",
        !            45:      "500", "Internal Error",
        !            46:      "501", "Not Implemented",
        !            47:      );
        !            48: %verrors=
        !            49:     (
        !            50:      "403", "Your client is not allowed to request this item",
        !            51:      "404", "The requested item was not found on this server",
        !            52:      "500", "An error occurred while trying to retrieve item",
        !            53:      "501", "This server does not support the given request type",
        !            54:      );
        !            55: 
        !            56: (($>)&&($<==$>)&&($(==$))) || die "Don't run this program with privileges!\n";
        !            57: 
        !            58: # set up a server socket, redirect stderr to logfile
        !            59: $IPPROTO_TCP=6;
        !            60: $sockaddr = 'S n a4 x8';
        !            61: $this = pack($sockaddr, $AF_INET, $port, "\0\0\0\0");
        !            62: socket(S, $PF_INET, $SOCK_STREAM, $IPPROTO_TCP) || die "socket: $!";
        !            63: bind(S, $this) || die "bind: $!";
        !            64: listen(S, 5) || die "listen: $!";
        !            65: open(LOG,">>/home/httpd/perl/logs/lonhttpd.log");
        !            66: select(LOG); $|=1;
        !            67: open(STDERR, ">&LOG") || die "dup2 log->stderr";
        !            68: 
        !            69: # accept incoming calls
        !            70: for (;;) {
        !            71:     ($addr=accept(NS,S)) || die "accept: $!";
        !            72:     next if $pid=fork;
        !            73:     die "fork: $!" unless defined $pid;
        !            74:     close(S);
        !            75:     ($a,$p,$inetaddr) = unpack($sockaddr, $addr);
        !            76:     @inetaddr = unpack('C4', $inetaddr);
        !            77:     ($host,$aliases) = gethostbyaddr($inetaddr, $AF_INET);
        !            78:     $inetaddr = join(".", @inetaddr);
        !            79:     @host=split(' ', "$host $aliases");
        !            80:     $host || do { $host = $inetaddr; };
        !            81:     @t=localtime;
        !            82:     open(STDIN, "+<&NS") || die "dup2 ns->stdin";
        !            83:     open(STDOUT, "+>&NS") || die "dup2 ns->stdout";
        !            84:     select(STDOUT); $|=1;
        !            85:     &serve_request;
        !            86:     close(STDIN); close(STDOUT);
        !            87:     exit;
        !            88: }
        !            89: 
        !            90: # Read request from stdin and produce output
        !            91: sub serve_request {
        !            92: 
        !            93:     # Analyze HTTP input.
        !            94:     $_=<STDIN>;
        !            95:     ($method, $url, $proto) = split;
        !            96:     if ($proto) {
        !            97: 	while (<STDIN>) { 
        !            98: 	    s/\n|\r//g; # kill CR and NL chars
        !            99: 	    /^Content-Length: (\S*)/i && ($content_length=$1);
        !           100: 	    /^Content-Type: (\S*)/i && ($content_type=$1);
        !           101: 	    length || last; # empty line - end of header
        !           102: 	}
        !           103:     } else {
        !           104: 	$proto="HTTP/0.9";
        !           105:     }
        !           106:     ($method=~/^(GET|POST)$/) || do { &error(501,$method); return; };
        !           107: 
        !           108:     # prevent directory go-back
        !           109:     $url=~/\.\./ && do { &error(403,$url,"contains go-back"); return; };
        !           110: 
        !           111:     # Check access control
        !           112:     unless (($url=~/^\/res\/adm\//) || ($url=~/^\/adm\//)) {
        !           113:         do { &error(403,$url,"not on allow list"); return; };
        !           114:     }
        !           115:     print LOG "$$: $url\n";
        !           116: 
        !           117: # Get and return file
        !           118: 
        !           119: 	$file="$htmldir$url";
        !           120: 	(-r "$file") || do { &error(404,$url); return; };
        !           121: 	# output the file
        !           122: 	print "HTTP/1.0 200 OK\nMIME-Version: 1.0\nContent-Type: ";
        !           123:         CASE:	
        !           124: 	{
        !           125: 	    $url=~/\.html$/ && do { print "text/html\n\n"; last CASE; };
        !           126: 	    $url=~/\.gif$/ && do { print "image/gif\n\n"; last CASE; };
        !           127: 	    print "text/plain\n\n";
        !           128: 	}
        !           129: 	system("cat $file");
        !           130: }
        !           131: 
        !           132: sub error {
        !           133:     # generate error response
        !           134:     local($errno) = @_[0];
        !           135:     local($errmsg) = "$errno $errors{$errno}";
        !           136:     print LOG "$$ $errmsg (@_[1,2])\n";
        !           137:     print <<TheEnd;
        !           138: HTTP/1.0 $errmsg
        !           139: MIME-version: 1.0
        !           140: Content-type: text/html
        !           141: 
        !           142: <HTML>
        !           143: <HEAD><TITLE>$errmsg</TITLE></HEAD>
        !           144: <BODY><H1>$errmsg</H1>
        !           145: $verrors{$errno}: <PRE> @_[1] </PRE>
        !           146: <HR>
        !           147: <ADDRESS><A HREF="http://www.lon-capa.org/">
        !           148: $ENV{'SERVER_SOFTWARE'} by Olaf Titz, modified by LON-CAPA</A></ADDRESS>
        !           149: </BODY>
        !           150: </HTML>
        !           151: TheEnd
        !           152: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>