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 #include "error.h"
30
31 #include <cx/string.h>
32 #include "../util/pblock.h"
33 #include "../util/strbuf.h"
34
35
36 #define ERRMSG(s) { s,
sizeof(s)-
1 }
37
38 static cxmutstr error_400 =
ERRMSG(
"<html><body>bad request</body></html>");
39 static cxmutstr error_403 =
ERRMSG(
"<html><body>forbidden</body></html>");
40 static cxmutstr error_404 =
ERRMSG(
"<html><body>not found</body></html>");
41 static cxmutstr error_500 =
ERRMSG(
"<html><body>server error</body></html>");
42 static cxmutstr error_503 =
ERRMSG(
"<html><body>service unavailable</body></html>");
43
44 static cxmutstr error_std =
ERRMSG(
"<html><body>error</body></html>");
45
46 int nsapi_error_request(Session *sn, Request *rq) {
47 short status = rq->status_num;
48 cxmutstr msg;
49 if(status <=
0) {
50 status =
500;
51 msg = error_500;
52 }
else if(status <
400) {
53 msg.ptr =
NULL;
54 msg.length =
0;
55 }
else {
56 switch(status) {
57 default: msg = error_std;
58 case 403: {
59 msg = error_403;
60 break;
61 }
62 case 404: {
63 msg = error_404;
64 break;
65 }
66 case 500: {
67 msg = error_500;
68 break;
69 }
70 }
71 }
72
73 pblock_removekey(pb_key_content_type, rq->srvhdrs);
74 pblock_removekey(pb_key_content_length, rq->srvhdrs);
75
76 pblock_kninsert(pb_key_content_length, msg.length, rq->srvhdrs);
77 pblock_nvinsert(
"content-type",
"text/html", rq->srvhdrs);
78 protocol_status(sn, rq, status,
NULL);
79 http_start_response(sn, rq);
80
81 if(msg.length >
0) {
82 net_write(sn->csd, msg.ptr, msg.length);
83 }
84
85 return REQ_PROCEED;
86 }
87
88 void fatal_error(HTTPRequest *req,
int status) {
89 cxmutstr msg = error_500;
90 char *statusmsg =
"Internal Server Error";
91 switch(status) {
92 case 400: {
93 msg = error_400;
94 statusmsg =
"Bad request";
95 break;
96 }
97 case 500: {
98 msg = error_500;
99 statusmsg =
"Internal Server Error";
100 break;
101 }
102 case 503: {
103 msg = error_503;
104 statusmsg =
"Service Unavailable";
105 break;
106 }
107 }
108
109 char buf[
512];
110 int len = snprintf(buf,
512,
"HTTP/1.1 %d %s\r\nServer: webserver\r\nContent-type: text/html\r\nContent-length: %zd\r\n\r\n", status, statusmsg, msg.length);
111
112
113 int flags;
114 if (-
1 == (flags = fcntl(req->connection->fd,
F_GETFL,
0))) {
115 flags =
0;
116 }
117 if (fcntl(req->connection->fd,
F_SETFL, flags & ~
O_NONBLOCK) !=
0) {
118
119 }
120
121 req->connection->write(req->connection, buf, len);
122 req->connection->write(req->connection, msg.ptr, msg.length);
123 }
124