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
|
|
|
|
*
|
|
|
|
* Copyright (c) 2008, Tomasz Sowa
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "requestcontroller.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
RequestController::RequestController()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
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();
|
2008-12-10 05:42:49 +01:00
|
|
|
//
|
|
|
|
|
|
|
|
if( !content.Init() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-12-12 04:11:29 +01:00
|
|
|
bool RequestController::BaseUrlRedirect()
|
|
|
|
{
|
2008-12-31 14:36:46 +01:00
|
|
|
if( data.base_url_http_host.empty() )
|
2008-12-12 04:11:29 +01:00
|
|
|
return false;
|
|
|
|
|
|
|
|
if( data.base_url_http_host == request.env_http_host )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
request.result = Request::redirect;
|
2008-12-31 14:36:46 +01:00
|
|
|
request.str = data.base_url + 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();
|
2009-04-20 00:13:21 +02:00
|
|
|
data.mounts.CalculateCurrentMountType();
|
2008-12-12 04:11:29 +01:00
|
|
|
|
|
|
|
content.Make();
|
|
|
|
}
|
|
|
|
|
2008-12-30 02:05:03 +01:00
|
|
|
request.SendAll();
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
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();
|
|
|
|
}
|