#!/usr/bin/perl use strict; use warnings "all"; use Fcntl; use BerkeleyDB; my $str = ''; my $DIR = '/var/www/p.dafuq.ru/paste'; my $TSDB = "$DIR/timestamps.db"; my $DB = "$DIR/data.db"; my $URL = 'http://p.dafuq.ru/'; my $fsize = 262144; my $minlen = 3; my $maxlen = 9; sub initdb(); sub showindex($); sub eclient(); sub dclient(); sub getpaste($); my $dbh = initdb(); showindex('') unless (defined($ENV{'REQUEST_METHOD'})); if ($ENV{'REQUEST_METHOD'} eq 'GET'){ showindex('') unless (defined($ENV{'QUERY_STRING'})); if ($ENV{'QUERY_STRING'} eq 'e'){ eclient(); } if ($ENV{'QUERY_STRING'} eq 'd'){ dclient(); } getpaste($ENV{'QUERY_STRING'}); # assume POST(?) request }elsif($ENV{'REQUEST_METHOD'} eq 'POST'){ showindex('') unless (defined($ENV{'CONTENT_LENGTH'})); showindex('') if ($ENV{'CONTENT_LENGTH'} == ''); showindex('') if ($ENV{'CONTENT_LENGTH'} > $fsize); showindex('') if ($ENV{'CONTENT_LENGTH'} eq '0'); my $fname; # url key length should be 3-9 symbols my $urllen = int(rand ($maxlen - $minlen)) + $minlen; for(my $i = 0;$i < $urllen; $i++){ $fname .= ('a'..'z', 'A'..'Z')[int rand length(join('',('a'..'z', 'A'..'Z')))]; } if ( $dbh->db_get($fname, undef) == 0 ){ # looks like we already have value here # TODO: check timestamp! if ( $dbh->db_del($fname) != 0 ){ # oops, error... how can it be here? $str = 'Status: 500 Application Error Pragma: no-cache Cache-Control: no-cache Content-Language: en, ru Content-type: text/plain Application error - unable to delete key in $DB '; } } my $c = 0; my $delim = ''; my $header = ''; my $char = ''; while(read(STDIN, $char, 1)){ # looks like this case is obviously sic, but... :) if($c >= $ENV{'CONTENT_LENGTH'}){ $str = 'Status: 400 Bad Request Pragma: no-cache Cache-Control: no-cache Content-Language: en, ru Content-type: text/plain '; } last if ($char eq "\n"); $delim .= $char; $c++; } read(DATA, $char, 1); while(read(STDIN, $char, 1)){ if($c >= $ENV{'CONTENT_LENGTH'}){ $str = 'Status: 400 Bad Request Pragma: no-cache Cache-Control: no-cache Content-Language: en, ru Content-type: text/plain '; } last if ($char eq "\n"); $header .= $char; $c++; } unless ($header =~ /Content-Disposition: form-data; name=.exs./) { $str = 'Status: 400 Bad Request Pragma: no-cache Cache-Control: no-cache Content-Language: en, ru Content-type: text/plain Form should be multipart and parameter/field should be exs.'; syswrite STDOUT, $str; exit 0; } read(STDIN, $char, 2); my $datalen = $ENV{'CONTENT_LENGTH'} - (length($delim) + 2 + length($header) + 4 + length($delim) + 3); my $paste = ''; read(STDIN, $paste, $datalen); # read one nl+cr read(STDIN, $char, 1); # read last delimiter my $checkstr; read(STDIN, $checkstr, (length($delim))); # compare first delimiter and last one chop($delim); chop($checkstr); unless ($delim eq $checkstr){ $str .= 'Status: 400 Bad Request Pragma: no-cache Cache-Control: no-cache Content-Language: en, ru Content-type: text/plain '; } $dbh->db_put($fname, $paste); # TODO: check status! # if defined useragent and it doesen't match text browsers/download tools # show fancy page if (defined($ENV{'HTTP_USER_AGENT'})){ if (not($ENV{'HTTP_USER_AGENT'} =~ /^fetch libfetch/ or $ENV{'HTTP_USER_AGENT'} =~ /^curl\// or $ENV{'HTTP_USER_AGENT'} =~ /^Wget\// or $ENV{'HTTP_USER_AGENT'} =~ /^Axel / or $ENV{'HTTP_USER_AGENT'} =~ /^aria2\// or $ENV{'HTTP_USER_AGENT'} =~ /^Links \(/ or $ENV{'HTTP_USER_AGENT'} =~ /^Elinks( |\/)/ or $ENV{'HTTP_USER_AGENT'} =~ /^w3m\// or $ENV{'HTTP_USER_AGENT'} =~ /^Lynx( |\/)/ )){ showindex("$URL$fname"); } } $str = "Pragma: no-cache Cache-Control: no-cache Content-Language: en, ru Content-type: text/plain $URL$fname "; }else{ # unknown method or commandline call without correct environment showindex(''); } syswrite STDOUT, $str; sub initdb(){ my $dbh = undef; unless (-f "$TSDB"){ $dbh = new BerkeleyDB::Hash( -Filename => $TSDB, -Flags => DB_CREATE ) or die "Error opening $TSDB : $! $BerkeleyDB::Error\n"; }else{ $dbh = new BerkeleyDB::Hash( -Filename => $TSDB, ) or die "Error opening $TSDB : $! $BerkeleyDB::Error\n"; } unless (-f "$DB"){ $dbh = new BerkeleyDB::Hash( -Filename => $DB, -Flags => DB_CREATE ) or die "Error opening $DB : $! $BerkeleyDB::Error\n"; }else{ $dbh = new BerkeleyDB::Hash( -Filename => $DB, ) or die "Error opening $DB : $! $BerkeleyDB::Error\n"; } return $dbh; } sub showindex($){ my $link = shift; my $str = 'Pragma: no-cache Cache-Control: no-cache Content-Language: en, ru Content-type: text/html; charset=UTF-8
| $link |
Console client can be found here: http://p.dafuq.ru/e thanks sprunge.us for their client :)
More minimalist console client can be found here: http://p.dafuq.ru/d
2015