Annotation of parser3/src/include/pa_request.h, revision 1.160.2.37.2.14
1.61 paf 1: /** @file
1.62 paf 2: Parser: request class decl.
3:
1.160.2.9 paf 4: Copyright (c) 2001-2003 ArtLebedev Group (http://www.artlebedev.com)
1.121 paf 5: Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
1.1 paf 6: */
7:
8: #ifndef PA_REQUEST_H
9: #define PA_REQUEST_H
1.141 paf 10:
1.160.2.37.2. 4(paf 11:3): static const char* IDENT_REQUEST_H="$Date: 2003/03/26 13:46:58 $";
1.1 paf 12:
1.5 paf 13: #include "pa_hash.h"
1.7 paf 14: #include "pa_wcontext.h"
1.6 paf 15: #include "pa_value.h"
1.7 paf 16: #include "pa_stack.h"
1.160.2.6 paf 17: #include "pa_request_info.h"
18: #include "pa_request_charsets.h"
1.160.2.8 paf 19: #include "pa_sapi.h"
1.44 paf 20:
1.112 paf 21: #ifdef RESOURCES_DEBUG
22: #include <sys/resource.h>
23: #endif
24:
1.128 paf 25: // consts
26:
1.160.2.35 paf 27: const uint ANTI_ENDLESS_EXECUTE_RECOURSION=1000;
1.128 paf 28:
1.160.2.8 paf 29: // forwards
30:
1.39 paf 31: class Temp_lang;
1.84 paf 32: class Methoded;
1.116 paf 33: class VMethodFrame;
1.160.2.30 paf 34: class GdomeDOMString_auto_ptr;
1.160.2.37.2. 3(paf 35:3): class VMail;
36:3): class VForm;
37:3): class VResponse;
38:3): class VCookie;
39:3): class VStateless_class;
1.1 paf 40:
1.61 paf 41: /// Main workhorse.
1.160.2.6 paf 42: class Request: public PA_Object {
1.107 paf 43: friend class Temp_lang;
1.117 paf 44: friend class Temp_connection;
1.148 paf 45: friend class Request_context_saver;
1.155 paf 46: friend class Temp_request_self;
1.160.2.6 paf 47:
1.160.2.7 paf 48: ///@{ core data
49:
50: /// classes
1.160.2.8 paf 51: HashStringValue fclasses;
1.160.2.7 paf 52:
53: /// already used files to avoid cyclic uses
1.160.2.37.2. 0(paf 54:3): Hash<const StringBody, bool> used_files;
1.160.2.7 paf 55:
56: /** endless execute(execute(... preventing counter
57: @see ANTI_ENDLESS_EXECUTE_RECOURSION
58: */
59: uint anti_endless_execute_recoursion;
60:
61: ///@}
62:
1.160.2.37.2. (paf 63:): union StackItem {
64:): const String* string() const { return value->get_string(); }
65:): Value* value;
66:): ArrayOperation* ops;
67:): VMethodFrame* method_frame;
1.160.2.12 paf 68:
69: /// needed to fill unused Array entries
70: StackItem() {}
1.160.2.37.2. (paf 71:): StackItem(Value* avalue): value(avalue) {}
72:): StackItem(ArrayOperation* aops): ops(aops) {}
73:): StackItem(VMethodFrame* amethod_frame): method_frame(amethod_frame) {}
1.160.2.12 paf 74: };
75:
1.160.2.37.2. 4(paf 76:3): /// execution stack
77:3): Stack<StackItem> stack;
78:3):
79:3): public:
80:3):
1.160.2.6 paf 81: //@{ request processing status
82: /// exception stack trace
1.160.2.37.2. (paf 83:): //Stack<String*> exception_trace;
1.160.2.6 paf 84: /// contexts
1.160.2.37.2. (paf 85:): VMethodFrame* method_frame;
86:): Value* rcontext;
87:): WContext* wcontext;
1.160.2.6 paf 88: /// current language
1.160.2.37.2. (paf 89:): String::Language flang;
1.160.2.6 paf 90: /// current connection
1.160.2.37.2. (paf 91:): SQL_Connection* fconnection;
1.160.2.6 paf 92: //@}
93: /// interrupted flag, raised on signals [SIGPIPE]
94: bool finterrupted;
95:
1.1 paf 96: public:
1.160.2.37.2. 4(paf 97:3):
98:3): /// @see Stack::wipe_unused
99:3): void wipe_unused_execution_stack() {
100:3): stack.wipe_unused();
101:3): }
1.112 paf 102:
103: #ifdef RESOURCES_DEBUG
104: /// measures
105: double sql_connect_time;
106: double sql_request_time;
107: #endif
1.61 paf 108:
1.160.2.37.2. (paf 109:): Request(SAPI_Info& asapi_info, Request_info& arequest_info,
110:): String::Language adefault_lang, ///< all tainted data default untainting lang
1.110 paf 111: bool status_allowed ///< status class allowed
1.50 paf 112: );
1.118 paf 113: ~Request();
1.1 paf 114:
1.61 paf 115: /// global classes
1.160.2.8 paf 116: HashStringValue& classes() { return fclasses; }
1.6 paf 117:
1.65 paf 118: /**
119: core request processing
120:
121: BEWARE: may throw exception to you: catch it!
122: */
123: void core(
1.160.2.9 paf 124: const char* config_filespec, ///< system config filespec
1.138 paf 125: bool config_fail_on_read_problem, ///< fail if system config file not found
1.65 paf 126: bool header_only);
1.17 paf 127:
1.61 paf 128: /// executes ops
1.160.2.12 paf 129: void execute(ArrayOperation& ops); // execute.C
1.127 paf 130: /// execute ops with anti-recoursion check
1.160.2.37.2. (paf 131:): void recoursion_checked_execute(/*const String& name, */ArrayOperation& ops) {
1.128 paf 132: // anti_endless_execute_recoursion
133: if(++anti_endless_execute_recoursion==ANTI_ENDLESS_EXECUTE_RECOURSION) {
134: anti_endless_execute_recoursion=0; // give @exception a chance
135: throw Exception("parser.runtime",
1.160.2.37.2. (paf 136:): 0, //&name,
1.128 paf 137: "call canceled - endless recursion detected");
138: }
1.147 paf 139: execute(ops); // execute it
1.128 paf 140: anti_endless_execute_recoursion--;
141: }
1.40 paf 142:
1.64 paf 143: /// compiles the file, maybe forcing it's class @a name and @a base_class.
1.160.2.37 paf 144: void use_file(VStateless_class& aclass,
1.160.2.37.2. (paf 145:): const String& file_name,
1.149 paf 146: bool ignore_class_path=false,
1.160.2.8 paf 147: bool fail_on_read_problem=true, bool fail_on_file_absence=true); // pa_request.C
1.64 paf 148: /// compiles a @a source buffer
1.160.2.37 paf 149: void use_buf(VStateless_class& aclass,
1.160.2.9 paf 150: const char* source,
1.160.2.37.2. (paf 151:): const String& filespec, const char* filespec_cstr); // pa_request.C
1.28 paf 152:
1.129 paf 153: /// processes any code-junction there may be inside of @a value
1.160.2.37.2. (paf 154:): StringOrValue process(Value& input_value, bool intercept_string=true); // execute.C
1.129 paf 155: //@{ convinient helpers
1.160.2.37.2. (paf 156:): const String& process_to_string(Value& input_value) {
157:): return process(input_value, true/*intercept_string*/).as_string();
1.129 paf 158: }
1.160.2.37.2. (paf 159:): Value& process_to_value(Value& input_value, bool intercept_string=true) {
1.129 paf 160: return process(input_value, intercept_string).as_value();
1.126 paf 161: }
162: //@}
1.131 paf 163:
1.126 paf 164:
1.131 paf 165: #define DEFINE_DUAL(modification) \
166: void write_##modification##_lang(StringOrValue dual) { \
1.160.2.37.2. (paf 167:): if(const String* string=dual.get_string()) \
1.132 paf 168: write_##modification##_lang(*string); \
169: else \
1.160.2.37.2. (paf 170:): write_##modification##_lang(*dual.get_value()); \
1.132 paf 171: }
1.131 paf 172:
1.61 paf 173: /// appending, sure of clean string inside
1.65 paf 174: void write_no_lang(const String& astring) {
1.111 paf 175: wcontext->write(astring,
1.160.2.37.2. (paf 176:): (String::Language)(String::L_CLEAN | flang&String::L_OPTIMIZE_BIT));
1.49 paf 177: }
1.131 paf 178: /// appending sure value, that would be converted to clean string
1.160.2.37.2. (paf 179:): void write_no_lang(Value& avalue) {
1.131 paf 180: if(wcontext->get_in_expression())
1.160.2.37.2. (paf 181:): wcontext->write(avalue);
1.131 paf 182: else
1.160.2.37.2. (paf 183:): wcontext->write(avalue,
184:): (String::Language)(String::L_CLEAN | flang&String::L_OPTIMIZE_BIT));
1.131 paf 185: }
186:
1.61 paf 187: /// appending string, passing language built into string being written
1.65 paf 188: void write_pass_lang(const String& astring) {
1.160.2.37.2. (paf 189:): wcontext->write(astring, String::L_PASS_APPENDED);
1.59 paf 190: }
1.131 paf 191: /// appending possible string, passing language built into string being written
1.160.2.37.2. (paf 192:): void write_pass_lang(Value& avalue) {
193:): wcontext->write(avalue, String::L_PASS_APPENDED);
1.131 paf 194: }
195: DEFINE_DUAL(pass)
196:
1.61 paf 197: /// appending possible string, assigning untaint language
1.160.2.37.2. (paf 198:): void write_assign_lang(Value& avalue) {
199:): wcontext->write(avalue, flang);
1.132 paf 200: }
1.106 parser 201: /// appending string, assigning untaint language
202: void write_assign_lang(const String& astring) {
203: wcontext->write(astring, flang);
1.22 paf 204: }
1.131 paf 205: DEFINE_DUAL(assign)
1.22 paf 206:
1.64 paf 207: /// returns relative to @a path path to @a file
1.160.2.37.2. (paf 208:): const String& relative(const char* apath, const String& relative_name);
1.61 paf 209:
1.64 paf 210: /// returns an absolute @a path to relative @a name
1.160.2.37.2. (paf 211:): const String& absolute(const String& relative_name);
1.42 paf 212:
1.80 paf 213: /// returns the mime type of 'user_file_name_cstr'
1.160.2.37.2. (paf 214:): const String& mime_type_of(const char* user_file_name_cstr);
1.80 paf 215:
1.117 paf 216: /// returns current SQL connection if any
1.160.2.37.2. (paf 217:): SQL_Connection* connection(bool fail_on_error=true) {
218:): if(fail_on_error && !fconnection)
1.125 paf 219: throw Exception("parser.runtime",
1.160.2.37.2. (paf 220:): 0,
1.117 paf 221: "outside of 'connect' operator");
222:
223: return fconnection;
1.133 paf 224: }
225:
1.160.2.36 paf 226: void set_interrupted(bool ainterrupted) { finterrupted=ainterrupted; }
227: bool get_interrupted() { return finterrupted; }
1.158 paf 228:
1.17 paf 229: public:
1.22 paf 230:
1.61 paf 231: /// info from web server
1.160.2.8 paf 232: Request_info& request_info;
233:
234: /// info about ServerAPI
235: SAPI_Info& sapi_info;
1.160.2.2 paf 236:
237: /// source, client, mail charsets
1.160.2.6 paf 238: Request_charsets charsets;
1.53 paf 239:
1.154 paf 240: /// 'MAIN' class conglomerat & operators are methods of this class
1.160.2.37.2. (paf 241:): VStateless_class& main_class;
1.86 paf 242: /// $form:elements
1.160.2.37.2. (paf 243:): VForm& form;
1.140 paf 244: /// $mail
1.160.2.37.2. (paf 245:): VMail& mail;
1.86 paf 246: /// $response:elements
1.160.2.37.2. (paf 247:): VResponse& response;
1.86 paf 248: /// $cookie:elements
1.160.2.37.2. (paf 249:): VCookie& cookie;
1.70 paf 250:
1.148 paf 251: /// classes configured data
1.160.2.20 paf 252: HashStringObject classes_conf;
1.85 paf 253:
1.148 paf 254: public: // status read methods
1.76 paf 255:
1.148 paf 256: VMethodFrame *get_method_frame() { return method_frame; }
1.160.2.37.2. (paf 257:): Value& get_self();
258:): #define GET_SELF(request, type) (static_cast<type &>(request.get_self()))
1.160.2.18 paf 259: /* for strange reason call to this:
260: r.get_self<VHash>()
261: refuses to compile
262:
263: template<typename T> T& get_self() {
264: return *static_cast<T*>(get_self().get());
265: }
266: */
1.160.2.30 paf 267:
268: #ifdef XML
269: public: // charset helpers
270:
271: /// @see Charset::transcode
1.160.2.37.2. (paf 272:): GdomeDOMString_auto_ptr transcode(const String& s);
2(paf 273:3): /// @see Charset::transcode
274:3): GdomeDOMString_auto_ptr transcode(const StringBody s);
1.160.2.30 paf 275: /// @see Charset::transcode
1.160.2.37.2. 1(paf 276:3): const String& transcode(GdomeDOMString* s);
1.160.2.31 paf 277: /// @see Charset::transcode
1.160.2.37.2. 1(paf 278:3): const String& transcode(xmlChar* s);
1.160.2.31 paf 279:
1.160.2.30 paf 280: #endif
1.87 paf 281:
1.136 paf 282: private:
283:
284: /// already executed some @conf method
285: bool configure_admin_done;
286:
1.160.2.37.2. (paf 287:): void configure_admin(VStateless_class& conf_class);
1.99 parser 288:
1.7 paf 289: private: // compile.C
290:
1.160.2.37.2. (paf 291:): VStateless_class& compile(VStateless_class* aclass, const char* source, const char* file);
1.7 paf 292:
293: private: // execute.C
294:
1.139 paf 295: /// for @postprocess[body]
1.160.2.37.2. (paf 296:): const String& execute_method(VMethodFrame& amethodFrame, const Method& method);
1.139 paf 297: //{ for @conf[filespec] and @auto[filespec]
1.160.2.37.2. (paf 298:): const String* execute_method(Value& aself,
299:): const Method& method, VString* optional_param,
1.160.2.10 paf 300: bool do_return_string);
1.160.2.25 paf 301: struct Execute_nonvirtual_method_result {
1.160.2.37.2. (paf 302:): const String* string;
303:): Method* method;
304:): Execute_nonvirtual_method_result(): string(0), method(0) {}
1.160.2.25 paf 305: };
306: Execute_nonvirtual_method_result execute_nonvirtual_method(VStateless_class& aclass,
1.160.2.37.2. (paf 307:): const String& method_name, VString* optional_param,
1.160.2.25 paf 308: bool do_return_string);
1.139 paf 309: //}
310: /// for @main[]
1.160.2.37.2. (paf 311:): const String* execute_virtual_method(Value& aself, const String& method_name);
1.9 paf 312:
1.160.2.37.2. (paf 313:): Value* get_element(bool can_call_operator);
1.22 paf 314:
1.58 paf 315: private: // defaults
316:
1.160.2.37.2. (paf 317:): const String::Language fdefault_lang;
1.80 paf 318:
319: private: // mime types
320:
321: /// $MAIN:MIME-TYPES
322: Table *mime_types;
1.22 paf 323:
1.39 paf 324: private: // lang manipulation
1.22 paf 325:
1.160.2.37.2. (paf 326:): String::Language set_lang(String::Language alang) {
327:): String::Language result=flang;
1.39 paf 328: flang=alang;
329: return result;
330: }
1.160.2.37.2. (paf 331:): void restore_lang(String::Language alang) {
1.39 paf 332: flang=alang;
333: }
334:
1.117 paf 335: private: // connection manipulation
336:
1.160.2.37.2. (paf 337:): SQL_Connection* set_connection(SQL_Connection* aconnection) {
338:): SQL_Connection* result=fconnection;
1.117 paf 339: fconnection=aconnection;
340: return result;
341: }
1.160.2.37.2. (paf 342:): void restore_connection(SQL_Connection* aconnection) {
1.117 paf 343: fconnection=aconnection;
344: }
345:
346: private:
347:
1.160.2.37.2. (paf 348:): void output_result(VFile* body_file, bool header_only, bool as_attachment);
1.148 paf 349: };
350:
351: /// Auto-object used to save request context across ^try body
352: class Request_context_saver {
353: Request& fr;
354:
355: /// exception stack trace
356: int exception_trace;
357: /// execution stack
358: int stack;
359: /// contexts
360: VMethodFrame *method_frame;
361: Value *rcontext;
362: WContext *wcontext;
363: /// current language
1.160.2.37.2. (paf 364:): String::Language flang;
1.148 paf 365: /// current connection
1.160.2.37.2. (paf 366:): SQL_Connection* fconnection;
1.126 paf 367:
1.148 paf 368: public:
369: Request_context_saver(Request& ar) :
1.160.2.37.2. (paf 370:): //exception_trace(ar.exception_trace.top_index()),
1.148 paf 371: stack(ar.stack.top_index()),
372: method_frame(ar.method_frame),
373: rcontext(ar.rcontext),
374: wcontext(ar.wcontext),
375: flang(ar.flang),
376: fconnection(ar.fconnection),
377: fr(ar) {}
1.153 paf 378: void restore() {
1.160.2.37.2. (paf 379:): //fr.exception_trace.top_index(exception_trace);
1.148 paf 380: fr.stack.top_index(stack);
1.157 paf 381: fr.method_frame=method_frame, fr.rcontext=rcontext; fr.wcontext=wcontext;
1.148 paf 382: fr.flang=flang;
383: fr.fconnection=fconnection;
384: }
1.39 paf 385: };
386:
1.61 paf 387: /// Auto-object used for temporary changing Request::flang.
1.39 paf 388: class Temp_lang {
389: Request& frequest;
1.160.2.37.2. (paf 390:): String::Language saved_lang;
1.39 paf 391: public:
1.160.2.37.2. (paf 392:): Temp_lang(Request& arequest, String::Language alang) :
1.39 paf 393: frequest(arequest),
394: saved_lang(arequest.set_lang(alang)) {
395: }
396: ~Temp_lang() {
397: frequest.restore_lang(saved_lang);
1.117 paf 398: }
399: };
400:
401: /// Auto-object used for temporary changing Request::fconnection.
402: class Temp_connection {
403: Request& frequest;
1.160.2.37.2. (paf 404:): SQL_Connection* saved_connection;
1.117 paf 405: public:
1.160.2.37.2. (paf 406:): Temp_connection(Request& arequest, SQL_Connection* aconnection) :
1.117 paf 407: frequest(arequest),
408: saved_connection(arequest.set_connection(aconnection)) {
409: }
410: ~Temp_connection() {
411: frequest.restore_connection(saved_connection);
1.39 paf 412: }
1.4 paf 413: };
1.160.2.7 paf 414:
1.160.2.15 paf 415:
416: // defines for externs
417:
418: #define CONTENT_DISPOSITION_NAME "content-disposition"
419: #define CONTENT_DISPOSITION_VALUE "attachment"
420: #define CONTENT_DISPOSITION_FILENAME_NAME "filename"
421:
1.160.2.7 paf 422: // externs
423:
1.160.2.37.2. (paf 424:): extern const String main_method_name;
425:): extern const String auto_method_name;
426:): extern const String body_name;
427:): extern const String content_disposition_name;
428:): extern const String content_disposition_value;
429:): extern const String content_disposition_filename_name;
1.160.2.19 paf 430:
431: // defines for statics
432:
433: #define MAIN_CLASS_NAME "MAIN"
1.160.2.21 paf 434: #define AUTO_FILE_NAME "auto.p"
1.1 paf 435:
436: #endif
E-mail: