18
18
19
19
using namespace std ;
20
20
21
+ class NotFoundHandler : public RequestHandler {
22
+ string notFoundErrPage;
23
+
24
+ public:
25
+ NotFoundHandler (string notFoundErrPage = " " )
26
+ : notFoundErrPage(notFoundErrPage) {}
27
+ Response *callback (Request *req) {
28
+ Response *res = new Response (404 );
29
+ if (!notFoundErrPage.empty ()) {
30
+ res->setHeader (" Content-Type" , " text/" + getExtension (notFoundErrPage));
31
+ res->setBody (readFile (notFoundErrPage.c_str ()));
32
+ }
33
+ return res;
34
+ }
35
+ };
36
+
37
+ class ServerErrorHandler {
38
+ public:
39
+ static Response *callback (string msg) {
40
+ Response *res = new Response (500 );
41
+ res->setHeader (" Content-Type" , " application/json" );
42
+ res->setBody (" { \" code\" : \" 500\" , \" message\" : \" " + msg + " \" }\n " );
43
+ return res;
44
+ }
45
+ };
46
+
21
47
void split (string str, string separator, int max, vector<string> &results) {
22
48
int i = 0 ;
23
49
size_t found = str.find_first_of (separator);
@@ -174,7 +200,9 @@ Request *parseRawReq(char *headersRaw) {
174
200
return req;
175
201
}
176
202
177
- Server::Server (int _port) : port(_port), notFoundHandler(NULL ) {
203
+ Server::Server (int _port) : port(_port) {
204
+ notFoundHandler = new NotFoundHandler ();
205
+
178
206
sc = socket (AF_INET, SOCK_STREAM, 0 );
179
207
int sc_option = 1 ;
180
208
setsockopt (sc, SOL_SOCKET, SO_REUSEADDR, &sc_option, sizeof (sc_option));
@@ -202,19 +230,6 @@ void Server::post(string path, RequestHandler *handler) {
202
230
routes.push_back (route);
203
231
}
204
232
205
- class NotFoundHandler : public RequestHandler {
206
- string notFoundErrPage;
207
-
208
- public:
209
- NotFoundHandler (string notFoundErrPage) : notFoundErrPage(notFoundErrPage) {}
210
- Response *callback (Request *req) {
211
- Response *res = new Response (404 );
212
- res->setHeader (" Content-Type" , " text/" + getExtension (notFoundErrPage));
213
- res->setBody (readFile (notFoundErrPage.c_str ()));
214
- return res;
215
- }
216
- };
217
-
218
233
void Server::run () {
219
234
::listen (sc, 10 );
220
235
@@ -227,37 +242,42 @@ void Server::run() {
227
242
newsc = ::accept (sc, (struct sockaddr *)&cli_addr, &clilen);
228
243
if (newsc < 0 )
229
244
throw Exception (" Error on accept: " + string (strerror (errno)));
230
-
231
- char data[BUFSIZE + 1 ];
232
- size_t recv_len, recv_total_len = 0 ;
233
- Request *req = NULL ;
234
- while (!req) {
235
- recv_len =
236
- recv (newsc, data + recv_total_len, BUFSIZE - recv_total_len, 0 );
237
- if (recv_len > 0 ) {
238
- recv_total_len += recv_len;
239
- data[recv_total_len >= 0 ? recv_total_len : 0 ] = 0 ;
240
- req = parseRawReq (data);
241
- } else
242
- break ;
243
- }
244
- if (!recv_total_len) {
245
- ::close (newsc);
246
- continue ;
247
- }
248
- req->log ();
249
- Response *res = new Response ();
250
- size_t i = 0 ;
251
- for (; i < routes.size (); i++) {
252
- if (routes[i]->isMatch (req->getMethod (), req->getPath ())) {
253
- res = routes[i]->handle (req);
254
- break ;
245
+ Response *res = NULL ;
246
+ try {
247
+ char data[BUFSIZE + 1 ];
248
+ size_t recv_len, recv_total_len = 0 ;
249
+ Request *req = NULL ;
250
+ while (!req) {
251
+ recv_len =
252
+ recv (newsc, data + recv_total_len, BUFSIZE - recv_total_len, 0 );
253
+ if (recv_len > 0 ) {
254
+ recv_total_len += recv_len;
255
+ data[recv_total_len >= 0 ? recv_total_len : 0 ] = 0 ;
256
+ req = parseRawReq (data);
257
+ } else
258
+ break ;
255
259
}
260
+ if (!recv_total_len) {
261
+ ::close (newsc);
262
+ continue ;
263
+ }
264
+ req->log ();
265
+ res = new Response ();
266
+ size_t i = 0 ;
267
+ for (; i < routes.size (); i++) {
268
+ if (routes[i]->isMatch (req->getMethod (), req->getPath ())) {
269
+ res = routes[i]->handle (req);
270
+ break ;
271
+ }
272
+ }
273
+ if (i == routes.size () && notFoundHandler) {
274
+ res = notFoundHandler->callback (req);
275
+ }
276
+ delete req;
277
+ } catch (Exception exc) {
278
+ delete res;
279
+ res = ServerErrorHandler::callback (exc.getMessage ());
256
280
}
257
- if (i == routes.size () && notFoundHandler) {
258
- res = notFoundHandler->callback (req);
259
- }
260
- delete req;
261
281
int si;
262
282
res->log ();
263
283
string res_data = res->print (si);
0 commit comments