fixed: dots in url-es (now only one dot is available in the whole name and it cannot be only one dot ".")

added:   cmslu can act as an authorizer (fast cgi authorize role)
added:   Item::static_auth we can have additional static content on the file system
         this content is authorized through cmslu (fastcgi authorizer mode)
changed: some changes in config
changed: the way how the www server is using cmslu
         added new virtuals: static static_auth
changed: cmslu returns correct http headers (200, 404, 403)
changed: in cookie parser: we get the last cookie (if the server has more than one cookie with the same name)



git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@540 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
Tomasz Sowa 2009-12-30 20:46:12 +00:00
parent 118bf1fc65
commit 60fccea703
23 changed files with 431 additions and 128 deletions

View File

@ -107,15 +107,31 @@ void Content::SetDefaultFunction()
void Content::MakeStandardFunction() void Content::MakeStandardFunction()
{ {
if( request.role == Request::authorizer )
{
// in authorizer mode only cat function is available
// (and must be default)
if( request.pfunction )
{
request.status = Error::db_no_item;
log << log1 << "Content: in authorizer mode only 'cat' funtion is available and must "
"be default (not in the url)" << logend;
return;
}
request.pfunction = data.functions.GetFunction(FUN_CAT);
}
if( !request.pfunction ) if( !request.pfunction )
SetDefaultFunction(); SetDefaultFunction();
if( !request.redirect_to.empty() ) if( !request.redirect_to.empty() )
return; return;
if( !request.pfunction ) if( !request.pfunction )
{ {
request.status = Error::no_function;
log << log1 << "Content: no function (neither cat nor ls)" << logend; log << log1 << "Content: no function (neither cat nor ls)" << logend;
return; return;
} }
@ -176,17 +192,22 @@ void Content::MakeStandardFunction()
void Content::MakePost() void Content::MakePost()
{ {
if( request.role == Request::authorizer )
{
request.status = Error::permision_denied;
return;
}
if( !request.pfunction ) if( !request.pfunction )
SetDefaultFunction(); SetDefaultFunction();
if( !request.pfunction ) if( !request.pfunction )
{ {
log << log1 << "Content: MakePost: no function" << logend;
request.status = Error::no_function; request.status = Error::no_function;
log << log1 << "Content: MakePost: no function" << logend;
return; return;
} }
switch( request.pfunction->code ) switch( request.pfunction->code )
{ {
case FUN_RUN: case FUN_RUN:
@ -355,7 +376,7 @@ void Content::PrepareUrl(Item & item)
if( item.url.empty() ) if( item.url.empty() )
item.url = item.subject; // if the subject is empty then the url will be corrected by CorrectUrl() item.url = item.subject; // if the subject is empty then the url will be corrected by CorrectUrl()
CorrectUrl(item); CorrectUrlOnlyAllowedChar(item.url);
if( data.functions.GetFunction(item.url) ) if( data.functions.GetFunction(item.url) )
{ {

View File

@ -7,7 +7,7 @@ config.o: dircontainer.h users.h user.h ugcontainer.h groups.h group.h
config.o: functions.h function.h lastcontainer.h mounts.h mount.h rebus.h config.o: functions.h function.h lastcontainer.h mounts.h mount.h rebus.h
config.o: plugin.h request.h requesttypes.h session.h done.h error.h thread.h config.o: plugin.h request.h requesttypes.h session.h done.h error.h thread.h
config.o: compress.h acceptencodingparser.h acceptbaseparser.h htmlfilter.h config.o: compress.h acceptencodingparser.h acceptbaseparser.h htmlfilter.h
config.o: pluginmsg.h config.o: pluginmsg.h misc.h
data.o: data.h dirs.h item.h dircontainer.h users.h user.h ugcontainer.h data.o: data.h dirs.h item.h dircontainer.h users.h user.h ugcontainer.h
data.o: log.h groups.h group.h functions.h function.h lastcontainer.h data.o: log.h groups.h group.h functions.h function.h lastcontainer.h
data.o: mounts.h mount.h rebus.h data.o: mounts.h mount.h rebus.h
@ -36,7 +36,9 @@ htmlfilter.o: htmlfilter.h
httpsimpleparser.o: httpsimpleparser.h httpsimpleparser.o: httpsimpleparser.h
lastcontainer.o: lastcontainer.h log.h lastcontainer.o: lastcontainer.h log.h
log.o: log.h log.o: log.h
misc.o: misc.h item.h log.h misc.o: misc.h item.h log.h data.h dirs.h dircontainer.h users.h user.h
misc.o: ugcontainer.h groups.h group.h functions.h function.h lastcontainer.h
misc.o: mounts.h mount.h rebus.h
mount.o: mount.h mount.o: mount.h
mountparser.o: mountparser.h mount.h item.h error.h log.h data.h dirs.h mountparser.o: mountparser.h mount.h item.h error.h log.h data.h dirs.h
mountparser.o: dircontainer.h users.h user.h ugcontainer.h groups.h group.h mountparser.o: dircontainer.h users.h user.h ugcontainer.h groups.h group.h

View File

@ -11,6 +11,7 @@
#include "log.h" #include "log.h"
#include "data.h" #include "data.h"
#include "plugin.h" #include "plugin.h"
#include "misc.h"
Config::Config() Config::Config()
@ -109,9 +110,19 @@ void Config::AssignValues()
data.db_database = Text("db_database"); data.db_database = Text("db_database");
data.db_user = Text("db_user"); data.db_user = Text("db_user");
data.db_pass = Text("db_pass"); data.db_pass = Text("db_pass");
data.base_url = Text("base_url"); data.item_url_empty = Text("item_url_empty");
NoLastSlash(data.base_url); data.base_server = Text("base_server");
data.base_url_prefix = Text("base_url_prefix");
data.base_url_static_prefix = Text("base_url_static_prefix");
data.base_url_static_auth_prefix = Text("base_url_static_auth_prefix");
NoLastSlash(data.base_server);
NoFirstHttp(data.base_server);
data.base_url = data.base_url_prefix + data.base_server;
data.base_url_static = data.base_url_static_prefix + data.base_server;
data.base_url_static_auth = data.base_url_static_auth_prefix + data.base_server;
data.one_item_is_showed = Bool("one_item_is_showed"); data.one_item_is_showed = Bool("one_item_is_showed");
@ -199,18 +210,34 @@ void Config::NoLastSlash(std::string & s)
if( s.empty() ) if( s.empty() )
return; return;
log << log2 << "Config: removing the last slash from: " << s << logend;
if( *(--s.end()) == '/' ) if( *(--s.end()) == '/' )
s.erase(--s.end()); s.erase(--s.end());
} }
void Config::NoFirstHttp(std::string & s)
{
if( s.empty() )
return;
const char http[] = "http://";
const char https[] = "https://";
if( IsSubStringNoCase(http, s.c_str()) )
{
s.erase(0, sizeof(http)/sizeof(char));
}
else
if( IsSubStringNoCase(https, s.c_str()) )
{
s.erase(0, sizeof(https)/sizeof(char));
}
}

View File

@ -45,7 +45,8 @@ private:
bool errors_to_stdout; bool errors_to_stdout;
void NoLastSlash(std::string & s); void NoLastSlash(std::string & s);
void NoFirstHttp(std::string & s);
}; };

View File

@ -46,9 +46,12 @@ protected:
log << log2 << "Cookie, name: \"" << name << "\", value: \"" << value << "\""; log << log2 << "Cookie, name: \"" << name << "\", value: \"" << value << "\"";
if( res.second == false ) if( res.second == false )
log << log2 << " (skipped)"; {
res.first->second = value;
log << " (overwritten)";
}
log << log2 << logend; log << logend;
} }

View File

@ -25,18 +25,19 @@ Data::Data()
void Data::SetAdditionalVariables() void Data::SetAdditionalVariables()
{ {
SetHttpHost(); SetHttpHost(base_url, base_url_http_host);
SetHttpHost(base_url_static_auth, base_url_static_auth_http_host);
} }
void Data::SetHttpHost() void Data::SetHttpHost(const std::string & in, std::string & out)
{ {
if( strncmp(base_url.c_str(), "http://", 7) == 0 ) if( strncmp(in.c_str(), "http://", 7) == 0 )
base_url_http_host = base_url.substr(7); out = in.substr(7);
else else
if( strncmp(base_url.c_str(), "https://", 8) == 0 ) if( strncmp(in.c_str(), "https://", 8) == 0 )
base_url_http_host = base_url.substr(8); out = in.substr(8);
else else
base_url_http_host.clear(); // if empty the RequestController::BaseUrlRedirect() returns false and no redirecting will be done out.clear(); // if empty the RequestController::BaseUrlRedirect() returns false and no redirecting will be done
} }

View File

@ -64,7 +64,12 @@ public:
std::string db_database; std::string db_database;
std::string db_user; std::string db_user;
std::string db_pass; std::string db_pass;
std::string base_url;
std::string base_server;
std::string base_url_prefix;
std::string base_url_static_prefix;
std::string base_url_static_auth_prefix;
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) // when the HOST_HTTP environment variable doesn't point into 'base_url' (the part 'http://' and the last slash is removed)
@ -101,10 +106,25 @@ public:
// the html code is cleaned by our filter // the html code is cleaned by our filter
bool html_filter; bool html_filter;
// the url of a new empty item (if there is not the subject too)
std::string item_url_empty;
// below variables are based on the other config variables
// base_url_prefix + base_server
std::string base_url;
// base_url_static_prefix + base_server
std::string base_url_static;
// base_url_static_auth_prefix + base_server
std::string base_url_static_auth;
// end config members // end config members
// ----------------------------------------------------------------- // -----------------------------------------------------------------
// false at the beginning // false at the beginning
bool stdout_is_closed; bool stdout_is_closed;
@ -116,7 +136,11 @@ public:
// based on base_url // based on base_url
// set by SetAdditionalVariables() // set by SetAdditionalVariables()
// without the first part http:// (or https://) or the whole string is empty
std::string base_url_http_host; std::string base_url_http_host;
std::string base_url_static_auth_http_host;
// call this method after the config file is read // call this method after the config file is read
void SetAdditionalVariables(); void SetAdditionalVariables();
@ -146,7 +170,7 @@ public:
private: private:
void SetHttpHost(); void SetHttpHost(const std::string & in, std::string & out);
}; };

