This uses the underlying CGI functionality of method and its associated classes to call classes derived from the resource base class when an HTTP request is received.
The basic model is that the application uses the resource class as a base classe to code its hierarchically contained resources, or their proxies. The process() method of this class then handles all framework processing except for the method responses for the resources. These are the steps, implemented as overridable methods:
Example code using FastCGI: The application-specific class myrootrsc
is derived from the resource class to represent its root resource.
#include <fcgio.h> #include <restcgi/endpoint.h> #include <restcgi/rest.h> #include "myrootrsc.h" int main(int argc, char* argv[]) { // FastCGI initialization. FCGX_Init(); FCGX_Request request; FCGX_InitRequest(&request, 0, 0); while (FCGX_Accept_r(&request) >= 0) { // FastCGI request setup. fcgi_streambuf fisbuf(request.in); std::istream is(&fisbuf); fcgi_streambuf fosbuf(request.out); std::ostream os(&fosbuf); set_env(request.envp); // restcgi processing. Note rest::process() catches exceptions and // translates them to HTTP error status codes (derive from rest to customize). restcgi::endpoint::method_pointer m = restcgi::endpoint::create(is, os)->receive(); restcgi::resource::pointer root(new myrootrsc()); restcgi::rest().process(m, root); } return 0; } void set_env(char** penv) { char buf[4000]; for (; *penv; ++penv) { ::strncpy(buf, *penv, sizeof(buf)); buf[sizeof(buf) - 1] = 0; // ensure terminated char* p = ::strchr(buf, '='); const char* v = ""; if (p) {*p = 0; v = p + 1;} ::setenv(buf, v, 1); // makes copy of buf, v } }
Public Types | |
typedef restcgi::method | method_type |
method type | |
typedef boost::shared_ptr< method_type > | method_pointer |
method shared ptr | |
typedef restcgi::resource | resource_type |
resource type | |
typedef boost::shared_ptr< resource_type > | resource_pointer |
resource shared ptr | |
typedef std::map< std::string, resource_pointer > | vhosts_resources_type |
virtual hosts resources type | |
Public Member Functions | |
rest () | |
Construct. | |
void | process (method_pointer m, resource_pointer root, const sc_ctmpls &sccts=sc_ctmpls()) |
Perform processing of the given method starting at the given root resource. | |
void | process (method_pointer m, const vhosts_resources_type &vhrs) |
Perform processing of the given method for the root resouce that matches the HTTP_HOST header. | |
method_pointer | method () const |
Get method (valid after process()). | |
resource_pointer | root () const |
Get root resource (valid after process()). | |
resource_pointer | resource () const |
Get resource (valid after locate()). | |
Static Public Member Functions | |
static bool | special_case (method_pointer m) |
Default special case. | |
static resource_pointer | locate (method_pointer m, resource_pointer &r) |
Default locate. | |
static void | apply (method_pointer m, resource_pointer r) |
Default apply. | |
static void | on_exception (method_pointer m, const sc_ctmpls &sccts) |
Default exception handler. | |
Protected Member Functions | |
virtual bool | special_case () |
virtual resource_pointer | locate (resource_pointer &r) |
virtual void | apply () |
virtual void | on_exception (const sc_ctmpls &sccts) |
virtual void restcgi::rest::apply | ( | ) | [protected, virtual] |
Apply the method to the resource. This examines the method type and calls the corresponding resource method to create a response, e.g. calls resource::get() if the method is a GET.
exception | many different kinds if error in processing |
virtual resource_pointer restcgi::rest::locate | ( | resource_pointer & | r | ) | [protected, virtual] |
Locate the resource for the method's URI path. This will start with the root and call resource::locate() and the resource it returns, transitively, until either no resource is returned (the previous is used in this case) or uri path is empty. The resource arg should be updated as the algorithm progresses so it is left at the last known good point if an exception is thrown. Sets resource pointer member as it progresses.
not_found |
virtual void restcgi::rest::on_exception | ( | const sc_ctmpls & | sccts | ) | [protected, virtual] |
Handle response for exception during processing. This first tests that a method has been received and that there is no response yet. It (internally) rethrows the last exception and then produces an appropriate response based on the exception and the provided content template for the exception based on its status code.
void restcgi::rest::process | ( | method_pointer | m, | |
const vhosts_resources_type & | vhrs | |||
) |
Perform processing of the given method for the root resouce that matches the HTTP_HOST header.
This uses the domain name/IP addr plus the ":<port>" if any. (See also other process()).
void restcgi::rest::process | ( | method_pointer | m, | |
resource_pointer | root, | |||
const sc_ctmpls & | sccts = sc_ctmpls() | |||
) |
Perform processing of the given method starting at the given root resource.
Uses the optional templates on exceptions. See class description. This does not throw any exception.
virtual bool restcgi::rest::special_case | ( | ) | [protected, virtual] |
Detect and handle special case methods and return whether special case or not. This handles OPTIONS "*" by sending an empty response ("ping"-like behavior).