Thursday, February 10, 2011

X-Forwarded-For vs. HTTP_X_FORWARDED_HOST vs. HTTP_HOST

X-Forwarded-For

http://en.wikipedia.org/wiki/X-Forwarded-For
The X-Forwarded-For (XFF) HTTP header field is a de facto standard for identifying the originating IP address of a client connecting to a web server through an HTTP proxy or load balancer. This is a non-RFC-standard request field which was introduced by the Squid caching proxy server's developers.

HTTP_X_FORWARDED_HOST

Apache's mod_proxy code inserts the HTTP_X_FORWARDED_HOST header for the originating host. Apache

modules/proxy/mod_proxy_http.c
/* Add X-Forwarded-Host: so that upstream knows what the
         * original request hostname was.
         */
        if ((buf = apr_table_get(r->headers_in, "Host"))) {
            apr_table_mergen(r->headers_in, "X-Forwarded-Host", buf);
        }

HTTP_HOST

http://stackoverflow.com/questions/4096151/how-reliable-is-http-host
HTTP_HOST is for the Host: header sent by HTTP 1.1 user-agents during the request. This is not used by HTTP 1.0 clients, so it won't appear then. However, nowadays, I don't think there are still many HTTP 1.0 clients.
Contents of the Host: header from the current request, if there is one.

http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
The Host request-header field specifies the Internet host and port number of the resource being requested, as obtained from the original URI given by the user or referring resource (generally an HTTP URL, as described in section 3.2.2). The Host field value MUST represent the naming authority of the origin server or gateway given by the original URL. This allows the origin server or gateway to differentiate between internally-ambiguous URLs, such as the root "/" URL of a server for multiple host names on a single IP address.

Host = "Host" ":" host [ ":" port ] ; Section 3.2.2
A "host" without any trailing port information implies the default port for the service requested (e.g., "80" for an HTTP URL). For example, a request on the origin server for  would properly include:

GET /pub/WWW/ HTTP/1.1
Host: www.w3.org

A client MUST include a Host header field in all HTTP/1.1 request messages . If the requested URI does not include an Internet host name for the service being requested, then the Host header field MUST be given with an empty value. An HTTP/1.1 proxy MUST ensure that any request message it forwards does contain an appropriate Host header field that identifies the service being requested by the proxy. All Internet-based HTTP/1.1 servers MUST respond with a 400 (Bad Request) status code to any HTTP/1.1 request message which lacks a Host header field.

See sections 5.2 and 19.6.1.1 for other requirements relating to Host.

mod_wsgi will then set HTTP_HOST from the Host: header

mod_wsgi.c:
 if (apr_table_get(r->subprocess_env, "HTTP_HOST")) {
        apr_table_setn(r->headers_in, "Host",
                       apr_table_get(r->subprocess_env, "HTTP_HOST"));
    }

No comments:

Post a Comment