sandal has asked for the wisdom of the Perl Monks concerning the following question:

I tried this code, but got an Internal Server Error. Where is problem?(chmod 755, server Unix).

#!/usr/local/bin/perl -w $FILE= "/home/username/cgi-bin/test/file.exe"; open(FH, $FILE) || die "Can't access file"; print "Content-Type: application/octet-stream\n\n"; print "\n"; while(<FH>) { print; }

Thanks, Sandal

20030720 Edit by Corion: Fixed formatting

Replies are listed 'Best First'.
Re: code problem
by sgifford (Prior) on Jul 21, 2003 at 17:55 UTC
    If you can't get to the server's error logs, write a short shell script wrapper to see what the error is:
    #!/bin/sh -x
    
    printf "Content-type: text/plain\n\n"
    exec 2>&1
    
    ./your_script
    

    One thing that occured to me is that perhaps the path to Perl at the top is wrong.

Re: code problem
by blue_cowdawg (Monsignor) on Jul 21, 2003 at 17:21 UTC

    Huh?

    Looking at your code I am compelled to wonder just what you are trying to accomplish... Is this to allow a user to download file.exe?

    Go to the logs

    Second, what messages are being written to the web server's logs when this code is run from CGI?


    Peter L. BergholdBrewer of Belgian Ales
    Peter@Berghold.Netwww.berghold.net
    Unix Professional
      It should allow open any necessary file(including appl) instantly in a client browser. There are Internal server error(500)message, I can no get other details from server. Sandal

          I can no get other details from server. Sandal
        Bad ju-ju that. You really need to know what the server itself is complaining about. Internal errors are usually logged to the server's logs. See if your system administrator can glean that information for you.

        Suggestions

        1. Try setting the permissions of the file you are trying to open to 777 temporarily and see if it runs
        2. Try using adding the line: to your code and see what shows up on the browser. You will want to remove the qw/ fatalsToBrowser / once your code goes " production" as it can present an information leak later on.
        3. Try substituting a plain text file for the executable and change your header to Content-type: text/plain and see if that works. There may be something configured on the server that will prevent you from pushing presenting executables, such as some form of draconian measures to prevent spread of viruses.

        Hope this helps.


        Peter L. BergholdBrewer of Belgian Ales
        Peter@Berghold.Netwww.berghold.net
        Unix Professional
Re: code problem
by erasei (Pilgrim) on Jul 21, 2003 at 17:43 UTC
    The error itself should be reported in the server error log. That should be your first place to check. The code itself is syntactically correct, however, I'd error check your 'open' call. I don't know, but that extra new line might be causing you a problem. You are telling the browser to expect a binary stream and the first thing it gets is a new line. Like I said, that may, or may not be your problem. If not, then there are several ways you can accomplish the same function. One would be to print a Location: /path/to/file.exe instead of the header. That will cause most (if not all) browsers to redirect directly to the file.

    If the purpose of the script is to track how many times the file is downloaded, you should move the file outside of a public directory. As it stands now, anyone that knows the direct link to the file can download, thus bypassing your logging.

    Also, just for reference, a more perlish way of writing your code (not that I am endorsing your method of solving your problem, but..) it would be:

    #!/usr/local/bin/perl -w use strict; my $FILE= "/home/username/cgi-bin/test/file.exe"; print "Content-Type: application/octet-stream\n\n"; open(FH, $FILE) || die "Can't access file: $_\n"; print <FH>; close(FH);
Re: code problem
by neuro (Initiate) on Jul 21, 2003 at 17:43 UTC
    regardless of the rationale behind the code, this should work:
    $FILE = "/path/to/file"; open (FH, $FILE) || die "Content-type: text/html\n\nCan't access file +$FILE"; print "Content-type: application/octet-stream\n\n"; while(<FH>) { print <FH>; } close (FH);

      File Looping

      Look at the following code, which is an analog of what you have posted.

        #!/usr/bin/perl -w ###################################################################### +## use strict; my $file=$0; my $line=1; open(FH,"$file") or die $!; print "Content-type: text/plain\n\n\n"; while (<FH>) { printf "%d:%s",$line++,<FH>; }
      When I run that I get:
        --$ ./filetest.pl Content-type: text/plain 1:#################################################################### +#### --$

      To fix this I do the following:

        #!/usr/bin/perl -w ###################################################################### +## use strict; my $file=$0; my $line=1; open(FH,"$file") or die $!; print "Content-type: text/plain\n\n\n"; while (<FH>) { printf "%d:%s",$line++,$_; # $_ vs. <FH> }
      Which yields:
        --$ ./filetest.pl Content-type: text/plain 1:#!/usr/bin/perl -w 2:#################################################################### +#### 3: 4:use strict; 5: 6:my $file=$0; 7:my $line=1; 8: 9:open(FH,"$file") or die $!; 10: 11:print "Content-type: text/plain\n\n\n"; 12:while (<FH>) { 13: printf "%d:%s",$line++,$_; 14:} --$
      Which I believe is more what you wanted.

      Yeah... I know the close(FH) is missing at the end.


      Peter L. BergholdBrewer of Belgian Ales
      Peter@Berghold.Netwww.berghold.net
      Unix Professional
        > Which I believe is more what you wanted.
        s'not what i wanted, s'what the other guy wanted :)
Re: code problem
by PodMaster (Abbot) on Jul 21, 2003 at 21:48 UTC