remove Request::post_tab and add Request::http_status

Instead of Reqest::post_tab we use now Request::post_in (pt::Space).

Request::http_status will be used instead Request::status,
but at the moment is not changed in all places.
Request::status has been marked as depracated.

While here:
- Check for root dir in App and not in FunctionParser,
let FunctionParser only log the root dir.
- Read post variables after parsing url parameters,
this allows winix functions to set limits
for post input.
- Set limits when parsing input json format, new
options added to config: post_max_object_items, post_max_table_items,
post_max_all_items, post_max_nested_objects.
There are similar options in each winix function (they are in
FunctionBase).
- Some refactoring in App.
- Add config option: log_whole_http_post if true
then the whole parsed post input is logged.
- Add config option: post_json_max - max length of input stream
for parsing json.
- Add config option: templates_request_status, default request_status.html
this is an ezc template used as [content] when the request status
is not 200_ok.
- Fix: Sort winix function didn't show items to sort (fix and do some
refactoring as well)
- Properly sort items in: ImgCrop, Ls, Sort, Upload
- Remove ezc templates: err_404.html, err_per_denied.html - now
request_status.html is used.
This commit is contained in:
2022-05-30 01:29:18 +02:00
parent 9e222f5b80
commit 7d1fb3c04e
46 changed files with 1224 additions and 835 deletions

View File

