Qore WebUtil Module Reference 1.6.2
Loading...
Searching...
No Matches
WebUtil.qm.dox.h
1// -*- mode: c++; indent-tabs-mode: nil -*-
3
4/* WebUtil.qm Copyright (C) 2013 - 2023 Qore Technologies, s.r.o.
5
6 Permission is hereby granted, free of charge, to any person obtaining a
7 copy of this software and associated documentation files (the "Software"),
8 to deal in the Software without restriction, including without limitation
9 the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 and/or sell copies of the Software, and to permit persons to whom the
11 Software is furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 DEALINGS IN THE SOFTWARE.
23*/
24
25// minimum Qore version
26
27// require type definitions everywhere
28
29// enable all warnings
30
31// do not use "$" signs, assume local vars
32
33
34
106namespace WebUtil {
109
110public:
111
112
113protected:
115 ReadOnlyFile f;
117 bool txt;
119 int cs;
121 *hash<auto> respHdr;
122
123public:
124
127 Qore::Socket s, hash<auto> cx, hash<auto> hdr, *data body, Qore::ReadOnlyFile file, bool textflag,
128 int chunk_size, *hash<auto> respHdr)
129 ;
130
131
133protected:
134 hash<HttpResponseInfo> getResponseHeaderMessageImpl();
135public:
136
137
139protected:
140 auto sendImpl();
141public:
142
143 };
144
147
148public:
149
150
151protected:
153 InputStream stream;
155 int cs;
157 *hash<auto> respHdr;
158
159public:
160
163 Qore::Socket s, hash<auto> cx, hash<auto> hdr, *data body, InputStream stream,
164 int chunk_size, *hash<auto> respHdr)
165 ;
166
167
169protected:
170 hash<HttpResponseInfo> getResponseHeaderMessageImpl();
171public:
172
173
175protected:
176 auto sendImpl();
177public:
178
179 };
180
181 class AbstractTemplate {
182
183public:
185
200 hash<HttpResponseInfo> render(date new_mtime, hash<auto> ctx, int http_code = 200, *hash<auto> hdr);
201
202
204
215protected:
216 abstract hash<HttpResponseInfo> renderImpl(date new_mtime, hash<auto> ctx, int http_code = 200, *hash<auto> hdr);
217public:
218 };
219
222
223public:
225 const DefaultProgramOptions = PO_REQUIRE_OUR|PO_NO_TOP_LEVEL_STATEMENTS|PO_NO_INHERIT_USER_FUNC_VARIANTS|PO_NO_INHERIT_GLOBAL_VARS|PO_NO_USER_CLASSES|PO_NO_TERMINAL_IO;
226
228
254 static string add(Qore::Program p, string fn, string name, string src);
255
257protected:
258 static string getCode(bool bare_refs, string fmt);
259public:
260
261
263protected:
264 static bool doBlock(string end, reference<string> src, string type, reference<int> i, reference<list<hash>> l);
265public:
266
267
269 static string getContentType(string name);
270 };
271
274
275public:
276protected:
278 Program p;
279
280public:
281
284
285
287 Program getProgram();
288
289 };
290
292class FileTemplate : public AbstractTemplate,public TextTemplateBase {
293
294public:
295protected:
297 int po;
298
300 string path;
301
303 string ct;
304
306 const TemplateFunc = "t";
307
309 *code psetup;
310
312 RWLock rwl();
313
315 *date mtime;
316
317public:
318
319
321
325 constructor(string resource_path, int parse_opts = DefaultProgramOptions, *code pgm_setup) ;
326
327
329
344protected:
345 hash<HttpResponseInfo> renderImpl(date new_mtime, hash<auto> ctx, int http_code = 200, *hash<auto> hdr);
346public:
347
348
349protected:
350 setupTemplateIntern(date new_mtime);
351public:
352
353 };
354
356
360
361public:
362protected:
364 RWLock rwl();
365
367 hash<string, AbstractTemplate> th;
368
370 int po;
371
373 *code psetup;
374
375public:
376
378
383
384
386
403 hash<HttpResponseInfo> render(string tname, string path, date mtime, hash<auto> ctx, int code = 200, *hash<auto> hdr);
404
405
407 purge(string tname);
408
409 };
410
412
418
419public:
420protected:
422 hash<string, TextTemplateBase> toh;
423
425 hash<string, hash<auto>> th;
426
428 Sequence seq();
429
431 int po;
432
433public:
434
437
438
440
465 string add(string name, string src, *string ct);
466
467
469 bool hasTemplate(string tname);
470
471
473
490 hash<HttpResponseInfo> render(string tname, hash<auto> ctx, int code = 200, *hash<auto> hdr);
491
492
494
509 *hash<HttpResponseInfo> tryRender(string tname, hash<auto> ctx, int code = 200, *hash<auto> hdr);
510
511
513 *hash<string, bool> getTemplateHash();
514
515
517 list<string> getTemplateList();
518
519
521 setupProgram(Program p);
522
523 };
524
527
528public:
530 string file_root;
531
533 softlist indexes = (Defaults.IndexTemplate, Defaults.IndexFile);
534
536 hash template_extensions = Defaults.TemplateExtensions;
537
540
542 softint chunked_threshold = Defaults.ChunkedThreshold;
543
545 softint chunk_size = Defaults.ChunkSize;
546
548
553 softint error_level = 0;
554
556 const Unix = (PlatformOS != "Windows");
557
560
562
566
568 const Defaults = {
569 // default index file
570 "IndexFile": "index.html",
571 "IndexTemplate": "index.qhtml",
572 "TemplateExtensions": {
573 "qhtml": True,
574 },
575 "ChunkedThreshold": 10 * 1024,
576 "ChunkSize": 4096,
577 };
578
580 const Dirlisting = ...;
581
582
583protected:
586
587public:
588
590
606 constructor(string new_file_root, string url_root = '/', *hash<auto> opt)
607 ;
608
609
610protected:
611 string getDirlistingTemplate();
612public:
613
614
616
660 hash<auto> cx, hash<auto> hdr, *data body) {
661 // get local request path and "localize" it and strip off any query args
662 string path = getRelativePath(hdr.path);
663
664 // add URI query parameters to hdr if possible
665 hdr.params = parse_uri_query(hdr.path).params;
666
667 cx += {"resource_path": path, "url_root": url_root, "file_root": file_root, "isregex": False, "hdr": hdr};
668
669 try {
670 *hash<HttpResponseInfo> h = handleRequestImpl(\cx, hdr, body);
671 if (!h) {
672 h = tryServeRequest(listener, s, cx, hdr, body);
673 if (!h) {
674 cx.resource_path = default_target;
675 h = tryServeRequest(listener, s, cx, hdr, body);
676 }
677 }
678 if (h) {
679 return h;
680 }
681 } catch (hash<ExceptionInfo> ex) {
682 return serverError(cx, ex);
683 }
684
685 return unhandledRequest(cx, hdr, body);
686 }
687
689 logInfo(string fmt);
690
691
693 logError(string fmt);
694
695
697 logDebug(string fmt);
698
699
701
703protected:
704 hash<HttpResponseInfo> unhandledRequest(hash<auto> cx, hash<auto> hdr, *data body);
705public:
706
707
709
711protected:
712 hash<HttpResponseInfo> fileError(hash<auto> cx, hash<auto> sh);
713public:
714
715
717
719protected:
720 hash<HttpResponseInfo> serverError(hash<auto> cx, hash<auto> ex);
721public:
722
723
725 private *hash<HttpResponseInfo> tryServeRequest(HttpServer::HttpListenerInterface listener, Qore::Socket s,
726 hash<auto> cx, hash<auto> hdr, *data body) {
727 string path;
728 *hash<StatInfo> stat_hash = statPath(cx, hdr, \path);
729 if (!stat_hash);
730
731
732 // issue #4550: ensure that the path is inside the file_root
733 if (cx.resource_path ==1);
734
735
736 // add index if the request corresponds to a directory
737 if (stat_hash.type == 'DIRECTORY');
738 else if (stat_hash.type != 'REGULAR');
739
740
741 // see if we should handle as a template
742 *string ext = (cx.resource_path =~ x/\.([a-z0-9]+)$/i)[0];
743 if (ext && template_extensions{ext});
744
745
746 return sendFilePath(listener, s, cx, hdr, body, path, stat_hash);
747 }
748
749 private *hash<HttpResponseInfo> sendFilePath(HttpServer::HttpListenerInterface listener, Qore::Socket s,
750 hash<auto> cx, hash<auto> hdr, *data body, string path, hash<StatInfo> stat_hash) {
751 // send an empty response for an empty file
752 if (!stat_hash.size);
753
754
755 FileInputStream stream;
756 try {
757 stream = new FileInputStream(path, DefaultFileReadTimeout);
758 } catch (hash<ExceptionInfo> ex) {
759 if (ex.err == "FILE-OPEN2-ERROR") {
760 return;
761 }
762 rethrow;
763 }
764
765 *hash<auto> respHdr = getResponseHeadersForFile(path, cx, hdr);
766 // add the content type if it's missing for backwards compatibilitye
767 if (!hdr.'Content-Type');
768
769 return stat_hash.size > chunked_threshold
770 ? sendFileChunked(listener, s, cx, hdr, body, stream, respHdr)
771 : sendFile(stream, respHdr);
772 }
773
774protected:
775 *hash<StatInfo> statPath(hash<auto> cx, hash<auto> hdr, reference<string> path);
776public:
777
778
780 private AbstractStreamRequest getStreamRequestImpl(HttpServer::HttpListenerInterface listener, Qore::Socket s,
781 hash<auto> cx, hash<auto> hdr, *data body, InputStream stream, *hash<auto> respHdr) {
782 return new InputStreamRequest(listener, self, s, cx, hdr, body, stream, chunk_size, respHdr);
783 }
784
786
797protected:
798 hash<auto> getResponseHeadersForFile(string path, hash<auto> cx, hash<auto> request_hdr);
799public:
800
801
803protected:
804 hash<HttpResponseInfo> sendFile(InputStream stream, *hash<auto> respHdr);
805public:
806
807
809 private hash<HttpResponseInfo> sendFileChunked(HttpServer::HttpListenerInterface listener, Qore::Socket s,
810 hash<auto> cx, hash<auto> hdr, *data body, InputStream stream, *hash<auto> respHdr) {
811 AbstractStreamRequest fsr = getStreamRequestImpl(listener, s, cx, hdr, body, stream, respHdr);
812 return cast<hash<HttpResponseInfo>>(fsr.handleRequest());
813 }
814
816
819 *hash<HttpResponseInfo> renderDirectory(hash<auto> cx, string path);
820
821
823
854protected:
855 *hash<HttpResponseInfo> handleRequestImpl(reference<hash<auto>> cx, hash<auto> hdr, *data body);
856public:
857
858 };
859};
AbstractHttpRequestHandler handler
HttpListenerInterface listener
string getRelativePath(string path)
this class serves files from the file system based on a root location
Definition: WebUtil.qm.dox.h:526
private *hash< HttpResponseInfo > tryServeRequest(HttpServer::HttpListenerInterface listener, Qore::Socket s, hash< auto > cx, hash< auto > hdr, *data body)
tries to serve the request from the filesystem
Definition: WebUtil.qm.dox.h:725
softint error_level
set for error info level
Definition: WebUtil.qm.dox.h:553
hash< HttpResponseInfo > fileError(hash< auto > cx, hash< auto > sh)
this method returns a 400 "Bad Request" error code when a file should be served that's not a regular ...
private hash< HttpResponseInfo > sendFileChunked(HttpServer::HttpListenerInterface listener, Qore::Socket s, hash< auto > cx, hash< auto > hdr, *data body, InputStream stream, *hash< auto > respHdr)
returns a handler hash response with the file's data to be sent in a HTTP message with chunked transf...
Definition: WebUtil.qm.dox.h:809
hash< HttpResponseInfo > serverError(hash< auto > cx, hash< auto > ex)
this method returns a 500 "Internal Server Error" error code when an exception occurs
hash< auto > getResponseHeadersForFile(string path, hash< auto > cx, hash< auto > request_hdr)
this method returns a hash giving response headers with a default content type for the file to be ser...
const Defaults
default configuration values
Definition: WebUtil.qm.dox.h:568
softint chunk_size
HTTP chunk size in bytes.
Definition: WebUtil.qm.dox.h:545
logError(string fmt)
default implementation is empty; this method is called with error log messages; reimplement in subcla...
const DefaultFileReadTimeout
default read timeout for serving files
Definition: WebUtil.qm.dox.h:559
const Dirlisting
dirlisting template
Definition: WebUtil.qm.dox.h:580
StaticTemplateManager stm()
static templates
*hash< HttpResponseInfo > renderDirectory(hash< auto > cx, string path)
this method is called when a directory should be rendered
private AbstractStreamRequest getStreamRequestImpl(HttpServer::HttpListenerInterface listener, Qore::Socket s, hash< auto > cx, hash< auto > hdr, *data body, InputStream stream, *hash< auto > respHdr)
must return a AbstractStreamRequest object to stream the requested file with chunked transfer encodin...
Definition: WebUtil.qm.dox.h:780
logDebug(string fmt)
default implementation is empty; this method is called with debug log messages; reimplement in subcla...
const Unix
flag for UNIX operating systems
Definition: WebUtil.qm.dox.h:556
*string default_target
the default target if a URL cannot be satisfied
Definition: WebUtil.qm.dox.h:539
hash< HttpResponseInfo > sendFile(InputStream stream, *hash< auto > respHdr)
returns a handler hash response with the data to be sent in a monolithic message
hash< HttpResponseInfo > handleRequest(HttpServer::HttpListenerInterface listener, Qore::Socket s, hash< auto > cx, hash< auto > hdr, *data body)
this method calls handleRequestImpl() to service the request, if handleRequestImpl() returns NOTHING,...
Definition: WebUtil.qm.dox.h:659
const DirSep
directory separator character
Definition: WebUtil.qm.dox.h:565
hash< HttpResponseInfo > unhandledRequest(hash< auto > cx, hash< auto > hdr, *data body)
this method returns a 404 "Not Found" error code to GET requests and a 501 "Not Implemented" error co...
softlist indexes
indexes for directories; handled in order of appearance
Definition: WebUtil.qm.dox.h:533
string file_root
root directory for serving files
Definition: WebUtil.qm.dox.h:530
softint chunked_threshold
minimum size in bytes for plain files to be sent with a chnked transfer
Definition: WebUtil.qm.dox.h:542
logInfo(string fmt)
default implementation is empty; this method is called with informational log messages; reimplement i...
hash template_extensions
file extensions handled as templates
Definition: WebUtil.qm.dox.h:536
constructor(string new_file_root, string url_root='/', *hash< auto > opt)
create the object optionally with the given HttpServer::AbstractAuthenticator
*hash< HttpResponseInfo > handleRequestImpl(reference< hash< auto > > cx, hash< auto > hdr, *data body)
this method is called by this class's handleRequest() before trying to service the request automatica...
this class handles chunked file sends
Definition: WebUtil.qm.dox.h:108
hash< HttpResponseInfo > getResponseHeaderMessageImpl()
returns the reponse headers
bool txt
text flag
Definition: WebUtil.qm.dox.h:117
constructor(HttpServer::HttpListenerInterface listener, HttpServer::AbstractHttpRequestHandler handler, Qore::Socket s, hash< auto > cx, hash< auto > hdr, *data body, Qore::ReadOnlyFile file, bool textflag, int chunk_size, *hash< auto > respHdr)
creates the object
auto sendImpl()
returns data to send
int cs
chunk size
Definition: WebUtil.qm.dox.h:119
*hash< auto > respHdr
response headers
Definition: WebUtil.qm.dox.h:121
ReadOnlyFile f
file object
Definition: WebUtil.qm.dox.h:115
manages a template resource that may need to be recompiled if the file is updated in the filesystem; ...
Definition: WebUtil.qm.dox.h:292
int po
parse options used on the program
Definition: WebUtil.qm.dox.h:297
string ct
the content type of the rendered template
Definition: WebUtil.qm.dox.h:303
RWLock rwl()
to ensure atomicity regarding contention between setup/recompiles and rendering requests
*code psetup
code to perform Program initialization when creating a new Program object (inport API,...
Definition: WebUtil.qm.dox.h:309
const TemplateFunc
the name of the template function
Definition: WebUtil.qm.dox.h:306
string path
the path to the template
Definition: WebUtil.qm.dox.h:300
*date mtime
file's modification time
Definition: WebUtil.qm.dox.h:315
constructor(string resource_path, int parse_opts=DefaultProgramOptions, *code pgm_setup)
creates the object based on the pathname and Program options
hash< HttpResponseInfo > renderImpl(date new_mtime, hash< auto > ctx, int http_code=200, *hash< auto > hdr)
explicitly renders the given template with the given argument
this class handles chunked file sends
Definition: WebUtil.qm.dox.h:146
*hash< auto > respHdr
response headers
Definition: WebUtil.qm.dox.h:157
InputStream stream
input stream object
Definition: WebUtil.qm.dox.h:153
auto sendImpl()
returns data to send
hash< HttpResponseInfo > getResponseHeaderMessageImpl()
returns the reponse headers
constructor(HttpServer::HttpListenerInterface listener, HttpServer::AbstractHttpRequestHandler handler, Qore::Socket s, hash< auto > cx, hash< auto > hdr, *data body, InputStream stream, int chunk_size, *hash< auto > respHdr)
creates the object
int cs
chunk size
Definition: WebUtil.qm.dox.h:155
A container for holding static text templates (ie that do not change once created in the template man...
Definition: WebUtil.qm.dox.h:417
Sequence seq()
Sequence for template function names.
int po
parse options for template containers
Definition: WebUtil.qm.dox.h:431
constructor(int po=DefaultProgramOptions)
sets up the object
hash< string, hash< auto > > th
Maps template names to function names.
Definition: WebUtil.qm.dox.h:425
*hash< string, bool > getTemplateHash()
returns a hash of template names, values are True or NOTHING if no templates are currently cached
setupProgram(Program p)
override in subclasses to customize the setup of template Programs; this method performs no action
string add(string name, string src, *string ct)
adds a template to the object
list< string > getTemplateList()
returns a list of template names, an empty list is returned if there are no templates
bool hasTemplate(string tname)
returns True if the given template exists, False if not
hash< string, TextTemplateBase > toh
Maps template names to TextTemplateBase objects.
Definition: WebUtil.qm.dox.h:422
*hash< HttpResponseInfo > tryRender(string tname, hash< auto > ctx, int code=200, *hash< auto > hdr)
explicitly renders the given template with the given argument context hash if the template exists; if...
hash< HttpResponseInfo > render(string tname, hash< auto > ctx, int code=200, *hash< auto > hdr)
explicitly renders the given template with the given argument
this is the static base class for all template Program container classes
Definition: WebUtil.qm.dox.h:221
const DefaultProgramOptions
default parse options for template Programs
Definition: WebUtil.qm.dox.h:225
static string getContentType(string name)
returns the content type from the file name, ignores any leading "q" in the extensions,...
static string add(Qore::Program p, string fn, string name, string src)
adds a template function to a template Program object
static bool doBlock(string end, reference< string > src, string type, reference< int > i, reference< list< hash > > l)
a helper method used in parsing
static string getCode(bool bare_refs, string fmt)
a helper method that strips dollar signs from code when PO_ALLOW_BARE_REFS is set in the template pro...
this class manages templates based on files
Definition: WebUtil.qm.dox.h:359
hash< string, AbstractTemplate > th
hash for template storage
Definition: WebUtil.qm.dox.h:367
purge(string tname)
this method can be called when a resource is requested that no longer exists in case a template is st...
hash< HttpResponseInfo > render(string tname, string path, date mtime, hash< auto > ctx, int code=200, *hash< auto > hdr)
explicitly renders the given template with the given path and context argument
RWLock rwl()
read-write lock for managing template access
*code psetup
code to perform Program initialization when creating a new Program object (inport API,...
Definition: WebUtil.qm.dox.h:373
int po
parse options used on the program
Definition: WebUtil.qm.dox.h:370
constructor(int parse_opts=StaticTextTemplateBase::DefaultProgramOptions, *code pgm_setup)
creates the object with optional Program options
this is the base class for all template Program container classes
Definition: WebUtil.qm.dox.h:273
Program p
Holds the template generation function.
Definition: WebUtil.qm.dox.h:278
Program getProgram()
returns the contained Program object
constructor(int po=DefaultProgramOptions)
sets up the object
const DirSep
the WebUtil namespace contains all the objects in the WebUtil module
Definition: WebUtil.qm.dox.h:106