CGI Program
CGI programs work very similar to regular
programs. On entry of main(),
n
stdin
is set to a data file which stores data from user browser.
n
stdout
is set to a pipe which sends data to user browser indirectly.
Instead of using regular query string like
"?id=xxx&p=yyy", we use the simple ISINDEX format which separates
arguments by "+". The advantage of ISINDEX is that HTTP server had
already parsed the arguments for us, and put them in argv[] of main(argc,
argv[]). Therefore we don't need to parse the query strings, this will make
things easier. The arguments are arranged as:
arg[1] = 's' - display web page
'u' - update settings or command
arg[2] = name of page or command.
The cgi program uses 30 KB memory to buffer HTML pages. It has been large enough for most CGI applications, but it may still become overflow for some authoring tools generate very complicated JavaScript to produce fancy looking. You should check the size of HTML carefully.
The detailed operations are best explained
by codes in "app/cgi/cgi.c".
main() of cgi.c
// CGI Program Entry // When starting, the HTTP server set // stdin (FD 0) as
the input from browser ( a /tmp file handle) // stdout (FD 1) as the output to browser ( a pipe handle) int
main(int argc, char *argv[]) { char *s,*sMethod; int n;
// change to our working directory
chdir("sys");
/* Catch various termination signals. */ signal( SIGTERM,
SigTerminate ); signal( SIGINT,
SigTerminate ); signal( SIGHUP,
SigTerminate );
// Validate CGI arguments //
We use simple ISINDEX format, 2 arguments only // show page
-> s + page_name
// save / command
-> u + page_name if(argc!=3)
HttpError("Invalid URL"); // get HTTP method. GET or
POST
sMethod=getenv("REQUEST_METHOD"); if(!s)
HttpError("Unknown method"); // GET
method, show page if(strcmp(argv[1],"s")==0) { // GET method only if(strcmp(sMethod,"GET"))
HttpError("GET method only"); // select the page we want to display
if(strcmp(argv[2],"status")==0) ShowStatus(); else
if(strcmp(argv[2],"network")==0) ShowNetwork(); else
if(strcmp(argv[2],"io")==0) ShowIo(); else
if(strcmp(argv[2],"system")==0) ShowSystem(); else
if(strcmp(argv[2],"reboot")==0) Reboot(); else
HttpError("Invalid URL"); //
Ok, exit CGI exit(0); } //
POST method, command or save settings if(strcmp(argv[1],"u")==0) { // POST method only if(strcmp(sMethod,"POST"))
HttpError("POST method only"); s=getenv("CONTENT_LENGTH"); if(!s) HttpError("Need data"); m_pSize=atoi(s);
if(m_pSize>10240) HttpError("CGI data too large"); //
Read post data into buffer n=fread(m_pBuf,1,m_pSize,stdin); if(n<=0)
HttpError("CGI read error"); //
the page we want to save if(strcmp(argv[2],"network")==0)
SaveNetwork(); else
if(strcmp(argv[2],"io")==0) SaveIo(); else
if(strcmp(argv[2],"system")==0) SaveSystem(); else
if(strcmp(argv[2],"reboot")==0) Reboot(); else
HttpError("Invalid URL"); //
Ok, exit CGI exit(0); } //
Unknown queries HttpError("Invalid
URL"); return 0; } |