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

I've gotten spoiled with shell access, I guess. I'm now working on a site I can only access by ftp and browser. The browser returns an error of:
The server encountered an internal error and was unable to complete yo +ur request. Error message: Premature end of script headers: <scriptname>
I've commented out nearly everything, yet this is still what I get. There is already a script running here using DBI, from which I snagged the connection parameters. This passes the perl -wc check on my local sandbox, but when I upload it I get nothing but the browser error reported above. I'm running out of ideas for how to debug this. Any clues would be greatly appreciated.

-- Hugh

UPDATE
Well, that's embarrasing folks. I'm used to scp preserving permissions. Apparently ftp applies a mask to the incoming so folks are more deliberate about how they pass around privileges in the file system. A simple chmod was all it took. I guess it really was about me operating in a new environment. Now I need to go monitor what's happening on my test dataset. Thanks for the feedback.

#!/usr/bin/perl -w use strict; use DBI; # use CGI::Carp qw(fatalsToBrowser); # use lib qw{/public_html/lib}; # use Date::Manip; my $preserve_date = '2006-10-30'; my %registrations; # my $dbh = DBI->connect('dbi:mysql:dbname','userID','secret',{RaiseEr +ror=>1}) or die "no \$dbh: $DBI::errstr"; # ### ALL THE MAIN() LOGIC HAS BEEN COMMENTED OUT! print <<EOF; <html> <head> <title>Masking Private Data</title> </head> <body> <h2>Masking Private Data</h2> This script is masking private data in the test data set with a depart +ure date before $preserve_date. Records related to later events are +being preserved.<p> </body> </html> EOF 1; sub parse_date { my ($date_str) = @_; my $date = ParseDate($date_str); $date = substr($date,0,4) . '-' . substr($date,4,2) . '-' . substr($ +date,6,2); return $date; }
if( $lal && $lol ) { $life++; }

Replies are listed 'Best First'.
Re: Debugging without shell access?
by muba (Priest) on Oct 30, 2006 at 16:17 UTC
    You never send HTTP headers.
Re: Debugging without shell access?
by davorg (Chancellor) on Oct 30, 2006 at 16:16 UTC

    Firstly, what's to stop you debugging it on the computer that you develop on? Perl, Apache and MySQL are all available for free download and they all work fine on a Linux, Mac and Windows.

    Secondly, why would you use a hosting service that doesn't give you a shell account or (at the very least) access to the server logs. Those kinds of accounts are fine for simple static sites, but if you're doing any kind of development, then you really need shell access.

    Didn't you get any useful help from use CGI::Carp 'fatalsToBrowser'?

    Update: Looks like muba has got the answer - but my comments still apply.

    --
    <http://dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

      Agree 110% with setting up your own dev environment. If you have restricted access to a server then working in an environment you have full control over is crucial. You can get your app working properly on your dev box, then when you promote to "live", you know any problems you experience are most likely environmental.

      Of course, there are other advantages to having a dev environment... mostly the fact that you don't break the live site whenever you try to make changes.

      It may take a while to setup, but it'll save you so much time in the long run.
Re: Debugging without shell access?
by blue_cowdawg (Monsignor) on Oct 30, 2006 at 16:45 UTC
        I'm now working on a site I can only access by ftp and browser.

    Besides the comments you've gotten about what a rotten hosting site this is, and the answers to why your script is not behaving correctly (no headers!) here is a trick I use when I'm force to work under such rotten hosting conditions:

    I write a simple shell wrapper script that executes my CGI and writes the stdout/stderr to the browser like so:

    #!/bin/sh echo "Content-type: text/html" echo echo echo echo "<pre> ( /path/to/my/script/here.pl ) 2>&1 echo "</pre>" echo
    of course substituting the path accordingly. Now I can see what I'm not seeing in the logs since I don't have access to those.

    I can empathise with your situation of "ftp access only" since I've inherited sites like that. Still I've worked as quickly as possible to move those sites to a new home or I've "un-inherited" them as quickly as possible.

    I figure that any hosting folks that don't trust me with shell aren't worthy of my trust. :-/

    Also, I try and set up a test environment that matches as closely as practical the environment I'm going to be running in and test before I publish.


    Peter L. Berghold -- Unix Professional
    Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg
