Annotation of loncom/lonhttpd, revision 1.10

1.1       www         1: #!/usr/bin/perl
1.10    ! albertel    2: # $Id: lonhttpd,v 1.9 2003/07/30 15:28:56 www Exp $
1.1       www         3: 
1.6       albertel    4: $VERSION = "1.3.2 (Demonic/Linux/LON-CAPA Derivative $Revison$)";
1.1       www         5: 
1.3       www         6: # HTTPi Hypertext Tiny Truncated Process Implementation
                      7: # Copyright 1999-2001 Cameron Kaiser # All rights reserved
                      8: # Please read LICENSE # Do not strip this copyright message.
                      9: #
                     10: # LON-CAPA: find httpi license and readme at CVS loncom/license
                     11: #
                     12: 
1.6       albertel   13: use lib '/home/httpd/lib/perl/';
                     14: use LONCAPA::Configuration();
                     15: %loncapavar=%{&LONCAPA::Configuration::read_conf('loncapa.conf')};
                     16: $port_to_use=$loncapavar{'lonhttpdPort'};
                     17: if (!defined($port_to_use)) {
                     18:     $port_to_use='8080';
                     19: }
                     20: 
                     21: # The main server is running on 80, so exit in this case
                     22: if ($port_to_use eq '80') { die('Apache is already on Port 80'); }
                     23: 
1.3       www        24: %system_content_types =
                     25: 	("html" => "text/html",
                     26: 	 "htm" => "text/html",
                     27: 	 "wml" => "text/vnd.wap.wml",
                     28: 	 "wbmp" => "image/vnd.wap.wbmp",
                     29: 	 "wbm" => "image/vnd.wap.wbmp",
                     30: 	 "xbm" => "image/x-xbitmap",
                     31: 	 "pdf" => "application/pdf",
                     32: 	 "fdf" => "application/vnd.fdf",
                     33: 	 "bin" => "application/octet-stream",
                     34: 	 "class" => "application/octet-stream",
                     35: 	 "jar" => "application/octet-stream",
                     36: 	 "js" => "application/x-javascript",
                     37: 	 "lnk" => "application/x-hyperlink",
                     38: 	 "wav" => "audio/x-wav",
                     39: 	 "mp3" => "audio/x-mpeg",
                     40: 	 "tif" => "image/tiff",
                     41: 	 "tiff" => "image/tiff",
                     42: 	 "mid" => "audio/x-midi",
                     43: 	 "txt" => "text/plain",
                     44: 	 "gif" => "image/gif",
                     45: 	 "sit" => "application/x-stuffit",
                     46: 	 "zip" => "application/x-zip-compressed",
                     47: 	 "lzh" => "application/octet-stream",
                     48: 	 "lha" => "application/octet-stream",
                     49: 	 "gz"  => "application/x-gzip",
                     50: 	 "mov" => "movie/quicktime",
                     51: 	 "mpeg" => "video/mpeg",
                     52: 	 "mpg" => "video/mpeg",
                     53: 	 "jpeg" => "image/jpeg",
                     54: 	 "jpg" => "image/jpeg");
                     55: 
                     56: $logfile = "/home/httpd/perl/logs/lonhttpd.log";
                     57: 
                     58: # Write out PID
                     59: 
                     60: $pidfile="/home/httpd/perl/logs/lonhttpd.pid";
                     61: 
                     62: if (-e $pidfile) {
                     63:    open(LFH,"$pidfile");
1.10    ! albertel   64:    my $pide=<LFH>;
1.3       www        65:    chomp($pide);
                     66:    close(LFH);
                     67:    if (kill 0 => $pide) { die "already running"; }
                     68: }
                     69: 
                     70: $path = "/home/httpd/html";
                     71: $sockaddr = 'S n a4 x8';
1.1       www        72: 
                     73: 
