-
Notifications
You must be signed in to change notification settings - Fork 1
/
request_handler.h
68 lines (55 loc) · 2.3 KB
/
request_handler.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
// Based off of https://github.com/jfarrell468/registerer
#ifndef REQUEST_HANDLER_H
#define REQUEST_HANDLER_H
#include <map>
#include <memory>
#include <string>
#include "config_parser.h"
#include "request.h"
#include "response.h"
// Represents the parent of all request handlers. Implementations should expect
// to be long lived and created at server construction
class RequestHandler {
public:
// Request handler return codes
enum Status {
OK = 0,
Error = 1
};
// Registers a request handler by name
static RequestHandler* CreateByName(const char* type);
// Initializes the handler. Returns OK if successful
// uri_prefix is the value in the config file that this handler will run for
// config is the contents of the child block for this handler ONLY
virtual Status Init(const std::string& uri_prefix,
const NginxConfig& config) = 0;
// Handles an HTTP request, and generates a response. Returns a response code
// indicating success or failure condition. If ResponseCode is not OK, the
// contents of the response object are undefined, and the server will return
// HTTP code 500
virtual Status HandleRequest(const Request& request,
Response* response) = 0;
};
// Notes:
// * The trick here is that you can declare an object at file scope, but you
// can't do anything else, such as set a map key. But you can get around this
// by creating a class that does work in its constructor.
// * request_handler_builders must be a pointer. Otherwise, it won't necessarily
// exist when the RequestHandlerRegisterer constructor gets called.
extern std::map<std::string, RequestHandler* (*)(void)>* request_handler_builders;
template<typename T>
class RequestHandlerRegisterer {
public:
RequestHandlerRegisterer(const std::string& type) {
if (request_handler_builders == nullptr) {
request_handler_builders = new std::map<std::string, RequestHandler* (*)(void)>;
}
(*request_handler_builders)[type] = RequestHandlerRegisterer::Create;
}
static RequestHandler* Create() {
return new T;
}
};
#define REGISTER_REQUEST_HANDLER(ClassName) \
static RequestHandlerRegisterer<ClassName> ClassName##__registerer(#ClassName)
#endif // REQUEST_HANDLER_H