add config options: db_startup_connection_max_attempts - default 0 (infinite) db_startup_connection_attempt_delay - delay in seconds between attempts (default 5) BREAKING CHANGE: WINIX_PLUGIN_INIT plugin message requires to set result status, you have to set the result status to true (env.res) if your plugin was initialized correctly, otherwise winix will not start
315 lines
8.5 KiB
C++
315 lines
8.5 KiB
C++
/*
|
|
* This file is a part of Winix
|
|
* and is distributed under the 2-Clause BSD licence.
|
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
|
*/
|
|
|
|
/*
|
|
* Copyright (c) 2010-2022, Tomasz Sowa
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright notice,
|
|
* this list of conditions and the following disclaimer.
|
|
*
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
*/
|
|
|
|
#ifndef headerfile_winix_core_app
|
|
#define headerfile_winix_core_app
|
|
|
|
#include <iostream>
|
|
#include <ctime>
|
|
#include <unistd.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
#include <pwd.h>
|
|
#include <grp.h>
|
|
#include <errno.h>
|
|
#include <fcgiapp.h>
|
|
|
|
#include "sessionmanager.h"
|
|
#include "db/db.h"
|
|
#include "functions/functions.h"
|
|
#include "templates/templates.h"
|
|
#include "compress.h"
|
|
#include "postparser.h"
|
|
#include "cookieparser.h"
|
|
#include "postmultiparser.h"
|
|
#include "utils/acceptencodingparser.h"
|
|
#include "winixrequest.h"
|
|
#include "log/log.h"
|
|
#include "filelog.h"
|
|
#include "models/winixmodelconnector.h"
|
|
|
|
|
|
namespace Winix
|
|
{
|
|
|
|
|
|
class App
|
|
{
|
|
public:
|
|
|
|
App();
|
|
|
|
bool InitFCGI();
|
|
bool DropPrivileges();
|
|
void InitLoggers();
|
|
Log & GetMainLog();
|
|
void LoadPlugins();
|
|
bool InitializePlugins();
|
|
bool Init();
|
|
void Start();
|
|
void Close();
|
|
void LogUserGroups();
|
|
void LogRequestTime();
|
|
bool Demonize();
|
|
void SetStopSignal();
|
|
bool WasStopSignal();
|
|
bool Lock();
|
|
void Unlock();
|
|
void StartThreads();
|
|
void WaitForThreads();
|
|
|
|
// configuration read from a config file
|
|
Config config;
|
|
|
|
// pointers to the current request and a session
|
|
Cur cur;
|
|
|
|
// temporary one request object
|
|
// current request
|
|
Request req;
|
|
|
|
// users sessions
|
|
SessionManager session_manager;
|
|
|
|
// database (DEPRACATED)
|
|
Db db;
|
|
DbConn db_conn;
|
|
|
|
|
|
|
|
// ...
|
|
System system;
|
|
|
|
// functions (ls, cat, emacs, ...)
|
|
Functions functions;
|
|
|
|
// false at the beginning
|
|
// !! IMPROVE ME moze to do loggera dac?
|
|
bool stdout_is_closed;
|
|
|
|
|
|
|
|
Templates templates;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
enum Header
|
|
{
|
|
h_200,
|
|
h_404,
|
|
h_403
|
|
};
|
|
|
|
PostParser post_parser;
|
|
PostMultiParser post_multi_parser;
|
|
pt::SpaceParser space_parser;
|
|
std::string post_buffer;
|
|
|
|
CookieParser cookie_parser;
|
|
AcceptBaseParser accept_base_parser;
|
|
AcceptEncodingParser accept_encoding_parser;
|
|
Compress compress;
|
|
FCGX_Request fcgi_request;
|
|
int fcgi_socket;
|
|
Synchro synchro;
|
|
pthread_t signal_thread;
|
|
std::string socket_to_send_on_exit;
|
|
std::string send_data_buf;
|
|
pt::WTextStream json_out_stream;
|
|
std::string aheader_name, aheader_value;
|
|
//std::wstring html_filtered;
|
|
//std::string output_8bit;
|
|
pt::TextStream serialized_model;
|
|
|
|
pt::WTextStream output_tmp_filtered_stream;
|
|
BinaryPage output_8bit;
|
|
BinaryPage compressed_output;
|
|
|
|
std::wstring cookie_id_string;
|
|
std::wstring http_header_name;
|
|
std::wstring http_header_value;
|
|
std::string http_header_8bit;
|
|
pt::WTextStream empty_response;
|
|
|
|
WinixModelConnector model_connector; // main thread model connector, each thread has its own connector
|
|
morm::JSONConnector json_connector;
|
|
morm::PostgreSQLConnector postgresql_connector;
|
|
|
|
// objects for main thread
|
|
WinixBase winix_base;
|
|
WinixModelDeprecated winix_model;
|
|
WinixSystem winix_system;
|
|
WinixRequest winix_request;
|
|
// ///////////////////////
|
|
|
|
Plugin plugin;
|
|
|
|
//////////////////////////
|
|
|
|
// log_buffer for the main thread
|
|
pt::WTextStream log_buffer;
|
|
|
|
// logger only for the main thread
|
|
Log log;
|
|
|
|
// file logger, one object for all Log objects
|
|
FileLog file_log;
|
|
|
|
bool AddSystemThreads();
|
|
|
|
bool TranslateFCGInames(char * sock, char * sock_user, char * sock_group);
|
|
bool InitFCGIChmodChownSocket(char * sock, char * sock_user, char * sock_group);
|
|
bool DropPrivileges(char * user, char * group);
|
|
bool DropPrivileges(const char * user, uid_t uid, gid_t gid, bool additional_groups);
|
|
bool CheckAccessFromPlugins();
|
|
void ProcessRequestThrow();
|
|
void ProcessRequest();
|
|
void BaseUrlRedirect(int code, bool add_subdomain);
|
|
bool BaseUrlRedirect();
|
|
void CheckIfNeedSSLredirect();
|
|
void SetLocale();
|
|
void CheckPostRedirect();
|
|
void UseEzcGenerator();
|
|
void AddDefaultModels();
|
|
void Make();
|
|
void SaveSessionsIfNeeded(); // !! IMPROVE ME wywalic do menagera sesji??
|
|
void LogAccess();
|
|
void SendData(const BinaryPage & page, FCGX_Stream * out);
|
|
|
|
void ReadRequest();
|
|
|
|
void SendAnswer();
|
|
void PrepareRawAnswer();
|
|
void PrepareJsonAnswer();
|
|
void PrepareXmlAnswer();
|
|
void PrepareCsvAnswer();
|
|
void PrepareContenerizedAnswer();
|
|
|
|
void PutSeparatorIfNeeded(bool put_separator);
|
|
|
|
void SerializeFieldJson(const wchar_t * field_name);
|
|
|
|
void SerializeStream(const pt::WTextStream & input_stream, const wchar_t * field_name);
|
|
void SerializeStreamJson(const pt::WTextStream & input_stream, const wchar_t * field_name);
|
|
void SerializeStreamXml(const pt::WTextStream & input_stream, const wchar_t * field_name);
|
|
void SerializeStreamCsv(const pt::WTextStream & input_stream, const wchar_t * field_name);
|
|
void SerializeAllFrames();
|
|
void SerializeSpecificFrames();
|
|
void SerializeModels();
|
|
void Send8bitOutput(BinaryPage & output);
|
|
|
|
void SerializeModel(morm::Wrapper & wrapper, const wchar_t * field_name);
|
|
void SerializeModelJson(morm::Wrapper & wrapper, const wchar_t * field_name);
|
|
void SerializeModelXml(morm::Wrapper & wrapper, const wchar_t * field_name);
|
|
void SerializeModelCsv(morm::Wrapper & wrapper, const wchar_t * field_name);
|
|
|
|
void FilterHtmlIfNeeded(const pt::WTextStream & input_stream, BinaryPage & output, bool clear_stream = true);
|
|
|
|
|
|
void LogEnvironmentVariables();
|
|
void LogEnvironmentHTTPVariables();
|
|
void ParseAcceptHeader(const wchar_t * header_name, const std::wstring & env, std::vector<HeaderValue> & container, size_t max_len);
|
|
void ParseAcceptHeader();
|
|
void ParseAcceptLanguageHeader();
|
|
|
|
void SetEnv(const char * name, std::wstring & env);
|
|
void ReadEnvVariables();
|
|
void ReadEnvHTTPVariables();
|
|
bool SaveEnvHTTPVariable(const char * env);
|
|
void ReadEnvRemoteIP();
|
|
void ReadPostJson();
|
|
void ReadPostVars();
|
|
|
|
void CheckIE();
|
|
void CheckKonqueror();
|
|
void CheckRequestMethod();
|
|
void CheckSSL();
|
|
void CheckHtmx();
|
|
void SetSubdomain();
|
|
|
|
bool IsRequestedFrame();
|
|
|
|
Header GetHTTPStatusCode();
|
|
void PrepareSessionCookie();
|
|
void SendHeaders();
|
|
void SendCookies();
|
|
bool AddHeader(const wchar_t * name, const wchar_t * value);
|
|
bool AddHeader(const std::wstring & name, const std::wstring & value);
|
|
bool AddHeader(const wchar_t * name, const pt::WTextStream & value);
|
|
bool AddHeader(const std::wstring & name, const pt::WTextStream & value);
|
|
bool PrepareHeadersStaticCreateResource(pt::WTextStream & out_path);
|
|
void PrepareHeadersStatic();
|
|
void PrepareHeaderContentType();
|
|
void PrepareHeadersForbidden();
|
|
void PrepareHeadersRedirect();
|
|
void PrepareHeadersSendFile();
|
|
void PrepareHeadersCompression(int compress_encoding);
|
|
void PrepareHeadersNormal(Header header, size_t output_size);
|
|
void PrepareHeaders(bool compressing, int compress_encoding, Header header, size_t output_size);
|
|
int SelectDeflateVersion();
|
|
void SelectCompression(size_t source_len, bool & compression_allowed, int & compression_encoding);
|
|
bool CanSendContent();
|
|
void ClearAfterRequest();
|
|
|
|
void LogUser(const char * msg, uid_t id);
|
|
void LogGroup(const char * msg, gid_t id, bool put_logend = true);
|
|
void LogUsers();
|
|
void LogEffectiveGroups(std::vector<gid_t> & tab);
|
|
void LogGroups();
|
|
|
|
static void * SpecialThreadForSignals(void*);
|
|
void SendEmptyFastCGIPacket();
|
|
|
|
void CreateStaticTree();
|
|
|
|
bool DoDatabaseMigration();
|
|
bool TryToMakeDatabaseMigration();
|
|
|
|
|
|
// !! IMPROVE ME
|
|
// !! move to the session manager?
|
|
time_t last_sessions_save;
|
|
};
|
|
|
|
|
|
} // namespace Winix
|
|
|
|
|
|
#endif
|
|
|
|
|