Diff for /parser3/src/include/pa_request.h between versions 1.273 and 1.291

version 1.273, 2026/09/24 02:40:10 version 1.291, 2026/10/23 18:47:40
Line 12 Line 12
   
 #include "pa_pool.h"  #include "pa_pool.h"
 #include "pa_hash.h"  #include "pa_hash.h"
   #include "pa_file.h"
 #include "pa_wcontext.h"  #include "pa_wcontext.h"
 #include "pa_value.h"  #include "pa_value.h"
 #include "pa_vhash.h"  #include "pa_vhash.h"
   #include "pa_vresponse.h"
 #include "pa_stack.h"  #include "pa_stack.h"
 #include "pa_request_info.h"  #include "pa_request_info.h"
 #include "pa_request_charsets.h"  #include "pa_request_charsets.h"
Line 36  const size_t pseudo_file_no__process=1; Line 38  const size_t pseudo_file_no__process=1;
   
 // forwards  // forwards
   
 class Temp_lang;  
 class Methoded;  class Methoded;
 class VMethodFrame;  class VMethodFrame;
 class VMail;  class VMail;
 class VForm;  class VForm;
 class VResponse;  
 class VCookie;  class VCookie;
 class VStateless_class;  class VStateless_class;
 class VConsole;  class VConsole;
   class WebSocket;
 class VException;  class VException;
   
 extern int pa_loop_limit;  extern int pa_loop_limit;
