view xml/en/docs/http/request_processing.xml @ 74:e9948ec6286b

Removed the pre-0.7.11 tip for "How to prevent processing requests with undefined server names".
author Ruslan Ermilov <ru@nginx.com>
date Mon, 10 Oct 2011 09:39:11 +0000
parents 6327603448e2
children 49443032011c
line wrap: on
line source

<!DOCTYPE article SYSTEM "../../../../dtd/article.dtd">

<article title="How nginx processes a request"
         link="/en/docs/http/request_processing.html"
         lang="en"
         author="Igor Sysoev"
         editor="Brian Mercer">


<section title="Name-based virtual servers">

<para>
nginx first decides which <i>server</i> should process the request.
Let&rsquo;s start with a simple configuration
where all three virtual servers listen on port *:80:

<programlisting>
server {
    listen       80;
    server_name  nginx.org  www.nginx.org;
    ...
}

server {
    listen       80;
    server_name  nginx.net  www.nginx.net;
    ...
}

server {
    listen       80;
    server_name  nginx.com  www.nginx.com;
    ...
}
</programlisting>
</para>

<para>
In this configuration nginx tests only the request&rsquo;s header line
&ldquo;Host&rdquo; to determine which server the request should be routed to.
If the &ldquo;Host&rdquo; header line does not match any server name,
or the request does not contain this line at all,
then nginx will route the request to the default server.
In the configuration above, the default server is the first
one&mdash;which is nginx&rsquo;s standard default behaviour.
If you do not want the first server listed to be the default server,
you may set it explicitly with the <dirname>default_server</dirname> parameter
in the <dirname>listen</dirname> directive:

<programlisting>
server {
    listen       80  <b>default_server</b>;
    server_name  nginx.net  www.nginx.net;
    ...
}
</programlisting>

<note>
The <dirname>default_server</dirname> parameter has been available since
version 0.8.21.
In earlier versions the <dirname>default</dirname> parameter should be used
instead.
</note>

Note that the default server is a property of the listen port
and not of the server name. More about this later.
</para>

</section>


<section name="how_to_prevent_undefined_server_names"
        title="How to prevent processing requests with undefined server names">

<para>
If you do not want to process requests without the <header>Host</header>
header line, you may define a server that just drops the requests:

<programlisting>
server {
    listen       80;
    server_name  "";
    return       444;
}
</programlisting>

Here, the server name is set to an empty string which will match
requests without the <header>Host</header> header line,
and a special nginx’s non-standard code 444
is returned that closes the connection.
Since version 0.8.48, this is the default setting for the
server name, so the <code>server_name ""</code> can be omitted.
In earlier versions, the machine's <i>hostname</i> was used as
a default server name.
</para>

</section>


<section name="mixed_name_ip_based_servers"
        title="Mixed name-based and IP-based virtual servers">

<para>
Let&rsquo;s look at a more complex configuration
where some virtual servers listen on different addresses:

<programlisting>
server {
    listen       192.168.1.1:80;
    server_name  nginx.org  www.nginx.org;
    ...
}

server {
    listen       192.168.1.1:80;
    server_name  nginx.net  www.nginx.net;
    ...
}

server {
    listen       192.168.1.2:80;
    server_name  nginx.com  www.nginx.com;
    ...
}
</programlisting>

In this configuration, nginx first tests the IP address and port
of the request against the <dirname>listen</dirname> directives
of the <dirname>server</dirname> blocks. It then tests the &ldquo;Host&rdquo;
header line of the request against the <dirname>server_name</dirname>
entries of the <dirname>server</dirname> blocks that matched
the IP address and port.

If the server name is not found, the request will be processed by
the default server.
For example, a request for <url>www.nginx.com</url> received on
the 192.168.1.1:80 port will be handled by the default server
of the 192.168.1.1:80 port, i.e., by the first server,
since there is no <url>www.nginx.com</url> defined for this port.
</para>

