X-Git-Url: https://git.sesse.net/?p=pr0n;a=blobdiff_plain;f=perl%2FSesse%2Fpr0n%2FWebDAV.pm;h=c883a03bd0ababe0446375146c594bf06a926f07;hp=9d23bb9668af0860e186f0a25ce3a2d1cb7dd559;hb=880cae38c7c52ad9231674dc20a5f4713c822104;hpb=0da154f826ede0ad490099494c36472822a90260 diff --git a/perl/Sesse/pr0n/WebDAV.pm b/perl/Sesse/pr0n/WebDAV.pm index 9d23bb9..c883a03 100644 --- a/perl/Sesse/pr0n/WebDAV.pm +++ b/perl/Sesse/pr0n/WebDAV.pm @@ -5,6 +5,8 @@ use warnings; use Sesse::pr0n::Common qw(error dberror); use Digest::SHA1; use MIME::Base64; +use Apache2::Request; +use Apache2::Upload; sub handler { my $r = shift; @@ -466,7 +468,7 @@ EOF $dbh->do('INSERT INTO images (id,event,uploadedby,takenby,filename) VALUES (?,?,?,?,?);', undef, $newid, $event, $user, $takenby, $filename); - $dbh->do('UPDATE events SET last_update=CURRENT_TIMESTAMP WHERE event=?', + $dbh->do('UPDATE events SET last_update=CURRENT_TIMESTAMP WHERE id=?', undef, $event); # Now save the file to disk @@ -500,7 +502,7 @@ EOF if ($@) { # Some error occurred, rollback and bomb out $dbh->rollback; - dberror($r, "Transaction aborted because $@"); + error($r, "Transaction aborted because $@"); unlink($fname); } } @@ -522,7 +524,130 @@ EOF return Apache2::Const::OK; } + + # Used by the XP publishing wizard -- largely the same as the code above + # but vastly simplified. Should we refactor? + if ($r->method eq "POST") { + my $apr = Apache2::Request->new($r); + my $client_size = $apr->param('size'); + my $event = $apr->param('event'); + + my $file = $apr->upload('image'); + my $filename = $file->filename(); + if ($client_size != $file->size()) { + $r->content_type('text/plain; charset="utf-8"'); + $r->status(403); + $r->print("Client-size resizing detected; refusing automatically"); + + $r->log->info("Client-size resized upload of $event/$filename detected"); + return Apache2::Const::OK; + } + + # Ugh, Windows XP seems to be sending this in... something that's not UTF-8, at least + my $takenby_given = Sesse::pr0n::Common::guess_charset($apr->param('takenby')); + + if (defined($takenby_given) && $takenby_given !~ /^\s*$/ && $takenby_given !~ /[<>&]/ && length($takenby_given) <= 100) { + $takenby = $takenby_given; + } + + my $ne_id = Sesse::pr0n::Common::guess_charset($apr->param('neweventid')); + my $ne_date = Sesse::pr0n::Common::guess_charset($apr->param('neweventdate')); + my $ne_desc = Sesse::pr0n::Common::guess_charset($apr->param('neweventdesc')); + if (defined($ne_id)) { + # Trying to add a new event, let's see if it already exists + my $q = $dbh->prepare('SELECT COUNT(*) AS cnt FROM events WHERE id=? AND vhost=?') + or dberror($r, "Couldn't prepare event count"); + $q->execute($ne_id, $r->get_server_name) + or dberror($r, "Couldn't execute event count"); + my $ref = $q->fetchrow_hashref; + + if ($ref->{'cnt'} == 0) { + my @errors = Sesse::pr0n::Common::add_new_event($dbh, $ne_id, $ne_date, $ne_desc, $r->get_server_name); + if (scalar @errors > 0) { + die "Couldn't add new event $ne_id: " . join(', ', @errors); + } + } + + $event = $ne_id; + } + + # Remove evil characters + if ($filename =~ /[^a-zA-Z0-9._-]/) { + $filename =~ tr/a-zA-Z0-9.-/_/c; + } + + # Get the new ID + my $ref = $dbh->selectrow_hashref("SELECT NEXTVAL('imageid_seq') AS id;"); + my $newid = $ref->{'id'}; + if (!defined($newid)) { + dberror($r, "Couldn't get new ID"); + } + + # Autorename if we need to + { + my $ref = $dbh->selectrow_hashref("SELECT COUNT(*) AS numfiles FROM images WHERE event=? AND filename=?", + undef, $event, $filename) + or dberror($r, "Couldn't check for existing files"); + if ($ref->{'numfiles'} > 0) { + $r->log->info("Renaming $filename to $newid.jpeg"); + $filename = "$newid.jpeg"; + } + } + + { + # Enable transactions and error raising temporarily + local $dbh->{AutoCommit} = 0; + local $dbh->{RaiseError} = 1; + my $fname; + # Try to insert this new file + eval { + $dbh->do('INSERT INTO images (id,event,uploadedby,takenby,filename) VALUES (?,?,?,?,?);', + undef, $newid, $event, $user, $takenby, $filename); + $dbh->do('UPDATE events SET last_update=CURRENT_TIMESTAMP WHERE id=?', + undef, $event); + + # Now save the file to disk + $fname = Sesse::pr0n::Common::get_disk_location($r, $newid); + open NEWFILE, ">$fname" + or die "$fname: $!"; + + my $buf; + $file->slurp($buf); + print NEWFILE $buf or die "write($fname): $!"; + close NEWFILE or die "close($fname): $!"; + + # Orient stuff correctly + system("/usr/bin/exifautotran", $fname) == 0 + or die "/usr/bin/exifautotran: $!"; + + # Make cache while we're at it. + Sesse::pr0n::Common::ensure_cached($r, $filename, $newid, -1, -1, 1, 80, 64, 320, 256, -1, -1); + + # OK, we got this far, commit + $dbh->commit; + + $r->log->notice("Successfully wrote $event/$filename to $fname"); + }; + if ($@) { + # Some error occurred, rollback and bomb out + $dbh->rollback; + error($r, "Transaction aborted because $@"); + unlink($fname); + + $r->content_type('text/plain; charset="utf-8"'); + $r->status(500); + $r->print("Error: $@"); + } + } + + $r->content_type('text/plain; charset="utf-8"'); + $r->status(201); + $r->print("OK"); + + return Apache2::Const::OK; + } + # Yes, we fake locks. :-) if ($r->method eq "LOCK") { if ($r->uri !~ m#^/webdav/upload/([a-zA-Z0-9-]+)/(autorename/)?([a-zA-Z0-9._-]+)$#) { @@ -601,7 +726,7 @@ EOF $r->print("Sorry, you do not have access to that feature."); return Apache2::Const::OK; } - + $r->content_type('text/plain; charset=utf-8'); $r->log->error("unknown method " . $r->method); $r->status(500);