2008-12-10 05:42:49 +01:00
|
|
|
/*
|
|
|
|
* This file is a part of CMSLU -- Content Management System like Unix
|
|
|
|
* and is not publicly distributed
|
|
|
|
*
|
2010-01-28 16:39:01 +01:00
|
|
|
* Copyright (c) 2008-2010, Tomasz Sowa
|
2008-12-10 05:42:49 +01:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "requestcontroller.h"
|
2009-04-21 22:50:55 +02:00
|
|
|
#include "data.h"
|
|
|
|
#include "log.h"
|
|
|
|
#include "request.h"
|
|
|
|
#include "postparser.h"
|
|
|
|
#include "cookieparser.h"
|
2009-10-01 00:31:20 +02:00
|
|
|
#include "notify.h"
|
2008-12-10 05:42:49 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
RequestController::RequestController()
|
|
|
|
{
|
2009-11-21 00:09:52 +01:00
|
|
|
last_sessions_save = time(0);
|
2008-12-10 05:42:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-12-11 03:46:16 +01:00
|
|
|
RequestController::~RequestController()
|
|
|
|
{
|
|
|
|
Close();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void RequestController::Close()
|
|
|
|
{
|
|
|
|
// don't call close(0)
|
|
|
|
// it will be closed next time during dup(s,0)
|
|
|
|
|
|
|
|
// if you closed the descriptor here
|
|
|
|
// then the database would have that descriptor (during connecting)
|
|
|
|
// and there'll be a problem in the next loop (after SIGHUP)
|
|
|
|
}
|
|
|
|
|
2008-12-10 05:42:49 +01:00
|
|
|
|
|
|
|
|
2009-01-27 19:43:44 +01:00
|
|
|
|
2008-12-10 05:42:49 +01:00
|
|
|
bool RequestController::Init()
|
|
|
|
{
|
|
|
|
const char * sock = data.fcgi_socket.c_str();
|
|
|
|
|
|
|
|
unlink(sock);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int s = FCGX_OpenSocket(sock, 10);
|
|
|
|
|
|
|
|
if( s < 0 )
|
|
|
|
{
|
|
|
|
log << log1 << "An error during creating a socket" << logend;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
chmod(sock, data.fcgi_socket_chmod);
|
|
|
|
|
|
|
|
passwd * pw = getpwnam(data.fcgi_socket_user.c_str());
|
|
|
|
|
|
|
|
if( !pw )
|
|
|
|
{
|
|
|
|
log << log1 << "There is no user: " << data.fcgi_socket_user << logend;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
group * gr = getgrnam(data.fcgi_socket_group.c_str());
|
|
|
|
|
|
|
|
if( !gr )
|
|
|
|
{
|
|
|
|
log << log1 << "There is no group: " << data.fcgi_socket_group << logend;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
chown(sock, pw->pw_uid, gr->gr_gid);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( setuid(pw->pw_uid) < 0 )
|
|
|
|
{
|
|
|
|
log << log1 << "I can't change the user into: " << data.fcgi_socket_user << logend;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
if( setgid(gr->gr_gid) < 0 )
|
|
|
|
{
|
|
|
|
int e = errno;
|
|
|
|
|
|
|
|
log << log1 << "I can't change the group into: " << data.fcgi_socket_group << " " << gr->gr_gid << logend;
|
|
|
|
log << log1 << "errno: " << e << logend;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
dup2(s, 0);
|
|
|
|
|
|
|
|
//
|
2008-12-21 22:17:09 +01:00
|
|
|
data.dirs.ReadDirs();
|
|
|
|
data.users.ReadUsers();
|
|
|
|
data.groups.ReadGroups();
|
2008-12-30 02:05:03 +01:00
|
|
|
data.functions.ReadFunctions();
|
2009-04-20 00:13:21 +02:00
|
|
|
data.mounts.ReadMounts();
|
2010-01-28 16:39:01 +01:00
|
|
|
data.locale.Read(data.locale_dir, data.locale_dir_default); // call it before content.Init()
|
2009-11-17 00:36:38 +01:00
|
|
|
data.rebus.Init();
|
2008-12-10 05:42:49 +01:00
|
|
|
//
|
|
|
|
|
2009-09-22 01:05:05 +02:00
|
|
|
|
|
|
|
|
2008-12-10 05:42:49 +01:00
|
|
|
if( !content.Init() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-11-21 00:09:52 +01:00
|
|
|
void RequestController::LoadSessions()
|
|
|
|
{
|
|
|
|
session_manager.LoadSessions();
|
|
|
|
}
|
|
|
|
|
|
|
|
void RequestController::SaveSessions()
|
|
|
|
{
|
|
|
|
session_manager.SaveSessions();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void RequestController::SaveSessionsIfNeeded()
|
|
|
|
{
|
|
|
|
time_t t = time(0);
|
|
|
|
|
|
|
|
if( last_sessions_save + 86400 > t )
|
|
|
|
return;
|
|
|
|
|
|
|
|
// saving once a day for safety
|
|
|
|
last_sessions_save = t;
|
|
|
|
SaveSessions();
|
|
|
|
}
|
|
|
|
|
2008-12-10 05:42:49 +01:00
|
|
|
|
2008-12-12 04:11:29 +01:00
|
|
|
bool RequestController::BaseUrlRedirect()
|
|
|
|
{
|
2009-12-30 21:46:12 +01:00
|
|
|
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;
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
2008-12-12 04:11:29 +01:00
|
|
|
|
2008-12-31 14:36:46 +01:00
|
|
|
log << log3 << "RC: BaseUrlRedirect from: " << request.env_http_host << logend;
|
2008-12-12 04:11:29 +01:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-12-10 05:42:49 +01:00
|
|
|
void RequestController::Loop()
|
|
|
|
{
|
|
|
|
while( FCGX_Accept(&request.in, &request.out, &request.err, &request.env) == 0 )
|
|
|
|
{
|
2008-12-30 02:05:03 +01:00
|
|
|
log << log2 << "---------------------------------------------------------------------------------" << logend;
|
2008-12-10 05:42:49 +01:00
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
request.Clear();
|
|
|
|
request.Read();
|
2008-12-12 04:11:29 +01:00
|
|
|
|
|
|
|
// 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() )
|
|
|
|
{
|
2009-01-31 07:53:36 +01:00
|
|
|
session_manager.DeleteOldSessions();
|
2008-12-30 02:05:03 +01:00
|
|
|
session_manager.SetSession(); // set request.session as well
|
2008-12-12 04:11:29 +01:00
|
|
|
request.session->CheckTimers();
|
2008-12-30 02:05:03 +01:00
|
|
|
|
|
|
|
function_parser.Parse();
|
2010-01-25 05:52:17 +01:00
|
|
|
data.mounts.CalcCurMount();
|
2008-12-12 04:11:29 +01:00
|
|
|
|
2009-04-21 01:49:28 +02:00
|
|
|
content.ReadAdditionalInfo();
|
2008-12-12 04:11:29 +01:00
|
|
|
content.Make();
|
|
|
|
}
|
|
|
|
|
2008-12-30 02:05:03 +01:00
|
|
|
request.SendAll();
|
2009-10-01 00:31:20 +02:00
|
|
|
notify.ItemChanged(request.notify_code);
|
2008-12-10 05:42:49 +01:00
|
|
|
}
|
|
|
|
catch(const std::exception & e)
|
|
|
|
{
|
|
|
|
log << log1 << "uncaught std exception: " << e.what() << logend;
|
|
|
|
}
|
|
|
|
catch(const Error & e)
|
|
|
|
{
|
|
|
|
log << log1 << "uncaught exception: Error: " << e << logend;
|
|
|
|
}
|
|
|
|
catch(...)
|
|
|
|
{
|
|
|
|
log << log1 << "uncaught exception" << logend;
|
|
|
|
}
|
|
|
|
|
2009-11-21 00:09:52 +01:00
|
|
|
SaveSessionsIfNeeded();
|
2008-12-10 05:42:49 +01:00
|
|
|
|
2008-12-11 03:46:16 +01:00
|
|
|
// !! this should be immediately after FCGX_Accept() but signals don't want to break FCGX_Accept
|
|
|
|
if( data.signal_hup )
|
|
|
|
{
|
|
|
|
FCGX_Finish();
|
|
|
|
return;
|
|
|
|
}
|
2010-01-06 20:17:53 +01:00
|
|
|
|
|
|
|
request.ClearPostFileTmp();
|
2008-12-10 05:42:49 +01:00
|
|
|
}
|
|
|
|
}
|
2009-01-31 07:53:36 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SessionContainer::Iterator RequestController::SessionBegin()
|
|
|
|
{
|
|
|
|
return session_manager.SessionBegin();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SessionContainer::Iterator RequestController::SessionEnd()
|
|
|
|
{
|
|
|
|
return session_manager.SessionEnd();
|
|
|
|
}
|