## HOWTO: Compile and Install Unix, install in home directory: $ ./configure --prefix=$HOME/local --enable-so --enable-mods-shared=most Note: without --enable-mods-shared=XXX none of the modules get compiled! Unix, install in default (system) location: $ ./configure --enable-layout=Darwin --enable-so --enable-mods-shared=most SunOS: Apache installed into $HOME: $ lconfigure --with-apxs2=$LOCAL/bin/apxs --with-xsl=$LOCAL \ --with-libxml-dir=$LOCAL (May need to adjust the paths in the "LoadModule" commands by hand, though they may only get broken if installing PHP at the same.) (See php.txt for how to install PHP.) ## HOWTO: Install on Windows. 1. Use the installer, select the "custom" mode. 2. To install into e.g. c:\server\apache-2.2.4 (where httpd.exe is c:\server\apache-2.2.4\bin\httpd.exe), choose c:\server\apache-2.2.4 for the "Install to" (root) directory. (This used to be a lot more non-intuitive and complicated, but this seems to just work now.) (See php.txt for how to install PHP.) ## HOWTO: Rewrite URLs Based on Query String If you want to redirect: http://foo.com/foo/bar?name=quux to: http://foo.com/new/quux Use: RewriteCond %{REQUEST_URI} ^/foo/bar$ RewriteCond %{QUERY_STRING} ^name=(.+)$ RewriteRule .* /new/%1? [R] or RewriteCond %{QUERY_STRING} ^name=(.+)$ RewriteRule ^/foo/bar$ /new/%1? [R] The final question mark prevents the original query string from being appended, which otherwise happens via default. See the [mod_rewrite documentation](http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewriterule). (See the QSA option for more query string manipulation options.) ## HOWTO: Ensure Some URLs are Delivered via https # Rewrite https:// URLs that shouldn't be https (most of them) # to the http:// equivalent. If modifying this, remember images! # (The pattern on the second line has to match every URL that # is of content type text/html.) RewriteCond %{HTTPS} ^on$ RewriteCond %{REQUEST_URI} (\.html$|\/$) RewriteRule !(^join/join.html|^supportus/donate.html) http://%{SERVER_NAME}%{REQUEST_URI} [R] # Rewrite http:// URLs that should be https to the https:// # equivalent. (If running on www.artfund.org only.) RewriteCond %{HTTPS} ^off$ RewriteCond %{SERVER_NAME} ^www.artfund.org$ RewriteRule (^join/join.html|^supportus/donate.html) https://%{SERVER_NAME}%{REQUEST_URI} [R] ## GOTCHA: Can't Rewrite Encoded Question Marks or Slashes If you're having trouble rewriting characters like %3F (encoded question mark) or an encoded slash, you've hit a bug; see [the bug report](http://issues.apache.org/bugzilla/show_bug.cgi?id=34602#c16) for a workaround and associated discussion. ## HOWTO: Canonical Hostnames [Canonical host documentation](http://httpd.apache.org/docs/2.2/rewrite/rewrite_guide.html#canonicalhost) ## GOTCHA: mod_rewrite log File Isn't Written Even if you're editing the main httpd.conf, the RewriteLogLevel command needs to be issued from within a VirtualHost (or similar) directive. ## TIP: Directive are merged in which order? [Merge order documentation](http://httpd.apache.org/docs/2.2/sections.html#mergin) ## ERROR: "Cannot get media type" If the types specified in your Action and AddType lines don't actually look like MIME types, Apache will generate this error: # WRONG Action php-fastcgi /bin/test.fcgi AddType php-fastcgi php # RIGHT Action text/php-fastcgi /bin/test.fcgi AddType text/php-fastcgi php ## ERROR: "Negotiation: discovered file(s) matching request: ... (None could be negotiated)." This probably means you have MultiViews turned on accidentally via httpd.conf or .htaccess. Disable it. ## TIP: Userful environment variables when running PHP, mod_rewrite Suppose the following URL is requested: http://example.com/foo?name=Michael which is matched and rewritten via: RewriteRule ^foo$ /quux.php/baz?email=mjs@beebo.org [QSA] then the following are set based on the original request: SCRIPT_URL /foo SCRIPT_URI http://example.com/foo REQUEST_URI /foo?bar=quux SERVER_NAME example.com - from Apache HTTP_HOST example.com - from PHP and the following are set based on the rewritten request: PATH_INFO /baz QUERY_STRING name=Michael&email=mjs@beebo.org SCRIPT_NAME /quux.php - filesystem path (relative to docroot) SCRIPT_FILENAME /www/quux.php - filesystem path (absolute) PHP_SELF /quux.php/baz - filesystem path (relative to docroot) More information: * [http://hoohoo.ncsa.uiuc.edu/cgi/env.html](http://hoohoo.ncsa.uiuc.edu/cgi/env.html) * [http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#EnvVar](http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#EnvVar) * [http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewritecond](http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewritecond) * [http://php.net/manual/reserved.variables.html#reserved.variables.server](http://php.net/manual/reserved.variables.html#reserved.variables.server) ## ERROR: "Could not reliably determine the server's fully qualified domain name" Add a ServerName directive somewhere at the top level of your httpd.conf. i.e. not within a <VirtualHost> section. ## HOWTO: Proxy requests to/from another server For proxying to work, you need to have both the `mod_proxy_http` and `mod_proxy` modules loaded. Single URL: RewriteRule ^feedback/ http://example.com%{REQUEST_URI} [P] This transparently proxies all requests for URLs that begin with `/feedback/` to the `example.com` server. HTTP authentication, cookies, etc. all work. Entire site: ServerName wikileaks.beebo.org RewriteEngine On RewriteRule ^ http://88.80.13.160%{REQUEST_URI} [P] Allow from all ## ERROR: "NameVirtualHost *:80 has no VirtualHosts" This is pretty much as described; you get this error if, for example, you have: NameVirtualHost *:80 with no corresponding: Note that the rogue `NameVirtualHost` statement can appear in a file you're not expecting, like `/etc/apache2/ports.conf`. ## TIP: Virtual host configuration About virtual hosts: 1. The [`Listen`](http://httpd.apache.org/docs/2.2/mod/mpm_common.html#listen) directive controls what addresses and ports Apache will receive connections on. You probably want `Listen *:80`. 1. The [`NameVirtualHost`](http://httpd.apache.org/docs/2.2/mod/core.html#namevirtualhost) directive controls what addresses and ports Apache will use for virtual hosts. (A subset of whatever addresses and ports Apache is listening on.) You probably want `NameVirtualHost *`. 1. The argument to the `` block must exactly match the argument to `NameVirtualHost`. You probably want ``. There must also be a `ServerName` directive within the block. You should make sure that all hostnames that map to the current server are explicitly mentioned in a `ServerName` or `ServerAlias` line. If not, clients will get the site defined by the first section, which may not be the one you expect if Includes, etc. are being used. Listen 80 NameVirtualHost *:80 # If an IP address maps to this server, and it # *doesn't* match a ServerName or a ServerAlias, # the first section is used. ServerName beebo.org ServerAlias www.beebo.org # Redirect to canonical hostname. RewriteEngine On RewriteCond %{HTTP_HOST} !^beebo\.org [NC] RewriteCond %{HTTP_HOST} !^$ RewriteRule ^/(.*) http://beebo.org/$1 [L,R] ServerName dev.beebo.org # Redirect to canonical hostname. RewriteEngine On RewriteCond %{HTTP_HOST} !^dev\.beebo\.org [NC] RewriteCond %{HTTP_HOST} !^$ RewriteRule ^/(.*) http://dev.beebo.org/$1 [L,R] ## FAQ: Why does my `Alias` or `ScriptAlias` command not work? Try with and without trailing slashes; there are [some complicated rules that make them signification](http://httpd.apache.org/docs/2.2/mod/mod_alias.html). ## ERROR: "client denied by server configuration" A common cause of this error is Apache not being given explicit permission to server files from the directory in question. This can be fixed as follows: Order allow,deny Allow from all You may also get this error in conjunction with `RewriteRule`. If you're rewriting to something like `/bin/foo.php`, then even if loading `http://localhost/bin/foo.php` works, a rewrite to exactly the same file may not. I'm not sure if this is a bug or not, but it can be fixed by specifying the full path to the rewrite target. i.e. change: RewriteRule .? /bin/simple.php [L] to RewriteRule .? %{DOCUMENT_ROOT}/bin/simple.php [L] (It [seems that](http://discuss.joyent.com/viewtopic.php?id=14452) Apache checks to see if `/bin` on the filesystem exists, discovers that it does and then notices that you aren't allowed to access it.) (You may encounter this error if moving rules from a `.htaccess` to `httpd.conf`--the first works in the context of a `.htaccess`, but for some reason fails in `httpd.conf`.) ## ERROR: Address already in use: make_sock: could not bind to address 0.0.0.0:443 This can happen if another program is already listening on the port (use `sudo netstat -lp --numeric-ports` or `sudo lsof -i tcp:443` to see if this is the case), but it can also happen if your Apache configuration contains the same `Listen 443` line twice. ## FAQ: Having problems with `RewriteRule` and `REQUEST_FILENAME` in conjunction with `VirtualDocumentRoot` There seem to be some problems when using `RewriteRule` on `REQUEST_FILENAME` in conjunction with `VirtualDocumentRoot`. In particular, the the `REQUEST_FILENAME` appears to change, from one internal subrequest to another, you might be experiencing this problem. For example, if you see something like RewriteCond: input='/mnt/hgfs/workspace/kookai/mnt' pattern='!-f' => matched in the log where you were expecting something like RewriteCond: input='/mnt/hgfs/workspace/kookai/index.php' pattern='!-f' => matched Then the solution may be to change the `RewriteRule` from RewriteRule .* index.php [L] to RewriteRule .* /index.php [L] (I came across this problem when using Magento with rewrites turned on, in a `VirtualDocumentRoot` environment.)