Tuesday, May 25. 2010
Making a SUDOKU using CGI
Two or three months ago my friend Ramón and me were invited to eat shrimp by an old work mate, Antonio. He is about to retire (unfortunately for him in two or three years) and he had reached an agreement to leave the company. He wanted to say us goodbye. Talking about different things he asked me to help him with some stuff he was amusing himself with. He had developed a little C program to resolve sudokus and he wanted to take it to the web. Antonio is an old school technician and knows rather little about web design, java or things like these, so I talked about old CGI solution. He told me not to waste his time and to send him some examples. I know CGI stuff is not something that I usually deal with in my blog, but if these examples are useful for Antonio they may be for any of you. And Antonio, I know it took me a long time but I am an occupied person, I can simply say I forgot it but maybe I would offend you.
First of all the sudoku itself must to be design. The user is supposed to fill the sudoku (copying from the newspaper or the magazine) and then call Antonio's CGI in order to solve the quiz. The sudoku is designed like a 9x9 text input square. Of course some CSS is used to make the boxes look like the famous sudoku board. Besides a little javascript is incorporated to avoid the user to type something different than numbers (from 1 to 9). The HTML stuff consists of three files:
The final result is the empty sudoku board I present below.
Now the user can fill the sudoku the CGI part takes the turn. CGI is an old technique that let any executable (C, perl or whatever) to be integrated into a web server. The executable receives typical web parameters via environment variables (QUERY_STRING, REQUEST_URI, HTTP_USER_AGENT and many others) and it generates the HTML code directly writing to standard output. It is clear this technique is not the best in terms of performance (every call to the CGI means a fork, initialization and execution) and that is the reason CGI were obsoleted by other multi-threaded, tightly coupled solutions like FastCGI, SCGI, Servlets, mod_perl or PHP.
Going back to our sudoku problem when the user presses the submit button all the text inputs are sent to the CGI. As you know an HTTP form can send information via GET or POST. The GET method adds all the parameters to the QUERY_STRING, for example GET submit of the sudoku form results in the following URL:
So the CGI receives all the cell data inside QUERY_STRING environment variable. Parameters are sent using pairs name=value and separated each other with an ampersand (&). Besides values are encoded to avoid non-ascii characters.
But if POST submit is used the parameters are sent in the body of the message. I mean, using GET all the data is in the URL and no body is sent in the HTTP message but using POST the URL has no parameters and all of them are written in the HTTP body. The CGI receives the body as standard input, i.e. the CGI has to read the standard input (parameters are sent exactly the same way as GET, encoded and separated with an ampersand).
In summary, a little sudoku.c is presented. The program performs the following steps:
In order to compile the c program it is just needed the simplest gcc command:
The final point is how to put the CGI inside a web server. My CGI example deserves to run inside Apache web server. Apache is the everlasting open source web server, it is very complete and robust but a bit heavy. Now there are other web servers which out-perform Apache mainly when not a full-featured web server is needed (lightweight httpd).
To run the example inside Apache we need to move our static content inside the docroot in a /sudoku directory (references of the generated HTML are pointing this directory). This way if the /var/apache2/htdocs is the docroot of the Apache we set the following files:
And the sudoku binary must be placed inside a cgi-bin directory. Any Apache installation usually has a CGI directory, for example in my box this is the line of the httpd.conf configuration file that defines the cgi-bin:
Any binary placed inside /var/apache2/cgi-bin/ acts as a CGI program, so our sudoku binary must be moved there:
And the URI to call it is /cgi-bin/sudoku. If you check the index.html file, its form has the action pointing to this binary.
And it is done. Antonio use the comments part if you have any doubt (this way I am sure you will not make me crazy and you will try your best before asking).
Good luck!
First of all the sudoku itself must to be design. The user is supposed to fill the sudoku (copying from the newspaper or the magazine) and then call Antonio's CGI in order to solve the quiz. The sudoku is designed like a 9x9 text input square. Of course some CSS is used to make the boxes look like the famous sudoku board. Besides a little javascript is incorporated to avoid the user to type something different than numbers (from 1 to 9). The HTML stuff consists of three files:
- index.html: The main HTML page that has the sudoku to fill and a submit and reset button. The text inputs are called cXY where X and Y are the sudoku cell, from 1 to 9.
- sudoku.css: CSS style sheet to make the text inputs similar to a sudoku board, the tricky part for joining the boxes is to use negative numbers in margin tag.
- sudoku.js: The onlyNumbers javascript function which avoids typing something different from numbers.
The final result is the empty sudoku board I present below.
Now the user can fill the sudoku the CGI part takes the turn. CGI is an old technique that let any executable (C, perl or whatever) to be integrated into a web server. The executable receives typical web parameters via environment variables (QUERY_STRING, REQUEST_URI, HTTP_USER_AGENT and many others) and it generates the HTML code directly writing to standard output. It is clear this technique is not the best in terms of performance (every call to the CGI means a fork, initialization and execution) and that is the reason CGI were obsoleted by other multi-threaded, tightly coupled solutions like FastCGI, SCGI, Servlets, mod_perl or PHP.
Going back to our sudoku problem when the user presses the submit button all the text inputs are sent to the CGI. As you know an HTTP form can send information via GET or POST. The GET method adds all the parameters to the QUERY_STRING, for example GET submit of the sudoku form results in the following URL:
http://server:port/cgi-bin/sudoku?c11=1&c12=&c13=&c14=8&...
So the CGI receives all the cell data inside QUERY_STRING environment variable. Parameters are sent using pairs name=value and separated each other with an ampersand (&). Besides values are encoded to avoid non-ascii characters.
But if POST submit is used the parameters are sent in the body of the message. I mean, using GET all the data is in the URL and no body is sent in the HTTP message but using POST the URL has no parameters and all of them are written in the HTTP body. The CGI receives the body as standard input, i.e. the CGI has to read the standard input (parameters are sent exactly the same way as GET, encoded and separated with an ampersand).
In summary, a little sudoku.c is presented. The program performs the following steps:
- The sudoku representation is a int[10][10] matrix array. I know I am wasting the 0 row and 0 column but it does not matter cos my representation is pointless (Antonio representation is the meaningful).
- Matrix is reset to 0 (9x9 board is set to 0).
- The program receives the cXY parameters (using QUERY_STRING or standard input, GET or POST) and fills the sudoku matrix. The non-empty parameters are placed in the corresponding cells (the remaining cells are still zero). The final solution must be modified to assign cXY parameters to the correct sudoku representation. For this part I copied some code from cgiparse.c of W3C (parsing and decoding stuff).
- Nothing. The four step would be resolving the sudoku but my example is just an empty box (Antonio you have to insert your code here).
- The HTML is generated to the standard output. The page is just the same to the first one but the inputs are readonly (they are non modifiable). My empty example just returns the same sudoku previously sent but with 0's in the not filled cells.
In order to compile the c program it is just needed the simplest gcc command:
$ gcc -o sudoku sudoku.c
The final point is how to put the CGI inside a web server. My CGI example deserves to run inside Apache web server. Apache is the everlasting open source web server, it is very complete and robust but a bit heavy. Now there are other web servers which out-perform Apache mainly when not a full-featured web server is needed (lightweight httpd).
To run the example inside Apache we need to move our static content inside the docroot in a /sudoku directory (references of the generated HTML are pointing this directory). This way if the /var/apache2/htdocs is the docroot of the Apache we set the following files:
/var/apache2/htdocs/sudoku/index.html
/var/apache2/htdocs/sudoku/sudoku.css
/var/apache2/htdocs/sudoku/sudoku.js
And the sudoku binary must be placed inside a cgi-bin directory. Any Apache installation usually has a CGI directory, for example in my box this is the line of the httpd.conf configuration file that defines the cgi-bin:
ScriptAlias /cgi-bin/ "/var/apache2/cgi-bin/"
Any binary placed inside /var/apache2/cgi-bin/ acts as a CGI program, so our sudoku binary must be moved there:
/var/apache2/cgi-bin/sudoku
And the URI to call it is /cgi-bin/sudoku. If you check the index.html file, its form has the action pointing to this binary.
And it is done. Antonio use the comments part if you have any doubt (this way I am sure you will not make me crazy and you will try your best before asking).
Good luck!
Comments