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

Dear fellow robed ones,

This is not the typical why can't I set a cookie using an SSI script? question and really I've spent a couple of hours browsing already without success.

I already know that you cannot set a cookie with an SSI script and I think I understand why - the set cookie command has to go before the headers and the SSI content is generated by the server and put below those headers.

However, I only need to use an existing cookie in an SSI script. I have read that the SSI script cannot use the cookie environment variable because the server runs the script without reference to the incoming cookie. In fact, I think I've verified this because I've tried to use it in my SSI and it took me a long time to work out why my script wasn't working. (I don't fully understand why this should be so - the cookie is sent to the server and so I would have thought that there ought to be a way for the SSI script to use what the server already knows).

Anyway, to cut to the chase - I am after any method of working around this while still using my SSI scripts. One workaround is to simply generate the whole page, of course. I can do that but that means changing the page names and is therefore not an option for me unfortunately.

While searching the web, I have seen snippets of information that imply it IS possible to workaround this using javascript and using PHP. I don't know these but am willing to learn if necessary. However, I gathered that javascript was spawn of the devil. And I thought that PHP could only be used to generate WHOLE pages and if so, that is not an option again. Anyway, the snippets were not understandable to me. Maybe someone can explain them in more detail for l'il ol' me. Can something be done in Java? (not that I know that either)

Or is it possible in any way to make the cookie variable appear within the HTML and therefore pass that parameter through as an argument to my SSI script?

Gosh, this is frustrating as I've done a lot of work which is tested and working and finished and now it will all be wasted if I cannot get hold of this cookie variable within the script.

I can give you the details of what my script is doing if you like but did not want to waste your time as the question is really a generic one, not a specific thing.

Any advice or tips appreciated...

thanks,

A pitiful and desperate monk.

Replies are listed 'Best First'.
Re: SSI and *reading* a cookie only
by derby (Abbot) on Jun 17, 2005 at 18:45 UTC

    How complicated does your cookie check need to be? If HTTP_COOKIE is set in your enviroment you can check to see if something is set like this:

    <!--#if expr="$HTTP_COOKIE = /foo\=bar/"--> <p>Cookie foo is set to bar</p> <!--#endif -->

    If you need something more complicated you could use exec or virtual to run a cgi.

    foo.shtml

    <html> <body> <p>Test of include</p> <!--#include virtual="/cgi-bin/bar.pl" --> </body> </html>

    bar.pl

    #!/usr/bin/perl -w use strict; use CGI; my $cgi = CGI->new(); print $cgi->header, $cgi->start_html; my @names = $cgi->cookie(); foreach my $c ( @names ) { my $val = $cgi->cookie( $c ); print $cgi->blockquote( $cgi->em( $c ), ' - ', $val ); }
    -derby
      Thank you for answering. I don't think this works as far as I can see, though. Perhaps I'm being dense.

      Keeping it simple, my SSI script uses the cookie to lookup a person's session file and thus determine if a person is in the EU, US or UK. If the person is from the US, it displays a US flag and a price in US$, if EU, an EU flag and a price in Euros etc. But since it can't get at the cookie, it can't get the person's session file and so cannot determine what to display.

      I have already set up a test SSI which calls a virtual in the way you suggest. It works but doesn't do anything except show the current ENV variables. I pasted in the code exactly as you have it but without the header and start_html as I already had these. It didn't show anything and a print of @names showed that @names was empty.

      I don't use CGI module so am not too familiar but surely if a perl script called by SSI virtual finds the HTTP_COOKIE environment variable undefined, surely the CGI module will find the same thing when calling cgi->cookie(), won't it?

      thanks,

      P&DM.

Re: SSI and *reading* a cookie only
by merlyn (Sage) on Jun 17, 2005 at 21:38 UTC
    I already know that you cannot set a cookie with an SSI script and I think I understand why - the set cookie command has to go before the headers and the SSI content is generated by the server and put below those headers.
    No, that's not it. It's that the headers (including MIME type) don't matter. Try setting your MIME type to "image/jpeg", for example. The server doesn't care: it just inserts the contents of STDOUT into the middle of your output stream.

    I'm guessing here, but I don't think the "Cookie:" header will be passed to the subrequest, since it's a separate request. In that case, you won't get any $ENV{HTTP_COOKIE} variable either, which fits the symptoms you describe.

    SSI is fairly limited. You should probably be using a full CGI script to generate your entire page, or perhaps a templating system of some kind.

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

      Dear Merlyn,

      Thanks for replying. I now have a solution to this question (well more correctly, I've understood why my question was a dud) which I will post in a sec.

      Regarding, the setting of a cookie, I puzzled over your paragraph for a few minutes, trying to understand what you were saying. In the end I decided that we were both saying the same thing but neither of us said it very well, me in particular. I don't understand why you bring MIME into this but that is probably my ignorance. But I wanted to fix what I said so that I don't mislead monks searching on this subject in the future.

      I think that you cannot set a cookie with an SSI script because the set-cookie command goes into the CGI header before the html starts. Since that's the only place the server looks for the set-cookie command, it is not going to find it in the output of the SSI which is embedded into the HTML.

        No, you can't set a cookie in an SSI because the SSI headers are ignored (including your set-cookie header). I think I said this. You can put "scooby-doo: where are you?" in an SSI header, and you won't see it in your output. SSI headers are ignored. And my point about MIME type is that that's a typical header (in fact, mandatory).

        It has nothing at all to do with the timing of invoking the SSI. In fact, the SSI could be (and typically is) complete before the first byte has been sent to the browser. It's just that by decree, SSI headers don't matter (except a redirect, and maybe some other status values).

        -- Randal L. Schwartz, Perl hacker
        Be sure to read my standard disclaimer if this is a reply.

Re: SSI and *reading* a cookie only
by jfrm (Monk) on Jun 20, 2005 at 12:24 UTC
    I have read that the SSI script cannot use the cookie environment variable because the server runs the script without reference to the incoming cookie. In fact, I think I've verified this because I've tried to use it in my SSI and it took me a long time to work out why my script wasn't working. (I don't fully understand why this should be so - the cookie is sent to the server and so I would have thought that there ought to be a way for the SSI script to use what the server already knows).

    OK, I've sussed this now. Although I read in 2 places on websites that you cannot set OR read a cookie within SSI, this has turned out to be false. You cannot set a cookie but you CAN read one quite happily. I am now doing it on my website. q.v. change currency functionality in the price tables on pages on www.mastersgames.com

    For the record and in case this happens to anyone else, my error occurred when I was setting the cookie - I did not specify the path variable. Therefore it defaulted to "/cgi-bin", the location of the script doing the setting. Since my normal web pages are not in cgi-bin, the cookie was not passed to them when the browser requested a normal page.

    As soon as I set the path variable to be explicitly "/", the cookie environment variable was available within the page and also within SSIs within that page.

    A still pitiful but much less desperate monk.