-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathrequest_handler.h
136 lines (111 loc) · 3.72 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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// For the Request and Response classes, you need to implement the methods
// and add private data as appropriate. You may also need to modify or extend
// the API when implementing the reverse proxy. Use your good judgment.
#ifndef REQUEST_HANDLER_H
#define REQUEST_HANDLER_H
#include <map>
#include <memory>
#include <string>
#include "ngnix/config_parser.h"
// Represents an HTTP Request.
//
// Usage:
// auto request = Request::Parse(raw_request);
namespace http {
namespace server {
class Request {
public:
static std::unique_ptr<Request> Parse(const std::string& raw_request);
// Getters
std::string raw_request() const { return m_raw_request; }
std::string method() const { return m_method; }
std::string uri() const { return m_uri; };
std::string version() const { return m_version; }
using Headers = std::vector<std::pair<std::string, std::string>>;
Headers headers() const { return m_headers; }
std::string body() const { return m_body; }
private:
std::string m_raw_request;
std::string m_method;
std::string m_uri;
std::string m_version;
std::string m_body;
Headers m_headers;
};
// Represents an HTTP response.
//
// Usage:
// Response r;
// r.SetStatus(RESPONSE_200);
// r.SetBody(...);
// return r.ToString();
//
// Constructed by the RequestHandler, after which the server should call ToString
// to serialize.
class Response {
public:
enum ResponseCode {
// Define your HTTP response codes here.
OK = 200,
BAD_REQUEST = 400,
NOT_FOUND = 404
};
void SetStatus(const ResponseCode response_code);
void AddHeader(const std::string& header_name, const std::string& header_value);
void SetBody(const std::string& body);
ResponseCode GetStatus();
std::string ToString();
private:
ResponseCode responseStatus;
std::string content;
std::vector<std::pair<std::string, std::string>> mHeaders;
std::string mVersion;
};
// Represents the parent of all request handlers. Implementations should expect to
// be long lived and created at server constrution.
class RequestHandler {
public:
enum Status {
OK = 0,
BAD_REQUEST = 1,
NOT_FOUND = 2
// Define your status codes here.
};
// Initializes the handler. Returns a response code indicating success or
// failure condition.
// 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;
static RequestHandler* CreateByName(const char* type);
// private:
std::string mUri_prefix;
std::string mPath;
std::string mHandlerName;
std::string mRoot;
};
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)
} // namespace server
} // namespace http
#endif // REQUEST_HANDLER_H