1.3       www        74: %content_types =
                     75: 	("html" => "text/html",
                     76: 	 "htm" => "text/html");
                     77: %restrictions =
                     78: 	("/"        => "#.##",  # deny everything
                     79:          "/res/adm" => ".###",  # allow /res/adm
                     80:          "/adm"     => ".###",  # allow /adm
                     81: 	 "/status"  => ".####lonadm:oeRooOvb3HtpI");
                     82: 		# See documentation for interpreting this string.
                     83: 
                     84: $headers = <<"EOF";
                     85: Server: HTTPi/$VERSION
                     86: MIME-Version: 1.0
                     87: EOF
                     88: 
                     89: %virtual_files =
                     90: 	(
                     91: "/adm/lonLCDfont/0.gif" => [ "image/gif", "FILE",
                     92: 		"/home/httpd/html/adm/lonLCDfont/0.gif" ] ,
                     93: "/adm/lonLCDfont/1.gif" => [ "image/gif", "FILE",
                     94: 		"/home/httpd/html/adm/lonLCDfont/1.gif" ] ,
                     95: "/adm/lonLCDfont/2.gif" => [ "image/gif", "FILE",
                     96: 		"/home/httpd/html/adm/lonLCDfont/2.gif" ] ,
                     97: "/adm/lonLCDfont/3.gif" => [ "image/gif", "FILE",
                     98: 		"/home/httpd/html/adm/lonLCDfont/3.gif" ] ,
                     99: "/adm/lonLCDfont/4.gif" => [ "image/gif", "FILE",
                    100: 		"/home/httpd/html/adm/lonLCDfont/4.gif" ] ,
                    101: "/adm/lonLCDfont/5.gif" => [ "image/gif", "FILE",
                    102: 		"/home/httpd/html/adm/lonLCDfont/5.gif" ] ,
                    103: "/adm/lonLCDfont/6.gif" => [ "image/gif", "FILE",
                    104: 		"/home/httpd/html/adm/lonLCDfont/6.gif" ] ,
                    105: "/adm/lonLCDfont/7.gif" => [ "image/gif", "FILE",
                    106: 		"/home/httpd/html/adm/lonLCDfont/7.gif" ] ,
                    107: "/adm/lonLCDfont/8.gif" => [ "image/gif", "FILE",
                    108: 		"/home/httpd/html/adm/lonLCDfont/8.gif" ] ,
                    109: "/adm/lonLCDfont/9.gif" => [ "image/gif", "FILE",
                    110: 		"/home/httpd/html/adm/lonLCDfont/9.gif" ] ,
                    111: "/adm/lonLCDfont/a.gif" => [ "image/gif", "FILE",
                    112: 		"/home/httpd/html/adm/lonLCDfont/a.gif" ] ,
                    113: "/adm/lonLCDfont/b.gif" => [ "image/gif", "FILE",
                    114: 		"/home/httpd/html/adm/lonLCDfont/b.gif" ] ,
                    115: "/adm/lonLCDfont/c.gif" => [ "image/gif", "FILE",
                    116: 		"/home/httpd/html/adm/lonLCDfont/c.gif" ] ,
                    117: "/adm/lonLCDfont/d.gif" => [ "image/gif", "FILE",
                    118: 		"/home/httpd/html/adm/lonLCDfont/d.gif" ] ,
                    119: "/adm/lonLCDfont/e.gif" => [ "image/gif", "FILE",
                    120: 		"/home/httpd/html/adm/lonLCDfont/e.gif" ] ,
                    121: "/adm/lonLCDfont/f.gif" => [ "image/gif", "FILE",
                    122: 		"/home/httpd/html/adm/lonLCDfont/f.gif" ] ,
                    123: "/adm/lonLCDfont/g.gif" => [ "image/gif", "FILE",
                    124: 		"/home/httpd/html/adm/lonLCDfont/g.gif" ] ,
                    125: "/adm/lonLCDfont/h.gif" => [ "image/gif", "FILE",
                    126: 		"/home/httpd/html/adm/lonLCDfont/h.gif" ] ,
                    127: "/adm/lonLCDfont/i.gif" => [ "image/gif", "FILE",
                    128: 		"/home/httpd/html/adm/lonLCDfont/i.gif" ] ,
                    129: "/adm/lonLCDfont/j.gif" => [ "image/gif", "FILE",
                    130: 		"/home/httpd/html/adm/lonLCDfont/j.gif" ] ,
                    131: "/adm/lonLCDfont/k.gif" => [ "image/gif", "FILE",
                    132: 		"/home/httpd/html/adm/lonLCDfont/k.gif" ] ,
                    133: "/adm/lonLCDfont/l.gif" => [ "image/gif", "FILE",
                    134: 		"/home/httpd/html/adm/lonLCDfont/l.gif" ] ,
                    135: "/adm/lonLCDfont/m.gif" => [ "image/gif", "FILE",
                    136: 		"/home/httpd/html/adm/lonLCDfont/m.gif" ] ,
                    137: "/adm/lonLCDfont/n.gif" => [ "image/gif", "FILE",
                    138: 		"/home/httpd/html/adm/lonLCDfont/n.gif" ] ,
                    139: "/adm/lonLCDfont/o.gif" => [ "image/gif", "FILE",
                    140: 		"/home/httpd/html/adm/lonLCDfont/o.gif" ] ,
                    141: "/adm/lonLCDfont/p.gif" => [ "image/gif", "FILE",
                    142: 		"/home/httpd/html/adm/lonLCDfont/p.gif" ] ,
                    143: "/adm/lonLCDfont/q.gif" => [ "image/gif", "FILE",
                    144: 		"/home/httpd/html/adm/lonLCDfont/q.gif" ] ,
                    145: "/adm/lonLCDfont/r.gif" => [ "image/gif", "FILE",
                    146: 		"/home/httpd/html/adm/lonLCDfont/r.gif" ] ,
                    147: "/adm/lonLCDfont/s.gif" => [ "image/gif", "FILE",
                    148: 		"/home/httpd/html/adm/lonLCDfont/s.gif" ] ,
                    149: "/adm/lonLCDfont/t.gif" => [ "image/gif", "FILE",
                    150: 		"/home/httpd/html/adm/lonLCDfont/t.gif" ] ,
                    151: "/adm/lonLCDfont/u.gif" => [ "image/gif", "FILE",
                    152: 		"/home/httpd/html/adm/lonLCDfont/u.gif" ] ,
                    153: "/adm/lonLCDfont/v.gif" => [ "image/gif", "FILE",
                    154: 		"/home/httpd/html/adm/lonLCDfont/v.gif" ] ,
                    155: "/adm/lonLCDfont/w.gif" => [ "image/gif", "FILE",
                    156: 		"/home/httpd/html/adm/lonLCDfont/w.gif" ] ,
                    157: "/adm/lonLCDfont/x.gif" => [ "image/gif", "FILE",
                    158: 		"/home/httpd/html/adm/lonLCDfont/x.gif" ] ,
                    159: "/adm/lonLCDfont/y.gif" => [ "image/gif", "FILE",
                    160: 		"/home/httpd/html/adm/lonLCDfont/y.gif" ] ,
                    161: "/adm/lonLCDfont/z.gif" => [ "image/gif", "FILE",
                    162: 		"/home/httpd/html/adm/lonLCDfont/z.gif" ] ,
                    163: "/adm/lonLCDfont/colon.gif" => [ "image/gif", "FILE",
                    164: 		"/home/httpd/html/adm/lonLCDfont/colon.gif" ] ,
                    165: "/adm/lonLCDfont/slash.gif" => [ "image/gif", "FILE",
                    166: 		"/home/httpd/html/adm/lonLCDfont/slash.gif" ] ,
                    167: "/adm/lonLCDfont/hyphen.gif" => [ "image/gif", "FILE",
                    168: 		"/home/httpd/html/adm/lonLCDfont/hyphen.gif" ] ,
                    169: "/adm/lonLCDfont/space.gif" => [ "image/gif", "FILE",
                    170: 		"/home/httpd/html/adm/lonLCDfont/space.gif" ] ,
                    171: 	);
                    172: 
                    173: %content_types = (%system_content_types, %content_types);
                    174: undef %system_content_types;
                    175: 
                    176: while (($file, $arrayref) = each(%virtual_files)) {
                    177: 	my ($mime, $type, $block) = (@{ $arrayref });
                    178: 	next if ($type ne 'FILE');
                    179: 	if(open(S, "$block")) {
                    180: 		$j = $/; undef $/; $virtual_files{$file}->[2] = scalar(<S>);
                    181: 		$/ = $j; close(S);
                    182: 	} else {
                    183: 		warn "while getting virtual file $file: $!\n";
                    184: 		map_delete(%virtual_files, $file);
                    185: 	}
                    186: }
                    187: if ($pid = fork()) { exit; }
                    188: 
                    189: #
                    190: # Store parent PID
                    191: #