Re: Debugging without shell access?
by dirving (Friar) on Oct 30, 2006 at 16:27 UTC
    Your script doesn't send a Content-type header, which is what the part of the error message that says "Premature end of script headers" is referring to. Try adding the following line just above where you print out that block of HTML:  print "Content-Type: text/html\015\012";
Re: Debugging without shell access?
by hesco (Deacon) on Oct 30, 2006 at 16:26 UTC
    I've fully tested this script on my own server. But its got to get deployed sometime and made to work on the production server.

    I thought I was sending html headers with my heredoc "print <<EOF;" block. If that is not the case, then what am I missing, here?

    This server is not of my choosing. My client's client contracts with them. They have an extensive bit of php code already there, working and bringing in revenue. I started out doing this in php, until I learned that their date fields were actually text fields and I switched to perl for Date::Manip so I could do date comparisons against these text fields.

    -- Hugh

    if( $lal && $lol ) { $life++; }
      I thought I was sending html headers with my heredoc "print <<EOF;" block. If that is not the case, then what am I missing, here?

      You're missing the "Content-Type:" header.

      Update: Also, this is interesting:

      I've fully tested this script on my own server.

      How did you test it? Without the content-type header, there's no way it's going to work in a CGI environment.

      --
      <http://dave.org.uk>

      "The first rule of Perl club is you do not talk about Perl club."
      -- Chip Salzenberg

        You're missing the "Content-Type:" header.

        ...

        Without the content-type header, there's no way it's going to work in a CGI environment.

        That's not entirely true. His code is perfectly valid ... for HTTP/0.9, running under some webservers. In fact, sending headers would be an error under HTTP/0.9. (current versions of Apache will strip them out for you, so you don't need to detect that case)

        I've just re-read the HTTP/1.1 specs, and I can't find any mention of Content-Type being required. The only 'MUST' that I see is for sending Content-Length on a request with a message body. (eg, POST). Even if that were not the case, all headers were optional in previous versions

        The following is a perfectly acceptable response, should you give it a useful message body:

        HTTP/1.0 200 OK <html> ... </html>

        The important factor is the blank line to seperate the headers from the body -- but personally, I'd just stick with using CGI or some other toolkit to generate the appropriate headers.

Re: Debugging without shell access?
by hesco (Deacon) on Oct 30, 2006 at 17:00 UTC
    Thanks for the leads folks.

    OK, I've pared this one down as far as it can go, yet I still get the same "Premature end of script headers" errors. I also tried it using CGI, which I figured knows the html spec better than I ever will. Any further ideas?

    #!/usr/bin/perl -w use strict; my $preserve_date = '2006-09-01'; my %registrations; print <<EOF; Content-type: text/html <html> <head> <title>Masking Private Data</title> </head> <body> <h2>Masking Private Data</h2> This script is masking private data in the test data set with a depart +ure date before $preserve_date. Records related to later events are +being preserved.<p> </body> </html> EOF 1; sub parse_date { my ($date_str) = @_; my $date = ParseDate($date_str); $date = substr($date,0,4) . '-' . substr($date,4,2) . '-' . substr($ +date,6,2); return $date; }
    if( $lal && $lol ) { $life++; }

      See, this is why you really need access to the server logs. And the Apache configuration files.

      Is the server running suexec? And, if so, are are file ownership and permissions correct?

      --
      <http://dave.org.uk>

      "The first rule of Perl club is you do not talk about Perl club."
      -- Chip Salzenberg

      Where is ParseDate defined? Don't you need to include Date::Manip or something?

      Like others, I'm still confused by you saying you tested this on a local environment - that script would never have worked running under apache/cgi - did you just capture the output to file and open the file in a browser? That is not the same thing...

      <update>I've just noticed - you've commented out Date::Manip, but you are still using ParseDate in your code. Fix that and try again...</update>

      Tom Melly, tom@tomandlu.co.uk

        That shouldn't be a problem since parse_date is never called.

        -derby
Re: Debugging without shell access?
by fenLisesi (Priest) on Oct 31, 2006 at 07:11 UTC
    One minor point, not related to your problem, that caught my eye: I think EOF is not the best choice for a heredoc terminator. I would recommend something like END_HTML. Also, using quotes around the terminator may help the reader, even if the default behavior without the quotes is what you need. Cheers.