#!/usr/bin/perl # Very simple PUT handler. # From apacheweek. Changed by Jonathan Riddell (jr@jriddell.org) to # work with Central Radio Taxis website. # Parts Copyright 2001 Jonathan riddell #this is a hack upon a hack # A simple log file, must be writable by the user that this program runs as. # Should not be within the document tree. $putlog = "log"; $tempfile = "/home/riddell/www/example.com/tempfile"; # Check we are using PUT method if ($ENV{'REQUEST_METHOD'} ne "PUT") { &reply(500, "Request method is not PUT"); } # Note: should also check we are an authentication user by checking # REMOTE_USER # Check we got a destination filename $filename = $ENV{'PATH_TRANSLATED'}; if (!$filename) { &reply(500, "No PATH_TRANSLATED"); } if ($filename =~ /\.\./) { &reply(500, "Invalid name - shouldn't contain '..'"); } if ($filename !~ /(\.html|\.gif|\.jpg|\.png|\.css)$/) { &reply(500, "Invalid name = should end in '.html'"); } # Check we got some content $clength = $ENV{'CONTENT_LENGTH'}; if (!$clength) { &reply(500, "Content-Length missing or zero ($clength)"); } # Read the content itself $toread = $clength; $content = ""; while ($toread > 0) { $nread = read(STDIN, $data, $clength); &reply(500, "Error reading content") if !defined($nread); $toread -= $nread; $content = $data; } # Write it out # Note: doesn't check the location of the file, whether it already # exists, whether it is a special file, directory or link. Does not # set the access permissions. Does not handle subdirectories that # need creating. my $readtemp = ""; #parse HTML if ($filename =~ /(\.html)$/) { open(OUT, "> $tempfile") || &reply(500, "Cannot write to $tempfile"); print OUT $content; close(OUT); $tidyreturn = system("/usr/bin/tidy -i -m $tempfile 2>/dev/null"); if (($tidyreturn/256) == 2) { &reply(500, "The HTML could not be tidied, please edit and retry"); } #remove headers and footers and put in PHP. You will need to change this # or remove it to suit your site open(IN, "$tempfile") || &reply(500, "Cannot read $tempfile"); my $head = 0; my $foot = 0; while () { my $in = $_; if ($in =~ /\<\!-- &&&end of header (.) -->/) { $page_index = $1; if ($head == 1) {&reply(500, "End of header comment read twice");} $head = 1; $readtemp .= "\n\n"; } elsif ($in =~ /\<\!-- &&&start of footer (.) -->/) { $page_index = $1; if ($foot == 1) {&reply(500, "Start of footer comment read twice");} $foot = 1; $readtemp .= "\n\n\n\n"; } elsif ($head == 1 && $foot == 0) { $readtemp .= $in; } } if ($head == 0) { &reply(500, "Missing header comment"); } if ($foot == 0) { &reply(500, "Missing footer comment"); } open(OUT, "> $filename") || &reply(500, "Cannot write to $filename"); print OUT $readtemp; close(OUT); } else { #file wasn't HTML, just write it out open(OUT, "> $filename") || &reply(500, "Cannot write to $tempfile"); print OUT $content; close(OUT); } # Everything seemed to work, reply with 204 (or 200). Should reply with 201 # if content was created, not updated. &reply(204); exit(0); # # Send back reply to client for a given status. # sub reply { local($status, $message) = @_; local($remuser, $remhost, $logline) = (); print "Status: $status\n"; print "Content-Type: text/html\n\n"; if ($status == 200) { print "OK

Content Accepted

\n"; } elsif ($status == 500) { print "Error

Error Publishing File

\n"; print "An error occurred publishing this file ($message).\n"; } # Note: status 204 and 201 gives have content part # Create a simple log $remuser = $ENV{'REMOTE_USER'} || "-"; $remhost = $ENV{'REMOTE_HOST'} || $ENV{'REMOTE_ADDR'} || "-"; ($sec,$min,$hour,$day,$mon,$year,$wday,$yday,$isdst) = localtime(time()); $mon += 1; $year -= 100; $year +=2000; $logline = sprintf("%02d/%02d/%2d %02d:%02d:%02d",$day,$mon,$year,$hour,$min,$sec,); $logline .= " $remhost $remuser $filename status $status"; $logline .= " ($message)" if ($status == 500); &log($logline); exit(0); } sub log { local($msg) = @_; open (LOG, ">> $putlog") || return; print LOG "$msg\n"; close(LOG); open(SENDMAIL, "|/usr/lib/sendmail -oi -t -odq") or die "Can't fork for sendmail: $!\n"; print SENDMAIL <<"EOF"; From: put log To: foo\@example.com Subject: Electrospect put log $msg EOF close(SENDMAIL) or warn "sendmail didn't close nicely"; }