added: config: base_url_redirect

when true the server checks whether HTTP_HOST environment variable
       is the same as base_url from the config (of course without the 'http://' part
       and the last slash) - if it's not the same then the server
       redirects you into a new location base_url+REQUEST_URI
changed: variables env_* from Request are never null (after Request::Read())
       if the server didn't set such a variable it will be pointing into an empty string "\0"


git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@465 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
Tomasz Sowa 2008-12-12 03:11:29 +00:00
parent 3462cdf827
commit 023faa66fc
8 changed files with 109 additions and 26 deletions

View File

@ -68,6 +68,8 @@ bool Config::ReadConfig(bool errors_to_stdout_)
if( status == ConfParser::ok )
{
AssignValues();
data.SetAdditionalVariables();
return true;
}
else

View File

@ -21,3 +21,27 @@ Data::Data()
void Data::SetAdditionalVariables()
{
SetHttpHost();
}
void Data::SetHttpHost()
{
if( strncmp(base_url.c_str(), "http://", 7) == 0 )
base_url_http_host = base_url.substr(7);
else
if( strncmp(base_url.c_str(), "https://", 8) == 0 )
base_url_http_host = base_url.substr(8);
else
base_url_http_host.clear();
if( base_url_http_host.empty() )
return;
// removing the last slash (if it is present)
if( base_url_http_host[ base_url_http_host.size() - 1 ] == '/' )
base_url_http_host.erase( base_url_http_host.end() - 1 );
}

View File

@ -13,6 +13,7 @@
#include <string>
#include <vector>
#include <map>
#include <string.h>
#include "misc.h"
#include "item.h"
@ -64,6 +65,11 @@ public:
std::string base_url;
std::string http_session_id_name;
// when the HOST_HTTP environment variable doesn't point into 'base_url' (the part 'http://' and the last slash is removed)
// the server will redirect into 'base_url' + 'REQUEST_URI'
// it's useful when you want to redirect from 'mydomain.tld' into 'www.mydomain.tld' etc.
bool base_url_redirect;
// if there is one item in a directory
// it will be showed
// (instead of showing directory contents)
@ -73,21 +79,29 @@ public:
// end config members
// -----------------------------------------------------------------
// false at the beginning
bool stdout_is_closed;
// true if there was the SIGHUP signal
// true if there was SIGHUP signal
volatile bool signal_hup;
// contains current directories tree
Dir dir;
// based on base_url
// set by SetAdditionalVariables()
std::string base_url_http_host;
// call this method after the config file is read
void SetAdditionalVariables();
Data();
private:
void SetHttpHost();
};

View File

@ -11,7 +11,7 @@
Request::Request()
Request::Request() : char_empty(0)
{
Clear();
}
@ -31,9 +31,12 @@ void Request::Clear()
page.str("");
debug.str("");
env_request_method = 0;
env_request_uri = 0;
env_http_cookie = 0;
env_request_method = &char_empty;
env_request_uri = &char_empty;
env_http_cookie = &char_empty;
env_remote_addr = &char_empty;
env_http_host = &char_empty;
session = 0;
@ -176,15 +179,29 @@ int len;
const char * Request::SetEnvVar(const char * var)
{
const char * v = FCGX_GetParam(var, env);
if( v )
return v;
// char_empty contains '\0'
return &char_empty;
}
void Request::ReadEnvVariables()
{
// we store that values because FCGX_GetParam has O(n) complexity
// with this variables (env_*) we have O(1)
env_request_method = FCGX_GetParam("REQUEST_METHOD", env);
env_request_uri = FCGX_GetParam("REQUEST_URI", env);
env_http_cookie = FCGX_GetParam("HTTP_COOKIE", env);
env_remote_addr = FCGX_GetParam("REMOTE_ADDR", env);
env_request_method = SetEnvVar("REQUEST_METHOD");
env_request_uri = SetEnvVar("REQUEST_URI");
env_http_cookie = SetEnvVar("HTTP_COOKIE");
env_remote_addr = SetEnvVar("REMOTE_ADDR");
env_http_host = SetEnvVar("HTTP_HOST");
log << log1 << "IP: " << env_remote_addr << logend;
}
@ -194,9 +211,6 @@ void Request::ReadEnvVariables()
void Request::CheckMethod()
{
method = none;
if( !env_request_method )
return;
if( env_request_method[0] == 'G' )
method = get;

View File

@ -41,11 +41,13 @@ struct Request
PostTable post_table;
CookieTable cookie_table;
// environment variables (can be null)
// environment variables
// they are not null -- when the server doesn't have such a variable it will be pointing into 'char_empty' which is default '\0'
const char * env_request_method;
const char * env_request_uri;
const char * env_http_cookie;
const char * env_remote_addr;
const char * env_http_host;
// current session
// is set after calling session_manager.SetSession()
@ -107,6 +109,12 @@ struct Request
void SendAll();
private:
// used to set some env_* variables into it, when the server didn't set that variable
// it contains '\0'
const char char_empty;
const char * SetEnvVar(const char * var);
};

View File

@ -109,6 +109,23 @@ return true;
bool RequestController::BaseUrlRedirect()
{
if( request.env_request_uri[0] == 0 )
return false;
if( data.base_url_http_host == request.env_http_host )
return false;
request.result = Request::redirect;
request.str = data.base_url + (request.env_request_uri + 1); // +1 means skipping the first slash from env_request_uri
return true;
}
void RequestController::Loop()
{
while( FCGX_Accept(&request.in, &request.out, &request.err, &request.env) == 0 )
@ -119,13 +136,19 @@ void RequestController::Loop()
{
request.Clear();
request.Read();
session_manager.SetSession(); // setting request.session as well
request.session->CheckTimers();
content.Make();
// when BaseUrlRedirect() return true we didn't have to set everything in request.Read()
// in the future request.Read() can be split and at the beginning only environment variables will be read
// and then BaseUrlRedirect() will be called (for performance)
if( !BaseUrlRedirect() )
{
session_manager.SetSession(); // setting request.session as well
request.session->CheckTimers();
content.Make();
}
request.SendAll();
}
catch(const std::exception & e)
{

View File

@ -32,6 +32,7 @@ class RequestController
Content content;
SessionManager session_manager;
bool BaseUrlRedirect();
public:

View File

@ -109,10 +109,7 @@ void base_url(Info & i)
void current_url(Info & i)
{
if( request.env_request_uri )
i.out << request.env_request_uri;
else
base_url(i);
i.out << request.env_request_uri;
}