allow a request to be processed in a job
Now we allow a request to be passed into a job queue, and after the job finishes the request is passed into a controller again. In order to achieve this we have a requests queue in System, when we put a request to the job this Request structure is preserved in the queue and for a new request a new Request is added to the queue. while here: - remove App::Lock()/Unlock(), use scoped locking - fix: Plugin now has a Call method which takes ModelConnector and a logger (used in multithreaded environment) - BaseThread has a main_model_connector pointer to the main (from the main thread) model connector - the FastCGI structure fcgi_request moved from App to Request - some methods for handling requests moved from App to Request - small refactoring in main.cpp - add Http class (a http client)
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008-2021, Tomasz Sowa
|
||||
* Copyright (c) 2008-2022, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -34,6 +34,7 @@
|
||||
|
||||
#include "cat.h"
|
||||
|
||||
|
||||
namespace Winix
|
||||
{
|
||||
|
||||
|
||||
@@ -167,6 +167,24 @@ void FunctionBase::Clear()
|
||||
|
||||
|
||||
|
||||
void FunctionBase::ContinueMakePost()
|
||||
{
|
||||
// do nothing by default
|
||||
}
|
||||
|
||||
|
||||
void FunctionBase::ContinueMakeGet()
|
||||
{
|
||||
// do nothing by default
|
||||
}
|
||||
|
||||
void FunctionBase::ContinueMakeDelete()
|
||||
{
|
||||
// do nothing by default
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace Winix
|
||||
|
||||
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
#include "db/db.h"
|
||||
#include "core/request.h"
|
||||
#include "core/config.h"
|
||||
#include "core/system.h"
|
||||
#include "core/synchro.h"
|
||||
#include "notify/notify.h"
|
||||
#include "core/winixrequest.h"
|
||||
@@ -116,6 +115,14 @@ public:
|
||||
virtual void MakeDelete();
|
||||
virtual void Clear();
|
||||
|
||||
/*
|
||||
* called from the jobs thread
|
||||
* objects are locked
|
||||
*/
|
||||
virtual void ContinueMakePost();
|
||||
virtual void ContinueMakeGet();
|
||||
virtual void ContinueMakeDelete();
|
||||
|
||||
|
||||
//void SetConfig(Config * pconfig);
|
||||
//void SetCur(Cur * pcur);
|
||||
@@ -130,7 +137,6 @@ public:
|
||||
protected:
|
||||
|
||||
//Config * config;
|
||||
//Cur * cur;
|
||||
Db * db; // depracated
|
||||
//System * system;
|
||||
Functions * functions;
|
||||
|
||||
@@ -50,22 +50,21 @@ FunctionParser::FunctionParser()
|
||||
}
|
||||
|
||||
|
||||
bool FunctionParser::Parse(Cur * pcur, Db * pdb, Functions * pfunctions, System * psystem)
|
||||
bool FunctionParser::Parse(Request * request, Dirs * dirs, Functions * functions)
|
||||
{
|
||||
db = pdb;
|
||||
cur = pcur;
|
||||
system = psystem;
|
||||
functions = pfunctions;
|
||||
this->request = request;
|
||||
this->dirs = dirs;
|
||||
this->functions = functions;
|
||||
last_dir = nullptr;
|
||||
path = cur->request->env_request_uri.c_str();
|
||||
path = request->env_request_uri.c_str();
|
||||
status = true;
|
||||
|
||||
// IMPROVEME put WINIX_URL_MAX_SIZE to the config
|
||||
if( cur->request->env_request_uri.size() <= WINIX_URL_MAX_SIZE )
|
||||
if( request->env_request_uri.size() <= WINIX_URL_MAX_SIZE )
|
||||
{
|
||||
if( !cur->request->dir_tab.empty() )
|
||||
if( !request->dir_tab.empty() )
|
||||
{
|
||||
last_dir = cur->request->dir_tab.back();
|
||||
last_dir = request->dir_tab.back();
|
||||
PrintCurrentDirs();
|
||||
|
||||
if( ParseDirsItemFunction() )
|
||||
@@ -77,36 +76,74 @@ bool FunctionParser::Parse(Cur * pcur, Db * pdb, Functions * pfunctions, System
|
||||
else
|
||||
{
|
||||
status = false;
|
||||
cur->request->http_status = Header::status_500_internal_server_error;
|
||||
request->http_status = Header::status_500_internal_server_error;
|
||||
log << log1 << "FP: no root directory provided in the request dir_tab" << logend;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = false;
|
||||
cur->request->http_status = Header::status_414_uri_too_long;
|
||||
log << log1 << "FP: the URL is too long: " << cur->request->env_request_uri.size() << logend;
|
||||
request->http_status = Header::status_414_uri_too_long;
|
||||
log << log1 << "FP: the URL is too long: " << request->env_request_uri.size() << logend;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool FunctionParser::ParseDirs(Request * request, Dirs * dirs)
|
||||
{
|
||||
this->request = request;
|
||||
this->dirs = dirs;
|
||||
this->functions = nullptr;
|
||||
last_dir = nullptr;
|
||||
path = request->env_request_uri.c_str();
|
||||
status = true;
|
||||
|
||||
// IMPROVEME put WINIX_URL_MAX_SIZE to the config
|
||||
if( request->env_request_uri.size() <= WINIX_URL_MAX_SIZE )
|
||||
{
|
||||
if( !request->dir_tab.empty() )
|
||||
{
|
||||
last_dir = request->dir_tab.back();
|
||||
PrintCurrentDirs();
|
||||
ParseDirs();
|
||||
}
|
||||
else
|
||||
{
|
||||
status = false;
|
||||
request->http_status = Header::status_500_internal_server_error;
|
||||
log << log1 << "FP: no root directory provided in the request dir_tab" << logend;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = false;
|
||||
request->http_status = Header::status_414_uri_too_long;
|
||||
log << log1 << "FP: the URL is too long: " << request->env_request_uri.size() << logend;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* there should be at least the root directory
|
||||
*/
|
||||
void FunctionParser::PrintCurrentDirs()
|
||||
{
|
||||
std::vector<Item*>::iterator i = cur->request->dir_tab.begin();
|
||||
std::vector<Item*>::iterator i = request->dir_tab.begin();
|
||||
|
||||
for( ; i != cur->request->dir_tab.end() ; ++i)
|
||||
for( ; i != request->dir_tab.end() ; ++i)
|
||||
{
|
||||
LogDir(*i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool FunctionParser::ParseDirsItemFunction()
|
||||
void FunctionParser::ParseDirs()
|
||||
{
|
||||
ReadName();
|
||||
|
||||
@@ -115,6 +152,12 @@ bool FunctionParser::ParseDirsItemFunction()
|
||||
AddDir();
|
||||
ReadName();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool FunctionParser::ParseDirsItemFunction()
|
||||
{
|
||||
ParseDirs();
|
||||
|
||||
if( name.empty() )
|
||||
{
|
||||
@@ -150,7 +193,7 @@ bool FunctionParser::ParseDirsItemFunction()
|
||||
if( !CheckAddFunction() )
|
||||
{
|
||||
log << log3 << "FP: unknown function: " << name << logend;
|
||||
cur->request->http_status = Header::status_404_not_found;
|
||||
request->http_status = Header::status_404_not_found;
|
||||
status = false;
|
||||
return false;
|
||||
}
|
||||
@@ -167,7 +210,7 @@ bool FunctionParser::IsDir()
|
||||
if( name.empty() || !last_dir )
|
||||
return false;
|
||||
|
||||
last_dir = system->dirs.GetDir(name, last_dir->id);
|
||||
last_dir = dirs->GetDir(name, last_dir->id);
|
||||
|
||||
return last_dir != nullptr;
|
||||
}
|
||||
@@ -175,8 +218,8 @@ bool FunctionParser::IsDir()
|
||||
|
||||
bool FunctionParser::CheckAddItem()
|
||||
{
|
||||
// cur->request->dir_tab has at least one element
|
||||
long parent_id = cur->request->dir_tab.back()->id;
|
||||
// request->dir_tab has at least one element
|
||||
long parent_id = request->dir_tab.back()->id;
|
||||
morm::Finder<Item> finder(model_connector);
|
||||
|
||||
finder.
|
||||
@@ -184,33 +227,36 @@ bool FunctionParser::CheckAddItem()
|
||||
where().
|
||||
eq(L"parent_id", parent_id).
|
||||
eq(L"url", name).
|
||||
get(cur->request->item);
|
||||
get(request->item);
|
||||
|
||||
if( cur->request->item.found() )
|
||||
if( request->item.found() )
|
||||
{
|
||||
log << log3 << "FP: Item: id: " << cur->request->item.id << ", url: " << cur->request->item.url << logend;
|
||||
cur->request->last_item = &cur->request->item;
|
||||
cur->request->is_item = true;
|
||||
log << log3 << "FP: Item: id: " << request->item.id << ", url: " << request->item.url << logend;
|
||||
request->last_item = &request->item;
|
||||
request->is_item = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
log << log3 << "FP: No Item: url: " << name << logend;
|
||||
cur->request->http_status = Header::status_404_not_found;
|
||||
request->http_status = Header::status_404_not_found;
|
||||
status = false;
|
||||
}
|
||||
|
||||
return cur->request->item.found();
|
||||
return request->item.found();
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool FunctionParser::CheckAddFunction()
|
||||
{
|
||||
cur->request->function = functions->Find(name);
|
||||
|
||||
if( cur->request->function )
|
||||
if( functions )
|
||||
{
|
||||
log << log3 << "FP: Function: " << cur->request->function->fun.url << logend;
|
||||
request->function = functions->Find(name);
|
||||
}
|
||||
|
||||
if( request->function )
|
||||
{
|
||||
log << log3 << "FP: Function: " << request->function->fun.url << logend;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -231,9 +277,9 @@ void FunctionParser::LogDir(Item * dir)
|
||||
|
||||
void FunctionParser::AddDir()
|
||||
{
|
||||
cur->request->dir_tab.push_back(last_dir);
|
||||
request->dir_tab.push_back(last_dir);
|
||||
LogDir(last_dir);
|
||||
cur->request->last_item = cur->request->dir_tab.back();
|
||||
request->last_item = request->dir_tab.back();
|
||||
}
|
||||
|
||||
|
||||
@@ -302,7 +348,7 @@ void FunctionParser::AddParam()
|
||||
{
|
||||
param.name = name;
|
||||
param.value = value;
|
||||
cur->request->param_tab.push_back(param);
|
||||
request->param_tab.push_back(param);
|
||||
|
||||
log << log3 << "FP: Param: name=" << param.name;
|
||||
|
||||
@@ -323,15 +369,15 @@ void FunctionParser::ParseAnchor()
|
||||
while( *path )
|
||||
name_ascii += GetChar();
|
||||
|
||||
pt::utf8_to_wide(name_ascii, cur->request->anchor);
|
||||
pt::utf8_to_wide(name_ascii, request->anchor);
|
||||
|
||||
if( !cur->request->anchor.empty() )
|
||||
log << log3 << "FP: anchor: " << cur->request->anchor << logend;
|
||||
if( !request->anchor.empty() )
|
||||
log << log3 << "FP: anchor: " << request->anchor << logend;
|
||||
}
|
||||
else
|
||||
if( *path != 0 )
|
||||
{
|
||||
cur->request->http_status = Header::status_400_bad_request;
|
||||
request->http_status = Header::status_400_bad_request;
|
||||
status = false;
|
||||
}
|
||||
}
|
||||
@@ -362,7 +408,7 @@ int FunctionParser::FromHex(int c)
|
||||
}
|
||||
else
|
||||
{
|
||||
cur->request->http_status = Header::status_400_bad_request;
|
||||
request->http_status = Header::status_400_bad_request;
|
||||
status = false;
|
||||
}
|
||||
|
||||
@@ -383,7 +429,7 @@ int c;
|
||||
|
||||
if( c == 0 && status )
|
||||
{
|
||||
cur->request->http_status = Header::status_400_bad_request;
|
||||
request->http_status = Header::status_400_bad_request;
|
||||
status = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008-2021, Tomasz Sowa
|
||||
* Copyright (c) 2008-2022, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -40,7 +40,7 @@
|
||||
#include "core/winixmodeldeprecated.h"
|
||||
#include "db/db.h"
|
||||
#include "core/cur.h"
|
||||
#include "core/system.h"
|
||||
#include "core/dirs.h"
|
||||
|
||||
|
||||
namespace Winix
|
||||
@@ -60,13 +60,15 @@ public:
|
||||
/*
|
||||
* if the method returns false then cur->request->http_status will be already set to a specific error
|
||||
*/
|
||||
bool Parse(Cur * pcur, Db * pdb, Functions * pfunctions, System * psystem);
|
||||
bool Parse(Request * request, Dirs * dirs, Functions * functions);
|
||||
bool ParseDirs(Request * request, Dirs * dirs);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
Db * db;
|
||||
Cur * cur;
|
||||
System * system;
|
||||
Request * request;
|
||||
Dirs * dirs;
|
||||
Functions * functions;
|
||||
|
||||
const wchar_t * path;
|
||||
@@ -79,6 +81,7 @@ private:
|
||||
void SkipSlashes();
|
||||
|
||||
void PrintCurrentDirs();
|
||||
void ParseDirs();
|
||||
bool ParseDirsItemFunction();
|
||||
void ParseParams();
|
||||
void ParseAnchor();
|
||||
|
||||
@@ -170,6 +170,7 @@ Error Functions::CheckSpecialFile(const Item & item)
|
||||
|
||||
cur->mount = system->mounts.GetEmptyMount();
|
||||
system->mounts.ReadMounts(item.item_content.content_raw);
|
||||
system->mounts.CalcCurMount(cur->request);
|
||||
cur->mount = system->mounts.pmount;
|
||||
templates->ReadNewIndexTemplates();
|
||||
templates->ReadNewChangeTemplates();
|
||||
@@ -275,7 +276,7 @@ void Functions::CreateFunctions()
|
||||
Add(fun_who);
|
||||
Add(fun_vim);
|
||||
|
||||
plugin->Call((Session*)0, WINIX_CREATE_FUNCTIONS);
|
||||
plugin->Call(WINIX_CREATE_FUNCTIONS);
|
||||
}
|
||||
|
||||
|
||||
@@ -312,10 +313,15 @@ void Functions::Finish()
|
||||
|
||||
bool Functions::Parse()
|
||||
{
|
||||
return function_parser.Parse(cur, db, this, system);
|
||||
return function_parser.Parse(cur->request, &system->dirs, this);
|
||||
}
|
||||
|
||||
|
||||
bool Functions::ParseOnlyDirs()
|
||||
{
|
||||
return function_parser.ParseDirs(cur->request, &system->dirs);
|
||||
}
|
||||
|
||||
|
||||
void Functions::SetDefaultFunctionForFile()
|
||||
{
|
||||
@@ -494,6 +500,56 @@ void Functions::MakeFunction()
|
||||
}
|
||||
|
||||
|
||||
void Functions::ContinueMakeFunction()
|
||||
{
|
||||
if( !cur->request->function )
|
||||
{
|
||||
cur->request->status = WINIX_ERR_NO_FUNCTION;
|
||||
log << log1 << "Functions: no function (neither cat nor ls)" << logend;
|
||||
return;
|
||||
}
|
||||
|
||||
// if( !system->DirsHaveReadExecPerm() ||
|
||||
// !system->HasReadExecAccess(cur->request->function->fun) ||
|
||||
// !cur->request->function->HasAccess() )
|
||||
// {
|
||||
// cur->request->status = WINIX_ERR_PERMISSION_DENIED;
|
||||
// return;
|
||||
// }
|
||||
|
||||
if( cur->request->method == Request::get )
|
||||
{
|
||||
log << log4 << "Functions: continuing method get for request " << cur->request
|
||||
<< " for function " << cur->request->function->fun.url << logend;
|
||||
cur->request->function->ContinueMakeGet();
|
||||
}
|
||||
else
|
||||
if( cur->request->method == Request::post )
|
||||
{
|
||||
log << log4 << "Functions: continuing method post for request " << cur->request
|
||||
<< " for function " << cur->request->function->fun.url << logend;
|
||||
cur->request->function->ContinueMakePost();
|
||||
}
|
||||
else
|
||||
if( cur->request->method == Request::head )
|
||||
{
|
||||
// do nothing
|
||||
|
||||
// !! IMPROVE ME
|
||||
// we should make a page similar like in a GET request but the content should not be returned only
|
||||
}
|
||||
else
|
||||
if( cur->request->method == Request::delete_ )
|
||||
{
|
||||
log << log4 << "Functions: continuing method delete for request " << cur->request
|
||||
<< " for function " << cur->request->function->fun.url << logend;
|
||||
cur->request->function->ContinueMakeDelete();
|
||||
}
|
||||
else
|
||||
{
|
||||
log << log1 << "Functions: cannot continue a request, unknown request method (skipping)" << logend;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2010-2018, Tomasz Sowa
|
||||
* Copyright (c) 2010-2022, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -151,6 +151,7 @@ public:
|
||||
void Init();
|
||||
void Finish();
|
||||
bool Parse();
|
||||
bool ParseOnlyDirs();
|
||||
size_t FunctionsSize();
|
||||
|
||||
Iterator Begin();
|
||||
@@ -159,6 +160,12 @@ public:
|
||||
void CheckFunctionAndSymlink();
|
||||
void MakeFunction();
|
||||
|
||||
/*
|
||||
* this function is called from the jobs thread
|
||||
* objects are locked
|
||||
*/
|
||||
void ContinueMakeFunction();
|
||||
|
||||
|
||||
//void SetConfig(Config * pconfig);
|
||||
void SetCur(Cur * pcur);
|
||||
|
||||
Reference in New Issue
Block a user