Example

Using HTTP Cookies

Author: Viktor Pavlu
Return to REBOL Cookbook

Here is short example of how to use Cookies in your CGI scripts.

Cookies are sent (set) and received (read) via HTTP headers. The general form of a HTTP header is "bla: value<CR>". An empty line (one that only consists of the carriage return (<CR>) character denotes the end of the headers - after that, the actual content of the page follows.


    REBOL []
    print "content-type: text/html" ;mandatory
    print "" ;end of headers

    print "content" ;actual content

This is an example of a minimal cgi script. It prints a content-type header (which is mandatory) and then adds the blank line to end the headers and then prints the content of the page which will then be interpreted by the client application (browser) according to the content type.

So back to the Cookies now. Setting a Cookie is done with a "Set-Cookie: <key>=<value>;expires=<exp-date>" HTTP header. The expiration date is optional and gives the date on which the cookie expires. Cookies without expiration dates don't expire.


    REBOL []
    print "content-type: text/html"
    print join "set-cookie: name=Viktor C. Pavlu;expires=" to-idate now + 7
    print ""
    print "wohooo!"

Reading a Cookie's value is also done via HTTP headers, but this time an incoming header has to be parsed by us. Somewhere in "system/options/cgi/other-headers" there is an entry named "HTTP_COOKIE". This header is what we are searching for and now have to parse.


    cookie-string: select system/options/cgi/other-headers "HTTP_COOKIE"
    tokens: none
    if found? cookie-string [
        tokens: parse cookie-string ";="
    ]

In the "tokens" word we now have the key-value pairs we put on the client in the first place with "Set-Cookie". The expiration date is not sent back to the server, instead cookies that already have expired will not be sent at all.

So to get the value of our cookie "name", we would write something like:


    REBOL []
    print "content-type: text/html"
    print join "set-cookie: name=hans;expires=" to-idate now + 7
    print ""
    name: none
    cookie-string: select system/options/cgi/other-headers "HTTP_COOKIE"
    if found? cookie-string [
        tokens: parse cookie-string ";="
        name: select tokens "name"
    ]
    print join "Hello " any [ name "unknown" ]

I have also written two short functions, that you can use in your scripts:


    set-cookie: func [
        "Sets a cookie"
        key [string!] value
        /expires "set expiration date" exp-date [date!]
    ][
        print rejoin [
            "Set-Cookie: " key "=" value ";"
            either expires [join " expires=" to-idate exp-date][""]
        ]
    ]

    get-cookie: func [
        "Returns value of a cookie"
        name [string!]
    ][
        select parse to-string select system/options/cgi/other-headers
                "HTTP_COOKIE" ";=" name
    ]

But notice that as cookies are set via HTTP headers, the set-cookie function will only work if it is called before the end of the HTTP headers - otherwise its output will be interpreted as normal text.

Setting cookies:


    REBOL []
    print "content-type: text/html"
    set-cookie/expires "name" name now + 7
    set-cookie "birth" birth
    print ""
    ;put content here

and reading cookies:


    ;anywhere
    birth: get-cookie "birth"
    name: get-cookie "name"
    ;anywhere

2006 REBOL Technologies REBOL.com REBOL.net