@@ -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,7 +34,6 @@
#include "functionparser.h"
#include "core/log.h"
#include "core/error.h"
#include "functions.h"
#include "utf8/utf8.h"
#include "models/item.h"
@@ -51,30 +50,64 @@ FunctionParser::FunctionParser()
}
bool FunctionParser::Parse(Cur * pcur, Db * pdb, Functions * pfunctions, System * psystem)
{
db = pdb;
cur = pcur;
system = psystem;
functions = pfunctions;
last_dir = 0;
last_dir = nullptr;
path = cur->request->env_request_uri.c_str();
status = true;
ParseDirsItemFunction();
ParseParams();
ParseAnchor();
// IMPROVEME put WINIX_URL_MAX_SIZE to the config
if( cur->request->env_request_uri.size() <= WINIX_URL_MAX_SIZE )
{
if( !cur->request->dir_tab.empty() )
{
last_dir = cur->request->dir_tab.back();
PrintCurrentDirs();
return cur->request->status == WINIX_ERR_OK;
if( ParseDirsItemFunction() )
{
ParseParams();
ParseAnchor();
}
}
else
{
status = false;
cur->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;
}
return status;
}
void FunctionParser::ParseDirsItemFunction()
/*
* there should be at least the root directory
*/
void FunctionParser::PrintCurrentDirs()
{
if( !AddRootDir() )
return;
std::vector<Item*>::iterator i = cur->request->dir_tab.begin();
for( ; i != cur->request->dir_tab.end() ; ++i)
{
LogDir(*i);
}
}
bool FunctionParser::ParseDirsItemFunction()
{
ReadName();
while( IsDir() )
@@ -84,43 +117,46 @@ void FunctionParser::ParseDirsItemFunction()
}
if( name.empty() )
return;
{
/*
* no more names to analyze, return now
*/
return true;
}
if( CheckAddFunction() )
return;
if( CheckAddItem() )
{
ReadName();
/*
* the name is a function so return now, we do not parse item
*/
return true;
}
if( !name.empty() )
if( !CheckAddItem() )
{
/*
* the name is not an item so a 404 error was set, return now
*/
return false;
}
/*
* read next name and try if it is a function
*/
ReadName();
if( !name.empty() )
{
if( !CheckAddFunction() )
{
CheckAddFunction();
if( !cur->request->function )
{
log << log3 << "FP: unknown function: " << name << logend;
cur->request->status = WINIX_ERR_NO_ITEM;
}
log << log3 << "FP: unknown function: " << name << logend;
cur->request->http_status = Header::status_404_not_found;
status = false;
return false;
}
}
}
bool FunctionParser::AddRootDir()
{
last_dir = system->dirs.GetRootDir();
if( !last_dir )
{
log << log3 << "FP: there is not a root directory" << logend;
cur->request->status = WINIX_ERR_INTERNAL_ERROR;
return false;
}
AddDir();
return true;
return true;
}
@@ -133,7 +169,7 @@ bool FunctionParser::IsDir()
last_dir = system->dirs.GetDir(name, last_dir->id);
return last_dir != 0;
return last_dir != nullptr;
}
@@ -141,7 +177,6 @@ bool FunctionParser::CheckAddItem()
{
// cur->request->dir_tab has at least one element
long parent_id = cur->request->dir_tab.back()->id;
morm::Finder<Item> finder(model_connector);
finder.
@@ -151,26 +186,20 @@ bool FunctionParser::CheckAddItem()
eq(L"url", name).
get(cur->request->item);
//Error status = db->GetItem(parent_id, name, cur->request->item);
//if( status == WINIX_ERR_OK )
if( cur->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;
return true;
}
else
{
log << log3 << "FP: No Item: url: " << name << logend;
cur->request->status = WINIX_ERR_NO_ITEM;
return false;
cur->request->http_status = Header::status_404_not_found;
status = false;
}
log << log1 << "FP: db error" << logend;
cur->request->status = WINIX_ERR_INTERNAL_ERROR;
return false;
return cur->request->item.found();
}
@@ -185,20 +214,25 @@ bool FunctionParser::CheckAddFunction()
return true;
}
return false;
return false;
}
void FunctionParser::LogDir(Item * dir)
{
log << log3 << "FP: Directory: ";
if( dir->parent_id == -1 )
log << "(root)" << logend;
else
log << dir->url << logend;
}
void FunctionParser::AddDir()
{
cur->request->dir_tab.push_back( last_dir );
log << log3 << "FP: Directory: ";
if( last_dir->parent_id == -1 )
log << "(root)" << logend;
else
log << last_dir->url << logend;
cur->request->dir_tab.push_back(last_dir);
LogDir(last_dir);
cur->request->last_item = cur->request->dir_tab.back();
}
@@ -281,25 +315,25 @@ void FunctionParser::AddParam()
void FunctionParser::ParseAnchor()
{
if( *path == 0 )
return;
if( *path != '#' )
if( *path == '#' )
{
cur->request->status = WINIX_ERR_INCORRECT_URI;
return;
}
path += 1;
name_ascii.clear();
path += 1;
name_ascii.clear();
while( *path )
name_ascii += GetChar();
pt::utf8_to_wide(name_ascii, cur->request->anchor);
while( *path )
name_ascii += GetChar();
if( !cur->request->anchor.empty() )
log << log3 << "FP: anchor: " << cur->request->anchor << logend;
pt::utf8_to_wide(name_ascii, cur->request->anchor);
if( !cur->request->anchor.empty() )
log << log3 << "FP: anchor: " << cur->request->anchor << logend;
}
else
if( *path != 0 )
{
cur->request->http_status = Header::status_400_bad_request;
status = false;
}
}
@@ -313,17 +347,26 @@ void FunctionParser::SkipSlashes()
int FunctionParser::FromHex(int c)
{
if( c>='0' && c<='9' )
{
return c - '0';
}
else
if( c>='a' && c<='f' )
{
return c - 'a' + 10;
}
else
if( c>='A' && c<='F' )
{
return c - 'A' + 10;
}
else
cur->request->status = WINIX_ERR_INCORRECT_URI;
{
cur->request->http_status = Header::status_400_bad_request;
status = false;
}
return 0;
return 0;
}
@@ -338,8 +381,11 @@ int c;
{
c = (FromHex(*(path+1)) << 4) + FromHex(*(path+2));
if( c == 0 )
cur->request->status = WINIX_ERR_INCORRECT_URI;
if( c == 0 && status )
{
cur->request->http_status = Header::status_400_bad_request;
status = false;
}
path += 3;
}
@@ -355,7 +401,7 @@ int c;
path += 1;
}
return c;
return c;
}