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!
Saturday, May 8. 2010
Videos were About to Change
The original idea of this entry was to announce HTML5 videos inside the blog, I mean, changing from my well known flash flowplayer to the brand new HTML5 video tag. But finally I decided it is too early for such a change, please see my reasons below.
HTML5 video is a new feature that is being adopted by browsers quickly. Nevertheless the never-ending fight between browsers is now focusing on the formats/codecs supported by this new feature. At the moment there are three codecs in the game:
It is already known I use debian testing as linux distribution, taking it as example firefox/iceweasel is at 3.5 version, epiphany is 2.29.3 and chromium-browser has just entered to unstable (5.0.375.29). So almost every debian testing browser supports video, and more generally, it can be said any linux distribution has right now a good support for HTML5 video (OGG format). Apple safari has no problems either and it has been supporting video feature for a long time (H.264). But the problem comes with Microsoft Internet Explorer, neither 7 nor 8 supports new video tag, even the just released IE9 platform preview 2 does not support it (it seems that we have to wait til end of June for preview 3 and H.264 support). Assuming IE9 previews are alpha (developer target) releases and final IE9 will not support XP I gave in and I held my unstoppable wishes of change back.
Videos were going to use both codecs (H.264 and OGG) in order to support all browsers that nowadays deal with video tag. Here it is an example of the failed HTML5 attempt using the video from Integrating Skype into a Portal post.
It is hard to slow your ideas down and even more if the infamous IE is the guilty one.
Keep trying!
EDIT: Google has just open-sourced VP8 with WebM (VP8 video + vorbis audio container). The source code can be found on the project web site. So the rules of the game have been reset again.
HTML5 video is a new feature that is being adopted by browsers quickly. Nevertheless the never-ending fight between browsers is now focusing on the formats/codecs supported by this new feature. At the moment there are three codecs in the game:
- OGG Theora: Open source and patent free, it was recommended by HTML5 specification in first drafts but the standard removed later its mention replacing any reference to concrete formats.
- H.264/MPEG-4 AVC. Codec widely used, good speed, compression, hardware decoders, and video quality, but covered by patents. Except in particular cases, users of H.264 have to pay licensing fees to the MPEG LA, a group of patent-holders including Microsoft and Apple.
- VP8. Google's acquisition of On2 will reportedly result in the open-sourcing of On2's proprietary codec, VP8, which would make it a possible option for HTML5 video. Community is awaiting for google and now it is not a real choice.
It is already known I use debian testing as linux distribution, taking it as example firefox/iceweasel is at 3.5 version, epiphany is 2.29.3 and chromium-browser has just entered to unstable (5.0.375.29). So almost every debian testing browser supports video, and more generally, it can be said any linux distribution has right now a good support for HTML5 video (OGG format). Apple safari has no problems either and it has been supporting video feature for a long time (H.264). But the problem comes with Microsoft Internet Explorer, neither 7 nor 8 supports new video tag, even the just released IE9 platform preview 2 does not support it (it seems that we have to wait til end of June for preview 3 and H.264 support). Assuming IE9 previews are alpha (developer target) releases and final IE9 will not support XP I gave in and I held my unstoppable wishes of change back.
Videos were going to use both codecs (H.264 and OGG) in order to support all browsers that nowadays deal with video tag. Here it is an example of the failed HTML5 attempt using the video from Integrating Skype into a Portal post.
<video width="640" height="400" autobuffer="true" controls="true">
<source src="out.mp4" type="video/mp4"/>
<source src="out.ogv" type="video/ogg"/>
Your browser doesn't support the video tag.
You can <a href="out.ogv">download the video here</a>.
</video>
It is hard to slow your ideas down and even more if the infamous IE is the guilty one.
Keep trying!
EDIT: Google has just open-sourced VP8 with WebM (VP8 video + vorbis audio container). The source code can be found on the project web site. So the rules of the game have been reset again.
(Page 1 of 1, totaling 2 entries)
Comments