1.1       www       192: 
1.3       www       193: open (PIDSAVE,">$pidfile");
1.1       www       194: print PIDSAVE "$$\n";
                    195: close(PIDSAVE);
                    196: 
1.5       albertel  197: $0 = "lonhttpd: (dhttpi) binding port ...";
1.6       albertel  198: $bindthis = pack($sockaddr, 2, $port_to_use,
                    199: 		 pack('l', chr(0).chr(0).chr(0).chr(0)));
1.3       www       200: socket(S, 2, 1, 6);
                    201: setsockopt(S, 1, 2, 1);
1.6       albertel  202: bind(S, $bindthis) || die("$0: while binding port $port_to_use:\n\"$!\"\n");
1.3       www       203: listen(S, 128);
1.6       albertel  204: $0 = "lonhttpd: (dhttpi) connected and waiting ANY:$port_to_use";
1.3       www       205: 
                    206: $statiosuptime = time();
                    207: 
                    208: ###############################################################
                    209: # WHITE HATS ONLY BELOW THIS POINT -- SEE DOCUMENTATION FIRST #
                    210: ###############################################################
                    211: 
                    212: sub sock_to_host {
                    213: 	local($sock) = getpeername(STDIN);
                    214: 
                    215: 	return (undef, undef, undef) if (!$sock);
                    216: 	local($AFC, $port, $thataddr, $zero) = unpack($sockaddr, $sock);
                    217: 	local($ip) = join('.', unpack("C4", $thataddr));
                    218: 	return ($ip, $port, $ip);
                    219: }
                    220: 
                    221: sub htsponse {
                    222: 	($currentcode, $currentstring) = (@_);
                    223: 	return if (0+$httpver < 1);
                    224: 	local($what) = <<"EOF";
                    225: HTTP/$httpver $currentcode $currentstring
                    226: ${headers}Date: $rfcdate
                    227: EOF
                    228: 	$what =~ s/\n/\r\n/g;
                    229: 	print stdout $what;
                    230: 	&hthead("Connection: close") if (0+$httpver > 1);
                    231: }
                    232: 
                    233: sub hthead {
                    234: 	local($header, $term) = (@_);
                    235: 	return if (0+$httpver < 1);
                    236: 	print stdout "$header\r\n" , ($term) ? "\r\n" : "";
                    237: }
                    238: 
                    239: sub htcontent {
                    240: 	local($what, $ctype, $mode) = (@_);
                    241: 	($contentlength) = $mode || length($what);
                    242: 	&hthead("Content-Length: $contentlength");
                    243: 	&hthead("Content-Type: $ctype", 1);
                    244: 	return if ($method eq 'HEAD' || $mode);
                    245: 	print stdout $what;
                    246: }
                    247: 
                    248: sub log {
                    249:  	if (open(J, ">>$logfile")) {
                    250: 		local $q = $address . (($variables) ? "?$variables" : "");
                    251: 		$contentlength += 0;
                    252: 		$contentlength = 0 if ($method eq 'HEAD');
                    253: 		local ($hostname, $port, $ip) = &sock_to_host();
                    254: 		$hostname = $hostname || "-";
                    255: 		$httpuser = $httpuser || "-";
                    256: 		print J <<"EOF";
                    257: $hostname - $httpuser [$date] "$method $q HTTP/$httpver" $currentcode $contentlength "$httpref" "$httpua"
                    258: EOF
                    259: 		close(J); }
                    260: 	}
                    261: 
                    262: 
