2

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\"/>"
cigarman
  • 635
  • 6
  • 15

2 Answers2

2

You need to tell the browser (and possible proxies) to disable caching of the file with the appropriate HTTP headers:

Pragma-directive: no-cache
Cache-directive: no-cache
Cache-control: no-cache
Pragma: no-cache
Expires: 0

Of course, you'll just add each these in your script like this:

printf "Pragma-directive: no-cache\r\n";

There's a fair bit of redundancy in these directives. All are probably not necessary, but it's good to make sure there's something all browsers and proxies out there understand.

Ville Laurikari
  • 28,380
  • 7
  • 60
  • 55
2

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)

miken32
  • 42,008
  • 16
  • 111
  • 154
Sean Bright
  • 118,630
  • 17
  • 138
  • 146
  • Sorry, Sean, but that doesn't redirect. All that does is print "Location: /foo.html" in the browser. Am I missing something? The new script is: #!/bin/ash cat /myspecialdir/foo > /httpd/foo.txt printf "Location: /foo.txt\r\n"; printf "Pragma-directive: no-cache\r\n" printf "Cache-directive: no-cache\r\n" printf "Cache-control: no-cache\r\n" printf "Pragma: no-cache\r\n" printf "Expires: 0\r\n" – cigarman Aug 04 '09 at 14:35
  • Thanks for the clarification, Sean. It looks like the server I'm using (httpd from an older BusyBox) breaks this though because it automatically sends the Content-type: text/plain header which prevents my script from sending headers. So, unforutnately, I have to use META tags. – cigarman Aug 04 '09 at 16:24