View File

@ -420,7 +420,8 @@ Error Db::AddItemIntoItem(Item & item)
{ {
AssertConnection(); AssertConnection();
std::ostringstream query; std::ostringstream query;
query << "insert into core.item (user_id, group_id, privileges, date_creation, date_modification, type, parent_id, content_id, default_item, subject, guest_name, url) values ("; query << "insert into core.item (user_id, group_id, privileges, date_creation, date_modification, type, "
"parent_id, content_id, static_auth, default_item, subject, guest_name, url) values (";
query << '\'' << item.user_id << "', "; query << '\'' << item.user_id << "', ";
query << '\'' << item.group_id << "', "; query << '\'' << item.group_id << "', ";
query << '\'' << item.privileges << "', "; query << '\'' << item.privileges << "', ";
@ -429,9 +430,11 @@ Error Db::AddItemIntoItem(Item & item)
query << '\'' << static_cast<int>(item.type) << "', "; query << '\'' << static_cast<int>(item.type) << "', ";
query << '\'' << item.parent_id << "', "; query << '\'' << item.parent_id << "', ";
query << '\'' << item.content_id << "', "; query << '\'' << item.content_id << "', ";
query << '\'' << static_cast<int>(item.static_auth) << "', ";
query << '\'' << item.default_item << "', "; query << '\'' << item.default_item << "', ";
query << '\'' << Escape(item.subject) << "', "; query << '\'' << Escape(item.subject) << "', ";
query << '\'' << Escape(item.guest_name) << "', "; query << '\'' << Escape(item.guest_name) << "', ";
url_without_id = AddItemCreateUrlSubject(item); url_without_id = AddItemCreateUrlSubject(item);
@ -523,7 +526,8 @@ Error Db::EditItemInItem(Item & item, bool with_url)
{ {
AssertConnection(); AssertConnection();
std::ostringstream query; std::ostringstream query;
query << "update core.item set (user_id, group_id, privileges, date_creation, date_modification, type, default_item, parent_id, subject, guest_name"; query << "update core.item set (user_id, group_id, privileges, date_creation, date_modification, type, "
"default_item, parent_id, subject, guest_name, static_auth";
if( with_url ) if( with_url )
query << ", url"; query << ", url";
@ -538,7 +542,8 @@ Error Db::EditItemInItem(Item & item, bool with_url)
query << '\'' << item.default_item << "', "; query << '\'' << item.default_item << "', ";
query << '\'' << item.parent_id << "', "; query << '\'' << item.parent_id << "', ";
query << '\'' << Escape(item.subject) << "', "; query << '\'' << Escape(item.subject) << "', ";
query << '\'' << Escape(item.guest_name) << "' "; query << '\'' << Escape(item.guest_name) << "', ";
query << '\'' << static_cast<int>(item.static_auth) << "' ";
if( with_url ) if( with_url )
{ {
@ -583,7 +588,6 @@ Error Db::EditItemInContent(Item & item)
query << '\'' << Escape(item.content) << "', "; query << '\'' << Escape(item.content) << "', ";
query << '\'' << item.content_type << "' "; query << '\'' << item.content_type << "' ";
query << ") where id='" << item.content_id << "';"; query << ") where id='" << item.content_id << "';";
r = AssertQuery(query.str()); r = AssertQuery(query.str());
@ -751,7 +755,8 @@ return result;
PGresult * Db::GetItemsQuery(long parent_id, Item::Type type, bool with_subject, bool with_content, bool sort_asc) PGresult * Db::GetItemsQuery(long parent_id, Item::Type type, bool with_subject, bool with_content, bool sort_asc)
{ {
std::ostringstream query; std::ostringstream query;
query << "select item.id, user_id, group_id, privileges, date_creation, date_modification, url, type, parent_id, content_id, default_item, guest_name"; query << "select item.id, user_id, group_id, privileges, date_creation, date_modification, url, type, parent_id, "
"content_id, default_item, guest_name, static_auth";
if( type != Item::dir ) if( type != Item::dir )
{ {

View File

@ -129,9 +129,9 @@ protected:
struct ItemColumns struct ItemColumns
{ {
int id, user_id, group_id, privileges, date_creation, date_modification, url, type, parent_id, content_id, default_item, subject, content, content_type, guest_name; int id, user_id, group_id, privileges, date_creation, date_modification, url, type, parent_id,
content_id, default_item, subject, content, content_type, guest_name, static_auth;
void SetColumns(PGresult * r); void SetColumns(PGresult * r);
void SetItem(PGresult * r, long row, Item & item); void SetItem(PGresult * r, long row, Item & item);
}; };

View File

@ -29,6 +29,7 @@ void Db::ItemColumns::SetColumns(PGresult * r)
content = PQfnumber(r, "content"); content = PQfnumber(r, "content");
content_type = PQfnumber(r, "content_type"); content_type = PQfnumber(r, "content_type");
guest_name = PQfnumber(r, "guest_name"); guest_name = PQfnumber(r, "guest_name");
static_auth = PQfnumber(r, "static_auth");
} }
@ -42,7 +43,7 @@ void Db::ItemColumns::SetItem(PGresult * r, long row, Item & item)
if( date_creation != -1 ) item.date_creation = ConvertTime( Db::AssertValue(r, row, date_creation) ); if( date_creation != -1 ) item.date_creation = ConvertTime( Db::AssertValue(r, row, date_creation) );
if( date_modification != -1 ) item.date_modification = ConvertTime( Db::AssertValue(r, row, date_modification) ); if( date_modification != -1 ) item.date_modification = ConvertTime( Db::AssertValue(r, row, date_modification) );
if( url != -1 ) item.url = Db::AssertValue(r, row, url); if( url != -1 ) item.url = Db::AssertValue(r, row, url);
if( type != -1 ) item.type = static_cast<Item::Type>( atoi( Db::AssertValue(r, row, type) ) ); if( type != -1 ) item.type = static_cast<Item::Type>( atoi(Db::AssertValue(r, row, type)) );
if( parent_id != -1 ) item.parent_id = atol( Db::AssertValue(r, row, parent_id) ); if( parent_id != -1 ) item.parent_id = atol( Db::AssertValue(r, row, parent_id) );
if( content_id != -1 ) item.content_id = atol( Db::AssertValue(r, row, content_id) ); if( content_id != -1 ) item.content_id = atol( Db::AssertValue(r, row, content_id) );
if( default_item != -1 ) item.default_item = atol( Db::AssertValue(r, row, default_item) ); if( default_item != -1 ) item.default_item = atol( Db::AssertValue(r, row, default_item) );
@ -50,6 +51,7 @@ void Db::ItemColumns::SetItem(PGresult * r, long row, Item & item)
if( content != -1 ) item.content = Db::AssertValue(r, row, content); if( content != -1 ) item.content = Db::AssertValue(r, row, content);
if( content_type != -1 ) item.content_type = atoi( Db::AssertValue(r, row, content_type) ); if( content_type != -1 ) item.content_type = atoi( Db::AssertValue(r, row, content_type) );
if( guest_name != -1 ) item.guest_name = Db::AssertValue(r, row, guest_name); if( guest_name != -1 ) item.guest_name = Db::AssertValue(r, row, guest_name);
if( static_auth != -1 ) item.static_auth = static_cast<Item::StaticAuth>( atoi(Db::AssertValue(r, row, static_auth)) );
} }

View File

@ -80,12 +80,21 @@ void FunctionParser::ParseItem()
if( request.status == Error::ok ) if( request.status == Error::ok )
{ {
if( request.role == Request::authorizer && request.item.static_auth == Item::static_none )
{
log << log1 << "FP: item.url: " << url << " exists but has not a static content (authorizer role)" << logend;
request.status = Error::db_no_item;
return;
}
++get_index; ++get_index;
request.is_item = true; request.is_item = true;
log << log3 << "FP: Item: id: " << request.item.id << ", url: " << request.item.url << logend; log << log3 << "FP: Item: id: " << request.item.id << ", url: " << request.item.url << logend;
} }
else else
{
log << log3 << "FP: No Item: url: " << url << logend; log << log3 << "FP: No Item: url: " << url << logend;
}
} }
@ -158,7 +167,7 @@ void FunctionParser::Parse()
return; return;
} }
} }
ParseParams(); ParseParams();
} }

View File

@ -35,10 +35,10 @@ std::string content;
std::string url; std::string url;
// 0 - simple txt // 0 - text: simple
// 1 - formatted txt // 1 - text: formatted
// 2 - html // 2 - text: html
// 3 - bbcode // 3 - text: bbcode
int content_type; int content_type;
@ -65,6 +65,19 @@ long default_item;
long content_id; long content_id;
// external static file (saved in file system)
// the direct url is the same but the prefix is: base_url_static_auth
enum StaticAuth
{
static_none = 0,
static_image = 1,
static_other = 2
};
StaticAuth static_auth;
Item() Item()
{ {
Clear(); Clear();
@ -93,7 +106,9 @@ void Clear()
default_item = -1; default_item = -1;
content_id = -1; content_id = -1;
static_auth = static_none;
time_t t = std::time(0); time_t t = std::time(0);
date_creation = *std::localtime( &t ); date_creation = *std::localtime( &t );
date_modification = date_creation; date_modification = date_creation;

View File

@ -142,33 +142,32 @@ return *this;
void Log::SaveLog() void Log::SaveLog()
{ {
int attempt = 2; int attempt = 2;
if( current_level > log_level ) if( current_level > log_level )
return; return;
if( log_stdout ) if( log_stdout )
std::cout << buffer.str() << std::endl; std::cout << buffer.str() << std::endl;
if( log_file.empty() ) if( log_file.empty() )
return; return;
std::ofstream file; std::ofstream file;
do do
{ {
file.open( log_file.c_str(), std::ios_base::out | std::ios_base::app ); file.open( log_file.c_str(), std::ios_base::out | std::ios_base::app );
// if( !file ) // if( !file )
// sleep(1); // sleep(1);
} }
while( --attempt > 0 && !file ); while( --attempt > 0 && !file );
if( !file ) if( !file )
return; return;
file << buffer.str() << std::endl; file << buffer.str() << std::endl;
} }

View File

@ -9,7 +9,7 @@
#include "misc.h" #include "misc.h"
#include "log.h" #include "log.h"
#include "data.h"
@ -48,11 +48,30 @@ return false;
} }
void CorrectUrl(Item & item) void CorrectUrlDots(std::string & url)
{
size_t i = url.size();
bool was_dot = false;
while( i-- > 0 )
{
if( url[i] == '.' )
{
if( was_dot )
// only one dot is allowed
url[i] = '_';
was_dot = true;
}
}
}
void CorrectUrlChars(std::string & url)
{ {
std::string::iterator i; std::string::iterator i;
for(i = item.url.begin(); i!=item.url.end() ; ++i) for(i = url.begin(); i!=url.end() ; ++i)
{ {
if( !CorrectUrlChar(*i) ) if( !CorrectUrlChar(*i) )
{ {
@ -64,51 +83,34 @@ std::string::iterator i;
*i = '_'; *i = '_';
} }
} }
ToSmall(item.url);
if( item.url.empty() )
item.url = "bez_nazwy"; // !! wrzucic do pliku konfiguracyjnego
else
if( item.url[0] >= '0' && item.url[0] <= '9' )
// url must begin with a letter
item.url.insert(item.url.begin(), '_');
} }
void SetUrlFromSubject(Item & item) void CorrectUrlOnlyAllowedChar(std::string & url)
{ {
item.url = item.subject; CorrectUrlDots(url);
CorrectUrl(item); CorrectUrlChars(url);
ToSmall(url);
Trim(url, '_');
/* if( url.empty() || url == "." )
std::string::iterator i;
item.url.clear();
for(i = item.subject.begin(); i!=item.subject.end() ; ++i)
{ {
int c = ChangeLocalChar(*i); if( data.item_url_empty.empty() )
url = "unnamed";
if( (c >= 'a' && c <='z') || else
(c >= 'A' && c <='Z') || {
(c >= '0' && c <='9') || url = data.item_url_empty;
(c == '(' || c == ')' || c == '.' || c == ',' || c == '_' )
) CorrectUrlDots(url);
{ CorrectUrlChars(url);
item.url += c; ToSmall(url);
} // we don't trim here and the string will not be empty
else }
item.url += '_';
} }
if( item.url.empty() ) if( url[0] >= '0' && url[0] <= '9' )
item.url = "bez_nazwy"; // !! wrzucic do pliku konfiguracyjnego
else
if( item.url[0] >= '0' && item.url[0] <= '9' )
// url must begin with a letter // url must begin with a letter
item.url.insert(item.url.begin(), '_'); url.insert(url.begin(), '_');
*/
} }
@ -392,6 +394,36 @@ std::string::size_type i;
} }
void Trim(std::string & s, char c)
{
std::string::size_type i;
if( s.empty() )
return;
// looking for the 'c' characters at the end
for(i=s.size()-1 ; i>0 && s[i]==c ; --i);
if( i==0 && s[i]==c )
{
// the whole string has the 'c' characters
s.clear();
return;
}
// deleting 'c' characters at the end
if( i != s.size() - 1 )
s.erase(i+1, std::string::npos);
// looking for the 'c' characters at the beginning
for(i=0 ; i<s.size() && s[i]==c ; ++i);
// deleting the 'c' characters at the beginning
if( i != 0 )
s.erase(0, i);
}
const char * SkipWhite(const char * s) const char * SkipWhite(const char * s)
{ {
while( IsWhite(*s) ) while( IsWhite(*s) )
@ -401,18 +433,53 @@ return s;
} }
int ToSmall(int c)
{
if( c>='A' && c<='Z' )
c = c - 'A' + 'a';
return c;
}
void ToSmall(std::string & s) void ToSmall(std::string & s)
{ {
std::string::size_type i; std::string::size_type i;
for(i=0 ; i<s.size() ; ++i) for(i=0 ; i<s.size() ; ++i)
{ s[i] = ToSmall(s[i]);
if( s[i]>='A' && s[i]<='Z' )
s[i] = s[i] - 'A' + 'a';
}
} }
bool IsSubString(const char * short_str, const char * long_str)
{
while( *short_str && *long_str && *short_str == *long_str )
{
++short_str;
++long_str;
}
if( *short_str == 0 )
return true;
return false;
}
bool IsSubStringNoCase(const char * short_str, const char * long_str)
{
while( *short_str && *long_str && ToSmall(*short_str) == ToSmall(*long_str) )
{
++short_str;
++long_str;
}
if( *short_str == 0 )
return true;
return false;
}
bool ValidateEmail(const std::string & email) bool ValidateEmail(const std::string & email)
{ {

View File

@ -26,8 +26,9 @@ void ToString(std::string & s, long value);
int ChangeLocalChar(unsigned char c); int ChangeLocalChar(unsigned char c);
bool CorrectUrlChar(char c); bool CorrectUrlChar(char c);
void CorrectUrl(Item & item); void CorrectUrlDots(std::string & url);
void SetUrlFromSubject(Item & item); void CorrectUrlChars(std::string & url);
void CorrectUrlOnlyAllowedChar(std::string & url);
void HtmlEscape(std::ostringstream & out, const std::string & in); void HtmlEscape(std::ostringstream & out, const std::string & in);
void HtmlEscapeFormTxt(std::ostringstream & out, const std::string & in); void HtmlEscapeFormTxt(std::ostringstream & out, const std::string & in);
@ -46,10 +47,15 @@ const char * IpToStr(unsigned int ip_);
bool IsWhite(int s); bool IsWhite(int s);
void TrimWhite(std::string & s); void TrimWhite(std::string & s);
void Trim(std::string & s, char c);
int ToSmall(int c);
void ToSmall(std::string & s); void ToSmall(std::string & s);
const char * SkipWhite(const char * s); const char * SkipWhite(const char * s);
const char * ToStr(int value); const char * ToStr(int value);
bool IsSubString(const char * short_str, const char * long_str);
bool IsSubStringNoCase(const char * short_str, const char * long_str);
bool ValidateEmail(const std::string & email); bool ValidateEmail(const std::string & email);

View File

@ -45,7 +45,8 @@ void Request::Clear()
cookie_table.clear(); cookie_table.clear();
method = none; method = none;
role = responder;
headers.str(""); headers.str("");
page.str(""); page.str("");
debug.str(""); debug.str("");
@ -58,6 +59,7 @@ void Request::Clear()
env_http_host = &char_empty; env_http_host = &char_empty;
env_http_user_agent = &char_empty; env_http_user_agent = &char_empty;
env_http_accept_encoding = &char_empty; env_http_accept_encoding = &char_empty;
env_fcgi_role = &char_empty;
session = 0; session = 0;
@ -97,7 +99,7 @@ void Request::SetCookie(const char * name, const char * value, tm * expires)
if( expires ) if( expires )
headers << "; expires=" << DateToStrCookie(expires) << " GMT"; headers << "; expires=" << DateToStrCookie(expires) << " GMT";
headers << "; path=/\r\n"; headers << "; path=/; domain=." << data.base_server << "\r\n";
} }
@ -109,7 +111,7 @@ void Request::SetCookie(const char * name, long value, tm * expires)
if( expires ) if( expires )
headers << "; expires=" << DateToStrCookie(expires) << " GMT"; headers << "; expires=" << DateToStrCookie(expires) << " GMT";
headers << "; path=/\r\n"; headers << "; path=/; domain=." << data.base_server << "\r\n";
} }
@ -238,6 +240,7 @@ void Request::ReadEnvVariables()
env_http_host = SetEnvVar("HTTP_HOST"); env_http_host = SetEnvVar("HTTP_HOST");
env_http_user_agent = SetEnvVar("HTTP_USER_AGENT"); env_http_user_agent = SetEnvVar("HTTP_USER_AGENT");
env_http_accept_encoding = SetEnvVar("HTTP_ACCEPT_ENCODING"); env_http_accept_encoding = SetEnvVar("HTTP_ACCEPT_ENCODING");
env_fcgi_role = SetEnvVar("FCGI_ROLE");
} }
@ -268,11 +271,18 @@ void Request::CheckMethod()
{ {
method = none; method = none;
if( env_request_method[0] == 'G' ) if( ToSmall(env_request_method[0]) == 'g' )
method = get; method = get;
else else
if( env_request_method[0] == 'P' ) if( ToSmall(env_request_method[0]) == 'p' )
method = post; method = post;
// default we assume 'responder'
role = responder;
if( ToSmall(env_fcgi_role[0]) == 'a' )
role = authorizer;
} }
@ -310,7 +320,8 @@ void Request::ReadParameters()
void Request::StandardLog() void Request::StandardLog()
{ {
log.PutDate(log1); log.PutDate(log1);
log << env_remote_addr << ' ' << env_request_method << ' ' << env_request_uri << ' ' << env_http_user_agent << logend; log << env_remote_addr << ' ' << env_request_method << ' ';
log << env_http_host << env_request_uri << ' ' << env_http_user_agent << logend;
} }
@ -319,10 +330,14 @@ void Request::StandardLog()
void Request::Read() void Request::Read()
{ {
ReadEnvVariables(); ReadEnvVariables();
StandardLog();
CheckMethod(); CheckMethod();
StandardLog();
ReadParameters(); ReadParameters();
CheckIE(); CheckIE();
if( role == authorizer )
log << log3 << "Request: fast cgi role: authorizer" << logend;
CheckKonqueror(); CheckKonqueror();
} }
@ -353,7 +368,7 @@ void Request::SendSessionCookie()
} }
void Request::SendHeaders(bool compressing) void Request::SendHeaders(bool compressing, Header header)
{ {
if( !redirect_to.empty() ) if( !redirect_to.empty() )
{ {
@ -364,8 +379,25 @@ void Request::SendHeaders(bool compressing)
} }
else else
{ {
FCGX_PutS("Status: 200 OK\r\n", out); switch(header)
FCGX_PutS("Content-Type: Text/Html\r\n", out); {
case h_404:
FCGX_PutS("Status: 404 Not Found\r\n", out);
FCGX_PutS("Content-Type: Text/Html\r\n", out);
break;
case h_403:
FCGX_PutS("Status: 403 Forbidden\r\n", out);
FCGX_PutS("Content-Type: Text/Html\r\n", out);
break;
default:
FCGX_PutS("Status: 200 OK\r\n", out);
if( role != authorizer )
FCGX_PutS("Content-Type: Text/Html\r\n", out);
}
} }
if( compressing ) if( compressing )
@ -415,14 +447,25 @@ void Request::SendPage(bool compressing)
void Request::SendAll() void Request::SendAll()
{ {
bool compressing = data.compression && !browser_msie && !browser_konqueror && accept_encoding_parser.AcceptDeflate(); bool compressing = data.compression && !browser_msie && !browser_konqueror && accept_encoding_parser.AcceptDeflate();
Header header = h_200;
if( status == Error::db_no_item || status == Error::no_function || status == Error::unknown_param )
header = h_404;
if( status == Error::permision_denied || status == Error::cant_change_user || status == Error::cant_change_group )
header = h_403;
SendSessionCookie(); SendSessionCookie();
SendHeaders(compressing); SendHeaders(compressing, header);
if( !redirect_to.empty() ) if( !redirect_to.empty() )
// if there is a redirect we do not send a content // if there is a redirect we do not send a content
return; return;
if( header == h_200 && role == authorizer && is_item && item.static_auth != Item::static_none )
// if there is an item and the item has 'file' storage we do not send a content
return;
// adding debug info if exists // adding debug info if exists
AddDebugInfo(); AddDebugInfo();

View File

@ -41,7 +41,7 @@ struct Request
enum Method { get, post, none } method; enum Method { get, post, none } method;
enum Role { responder, authorizer } role;
// headers, page and debug // headers, page and debug
// notify (for mailing) // notify (for mailing)
@ -62,7 +62,7 @@ struct Request
const char * env_http_host; const char * env_http_host;
const char * env_http_user_agent; const char * env_http_user_agent;
const char * env_http_accept_encoding; const char * env_http_accept_encoding;
const char * env_fcgi_role;
// true if the browser is Microsoft Internet Explorer // true if the browser is Microsoft Internet Explorer
bool browser_msie; bool browser_msie;
@ -152,11 +152,18 @@ struct Request
private: private:
enum Header
{
h_200,
h_404,
h_403
};
void SendSessionCookie(); void SendSessionCookie();
void CheckIE(); void CheckIE();
void CheckKonqueror(); void CheckKonqueror();
void SendHeaders(bool compressing); void SendHeaders(bool compressing, Header header);
void AddDebugInfo(); void AddDebugInfo();
void SendPage(bool compressing); void SendPage(bool compressing);
@ -173,6 +180,7 @@ private:
// html after filtering // html after filtering
std::string clean_html; std::string clean_html;
}; };

View File

@ -148,14 +148,29 @@ void RequestController::SaveSessionsIfNeeded()
bool RequestController::BaseUrlRedirect() bool RequestController::BaseUrlRedirect()
{ {
if( data.base_url_http_host.empty() ) if( request.role == Request::responder )
return false; {
if( data.base_url_http_host.empty() )
if( data.base_url_http_host == request.env_http_host ) return false;
return false;
if( data.base_url_http_host == request.env_http_host )
return false;
request.redirect_to = data.base_url + request.env_request_uri;
}
else
{
// authorizer
if( data.base_url_static_auth_http_host.empty() )
return false;
if( data.base_url_static_auth_http_host == request.env_http_host )
return false;
request.redirect_to = data.base_url_static_auth + request.env_request_uri;
}
request.redirect_to = data.base_url + request.env_request_uri;
log << log3 << "RC: BaseUrlRedirect from: " << request.env_http_host << logend; log << log3 << "RC: BaseUrlRedirect from: " << request.env_http_host << logend;
return true; return true;

View File

@ -96,6 +96,10 @@ int main(int argv, char ** argc)
nlog.Init(data.log_level, data.log_notify_file, false); nlog.Init(data.log_level, data.log_notify_file, false);
db.Init(data.db_database, data.db_user, data.db_pass); db.Init(data.db_database, data.db_user, data.db_pass);
// data.base_server can be changed (stripped from 'http://' or a last slash)
// it is done when the config is read
log << log3 << "base_server: " << data.base_server << logend;
plugin.LoadPlugins(data.plugin_file); plugin.LoadPlugins(data.plugin_file);
request.Init(); request.Init();

View File

@ -64,6 +64,19 @@ void doc_base_url(Info & i)
void doc_base_url_static(Info & i)
{
i.out << data.base_url_static;
}
void doc_base_url_static_auth(Info & i)
{
i.out << data.base_url_static_auth;
}
void doc_current_url(Info & i) void doc_current_url(Info & i)
{ {
i.out << request.env_request_uri; i.out << request.env_request_uri;

View File

@ -119,6 +119,31 @@ void item_link(Info & i)
} }
void item_link_static_auth(Info & i)
{
HtmlEscape(i.out, data.base_url_static_auth);
item_dir(i);
item_url(i);
}
void item_static_auth_is_none(Info & i)
{
i.result = request.item.static_auth == Item::static_none;
}
void item_static_auth_is_image(Info & i)
{
i.result = request.item.static_auth == Item::static_image;
}
void item_static_auth_is_other(Info & i)
{
i.result = request.item.static_auth == Item::static_other;
}
void item_can_read(Info & i) void item_can_read(Info & i)
{ {

View File

@ -202,13 +202,15 @@ void Templates::CreateFunctions()
/* /*
doc doc
*/ */
functions.Insert("doc_language", doc_language); functions.Insert("doc_language", doc_language);
functions.Insert("doc_title", doc_title); functions.Insert("doc_title", doc_title);
functions.Insert("doc_charset", doc_charset); functions.Insert("doc_charset", doc_charset);
functions.Insert("doc_base_url", doc_base_url); functions.Insert("doc_base_url", doc_base_url);
functions.Insert("doc_current_url", doc_current_url); functions.Insert("doc_base_url_static", doc_base_url_static);
functions.Insert("doc_is_error", doc_is_error); functions.Insert("doc_base_url_static_auth", doc_base_url_static_auth);
functions.Insert("doc_status", doc_status); functions.Insert("doc_current_url", doc_current_url);
functions.Insert("doc_is_error", doc_is_error);
functions.Insert("doc_status", doc_status);
/* /*
item item
@ -224,6 +226,11 @@ void Templates::CreateFunctions()
functions.Insert("item_dir", item_dir); functions.Insert("item_dir", item_dir);
functions.Insert("item_url", item_url); functions.Insert("item_url", item_url);
functions.Insert("item_link", item_link); functions.Insert("item_link", item_link);
functions.Insert("item_link_static_auth", item_link_static_auth);
functions.Insert("item_static_auth_is_none", item_static_auth_is_none);
functions.Insert("item_static_auth_is_image", item_static_auth_is_image);
functions.Insert("item_static_auth_is_other", item_static_auth_is_other);
functions.Insert("item_can_read", item_can_read); functions.Insert("item_can_read", item_can_read);
functions.Insert("item_can_write", item_can_write); functions.Insert("item_can_write", item_can_write);
functions.Insert("item_info", item_info); functions.Insert("item_info", item_info);

View File

@ -45,6 +45,8 @@ namespace TemplatesFunctions
void doc_title(Info & i); void doc_title(Info & i);
void doc_charset(Info & i); void doc_charset(Info & i);
void doc_base_url(Info & i); void doc_base_url(Info & i);
void doc_base_url_static(Info & i);
void doc_base_url_static_auth(Info & i);
void doc_current_url(Info & i); void doc_current_url(Info & i);
void doc_is_error(Info & i); void doc_is_error(Info & i);
void doc_status(Info & i); void doc_status(Info & i);
@ -64,6 +66,10 @@ namespace TemplatesFunctions
void item_dir(Info & i); void item_dir(Info & i);
void item_url(Info & i); void item_url(Info & i);
void item_link(Info & i); void item_link(Info & i);
void item_link_static_auth(Info & i);
void item_static_auth_is_none(Info & i);
void item_static_auth_is_image(Info & i);
void item_static_auth_is_other(Info & i);
void item_can_read(Info & i); void item_can_read(Info & i);
void item_can_write(Info & i); void item_can_write(Info & i);
void item_info(Info & i); void item_info(Info & i);