Qore HttpServer Module Reference  0.3.11
 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 - 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 
231 
238 namespace HttpServer {
240 
246  string get_exception_string(hash ex);
247 
248 };
249 
250 // class containing handler info
251 class HttpServer::HandlerInfo {
252 
253 public:
254  public :
255  string name;
257  string path;
258  bool isregex;
259  // content type hash
260  hash ch;
261  *list shdr;
262 
263 public:
264 
265  constructor(string n_name, HttpServer::AbstractHttpRequestHandler n_obj, string n_path, bool n_isregex = True, *softlist n_content, *softlist n_shdr);
266 
267 
268  bool matchContentType(string ct);
269 
270 
272  int matchRequest(hash hdr, int score);
273 
274 };
275 
276 // class to implement handler-handling (private)
277 class HttpServer::HttpHandlerList {
278 
279 public:
280  public :
281  hash handlers;
282  TreeMap treeMap();
283 
284 public:
285 
286 
287 private:
288  static checkSpecialHeaders(reference sh);
289 public:
290 
291 
293  setHandler(string name, string path, bool isregex = True, *softlist content, HttpServer::AbstractHttpRequestHandler obj, *softlist special_headers);
294 
295 
296  // matches a handler to the request
297  *HandlerInfo findHandler(hash hdr, reference score, bool finalv = False, *reference root_path);
298 
299 
300  bool empty();
301 
302 
303  int size();
304 
305 };
306 
307 // class containing dynamic handler info
308 class HttpServer::DynamicHandlerInfo : public HttpServer::HandlerInfo {
309 
310 public:
311  public :
312  Counter counter();
313 
314 public:
315 
316  constructor(string name, HttpServer::AbstractHttpRequestHandler obj, string path, bool isregex = True, *softlist content, *softlist shdr) ;
317 
318 };
319 
320 // maintains the request count for dynamic handlers (private)
321 class HttpServer::DynamicHandlerHelper {
322 
323 public:
324 private:
325 
326 public:
327 
328  private :
329  Counter c;
330 
331 public:
332 
333  constructor(Counter n_c);
334 
335 
336  destructor();
337 
338 };
339 
340 // for dynamic handler-handling (private)
341 class HttpServer::DynamicHttpHandlerList : public HttpServer::HttpHandlerList {
342 
343 public:
344  private :
345  RWLock dhl();
346 
347 public:
348 
350  setHandler(string name, string path, bool isregex, *softlist content_type, HttpServer::AbstractHttpRequestHandler obj, *softlist special_headers);
351 
352 
354  removeHandler(string name);
355 
356 
357  *DynamicHandlerInfo findHandler(hash hdr, reference score, reference dhh, *reference root_path);
358 
359 };
360 
363 
364 public:
365  public :
369  const ReadTimeout = HttpServer::ReadTimeout; // recvs timeout after 30 seconds
371  const PollTimeout = 5000; // check for exit every 5 seconds while waiting
372 
373  // logging options
374  const LP_LOGPARAMS = HttpServer::LP_LOGPARAMS;
375  const LP_LEVELMASK = HttpServer::LP_LEVELMASK;
376 
379 
381  const HttpMethods = (
382  "HEAD": True,
383  "POST": True,
384  "PUT": True,
385  "DELETE": True,
386  "GET": True,
387  "OPTIONS": True,
388  //"TRACE": True,
389  //"CONNECT": True,
390  );
391 
394 
397  "gzip": "gzip",
398  "deflate": "deflate",
399  "bzip2": "bzip2",
400  "x-gzip": "gzip",
401  "x-deflate": "deflate",
402  "x-bzip2": "bzip2",
403  );
404 
406  const DefaultIdleThreads = 10;
407 
409  const CompressionThreshold = 1024;
410 
420  const LLO_RECV_HEADERS = (1 << 0);
422 
424  const LLO_RECV_BODY = (1 << 1);
425 
427  const LLO_SEND_HEADERS = (1 << 2);
428 
430  const LLO_SEND_BODY = (1 << 3);
432 
433 public:
434 
436  private :
437  *code logfunc;
438  *code errlogfunc;
439 
440  // quit server flag
441  bool exit = False;
442 
443  // if True then verbose exception info will be logged
444  bool debug;
445 
446  Sequence seqSessions();
447  Sequence seqListeners();
448 
449  bool stopped = False;
450 
451  // permanent handlers; these handlers are never removed
452  HttpHandlerList handlers();
453 
454  // default handler
455  hash defaultHandler;
456 
457  // hash of listeners keyed by listener ID
458  hash listeners;
459 
460  // map of bind addresses to listener IDs
461  hash smap;
462 
463  // map of listener names to listener IDs
464  hash nmap;
465 
466  // listener Gate
467  Gate lm();
468 
469  // running listener counter
470  Counter c();
471 
472  // dynamic handlers
473  DynamicHttpHandlerList dhandlers();
474 
475  // connection thread pool
476  ThreadPool threadPool(-1, DefaultIdleThreads);
477 
478  // other misc response headers
479  hash hdr;
480 
481  // 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
482  *string override_encoding;
483 
484  string http_server_string;
485 
486 public:
488 
490 
498  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));
499 
500 
502  destructor();
503 
504 
506  static string getHttpServerVersionString();
507 
508  setDefaultTextEncoding(string enc);
509 
510 
511  string getDefaultTextEncoding();
512 
513 
515 
544  final list addListenersWithHandler(string hname, HttpServer::AbstractHttpRequestHandler handler, hash lp, *code logger, *code errorlogger, *code stopc, *string name, int family = AF_UNSPEC);
545 
546 
548 
572  final list addListeners(string bind, hash lp, *code logger, *code errorlogger, *code stopc, *string name, int family = AF_UNSPEC);
573 
574 
576 
592  hash addListener(softstring sock, *string cert_path, *string key_path, *string name, int family = AF_UNSPEC, *string pwd);
593 
594 
596 
612  softlist addListeners(softstring sock, *string cert_path, *string key_path, *string name, int family = AF_UNSPEC, *string pwd);
613 
614 
616 
631  list addINETListeners(*string node, softstring service, *string cert_path, *string key_path, *string name, int family = AF_UNSPEC, *string pwd);
632 
633 
635  copy();
636 
637 
639 
641  hash getListeners();
642 
643 
645 
662  hash getListenerInfo(softint id);
663 
664 
666 
683  hash getListenerInfoName(string name);
684 
685 
687  int getListenerCount();
688 
689 
691 
693  stopNoWait();
694 
695 
697  waitStop();
698 
699 
701 
706  listenerStarted(int id, hash sinfo);
707 
708 
709  // only called from the listeners - do not call externally
710  listenerStopped(HttpListener l);
711 
712 
714 
716  stop();
717 
718 
720  stopListener(softstring bind);
721 
722 
724  stopListenerID(softint id);
725 
726 
728  int getListenerTID(softint id);
729 
730 
733 
734 
736  setHandler(string name, string path, *softlist content_type, HttpServer::AbstractHttpRequestHandler obj, *softlist special_headers, bool isregex = True);
737 
738 
740  setDynamicHandler(string name, string path, *softlist content_type, HttpServer::AbstractHttpRequestHandler obj, *softlist special_headers, bool isregex = True);
741 
742 
744  setHandler(string name, HttpServer::AbstractUrlHandler obj);
745 
746 
749 
750 
752  addHandlerToListener(softstring bind, string name, string path, *softlist content_type, HttpServer::AbstractHttpRequestHandler obj, *softlist special_headers, bool isregex = True);
753 
754 
756  addHandlerToListenerID(softint id, string name, string path, *softlist content_type, HttpServer::AbstractHttpRequestHandler obj, *softlist special_headers, bool isregex = True);
757 
758 
760  addHandlerToListener(softstring bind, string name, HttpServer::AbstractUrlHandler obj);
761 
762 
764  addHandlerToListenerID(softint id, string name, HttpServer::AbstractUrlHandler obj);
765 
766 
768 
778  setListenerLogOptions(softstring bind, softint code);
779 
780 
782 
792  setListenerLogOptionsID(softint id, softint code);
793 
794 
796 
799  int getListenerLogOptions(softstring bind);
800 
801 
803 
806  int getListenerLogOptionsID(softint id);
807 
808 
810  removeDynamicHandler(string name);
811 
812 
814  log(string fmt);
815 
816 
818  logError(string fmt);
819 
820 
822  sendHttpError(HttpListener listener, hash cx, Socket s, int code, string msg, *hash extra_hdrs, *string encoding);
823 
824 
826 
831  static string getURLFromBind(softstring bind, *string host);
832 
834  setDebug(bool dbg = True);
835 
836 
838  bool getDebug();
839 
840 
841  startConnection(code c);
842 
843 
845 
847  private int getListenerIdFromBindUnlocked(string bind);
848 
849 
851  private setListenerLogOptionsUnlocked(softstring id, int code);
852 
853 
855  private int getListenerLogOptionsUnlocked(softstring id);
856 
857 
859  static nothing setReplyHeaders(Socket s, hash cx, reference rv);
860 
862  // don't reimplement this method; fix/enhance it in the module
863  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);
864 
865 
866  // don't reimplement this method; fix/enhance it in the module
867  static final private hash getSSLObjects(string cert_path, *string key_path, *string pwd);
868 
869  // don't reimplement this method; fix/enhance it in the module
870  final private list addINETListenersIntern(*string node, softstring service, *hash sd, *hash lp, *code logger, *code errorlogger, *code stopc, *string name, int family = AF_UNSPEC);
871 
872 
873  // don't reimplement this method; fix/enhance it in the module
874  final private hash noHandlerError(hash cx, hash hdr, any body);
875 
876 
877  // handles an incoming request - do not call externally; this method is called by the listeners when a request is received
878  // don't reimplement this method; fix/enhance it in the module
879  final handleRequest(HttpListener listener, Socket s, reference cx, hash hdr, hash hh, *data body, bool head = False, HttpPersistentHandlerInfo phi);
880 
881 
882  // sends a reply to a request
883  // don't reimplement this method; fix/enhance it in the module
884  final sendReply(HttpListener listener, Socket s, HttpServer::AbstractHttpRequestHandler handler, hash rv, reference cx, hash hdr, bool head);
885 
887 };
888 
889 class HttpServer::HttpPersistentHandlerInfo {
890 
891 public:
892  public :
893  *DynamicHandlerHelper dhh;
895 
896 public:
897 
898  destructor();
899 
900 
901  assign(*DynamicHandlerHelper n_dhh, HttpServer::AbstractHttpRequestHandler n_handler);
902 
903 
904  clear();
905 
906 };
907 
909 
912 
913 public:
914  private :
915  HttpServer serv;
916  Sequence ss;
917  *SSLCertificate cert;
918  *SSLPrivateKey key;
919  bool ssl = False;
920  any socket;
921  hash socket_info;
922 
923  // connection counter
924  Counter cThreads();
925  bool exit = False;
926  bool stopped = False;
927  int id;
928 
929  // socket handler hash
930  hash shh;
931 
932  // mutex
933  Mutex m();
934 
935  // code references to external logging functions
936  *code logger;
937  *code errorlogger;
938 
939  // stop notification closure
940  *code stopc;
941 
942  string name;
943 
944  // log recv headers flag
945  bool log_recv_headers = False;
946 
947  // log recv body flag
948  bool log_recv_body = False;
949 
950  // log send headers flag
951  bool log_send_headers = False;
952 
953  // log send body flag
954  bool log_send_body = False;
955 
956  const PollInterval = 1s;
957  const ListenQueue = 100;
958 
959 public:
960 
961  public :
962  // TID of the background listener thread
963  int tid;
964 
965  // listener-specific handlers
966  HttpHandlerList handlers();
967 
968  // default handler info
969  *HandlerInfo defaultHandler;
970 
971 public:
972 
973  // params: server, id, session ID sequence object, socket, rbac obj, [cert, key]
974  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);
975 
976 
977  addHandlers(hash hi);
978 
979 
980  setDefaultHandler(string name);
981 
982 
983  copy();
984 
985 
986  destructor();
987 
988 
989  logRecvHeaders(softbool flag = True);
990 
991 
992  logRecvBody(softbool flag = True);
993 
994 
995  logSendHeaders(softbool flag = True);
996 
997 
998  logSendBody(softbool flag = True);
999 
1000 
1001  hash getLogOptions();
1002 
1003 
1004  string getName();
1005 
1006 
1007  any getAddress();
1008 
1009 
1010  int getID();
1011 
1012 
1013  bool isSecure();
1014 
1015 
1016  hash getInfo();
1017 
1018 
1019  any removeUserThreadContext(*string k);
1020 
1021 
1022  addUserThreadContext(hash uctx);
1023 
1024 
1025  stopNoWait();
1026 
1027 
1028  stop();
1029 
1030 
1031  logResponse(hash cx, int code, *data body, *hash hdr);
1032 
1033 
1034  logResponse(hash cx, hash rv);
1035 
1036 
1037  log(string fmt);
1038 
1039 
1040  logError(string fmt);
1041 
1042 
1043  private mainThread();
1044 
1045 
1046  // thread for handling communication per connection
1047  private connectionThread(Socket s);
1048 
1049 
1050  bool registerDedicatedSocket(softstring id, HttpServer::AbstractHttpSocketHandler h);
1051 
1052 
1053  removeDedicatedSocket(softstring id, HttpServer::AbstractHttpSocketHandler h);
1054 
1055 };
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
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 AF_UNSPEC
hash getListeners()
returns a hash of listener information
int getListenerLogOptions(softstring bind)
returns a binary-or&#39;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&#39;s name or bind address
const ReadTimeout
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:369
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:421
const DefaultIdleThreads
default number of idle threads to have waiting for new connections (accross all listeners) ...
Definition: HttpServer.qm.dox.h:406
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:381
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:430
const PollTimeout
default poll timeout in ms
Definition: HttpServer.qm.dox.h:371
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&#39;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:424
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:409
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:378
const LP_LEVELMASK
const HttpServerString
copy()
throws an exception; these objects do not support copying
const Version
version of the HttpServer&#39;s implementation
Definition: HttpServer.qm.dox.h:367
The HttpServer class implements a multithreaded HTTP server.
Definition: HttpServer.qm.dox.h:362
int getListenerCount()
returns the number of running HTTP listeners
this class implements the listeners for the HttpServer class
Definition: HttpServer.qm.dox.h:911
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&#39;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:393
const LLO_SEND_HEADERS
listener log option: log send headers
Definition: HttpServer.qm.dox.h:427
const AI_PASSIVE
private int getListenerLogOptionsUnlocked(softstring id)
returns header and body logging options for the given listener as a binary-or&#39;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:396
int getListenerTID(softint id)
gets the TID of a listener based on its listener ID