Saturday, February 18, 2012

X-Forwarded-Host to X_FORWARDED_HOST in mod_wsgi..

Ever wondered how the parameters in Django's request.META, such as X-Forwarded-Host or X-Forwarded-For get set in the os.environ objects? The headers often get transformed to entire upper-case and the dashes get replaced by underscores (i.e. X-Forwarded-Host becomes X_FORWARDED_HOST). Most of the work gets done inside mod_wsgi.c using the wsgi_http2env() function.

static PyObject *Auth_environ(AuthObject *self, const char *group)
{
PyDict_SetItemString(vars, wsgi_http2env(r->pool, hdrs[i].key),
object);

The wsgi_http2env() function basically performs this conversion to HTTP environment variables:

static char *wsgi_http2env(apr_pool_t *a, const char *w)
{
char *res = (char *)apr_palloc(a, sizeof("HTTP_") + strlen(w));
char *cp = res;
char c;

*cp++ = 'H';
*cp++ = 'T';
*cp++ = 'T';
*cp++ = 'P';
*cp++ = '_';

while ((c = *w++) != 0) {
if (!apr_isalnum(c)) {
*cp++ = '_';
}
else {
*cp++ = apr_toupper(c);
}
}
*cp = 0;

return res;
}

1 comment:

  1. That is only true for mod_wsgi daemon mode. In embedded mode code in Apache does it.

    This is all done as WSGI uses CGI convention for how headers are represented in WSGI environ dictionary.

    ReplyDelete