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 )
|
||||
{
|
||||
AssignValues();
|
||||
|
||||
data.SetAdditionalVariables();
|
||||
return true;
|
||||
}
|
||||
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 <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();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -32,6 +32,7 @@ class RequestController
|
|||
Content content;
|
||||
SessionManager session_manager;
|
||||
|
||||
bool BaseUrlRedirect();
|
||||
|
||||
public:
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue