From 023faa66fc641c0b54a73991903b846578aabd09 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Fri, 12 Dec 2008 03:11:29 +0000 Subject: [PATCH] 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 --- core/config.cpp | 2 ++ core/data.cpp | 24 ++++++++++++++++++++++++ core/data.h | 22 ++++++++++++++++++---- core/request.cpp | 36 +++++++++++++++++++++++++----------- core/request.h | 10 +++++++++- core/requestcontroller.cpp | 35 +++++++++++++++++++++++++++++------ core/requestcontroller.h | 1 + core/templates.cpp | 5 +---- 8 files changed, 109 insertions(+), 26 deletions(-) diff --git a/core/config.cpp b/core/config.cpp index 6b7db51..df36c10 100755 --- a/core/config.cpp +++ b/core/config.cpp @@ -68,6 +68,8 @@ bool Config::ReadConfig(bool errors_to_stdout_) if( status == ConfParser::ok ) { AssignValues(); + + data.SetAdditionalVariables(); return true; } else diff --git a/core/data.cpp b/core/data.cpp index 787a59c..bf145e5 100755 --- a/core/data.cpp +++ b/core/data.cpp @@ -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 ); +} diff --git a/core/data.h b/core/data.h index 8eee011..00ede86 100755 --- a/core/data.h +++ b/core/data.h @@ -13,6 +13,7 @@ #include #include #include +#include #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(); }; diff --git a/core/request.cpp b/core/request.cpp index 70a3612..660fabf 100755 --- a/core/request.cpp +++ b/core/request.cpp @@ -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; diff --git a/core/request.h b/core/request.h index decbe01..649f7f0 100755 --- a/core/request.h +++ b/core/request.h @@ -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); }; diff --git a/core/requestcontroller.cpp b/core/requestcontroller.cpp index 2c67bde..b2527cc 100755 --- a/core/requestcontroller.cpp +++ b/core/requestcontroller.cpp @@ -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) { diff --git a/core/requestcontroller.h b/core/requestcontroller.h index 9cb570b..9a56598 100755 --- a/core/requestcontroller.h +++ b/core/requestcontroller.h @@ -32,6 +32,7 @@ class RequestController Content content; SessionManager session_manager; + bool BaseUrlRedirect(); public: diff --git a/core/templates.cpp b/core/templates.cpp index aa34026..5b1e7ee 100755 --- a/core/templates.cpp +++ b/core/templates.cpp @@ -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; }