Documention for: acgiss.r Created by: sunanda on: 18-Dec-2006 Format: text/editable Downloaded on: 30-Apr-2025 [numbering-on [contents [asis Author: Sunanda Version: 1.0 Date: 18-dec-2006 asis] [h2 anonymous cgi session services overview [p **acgiss.r** allows you to save user-related data between invocations of a CGI script. Basically, it provides simple session support for you. [p The sessions are **anonymous** as they do not require a visitor to identify themselves by name. acgiss.r simply feeds their user-agent (usually a web browser) with a cookie; acgiss.r then uses that cookie as an identifier to a record that holds any visitor-related data that you have saved, [h2 installing acgiss.r [p Copy the script to your cgi-bin folder -- or to the folder where you keep utility scripts (ie ones not directly executable by a user). [p If you put it directly in your cgi-bin folder, then set the file permissions so it cannot be directly executed by a user (ie no public ability to read, write, or execute it). [p You may want to change a couple of lines of code to adapt it to your own circumstamces. See **Configuring acgiss.r** below. [h2 using acgiss.r [h3 example [asis do %acgiss.r ;; start the utility SESSION-RECORD: acgiss/get-session-record ;; retrieve session data either SESSION-RECORD/session-status = "new" [ .... code for a new visitor [] .... code for an old visitor ] append SESSION-RECORD/user-data "next=update" ;; set some user-data acgiss/save-session SESSION-RECORD ;; save the data asis] [h3 starting up [p Add these two lines to your CGI scripts (or your user.r file in the CGI scripts folder): [asis do %acgiss.r SESSION-RECORD: acgiss/get-session-record asis] [p (You can of course use your own word instead of **SESSION-RECORD** for the name). [p **session-record** is a REBOL object, and will look something like this.... [asis make object! [ scads-record-type: "acgiss" session-status: "new" session-expires: 18-Dec-2006/12:59:28 session-id: {--some gibberish--} user-data: [] ] asis] [p .... the **session-status** is **new** and there is nothing in **user-data**. This means there was no incoming cookie, so the user is not in a session with you. [p If **session-record** looked more like this.... [asis make object! [ scads-record-type: "acgiss" session-status: "old" session-expires: 18-Dec-2006/12:59:28 session-id: {--some gibberish--} user-data: ["male" 29 true "both" "depends"] ] asis] [p .... then this is an existing session. There was an incoming cookie, and acgiss.r used it to retrieved the saved **user-data**. The user-data is something that your application has saved. [p Simply calling **acgiss/get-session-record** does not start a session for you if one is not in progress; ie it does not send a cookie to the user-agent. To start a session, see immediately below. [h3 saving user data and starting a session [p The easiest way is: [asis append SESSION-RECORD/user-data ["male" 29 true "both" "depends"] acgiss/save-session SESSION-RECORD asis] [p That will add some data to the **user-data** block, save SESSION-RECORD, and write a cookie, if needed. [p You can make multiple calls to **acgiss/save-session**. It will only write a cookie on the first call. [p If the **user-data** block is not flexible enough for your needs, you can add words to the SESSION-RECORD object, eg: [asis SESSION-RECORD: make SESSION-RECORD [sex: "male" age: 29] asis] [p If you do that, please do not overwrite the four control fields: scads-record-type, session-status, session-expires, session-id. [h3 ending a session [asis acgiss/end-session SESSION-RECORD asis] [p The cookie (if any) will be deleted from memory, and the saved session-record will be deleted from your hard drive. [h3 extending a session [p By default, we create cookies with a life of 24 hours (you can change that default -- see **configuring acgiss.r** below). If you want to extend a cookie once a session is under way: [asis acgiss/extend-session: SESSION-RECORD 72:00:00 asis] [p Will extend the cookie's life by 72 hours from now. [h2 purging dead session records [p Many sessions will not formally end, so you cannot call an **end-session**; the visitor just drifts away and never comes back. [p That may mean that, over time, 1000s of expired session records pile up in your **acgiss.r working folder**. [p To clear those out on a regular basis, you could add a **CRON** (or equivalent) batch process that deletes any file in the acgiss.r working folder that is older than (say) 48 hours. [p That may however remove some session records that were intended to last longer -- ie had a session-expiry of more than 48 hours. [p To delete only expired session records, call acgiss.r from a CRON job like this: [asis do %acgiss.r acgiss/set-parameters "session-folder" %.... ;; see configuring below acgiss/purge-expired-sessions asis] [p To limit the time that the purge runs, you can ask it to stop after purging some records.... [asis do %acgiss.r acgiss/purge-expired-sessions/limit 100 asis] [p .... you may then need to run the CRON more often to prevent expired session records piling up. [h2 configuring acgiss.r [P There are some run-time parameters that you may want to change. You can do that in two ways: [li find the **_parameters** block in the source of acgiss.r, and make the changes directly [li use **acgiss/set-parameter** immediately after the **do acgiss.r** to change the parameter settings list] [p The first method means you need to make the change only once per installation of acgiss.r. The second method gives you more flexibility at run time. [p Example of set-parameter: [asis do %acgiss.r acgiss/set-parameter "session-folder" %/c/apache/acgiss-work-folder/ acgiss/set-parameter "session-duration" 3:15:00 asis] [p The above example: [li change the folder in which session records are saved [li change the default cookie expiry time to 3 hours and 15 minutes from now. list] [p Either way, there are three parameters: [h3 set-parameter "session-folder" [p Sets the folder in which we save session records. By default, it is **%../acgiss-work-folder/** [h3 set-parameter "session-cookie-id" [p Sets the identifying **name** in the cookie, By default it is **acgiss**, so a cookie looks like: [asis cookie: acgiss=xxxxxxxxx asis] To change the name field in cookies to "sid": [asis acgiss/set-parameter "session-cookie-id" "sid" asis] [h3 set-parameter "session-duration" [p Sets how long a session will last. By default, it is 24 hours. To make it 168 hours (one week) instead: [asis acgiss/set-parameter "session-duration" 168:00:00 asis] [p If you use: [asis acgiss/set-parameter "session-duration" none asis] [p Then the cookie expires as soon as the visitor closes their web browser. [h2 configuring and security [p I recommend that you change the default settings for all three parameters. This is so your application does not leak data to potential hackers. If a hacker sees a cookie with an **acgiss=** keyword in it, you have leaked potentially useful information: [li you are using **acgiss.r** -- and the hacker may be aware of flaws in the code [li you may have an /cgi-bin/../acgiss-work-folder/ that contains many cookie identifiers (and if that folder is unprotected, some mischief may be possible list] I am fully aware that security by obscurity alone is not a safe approach. But keeping things secret that can be kept secret is simply prudent; no need to give the bad guys a head start. [h2 limitations [p acgiss.r uses the simplest possible mechanism for setting and retrieving a cookie. [p We simple Version 0 HTTP cookie. Version 1 HTTP cookies (which, confusingly are known as COOKIE2) have greater flexibility. [p That limits acgiss.r to a single cookie per visitor. If you need multiple cookies per visitor, you'll need to tweak the code that retrieves and sets the cookie in **system/options/cgi/other-headers**. [p You may also want to add some extra settings to allow COOKIE-type keywords (path, domain, etc) to be set. [p If you do so, please consider letting us use your changes to make an improved version of acgiss.r [h2 appendix: ways of keeping session data [p HTTP was originally a stateless, anonymous protocol: there was no real way to handle continuity between incoming messages from the same visitor. [p There are three main ways to change it to a stateful connection. All have problems. The one **acgiss.r** uses is **cookies**. [p The three ways are: [li **IP address** -- every incoming message has an IP address -- it has to, otherwise there is no place to send a response [li **url parameters** -- eg adding something like **session-id=** to every URL [li cookies -- the CGI program feeds the browser a unique id. The browser quotes that on each call list] [p Each method has its strong points and weaknesses. [li **IP address** -- visitors may not have unique and unchanging IP addresses; someone revisiting in 10 minutes may come via a different gateway and so have a different IP address [li **url parameters** -- make it very difficult to quote URLs to other people without giving away session data [li cookies -- a few user agents still do not support cookies; or visitors may have cookies turned off list] [p It'd be relatively easy to extend acgiss.r to support multiple mechanisms.....Feel free to do so if you'd like to.