/* * This file is a part of CMSLU -- Content Management System like Unix * and is not publicly distributed * * Copyright (c) 2008-2009, Tomasz Sowa * All rights reserved. * */ #include "requestcontroller.h" #include "data.h" #include "log.h" #include "request.h" #include "postparser.h" #include "cookieparser.h" #include "notify.h" RequestController::RequestController() { } 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) } 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); // data.dirs.ReadDirs(); data.users.ReadUsers(); data.groups.ReadGroups(); data.functions.ReadFunctions(); data.mounts.ReadMounts(); data.rebus.Init(); // if( !content.Init() ) return false; return true; } bool RequestController::BaseUrlRedirect() { if( data.base_url_http_host.empty() ) 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; log << log3 << "RC: BaseUrlRedirect from: " << request.env_http_host << logend; return true; } void RequestController::Loop() { while( FCGX_Accept(&request.in, &request.out, &request.err, &request.env) == 0 ) { log << log2 << "---------------------------------------------------------------------------------" << logend; try { request.Clear(); request.Read(); // 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.DeleteOldSessions(); session_manager.SetSession(); // set request.session as well request.session->CheckTimers(); function_parser.Parse(); data.mounts.CalculateCurrentMountType(); content.ReadAdditionalInfo(); content.Make(); } request.SendAll(); notify.ItemChanged(request.notify_code); } 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; } // !! this should be immediately after FCGX_Accept() but signals don't want to break FCGX_Accept if( data.signal_hup ) { FCGX_Finish(); return; } } } SessionContainer::Iterator RequestController::SessionBegin() { return session_manager.SessionBegin(); } SessionContainer::Iterator RequestController::SessionEnd() { return session_manager.SessionEnd(); }