Search code examples
cgicgi-bin

CGI script not executing every page visit


I have a CGI script that generates a file on the server and then redirects the browser to that newly generated file.

#!/bin/bash
printf "Content-type: text/html\n\n";
cat /myspecialdir/foo > /httpd/foo.html
echo "<HTML><HEAD><BODY>"
echo "<META HTTP-EQUIV=\"CACHE-CONTROL\" CONTENT=\"NO-CACHE\">"
echo "<META HTTP-EQUIV=\"Refresh\" CONTENT=\"1; URL=/foo.html\">"
echo "</BODY></HEAD></HTML>"

The file /myspecialdir/foo contains some dynamic content that I want to be in /httpd/foo.html. I then want the script to redirect there after the generation of the new file.

The problem I have is that the script doesn't get new data on every hit from a browser. For example, if I visit http://myip/cgi-bin/genfoo.cgi the first time in IE the data gets generated and it gets redirected to foo.html. After that, if I go to the CGI page using the back button, it doesn't re-run and I get redirected to stale data.

How can I force the CGI script to execute even from the back button?

EDIT: I tried doing this with the HTTP headers approach, but this doesn't seem to be working. Here's the new script, am I missing something?

#!/bin/bash
cat /myspecialdir/foo > /httpd/foo.txt
printf "Pragma-directive: no-cache\n\n";
printf "Cache-directive: no-cache\n\n";
printf "Cache-control: no-cache\n\n";
printf "Pragma: no-cache\n\n";
printf "Expires: 0\n\n";
printf "Location: /foo.txt\n\n";
printf "Content-type: text/html\n\n";

All this does when I visit via IE is to print the headers in the page, like so:

Pragma-directive: no-cache

Cache-directive: no-cache

Cache-control: no-cache

Pragma: no-cache

Expires: 0

Location: /BACtrace.txt

Content-type: text/html

EDIT:

It turns out this was an issue with the HTTP server I was using (busybox v1.12.1). I was unable to send the HTTP headers as originally recommended, but I was able to get this to work with a combination of META tags and a setting in IE8 (Tools --> Internet Options --> Browsing History --> Settings Button --> check "Every time I visit a website").

The META tags I used are:

echo "<meta http-equiv=\"expires\" content=\"0\" />"
echo "<META HTTP-EQUIV=\"Pragma-directive\" CONTENT=\"no-cache\"/>"
echo "<META HTTP-EQUIV=\"Cache-directive\" CONTENT=\"no-cache\"/>"
echo "<META HTTP-EQUIV=\"Cache-control\" CONTENT=\"no-cache\"/>"
echo "<META HTTP-EQUIV=\"Pragma\" CONTENT=\"no-cache\"/>"
echo "<META HTTP-EQUIV=\"Refresh\" CONTENT=\"1; URL=/foo.txt\"/>"

Solution

  • You can make this much easier on yourself by doing:

    #!/bin/bash
    
    cat /myspecialdir/foo > /httpd/foo.html
    
    printf "Location: /foo.html\n\n";
    

    This sends a header to the browser telling it to redirect to /foo.html instead of having to load and parse the <meta> tags.

    Edit: You should only send 1 \n at the end of each header. After the entire request, you send 2 of them, like this (broken out for clarity):

    #!/bin/bash
    cat /myspecialdir/foo > /httpd/foo.txt
    printf "Pragma-directive: no-cache\n";
    printf "Cache-directive: no-cache\n";
    printf "Cache-control: no-cache\n";
    printf "Pragma: no-cache\n";
    printf "Expires: 0\n";
    printf "Location: /foo.txt\n";
    printf "\n";
    

    (Also note that the Content-Type header isn't included)