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