SitePoint Sponsor

User Tag List

Results 1 to 25 of 61

Hybrid View

  1. #1
    ********* Articles ArticleBot's Avatar
    Join Date
    Apr 2001
    Posts
    1
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Discussion thread for Build a File Download Script in Perl

    This is a dedicated thread for discussing the SitePoint article 'Build a File Download Script in Perl'

  2. #2
    SitePoint Member
    Join Date
    Jun 2003
    Location
    Cleveland
    Posts
    1
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You're right--sorry, no screen shot. However, you can see the script in action at freewebgrafix.com. What prevents the public from hotlinking is that the folder with the images is outside of ther servers document root--only the script can reach the files.

  3. #3
    SitePoint Enthusiast
    Join Date
    May 2002
    Posts
    75
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yup I absolutely agree with Anonymous. True. You hide the images folder from the public, but I can always point to your script with the appropriate parameters, and your script is still going to return me an image.

    Anonymous is right. You got to check $ENV{HTTP_REFERER} before advancing.

  4. #4
    SitePoint Enthusiast icrf's Avatar
    Join Date
    Jun 2003
    Location
    Tennessee
    Posts
    81
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This script does something that continues to amaze me. I realize some people just don't use CGI.pm for reasons unknown, but even more baffling are those that use CGI.pm for form parsing, but still manually generate headers. Was there something wrong with 'print header()' that you thought 'print "Content-Type: text/html\n\n"' is better? You can do the same thing with the content-disposition header:
    Code:
    print header( -type       => 'application/x-download',
                  -attachment => $ID,
                );
    Since the site is trying to be educational, please, it would be beneficial to properly generate headers with the module you've already loaded and imported into your namespace rather than introduce errors to people who forget to capitalize the C in Content and get very confused.

    And it seems lots of modern browsers look at either the filename's extension or the given mime type, and if it's not familliar with one of them, looks to the other. If you send it an application/x-download header, but it also sees a .jpg in the filename, it checks and see that it already has a default behavior for .jpg files and runs with that instead of this odd header it doesn't know about. We'd be hoping for too much to be able to control the client's browser from afar.

    I've seen other "download" mime's before, is there some generally accepted one? I've seen application/forced-download and application/octet-stream before, too. Any reason to use one over the others?

  5. #5
    SitePoint Member
    Join Date
    Apr 2004
    Location
    Canada
    Posts
    1
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi,

    I follow exactly the article and here is my URL : http://www.nttran.freesurf.fr/cgi-bin/test/test.htm
    However when I click on the download link, I got this "ࡱ" instead of having a Save as dialog box. Does anyone have any idea about this problem? Please any help would be appreciate, thanx. -Kelly

  6. #6
    SitePoint Member Smurfs Are Tasty's Avatar
    Join Date
    Aug 2004
    Location
    Nashville
    Posts
    20
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    I Agree.

    I Agree.

  7. #7
    SitePoint Enthusiast
    Join Date
    Jan 2004
    Location
    orlando
    Posts
    37
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    that is funny.

    that is funny.



    I hadnt thought of that..
    best web hosting provider on the internet.
    The best Web hosting provider Great customer service

  8. #8
    SitePoint Wizard bronze trophy KevinR's Avatar
    Join Date
    Nov 2004
    Location
    Moon Base Alpha
    Posts
    1,053
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    post your code.

  9. #9
    SitePoint Wizard bronze trophy KevinR's Avatar
    Join Date
    Nov 2004
    Location
    Moon Base Alpha
    Posts
    1,053
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Use this script instead of the one in the article unless and until the issues I have mentioned above are fixed.

    Code Perl:
    #!/usr/bin/perl -T
     
    use strict;
    use warnings;
    use CGI; 
    # Uncomment the next line only for debugging the script.
    #use CGI::Carp qw/fatalsToBrowser/;
     
    # the path to where the downloadable files are. 
    # prefereably this should be above the web root folder.
    my $path_to_files = '/home/you/downloads';
     
    my $q = CGI->new;
     
    my $file = $q->param('file') or error('Error: No file selected.');
     
    # here we untaint the filename and make sure there are no characters like / 
    # in the name that could be used to download files from any folder on the website.
    # personally I don't even recommend you pass filenames to the script, but that
    # gets too complicated for a simple example of a download script. 
    if ($file =~ /^(\w+[\w.-]+\.\w+)$/) {
       $file = $1;
    }
    else {
       error('Error: Unexpected characters in filename.');
    }	
     
    if ($file) {
      download($file) or error('Error: an unknown error has occured. Try again.');
    }  
     
    sub download {
     
       # Uncomment the next line only for debugging the script 
       #open(DLFILE, '<', "$path_to_files/$file") or die "Can't open file '$path_to_files/$file' : $!";
     
       # Comment the next line if you uncomment the above line 
       open(DLFILE, '<', "$path_to_files/$file") or return(0);
     
       # this prints the download headers with the file size included
       # so you get a progress bar in the dialog box that displays during file downlaods. 
       print $q->header(-type            => 'application/x-download',
                        -attachment      => $file,
                        'Content-length' => -s "$path_to_files/$file",
       );
     
       binmode DLFILE;
       print while <DLFILE>;
       close (DLFILE);
       return(1);
    }
     
    # This is a very generic error page. You should make a better one.
    sub error {
       print $q->header(),
             $q->start_html(-title=>'Error'),
             $q->h1($_[0]),
             $q->end_html;
       exit(0);
    }

    Note that this does not have the download tracking log file like the script in the article. But that log file was nearly useless anyway (IMHO) as all it did was append the name of the file to the end of the log. This script should also log all errors to a file and record some data that would be helpful in tracking abuses (or attempted abuses) of the script.

  10. #10
    SitePoint Member
    Join Date
    Aug 2008
    Posts
    2
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi,

    the new script i used keeps returning a 'bad file descriptor' error? on line 11, where the file is assigned to the $file variable?

    Any ideas?
    Thanks
    Joe

  11. #11
    SitePoint Wizard bronze trophy KevinR's Avatar
    Join Date
    Nov 2004
    Location
    Moon Base Alpha
    Posts
    1,053
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Do you mean this line?

    my $path_to_files = '/home/you/downloads';

    You have to determine what the correct value on the right should be for your server. '/home/you/downloads' is just a generic example.

    Don't put a trailing slash "/" on the end:

    '/home/you/downloads/'

    although I don't think that would cause the error you are getting.

  12. #12
    SitePoint Member
    Join Date
    Aug 2008
    Posts
    2
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    thanks for the reply. I know it was a generic example i changed it to my htdocs directory. still getting that error. whats interesting to note is that the script works at home, but not at work and yet the config is almost identical.

    Joe

  13. #13
    SitePoint Wizard bronze trophy KevinR's Avatar
    Join Date
    Nov 2004
    Location
    Moon Base Alpha
    Posts
    1,053
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Check the server error log and see if there is anymore information. There can be so many different setups on servers, and permissions problems, its very hard to say what your specific problem running the script at work could be.

  14. #14
    SitePoint Member
    Join Date
    Sep 2008
    Location
    europe
    Posts
    2
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Question

    hi everyone!

    i just came across the tutorial and the forum and found it quite helpful.
    i think the (security)problems with the original script should almost be discussed more prominently; if one reads the tutorial he/she could easily understand this to be the state of the art. maybe some admin should place a well visible hint at the page of the tut.

    anyways, i adopted many of the ideas to my own script which finally works very well.
    still, there remains one thing i am not really sure about:
    if someone clicks on a link to my download.cgi (with appropiate parameters of course), the transfer starts and a blank white page is displayed in the browser.
    i tried adding a 'target="_blank" to the link, but result is the same...

    is there a way to send a html-page additional to the file which would get displayed in the browser window?
    how would i do that? can i just send another header (one of type 'application/x-download' and another 'text/html')?
    is the order important?
    i guess somehow the end of the first part has to be signalled, otherwise the second header might be seen as part of the first? i guess a simple 'sleep 1' or similar won't do it...

    i'm pretty sure this issue has been brought up before. i just don't know what to search for, so if there is no simple answer to this, could anyone maybe point me to somewhere where this might be solved?

    thanks a lot & greez - anti

  15. #15
    SitePoint Wizard bronze trophy KevinR's Avatar
    Join Date
    Nov 2004
    Location
    Moon Base Alpha
    Posts
    1,053
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You can't mix the header content-types. I'm not sure how to do what you are trying.

  16. #16
    SitePoint Member
    Join Date
    Sep 2008
    Location
    europe
    Posts
    2
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    hmmm, thats what i almost expected, thanks for making this clear.

    well, i still wonder how many (big) sites are doing this instead.
    the pattern seems the same: you get on a page where downoadable files are listed, the links point to a dl.cgi, parameter is some form of id.

    when you click on the link, a new page is loaded (download page) where usally something like "your download will start shortly, in not, please <do something>" and then the download dialog pops up on my side.

    so if there is only one header sent in such a case, i guess its the one for the page so is the data follwing. but how is this next step triggered?
    another thing coming to my mind here is that maybe a referer or refresh is used, but i don't know much about either. any idea how this could work?

  17. #17
    SitePoint Member
    Join Date
    Nov 2008
    Posts
    1
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You can create a page that says something like "your download will begin shortly. If your download doesn't start click here" (include a link to the script) and then refresh the page by pointing it to the script and passing the download params. You can refresh using the following methods:

    A meta-tag

    Code:
    <META HTTP-EQUIV="Refresh" CONTENT="10;URL=/cgi-bin/download.cgi?ID=file.jpg">
    Javascript

    Code:
    <SCRIPT TYPE="text/javascript" LANGUAGE="JavaScript">
    <!--
    function redirect () { setTimeout("go_now()",5000); }
    function go_now ()   { window.location.href = "/cgi-bin/download.cgi?ID=file.jpg"; }
    //-->
    </SCRIPT>
    I, personally, like to include both.

  18. #18
    SitePoint Wizard bronze trophy KevinR's Avatar
    Join Date
    Nov 2004
    Location
    Moon Base Alpha
    Posts
    1,053
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    They may be using a redirect (meta tag) to redirect to the download script.

  19. #19
    SitePoint Member
    Join Date
    Jul 2009
    Posts
    1
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I must be missing something because every time I try running this all I get is the print messages on my page, and the file which I'm trying to download (small text file) simply displaying fully on my page. Where is the save as box?

  20. #20
    SitePoint Wizard bronze trophy KevinR's Avatar
    Join Date
    Nov 2004
    Location
    Moon Base Alpha
    Posts
    1,053
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The save-as box should be initiated from these lines in the file:

    print "Content-Type:application/x-download\n";
    print "Content-Disposition:attachment;filename=$ID\n\n";

    If they are not, have you changed anything in the script?

  21. #21
    SitePoint Wizard bronze trophy KevinR's Avatar
    Join Date
    Nov 2004
    Location
    Moon Base Alpha
    Posts
    1,053
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    There is a more robust article and code discussing the same topic here:

    http://bytes.com/topic/perl/insights...ad-script-perl


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •