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:
parent
118bf1fc65
commit
60fccea703
|
@ -107,15 +107,31 @@ void Content::SetDefaultFunction()
|
|||
|
||||
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 )
|
||||
SetDefaultFunction();
|
||||
|
||||
if( !request.redirect_to.empty() )
|
||||
return;
|
||||
|
||||
|
||||
if( !request.pfunction )
|
||||
{
|
||||
request.status = Error::no_function;
|
||||
log << log1 << "Content: no function (neither cat nor ls)" << logend;
|
||||
return;
|
||||
}
|
||||
|
@ -176,17 +192,22 @@ void Content::MakeStandardFunction()
|
|||
|
||||
void Content::MakePost()
|
||||
{
|
||||
if( request.role == Request::authorizer )
|
||||
{
|
||||
request.status = Error::permision_denied;
|
||||
return;
|
||||
}
|
||||
|
||||
if( !request.pfunction )
|
||||
SetDefaultFunction();
|
||||
|
||||
if( !request.pfunction )
|
||||
{
|
||||
log << log1 << "Content: MakePost: no function" << logend;
|
||||
request.status = Error::no_function;
|
||||
log << log1 << "Content: MakePost: no function" << logend;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
switch( request.pfunction->code )
|
||||
{
|
||||
case FUN_RUN:
|
||||
|
@ -355,7 +376,7 @@ void Content::PrepareUrl(Item & item)
|
|||
if( item.url.empty() )
|
||||
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) )
|
||||
{
|
||||
|
|
|
@ -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: 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: 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: log.h groups.h group.h functions.h function.h lastcontainer.h
|
||||
data.o: mounts.h mount.h rebus.h
|
||||
|
@ -36,7 +36,9 @@ htmlfilter.o: htmlfilter.h
|
|||
httpsimpleparser.o: httpsimpleparser.h
|
||||
lastcontainer.o: lastcontainer.h 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
|
||||
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
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "log.h"
|
||||
#include "data.h"
|
||||
#include "plugin.h"
|
||||
#include "misc.h"
|
||||
|
||||
|
||||
Config::Config()
|
||||
|
@ -109,9 +110,19 @@ void Config::AssignValues()
|
|||
data.db_database = Text("db_database");
|
||||
data.db_user = Text("db_user");
|
||||
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");
|
||||
|
||||
|
@ -199,18 +210,34 @@ void Config::NoLastSlash(std::string & s)
|
|||
if( s.empty() )
|
||||
return;
|
||||
|
||||
log << log2 << "Config: removing the last slash from: " << s << logend;
|
||||
|
||||
if( *(--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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ private:
|
|||
bool errors_to_stdout;
|
||||
|
||||
void NoLastSlash(std::string & s);
|
||||
void NoFirstHttp(std::string & s);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -46,9 +46,12 @@ protected:
|
|||
log << log2 << "Cookie, name: \"" << name << "\", value: \"" << value << "\"";
|
||||
|
||||
if( res.second == false )
|
||||
log << log2 << " (skipped)";
|
||||
{
|
||||
res.first->second = value;
|
||||
log << " (overwritten)";
|
||||
}
|
||||
|
||||
log << log2 << logend;
|
||||
log << logend;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -25,18 +25,19 @@ Data::Data()
|
|||
|
||||
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 )
|
||||
base_url_http_host = base_url.substr(7);
|
||||
if( strncmp(in.c_str(), "http://", 7) == 0 )
|
||||
out = in.substr(7);
|
||||
else
|
||||
if( strncmp(base_url.c_str(), "https://", 8) == 0 )
|
||||
base_url_http_host = base_url.substr(8);
|
||||
if( strncmp(in.c_str(), "https://", 8) == 0 )
|
||||
out = in.substr(8);
|
||||
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
|
||||
}
|
||||
|
|
28
core/data.h
28
core/data.h
|
@ -64,7 +64,12 @@ public:
|
|||
std::string db_database;
|
||||
std::string db_user;
|
||||
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;
|
||||
|
||||
// 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
|
||||
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
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
// false at the beginning
|
||||
bool stdout_is_closed;
|
||||
|
||||
|
@ -116,7 +136,11 @@ public:
|
|||
|
||||
// based on base_url
|
||||
// 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_static_auth_http_host;
|
||||
|
||||
|
||||
|
||||
// call this method after the config file is read
|
||||
void SetAdditionalVariables();
|
||||
|
@ -146,7 +170,7 @@ public:
|
|||
|
||||
|
||||
private:
|
||||
void SetHttpHost();
|
||||
void SetHttpHost(const std::string & in, std::string & out);
|
||||
};
|
||||
|
||||
|
||||
|
|
15
core/db.cpp
15
core/db.cpp
|
@ -420,7 +420,8 @@ Error Db::AddItemIntoItem(Item & item)
|
|||
{
|
||||
AssertConnection();
|
||||
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.group_id << "', ";
|
||||
query << '\'' << item.privileges << "', ";
|
||||
|
@ -429,10 +430,12 @@ Error Db::AddItemIntoItem(Item & item)
|
|||
query << '\'' << static_cast<int>(item.type) << "', ";
|
||||
query << '\'' << item.parent_id << "', ";
|
||||
query << '\'' << item.content_id << "', ";
|
||||
query << '\'' << static_cast<int>(item.static_auth) << "', ";
|
||||
query << '\'' << item.default_item << "', ";
|
||||
query << '\'' << Escape(item.subject) << "', ";
|
||||
query << '\'' << Escape(item.guest_name) << "', ";
|
||||
|
||||
|
||||
url_without_id = AddItemCreateUrlSubject(item);
|
||||
|
||||
if( url_without_id )
|
||||
|
@ -523,7 +526,8 @@ Error Db::EditItemInItem(Item & item, bool with_url)
|
|||
{
|
||||
AssertConnection();
|
||||
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 )
|
||||
query << ", url";
|
||||
|
@ -538,7 +542,8 @@ Error Db::EditItemInItem(Item & item, bool with_url)
|
|||
query << '\'' << item.default_item << "', ";
|
||||
query << '\'' << item.parent_id << "', ";
|
||||
query << '\'' << Escape(item.subject) << "', ";
|
||||
query << '\'' << Escape(item.guest_name) << "' ";
|
||||
query << '\'' << Escape(item.guest_name) << "', ";
|
||||
query << '\'' << static_cast<int>(item.static_auth) << "' ";
|
||||
|
||||
if( with_url )
|
||||
{
|
||||
|
@ -583,7 +588,6 @@ Error Db::EditItemInContent(Item & item)
|
|||
|
||||
query << '\'' << Escape(item.content) << "', ";
|
||||
query << '\'' << item.content_type << "' ";
|
||||
|
||||
query << ") where id='" << item.content_id << "';";
|
||||
|
||||
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)
|
||||
{
|
||||
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 )
|
||||
{
|
||||
|
|
|
@ -129,8 +129,8 @@ protected:
|
|||
|
||||
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 SetItem(PGresult * r, long row, Item & item);
|
||||
|
|
|
@ -29,6 +29,7 @@ void Db::ItemColumns::SetColumns(PGresult * r)
|
|||
content = PQfnumber(r, "content");
|
||||
content_type = PQfnumber(r, "content_type");
|
||||
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_modification != -1 ) item.date_modification = ConvertTime( Db::AssertValue(r, row, date_modification) );
|
||||
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( 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) );
|
||||
|
@ -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_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( static_auth != -1 ) item.static_auth = static_cast<Item::StaticAuth>( atoi(Db::AssertValue(r, row, static_auth)) );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -80,12 +80,21 @@ void FunctionParser::ParseItem()
|
|||
|
||||
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;
|
||||
request.is_item = true;
|
||||
log << log3 << "FP: Item: id: " << request.item.id << ", url: " << request.item.url << logend;
|
||||
}
|
||||
else
|
||||
{
|
||||
log << log3 << "FP: No Item: url: " << url << logend;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
23
core/item.h
23
core/item.h
|
@ -35,10 +35,10 @@ std::string content;
|
|||
std::string url;
|
||||
|
||||
|
||||
// 0 - simple txt
|
||||
// 1 - formatted txt
|
||||
// 2 - html
|
||||
// 3 - bbcode
|
||||
// 0 - text: simple
|
||||
// 1 - text: formatted
|
||||
// 2 - text: html
|
||||
// 3 - text: bbcode
|
||||
int content_type;
|
||||
|
||||
|
||||
|
@ -65,6 +65,19 @@ long default_item;
|
|||
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()
|
||||
{
|
||||
Clear();
|
||||
|
@ -94,6 +107,8 @@ void Clear()
|
|||
|
||||
content_id = -1;
|
||||
|
||||
static_auth = static_none;
|
||||
|
||||
time_t t = std::time(0);
|
||||
date_creation = *std::localtime( &t );
|
||||
date_modification = date_creation;
|
||||
|
|
27
core/log.cpp
27
core/log.cpp
|
@ -142,33 +142,32 @@ return *this;
|
|||
|
||||
void Log::SaveLog()
|
||||
{
|
||||
int attempt = 2;
|
||||
int attempt = 2;
|
||||
|
||||
if( current_level > log_level )
|
||||
return;
|
||||
if( current_level > log_level )
|
||||
return;
|
||||
|
||||
if( log_stdout )
|
||||
std::cout << buffer.str() << std::endl;
|
||||
|
||||
|
||||
if( log_file.empty() )
|
||||
return;
|
||||
|
||||
std::ofstream file;
|
||||
std::ofstream file;
|
||||
|
||||
do
|
||||
{
|
||||
do
|
||||
{
|
||||
file.open( log_file.c_str(), std::ios_base::out | std::ios_base::app );
|
||||
|
||||
// if( !file )
|
||||
// sleep(1);
|
||||
}
|
||||
while( --attempt > 0 && !file );
|
||||
// if( !file )
|
||||
// sleep(1);
|
||||
}
|
||||
while( --attempt > 0 && !file );
|
||||
|
||||
if( !file )
|
||||
return;
|
||||
if( !file )
|
||||
return;
|
||||
|
||||
file << buffer.str() << std::endl;
|
||||
file << buffer.str() << std::endl;
|
||||
}
|
||||
|
||||
|
||||
|
|
151
core/misc.cpp
151
core/misc.cpp
|
@ -9,7 +9,7 @@
|
|||
|
||||
#include "misc.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;
|
||||
|
||||
for(i = item.url.begin(); i!=item.url.end() ; ++i)
|
||||
for(i = url.begin(); i!=url.end() ; ++i)
|
||||
{
|
||||
if( !CorrectUrlChar(*i) )
|
||||
{
|
||||
|
@ -64,51 +83,34 @@ std::string::iterator 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;
|
||||
CorrectUrl(item);
|
||||
CorrectUrlDots(url);
|
||||
CorrectUrlChars(url);
|
||||
ToSmall(url);
|
||||
Trim(url, '_');
|
||||
|
||||
/*
|
||||
std::string::iterator i;
|
||||
|
||||
item.url.clear();
|
||||
|
||||
for(i = item.subject.begin(); i!=item.subject.end() ; ++i)
|
||||
if( url.empty() || url == "." )
|
||||
{
|
||||
int c = ChangeLocalChar(*i);
|
||||
if( data.item_url_empty.empty() )
|
||||
url = "unnamed";
|
||||
else
|
||||
{
|
||||
url = data.item_url_empty;
|
||||
|
||||
if( (c >= 'a' && c <='z') ||
|
||||
(c >= 'A' && c <='Z') ||
|
||||
(c >= '0' && c <='9') ||
|
||||
(c == '(' || c == ')' || c == '.' || c == ',' || c == '_' )
|
||||
)
|
||||
{
|
||||
item.url += c;
|
||||
}
|
||||
else
|
||||
item.url += '_';
|
||||
CorrectUrlDots(url);
|
||||
CorrectUrlChars(url);
|
||||
ToSmall(url);
|
||||
// we don't trim here and the string will not be empty
|
||||
}
|
||||
}
|
||||
|
||||
if( item.url.empty() )
|
||||
item.url = "bez_nazwy"; // !! wrzucic do pliku konfiguracyjnego
|
||||
else
|
||||
if( item.url[0] >= '0' && item.url[0] <= '9' )
|
||||
if( url[0] >= '0' && url[0] <= '9' )
|
||||
// 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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
std::string::size_type i;
|
||||
|
||||
for(i=0 ; i<s.size() ; ++i)
|
||||
{
|
||||
if( s[i]>='A' && s[i]<='Z' )
|
||||
s[i] = s[i] - 'A' + 'a';
|
||||
}
|
||||
s[i] = ToSmall(s[i]);
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
10
core/misc.h
10
core/misc.h
|
@ -26,8 +26,9 @@ void ToString(std::string & s, long value);
|
|||
int ChangeLocalChar(unsigned char c);
|
||||
|
||||
bool CorrectUrlChar(char c);
|
||||
void CorrectUrl(Item & item);
|
||||
void SetUrlFromSubject(Item & item);
|
||||
void CorrectUrlDots(std::string & url);
|
||||
void CorrectUrlChars(std::string & url);
|
||||
void CorrectUrlOnlyAllowedChar(std::string & url);
|
||||
|
||||
void HtmlEscape(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);
|
||||
void TrimWhite(std::string & s);
|
||||
void Trim(std::string & s, char c);
|
||||
int ToSmall(int c);
|
||||
void ToSmall(std::string & s);
|
||||
const char * SkipWhite(const char * s);
|
||||
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);
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ void Request::Clear()
|
|||
cookie_table.clear();
|
||||
|
||||
method = none;
|
||||
role = responder;
|
||||
|
||||
headers.str("");
|
||||
page.str("");
|
||||
|
@ -58,6 +59,7 @@ void Request::Clear()
|
|||
env_http_host = &char_empty;
|
||||
env_http_user_agent = &char_empty;
|
||||
env_http_accept_encoding = &char_empty;
|
||||
env_fcgi_role = &char_empty;
|
||||
|
||||
session = 0;
|
||||
|
||||
|
@ -97,7 +99,7 @@ void Request::SetCookie(const char * name, const char * value, tm * expires)
|
|||
if( expires )
|
||||
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 )
|
||||
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_user_agent = SetEnvVar("HTTP_USER_AGENT");
|
||||
env_http_accept_encoding = SetEnvVar("HTTP_ACCEPT_ENCODING");
|
||||
env_fcgi_role = SetEnvVar("FCGI_ROLE");
|
||||
}
|
||||
|
||||
|
||||
|
@ -268,11 +271,18 @@ void Request::CheckMethod()
|
|||
{
|
||||
method = none;
|
||||
|
||||
if( env_request_method[0] == 'G' )
|
||||
if( ToSmall(env_request_method[0]) == 'g' )
|
||||
method = get;
|
||||
else
|
||||
if( env_request_method[0] == 'P' )
|
||||
if( ToSmall(env_request_method[0]) == 'p' )
|
||||
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()
|
||||
{
|
||||
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()
|
||||
{
|
||||
ReadEnvVariables();
|
||||
StandardLog();
|
||||
CheckMethod();
|
||||
StandardLog();
|
||||
ReadParameters();
|
||||
CheckIE();
|
||||
|
||||
if( role == authorizer )
|
||||
log << log3 << "Request: fast cgi role: authorizer" << logend;
|
||||
|
||||
CheckKonqueror();
|
||||
}
|
||||
|
||||
|
@ -353,7 +368,7 @@ void Request::SendSessionCookie()
|
|||
}
|
||||
|
||||
|
||||
void Request::SendHeaders(bool compressing)
|
||||
void Request::SendHeaders(bool compressing, Header header)
|
||||
{
|
||||
if( !redirect_to.empty() )
|
||||
{
|
||||
|
@ -364,8 +379,25 @@ void Request::SendHeaders(bool compressing)
|
|||
}
|
||||
else
|
||||
{
|
||||
FCGX_PutS("Status: 200 OK\r\n", out);
|
||||
FCGX_PutS("Content-Type: Text/Html\r\n", out);
|
||||
switch(header)
|
||||
{
|
||||
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 )
|
||||
|
@ -415,14 +447,25 @@ void Request::SendPage(bool compressing)
|
|||
void Request::SendAll()
|
||||
{
|
||||
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();
|
||||
SendHeaders(compressing);
|
||||
SendHeaders(compressing, header);
|
||||
|
||||
if( !redirect_to.empty() )
|
||||
// if there is a redirect we do not send a content
|
||||
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
|
||||
AddDebugInfo();
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ struct Request
|
|||
|
||||
|
||||
enum Method { get, post, none } method;
|
||||
|
||||
enum Role { responder, authorizer } role;
|
||||
|
||||
// headers, page and debug
|
||||
// notify (for mailing)
|
||||
|
@ -62,7 +62,7 @@ struct Request
|
|||
const char * env_http_host;
|
||||
const char * env_http_user_agent;
|
||||
const char * env_http_accept_encoding;
|
||||
|
||||
const char * env_fcgi_role;
|
||||
|
||||
// true if the browser is Microsoft Internet Explorer
|
||||
bool browser_msie;
|
||||
|
@ -152,11 +152,18 @@ struct Request
|
|||
|
||||
private:
|
||||
|
||||
enum Header
|
||||
{
|
||||
h_200,
|
||||
h_404,
|
||||
h_403
|
||||
};
|
||||
|
||||
void SendSessionCookie();
|
||||
void CheckIE();
|
||||
void CheckKonqueror();
|
||||
|
||||
void SendHeaders(bool compressing);
|
||||
void SendHeaders(bool compressing, Header header);
|
||||
void AddDebugInfo();
|
||||
void SendPage(bool compressing);
|
||||
|
||||
|
@ -173,6 +180,7 @@ private:
|
|||
|
||||
// html after filtering
|
||||
std::string clean_html;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -148,13 +148,28 @@ void RequestController::SaveSessionsIfNeeded()
|
|||
|
||||
bool RequestController::BaseUrlRedirect()
|
||||
{
|
||||
if( data.base_url_http_host.empty() )
|
||||
return false;
|
||||
if( request.role == Request::responder )
|
||||
{
|
||||
if( data.base_url_http_host.empty() )
|
||||
return false;
|
||||
|
||||
if( data.base_url_http_host == request.env_http_host )
|
||||
return false;
|
||||
if( data.base_url_http_host == request.env_http_host )
|
||||
return false;
|
||||
|
||||
request.redirect_to = data.base_url + request.env_request_uri;
|
||||
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;
|
||||
}
|
||||
|
||||
log << log3 << "RC: BaseUrlRedirect from: " << request.env_http_host << logend;
|
||||
|
||||
|
|
|
@ -96,6 +96,10 @@ int main(int argv, char ** argc)
|
|||
nlog.Init(data.log_level, data.log_notify_file, false);
|
||||
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);
|
||||
|
||||
request.Init();
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
i.out << request.env_request_uri;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -202,13 +202,15 @@ void Templates::CreateFunctions()
|
|||
/*
|
||||
doc
|
||||
*/
|
||||
functions.Insert("doc_language", doc_language);
|
||||
functions.Insert("doc_title", doc_title);
|
||||
functions.Insert("doc_charset", doc_charset);
|
||||
functions.Insert("doc_base_url", doc_base_url);
|
||||
functions.Insert("doc_current_url", doc_current_url);
|
||||
functions.Insert("doc_is_error", doc_is_error);
|
||||
functions.Insert("doc_status", doc_status);
|
||||
functions.Insert("doc_language", doc_language);
|
||||
functions.Insert("doc_title", doc_title);
|
||||
functions.Insert("doc_charset", doc_charset);
|
||||
functions.Insert("doc_base_url", doc_base_url);
|
||||
functions.Insert("doc_base_url_static", doc_base_url_static);
|
||||
functions.Insert("doc_base_url_static_auth", doc_base_url_static_auth);
|
||||
functions.Insert("doc_current_url", doc_current_url);
|
||||
functions.Insert("doc_is_error", doc_is_error);
|
||||
functions.Insert("doc_status", doc_status);
|
||||
|
||||
/*
|
||||
item
|
||||
|
@ -224,6 +226,11 @@ void Templates::CreateFunctions()
|
|||
functions.Insert("item_dir", item_dir);
|
||||
functions.Insert("item_url", item_url);
|
||||
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_write", item_can_write);
|
||||
functions.Insert("item_info", item_info);
|
||||
|
|
|
@ -45,6 +45,8 @@ namespace TemplatesFunctions
|
|||
void doc_title(Info & i);
|
||||
void doc_charset(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_is_error(Info & i);
|
||||
void doc_status(Info & i);
|
||||
|
@ -64,6 +66,10 @@ namespace TemplatesFunctions
|
|||
void item_dir(Info & i);
|
||||
void item_url(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_write(Info & i);
|
||||
void item_info(Info & i);
|
||||
|
|
Loading…
Reference in New Issue