38.2. Configuring ApacheThe Apache web server is controlled by configuration files that live in the directory /opt/apache/conf. The main configuration file is httpd.conf , and like most configuration files for Unix services, it is a plain text file that can be edited by your favorite text editor. The configuration file is broken down into three main sections:
You may be asking "What is a virtual host?" While the Apache web server is perfectly capable of serving the web pages for a single web site (such as www.example.com), its real strength lies in its ability to serve pages for many different web sites, all from the same machine. Each of these web sites is called a virtual host, because it appears that each of them has Apache all to itself. This allows companies or ISPs to host many (often thousands) of web sites on a single Apache installation. Virtual host syntax will be covered later in the chapter. The global configuration section gives directives that affect the entire Apache installation, including any virtual hosts. Let's look at one of the simplest Apache httpd.conf files you'll ever see, Example 38-1. It's all global directives; we're not defining any virtual hosts. This is a complete httpd.conf file and is probably sufficient if you're just using Apache in a testing environment. Example 38-1. Apache configuration file
Most of these lines are pretty self-explanatory. ServerRoot defines where you installed Apache ; all directory paths given after this directive can be given relative to this root. Listen 80 tells Apache what TCP port to listen for connections on. The LoadModule lines ensure that the modules we compiled as DSOs get loaded into memory every time Apache starts. The User and Group directives dictate the security context under which the Apache binary will run. The ServerAdmin directive indicates the email address that is shown to web browsers when an error is encountered, and the DocumentRoot directive tells Apache where to look for pages to serve. The <Directory> line indicates the start of a container object. Anything between the <Directory /opt/apache/htdocs> and </Directory> tags applies only to the directory /opt/apache/htdocs. As you can see, we're turning on some options and dictating who can request content from this directory (in this case, anyone). The Options directive is a complicated one and can be a potential security risk. For more information, visit the Apache documentation at http://httpd.apache.org/docs/2.2/mod/core.html#options. For our simple example here, Indexes and FollowSymLinks are two pretty safe and popular options. DirectoryIndex defines what files Apache should look for when a directory is requested instead of a file. For example, if our site is www.example.com and our index page is /opt/apache/htdocs/index.html, we want to make sure that when someone requests either http://www.example.com or http://www.example.com/index.html they see the same resource. So the line: DirectoryIndex index.html handles this for us. You can add additional filenames here if you want Apache to search for them (in order) every time it serves files out of a directory. A common global option would be: DirectoryIndex index.html index.htm index.php to try and catch most of the different ways people would name their index files. The next three lines deal with how and where Apache saves log files. All errors will go to the file defined in the ErrorLog directive. All regular traffic will be logged to the file defined in the CustomLog directive, using the filter indicated, which is combined in this case. As you can see from the LogFormat directive, you have complete control over the formatting of your log files. However, because it's very common to use third-party tools to parse your Apache log files and generate reports for you, you probably want to stick with a standard format that these tools are expecting. The different standards for log file formatting are defined at http://httpd.apache.org/docs/2.2/logs.html#accesslog. Finally, the last four lines deal with how Apache handles certain "special" content. The ScriptAlias directive tells Apache that when a file is requested from this directory, instead of sending the file directly to the requestor's web browser, the file is executed and the output is sent to the web browser. This is the most common way to allow public users to execute programs on your server. These programs are known as Common Gateway Interface (CGI) scripts. They are often written in scripting languages, such as Perl or Python, but they can also be written in C, Ruby, or any other language that you can run on your server. The Default Type and Types Config lines tell Apache what to do with certain files. Unlike operating systems such as Microsoft Windows, where file types are usually determined by filename extensions, Apache relies on MIME types to determine the content of a file. These configuration lines tell Apache where to find the MIME types definition file and what the default MIME type should be for files that it serves. Finally, the AddHandler line allows you to have CGI programs anywhere in your web directory structure, not just limited to the cgi-bin directory. As long as your CGI program has a name that ends in .cgi, Apache will execute it and send the results to the web browser. The main section of the Apache configuration file is used to define default settings for requests that come in that do not match a virtual host. If you are running Apache without any virtual hosts (so it's serving content for only one domain name) this is the only other section you'll need. All your configuration options for that one domain will go here. If you have virtual host containers later, however, this section will be used only when no virtual host matches the request. To understand that a little better, we need to discuss the difference between name-based and IP-based virtual hosts. Years ago, when the Web was young, if you wanted to host multiple web sites on one system, you had to have a unique IP address for every domain you wanted to host. For example, if you were hosting the domains www.example1.com and www.example2.com, the IP addresses for them might be 192.168.1.1 and 192.168.2.1, respectively. If that were the case, your virtual host containers might look something like this: <VirtualHost 192.168.1.1> DocumentRoot /opt/apache/www.example1.com ServerName www.example1.com </VirtualHost> <VirtualHost 192.168.2.1> DocumentRoot /opt/apache/www.example2.com ServerName www.example2.com </VirtualHost> For every web request that came in on 192.168.1.1, Apache would serve files out of the /opt/apache/www.example1.com directory. For every web request that came in on 192.168.2.1, Apache would serve files out of the /opt/apache/www.example2.com directory. This works fine, but the problem is that IP addresses are becoming harder and harder to come by. The solution is instead to use name-based virtual hosts, which allow multiple domain names to resolve to the same IP address, while still allowing Apache to figure out what domain is being requested and serve web pages from the appropriate place. A name-based virtual host setup looks like this: NameVirtualHost *:80 <VirtualHost *:80> ServerName www.example1.com ServerAlias example1.com DocumentRoot /opt/apache/www.example1.com </VirtualHost> <VirtualHost *:80> ServerName www.example2.com ServerAlias example2.com DocumentRoot /opt/apache/www.example2.com </VirtualHost> Notice that the first directive is NameVirtualHost. This tells Apache to expect name-based virtual hosts. We also tell Apache here to expect name-based requests coming in on port 80 (as specified by *:80). This is not required if your implementation of Apache is going to listen only on port 80 (if that's the case, you can just put NameVirtualHost *), but it's good practice anyway, because web servers often listen on additional ports. In this case it's assumed that www.example1.com and www.example2.com both resolve to the same IP address. When a request comes in, Apache will look in the HTTP headers to determine what virtual host is being requested and will search the ServerName and ServerAlias directives to find a match. If a match is found, content is served from the corresponding DocumentRoot. If no match is found, the default virtual host is used. Name-based virtual hosts treat the different sections of the configuration file in a special way you need to understand. In an IP-based setup, if there is no virtual host match (which means that a request came in on an IP address that was not defined in a virtual host container), the main section is used. However, with name-based virtual hosts, if no match is found, the first defined VirtualHost container becomes the default. Essentially, therefore, named-based virtual hosting overrides the main section of the Apache config file. Even if that section is there, the directives will never be honored. You can put any directive in a VirtualHost container that you would normally put in the main section. Here is a better example of what a VirtualHost container would often contain: <VirtualHost *:80> ServerName www.example1.com ServerAlias example1.com CustomLog /opt/apache/logs/www.example1.com.log combined DocumentRoot /opt/apache/www.example1.com/ ScriptAlias /cgi-bin/ /opt/apache/www.example1.com/cgi-bin/ Alias /image/ /opt/apache/image/ Options FollowSymLinks ErrorDocument 404 /404.htm </VirtualHost> In this example, we're defining a custom log file, a unique script alias, and a unique error document for this virtual host. 38.2.1. Access ControlIt's common to use the Apache configuration to restrict access to certain directories. The two components of this process are the configuration directives and the username and password source. Apache has the ability to query many different sources to get authentication information. It's very common to have Apache query your existing LDAP or MySQL database if you already have user account information stored there. You can even have Apache query your Microsoft Windows Active Directory server for authentication information. Setting up this kind of advanced authentication is beyond the scope of this book. However, simple authentication with a manually maintained file of usernames and passwords is easy to do and is sufficient for most situations. The standard authentication mode for Apache is called basic authentication. Basic authentication reads a file created by the htpasswd program that ships with Apache. This program allows you to create and maintain a file containing usernames and passwords that Apache can use to enforce authentication on directories. Here is an example of creating an authentication file with htpasswd: # /opt/apache/bin/htpasswd -c /opt/apache/password.list demouser New password: Re-type new password: Adding password for user demouser Note that the password you type at the prompt is not echoed back to the screen. We can now look at the contents of this file: # cat /opt/apache/password.list demouser:RRm8uBOYINC.s It contains our username (demouser), a colon as a delimeter, and the encrypted version of the password we typed. Now that we have this file in place, we can add security to one of our virtual hosts. Let's say that we want to allow all users to access the top level of www.example1.com without a password, but the subdirectory /protected will require a username and password and will restrict access to the demouser user listed in the file we just created (of course, we can add more users later). Here is our new VirtualHost container to accomplish this: <VirtualHost *:80> ServerName www.example1.com ServerAlias example1.com CustomLog /opt/apache/logs/www.example1.com.log combined DocumentRoot /opt/apache/www.example1.com/ ScriptAlias /cgi-bin/ /opt/apache/www.example1.com/cgi-bin/ Alias /image/ /opt/apache/image/ Options FollowSymLinks ErrorDocument 404 /404.htm <Directory /opt/apache/www.example1.com/protected> AuthName "Authorized Users Only" AuthType Basic AuthUserFile /opt/apache/password.list require valid-user </Directory> </VirtualHost> After we add this directory container to the Apache config file at /opt/apache/conf/httpd.conf, we must restart Apache (/opt/apache/bin/apachectl restart). Like most other Unix services, the Apache server reads its config file only at startup, so any change to the config file will go into effect only when Apache restarts. Now when we go to www.example1.com/protected in our web browser, we get a pop-up box that is entitled Authorized Users Only and asks for our username and password. If our authentication as demouser is successful, we will be shown the content. If not, we'll be asked three times (this behavior is client-specific) before finally being shown an error page stating that our authentication failed. 38.2.2. Third-Party ModulesAs stated earlier, the existence of third-party modules is one of the reasons that the Apache web server has remained so popular. In this section, we will look at configuring three of the most popular third-party modules: mod_php, mod_perl, and mod_ssl. 38.2.2.1. mod_phpThe mod_php module integrates the PHP (Pre-Hypertext Processing) scripting language into Apache. Like most other web scripting languages, PHP works in this manner:
This is the same model that is used for CGI scripts, but in this case the parser is not a separate program that Apache calls; it will be built into Apache itself. Like the Apache web server, you have the choice of installing either the binary version or the source version of PHP. If you're using a binary version of Apache that accompanies your distribution, chances are good that the distribution also has a version of mod_php that will work with your version of Apache. If you're using a source installation of Apache, as we are in our examples, you'll need to download the source code for PHP and compile it. You can get the latest version of PHP from http://www.php.net. As of this writing, the latest version is 5.1.1. Download the file php-5.1.1.tar.bz2 from a mirror listed on the php.net site and save it to a directory on your hard drive. The procedure for compiling PHP is very similar to the procedure for compiling Apache: we will run ./configure with options, then run make, and finally run make install. The first step is to uncompress the PHP source code and run ./configure -help to see all the compile-time options available. # tar xjf php-5.1.1.tar.bz2 # cd php-5.1.1 # ./configure -help There are too many compile-time options to list them all here. You can find detailed instructions on each configure option at http://www.php.net/manual/en/configure.php. A couple of important configuration options are described here:
Although there are many more options, these two will get you off and running with a basic PHP installation that you can become familiar with. # ./configure --with-apxs=/opt/apache/bin/apxs --with-mysql If this command generates any errors, check your settings and try again. It's common to see errors when you're attempting to compile PHP with modules for which you don't have the necessary libraries installed. For example, if you try to enable LDAP support in PHP with the --with-ldap flag, but you don't have any LDAP libraries or headers installed on your system, the configure script will detect this and fail. Assuming the configure command completes successfully, you will now have a Makefile that will be read by the make command. # make # make install The make install command not only copies all of the necessary PHP files onto your system, but also modifies your Apache httpd.conf file to load the PHP module. This line is added to /opt/apache/conf/httpd.conf: LoadModule php5_module modules/libphp5.so In order for Apache to know how to identify PHP scripts , you also need to add this line to the global section of your Apache httpd.conf file: AddType application/x-httpd-php .php .phtml This tells Apache that any file ending in .php or .phtml will be assigned the MIME type application/x-httpd-php, which will be in turn handled by the PHP interpreter. Now we're ready to restart Apache and verify that PHP is working. # /opt/apache/bin/apachectl stop # /opt/apache/bin/apachectl start Since we're loading a new module, it's not sufficient just to tell Apache to reread its configuration file (which is what the restart option does). We actually need to stop it and then start it again. The easiest way to verify our PHP installation is to create a simple PHP script and try to view it in our web browser. Save this text file in /opt/apache/www.example1.com/test.php: <?php phpinfo( ); ?> Now go to http://www.example1.com/test.php in your browser. You should see a long table with a blue background that says PHP Version 5.1.1 at the top. You can scroll down this page to see all the different PHP settings that are currently set. Congratulations! You have a working installation of Apache and PHP! 38.2.2.2. mod_perlInstalling the mod_perl module is not much different than installing the mod_php module. mod_perl allows you to run Perl scripts from your web server using a Perl interpreter that is integrated into Apache. Do you need mod_perl in order to run Perl scripts on your web server? No. You can just as easily configure Apache to run Perl scripts as CGI programs, calling your system's Perl interpreter every time a web request is made for a Perl script. However, this can potentially place a very high load on your web server, because every time a Perl script is requested, the web server must load the complete Perl interpreter in memory, pass the script to the interpreter, and then unload the interpreter from memory. It's much more efficient to keep the interpreter in memory all the time, which is what mod_perl provides. It also gives you much tighter integration with Apache itself, including the ability to extend the functionality of the web server with Perl code. Download the latest version of mod_perl from http://perl.apache.org. As of this writing, the latest version is 2.0.2. Uncompress the file and go through the normal compile routine. The syntax is slightly different since this is a Perl package, but the concept is the same. # tar xvf mod_perl-2.0-current.tar.gz # cd mod_perl-2.0.2 # perl Makefile.PL MP_APXS=/opt/apache/bin/apxs # make # make install We are compiling mod_perl as an Apache DSO, just as we did for PHP. After the make install is complete, we need to add this line to our Apache httpd.conf file: LoadModule perl_module modules/mod_perl.so Now we can stop and start Apache and verify that mod_perl is successfully loaded. In addition to the test script like the one we used earlier for PHP, you can also get information on the currently active modules by looking in the error_log after you restart Apache. Every time Apache starts, it writes a line to the error_log showing what version it is and what modules are loaded, along with their versions. After stopping and starting Apache, look in the error_log and you should see a line that reads something like this: [Wed Jan 04 14:39:18 2006] [notice] Apache/2.2.0 (Unix) mod_ssl/2.2.0 OpenSSL/0.9.7f DAV/2 PHP/5.1.1 mod_perl/2.0.2 Perl/v5.8.6 configured -- resuming normal operations This tells us all of the modules that are configured. We see that we're using mod_perl 2.0.2 which was compiled against Perl Version 5.8.6. 38.2.2.3. mod_sslmod_ssl allows Apache to encrypt HTTP connections with the Secure Sockets Layer encryption libraries. SSL was originally developed by Netscape and has become the de facto standard for secure, encrypted communication over the World Wide Web. mod_ssl is an Apache module that allows Apache to interface with the openssl libraries, which are open source implementations of SSL. Apache versions before 2.0 required that mod_ssl be downloaded and installed separately, similarly to what we did for mod_php and mod_perl. You can get the latest code from http://www.modssl.org. As of this writing, the latest version is 2.8.25 for Apache 1.3.34. Apache 2.0 and above have mod_ssl built in, so there is no extra compilation process; all you need to do is configure it. In order to understand the process of encrypting your web traffic with mod_ssl, we need to go into the basics of certificate-based cryptography. SSL provides us with two basic pieces of connection security: authentication and encryption. The authentication piece works like this: when your web browser connects to an SSL-enabled web site (usually by using the https:// protocol in your browser, which tells your browser to attempt to connect to the web server on TCP port 443 instead of port 80 and to expect an encrypted connection), the web server presents the web browser with a certificate. This certificate has detailed information about the web site, including the official fully qualified domain name, contact information, and the Certificate Authority that is vouching for the identity of this web site. Because this is still the authentication phase, we are concerned with proving that this web site really is who it claims to be. And because there is no easy way to trust this company, we instead look to a third party that we do trust in order to vouch for this company. This is where the Certificate Authority (CA) comes into play. All of the major web browsers include a list of trusted Certificate Authorities. If a web site presents a certificate that has been signed by one of these trusted CAs, the browser accepts the certificate and the encrypted communication can begin. If the certificate was not signed by a trusted CA, the web browser will usually pop up a window warning the end user of this situation and asking if they'd like to proceed. (A lot of CAs are recognized by some popular web browsers but not others, so the warning box can often pop up for legitimate sites.) If the end user agrees to trust the CA that signed the certificate, an encrypted connection is made. If not, the connection is aborted. Examples of trusted CAs are Verisign, Thawte Consulting, and GeoTrust, to name a few. In order to get a signed certificate from one of these companies, you create a certificate request and then send it to one of these companies. For a fee, they will sign the certificate and send you back a file you can use to handle the authentication piece on your web server. Let's go through the process of creating a certificate signing request and submitting it to a CA. In order to accomplish this task, you must have the openssl program installed on your system. As of this writing, the latest version is 0.9.7. This should have come from your vendor in a standard package.
The easiest way to set up Apache to handle SSL connections is to create a VirtualHost container that handles all traffic coming in on port 443. Adding onto our example Apache httpd.conf from before for www.example1.com, we can create a container for SSL connections to www.example1.com that looks like this: <VirtualHost *:443> DocumentRoot "/opt/apache/www.example1.com" ScriptAlias /cgi-bin /opt/apache/cgi-bin ServerName www.example1.com ServerAdmin webmaster@example1.com ErrorLog /opt/apache/logs/ssl_error_log CustomLog /opt/apache/logs/ssl_access_log combined Options FollowSymLinks SSLEngine on SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL SSLCertificateFile /opt/apache/ssl/server.crt SSLCertificateKeyFile /opt/apache/ssl/server.key </VirtualHost> The SSLCipherSuite line lists all of the SSL encryption methods that you will support. This is a pretty standard list; consult the mod_ssl documentation for more encryption options. Once you've restarted Apache, you are ready to serve pages over an encrypted connection. When you point a browser to https://www.example1.com, you'll have an SSL-secured web connection. But what if you just want to set up an internal SSL site and don't want to have to pay a fee to a trusted CA? Can you still have an SSL-secured site? The answer is yes. Just because your web browser has a short list of Certificate Authorities it inherently trusts doesn't mean you can't sign your own certificate. Use this command to create a self-signed certificate file: # openssl req -new -x509 -nodes -sha1 -days 365 -key server.key \ -out server.crt Copy the resulting server.crt file to /opt/apache/ssl and restart Apache. Now when you point your web browser to https://www.example1.com, you'll probably get a box that looks something like Figure 38-1. Figure 38-1. Browser accepting certificate from web serverAs you can see, the default option is to accept this certificate temporarily for this session. If you select Accept this certificate permanently, you are telling the browser to accept this certificate from now on, even though it is not from a trusted CA. Clicking on Examine Certificate shows us Figure 38-2. Figure 38-2. Certificate from web server displayedYou can see that this certificate contains the information we entered when we signed the certificate ourselves. So why use a trusted CA at all and pay the money when you can sign your own certificates? There are two reasons:
SSL support has become a very common option for Apache users, as security issues become more important on the Web. We encourage anyone who operates a web site that takes personal information (even usernames and passwords) to consider the benefits of SSL encryption. 38.2.2.4. mod_rewriteThe mod_rewrite module was mentioned during our initial compilation of Apache. mod_rewrite allows you to apply regular expression patterns to HTTP requests and manipulate them as you see fit. This gives you the ability to redirect incoming requests, directing users to different pages or replacing content on the fly. mod_rewrite is one of the most powerful Apache modules and is widely used by webmasters wanting more control over the content and layout of their site. The complete documentation for mod_rewrite can be found at http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html. Let's look at a few examples to see how mod_rewrite works. In this example, we'll use our standard web site www.example1.com. Let's say our company just purchased another company called example2.com. We are now hosting web sites for both companies, but we want to redirect people who try to go to example2.com to example1.com. This is easy to do with a VirtualHost container, as we have seen before. We could just make sure our VirtualHost container looked something like this: <VirtualHost *:80> ServerName www.example1.com ServerAlias example1.com www.example2.com example2.com DocumentRoot /opt/apache/www.example1.com CustomLog /opt/apache/logs/www.example1.com.log combined </VirtualHost> Now, any request that comes in for any of these four web sites (www.example1.com, example1.com, www.example2.com, or example2.com) will display the content that lives in /opt/apache/www.example1.com. However, we have two problems with this setup. First, if someone accesses this site with www.example2.com, the URL in his web browser stays www.example2.com throughout his visit to the site. Since we now own this company, we want to change that automatically to www.example1.com. Also, we may want to know how many people come into our site through www.example1.com and how many come in through www.example2.com. Since we have only one log file in this situation, we won't see a breakdown of traffic between the domains. A better solution would be to use mod_rewrite. We set up a separate VirtualHost container for www.example2.com and use mod_rewrite to redirect traffic to www.example1.com: <VirtualHost *:80> ServerName www.example2.com ServerAlias example2.com DocumentRoot /opt/apache/www.example1.com CustomLog /opt/apache/logs/www.example2.com.log combined RewriteEngine On RewriteRule ^(.+) http://www.example1.com [R] </VirtualHost> The ServerName and ServerAlias lines ensure that requests coming in for these domains are handled by this VirtualHost container (assuming we removed www.example2.com and example2.com from the example1.com VirtualHost container). The DocumentRoot can essentially be any valid directory, because we're not actually going to serve any content from it. The CustomLog will be a specific log for this VirtualHost so we know how many requests are coming in for www.example2.com. The RewriteEngine On line tells Apache to turn on the rewrite rule-processing engine for this VirtualHost. This is a necessary step, because the rewrite engine does incur some overhead, and you don't want Apache wasting memory on it if you're not going to use it. Finally, the RewriteRule line does the actual work for us. The format of the RewriteRule syntax is: RewriteRule pattern substitution [options] The pattern can be any valid regular expression that will be applied to the requested URL. The substitution is what the URL is replaced with. The options are ways to modify the behavior of RewriteRule and are not always required. In our example, we want to redirect every request for www.example2.com to www.example1.com. We also want to ensure that if someone had bookmarked a deep-linked page of www.example2.com (for example, www.example2.com/products/1/a/product.html), she is redirected to the home page of www.example1.com. Since we want our initial regular expression to catch everything, we use a catchall regular expression: ^(.+) The ^ character indicates the start of a line. The parentheses enclose the rest of our regular expression. The period (.) matches any single character, and the plus sign (+) is a modifier for the period, meaning one or more instances of the preceding character. So this regular expression essentially means "match anything." The substitution section is what we are going to replace the URL with. In this case, we want to replace every URL with our home page of www.example1.com. The only option we're using in this case is the R option, which forces an external redirect. When you're redirecting from one domain to another, you need to use this R option so Apache prepends the http:// to your rewrite destination. This option is not required if you're simply redirecting to another file in the same DocumentRoot. Another, more complicated example takes advantage of the RewriteCond expression to query more than one variable before rewriting occurs. RewriteCond is also used to query something other than the URL before a rewrite. In this example, we've done some site redesign, but we don't want to break any bookmarks that web users may already have for our site. In the past, people accessed our pages through a CGI script, so requests looked like this: http://www.example1.com/cgi-bin/go.cgi?page1 and http://www.example1.com/cgi-bin/go.cgi?page2 We have changed our web layout, so the URLs should now be: http://www.example1.com/page1.html and http://www.example1.com/page2.html How can we handle this with mod_rewrite so the old URLs still work? <VirtualHost *:80> ServerName www.example1.com ServerAlias example1.com DocumentRoot /opt/apache/www.example1.com CustomLog /opt/apache/logs/www.example1.com.log combined RewriteEngine On RewriteCond %{QUERY_STRING} ^page.+ RewriteRule ^(.+) /%{QUERY_STRING}.html </VirtualHost> In our RewriteCond line, we're looking at the value of the environment variable QUERY_STRING. The complete list of variables that you can query can be found in the mod_rewrite instructions at http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html and includes variables such as HTTP_USER_AGENT, REMOTE_USER, and REMOTE_HOST. In this case, we're interested in performing a rewrite only if our QUERY_STRING variable matches the regular expression: ^page.+ Again, this is similar to our last regular expression. The ^ means the start of the line, and the .+ means "match anything," so we will perform a rewrite only if our query string starts with page and has anything else after it. If that is the case, the RewriteRule will be executed. It says "replace any URL with /%{QUERY_STRING}.html." So a URL of the form http://www.example1.com/cgi-bin/go.cgi?page1 would be redirected to http://www.example1.com/page1.html. Be sure to watch the Apache log files when you are troubleshooting your mod_rewrite rules. The error_log file in particular will give you a good idea of exactly what is going on if Apache is not behaving as you think it should. 38.2.2.5. Apache performance tuningSo far, we have looked at how to install and configure the Apache web server. We have touched on many different options, including DSO, SSL, mod_php, and mod_rewrite. This final Apache section deals with performance tuning. The Apache web server process follows the common Unix parent/child model. When you start the Apache web server, you are starting a parent process. This parent process will spawn a number of children to handle incoming HTTP requests. If the number of web requests exceeds the number of children currently available, Apache will spawn more, up to a specified limit. As you can imagine, the spawning of new children while HTTP requests are pending not only places overhead on the web server itself, but can adversely affect the web browsing experience, as web surfers sit and wait for the web server to honor their request. There are a number of options that you can set in the global httpd.conf section to maximize the performance of your Apache install:
Performance tuning can be a challenge. Careful monitoring of your Apache installation is essential in order to identify what the correct values should be for the parameters listed in this section. For more information on Apache monitoring, the mod_status module can be very useful. You can read its documentation at http://httpd.apache.org/docs/1.3/mod/mod_status.html. |