RestHandler.qm.dox.h
// -*- mode: c++; indent-tabs-mode: nil -*-
/* RestHandler.qm Copyright (C) 2013 - 2017 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.
*/
// minimum qore version
// use new-style
// require type definitions everywhere
// enable all warnings
namespace RestHandler {
class AbstractRestStreamRequestHandler {
public:
private:
public:
private :
hash cx;
*hash ex;
*hash ah;
hash rhdr;
*int timeout_ms;
public:
constructor(hash n_cx, *hash n_ah);
hash<HttpServer::HttpHandlerResponseInfo> getResponseHeaderMessage();
nothing recv(hash v);
auto send();
*code getPersistentClosedNotification();
bool isPersistent();
setTimeout(timeout n_timeout_ms);
*int getTimeout();
streamError(hash n_ex);
abstract hash getResponseHeaderMessageImpl();
abstract nothing recvImpl(hash v);
abstract auto sendImpl();
};
class RestStreamRequest : public HttpServer::AbstractStreamRequest {
public:
private :
RestHandler::AbstractRestStreamRequestHandler stream;
bool deserialized;
public:
constructor(RestHandler::AbstractRestStreamRequestHandler n_stream, HttpServer::HttpListenerInterface listener, HttpServer::AbstractHttpRequestHandler handler, Socket s, hash cx, hash hdr, auto body) ;
destructor();
// callback method for the response header; this calls @ref RestHandler::AbstractRestStreamRequestHandler::getResponseHeaderMessage() and returns the result
private:
hash<HttpServer::HttpHandlerResponseInfo> getResponseHeaderMessageImpl();
public:
private:
nothing recvImpl(hash v);
public:
private:
auto sendImpl();
public:
};
class AbstractRestClass {
public:
private:
public:
constructor();
abstract string name();
*AbstractRestClass subClass(string name, hash cx, *hash args);
hash<HttpServer::HttpHandlerResponseInfo> handleRequest(HttpListenerInterface listener, RestHandler rh, Socket s, *list cl, string mn, hash cx, *hash args);
private:
hash<HttpServer::HttpHandlerResponseInfo> dispatchStream(HttpListenerInterface listener, RestHandler rh, Socket s, string mn, *hash ah, hash cx);
public:
private:
hash<HttpServer::HttpHandlerResponseInfo> dispatch(RestHandler rh, string mn, *hash ah, hash cx);
public:
private:
hash<HttpServer::HttpHandlerResponseInfo> unknownSubClassError(string n_name);
public:
};
class RestHandler : public HttpServer::AbstractHttpRequestHandler,public AbstractRestClass {
public:
public :
const Err501 = new hash<HttpResponseInfo>((
"code": 501,
"body": "not implemented",
));
const Methods = (
"GET": "get",
"POST": "post",
"PUT": "put",
"DELETE": "del",
"OPTIONS": "options",
"PATCH": "patch",
);
const MimeDataTypes = (
MimeTypeJsonRpc: (
"serialize": \make_json(),
"deserialize": \parse_json(),
),
MimeTypeYaml: (
"serialize": \make_yaml(),
"deserialize": \parse_yaml(),
),
MimeTypeYamlRpc: (
"serialize": \make_yaml(),
"deserialize": \parse_yaml(),
),
MimeTypeXml: (
"serialize": \make_xmlrpc_value(),
"deserialize": \parse_xmlrpc_value(),
),
MimeTypeXmlApp: (
"serialize": string (auto v) {
switch (v.typeCode());
return make_xml(("value": v));
},
"deserialize": hash (string xml) {
try {
return parse_xmlrpc_value(xml);
}
catch (hash<ExceptionInfo> ex);
},
),
MimeTypeFormUrlEncoded: (
"serialize": \mime_get_form_urlencoded_string(),
"deserialize": \mime_parse_form_urlencoded_string(),
),
MimeTypeHtml: (
"serialize": string (auto body) { return sprintf("<pre>%N</pre>", body); },
),
);
public:
private :
hash ch;
Mutex mx();
RestSchemaValidator::AbstractRestSchemaValidator validator;
public:
constructor(*HttpServer::AbstractAuthenticator auth, RestSchemaValidator::AbstractRestSchemaValidator validator = new NullRestSchemaValidator()) ;
string name();
auto handleExternalRequest(string method, string path, *hash body, hash cx = {});
hash<HttpResponseInfo> handleRequest(HttpListenerInterface listener, Socket s, hash cx, hash hdr, *data b);
removeRootPath(reference<string> path);
requestDeserializationError(hash hdr, hash cx, string body);
responseSerializationError(hash cx, *hash aih, hash rv);
logInfo(string fmt);
logError(string fmt);
logDebug(string fmt);
addClass(AbstractRestClass cls);
hash get(hash cx, *hash ah);
static hash makeResponse(int code, auto body, *hash hdr);
};
};
// private, unexported namespace
namespace Priv {
// dumHttpListenerInterface class
class DummyListenerInterface : public HttpListenerInterface {
public:
addUserThreadContext(hash uctx);
auto removeUserThreadContext(*string k);
log(string fmt);
logError(string fmt);
};
};
sprintf
string sprintf(string fmt,...)
HttpServer::AbstractStreamRequest::hdr
hash hdr
RestHandler::RestHandler::ch
hash ch
class hash: name -> AbstractRestClass
Definition: RestHandler.qm.dox.h:696
RestHandler::AbstractRestStreamRequestHandler::getTimeout
*int getTimeout()
returns the timeout in milliseconds or NOTHING if no timeout is set
RestHandler::RestStreamRequest::recvImpl
nothing recvImpl(hash v)
callback method for receiving chunked data; this calls RestHandler::AbstractRestStreamRequestHandler:...
HttpServer::AbstractStreamRequest
HttpServer::AbstractHttpRequestHandler
MimeTypeYaml
const MimeTypeYaml
RestHandler::AbstractRestStreamRequestHandler::streamError
streamError(hash n_ex)
registers stream errors in the send operation with the stream handler if no error is already present ...
MimeTypeXml
const MimeTypeXml
RestSchemaValidator::AbstractRestSchemaValidator
RestHandler::AbstractRestStreamRequestHandler::cx
hash cx
call context hash
Definition: RestHandler.qm.dox.h:363
HttpServer::HttpListenerInterface
mime_get_form_urlencoded_string
string mime_get_form_urlencoded_string(hash h)
RestHandler::AbstractRestStreamRequestHandler::getResponseHeaderMessage
hash< HttpServer::HttpHandlerResponseInfo > getResponseHeaderMessage()
this method returns the response message description hash by calling getResponseHeaderMessageImpl() ...
RestHandler
the RestHandler namespace contains all the objects in the RestHandler module
Definition: RestHandler.qm.dox.h:345
HttpServer::AbstractStreamRequest::handler
AbstractHttpRequestHandler handler
MimeTypeJsonRpc
const MimeTypeJsonRpc
RestHandler::RestStreamRequest::destructor
destructor()
destroys the object and updates the request handler about the status of the persistent connection ...
list
list list(...)
HttpServer::AbstractAuthenticator
RestHandler::AbstractRestClass::handleRequest
hash< HttpServer::HttpHandlerResponseInfo > handleRequest(HttpListenerInterface listener, RestHandler rh, Socket s, *list cl, string mn, hash cx, *hash args)
this method is called by the RestHandler class to match the right object with incoming requests ...
RestHandler::RestStreamRequest::sendImpl
auto sendImpl()
callback method for sending chunked data; this calls RestHandler::AbstractRestStreamRequestHandler::s...
MimeTypeFormUrlEncoded
const MimeTypeFormUrlEncoded
HttpServer::AbstractStreamRequest::cx
hash cx
HttpServer::AbstractStreamRequest::s
Socket s
MimeTypeYamlRpc
const MimeTypeYamlRpc
RestHandler::AbstractRestStreamRequestHandler::recv
nothing recv(hash v)
this method provides the callback method for receiving chunked data by calling recvImpl() ...
RestHandler::AbstractRestClass::subClass
*AbstractRestClass subClass(string name, hash cx, *hash args)
this method will be called to find a sub-class (ie with GET /invoices/1 - if this class represents "i...
RestHandler::AbstractRestStreamRequestHandler::sendImpl
abstract auto sendImpl()
abstract callback method for sending chunked data
RestHandler::AbstractRestStreamRequestHandler::ah
*hash ah
call argument hash
Definition: RestHandler.qm.dox.h:369
RestHandler::AbstractRestStreamRequestHandler
the base abstract class for REST stream request handlers
Definition: RestHandler.qm.dox.h:354
HttpServer::AbstractStreamRequest::listener
HttpListenerInterface listener
RestHandler::AbstractRestClass
the base abstract class for REST handler classes
Definition: RestHandler.qm.dox.h:546
RestHandler::RestStreamRequest
the base class for handling HTTP chunked requests and responses within the RestHandler infrastructure...
Definition: RestHandler.qm.dox.h:484
RestHandler::RestHandler::validator
RestSchemaValidator::AbstractRestSchemaValidator validator
REST schema validator.
Definition: RestHandler.qm.dox.h:702
RestHandler::AbstractRestStreamRequestHandler::send
auto send()
this method provides the callback method for sending chunked data by calling sendImpl() ...
HttpServer::AbstractStreamRequest::body
auto body
RestHandler::AbstractRestStreamRequestHandler::timeout_ms
*int timeout_ms
socket I/O timeout in milliseconds
Definition: RestHandler.qm.dox.h:375
RestHandler::AbstractRestStreamRequestHandler::getPersistentClosedNotification
*code getPersistentClosedNotification()
returns a callable value in case a persistent connection is in progress; NOTHING if not; this method ...
RestHandler::AbstractRestStreamRequestHandler::isPersistent
bool isPersistent()
returns True if the connection is persistent; this method in the base class returns False by default ...
Priv
Definition: RestHandler.qm.dox.h:808
RestHandler::AbstractRestClass::name
abstract string name()
this provides the name of the REST class
RestHandler::AbstractRestStreamRequestHandler::getResponseHeaderMessageImpl
abstract hash getResponseHeaderMessageImpl()
this method should return the response message description hash
RestHandler::RestStreamRequest::constructor
constructor(RestHandler::AbstractRestStreamRequestHandler n_stream, HttpServer::HttpListenerInterface listener, HttpServer::AbstractHttpRequestHandler handler, Socket s, hash cx, hash hdr, auto body)
creates the object with the given attributes
RestHandler::AbstractRestClass::dispatch
hash< HttpServer::HttpHandlerResponseInfo > dispatch(RestHandler rh, string mn, *hash ah, hash cx)
this method is called to dispatch requests on the given object
RestHandler::RestStreamRequest::getResponseHeaderMessageImpl
hash< HttpServer::HttpHandlerResponseInfo > getResponseHeaderMessageImpl()
RestHandler::AbstractRestStreamRequestHandler::ex
*hash ex
if an exception is raised in a callback then the exception hash is saved here
Definition: RestHandler.qm.dox.h:366
MimeTypeHtml
const MimeTypeHtml
hash
hash hash(object obj)
RestHandler::AbstractRestStreamRequestHandler::rhdr
hash rhdr
headers to add in the response
Definition: RestHandler.qm.dox.h:372
RestHandler::AbstractRestStreamRequestHandler::recvImpl
abstract nothing recvImpl(hash v)
abstract callback method for receiving chunked data
MimeTypeXmlApp
const MimeTypeXmlApp
RestHandler::AbstractRestStreamRequestHandler::constructor
constructor(hash n_cx, *hash n_ah)
creates the object with the given arguments
RestHandler::AbstractRestClass::unknownSubClassError
hash< HttpServer::HttpHandlerResponseInfo > unknownSubClassError(string n_name)
returns a 404 Not Found response when a request tries to access an unknown subclass ...
mime_parse_form_urlencoded_string
hash< auto > mime_parse_form_urlencoded_string(string str)
RestHandler::AbstractRestClass::dispatchStream
hash< HttpServer::HttpHandlerResponseInfo > dispatchStream(HttpListenerInterface listener, RestHandler rh, Socket s, string mn, *hash ah, hash cx)
this method is called to dispatch streamed requests on the given object
RestHandler::AbstractRestStreamRequestHandler::setTimeout
setTimeout(timeout n_timeout_ms)
sets the internal socket I/O timeout value in ms