In the previous processes in this segment, our Apache service only served static content, which means that everything requested by a web-browser already existed in a constant state on the server, for example as plain HTML text files that don’t change. Apache simply sends the content of a specific file from the web server to the browser as a response where it then gets interpreted and rendered. If there were no way to change the contents sent to the client, the Internet would be really boring and not the huge success it is today. Not even the simplest example of dynamic content, such as showing a web page with the web server’s current local time would be possible.
Therefore, early in the 1990’s, some smart people started inventing mechanisms to make communication possible between a web server and some executable programs installed on the server to generate web pages dynamically. This means that the content of the HTML sent to the user can change in response to different contexts and conditions. Such programs are often written in scripting languages such as Perl or Ruby but can be written in any other computer language as well, such as Python, Java, or PHP (see later). Because Apache is written in pure C and C++, it cannot execute or interpret any other programming language such as Perl directly. Therefore, a bridge between the server and the program is needed to define how some external programs can interact with the server. One of these methods is called the Common Gateway Interface (CGI) which is a very old way to serve dynamic content. Most Apache web servers use some form of CGI applications and in this process, we will show you how to install and configure CGI for use with Perl and Ruby to generate our first dynamic content.
Note
There also exist some special Apache web server modules such as mod_perl, mod_python, mod_ruby, and so on which should be generally preferred as they directly embed the interpreter of the language into the web server process and therefore are a lot faster in comparison to any interface technology such as CGI.
To Start With: What Do You Need?
To complete this process, you will require a working installation of the CentOS 7 operating system with root privileges, a console-based text editor of your choice, and a connection to the Internet in order to facilitate the download of additional packages.
It is expected that your server will be using a static IP address, Apache is installed and currently running, and that your server supports one or more domains or subdomains.
The Process
As both scripting languages Perl as well as Ruby are not installed by default on CentOS 7 Minimal, we will start this process by installing all required packages using YUM.
- To begin, log in as root and type the following command:
yum install perl perl-CGI ruby
- Next, restart the Apache web server:
systemctl restart httpd
- Next, we need to configure SELinux appropriately for the use of CGI scripts:
setsebool -P httpd_enable_cgi 1
- Then we need to change the correct security context for our cgi-bin directory for SELinux to work:
semanage fcontext -a -t httpd_sys_script_exec_t /var/www/cgi-bin restorecon -Rv /var/www/cgi-bin
Creating your first Perl CGI script
- Now create the following Perl CGI script file by opening the new file vi /var/www/cgi-bin/perl-test.cgi and putting in the following content:
#!/usr/bin/perl
use strict;
use warnings;
use CGI qw(:standard);
print header;
my $now = localtime;
print start_html(-title=>'Server time via Perl CGI'),
h1('Time'), p("The time is $now"),
end_html; - Next, change the file’s permission to 755, so our apache user can execute it:
chmod 755 /var/www/cgi-bin/perl-test.cgi
- Next, to test and actually see what HTML is being generated from the preceding script, you can execute the perl script directly on the command line; just type:
/var/www/cgi-bin/perl-test.cgi
- Now open a browser on a computer in your network and run your first Perl CGI script, which will print the local time by using the URL:
http://<server name or IP address>/cgi-bin/perl-test.cgi
- If the script is not working, have a look at the log file /var/log/httpd/error_log.
Creating your first Ruby CGI script
- Create the new Ruby CGI script file vi /var/www/cgi-bin/ruby-test.cgi and put in the following content:
#!/usr/bin/ruby
require "cgi"
cgi = CGI.new("html4")
cgi.out{
cgi.html{
cgi.head{ cgi.title{"Server time via Ruby CGI"} } +
cgi.body{
cgi.h1 { "Time" } +
cgi.p { Time.now}
}
}
} - Now change the file’s permission to 755 so our apache user can execute it:
chmod 755 /var/www/cgi-bin/ruby-test.cgi
- To actually see what HTML is being generated from the preceding script, you can execute the Ruby script directly on the command line; just type /var/www/cgibin/ruby-test.cgi. When the line offline mode: enter name=value pairs on standard input is shown, press Ctrl+D to see the actual HTML output.
- Now open a browser on a computer in your network and run your first Ruby CGI script which will print the local time by using the following URL:
http://<server name or IP address>/cgi-bin/ruby-test.cgi
- If it is not working, have a look at the log file /var/log/httpd/error.log.
How Does It Work?
Here in this process, we showed you how easy it is to create some dynamic web sites using CGI. When a CGI resource is accessed, the Apache server executes that program on the server and sends its output back to the browser. The main advantage of this system is that CGI is not restricted to any programming language but works as long as a program is executable on the Linux command line and generates some form of text output. The big disadvantage of CGI technology is that it is a very old and outdated technology: every user request to a CGI resource starts a new process of the program. For example, every request to a Perl CGI script will start and load a new interpreter instance into memory, which will produce a lot of overhead, therefore making CGI only usable for smaller websites or lower parallel user request numbers. As said before, there are other technologies to deal with this issue, for example FastCGI or Apache modules such as mod_perl.
So what did we learn from this experience?
We began this process by logging in as root and installing the perl interpreter and the CGI.pm module for it as it is not included in the Perl standard library (we will use it in our script), as well as by installing the ruby interpreter for the Ruby programming language. Afterwards, to make sure our Apache web server takes notice of our new programming languages installed on the system, we restarted the Apache process.
Next, we made sure that SELinux is enabled to work with CGI scripts and then we provided the standard Apache cgi-bin directory /var/www/cgi-bin with the proper SELinux context type to allow system-wide execution. To learn more about SELinux, read, Working with SELinux. In this directory we then put our Perl and Ruby CGI scripts and made them executable afterwards for the Apache user. In the main Apache configuration file, the /var/www/cgi-bin directory has been defined as the standard CGI directory by default, which means that every executable file you put into this directory, with proper access and execution permissions and the .cgi extension, is automatically defined as a CGI script and can be accessed and executed from your web browser, no matter which programming or scripting language it has been written in. To test our scripts, we then opened a web browser and went to the URL http://<server name or IP address>/cgi-bin/ with the name of the .cgi script to follow.
There's more…
If you would like to allow execution of CGI scripts in other web directories as well, you need to add the following two lines (Options and AddHandler) to any virtual host or existing Directive directive, or create a new one in the following way (remember that you then also have to set the SELinux httpd_sys_script_exec_t label on the new CGI location as well):<Directory "/var/www/html/cgi-new">
Options +ExecCGI
AddHandler cgi-script .cgi
</Directory>