<para>
As already stated, a default server is a property of the listen port
and different default servers may be defined for different listen ports:

<programlisting>
server {
    listen        192.168.1.1:80;
    server_name   nginx.org  www.nginx.org;
    ...
}

server {
    listen        192.168.1.1:80  default_server;
    server_name   nginx.net  www.nginx.net;
    ...
}

server {
    listen        192.168.1.2:80  default_server;
    server_name   nginx.com  www.nginx.com;
    ...
}
</programlisting>
</para>

</section>


<section name="simple_php_site_configuration"
        title="A simple PHP site configuration">

<para>
Now let&rsquo;s look at how nginx chooses a <i>location</i> to process a request
for a typical, simple PHP site:

<programlisting>
server {
    listen        80;
    server_name   nginx.org  www.nginx.org;
    root          /data/www;

    location / {
        index     index.html  index.php;
    }

    location ~* \.(gif|jpg|png)$ {
        expires   30d;
    }

    location ~ \.php$ {
        fastcgi_pass   localhost:9000;
        fastcgi_param  SCRIPT_FILENAME
                       $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }
}
</programlisting>
</para>

<para>
nginx first searches for the most specific location given by literal strings
regardless of the listed order. In the configuration above
the only literal location is <path>/</path> and since it matches
any request it will be used as a last resort.
Then nginx checks locations given by
regular expression in the order listed in the configuration file.
The first matching expression stops the search and nginx will use this
location. If no regular expression matches a request, then nginx uses
the most specific literal location found earlier.
</para>

<para>
Note that locations of all types test only a request URI part without a query
string. This is done because arguments in the query string may be given in
several ways, for example:

<programlisting>
/index.php?user=john&amp;page=1
/index.php?page=1&amp;user=john
</programlisting>

Besides, anyone may request anything in the query string:

<programlisting>
/index.php?page=1&amp;something+else&amp;user=john
</programlisting>
</para>

<para>
Now let&rsquo;s look at how requests would be processed
in the configuration above:

<list>

<item>
<para>
A request <path>/logo.gif</path> is matched by the literal location
<dirname>/</dirname> first and then by the regular expression
<dirname>\.(gif|jpg|png)$</dirname>,
therefore, it is handled by the latter location.
Using the directive <dirname>root&nbsp;/data/www</dirname> the request
is mapped to a file <path>/data/www/logo.gif</path>, and the file
is sent to the client.
</para>
</item>

<item>
<para>
A request <path>/index.php</path> is also matched by the literal location
<dirname>/</dirname> first and then by the regular expression
<dirname>\.(php)$</dirname>. Therefore, it is handled by the latter location
and the request is passed to a FastCGI server listening on localhost:9000.
The <dirname>fastcgi_param</dirname> directive sets the FastCGI parameter
SCRIPT_FILENAME to <path>/data/www/index.php</path>,
and the FastCGI server executes the file.
The variable $document_root is equal to
the value of the <dirname>root</dirname> directive and
the variable $fastcgi_script_name is equal to the request URI,
i.e. <path>/index.php</path>.
</para>
</item>

<item>
<para>
A request <path>/about.html</path> is matched by the literal location
<dirname>/</dirname> only, therefore, it is handled in this location.
Using the directive <dirname>root /data/www</dirname> the request is mapped
to the file <path>/data/www/about.html</path>, and the file is sent
to the client.
</para>
</item>

<item>
<para>
Handling a request <path>/</path> is more complex.
It is matched by the literal location <dirname>/</dirname> only,
therefore, it is handled by this location.
Then the <dirname>index</dirname> directive tests for the existence
of an index file according to its parameters and
the <dirname>root&nbsp;/data/www</dirname> directive.
If a file <path>/data/www/index.php</path> exists,
then the directive does an internal redirect to <path>/index.php</path>, and
nginx searches the locations again as if the request had been sent by a client.
As we saw before, the redirected request will eventually be handled
by the FastCGI server.
</para>
</item>

</list>
</para>

</section>

</article>