Qore HttpServer Module Reference  0.3.7
 All Classes Namespaces Functions Variables Groups Pages
HttpServer.qm.dox.h
1 // -*- mode: c++; indent-tabs-mode: nil -*-
2 // @file HttpServer.qm HTTP multi-threaded server module definition
3 
4 /* HttpServer.qm Copyright (C) 2012 - 2014 David Nichols
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 // need mime definitions
26 
27 
28 /* Version History
29  * 2013-03-05 v0.3.7: David Nichols <david@qore.org>
30  + fixed a bug in parsing arguments in parse_uri_query()
31  + updated parse_uri_query() to accept both "&" and ";" as argument separators
32  + added support for the PUT and DELETE methods and for optional message bodies independent of the HTTP method
33  + fixed handler matching to use a score for each handler and to check dynamic handlers also for a match if the fixed handlers don't provide a perfect match
34  + fixed response handling to not overwrite the \c Connection header if present from the handler
35  + fixed response handling to only return error reponses with codes >= 400
36  + implemented theAbstractHttpSocketHandler handler class to support dedicated socket connections when switching protocols in handlers
37  + do not add HTML to the msg body from explicit error responses from handlers
38  + improved HTTP server log messages
39  + added "family" argument to HttpServer::add*Listener*() methods
40  + turned of TCP_NODELAY by default and use socket shutdown when closing sockets instead
41  + set the listen backlog queue size to 100 by default (previously was hardcoded internally in Qore to 5)
42  + use the new ThreadPool class introduced in Qore 0.8.8 to pre-allocate threads to reduce latency for new socket connections
43  + improved handler matching algorithm
44  + implemented many performance improvements
45  + implemented support for simple string path matching when finding a handler for a request
46  + added static AbstractHttpRequestHandler::redirect() to help in generating 301 Moved Permanently messages
47 
48  * 2012-12-18 v0.3.6: David Nichols <david@qore.org>
49  + fixed a race condition in tracking active requests in dynamic HTTP handlers and removing dynamic HTTP handlers
50 
51  * 2012-09-20 v0.3.5: David Nichols <david@qore.org>
52  + fixed bugs in regexes in the HttpServer::addListeners() and HttpServer::addListenersWithHandler() methods
53  + updated module example code in summary
54  + added "listener-id" to request context hash
55 
56  * 2012-06-01 v0.3.4: David Nichols <david@qore.org>
57  + added public parse_uri_query() function
58 
59  * 2012-05-24 v0.3.3: David Nichols <david@qore.org>
60  + updated to a user module
61  + added support for custom redirects from user handlers
62  + use the Mime module for mime definitions
63 
64  * v0.3.2: David Nichols <david@qore.org>
65  + added support for listeners with specific handler lists
66  + added the ability to manage dynamic content handlers
67  + implemented content-encoding handling flags in AbstractHttpRequestHandler
68  + implemented support for "identity" encoding (if anyone ever sends it)
69 
70  * v0.3.1: David Nichols <david@qore.org>
71  + added ipv6 support in qore 0.8.2
72 
73  * v0.3.0: David Nichols <david@qore.org>
74  + added the ability to start and stop listeners on demand
75 
76  * v0.2.9: David Nichols <david@qore.org>
77  + updates for new SSL and timeout behavior with with Socket class with qore 0.8.1+
78  + set socket encoding to UTF-8 by default
79  + add "charset=utf-8" to Content-Type header if not already present
80  + add "text/html" to Content-Type header if no content-type is given by the handler
81  + fixed setting X.509 certificate and private key for HTTPS listeners
82  + require qore >= 0.8.1 for new Socket features
83 
84  * v0.2.8: David Nichols <david@qore.org>
85  + converted to hard typing for use with %require-types
86  + require qore >= 0.8.0 for new Socket features
87 
88  * v0.2.7: David Nichols <david@qore.org>
89  + set TCP_NODELAY on all sockets to ensure that clients get all data before closing the socket, especially in case of errors
90  + require qore >= 0.7.4 for new Socket features
91 
92  * v0.2.6: David Nichols <david@qore.org>
93  + minor fixes for SOAP support
94  + improved handler matching
95 
96  * v0.2.5: David Nichols <david@qore.org>
97  + minor fixes for SOAP support
98 
99  * v0.2.4: David Nichols <david@qore.org>
100  + improved Content-Type handling
101  + improved URL/path support
102 
103  * v0.2.3: David Nichols <david@qore.org>
104  + bzip2 content-encoding support
105 
106  * v0.2.2: David Nichols <david@qore.org>
107  + basic authentication
108 
109  * v0.2.1: David Nichols <david@qore.org>
110  + implementing logic to handle "deflate" and "gzip" content-encoding
111  + chunked content-encoding supported for POSTs
112  + Date: header always sent as per HTTP 1.1 spec
113 
114  * v0.2.0: David Nichols <david@qore.org>
115  + modular/multiple listener support added
116  + https support added
117 
118  note that this server suffers from the following limitations, among many others:
119  + not totally HTTP 1.1 compliant although claims to be
120 */
121 
290 
297 namespace HttpServer {
299 
305  hash parse_uri_query(string path);
306 
307 
309 
315  string get_exception_string(hash ex);
316 
317 };
318 
319 // class containing handler info
320 class HttpServer::HandlerInfo {
321 
322 public:
323  public :
324  string name;
325  AbstractHttpRequestHandler obj;
326  string path;
327  bool isregex;
328  // content type hash
329  hash ch;
330  *list shdr;
331 
332 public:
333 
334  constructor(string name, AbstractHttpRequestHandler obj, string path, bool isregex = True, *softlist content, *softlist shdr);
335 
336 
337  bool matchContentType(string ct);
338 
339 
341  int matchRequest(hash hdr, int score);
342 
343 };
344 
345 // class to implement handler-handling (private)
346 class HttpServer::HttpHandlerList {
347 
348 public:
349  public :
350  hash handlers;
351 
352 public:
353 
354 
355 private:
356  static checkSpecialHeaders(reference sh);
357 public:
358 
359 
361  setHandler(string name, string path, bool isregex = True, *softlist content, AbstractHttpRequestHandler obj, *softlist special_headers);
362 
363 
364  // matches a handler to the request
365  *HandlerInfo findHandler(hash hdr, reference score, bool final = False);
366 
367 
368  bool empty();
369 
370 
371  int size();
372 
373 };
374 
375 // class containing dynamic handler info
376 class HttpServer::DynamicHandlerInfo : public HttpServer::HandlerInfo {
377 
378 public:
379  public :
380  Counter counter();
381 
382 public:
383 
384  constructor(string name, AbstractHttpRequestHandler obj, string path, bool isregex = True, *softlist content, *softlist shdr);
385 
386 };
387 
388 // maintains the request count for dynamic handlers (private)
389 class HttpServer::DynamicHandlerHelper {
390 
391 public:
392 private:
393 
394 public:
395 
396  private :
397  Counter c;
398 
399 public:
400 
401  constructor(Counter c);
402 
403 
404  destructor();
405 
406 };
407 
408 // for dynamic handler-handling (private)
409 class HttpServer::DynamicHttpHandlerList : public HttpServer::HttpHandlerList {
410 
411 public:
412  private :
413  RWLock dhl();
414 
415 public:
416 
418  setHandler(string name, string path, bool isregex, *softlist content_type, AbstractHttpRequestHandler obj, *softlist special_headers);
419 
420 
422  removeHandler(string name);
423 
424 
425  *DynamicHandlerInfo findHandler(hash hdr, reference score, reference dhh);
426 
427 };
428 
430 
433 
434 public:
436 
438  bool requiresAuthentication();
439 
440 
442 
444  string getRealm();
445 
446 
448 
454  authenticate(string user, string pass = "");
455 
456 
458 
464  authenticateByIP(string ip, reference user);
465 
466 
467  private hash getAuthHeader();
468 
469 
470  private hash do401(string msg = "Authentication is required to access this server");
471 
472 
474 
483  *hash authenticateRequest(HttpListener listener, hash hdr, reference cx);
484 
485 };
486 
488 
491 
492 public:
493  public :
496 
498  bool decompress = True;
499 
502 
503 public:
504 
506 
509 
510 
512 
535  hash handleRequest(hash cx, hash hdr, *data body);
536 
537 
539 
546  static *string getLogMessage(hash cx, hash api, reference params, *reference args);
547 
549 
552 
553 
555 
558 
559 
561  static hash makeResponse(int code, string fmt);
562 
564  static hash makeResponse(hash hdr, int code, string fmt);
565 
567  static hash makeResponse(int code, *data body, *hash hdr);
568 
570  static hash make400(string fmt);
571 
573  static hash make400(hash hdr, string fmt);
574 
576  static hash make501(string fmt);
577 
579  static hash make501(hash hdr, string fmt);
580 
582  static hash redirect(hash cx, hash hdr, string path);
583 };
584 
587 
588 public:
589  public :
591  string url_root;
592 
593 public:
594 
596 
600 
601 
603  string getRelativePath(string path);
604 
605 };
606 
608 
611 
612 public:
613  private :
615  bool stop = False;
616 
619 
622 
624  Mutex m();
625 
626 public:
627 
629 
632 
633 
635 
649  start(softstring lid, hash cx, hash hdr, Socket s);
650 
651 
653 
657  stop(softstring lid);
658 
659 
661 
663  stop();
664 
665 
667 
693  abstract hash handleRequest(hash cx, hash hdr, *data b);
694 
696 
710  private abstract startImpl(softstring lid, hash cx, hash hdr, Socket s);
711 
713 
715  private stopImpl(string lid);
716 
717 
719  private stopImpl();
720 
721 };
722 
725 
726 public:
727  public :
729  const Version = "0.3.7";
731  const ReadTimeout = 30000; // recvs timeout after 30 seconds
733  const PollTimeout = 5000; // check for exit every 5 seconds while waiting
734 
735  // logging options
736  const LP_LOGPARAMS = 1 << 16;
737  const LP_LEVELMASK = LP_LOGPARAMS - 1;
738 
741 
743  const HttpMethods = (
744  "HEAD": True,
745  "POST": True,
746  "PUT": True,
747  "DELETE": True,
748  "GET": True,
749  "OPTIONS": True,
750  //"TRACE": True,
751  //"CONNECT": True,
752  );
753 
755  const HttpCodes = (
756  // 100s: Informational
757  "100": "Continue",
758  "101": "Switching Protocols",
759 
760  // RFC 2518: WebDAV
761  "102": "Processing",
762 
763  // 200s: Success
764  "200": "OK",
765  "201": "Created",
766  "202": "Accepted",
767  "203": "Non-Authoritative Information",
768  "204": "No Content",
769  "205": "Reset Content",
770  "206": "Partial Content",
771 
772  // RFC 4918: WebDAV: The message body that follows is an XML message and can contain a number of separate response codes, depending on how many sub-requests were made
773  "207": "Multi-Status",
774 
775  // RFC 5842: WebDAV: The members of a DAV binding have already been enumerated in a previous reply to this request, and are not being included again
776  "208": "Already Reported",
777 
778  // RFC 3229
779  "226": "IM Used",
780 
781  // 300s: Redirection
782  "300": "Multiple Choices",
783  "301": "Moved Permanently",
784  "302": "Found",
785  "303": "See Other",
786  "304": "Not Modified",
787  "305": "Use Proxy",
788  //"306": "(Reserved)",
789  "307": "Temporary Redirect",
790 
791  // 400s: Client Errors
792  "400": "Bad Request",
793  "401": "Unauthorized",
794  "402": "Payment Required",
795  "403": "Forbidden",
796  "404": "Not Found",
797  "405": "Method Not Allowed",
798  "406": "Not Acceptable",
799  "407": "Proxy Authentication Required",
800  "408": "Request Timeout",
801  "409": "Conflict",
802  "410": "Gone",
803  "411": "Length Required",
804  "412": "Precondition Failed",
805  "413": "Request Entity Too Large",
806  "414": "Request-URI Too Long",
807  "415": "Unsupported Media Type",
808  "416": "Requested Range Not Satisfiable",
809  "417": "Expectation Failed",
810 
811  // RFC 2324: http://tools.ietf.org/html/rfc2324
812  "418": "I'm a teapot",
813 
814  // Returned by the Twitter Search and Trends API when the client is being rate limited
815  "420": "Enhance Yextern Calm",
816 
817  // RFC 4918: WebDAV: The request was well-formed but was unable to be followed due to semantic errors
818  "422": "Unprocessable Entity",
819 
820  // RFC 4918: WebDAV: The resource that is being accessed is locked
821  "423": "Locked",
822 
823  // RFC 4918: WebDAV: The request failed due to failure of a previous request (e.g. a PROPPATCH)
824  "424": "Failed Dependency",
825 
826  // Internet draft: Defined in drafts of "WebDAV Advanced Collections Protocol", but not present in "Web Distributed Authoring and Versioning (WebDAV) Ordered Collections Protocol"
827  "425": "Unordered Collection",
828 
829  // RFC 2817: The client should switch to a different protocol such as TLS/1.0
830  "426": "Upgrade Required",
831 
832  // RFC 6585: The origin server requires the request to be conditional. Intended to prevent "the 'lost update' problem, where a client GETs a resource's state, modifies it, and PUTs it back to the server, when meanwhile a third party has modified the state on the server, leading to a conflict."
833  "428": "Precondition Required",
834 
835  // RFC 6585: The user has sent too many requests in a given amount of time. Intended for use with rate limiting schemes
836  "429": "Too Many Requests",
837 
838  // RFC 6585
839  "431": "Request Header Fields Too Large",
840 
841  // 500s: Server Errors
842  "500": "Internal Server Error",
843  "501": "Not Implemented",
844  "502": "Bad Gateway",
845  "503": "Service Unavailable",
846  "504": "Gateway Timeout",
847  "505": "HTTP Version Not Supported",
848  "509": "Bandwidth Limit Exceeded",
849 
850  // RFC 2774: Further extensions to the request are required for the server to fulfill it
851  "510": "Not Extended",
852 
853  // RFC 6585: The client needs to authenticate to gain network access. Intended for use by intercepting proxies used to control access to the network (e.g. "captive portals" used to require agreement to Terms of Service before granting full Internet access via a Wi-Fi hotspot)
854  "511": "Network Authentication Required",
855  );
856 
859  "gzip": "gzip",
860  "deflate": "deflate",
861  "bzip2": "bzip2",
862  "x-gzip": "gzip",
863  "x-deflate": "deflate",
864  "x-bzip2": "bzip2",
865  );
866 
868  const DefaultIdleThreads = 10;
869 
870 public:
871 
873  private :
874  *code logfunc;
875  *code errlogfunc;
876 
877  // quit server flag
878  bool exit = False;
879 
880  // if True then verbose exception info will be logged
881  bool debug;
882 
883  Sequence seqSessions();
884  Sequence seqListeners();
885 
886  string httpserverstring;
887 
888  bool stopped = False;
889 
890  // permanent handlers; these handlers are never removed
891  HttpHandlerList handlers();
892 
893  // default handler
894  hash defaultHandler;
895 
896  // hash of listeners keyed by listener ID
897  hash listeners;
898 
899  // map of bind addresses to listener IDs
900  hash smap;
901 
902  // map of listener names to listener IDs
903  hash nmap;
904 
905  // listener Gate
906  Gate lm();
907 
908  // running listener counter
909  Counter c();
910 
911  // dynamic handlers
912  DynamicHttpHandlerList dhandlers();
913 
914  // connection thread pool
915  ThreadPool threadPool(-1, DefaultIdleThreads);
916 
917  // other misc response headers
918  hash hdr;
919 
920  // override message body encoding if none is received from the sender; http://tools.ietf.org/html/rfc2616#section-3.7.1 states that it must be iso-8850-1
921  *string override_encoding;
922 
923 public:
925 
927 
935  constructor(*code logfunc, *code errlogfunc, bool dbg = False, string name = sprintf("Qore-HTTP-Server/%s", HttpServer::Version), hash hdr = ("X-Powered-By": "Qore/" + Qore::VersionString));
936 
937 
939  destructor();
940 
941 
942  setDefaultTextEncoding(string enc);
943 
944 
945  string getDefaultTextEncoding();
946 
947 
949 
977  final list addListenersWithHandler(string hname, AbstractHttpRequestHandler handler, hash lp, *code logger, *code errorlogger, *code stopc, *string name, int family = AF_UNSPEC);
978 
979 
981 
996  hash addListener(softstring sock, *string cert_path, *string key_path, *string name, int family = AF_UNSPEC);
997 
998 
1000 
1015  softlist addListeners(softstring sock, *string cert_path, *string key_path, *string name, int family = AF_UNSPEC);
1016 
1017 
1019 
1033  list addINETListeners(*string node, softstring service, *string cert_path, *string key_path, *string name, int family = AF_UNSPEC);
1034 
1035 
1037  copy();
1038 
1039 
1041 
1043  hash getListeners();
1044 
1045 
1047 
1064  hash getListenerInfo(softint id);
1065 
1066 
1068 
1085  hash getListenerInfoName(string name);
1086 
1087 
1089  int getListenerCount();
1090 
1091 
1093 
1095  stopNoWait();
1096 
1097 
1099  waitStop();
1100 
1101 
1102  // only called from the listeners - do not call externally
1103  listenerStopped(HttpListener l);
1104 
1105 
1107 
1109  stop();
1110 
1111 
1113  stopListener(softstring bind);
1114 
1115 
1117  stopListenerID(softint id);
1118 
1119 
1121  int getListenerTID(softint id);
1122 
1123 
1126 
1127 
1129  setHandler(string name, string path, *softlist content_type, AbstractHttpRequestHandler obj, *softlist special_headers, bool isregex = True);
1130 
1131 
1133  setDynamicHandler(string name, string path, *softlist content_type, AbstractHttpRequestHandler obj, *softlist special_headers, bool isregex = True);
1134 
1135 
1137  setHandler(string name, AbstractUrlHandler obj);
1138 
1139 
1141  setDynamicHandler(string name, AbstractUrlHandler obj);
1142 
1143 
1145  addHandlerToListener(softstring bind, string name, string path, *softlist content_type, AbstractHttpRequestHandler obj, *softlist special_headers, bool isregex = True);
1146 
1147 
1149  addHandlerToListenerID(softint id, string name, string path, *softlist content_type, AbstractHttpRequestHandler obj, *softlist special_headers, bool isregex = True);
1150 
1151 
1153  addHandlerToListener(softstring bind, string name, AbstractUrlHandler obj);
1154 
1155 
1157  addHandlerToListenerID(softint id, string name, AbstractUrlHandler obj);
1158 
1159 
1161  removeDynamicHandler(string name);
1162 
1163 
1165  log();
1166 
1167 
1169  logError();
1170 
1171 
1173  logArgs(softlist args = ());
1174 
1175 
1177  logErrorArgs(softlist args = ());
1178 
1179 
1181  sendHttpError(HttpListener listener, hash cx, Socket s, int code, string msg, *hash extra_hdrs, *string encoding);
1182 
1183 
1185 
1187  static string getURLFromBind(softstring bind, *string host);
1188 
1190  setDebug(bool dbg = True);
1191 
1192 
1194  bool getDebug();
1195 
1196 
1197  startConnection(code c);
1198 
1199 
1201  // don't reimplement this method; fix/enhance it in the module
1202  final private HttpListener addListenerIntern(*string node, *softstring service, *Qore::SSLCertificate cert, *Qore::SSLPrivateKey key, *hash hi, *code logger, *code errorlogger, *code stopc, *string name, int family = AF_UNSPEC);
1203 
1204 
1205  // don't reimplement this method; fix/enhance it in the module
1206  static final private hash getSSLObjects(string cert_path, *string key_path);
1207 
1208  // don't reimplement this method; fix/enhance it in the module
1209  final private list addINETListenersIntern(*string node, softstring service, *hash sd, *hash lp, *code logger, *code errorlogger, *code stopc, *string name, int family = AF_UNSPEC);
1210 
1211 
1212  // don't reimplement this method; fix/enhance it in the module
1213  final private hash noHandlerError(hash cx, hash hdr, any body);
1214 
1215 
1216  // handles an incoming request - do not call externally; this method is called by the listeners when a request is received
1217  // don't reimplement this method; fix/enhance it in the module
1218  final handleRequest(HttpListener listener, Socket s, reference cx, hash hdr, hash hh, *data body, bool head = False);
1219 
1221 };
1222 
1225 
1226 public:
1227  private :
1228  HttpServer serv;
1229  Sequence ss;
1230  *SSLCertificate cert;
1231  *SSLPrivateKey key;
1232  bool ssl = False;
1233  any socket;
1234  hash socket_info;
1235 
1236  // connection counter
1237  Counter cThreads();
1238  bool exit = False;
1239  bool stopped = False;
1240  int id;
1241 
1242  // socket handler hash
1243  hash shh;
1244 
1245  // mutex
1246  Mutex m();
1247 
1248  // code references to external logging functions
1249  *code logger;
1250  *code errorlogger;
1251 
1252  // stop notification closure
1253  *code stopc;
1254 
1255  string name;
1256 
1257  const PollInterval = 1s;
1258  const ListenQueue = 100;
1259 
1260 public:
1261 
1262  public :
1263  // TID of the background listener thread
1264  int tid;
1265 
1266  // listener-specific handlers
1267  HttpHandlerList handlers();
1268 
1269  // default handler info
1270  *HandlerInfo defaultHandler;
1271 
1272 public:
1273 
1274  // params: server, id, session ID sequence object, socket, rbac obj, [cert, key]
1275  constructor(HttpServer server, int id, Sequence ss, *string node, *softstring service, *Qore::SSLCertificate cert, *Qore::SSLPrivateKey key, *hash hi, *code logger, *code errorlogger, *code stopc, string name, int family = AF_UNSPEC);
1276 
1277 
1278  addHandlers(hash hi);
1279 
1280 
1281  setDefaultHandler(string name);
1282 
1283 
1284  copy();
1285 
1286 
1287  destructor();
1288 
1289 
1290  string getName();
1291 
1292 
1293  any getAddress();
1294 
1295 
1296  int getID();
1297 
1298 
1299  bool isSecure();
1300 
1301 
1302  hash getInfo();
1303 
1304 
1305  stopNoWait();
1306 
1307 
1308  stop();
1309 
1310 
1311  logResponse(hash cx, int code, *data body, *hash hdr);
1312 
1313 
1314  logResponse(hash cx, hash rv);
1315 
1316 
1317  log();
1318 
1319 
1320  logError();
1321 
1322 
1323  private mainThread();
1324 
1325 
1326  // thread for handling communication per connection
1327  private connectionThread(Socket s);
1328 
1329 
1330  bool registerDedicatedSocket(softstring id, AbstractHttpSocketHandler h);
1331 
1332 
1333  removeDedicatedSocket(softstring id, AbstractHttpSocketHandler h);
1334 
1335 };
logError()
called to log error information to the registered error log code
logErrorArgs(softlist args=())
calls the error log function/closure with the given args
logArgs(softlist args=())
calls the log function/closure with the given args
const AF_UNSPEC
string sprintf(string fmt,...)
hash getListeners()
returns a hash of listener information
hash addListener(softstring sock, *string cert_path, *string key_path, *string name, int family=AF_UNSPEC)
adds a global listener to the server
string get_exception_string(hash ex)
returns a multi-line string from the exception hash argument suitable for logging or output on the co...
abstract hash handleRequest(hash cx, hash hdr, *data b)
called by the HTTP server to handle incoming HTTP requests
setDebug(bool dbg=True)
turns on or off debugging; when debugging is enabled more verbose error messages are reported ...
string getRealm()
returns the authentication realm as a string
abstract class that all HTTP request handler objects must inherit from
Definition: HttpServer.qm.dox.h:490
*AbstractAuthenticator auth
the optional AbstractAuthenticator for requests to this handler
Definition: HttpServer.qm.dox.h:495
static string getURLFromBind(softstring bind, *string host)
returns a complete URL from a bind address
const ReadTimeout
default read timeout in ms
Definition: HttpServer.qm.dox.h:731
removeDynamicHandler(string name)
remove dynamic handler
hash lh
hash of listener references; this is to stop all connections associated with a particular listener ...
Definition: HttpServer.qm.dox.h:618
constructor(*AbstractAuthenticator auth)
create the object optionally with the given AbstractAuthenticator
addHandlerToListenerID(softint id, string name, string path, *softlist content_type, AbstractHttpRequestHandler obj, *softlist special_headers, bool isregex=True)
adds a request handler to a listener given the listener&#39;s id
destructor()
calls stop() and destroys the object
addHandlerToListener(softstring bind, string name, string path, *softlist content_type, AbstractHttpRequestHandler obj, *softlist special_headers, bool isregex=True)
adds a request handler to a listener given the listener&#39;s name or bind address
const True
start(softstring lid, hash cx, hash hdr, Socket s)
called from the HTTP server after the handleRequest() method indicates that a dedicated connection sh...
string getRelativePath(string path)
returns the relative path anchored from the url_root if possible; URI query arguments are stripped of...
setDynamicHandler(string name, string path, *softlist content_type, AbstractHttpRequestHandler obj, *softlist special_headers, bool isregex=True)
sets a dynamic request handler according to the arguments given
const DefaultIdleThreads
default number of idle threads to have waiting for new connections (accross all listeners) ...
Definition: HttpServer.qm.dox.h:868
stopListener(softstring bind)
stops a single listener based on its name or bind address; does not return until all connections on t...
stopListenerID(softint id)
stops a single listener based on its listener ID; does not return until all connections on the listen...
const HttpMethods
supported HTTP methods
Definition: HttpServer.qm.dox.h:743
bool decompress
if POSTed data should be decompressed automatically if there is content-encoding
Definition: HttpServer.qm.dox.h:498
abstract private startImpl(softstring lid, hash cx, hash hdr, Socket s)
called from the HTTP server after the handleRequest() method indicates that a dedicated connection sh...
stop()
stops all listeners; only returns when all connections are closed on all listeners ...
constructor(string url_root, *AbstractAuthenticator auth)
creates the object based on the URL root and optional authenticator
Mutex m()
listener reference hash mutex
private stopImpl()
called from the HTTP server when the socket should be closed due to an external request; the start() ...
static hash make501(string fmt)
creates a hash for an HTTP 501 error response with the response message body as a string ...
constructor(*code logfunc, *code errlogfunc, bool dbg=False, string name=sprintf("Qore-HTTP-Server/%s", HttpServer::Version), hash hdr=("X-Powered-By":"Qore/"+Qore::VersionString))
creates the HttpServer
const False
bool requiresAuthentication()
called to check if the connection requires authentication
list list(...)
abstract base class for external authentication
Definition: HttpServer.qm.dox.h:432
static hash makeResponse(int code, string fmt)
creates a hash for an HTTP response with the response code and the response message body as a formatt...
static hash make400(string fmt)
creates a hash for an HTTP 400 error response with the response message body as a string ...
hash getListenerInfo(softint id)
returns a hash of information about the listener given the listener ID
restoreThreadLocalData(*hash data)
called after handleRequest() with any data returned from saveThreadData()
stop()
called from the HTTP server when the socket should be closed due to an external request; the start() ...
const PollTimeout
default poll timeout in ms
Definition: HttpServer.qm.dox.h:733
softlist addListeners(softstring sock, *string cert_path, *string key_path, *string name, int family=AF_UNSPEC)
adds one or more global listeners according to the bind address
constructor(*AbstractAuthenticator auth)
create the object optionally with the given AbstractAuthenticator
nothing exit(softint rc=0)
hash parse_uri_query(string path)
parses a URI path for a arguments and a method; where the method is the part of the path before the f...
final list addListenersWithHandler(string hname, AbstractHttpRequestHandler handler, hash lp, *code logger, *code errorlogger, *code stopc, *string name, int family=AF_UNSPEC)
adds a dedicated listener to the server with an explicit/dedicated handler for incoming connections ...
static *string getLogMessage(hash cx, hash api, reference params, *reference args)
helper method for handling log messages
sendHttpError(HttpListener listener, hash cx, Socket s, int code, string msg, *hash extra_hdrs, *string encoding)
sends an HTTP error message on the socket
stopNoWait()
stops all listeners; does not wait for all connections on the listeners to close
bool getDebug()
returns the current status of the debug flag
abstract class that all HTTP dedicated socket handler objects must inherit from
Definition: HttpServer.qm.dox.h:610
abstract class for HTTP request handlers anchored at a specific URL
Definition: HttpServer.qm.dox.h:586
waitStop()
waits for all listeners to be stopped; call after calling HttpServer::stopNoWait() ...
hash handleRequest(hash cx, hash hdr, *data body)
will be called when a request is received that should be directed to the handler
const AIFlags
address info flags
Definition: HttpServer.qm.dox.h:740
bool decompress_to_string
if automatically decompressed POSTed data should be converted to a string (if False, then it will be decompressed to a binary)
Definition: HttpServer.qm.dox.h:501
copy()
throws an exception; these objects do not support copying
const Version
version of the HttpServer&#39;s implementation
Definition: HttpServer.qm.dox.h:729
setDefaultHandler(string name, AbstractHttpRequestHandler obj)
sets the default request handler when no other handler can be matched
The HttpServer class implements a multithreaded HTTP server primarily designed for serving RPC-style ...
Definition: HttpServer.qm.dox.h:724
authenticate(string user, string pass="")
called to authenticate a user for a connection
setHandler(string name, string path, *softlist content_type, AbstractHttpRequestHandler obj, *softlist special_headers, bool isregex=True)
sets a request handler according to the arguments given
int getListenerCount()
returns the number of running HTTP listeners
this class implements the listeners for the HttpServer class
Definition: HttpServer.qm.dox.h:1224
log()
called to log information to the registered log code
const VersionString
*hash saveThreadLocalData()
called before handleRequest() any data returned here will be given to restoreThreadLocalData() after ...
list addINETListeners(*string node, softstring service, *string cert_path, *string key_path, *string name, int family=AF_UNSPEC)
adds one or more global listeners according to the bind address
authenticateByIP(string ip, reference user)
called when the connection requires authentication, but no authentication credentials were supplied...
hash hash(object obj)
string url_root
root part of URL for matching requests
Definition: HttpServer.qm.dox.h:591
const AI_ADDRCONFIG
hash getListenerInfoName(string name)
returns a hash of information about the listener given the listener name or bind ID ...
const HttpCodes
map of HTTP result codes and text messages
Definition: HttpServer.qm.dox.h:755
const AI_PASSIVE
static hash redirect(hash cx, hash hdr, string path)
generates a redirect hash for the given path
*hash authenticateRequest(HttpListener listener, hash hdr, reference cx)
primary method called to authenticate each request
hash lsh
hash of listener stop flags
Definition: HttpServer.qm.dox.h:621
const ContentEncodings
content-encodings supported; this is a hash to simulate a set with O(ln(n)) access times ...
Definition: HttpServer.qm.dox.h:858
int getListenerTID(softint id)
gets the TID of a listener based on its listener ID