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

Honoured monks. Maybe this question is a little off topic, but I'll search for your wisdom anyway, hoping you will forgive me. I have written a counter script to keep track of visitors to my website. I don't want the counter to be visible except on my private statistics-page. I am calling the program through an SSI exec command. The script should not return anything visible to the page that called it. If I do nothing or just sends a 'Html/1.0 204 No response', I get an error in the Apache log about malformed headers or premature end of headers. If I also sends the usual Content-type header I get no error, but then the No Response header is printed on my webpage. How can I avoid this and just have my script executed witout any output to the webpage and no errors in the log.

Replies are listed 'Best First'.
Re: Cgi script with no output to webpage?
by LesleyB (Friar) on Aug 10, 2008 at 10:37 UTC

    There are web statistics gathering solutions such as webalizer you might want to look at.

    Generally - when I get a premature end of headers or malformed headers error I have a bug in my script.

    You can run scripts from the command line to see what it returns and debug there first.

    You could also use telnet on port 80, request one of your pages and see what the response is from that. Maybe you are using this technique already.

    I imagine this exec call is simply incrementing numbers to some file(s) or DB table(s) and that you have some other script which reads the data back.

    From the exec documentation, if you are using -w or use warnings; and use an exec without a following die, warn or exit then Perl will complain.

    Check the permissions and accessibility of the program being exec'd and consider using the system call.

    Also consider using use CGI::Carp qw(fatalsToBrowser); to help debug what's happening.

    Let us know how you get on.

Re: Cgi script with no output to webpage?
by RMGir (Prior) on Aug 10, 2008 at 09:46 UTC
    This advice is likely to be worth even LESS than my usual advice, since I know near nothing about webservers.

    It sounds like the SSI Include mechanism you're using expects HTML output back. You should check if there's an "administrative include" or "no output" include alternative supported.

    But what happens if you just return this:

    print "Content-type: text/html\n\n\n";
    (note the 3rd newline)

    It's valid html, and it shouldn't mess up formatting much...

    Another alternative would be to return a 1x1 IMG tag to a pixel-sized GIF file, I guess... Or just a header and empty html tags:

    print "Content-type: text/html\n\n<html></html>\n";
    Hope this helps!

    Mike
      It's valid html

      I think that would be better as "valid page content." A newline by itself is not valid HTML.

      Aren't things sometimes uncomplicated?

      Of course I could return a single pixel image, but it just spoiled my sense of perfection. Same thing with the IFRAME solution. Isn't IFRAME deprecated these days?

      The solution are simply to send the content type header as mentioned by Mike. It even worked with only 2 newlines (at least on Windows). Thanks for this quick help to my prayers.

      Poul

Re: Cgi script with no output to webpage?
by Utilitarian (Vicar) on Aug 10, 2008 at 09:57 UTC
    The script should not return anything visible to the page that called it.
    So return something invisible ;)
    You could either put the response in a hidden iframe with a style visible: none; or send a Content-type text/html with no visible content.
Re: Cgi script with no output to webpage?
by Your Mother (Archbishop) on Aug 11, 2008 at 00:19 UTC

    Unless you're doing it for a learning exercise or just for fun, don't. It adds overhead to your server and it's harder to get the reporting right than you might think. Google Analytics is free and terrific.

    Then if you really want to do it yoursef, you should be able to do something like this-

    use strict; use warnings; use CGI (); use HTML::Entities (); eval { # Do counting stuff and make sure it's not failing # and won't matter if it does. }; my $output = $@ ? CGI::h3(HTML::Entities::encode_entities("I haz errerz: $@")) : "<!-- I haz a count -->"; print CGI::header(), CGI::start_html(), $output, CGI::end_html();