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:
parent
3462cdf827
commit
023faa66fc
|
@ -68,6 +68,8 @@ bool Config::ReadConfig(bool errors_to_stdout_)
|
||||||
if( status == ConfParser::ok )
|
if( status == ConfParser::ok )
|
||||||
{
|
{
|
||||||
AssignValues();
|
AssignValues();
|
||||||
|
|
||||||
|
data.SetAdditionalVariables();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -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 );
|
||||||
|
}
|
||||||
|
|
22
core/data.h
22
core/data.h
|
@ -13,6 +13,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "item.h"
|
#include "item.h"
|
||||||
|
@ -64,6 +65,11 @@ public:
|
||||||
std::string base_url;
|
std::string base_url;
|
||||||
std::string http_session_id_name;
|
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
|
// if there is one item in a directory
|
||||||
// it will be showed
|
// it will be showed
|
||||||
// (instead of showing directory contents)
|
// (instead of showing directory contents)
|
||||||
|
@ -73,21 +79,29 @@ public:
|
||||||
// end config members
|
// end config members
|
||||||
// -----------------------------------------------------------------
|
// -----------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// false at the beginning
|
// false at the beginning
|
||||||
bool stdout_is_closed;
|
bool stdout_is_closed;
|
||||||
|
|
||||||
// true if there was the SIGHUP signal
|
// true if there was SIGHUP signal
|
||||||
volatile bool signal_hup;
|
volatile bool signal_hup;
|
||||||
|
|
||||||
|
// contains current directories tree
|
||||||
Dir dir;
|
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();
|
Data();
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
void SetHttpHost();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Request::Request()
|
Request::Request() : char_empty(0)
|
||||||
{
|
{
|
||||||
Clear();
|
Clear();
|
||||||
}
|
}
|
||||||
|
@ -31,9 +31,12 @@ void Request::Clear()
|
||||||
page.str("");
|
page.str("");
|
||||||
debug.str("");
|
debug.str("");
|
||||||
|
|
||||||
env_request_method = 0;
|
env_request_method = &char_empty;
|
||||||
env_request_uri = 0;
|
env_request_uri = &char_empty;
|
||||||
env_http_cookie = 0;
|
env_http_cookie = &char_empty;
|
||||||
|
env_remote_addr = &char_empty;
|
||||||
|
env_http_host = &char_empty;
|
||||||
|
|
||||||
|
|
||||||
session = 0;
|
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()
|
void Request::ReadEnvVariables()
|
||||||
{
|
{
|
||||||
// we store that values because FCGX_GetParam has O(n) complexity
|
// we store that values because FCGX_GetParam has O(n) complexity
|
||||||
// with this variables (env_*) we have O(1)
|
// with this variables (env_*) we have O(1)
|
||||||
|
|
||||||
env_request_method = FCGX_GetParam("REQUEST_METHOD", env);
|
env_request_method = SetEnvVar("REQUEST_METHOD");
|
||||||
env_request_uri = FCGX_GetParam("REQUEST_URI", env);
|
env_request_uri = SetEnvVar("REQUEST_URI");
|
||||||
env_http_cookie = FCGX_GetParam("HTTP_COOKIE", env);
|
env_http_cookie = SetEnvVar("HTTP_COOKIE");
|
||||||
env_remote_addr = FCGX_GetParam("REMOTE_ADDR", env);
|
env_remote_addr = SetEnvVar("REMOTE_ADDR");
|
||||||
|
env_http_host = SetEnvVar("HTTP_HOST");
|
||||||
|
|
||||||
log << log1 << "IP: " << env_remote_addr << logend;
|
log << log1 << "IP: " << env_remote_addr << logend;
|
||||||
}
|
}
|
||||||
|
@ -194,9 +211,6 @@ void Request::ReadEnvVariables()
|
||||||
void Request::CheckMethod()
|
void Request::CheckMethod()
|
||||||
{
|
{
|
||||||
method = none;
|
method = none;
|
||||||
|
|
||||||
if( !env_request_method )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if( env_request_method[0] == 'G' )
|
if( env_request_method[0] == 'G' )
|
||||||
method = get;
|
method = get;
|
||||||
|
|
|
@ -41,11 +41,13 @@ struct Request
|
||||||
PostTable post_table;
|
PostTable post_table;
|
||||||
CookieTable cookie_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_method;
|
||||||
const char * env_request_uri;
|
const char * env_request_uri;
|
||||||
const char * env_http_cookie;
|
const char * env_http_cookie;
|
||||||
const char * env_remote_addr;
|
const char * env_remote_addr;
|
||||||
|
const char * env_http_host;
|
||||||
|
|
||||||
// current session
|
// current session
|
||||||
// is set after calling session_manager.SetSession()
|
// is set after calling session_manager.SetSession()
|
||||||
|
@ -107,6 +109,12 @@ struct Request
|
||||||
void SendAll();
|
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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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()
|
void RequestController::Loop()
|
||||||
{
|
{
|
||||||
while( FCGX_Accept(&request.in, &request.out, &request.err, &request.env) == 0 )
|
while( FCGX_Accept(&request.in, &request.out, &request.err, &request.env) == 0 )
|
||||||
|
@ -119,13 +136,19 @@ void RequestController::Loop()
|
||||||
{
|
{
|
||||||
request.Clear();
|
request.Clear();
|
||||||
request.Read();
|
request.Read();
|
||||||
|
|
||||||
session_manager.SetSession(); // setting request.session as well
|
// when BaseUrlRedirect() return true we didn't have to set everything in request.Read()
|
||||||
request.session->CheckTimers();
|
// 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)
|
||||||
content.Make();
|
if( !BaseUrlRedirect() )
|
||||||
|
{
|
||||||
|
session_manager.SetSession(); // setting request.session as well
|
||||||
|
request.session->CheckTimers();
|
||||||
|
|
||||||
|
content.Make();
|
||||||
|
}
|
||||||
|
|
||||||
request.SendAll();
|
request.SendAll();
|
||||||
|
|
||||||
}
|
}
|
||||||
catch(const std::exception & e)
|
catch(const std::exception & e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -32,6 +32,7 @@ class RequestController
|
||||||
Content content;
|
Content content;
|
||||||
SessionManager session_manager;
|
SessionManager session_manager;
|
||||||
|
|
||||||
|
bool BaseUrlRedirect();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -109,10 +109,7 @@ void base_url(Info & i)
|
||||||
|
|
||||||
void current_url(Info & i)
|
void current_url(Info & i)
|
||||||
{
|
{
|
||||||
if( request.env_request_uri )
|
i.out << request.env_request_uri;
|
||||||
i.out << request.env_request_uri;
|
|
||||||
else
|
|
||||||
base_url(i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue