All Classes Namespaces Functions Variables Groups Pages
HttpServer.qm.dox.h
// -*- mode: c++; indent-tabs-mode: nil -*-
// @file HttpServer.qm HTTP multi-threaded server module definition
/* HttpServer.qm Copyright (C) 2012 - 2018 Qore Technologies, s.r.o.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
// need mime definitions
namespace HttpServer {
string get_exception_string(hash ex);
};
// class containing handler info
class HttpServer::HandlerInfo {
public:
public :
string name;
HttpServer::AbstractHttpRequestHandler obj;
string path;
bool isregex;
// content type hash
hash ch;
*list shdr;
public:
constructor(string n_name, HttpServer::AbstractHttpRequestHandler n_obj, string n_path, bool n_isregex = True, *softlist n_content, *softlist n_shdr);
bool matchContentType(string ct);
int matchRequest(hash hdr, int score);
};
// class to implement handler-handling (private)
class HttpServer::HttpHandlerList {
public:
public :
hash handlers;
TreeMap treeMap();
public:
/*
private static checkSpecialHeaders(reference sh) {
foreach auto h in (\sh) {
if (h.typeCode() != NT_STRING)
throw "SETHANDLER-ERROR", sprintf("entry %d in the special header list is not a string; type: %s", $#, h.type());
# make sure header is in lower case for matching
h = tolower(h);
}
}
*/
setHandler(string name, string path, bool isregex = True, *softlist content, HttpServer::AbstractHttpRequestHandler obj, *softlist special_headers);
// matches a handler to the request
*HandlerInfo findHandler(hash hdr, reference<int> score, bool finalv = False, *reference<string> root_path);
bool empty();
int size();
};
// class containing dynamic handler info
class HttpServer::DynamicHandlerInfo : public HttpServer::HandlerInfo {
public:
public :
Counter counter();
public:
constructor(string name, HttpServer::AbstractHttpRequestHandler obj, string path, bool isregex = True, *softlist content, *softlist shdr) ;
};
// maintains the request count for dynamic handlers (private)
class HttpServer::DynamicHandlerHelper {
public:
private:
public:
private :
Counter c;
public:
constructor(Counter n_c);
destructor();
};
// for dynamic handler-handling (private)
class HttpServer::DynamicHttpHandlerList : public HttpServer::HttpHandlerList {
public:
private :
RWLock dhl();
public:
setHandler(string name, string path, bool isregex, *softlist content_type, HttpServer::AbstractHttpRequestHandler obj, *softlist special_headers);
removeHandler(string name);
*DynamicHandlerInfo findHandler(hash hdr, reference<int> score, reference<DynamicHandlerHelper> dhh, *reference<string> root_path);
};
class HttpServer::HttpServer : public HttpServer::AbstractLogger {
public:
public :
const Version = HttpServer::HttpServerVersion;
const ReadTimeout = HttpServer::ReadTimeout; // recvs timeout after 30 seconds
const PollTimeout = 5000; // check for exit every 5 seconds while waiting
// logging options
const LP_LOGPARAMS = HttpServer::LP_LOGPARAMS;
const LP_LEVELMASK = HttpServer::LP_LEVELMASK;
const AIFlags = AI_PASSIVE | AI_ADDRCONFIG;
const HttpMethods = (
"HEAD": True,
"POST": True,
"PUT": True,
"DELETE": True,
"GET": True,
"OPTIONS": True,
"PATCH": True,
//"TRACE": True,
//"CONNECT": True,
);
const HttpCodes = HttpServer::HttpCodes;
const ContentEncodings = (
"gzip": "gzip",
"deflate": "deflate",
"bzip2": "bzip2",
"x-gzip": "gzip",
"x-deflate": "deflate",
"x-bzip2": "bzip2",
);
const DefaultIdleThreads = 10;
const CompressionThreshold = 1024;
const LLO_RECV_HEADERS = (1 << 0);
const LLO_RECV_BODY = (1 << 1);
const LLO_SEND_HEADERS = (1 << 2);
const LLO_SEND_BODY = (1 << 3);
public:
private :
*code logfunc;
*code errlogfunc;
// for masking HTTP request log msgs
*code maskfunc;
// quit server flag
bool exit = False;
// if True then verbose exception info will be logged
bool debug;
Sequence seqSessions();
Sequence seqListeners();
bool stopped = False;
// permanent handlers; these handlers are never removed
HttpHandlerList handlers();
// default handler
hash defaultHandler;
// hash of listeners keyed by listener ID
hash listeners;
// map of bind addresses to listener IDs
hash smap;
// map of listener names to listener IDs
hash nmap;
// listener Gate
Gate lm();
// running listener counter
Counter c();
// dynamic handlers
DynamicHttpHandlerList dhandlers();
// connection thread pool
ThreadPool threadPool(-1, DefaultIdleThreads);
// other misc response headers
hash hdr;
// 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
*string override_encoding;
string http_server_string;
public:
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));
destructor();
static string getHttpServerVersionString();
setDefaultTextEncoding(string enc);
string getDefaultTextEncoding();
final list addListenersWithHandler(string hname, HttpServer::AbstractHttpRequestHandler handler, hash lp, *code logger, *code errorlogger, *code stopc, *string name, int family = AF_UNSPEC);
final list addListeners(string bind, hash lp, *code logger, *code errorlogger, *code stopc, *string name, int family = AF_UNSPEC);
hash addListener(softstring sock, *string cert_path, *string key_path, *string name, int family = AF_UNSPEC, *string pwd);
softlist addListeners(softstring sock, *string cert_path, *string key_path, *string name, int family = AF_UNSPEC, *string pwd);
list addINETListeners(*string node, softstring service, *string cert_path, *string key_path, *string name, int family = AF_UNSPEC, *string pwd);
copy();
hash getListeners();
hash getListenerInfo(softint id);
hash getListenerInfoName(string name);
int getListenerCount();
stopNoWait();
waitStop();
listenerStarted(int id, hash sinfo);
// only called from the listeners - do not call externally
listenerStopped(HttpListener l);
stop();
stopListener(softstring bind);
stopListenerID(softint id);
int getListenerTID(softint id);
setDefaultHandler(string name, HttpServer::AbstractHttpRequestHandler obj);
setHandler(string name, string path, *softlist content_type, HttpServer::AbstractHttpRequestHandler obj, *softlist special_headers, bool isregex = True);
setDynamicHandler(string name, string path, *softlist content_type, HttpServer::AbstractHttpRequestHandler obj, *softlist special_headers, bool isregex = True);
setHandler(string name, HttpServer::AbstractUrlHandler obj);
setDynamicHandler(string name, HttpServer::AbstractUrlHandler obj);
addHandlerToListener(softstring bind, string name, string path, *softlist content_type, HttpServer::AbstractHttpRequestHandler obj, *softlist special_headers, bool isregex = True);
addHandlerToListenerID(softint id, string name, string path, *softlist content_type, HttpServer::AbstractHttpRequestHandler obj, *softlist special_headers, bool isregex = True);
addHandlerToListener(softstring bind, string name, HttpServer::AbstractUrlHandler obj);
addHandlerToListenerID(softint id, string name, HttpServer::AbstractUrlHandler obj);
setListenerLogOptions(softstring bind, softint code);
setListenerLogOptionsID(softint id, softint code);
int getListenerLogOptions(softstring bind);
int getListenerLogOptionsID(softint id);
removeDynamicHandler(string name);
log(string fmt);
logError(string fmt);
sendHttpError(HttpListener listener, hash cx, Socket s, int code, string msg, *hash extra_hdrs, *string encoding);
string maskData(string msg);
setMaskCode(code maskfunc);
static string getURLFromBind(softstring bind, *string host);
setDebug(bool dbg = True);
bool getDebug();
startConnection(code c);
private:
int getListenerIdFromBindUnlocked(string bind);
public:
private:
setListenerLogOptionsUnlocked(softstring id, int code);
public:
private:
int getListenerLogOptionsUnlocked(softstring id);
public:
static nothing setReplyHeaders(Socket s, hash cx, reference<hash> rv);
// don't reimplement this method; fix/enhance it in the module
private:
final 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);
public:
// don't reimplement this method; fix/enhance it in the module
private:
static final hash getSSLObjects(string cert_path, *string key_path, *string pwd);
public:
// don't reimplement this method; fix/enhance it in the module
private:
final list addINETListenersIntern(*string node, softstring service, *hash sd, *hash lp, *code logger, *code errorlogger, *code stopc, *string name, int family = AF_UNSPEC);
public:
// don't reimplement this method; fix/enhance it in the module
private:
final hash<HttpResponseInfo> noHandlerError(hash cx, hash hdr, auto body);
public:
// handles an incoming request - do not call externally; this method is called by the listeners when a request is received
// don't reimplement this method; fix/enhance it in the module
final handleRequest(HttpListener listener, Socket s, reference<hash> cx, hash hdr, hash hh, *data body, bool head = False, HttpPersistentHandlerInfo phi);
// sends a reply to a request
// don't reimplement this method; fix/enhance it in the module
final sendReply(HttpListener listener, Socket s, HttpServer::AbstractHttpRequestHandler handler, hash rv, reference<hash> cx, hash hdr, bool head);
};
class HttpServer::HttpPersistentHandlerInfo {
public:
public :
*DynamicHandlerHelper dhh;
*HttpServer::AbstractHttpRequestHandler handler;
public:
destructor();
assign(*DynamicHandlerHelper n_dhh, HttpServer::AbstractHttpRequestHandler n_handler);
clear();
};
class HttpServer::HttpListener : public Qore::Socket,public HttpServer::HttpListenerInterface {
public:
private :
HttpServer serv;
Sequence ss;
*SSLCertificate cert;
*SSLPrivateKey key;
bool ssl = False;
auto socket;
hash socket_info;
// connection counter
Counter cThreads();
bool exit = False;
bool stopped = False;
int id;
// socket handler hash
hash shh;
// mutex
Mutex m();
// code references to external logging functions
*code logger;
*code errorlogger;
// stop notification closure
*code stopc;
string name;
// log recv headers flag
bool log_recv_headers = False;
// log recv body flag
bool log_recv_body = False;
// log send headers flag
bool log_send_headers = False;
// log send body flag
bool log_send_body = False;
const PollInterval = 1s;
const ListenQueue = 100;
const BodyLogLimit = 40;
public:
public :
// TID of the background listener thread
int tid;
// listener-specific handlers
HttpHandlerList handlers();
// default handler info
*HandlerInfo defaultHandler;
public:
// params: server, id, session ID sequence object, socket, rbac obj, [cert, key]
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);
addHandlers(hash hi);
setDefaultHandler(string name);
copy();
destructor();
logRecvHeaders(softbool flag = True);
logRecvBody(softbool flag = True);
logSendHeaders(softbool flag = True);
logSendBody(softbool flag = True);
hash getLogOptions();
string getName();
auto getAddress();
int getID();
bool isSecure();
hash getInfo();
auto removeUserThreadContext(*string k);
addUserThreadContext(hash uctx);
stopNoWait();
stop();
logResponse(hash cx, int code, *data body, *hash hdr);
logResponse(hash cx, hash rv);
log(string fmt);
logError(string fmt);
private:
mainThread();
public:
// thread for handling communication per connection
private:
connectionThread(Socket s);
public:
bool registerDedicatedSocket(softstring id, HttpServer::AbstractHttpSocketHandler h);
removeDedicatedSocket(softstring id, HttpServer::AbstractHttpSocketHandler h);
};
HttpServer::HttpServer::log
log(string fmt)
called to log information to the registered log code
HttpServer::HttpServer::addListener
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
Util::get_exception_string
string get_exception_string(hash ex)
returns a multi-line string from the exception hash argument suitable for logging or output on the co...
AF_UNSPEC
const AF_UNSPEC
HttpServer::HttpServer::getListeners
hash getListeners()
returns a hash of listener information
HttpServer::HttpServer::getListenerLogOptions
int getListenerLogOptions(softstring bind)
returns a binary-or&#39;ed product of listener log options corresponding to enabled log options for the g...
HttpServer::HttpServer::addHandlerToListener
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
HttpServer::ReadTimeout
const ReadTimeout
HttpServer::HttpServer::setListenerLogOptionsUnlocked
setListenerLogOptionsUnlocked(softstring id, int code)
turns on or off header and body logging options for the given listener according to the option code ...
HttpServer::HttpCodes
const HttpCodes
HttpServer::HttpServer::setDebug
setDebug(bool dbg=True)
turns on or off debugging; when debugging is enabled more verbose error messages are reported ...
HttpServer::LP_LOGPARAMS
const LP_LOGPARAMS
HttpServer::AbstractHttpRequestHandler
HttpServer::HttpServer::getURLFromBind
static string getURLFromBind(softstring bind, *string host)
returns a complete URL from a bind address
HttpServer::HttpServer::ReadTimeout
const ReadTimeout
default read timeout in ms
Definition: HttpServer.qm.dox.h:382
Qore::Socket
HttpServer::HttpServer::removeDynamicHandler
removeDynamicHandler(string name)
remove dynamic handler
HttpServer::HttpServer::constructor
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
HttpServer::HttpServer::destructor
destructor()
calls stop() and destroys the object
True
const True
HttpServer::HttpListenerInterface
HttpServer::HttpServer::LLO_RECV_HEADERS
const LLO_RECV_HEADERS
listener log option: log recv headers
Definition: HttpServer.qm.dox.h:435
HttpServer::HttpServer::DefaultIdleThreads
const DefaultIdleThreads
default number of idle threads to have waiting for new connections (accross all listeners) ...
Definition: HttpServer.qm.dox.h:420
HttpServer::HttpServer::stopListener
stopListener(softstring bind)
stops a single listener based on its name or bind address; does not return until all connections on t...
HttpServer::HttpServer::stopListenerID
stopListenerID(softint id)
stops a single listener based on its listener ID; does not return until all connections on the listen...
HttpServer::HttpServer::HttpMethods
const HttpMethods
supported HTTP methods
Definition: HttpServer.qm.dox.h:394
HttpServer::HttpServer::stop
stop()
stops all listeners; only returns when all connections are closed on all listeners ...
HttpServer::HttpServer::setReplyHeaders
static nothing setReplyHeaders(Socket s, hash cx, reference< hash > rv)
helper method to set HTTP response headers
False
const False
list
list list(...)
HttpServer::HttpServer::addListenersWithHandler
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 ...
HttpServer::HttpServer::getListenerInfo
hash getListenerInfo(softint id)
returns a hash of information about the listener given the listener ID
HttpServer::HttpServer::setListenerLogOptions
setListenerLogOptions(softstring bind, softint code)
turns on or off header and body logging options for receive operations for the given listener ...
HttpServer::HttpServer::LLO_SEND_BODY
const LLO_SEND_BODY
listener log option: log sent message body
Definition: HttpServer.qm.dox.h:444
HttpServer::HttpServer::PollTimeout
const PollTimeout
default poll timeout in ms
Definition: HttpServer.qm.dox.h:384
HttpServer::HttpServer::addListeners
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 ...
HttpServer::HttpServer::logError
logError(string fmt)
called to log error information to the registered error log code
HttpServer::HttpServerVersion
const HttpServerVersion
exit
nothing exit(softint rc=0)
Qore::SSLPrivateKey
HttpServer::HttpServer::getHttpServerVersionString
static string getHttpServerVersionString()
returns the HTTP server version string
HttpServer::HttpServer::sendHttpError
sendHttpError(HttpListener listener, hash cx, Socket s, int code, string msg, *hash extra_hdrs, *string encoding)
sends an HTTP error message on the socket
HttpServer::AbstractLogger
HttpServer::HttpServer::getListenerLogOptionsID
int getListenerLogOptionsID(softint id)
returns a binary-or&#39;ed product of listener log options corresponding to enabled log options for the g...
HttpServer::HttpServer::LLO_RECV_BODY
const LLO_RECV_BODY
listener log option: log recv message body
Definition: HttpServer.qm.dox.h:438
HttpServer::HttpServer::stopNoWait
stopNoWait()
stops all listeners; does not wait for all connections on the listeners to close
HttpServer::HttpServer::getDebug
bool getDebug()
returns the current status of the debug flag
HttpServer::HttpServer::setDynamicHandler
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
HttpServer::HttpServer::getListenerLogOptionsUnlocked
int getListenerLogOptionsUnlocked(softstring id)
returns header and body logging options for the given listener as a binary-or&#39;ed value of listener lo...
HttpServer::HttpServer::CompressionThreshold
const CompressionThreshold
default threadhold for data compressions; transfers smaller than this size will not be compressed ...
Definition: HttpServer.qm.dox.h:423
HttpServer::AbstractHttpSocketHandler
HttpServer::AbstractUrlHandler
HttpServer::HttpServer::waitStop
waitStop()
waits for all listeners to be stopped; call after calling HttpServer::stopNoWait() ...
HttpServer::HttpServer::setMaskCode
setMaskCode(code maskfunc)
sets the closure or call reference that will be used to mask sensitive data in log messages ...
HttpServer::HttpServer::setHandler
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
Qore::SSLCertificate
HttpServer::HttpServer::addINETListeners
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
HttpServer::HttpServer::AIFlags
const AIFlags
address info flags
Definition: HttpServer.qm.dox.h:391
HttpServer::LP_LEVELMASK
const LP_LEVELMASK
HttpServer::HttpServerString
const HttpServerString
HttpServer::HttpServer::copy
copy()
throws an exception; these objects do not support copying
HttpServer::HttpServer::Version
const Version
version of the HttpServer&#39;s implementation
Definition: HttpServer.qm.dox.h:380
HttpServer::HttpServer::maskData
string maskData(string msg)
masks log messages by removing sensitive data
HttpServer::HttpServer
The HttpServer class implements a multithreaded HTTP server.
Definition: HttpServer.qm.dox.h:375
HttpServer::HttpServer::getListenerCount
int getListenerCount()
returns the number of running HTTP listeners
HttpServer::HttpListener
this class implements the listeners for the HttpServer class
Definition: HttpServer.qm.dox.h:973
Qore::VersionString
const VersionString
hash
hash hash(object obj)
HttpServer::HttpServer::listenerStarted
listenerStarted(int id, hash sinfo)
called from listener when the actual listener thread is running
HttpServer::HttpServer::getListenerIdFromBindUnlocked
int getListenerIdFromBindUnlocked(string bind)
returns the listener ID from the bind name or throws an exception if not valid
AI_ADDRCONFIG
const AI_ADDRCONFIG
HttpServer::HttpServer::getListenerInfoName
hash getListenerInfoName(string name)
returns a hash of information about the listener given the listener name or bind ID ...
HttpServer::HttpServer::addHandlerToListenerID
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
HttpServer::HttpServer::setDefaultHandler
setDefaultHandler(string name, HttpServer::AbstractHttpRequestHandler obj)
sets the default request handler when no other handler can be matched
HttpServer::HttpServer::HttpCodes
const HttpCodes
map of HTTP result codes and text messages
Definition: HttpServer.qm.dox.h:407
HttpServer::HttpServer::LLO_SEND_HEADERS
const LLO_SEND_HEADERS
listener log option: log send headers
Definition: HttpServer.qm.dox.h:441
AI_PASSIVE
const AI_PASSIVE
HttpServer::HttpServer::setListenerLogOptionsID
setListenerLogOptionsID(softint id, softint code)
turns on or off header and body logging options for receive operations for the given listener ...
HttpServer::HttpServer::ContentEncodings
const ContentEncodings
content-encodings supported; this is a hash to simulate a set with O(ln(n)) access times ...
Definition: HttpServer.qm.dox.h:410
HttpServer::HttpServer::getListenerTID
int getListenerTID(softint id)
gets the TID of a listener based on its listener ID