Qore HttpServer Module Reference  0.3.11.1
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 - 2016 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 
234 
241 namespace HttpServer {
243 
249  string get_exception_string(hash ex);
250 
251 };
252 
253 // class containing handler info
254 class HttpServer::HandlerInfo {
255 
256 public:
257  public :
258  string name;
260  string path;
261  bool isregex;
262  // content type hash
263  hash ch;
264  *list shdr;
265 
266 public:
267 
268  constructor(string n_name, HttpServer::AbstractHttpRequestHandler n_obj, string n_path, bool n_isregex = True, *softlist n_content, *softlist n_shdr);
269 
270 
271  bool matchContentType(string ct);
272 
273 
275  int matchRequest(hash hdr, int score);
276 
277 };
278 
279 // class to implement handler-handling (private)
280 class HttpServer::HttpHandlerList {
281 
282 public:
283  public :
284  hash handlers;
285  TreeMap treeMap();
286 
287 public:
288 
289 
290 private:
291  static checkSpecialHeaders(reference sh);
292 public:
293 
294 
296  setHandler(string name, string path, bool isregex = True, *softlist content, HttpServer::AbstractHttpRequestHandler obj, *softlist special_headers);
297 
298 
299  // matches a handler to the request
300  *HandlerInfo findHandler(hash hdr, reference score, bool finalv = False, *reference root_path);
301 
302 
303  bool empty();
304 
305 
306  int size();
307 
308 };
309 
310 // class containing dynamic handler info
311 class HttpServer::DynamicHandlerInfo : public HttpServer::HandlerInfo {
312 
313 public:
314  public :
315  Counter counter();
316 
317 public:
318 
319  constructor(string name, HttpServer::AbstractHttpRequestHandler obj, string path, bool isregex = True, *softlist content, *softlist shdr) ;
320 
321 };
322 
323 // maintains the request count for dynamic handlers (private)
324 class HttpServer::DynamicHandlerHelper {
325 
326 public:
327 private:
328 
329 public:
330 
331  private :
332  Counter c;
333 
334 public:
335 
336  constructor(Counter n_c);
337 
338 
339  destructor();
340 
341 };
342 
343 // for dynamic handler-handling (private)
344 class HttpServer::DynamicHttpHandlerList : public HttpServer::HttpHandlerList {
345 
346 public:
347  private :
348  RWLock dhl();
349 
350 public:
351 
353  setHandler(string name, string path, bool isregex, *softlist content_type, HttpServer::AbstractHttpRequestHandler obj, *softlist special_headers);
354 
355 
357  removeHandler(string name);
358 
359 
360  *DynamicHandlerInfo findHandler(hash hdr, reference score, reference dhh, *reference root_path);
361 
362 };
363 
366 
367 public:
368  public :
372  const ReadTimeout = HttpServer::ReadTimeout; // recvs timeout after 30 seconds
374  const PollTimeout = 5000; // check for exit every 5 seconds while waiting
375 
376  // logging options
377  const LP_LOGPARAMS = HttpServer::LP_LOGPARAMS;
378  const LP_LEVELMASK = HttpServer::LP_LEVELMASK;
379 
382 
384  const HttpMethods = (
385  "HEAD": True,
386  "POST": True,
387  "PUT": True,
388  "DELETE": True,
389  "GET": True,
390  "OPTIONS": True,
391  //"TRACE": True,
392  //"CONNECT": True,
393  );
394 
397 
400  "gzip": "gzip",
401  "deflate": "deflate",
402  "bzip2": "bzip2",
403  "x-gzip": "gzip",
404  "x-deflate": "deflate",
405  "x-bzip2": "bzip2",
406  );
407 
409  const DefaultIdleThreads = 10;
410 
412  const CompressionThreshold = 1024;
413 
423  const LLO_RECV_HEADERS = (1 << 0);
425 
427  const LLO_RECV_BODY = (1 << 1);
428 
430  const LLO_SEND_HEADERS = (1 << 2);
431 
433  const LLO_SEND_BODY = (1 << 3);
435 
436 public:
437 
439  private :
440  *code logfunc;
441  *code errlogfunc;
442 
443  // quit server flag
444  bool exit = False;
445 
446  // if True then verbose exception info will be logged
447  bool debug;
448 
449  Sequence seqSessions();
450  Sequence seqListeners();
451 
452  bool stopped = False;
453 
454  // permanent handlers; these handlers are never removed
455  HttpHandlerList handlers();
456 
457  // default handler
458  hash defaultHandler;
459 
460  // hash of listeners keyed by listener ID
461  hash listeners;
462 
463  // map of bind addresses to listener IDs
464  hash smap;
465 
466  // map of listener names to listener IDs
467  hash nmap;
468 
469  // listener Gate
470  Gate lm();
471 
472  // running listener counter
473  Counter c();
474 
475  // dynamic handlers
476  DynamicHttpHandlerList dhandlers();
477 
478  // connection thread pool
479  ThreadPool threadPool(-1, DefaultIdleThreads);
480 
481  // other misc response headers
482  hash hdr;
483 
484  // 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
485  *string override_encoding;
486 
487  string http_server_string;
488 
489 public:
491 
493 
501  constructor(*code n_logfunc, *code n_errlogfunc, bool n_dbg = False, string n_name = HttpServer::HttpServerString, hash n_hdr = ("X-Powered-By": "Qore/" + Qore::VersionString));
502 
503 
505  destructor();
506 
507 
509  static string getHttpServerVersionString();
510 
511  setDefaultTextEncoding(string enc);
512 
513 
514  string getDefaultTextEncoding();
515 
516 
518 
547  final list addListenersWithHandler(string hname, HttpServer::AbstractHttpRequestHandler handler, hash lp, *code logger, *code errorlogger, *code stopc, *string name, int family = AF_UNSPEC);
548 
549 
551 
575  final list addListeners(string bind, hash lp, *code logger, *code errorlogger, *code stopc, *string name, int family = AF_UNSPEC);
576 
577 
579 
595  hash addListener(softstring sock, *string cert_path, *string key_path, *string name, int family = AF_UNSPEC, *string pwd);
596 
597 
599 
615  softlist addListeners(softstring sock, *string cert_path, *string key_path, *string name, int family = AF_UNSPEC, *string pwd);
616 
617 
619 
634  list addINETListeners(*string node, softstring service, *string cert_path, *string key_path, *string name, int family = AF_UNSPEC, *string pwd);
635 
636 
638  copy();
639 
640 
642 
644  hash getListeners();
645 
646 
648 
665  hash getListenerInfo(softint id);
666 
667 
669 
686  hash getListenerInfoName(string name);
687 
688 
690  int getListenerCount();
691 
692 
694 
696  stopNoWait();
697 
698 
700  waitStop();
701 
702 
704 
709  listenerStarted(int id, hash sinfo);
710 
711 
712  // only called from the listeners - do not call externally
713  listenerStopped(HttpListener l);
714 
715 
717 
719  stop();
720 
721 
723  stopListener(softstring bind);
724 
725 
727  stopListenerID(softint id);
728 
729 
731  int getListenerTID(softint id);
732 
733 
736 
737 
739  setHandler(string name, string path, *softlist content_type, HttpServer::AbstractHttpRequestHandler obj, *softlist special_headers, bool isregex = True);
740 
741 
743  setDynamicHandler(string name, string path, *softlist content_type, HttpServer::AbstractHttpRequestHandler obj, *softlist special_headers, bool isregex = True);
744 
745 
747  setHandler(string name, HttpServer::AbstractUrlHandler obj);
748 
749 
752 
753 
755  addHandlerToListener(softstring bind, string name, string path, *softlist content_type, HttpServer::AbstractHttpRequestHandler obj, *softlist special_headers, bool isregex = True);
756 
757 
759  addHandlerToListenerID(softint id, string name, string path, *softlist content_type, HttpServer::AbstractHttpRequestHandler obj, *softlist special_headers, bool isregex = True);
760 
761 
763  addHandlerToListener(softstring bind, string name, HttpServer::AbstractUrlHandler obj);
764 
765 
767  addHandlerToListenerID(softint id, string name, HttpServer::AbstractUrlHandler obj);
768 
769 
771 
781  setListenerLogOptions(softstring bind, softint code);
782 
783 
785 
795  setListenerLogOptionsID(softint id, softint code);
796 
797 
799 
802  int getListenerLogOptions(softstring bind);
803 
804 
806 
809  int getListenerLogOptionsID(softint id);
810 
811 
813  removeDynamicHandler(string name);
814 
815 
817  log(string fmt);
818 
819 
821  logError(string fmt);
822 
823 
825  sendHttpError(HttpListener listener, hash cx, Socket s, int code, string msg, *hash extra_hdrs, *string encoding);
826 
827 
829 
834  static string getURLFromBind(softstring bind, *string host);
835 
837  setDebug(bool dbg = True);
838 
839 
841  bool getDebug();
842 
843 
844  startConnection(code c);
845 
846 
848 
850  private int getListenerIdFromBindUnlocked(string bind);
851 
852 
854  private setListenerLogOptionsUnlocked(softstring id, int code);
855 
856 
858  private int getListenerLogOptionsUnlocked(softstring id);
859 
860 
862  static nothing setReplyHeaders(Socket s, hash cx, reference rv);
863 
865  // don't reimplement this method; fix/enhance it in the module
866  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);
867 
868 
869  // don't reimplement this method; fix/enhance it in the module
870  static final private hash getSSLObjects(string cert_path, *string key_path, *string pwd);
871 
872  // don't reimplement this method; fix/enhance it in the module
873  final private list addINETListenersIntern(*string node, softstring service, *hash sd, *hash lp, *code logger, *code errorlogger, *code stopc, *string name, int family = AF_UNSPEC);
874 
875 
876  // don't reimplement this method; fix/enhance it in the module
877  final private hash noHandlerError(hash cx, hash hdr, any body);
878 
879 
880  // handles an incoming request - do not call externally; this method is called by the listeners when a request is received
881  // don't reimplement this method; fix/enhance it in the module
882  final handleRequest(HttpListener listener, Socket s, reference cx, hash hdr, hash hh, *data body, bool head = False, HttpPersistentHandlerInfo phi);
883 
884 
885  // sends a reply to a request
886  // don't reimplement this method; fix/enhance it in the module
887  final sendReply(HttpListener listener, Socket s, HttpServer::AbstractHttpRequestHandler handler, hash rv, reference cx, hash hdr, bool head);
888 
890 };
891 
892 class HttpServer::HttpPersistentHandlerInfo {
893 
894 public:
895  public :
896  *DynamicHandlerHelper dhh;
898 
899 public:
900 
901  destructor();
902 
903 
904  assign(*DynamicHandlerHelper n_dhh, HttpServer::AbstractHttpRequestHandler n_handler);
905 
906 
907  clear();
908 
909 };
910 
912 
915 
916 public:
917  private :
918  HttpServer serv;
919  Sequence ss;
920  *SSLCertificate cert;
921  *SSLPrivateKey key;
922  bool ssl = False;
923  any socket;
924  hash socket_info;
925 
926  // connection counter
927  Counter cThreads();
928  bool exit = False;
929  bool stopped = False;
930  int id;
931 
932  // socket handler hash
933  hash shh;
934 
935  // mutex
936  Mutex m();
937 
938  // code references to external logging functions
939  *code logger;
940  *code errorlogger;
941 
942  // stop notification closure
943  *code stopc;
944 
945  string name;
946 
947  // log recv headers flag
948  bool log_recv_headers = False;
949 
950  // log recv body flag
951  bool log_recv_body = False;
952 
953  // log send headers flag
954  bool log_send_headers = False;
955 
956  // log send body flag
957  bool log_send_body = False;
958 
959  const PollInterval = 1s;
960  const ListenQueue = 100;
961 
962 public:
963 
964  public :
965  // TID of the background listener thread
966  int tid;
967 
968  // listener-specific handlers
969  HttpHandlerList handlers();
970 
971  // default handler info
972  *HandlerInfo defaultHandler;
973 
974 public:
975 
976  // params: server, id, session ID sequence object, socket, rbac obj, [cert, key]
977  constructor(HttpServer n_server, int n_id, Sequence n_ss, *string n_node, *softstring n_service, *Qore::SSLCertificate n_cert, *Qore::SSLPrivateKey n_key, *hash n_hi, *code n_logger, *code n_errorlogger, *code n_stopc, string n_name, int n_family = AF_UNSPEC);
978 
979 
980  addHandlers(hash hi);
981 
982 
983  setDefaultHandler(string name);
984 
985 
986  copy();
987 
988 
989  destructor();
990 
991 
992  logRecvHeaders(softbool flag = True);
993 
994 
995  logRecvBody(softbool flag = True);
996 
997 
998  logSendHeaders(softbool flag = True);
999 
1000 
1001  logSendBody(softbool flag = True);
1002 
1003 
1004  hash getLogOptions();
1005 
1006 
1007  string getName();
1008 
1009 
1010  any getAddress();
1011 
1012 
1013  int getID();
1014 
1015 
1016  bool isSecure();
1017 
1018 
1019  hash getInfo();
1020 
1021 
1022  any removeUserThreadContext(*string k);
1023 
1024 
1025  addUserThreadContext(hash uctx);
1026 
1027 
1028  stopNoWait();
1029 
1030 
1031  stop();
1032 
1033 
1034  logResponse(hash cx, int code, *data body, *hash hdr);
1035 
1036 
1037  logResponse(hash cx, hash rv);
1038 
1039 
1040  log(string fmt);
1041 
1042 
1043  logError(string fmt);
1044 
1045 
1046  private mainThread();
1047 
1048 
1049  // thread for handling communication per connection
1050  private connectionThread(Socket s);
1051 
1052 
1053  bool registerDedicatedSocket(softstring id, HttpServer::AbstractHttpSocketHandler h);
1054 
1055 
1056  removeDedicatedSocket(softstring id, HttpServer::AbstractHttpSocketHandler h);
1057 
1058 };
log(string fmt)
called to log information to the registered log code
hash addListener(softstring sock, *string cert_path, *string key_path, *string name, int family=AF_UNSPEC, *string pwd)
adds a global listener to the server
const AF_UNSPEC
hash getListeners()
returns a hash of listener information
int getListenerLogOptions(softstring bind)
returns a binary-or'ed product of listener log options corresponding to enabled log options for the g...
addHandlerToListener(softstring bind, string name, string path, *softlist content_type, HttpServer::AbstractHttpRequestHandler obj, *softlist special_headers, bool isregex=True)
adds a request handler to a listener given the listener's name or bind address
const ReadTimeout
string get_exception_string(hash ex)
returns a multi-line string from the exception hash argument suitable for logging or output on the co...
const HttpCodes
setDebug(bool dbg=True)
turns on or off debugging; when debugging is enabled more verbose error messages are reported ...
const LP_LOGPARAMS
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:372
removeDynamicHandler(string name)
remove dynamic handler
constructor(*code n_logfunc, *code n_errlogfunc, bool n_dbg=False, string n_name=HttpServer::HttpServerString, hash n_hdr=("X-Powered-By":"Qore/"+Qore::VersionString))
creates the HttpServer
destructor()
calls stop() and destroys the object
const True
const LLO_RECV_HEADERS
listener log option: log recv headers
Definition: HttpServer.qm.dox.h:424
const DefaultIdleThreads
default number of idle threads to have waiting for new connections (accross all listeners) ...
Definition: HttpServer.qm.dox.h:409
stopListener(softstring bind)
stops a single listener based on its name or bind address; does not return until all connections on t...
private setListenerLogOptionsUnlocked(softstring id, int code)
turns on or off header and body logging options for the given listener according to the option code ...
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:384
stop()
stops all listeners; only returns when all connections are closed on all listeners ...
const False
list list(...)
final list addListenersWithHandler(string hname, HttpServer::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 ...
hash getListenerInfo(softint id)
returns a hash of information about the listener given the listener ID
setListenerLogOptions(softstring bind, softint code)
turns on or off header and body logging options for receive operations for the given listener ...
const LLO_SEND_BODY
listener log option: log sent message body
Definition: HttpServer.qm.dox.h:433
const PollTimeout
default poll timeout in ms
Definition: HttpServer.qm.dox.h:374
final list addListeners(string bind, 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 ...
logError(string fmt)
called to log error information to the registered error log code
const HttpServerVersion
nothing exit(softint rc=0)
static string getHttpServerVersionString()
returns the HTTP server version string
sendHttpError(HttpListener listener, hash cx, Socket s, int code, string msg, *hash extra_hdrs, *string encoding)
sends an HTTP error message on the socket
int getListenerLogOptionsID(softint id)
returns a binary-or'ed product of listener log options corresponding to enabled log options for the g...
const LLO_RECV_BODY
listener log option: log recv message body
Definition: HttpServer.qm.dox.h:427
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
setDynamicHandler(string name, string path, *softlist content_type, HttpServer::AbstractHttpRequestHandler obj, *softlist special_headers, bool isregex=True)
sets a dynamic request handler according to the arguments given
const CompressionThreshold
default threadhold for data compressions; transfers smaller than this size will not be compressed ...
Definition: HttpServer.qm.dox.h:412
waitStop()
waits for all listeners to be stopped; call after calling HttpServer::stopNoWait() ...
setHandler(string name, string path, *softlist content_type, HttpServer::AbstractHttpRequestHandler obj, *softlist special_headers, bool isregex=True)
sets a request handler according to the arguments given
static nothing setReplyHeaders(Socket s, hash cx, reference rv)
helper method to set HTTP response headers
list addINETListeners(*string node, softstring service, *string cert_path, *string key_path, *string name, int family=AF_UNSPEC, *string pwd)
adds one or more global listeners according to the bind address
const AIFlags
address info flags
Definition: HttpServer.qm.dox.h:381
const LP_LEVELMASK
const HttpServerString
copy()
throws an exception; these objects do not support copying
const Version
version of the HttpServer's implementation
Definition: HttpServer.qm.dox.h:370
The HttpServer class implements a multithreaded HTTP server.
Definition: HttpServer.qm.dox.h:365
the main namespace for the HttpServer module
int getListenerCount()
returns the number of running HTTP listeners
this class implements the listeners for the HttpServer class
Definition: HttpServer.qm.dox.h:914
const VersionString
hash hash(object obj)
private int getListenerIdFromBindUnlocked(string bind)
returns the listener ID from the bind name or throws an exception if not valid
listenerStarted(int id, hash sinfo)
called from listener when the actual listener thread is running
const AI_ADDRCONFIG
hash getListenerInfoName(string name)
returns a hash of information about the listener given the listener name or bind ID ...
addHandlerToListenerID(softint id, string name, string path, *softlist content_type, HttpServer::AbstractHttpRequestHandler obj, *softlist special_headers, bool isregex=True)
adds a request handler to a listener given the listener's id
setDefaultHandler(string name, HttpServer::AbstractHttpRequestHandler obj)
sets the default request handler when no other handler can be matched
const HttpCodes
map of HTTP result codes and text messages
Definition: HttpServer.qm.dox.h:396
const LLO_SEND_HEADERS
listener log option: log send headers
Definition: HttpServer.qm.dox.h:430
const AI_PASSIVE
private int getListenerLogOptionsUnlocked(softstring id)
returns header and body logging options for the given listener as a binary-or'ed value of listener lo...
setListenerLogOptionsID(softint id, softint code)
turns on or off header and body logging options for receive operations for the given listener ...
const ContentEncodings
content-encodings supported; this is a hash to simulate a set with O(ln(n)) access times ...
Definition: HttpServer.qm.dox.h:399
int getListenerTID(softint id)
gets the TID of a listener based on its listener ID