Line 52  extern int pa_array_limit; Line 53  extern int pa_array_limit;
 extern int pa_execute_recursion_limit;  extern int pa_execute_recursion_limit;
 extern int pa_httpd_timeout;  extern int pa_httpd_timeout;
 extern size_t pa_file_size_limit;  extern size_t pa_file_size_limit;
   extern size_t pa_post_max_size;
   
   class Code_cache;
   
 /// Main workhorse.  /// Main workhorse.
 class Request: public PA_Object {  class Request: public PA_Object {
         friend class Temp_lang;  
         friend class Temp_connection;          friend class Temp_connection;
         friend class Temp_request_self;          friend class Temp_request_self;
         friend class Temp_value_element;          friend class Temp_value_element;
Line 63  class Request: public PA_Object { Line 66  class Request: public PA_Object {
         friend class Request_context_saver;          friend class Request_context_saver;
         friend class Exception_trace;          friend class Exception_trace;
         friend class VException;          friend class VException;
           friend class Code_cache_manager;
   
 public:  public:
         class Trace {          class Trace {
Line 118  private: Line 122  private:
                 size_t bottom_index() { return fbottom; }                  size_t bottom_index() { return fbottom; }
                 void set_bottom_index(size_t abottom) { fbottom=abottom; }                  void set_bottom_index(size_t abottom) { fbottom=abottom; }
                 element_type bottom_value() { return get(bottom_index()); }                  element_type bottom_value() { return get(bottom_index()); }
                   void set_range(size_t bottom, size_t top) { fbottom=bottom; fsize=top; }
   
                 void clear() {                  void clear() {
                         fsize=fbottom=0;                          fsize=fbottom=0;
Line 127  private: Line 132  private:
                         return fsize==fbottom;                          return fsize==fbottom;
                 }                  }
   
                 Table &table(Request &r);                  Table &table(Request &r, const String* problem_source) {
                           return table(r, problem_source, bottom_index(), top_index());
                   }
                   Table &table(Request &r, const String* problem_source, size_t bottom, size_t top);
         };          };
   
         ///@{ core data          ///@{ core data
Line 143  private: Line 151  private:
   
         /// endless execute(execute(... preventing counter          /// endless execute(execute(... preventing counter
         int anti_endless_execute_recursion;          int anti_endless_execute_recursion;
           int execute_recursion_limit;
           void recursion_limit_reached();
   
         ///@}          ///@}
   
         /// execution stack          /// execution stack
         Stack<StackItem> stack;          Stack<StackItem> stack;
   
   public:
         /// exception stack trace          /// exception stack trace
         Exception_trace exception_trace;          Exception_trace exception_trace;
 public:  
   
         bool allow_class_replace;          bool allow_class_replace;
   
Line 160  public: Line 170  public:
         VMethodFrame* method_frame;          VMethodFrame* method_frame;
         Value* rcontext;          Value* rcontext;
         WContext* wcontext;          WContext* wcontext;
         /// current language  
         String::Language flang;  
         /// current connection          /// current connection
         SQL_Connection* fconnection;          SQL_Connection* fconnection;
         //@}          //@}
Line 204  public: Line 212  public:
                 core request processing                  core request processing
                 BEWARE: may throw exception to you: catch it!                  BEWARE: may throw exception to you: catch it!
         */          */
         void core(const char* config_filespec, bool header_only, const String& amain_method_name = main_method_name, const String* amain_class_name = NULL);          void core(const char* config_filespec, const String& amain_method_name = main_method_name, const String* amain_class_name = NULL);
   
           /// ^response:stream[part]: the headers go with the first part
           void stream(Value& part);
   
           /// sends headers and sets response.started
           void start(VResponse::Started mode);
   
         /// executes ops          /// executes ops
         void execute(ArrayOperation& ops); // execute.C          void execute(ArrayOperation& ops); // execute.C
Line 239  public: Line 253  public:
   
         /// execute ops with anti-recursion check          /// execute ops with anti-recursion check
         void recursion_checked_execute(ArrayOperation& ops) {          void recursion_checked_execute(ArrayOperation& ops) {
                 if(++anti_endless_execute_recursion>=pa_execute_recursion_limit) {                  if(++anti_endless_execute_recursion>=execute_recursion_limit)
                         anti_endless_execute_recursion=0; // give @exception a chance                          recursion_limit_reached();
                         throw Exception(PARSER_RUNTIME, 0, "call canceled - endless recursion detected");  
                 }  
                 execute(ops); // execute it                  execute(ops); // execute it
                 anti_endless_execute_recursion--;                  anti_endless_execute_recursion--;
         }          }
   
           /// take the recovery reserve back if recursion limit is far enough
           void recursion_limit_try_restore() {
                   if(execute_recursion_limit>pa_execute_recursion_limit && anti_endless_execute_recursion<pa_execute_recursion_limit/2)
                           execute_recursion_limit=pa_execute_recursion_limit;
           }
   
         ///          ///
         void use_file_directly(const String& file_spec, bool fail_on_file_absence=true, bool with_auto_p=false);          void use_file_directly(const String& file_spec, bool fail_on_file_absence=true, bool with_auto_p=false);
   
Line 256  public: Line 274  public:
         /// for @USE only, calls ^use (which may be user-defined)          /// for @USE only, calls ^use (which may be user-defined)
         void use_file(const String& file_name, const String* use_filespec, Operation::Origin origin);          void use_file(const String& file_name, const String* use_filespec, Operation::Origin origin);
   
         /// compiles a @a source buffer          /// compiles a @a source buffer, recording it into @a code if given, or replays the cached @a code
         void use_buf(VStateless_class& aclass, const char* source, const String* main_alias, uint file_no, int line_no_offset=0);          void use_buf(VStateless_class& aclass, const char* source, const String* main_alias, uint file_no, int line_no_offset=0, Code_cache* code=0);
   
         /// processes any code-junction there may be inside of @a value          /// processes any code-junction there may be inside of @a value
         Value& process_getter(Junction& junction); // execute.C          Value& process_getter(Junction& junction); // execute.C
Line 292  public: Line 310  public:
         /// returns relative to @a path  path to @a file           /// returns relative to @a path  path to @a file 
         const String& relative(const char* apath, const String& relative_name);          const String& relative(const char* apath, const String& relative_name);
   
         const String& full_disk_path(const String& relative_name);          /// '/'-normalized disk path of a file name; a uri of another scheme is returned as is if allowed, otherwise throws
           const String& full_disk_path(const String& relative_name, uint allowed=0);
           /// '/'-normalized full_disk_path of a real file on disk, which does not throw: 0 for a uri or a remote, invalid or tainted file:// one
           const String* real_disk_path(const String& name);
   
         /// returns the mime type of 'user_file_name'          /// returns the mime type of 'user_file_name'
         const String& mime_type_of(const String* file_name);          const String& mime_type_of(const String* file_name);
Line 339  public: Line 360  public:
         VCookie& cookie;          VCookie& cookie;
         /// $console          /// $console
         VConsole& console;          VConsole& console;
           /// inited in httpd mode
           WebSocket* websocket;
   
         /// classes configured data          /// classes configured data
         HashString<void*> classes_conf;          HashString<void*> classes_conf;
Line 385  private: Line 408  private:
   
 private: // compile.C  private: // compile.C
   
         ArrayClass& compile(VStateless_class* aclass, const char* source, const String* main_alias, uint file_no, int line_no_offset);          ArrayClass& compile(VStateless_class* aclass, const char* source, const String* main_alias, uint file_no, int line_no_offset, Code_cache* code);
   
 private: // execute.C  private: // execute.C
   
Line 394  private: // execute.C Line 417  private: // execute.C
         Value& get_element4call(Value& ncontext, const String& name);          Value& get_element4call(Value& ncontext, const String& name);
 #endif  #endif
   
 private: // defaults  
   
         const String::Language fdefault_lang;  
   
 private: // mime types  private: // mime types
   
         /// $MAIN:MIME-TYPES          /// $MAIN:MIME-TYPES (table or @GET_MIME-TYPES[] property), built at the first use
         Table *mime_types;          Table *mime_types;
   
 private: // connection manipulation  private: // connection manipulation
Line 424  class VException: public VHashReference Line 443  class VException: public VHashReference
         Exception fexception;          Exception fexception;
         String::Body ffile;          String::Body ffile;
         Value* fhandled;          Value* fhandled;
           size_t ftrace_bottom, ftrace_top;
 public:  public:
         Operation::Origin origin;          Operation::Origin origin;
         const String* problem_source;          const String* problem_source;
Line 435  public: Line 455  public:
         override const VJunction* put_element(const String& name, Value* value);          override const VJunction* put_element(const String& name, Value* value);
   
         Value* handled();          Value* handled();
           Table& stack(Request& r);
           void expire_trace() { ftrace_top=size_t(-1); }
 };  };
   
 /// Auto-object used to save request context across ^try body  /// Auto-object used to save request context across ^try body
 class Request_context_saver {  class Request_context_saver {
         Request& fr;          Request& fr;
   
         /// exception stack trace  
         size_t exception_trace_top;  
         size_t exception_trace_bottom;  
         /// execution stack          /// execution stack
         size_t stack;          size_t stack;
         uint anti_endless_execute_recursion;          int anti_endless_execute_recursion;
         /// contexts          /// contexts
         VMethodFrame* method_frame;          VMethodFrame* method_frame;
         Value* rcontext;          Value* rcontext;
         WContext* wcontext;          WContext* wcontext;
         /// current language  
         String::Language flang;   
         /// current connection          /// current connection
         SQL_Connection* fconnection;          SQL_Connection* fconnection;
   
 public:  public:
         Request_context_saver(Request& ar) :          Request_context_saver(Request& ar) :
                 fr(ar),                  fr(ar),
                 exception_trace_top(ar.exception_trace.top_index()),  
                 exception_trace_bottom(ar.exception_trace.bottom_index()),  
                 stack(ar.stack.top_index()),                  stack(ar.stack.top_index()),
                 anti_endless_execute_recursion(ar.anti_endless_execute_recursion),                  anti_endless_execute_recursion(ar.anti_endless_execute_recursion),
                 method_frame(ar.method_frame),                  method_frame(ar.method_frame),
                 rcontext(ar.rcontext),                  rcontext(ar.rcontext),
                 wcontext(ar.wcontext),                  wcontext(ar.wcontext),
                 flang(ar.flang),  
                 fconnection(ar.fconnection) {}                  fconnection(ar.fconnection) {}
         void restore() {          void restore() {
                 fr.exception_trace.set_top_index(exception_trace_top);  
                 fr.exception_trace.set_bottom_index(exception_trace_bottom);  
                 fr.stack.set_top_index(stack);                  fr.stack.set_top_index(stack);
                 fr.anti_endless_execute_recursion=anti_endless_execute_recursion;                  fr.anti_endless_execute_recursion=anti_endless_execute_recursion;
                 fr.method_frame=method_frame, fr.rcontext=rcontext; fr.wcontext=wcontext;                  fr.method_frame=method_frame, fr.rcontext=rcontext; fr.wcontext=wcontext;
                 fr.flang=flang;  
                 fr.fconnection=fconnection;                  fr.fconnection=fconnection;
         }          }
 };  };

Removed from v.1.273  
changed lines
  Added in v.1.291


E-mail: