Greetings fellow perl lovers,
I host a fair number of larger files.
They are meant for those who actually want to use them --
not to "enhance" someone else' web page, or end up being
downloaded 50 times/day by every BOT known to the internet.
So, I've been on what seems an endless quest to find the
Ultimate ant-leech, anti-hotlink, ant-bot, anti-proxy (google
proxies, and even manipulates the results, in some cases --
PDF, for example).
Well, I've built/tried download scripts that hide the source location.
Those that prevent anti-leeching (easy to fool), and what seems
a myrid of other possible solutions.
But sadly, none completely fit the bill.
So last night I performed a search here at perlmonks
using the string CAPTCHA. I finally landed what looked like
it might be a great starting point to build the ultimate solution.
The monks thread I'm referring to is here.
The code I chose, was from an external link suggested by a fellow monk in that thread.
I made a few modifications, and "ran it up the flag pole" to see how it
would fly. The CAPTCHA && session routine(s) worked flawlessly.
My modification(s) aslo seemed to work -- save one; the link
to the file was produced, but when clicked, returns the files' source
(it's a bzip2(1) archive). Among other modules, it uses the CGI(3)
(CGI.pm) perl module. My guess is I need to post a header/content-type,
rather than a <a href which isn't what I was hoping for.
Here's the source I'm using:
#!/usr/bin/perl -w use strict; $|++; use CGI qw(:all); use Cache::FileCache; my $cache = Cache::FileCache->new ({namespace => 'antirobot', username => 'nobody', default_expires_in => '10 minutes', auto_purge_interval => '1 hour', }); if (length (my $info = path_info())) { # I am the image my ($session) = $info =~ m{\A/([0-9a-f]+)\.png\z}i or do { warn("bad URL $info"); print header(-status => '404 Not Found'); exit 0; }; defined(my $verify = $cache->get($session)) or do { warn("Cannot find $session"); print header(-status => '404 Not Found'); exit 0; }; ## make up an image from the verify string require GD; my $font = GD::gdGiantFont(); my $image = GD::Image->new(2 + $font->width * length $verify, 2 + $font->height); my $background = $image->colorAllocate(0,0,0); ## $image->transparent($background); my $ink = $image->colorAllocate(255,255,255); $image->string($font, 1, 1, $verify, $ink); print header('image/png'), $image->png; exit 0; } print header, start_html(-encoding=>'utf-8',-title=>'File download'), h1("File download"); if (defined(my $verify = param('verify'))) { Delete('verify'); if (defined (my $session = param('session'))) { Delete('session'); if (defined (my $validate = $cache->get($session))) { $cache->remove($session); # one chance is all you get if ($validate eq $verify) { # success! ## would save param('flavor') here print h2("You're human!"), p("Please use <a href=\"./_/file-name.tbz2\">this temporary li +nk</a> to download Filename."), p("<a href=\"/man/?query=md5\">MD5</a>: (filename-0.6.iso) = 0 +8f4fb31b1a33e126d1a1aa9315cb207"), end_html; exit 0; } print p("Sorry, please reenter the security string exactly as sh +own!"); } } } my $verify = do { my @charset = grep !/[10joli]/i, 0..9, 'a'..'z', 'A'..'Z'; join "", map { $charset[rand @charset] } 1..8; }; my $session = do { require MD5; MD5->hexhash(MD5->hexhash(time.{}.rand().$$)); }; param('session', $session); $cache->set($session, $verify); print hr, startform; print h3("You must first prove that you are human (not a bot)"); print p("Please choose your favorite color:"); print radio_group(-name => "flavor", -values => [qw(None Other Purple Green Orange)], -default => "None", -columns => 1); print p("then enter this verification string:", img({src => url()."/$session.png"}).":", textfield(-name => "verify")." (CasE sEnSitiVe)"); print hidden('session'); print submit(-name=>'continue'), endform, hr; print end_html;
While I could modify it to post a header of:
header(-type=>'application/x-bzip2');
or an HTTP 301, via Location:
print "Status: 301 Moved Permanently\n"; print "Location: http://host.domain.tld/filename.tbz2\n\n";
or some such thing. But this isn't quite what I'd hoped for.
I think this script is an ideal start for an ultimate solution.
I think this could/would be perfect, if I could create a temporary symlink(2)
to the actual file, much as the session image is created for the CAPTCHA.
Is this possible? Any ideas how to do it?

Thank you for all your time and consideration.

--chris

#!/usr/bin/perl -Tw
use perl::always;
my $perl_version = "5.12.4";
print $perl_version;

In reply to Ultimate anti-leech, anti-proxy, anti-bot, CAPTCHA works, link does not (code included) by taint

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.