A minimal, lightweight key-value store optimized to track Gemini CGI sessions for games and small applications.
Go to file
stack 44ba104317 Added usertask; implemented caching 2024-06-05 17:07:57 -04:00
src Added usertask; implemented caching 2024-06-05 17:07:57 -04:00
LICENSE.txt license 2024-05-15 22:19:15 -04:00
README.md typo in readme 2024-05-16 23:44:45 -04:00
WHATSTHIS.md works, cleaned up readme 2024-05-16 23:05:39 -04:00
env.sh Crude CGI; text testcli 2024-05-16 14:10:04 -04:00
infile.txt initial 2024-05-15 22:11:32 -04:00

README.md

cgisesh

cgisesh is a minimal in-memory key-value server designed to provide per-user session data for Gemini CGI scripts.

For lightweight applications, such as games, a traditional database is an overkill both in terms of hardware and maintenance requirements. cgisesh is a tiny standalone server which requires no configuration or maintenance (other than specifying record size, max size, and socket address on startup).

To minimize resource utilization and guarantee top performance, cgisesh runs as an in-memory domain-socket server, never touching the filesystem.

cgisesh is optimized for session-based access pattern (ideal for games) where repeated lookups on same keys are predominant, and loss of state is not critical.

Current Status

A working server and example cgi script that counts the number of visits for each certificate.

Made provisions for maximum records but not handling overflows yet.

Server

cgisesh RecordSize [MaxRecords=256] [SocketPath=/tmp/cgisesh]

The same binary may be used for multiple cgi scripts; each server needs to be started with proper parameters matched by the cgi clients.

Client

the cgi script must connect to the server socket. The easiest way to do so in C is to incorporate cgisesh.c cgisesh.h into the project. The public interface is:

void cgisesh_init(int RecSize,char* SocketPath);
int  cgisesh_lookup(char* sha256, void*buf);
int  cgisesh_update(void*buf);

This snippet explains the basics of using cgisesh:

struct sBuf {
    int token;     // reserved!
    long score;   // your data...
    ...
}
...

cgisesh_init(256,"/tmp/cgisesh");   //init record size and socket path

char* client_hash_str = getenv("TLS_CLIENT_HASH"); 

if(!client_hash_str) {
  printf("60 Client certificate required\r\n");
} else {
  printf("20 test/gemini\r\n");

  // the actual hash is just past "SHA256:", 7 chars in
  int err = cgisesh_lookup(client_hash_str+7, buf);  // read user state

  if(err) goto error_handler;

  printf("Score is %ld\n",buf.score);  

  buf.score += 5;                      // update user state

  cgisesh_update(buf);                 // send it to cgisesh
...

For more details, see the example cgi in client subdirectory.