1.9       www       263: sub bye { exit; }
                    264: 
                    265: sub goodbye { unlink($pidfile); exit; }
1.3       www       266: 
                    267: sub dead {
                    268: 	&htsponse(500, "Server Error");
                    269: 	&hterror("Server Error", <<"EOF");
                    270: While handling a request for resource $address, the server crashed. Please
                    271: attempt to notify the administrators.
                    272: <p>Useful(?) debugging information:
                    273: <pre>
                    274: @_
                    275: </pre>
                    276: EOF
                    277: 	&log; unlink($pidfile); exit;
                    278: }
                    279: 
                    280: $SIG{'__DIE__'} = \&dead;
1.9       www       281: $SIG{'ALRM'} = \&bye;
                    282: $SIG{'TERM'} = $SIG{'INT'} = \&goodbye;
1.3       www       283: 
                    284: sub master {
1.5       albertel  285: 	$0 = "lonhttpd: (dhttpi) handling request";
1.3       www       286: # $sock = getpeername(STDIN);
                    287: $rfcdate = scalar gmtime;
                    288: ($dow, $mon, $dt, $tm, $yr) = ($rfcdate =~
                    289: 	m/(...) (...) (..) (..:..:..) (....)/);
                    290: $dt += 0; $yr += 0;
                    291: $rfcdate = "$dow, $dt $mon $yr $tm GMT";
                    292: $date = scalar localtime;
                    293: ($dow, $mon, $dt, $tm, $yr) = ($date =~
                    294: 	m/(...) (...) (..) (..:..:..) (....)/);
                    295: $dt += 0;
                    296: $dt = substr("0$dt", length("0$dt") - 2, 2);
                    297: $date = "$dt/$mon/$yr:$tm +0000"; 
                    298: 
                    299: select(STDOUT); $|=1; $address = 0; 
                    300: alarm 1;
                    301: while (<STDIN>) {
1.8       albertel  302: 	if(/^([A-Z]+)\s+(\S+)\s+(\S*)/) {
1.3       www       303: 		$method = $1;
                    304: 		$address = $2; 
                    305: 		$httpver = $3;
                    306: 		$httpref = '';
                    307: 		$httpua = '';
                    308: 		$httpver = ($httpver =~ m#HTTP/([0-9]\.[0-9]+)#) ?
                    309: 			($1) : (0.9);
                    310: 		$address =~ s#^http://[^/]+/#/#;
                    311: 		next unless ($httpver < 1);
                    312: 	} else {
                    313: 		s/[\r\l\n\s]+$//;
                    314: 		(/^Host: (.+)/i) && ($httphost = $1) && ($httphost =~
                    315: 			s/:\d+$//);
                    316: 		(/^Referer: (.+)/i) && ($httpref = $1);
                    317: 		(/^User-agent: (.+)/i) && ($httpua = $1);
                    318: 		(/^Content-length: (\d+)/i) && ($ENV{'CONTENT_LENGTH'} =
                    319: 			$httpcl = $1);
                    320: 		(/^Content-type: (.+)/i) && ($ENV{'CONTENT_TYPE'} =
                    321: 			$httpct = $1);
                    322: 		(/^Expect: /) && ($expect = 1);
                    323: 		(/^Authorization: Basic (.+)/i) && ($httprawu = $1);
                    324: 		(/^Range: (.+)/i) && ($ENV{'CONTENT_RANGE'} = $1);
                    325: 		next unless (/^$/);
                    326: 	}
                    327: 	if ($expect) {
                    328: 		&htsponse(417, "Expectation Failed");
                    329: 		&hterror("Expectation Failed",
                    330: 			"The server does not support this method.");
                    331: 		&log; exit;
                    332: 	}
                    333: 	if (!$address || (0+$httpver > 1 && !$httphost)) {
                    334: 		&htsponse(400, "Bad Request");
                    335: 		&hterror("Bad Request",
                    336: 			"The server cannot understand your request.");
                    337: 		&log; exit;
                    338: 	}
                    339: 	if ($method !~ /^(GET|HEAD|POST)$/) {
                    340: 		&htsponse(501, "Illegal Method");
                    341: 		&hterror("Illegal Method",
                    342: 			"Only GET, HEAD and POST are supported.");
                    343: 		&log; exit;
                    344: 	}
                    345: 	($address, $variables) = split(/\?/, $address);
                    346: 	$address =~ s/%([0-9a-fA-F]{2})/pack("H2", $1)/eg;
                    347: 	$address=~ s#^/?#/#;
                    348: 	1 while $address =~ s#/\.(/|$)#\1#;
                    349:         1 while $address =~ s#/[^/]*/\.\.(/|$)#\1#;
                    350: 	1 while $address =~ s#^/\.\.(/|$)#\1#;
                    351: 	$fail = 0;
                    352: #
                    353: # Heavily customized for LON-CAPA
                    354: #
1.4       www       355: 	$address=~s/\/+/\//g;
1.3       www       356: 	unless ($address=~/^\/(status|adm\/|res\/adm\/)/) { $fail=1; }
                    357: #
                    358: # because existing restriction matrix would not do precedence across rules
                    359: #
                    360: #	J: foreach(sort { length $a <=> length $b }
                    361: #			keys %restrictions) {
                    362: #		next if ($address !~ /^$_/);
                    363: #		($allowip, $denyip, $allowua, $denyua, $auser) =
                    364: #			split(/#/, $restrictions{$_});
                    365: #		if ($allowip || $denyip) {
                    366: #			($hostname, $port, $ip) = &sock_to_host();
                    367: #			($allowip && $ip !~ /$allowip/) && ($fail = 1,
                    368: #				last J);
                    369: #			($denyip && $ip =~ /$denyip/) && ($fail = 1,
                    370: #				last J);
                    371: #		}
                    372: #		($allowua && $httpua !~ /$allowua/) &&
                    373: #			($fail = 2, last J);
                    374: #		($denyua && $httpua =~ /$denyua/) &&
                    375: #			($fail = 2, last J);
                    376: #	}
                    377: 	if ($fail) {
                    378: 		&htsponse(403, "Forbidden");
                    379: 		if ($fail == 1) {
1.7       www       380: 			&hterror("Wrong URL", <<"EOF");
                    381: You might want to remove the "<tt>:$port_to_use</tt>" from the web page address (URL).
1.3       www       382: EOF
                    383: 			&log; exit;
                    384: 		} else {
                    385: 			&hterror("Forbidden (Browser Disallowed)", <<"EOF");
                    386: The browser you are using (<i>$httpua</i>) is not capable of or
                    387: is not allowed access to this resource.
                    388: EOF
                    389: 			&log; exit;
                    390: 		}
                    391: 	}
                    392: 	if ($auser) {
                    393: 		$httprawu =~ tr#A-Za-z0-9+/##cd;
                    394: 		$httprawu =~ tr#A-Za-z0-9+/# -_#;
                    395: 		$httprawu = unpack("u", pack("c", 32+0.75*length($httprawu))
                    396: 			. $httprawu);
                    397: 		($httpuser, $httppw) = split(/:/, $httprawu);
                    398: 		$fail = 1;
                    399: 		foreach $user (split(/,/, $auser)) {
                    400: 			($user, $pw) = split(/:/, $user);
                    401: 			($fail = 0, last) if ($user eq $httpuser &&
                    402: 				crypt($httppw, substr($pw, 0, 2)) eq $pw);
                    403: 		}
                    404: 		if ($fail) {
                    405: 			$httpuser = '';
                    406: 			&htsponse(401, "Authorization Required");
                    407: 			&hthead("WWW-Authenticate: Basic realm=\"$address\"");
                    408: 			&hterror("Authorization Required", <<"EOF");
                    409: You must provide a username and password to use this resource. Either you
                    410: entered this information incorrectly, or your browser does not know how to
                    411: present the credentials required.
                    412: EOF
                    413: 			&log; exit;
                    414: 		}
                    415: 	}
1.1       www       416: 
1.3       www       417: 	alarm 0;
                    418: 
                    419: 	if ($address eq '/status') {
                    420: 		&htsponse(200, "OK");
                    421: 		$contentlength = 0; # kludge
                    422: 		&log;
                    423: 		if(open(S, $logfile)) {
                    424: 			seek(S, -5000, 2);
                    425: 			undef $/;
                    426: 			$logsnap = <S>;
                    427: 			$logsnap =~ s/^[^\n]+\n//s if
                    428: 				(length($logsnap) > 4999);
                    429: 			close(S);
                    430: 		}
                    431: 		$p = (time() - $statiosuptime);
                    432: 		$rps = $p/$statiosreq;
                    433: 		$d = int($p / 86400); $p -= $d * 86400;
                    434: 		$h = int($p / 3600); $p -= $h * 3600;
                    435: 		$m = int($p / 60); $s = $p - ($m * 60);
                    436: 		("0$s" =~ /(\d{2})$/) && ($s = $1);
                    437: 		("0$m" =~ /(\d{2})$/) && ($m = $1);
                    438: 		$h +=0; $d += 0;
                    439: 		$suptime = scalar localtime $statiosuptime;
                    440: 		&htcontent(<<"EOF", "text/html");
                    441: <html>
                    442: <head>
                    443: <title>
1.5       albertel  444: LonHTTPD (HTTPi) Status
1.3       www       445: </title>
                    446: </head>
                    447: <body bgcolor = "#ffffff" text = "#000000" vlink = "#0000ff" link = "#0000ff">
1.5       albertel  448: <h1>LonHTTPD (HTTPi) Server Status (<code>$VERSION</code>)</h1>
1.6       albertel  449: <h3>lonhttpd on port $port_to_use</h3>
1.3       www       450: <b>Started at:</b> $suptime<br>
                    451: <b>Uptime:</b> $d days, $h:$m:$s<br>
                    452: <b>Last request time:</b> $statiosltr<p>
                    453: <b>Requests received:</b> $statiosreq<br>
                    454: <b>Average time between requests:</b> ${rps}s
                    455: <p>
                    456: <b>Most recent requests:</b>
                    457: <form action = "/status" method = "post">
                    458: <textarea name = "bletch" rows = "8" cols = "70">
                    459: $logsnap
                    460: </textarea>
                    461: </form>
                    462: <hr>
                    463: <address>maintained by <a href =
                    464: "http://httpi.floodgap.com/">httpi/$VERSION</a></address>
                    465: </body>
                    466: </html>
                    467: EOF
                    468: 		exit;
                    469: 	}
                    470: 	if (defined $virtual_files{$address}) {
                    471: 		$virt_buffer = 1;
                    472: 		$mtime = $statiosuptime; # thus always needed
                    473: 		goto SERVEIT;		# yes, it's bad but it's fast
                    474: 	}
                    475: 	$raddress = "$path$address"
                    476: 	;
                    477: 	&hterror301("$address/")
                    478: 		if ($address !~ m#/$# && -d $raddress);
                    479: 	$raddress = "${raddress}index.html" if (-d $raddress);
                    480: 	if(!sysopen(S, $raddress, 0)) { &hterror404; } else {
                    481: 		if (-x $raddress) {
                    482: 			$currentcode = 100;
                    483: 			&log;
                    484: 			if (!$<) {
                    485: 				($x,$x,$x,$x,$uid,$gid) = stat(S);
                    486: 				(!$uid || !$gid) &&
                    487: 					die "executable is root-owned";
                    488: 				$> = $uid || die "can't set effuid";
                    489: 				$) = $gid || die "can't set effgid";
                    490: 			}
                    491: 			($hostname, $port, $ip) = &sock_to_host() if (!$port);
                    492: 			$ENV{'REQUEST_METHOD'} = $method;
                    493: 			$ENV{'SERVER_NAME'} = "localhost";
                    494: 			$ENV{'SERVER_PROTOCOL'} = "HTTP/$httpver";
                    495: 			$ENV{'SERVER_SOFTWARE'} = "HTTPi/$VERSION";
1.6       albertel  496: 			$ENV{'SERVER_PORT'} = "$port_to_use";
                    497: 			$ENV{'SERVER_URL'} = "http://localhost:$port_to_use/";
1.3       www       498: 			$ENV{'SCRIPT_FILENAME'} = $raddress;
                    499: 			$ENV{'SCRIPT_NAME'} = $address;
                    500: 			$ENV{'REMOTE_HOST'} = $hostname;
                    501: 			$ENV{'REMOTE_ADDR'} = $ip;
                    502: 			$ENV{'REMOTE_PORT'} = $port;
                    503: 			$ENV{'QUERY_STRING'} = $variables;
                    504: 			$ENV{'HTTP_USER_AGENT'} = $httpua;
                    505: 			$ENV{'HTTP_REFERER'} = $httpref;
                    506: 			if ($pid = fork()) { exit; } else {
                    507: 				if ($method eq 'POST') { # needs stdin
                    508: 					open(W, "|$raddress") || die
                    509: 						"can't POST to $raddress";
                    510: 					read(STDIN, $buf, $httpcl);
                    511: 					print W $buf;
                    512: 					exit;
                    513: 				}
                    514: 				exec "$raddress", "$variables";
                    515: 				die "exec() returned -1";
                    516: 			}
                    517: 		}
                    518: 		($x,$x,$x,$x,$x,$x,$x,$length,$x,$mtime) = stat(S);
                    519: 		$ctype = 0;
                    520: 		foreach(keys %content_types) {
                    521: 			if ($raddress =~ /\.$_$/i) {
                    522: 				$ctype = $content_types{$_};
                    523: 			}
                    524: 		}
                    525: SERVEIT:	$ctype ||= 'text/plain';
                    526: 		&htsponse(200, "OK");
                    527: 		$mtime = scalar gmtime $mtime;
                    528: 		($dow, $mon, $dt, $tm, $yr) =
                    529: 			($mtime =~ m/(...) (...) (..) (..:..:..) (....)/);
                    530: 		$dt += 0; $yr += 0;
                    531: 		&hthead("Last-Modified: $dow, $dt $mon $yr $tm GMT");
                    532: 		if ($pid = fork()) { exit; }
                    533: 		if ($virt_buffer) {
                    534: 			&htcontent($virtual_files{$address}->[2],
                    535: 				$virtual_files{$address}->[0], 0);
                    536: 		} else {
                    537: 			&htcontent("", $ctype, $length);
                    538: 			unless ($method eq 'HEAD') {
                    539: 				while(!eof(S)) {
                    540: 					read(S, $q, 16384);
                    541: 					print stdout $q;
                    542: 				}
                    543: 			}
                    544: 		}
                    545: 		alarm 0;
                    546: 	}
                    547: 	&log;
                    548: 	exit;
                    549: }
1.1       www       550: 
1.3       www       551: exit;
                    552: }
                    553: 
                    554: 
                    555: sub hterror {
                    556: 	local($errstr, $expl) = (@_);
                    557: 	&htcontent(<<"EOF", "text/html");
                    558: <html>
                    559: <body>
                    560: <h1>$errstr</h1>
                    561: $expl
                    562: <hr>
                    563: <address><a href = "http://httpi.floodgap.com/">httpi/$VERSION</a>
                    564: by Cameron Kaiser</address>
                    565: </body>
                    566: </html>
                    567: EOF
                    568: 	}
                    569: 
                    570: sub hterror404 {
                    571: 	&htsponse(404, "File Not Found");
                    572: 	&hterror("File Not Found",
                    573: 		"The resource $address was not found on this system.");
                    574: }
                    575: 
                    576: sub hterror301 {
                    577: 	&htsponse(301, "Moved Permanently");
                    578: 	&hthead("Location: @_");
                    579: 	&hterror("Resource Moved Permanently",
                    580: 		"This resource has moved <a href = \"@_\">here</a>.");
                    581: 	$keep = 0; &log; exit;
                    582: }
1.1       www       583: 
                    584: for (;;) {
1.3       www       585: 	$addr=accept(NS,S);
                    586: 	$statiosltr = scalar localtime;
                    587: 	$statiosreq++;
                    588: 	if ($pid = fork()) {
1.5       albertel  589: 		$0 = "lonhttpd: (dhttpi) waiting for child process";
1.3       www       590: 		waitpid($pid, 0);
1.6       albertel  591: 		$0 = "lonhttpd: (dhttpi) on ANY:$port_to_use, last request " .
1.3       www       592: 			scalar localtime;
                    593: 	} else {
1.5       albertel  594: 		$0 = "lonhttpd: (dhttpi) child switching to socket";
1.3       www       595: 		open(STDIN, "<&NS");
                    596: 		open(STDOUT, ">&NS");
                    597: 		&master;
                    598: 		exit;
                    599: 	}
1.1       www       600: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.