/* * This file is a part of Winix * and is distributed under the 2-Clause BSD licence. * Author: Tomasz Sowa */ /* * Copyright (c) 2010-2024, 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_functions_functionbase #define headerfile_winix_functions_functionbase #include #include "core/request.h" #include "core/winixrequest.h" #include "models/helpers/winixezchelper.h" #include "models/item.h" #include "notify/notify.h" namespace Winix { class Functions; class Templates; class FunctionBase : public WinixRequest { public: FunctionBase(); virtual ~FunctionBase(); // user, group, permissions, url (function name) Item fun; // auto follow sym links, default: true bool follow_symlinks; // html template index (for using with 'patterns' object) size_t template_index; // try to use SSL // if in the config 'use_ssl' is true and 'use_ssl_only_for_logged_users' is true // then ssl is used only for logged users but sometimes there is a need to use // SSL even if noone is logged (for example for such functions like 'login' or 'adduser') // default: false // (this option is ignored if 'use_ssl' in the config is false) bool need_ssl; // true if the function need a session object // if false then a temporary session is used bool need_session; // true if the function allows to register default models such as 'request', 'item', etc. // default: true bool register_default_models; // maximum key/value pairs in one object when parsing post json structure // default: 0 - means get the value from the config size_t post_max_object_items; // maximum items in one table when parsing post json structure // default: 0 - means get the value from the config size_t post_max_table_items; // maximum items (key/values pairs of objects or table items) througout the whole post input json structure // default: 0 - means get the value from the config size_t post_max_all_items; // maximum nested objects/tables when parsing post json structure // default: 0 - means get the value from the config size_t post_max_nested_objects; void set_functions(Functions * pfunctions); void set_templates(Templates * ptemplates); virtual void init(); virtual void finish(); virtual void add_allow_methods_header(); virtual bool is_cors_method_available(Request::Method method); virtual bool is_origin_available(const std::wstring & origin_url); virtual bool are_cors_credentials_available(); virtual bool are_cors_headers_available(const std::wstring & headers); virtual void add_access_control_allow_methods_header(Request::Method method); virtual void add_access_control_allow_origin_header(const std::wstring & origin_url); virtual void add_access_control_allow_headers_header(const std::wstring & headers); virtual void add_access_control_max_age_header(); virtual void add_access_control_allow_credentials_header(); virtual void add_access_control_expose_headers_header(); virtual void add_cors_preflight_request_headers(const std::wstring & origin, Request::Method method, const std::wstring * request_headers); virtual void add_cors_normal_request_headers(const std::wstring & origin); virtual void check_cors_preflight_request(const std::wstring & origin, const std::wstring & method_string); virtual void add_response_headers_for_origin(const std::wstring & origin); virtual void check_origin_header(); /* * - at the beginning call one of has_*_access() depending on the http method * by default all of them call has_access() * - next call start_request() * - call one of make_*() methods * - if the request is assigned to a job then call clear() and one of continue_make_*() methods * this call is made from a job thread (with locking mechanism) * - if the request is still assigned to a job then call clear() and continue_make_*() again * (this can create a loop of clear() and continue_make_*() calls) * - if the request is not assigned to a job_request then call finish_request() and clear() * */ virtual bool has_access(); virtual bool has_get_access(); virtual bool has_head_access(); virtual bool has_post_access(); virtual bool has_put_access(); virtual bool has_delete_access(); virtual bool has_connect_access(); virtual bool has_options_access(); virtual bool has_trace_access(); virtual bool has_patch_access(); virtual void start_request(); virtual void make_get(); virtual void make_head(); virtual void make_post(); virtual void make_put(); virtual void make_delete(); virtual void make_connect(); virtual void make_options(); virtual void make_trace(); virtual void make_patch(); virtual void finish_request(); virtual void clear(); /* * continue_make_* methods are called from the jobs thread * objects are locked */ virtual void continue_make_get(); virtual void continue_make_head(); virtual void continue_make_post(); virtual void continue_make_put(); virtual void continue_make_delete(); virtual void continue_make_connect(); virtual void continue_make_options(); virtual void continue_make_trace(); virtual void continue_make_patch(); virtual bool need_to_copy_raw_post(); virtual bool can_push_url_to_browser_history(); virtual void add_standard_models(); virtual void prepare_doc_url(const wchar_t * local_url, pt::WTextStream & url); virtual void prepare_doc_url(const wchar_t * local_url, std::wstring & url); virtual std::wstring prepare_doc_url(const wchar_t * local_url = nullptr); virtual std::wstring prepare_doc_url(const std::wstring & local_url); virtual void prepare_current_dir(const wchar_t * local_url, pt::WTextStream & url); virtual void prepare_current_dir(const wchar_t * local_url, std::wstring & url); virtual std::wstring prepare_current_dir(const wchar_t * local_url = nullptr); virtual std::wstring prepare_current_dir(const std::wstring & local_url); virtual void prepare_current_item(const wchar_t * local_url, pt::WTextStream & url); virtual void prepare_current_item(const wchar_t * local_url, std::wstring & url); virtual std::wstring prepare_current_item(const wchar_t * local_url); virtual std::wstring prepare_current_item(const std::wstring & local_url); virtual void prepare_current_function(const wchar_t * local_url, pt::WTextStream & url); virtual void prepare_current_function(const wchar_t * local_url, std::wstring & url); virtual std::wstring prepare_current_function(const wchar_t * local_url); virtual std::wstring prepare_current_function(const std::wstring & local_url); virtual void redirect_to(const wchar_t * url, bool append_domain = true); virtual void redirect_to(const std::wstring & url, bool append_domain = true); virtual void redirect_to(const pt::WTextStream & url, bool append_domain = true); virtual void redirect_to(const wchar_t * url, const wchar_t * frame_url, const wchar_t * dom_target); virtual void redirect_to(const std::wstring & url, const std::wstring & frame_url, const std::wstring & dom_target); virtual void redirect_to(pt::WTextStream & url, pt::WTextStream & frame_url, pt::WTextStream & dom_target); virtual void redirect_to(pt::WTextStream & url, pt::WTextStream & frame_url, const wchar_t * dom_target); virtual void redirect_to(const wchar_t * url, const wchar_t * frame_url, pt::WTextStream & dom_target); virtual void retarged(const wchar_t * frame, const wchar_t * dom_target, const wchar_t * push_url = nullptr, const wchar_t * swap_algorithm = nullptr); virtual void retarged(const std::wstring & frame, const std::wstring & dom_target, const std::wstring & push_url, const wchar_t * swap_algorithm = nullptr); virtual void retarged(const wchar_t * frame, pt::WTextStream & dom_target, const wchar_t * push_url = nullptr, const wchar_t * swap_algorithm = nullptr); virtual void remove_content(pt::WTextStream & dom_target, bool close_dialogs = false); virtual void remove_content(const wchar_t * dom_target, bool has_postfix, long dom_target_postfix, bool close_dialogs = false); virtual void remove_content(const wchar_t * dom_target, long dom_target_postfix, bool close_dialogs = false); virtual void remove_content(const wchar_t * dom_target, bool close_dialogs = false); virtual void update_content(const wchar_t * frame, pt::WTextStream & dom_target, bool close_dialogs = false); virtual void update_content(const wchar_t * frame, const wchar_t * dom_target, bool has_postfix, long dom_target_postfix, bool close_dialogs = false); virtual void update_content(const wchar_t * frame, const wchar_t * dom_target, long dom_target_postfix, bool close_dialogs = false); virtual void update_content(const wchar_t * frame, const wchar_t * dom_target, bool close_dialogs = false); virtual void close_modal_dialogs(); virtual void push_url_to(const wchar_t * local_url = nullptr); virtual void push_url_to(const pt::Stream & local_url); virtual void push_url_to_current_dir(const wchar_t * local_url = nullptr); virtual void push_url_to_current_item(const wchar_t * local_url = nullptr); virtual void push_url_to_current_function(const wchar_t * local_url = nullptr); virtual void redirect_to_current_dir(); virtual void redirect_to_current_item(); virtual void redirect_to_current_function(); virtual void redirect_if_needed(bool was_url_changed = false); /* * DEPRECATED * for backward compatibility */ virtual void Init(); virtual void Finish(); virtual bool HasAccess(); virtual void Clear(); virtual void MakeGet(); virtual void MakeHead(); virtual void MakePost(); virtual void MakePut(); virtual void MakeDelete(); virtual void MakeConnect(); virtual void MakeOptions(); virtual void MakeTrace(); virtual void MakePatch(); virtual void ContinueMakeGet(); virtual void ContinueMakeHead(); virtual void ContinueMakePost(); virtual void ContinueMakePut(); virtual void ContinueMakeDelete(); virtual void ContinueMakeConnect(); virtual void ContinueMakeOptions(); virtual void ContinueMakeTrace(); virtual void ContinueMakePatch(); protected: Functions * functions; Templates * templates; WinixEzcHelper winix_ezc_helper; /* * * in make_*() methods you can assing your controller methods in such a way: * assign_methods(this, * by_param(L"paramoption", &MyController::MyMethod3), * by_param(L"paramoption1", L"paramoption2", &MyController::MyMethod2), * by_param_post(L"paramoption", L"postoption", &MyController::MyMethod1) * ); * */ template struct by_param { const wchar_t * param1; const wchar_t * param2; // can be null void (Controller::*method)(); by_param(const wchar_t * param1, void (Controller::*method)()) { this->param1 = param1; this->param2 = nullptr; this->method = method; } by_param(const wchar_t * param1, const wchar_t * param2, void (Controller::*method)()) { this->param1 = param1; this->param2 = param2; this->method = method; } }; template struct by_param_post { const wchar_t * param; const wchar_t * post; void (Controller::*method)(); by_param_post(const wchar_t * param, const wchar_t * post, void (Controller::*method)()) { this->param = param; this->post = post; this->method = method; } }; template void assign_methods_internal(ControllerName * controller) { } template void assign_methods_internal(Controller * controller, const by_param & assign_by, AssignMethods... controller_methods) { if( cur->request->IsParam(assign_by.param1) && (!assign_by.param2 || cur->request->IsParam(assign_by.param2)) ) { (controller->*assign_by.method)(); } else { assign_methods_internal(controller, controller_methods...); } } template void assign_methods_internal(Controller * controller, const by_param_post & assign_by, AssignMethods... controller_methods) { if( cur->request->IsParam(assign_by.param) && (cur->request->IsPostVar(assign_by.post)) ) { (controller->*assign_by.method)(); } else { assign_methods_internal(controller, controller_methods...); } } template void assign_methods(Controller * controller, AssignMethods... controller_methods) { assign_methods_internal(controller, controller_methods...); } }; } // namespace Winix #endif