CGI Environment Vars in C





8
Date Submitted Fri. Sep. 22nd, 2006 12:16 AM
Revision 1 of 1
Scripter sehrgut
Tags C | CGI
Comments 0 comments
The best way I've found to keep a suite of CGI environment variables in my C CGI programs is actually just to read them as name-value pairs into a stack. It simplifies parsing and makes the code cleaner and less fragile than using a specialized structure or an ordered array of strings (as well, empty variables are simply not push()ed onto the stack, so memory doesn't have to be allocated for empty strings). Plus, since there are never a huge number of environment variables, and they are all unique (by definition), a search through the stack for a given name takes minimal time. In fact, retrieval of environment variables beats a PHP-like hash-table implementation by a good deal.

In the code below, all you have to keep in mind is that the NVStk is a name/value pair stack (implemented as a singly-linked list with each node containing two char*s). Variable retrieval times can be minimized by adjusting the order of variable names in the char**s passed to sgcgi_getenv(). In fact, the ones below are just about backwards from how they ought to be, since I forgot I was using a stack instead of a queue . . . *blush*

Of course, there are more environment variables you can get, but you have to draw the line between exhaustion and efficiency, and that depends on the project. The variables included here are pretty much overkill for any program you're likely to need.

A nice way to use these types of functions is to wrap them in an accessor function that gets the environment once and keeps it as a static variable, and then on subsequent calls just looks up values in its stack. (If you want to see the NVStk, I can put it up, but it's pretty much a basic linked list.)

NVStk*  sgcgi_getenv      (char **vars, int count) {

        NVStk   *stack          =    stk_new_nvstk();
        if(!stack) {
                sgcgi_fatal(SGCGI_ERR_MALLOC);
                }

        int i;
        char    *tmp;
        for(i=0; i<count; i++) {
                tmp          =    getenv(vars[i]);
                if(tmp) {
                        stk_nvstk_push(stack,vars[i],tmp);
                        }
                }
        return stack;
        }
 

NVStk*  sgcgi_get_servervars      (void) {
        char    *servervars[]       =      {
                "PATH_INFO", "PATH_TRANSLATED","SCRIPT_NAME",
                "QUERY_STRING","REMOTE_HOST","REMOTE_ADDR",
                "CONTENT_TYPE","CONTENT_LENGTH","DOCUMENT_ROOT",
                "REMOTE_PORT","REQUEST_METHOD","REQUEST_URI",
                "SCRIPT_FILENAME","SCRIPT_URI","SCRIPT_URL",
                "SERVER_NAME","SERVER_SOFTWARE",
                "GATEWAY_INTERFACE","SERVER_PROTOCOL",
                "SERVER_PORT","REQUEST_METHOD","AUTH_TYPE",
                "REMOTE_USER","REMOTE_IDENT","PATH","PWD",
                "SERVER_ADDR","SERVER_ADMIN"
                };

        return sgcgi_getenv(servervars,28);
        }
 

NVStk*  sgcgi_get_reqheaders      (void)        {
        char    *reqheadervars[]    =   {
                "HTTP_USER_AGENT","HTTP_COOKIE","HTTP_REFERER",
                "HTTP_HOST","HTTP_ACCEPT","HTTP_ACCEPT_CHARSET",
                "HTTP_ACCEPT_ENCODING","HTTP_ACCEPT_LANGUAGE",
                "HTTP_CONNECTION","HTTP_KEEP_ALIVE"
                };

        return sgcgi_getenv(reqheadervars,10);
        }
 

Keith B

alphahelical.com
I've got good news, and I've got bad news:
The universe is merely a figment of my imagination.
Now are you ready for the bad news?

Comments

There are currently no comments for this snippet.

Voting