Blame


1 04e4e993 2023-08-14 op /*
2 c2117f4b 2023-08-31 op * This is free and unencumbered software released into the public domain.
3 04e4e993 2023-08-14 op *
4 c2117f4b 2023-08-31 op * Anyone is free to copy, modify, publish, use, compile, sell, or
5 c2117f4b 2023-08-31 op * distribute this software, either in source code form or as a compiled
6 c2117f4b 2023-08-31 op * binary, for any purpose, commercial or non-commercial, and by any
7 c2117f4b 2023-08-31 op * means.
8 04e4e993 2023-08-14 op *
9 c2117f4b 2023-08-31 op * In jurisdictions that recognize copyright laws, the author or authors
10 c2117f4b 2023-08-31 op * of this software dedicate any and all copyright interest in the
11 c2117f4b 2023-08-31 op * software to the public domain. We make this dedication for the benefit
12 c2117f4b 2023-08-31 op * of the public at large and to the detriment of our heirs and
13 c2117f4b 2023-08-31 op * successors. We intend this dedication to be an overt act of
14 c2117f4b 2023-08-31 op * relinquishment in perpetuity of all present and future rights to this
15 c2117f4b 2023-08-31 op * software under copyright law.
16 c2117f4b 2023-08-31 op *
17 c2117f4b 2023-08-31 op * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 c2117f4b 2023-08-31 op * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 c2117f4b 2023-08-31 op * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 c2117f4b 2023-08-31 op * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 c2117f4b 2023-08-31 op * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 c2117f4b 2023-08-31 op * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 c2117f4b 2023-08-31 op * OTHER DEALINGS IN THE SOFTWARE.
24 04e4e993 2023-08-14 op */
25 04e4e993 2023-08-14 op
26 04e4e993 2023-08-14 op #include "config.h"
27 04e4e993 2023-08-14 op
28 04e4e993 2023-08-14 op #include <sys/uio.h>
29 04e4e993 2023-08-14 op
30 04e4e993 2023-08-14 op #include <ctype.h>
31 04e4e993 2023-08-14 op #include <errno.h>
32 04e4e993 2023-08-14 op #include <limits.h>
33 04e4e993 2023-08-14 op #include <stdarg.h>
34 04e4e993 2023-08-14 op #include <stdio.h>
35 04e4e993 2023-08-14 op #include <stdlib.h>
36 04e4e993 2023-08-14 op #include <string.h>
37 04e4e993 2023-08-14 op #include <unistd.h>
38 04e4e993 2023-08-14 op
39 3634fa70 2023-08-31 op #include "bufio.h"
40 04e4e993 2023-08-14 op #include "http.h"
41 04e4e993 2023-08-14 op #include "log.h"
42 04e4e993 2023-08-14 op #include "xmalloc.h"
43 04e4e993 2023-08-14 op
44 04e4e993 2023-08-14 op #ifndef nitems
45 04e4e993 2023-08-14 op #define nitems(x) (sizeof(x)/sizeof(x[0]))
46 04e4e993 2023-08-14 op #endif
47 04e4e993 2023-08-14 op
48 3634fa70 2023-08-31 op int
49 3634fa70 2023-08-31 op http_init(struct client *clt, int fd)
50 04e4e993 2023-08-14 op {
51 3634fa70 2023-08-31 op memset(clt, 0, sizeof(*clt));
52 3634fa70 2023-08-31 op if (bufio_init(&clt->bio) == -1)
53 3634fa70 2023-08-31 op return -1;
54 3634fa70 2023-08-31 op bufio_set_fd(&clt->bio, fd);
55 04e4e993 2023-08-14 op return 0;
56 04e4e993 2023-08-14 op }
57 04e4e993 2023-08-14 op
58 04e4e993 2023-08-14 op int
59 3634fa70 2023-08-31 op http_parse(struct client *clt)
60 04e4e993 2023-08-14 op {
61 3634fa70 2023-08-31 op struct buffer *rbuf = &clt->bio.rbuf;
62 3634fa70 2023-08-31 op struct request *req = &clt->req;
63 3634fa70 2023-08-31 op size_t len;
64 3634fa70 2023-08-31 op uint8_t *endln;
65 5e3e9499 2023-08-31 op char *frag, *query, *http, *line;
66 04e4e993 2023-08-14 op const char *errstr, *m;
67 04e4e993 2023-08-14 op
68 3634fa70 2023-08-31 op while (!clt->reqdone) {
69 3634fa70 2023-08-31 op endln = memmem(rbuf->buf, rbuf->len, "\r\n", 2);
70 3634fa70 2023-08-31 op if (endln == NULL) {
71 3634fa70 2023-08-31 op errno = EAGAIN;
72 04e4e993 2023-08-14 op return -1;
73 04e4e993 2023-08-14 op }
74 04e4e993 2023-08-14 op
75 3634fa70 2023-08-31 op line = rbuf->buf;
76 3634fa70 2023-08-31 op if (endln == rbuf->buf)
77 3634fa70 2023-08-31 op clt->reqdone = 1;
78 04e4e993 2023-08-14 op
79 3634fa70 2023-08-31 op len = endln - rbuf->buf + 2;
80 3634fa70 2023-08-31 op while (len > 0 && (line[len - 1] == '\r' ||
81 3634fa70 2023-08-31 op line[len - 1] == '\n' || line[len - 1] == ' ' ||
82 3634fa70 2023-08-31 op line[len - 1] == '\t'))
83 3634fa70 2023-08-31 op line[--len] = '\0';
84 04e4e993 2023-08-14 op
85 3634fa70 2023-08-31 op /* first line */
86 3634fa70 2023-08-31 op if (clt->req.method == METHOD_UNKNOWN) {
87 3634fa70 2023-08-31 op if (!strncmp("GET ", line, 4)) {
88 3634fa70 2023-08-31 op req->method = METHOD_GET;
89 7add2c3c 2023-08-31 op line += 4;
90 3634fa70 2023-08-31 op } else if (!strncmp("POST ", line, 5)) {
91 3634fa70 2023-08-31 op req->method = METHOD_POST;
92 7add2c3c 2023-08-31 op line += 5;
93 3634fa70 2023-08-31 op } else {
94 3634fa70 2023-08-31 op errno = EINVAL;
95 3634fa70 2023-08-31 op return -1;
96 04e4e993 2023-08-14 op }
97 04e4e993 2023-08-14 op
98 5e3e9499 2023-08-31 op if ((http = strchr(line, ' ')) == NULL)
99 5e3e9499 2023-08-31 op http = line;
100 5e3e9499 2023-08-31 op if (*http != '\0')
101 5e3e9499 2023-08-31 op *http++ = '\0';
102 a2298955 2023-08-31 op
103 a2298955 2023-08-31 op if ((query = strchr(line, '?')))
104 a2298955 2023-08-31 op *query = '\0';
105 a2298955 2023-08-31 op if ((frag = strchr(line, '#')))
106 a2298955 2023-08-31 op *frag = '\0';
107 a2298955 2023-08-31 op
108 7add2c3c 2023-08-31 op clt->req.path = xstrdup(line);
109 a2298955 2023-08-31 op
110 5e3e9499 2023-08-31 op if (!strcmp(http, "HTTP/1.0"))
111 3634fa70 2023-08-31 op clt->req.version = HTTP_1_0;
112 5e3e9499 2023-08-31 op else if (!strcmp(http, "HTTP/1.1")) {
113 3634fa70 2023-08-31 op clt->req.version = HTTP_1_1;
114 3634fa70 2023-08-31 op clt->chunked = 1;
115 3634fa70 2023-08-31 op } else {
116 5e3e9499 2023-08-31 op log_warnx("unknown http version %s", http);
117 3634fa70 2023-08-31 op errno = EINVAL;
118 3634fa70 2023-08-31 op return -1;
119 04e4e993 2023-08-14 op }
120 7add2c3c 2023-08-31 op
121 5e3e9499 2023-08-31 op line = http; /* so that no header below matches */
122 3634fa70 2023-08-31 op }
123 04e4e993 2023-08-14 op
124 3634fa70 2023-08-31 op if (!strncasecmp(line, "Content-Length:", 15)) {
125 3634fa70 2023-08-31 op line += 15;
126 3634fa70 2023-08-31 op line += strspn(line, " \t");
127 3634fa70 2023-08-31 op clt->req.clen = strtonum(line, 0, LONG_MAX,
128 3634fa70 2023-08-31 op &errstr);
129 3634fa70 2023-08-31 op if (errstr) {
130 3634fa70 2023-08-31 op log_warnx("content-length is %s: %s",
131 3634fa70 2023-08-31 op errstr, line);
132 3634fa70 2023-08-31 op errno = EINVAL;
133 3634fa70 2023-08-31 op return -1;
134 3634fa70 2023-08-31 op }
135 04e4e993 2023-08-14 op }
136 3634fa70 2023-08-31 op
137 3634fa70 2023-08-31 op buf_drain(rbuf, endln - rbuf->buf + 2);
138 04e4e993 2023-08-14 op }
139 04e4e993 2023-08-14 op
140 04e4e993 2023-08-14 op if (req->method == METHOD_GET)
141 04e4e993 2023-08-14 op m = "GET";
142 04e4e993 2023-08-14 op else if (req->method == METHOD_POST)
143 04e4e993 2023-08-14 op m = "POST";
144 04e4e993 2023-08-14 op else
145 04e4e993 2023-08-14 op m = "unknown";
146 9daa6569 2023-08-31 op log_debug("< %s %s HTTP/%s", m, req->path,
147 9daa6569 2023-08-31 op req->version == HTTP_1_1 ? "1.1" : "1.0");
148 04e4e993 2023-08-14 op
149 04e4e993 2023-08-14 op return 0;
150 04e4e993 2023-08-14 op }
151 04e4e993 2023-08-14 op
152 04e4e993 2023-08-14 op int
153 3634fa70 2023-08-31 op http_read(struct client *clt)
154 04e4e993 2023-08-14 op {
155 3634fa70 2023-08-31 op struct request *req = &clt->req;
156 04e4e993 2023-08-14 op size_t left;
157 3634fa70 2023-08-31 op size_t nr;
158 3b486b32 2023-08-14 op
159 3634fa70 2023-08-31 op if (req->clen > sizeof(clt->buf) - 1) {
160 87eb9c1e 2023-08-15 op log_warnx("POST has more data then what can be accepted");
161 04e4e993 2023-08-14 op return -1;
162 04e4e993 2023-08-14 op }
163 04e4e993 2023-08-14 op
164 87eb9c1e 2023-08-15 op /* clients may have sent more data than advertised */
165 3634fa70 2023-08-31 op if (req->clen < clt->len)
166 87eb9c1e 2023-08-15 op left = 0;
167 87eb9c1e 2023-08-15 op else
168 3634fa70 2023-08-31 op left = req->clen - clt->len;
169 87eb9c1e 2023-08-15 op
170 3634fa70 2023-08-31 op if (left > 0) {
171 3634fa70 2023-08-31 op nr = bufio_drain(&clt->bio, clt->buf + clt->len, left);
172 3634fa70 2023-08-31 op clt->len += nr;
173 3634fa70 2023-08-31 op if (nr < left) {
174 3634fa70 2023-08-31 op errno = EAGAIN;
175 04e4e993 2023-08-14 op return -1;
176 04e4e993 2023-08-14 op }
177 04e4e993 2023-08-14 op }
178 04e4e993 2023-08-14 op
179 3634fa70 2023-08-31 op clt->buf[clt->len] = '\0';
180 3634fa70 2023-08-31 op while (clt->len > 0 && (clt->buf[clt->len - 1] == '\r' ||
181 3634fa70 2023-08-31 op (clt->buf[clt->len - 1] == '\n')))
182 3634fa70 2023-08-31 op clt->buf[--clt->len] = '\0';
183 3634fa70 2023-08-31 op
184 04e4e993 2023-08-14 op return 0;
185 04e4e993 2023-08-14 op }
186 04e4e993 2023-08-14 op
187 04e4e993 2023-08-14 op int
188 3634fa70 2023-08-31 op http_reply(struct client *clt, int code, const char *reason, const char *ctype)
189 04e4e993 2023-08-14 op {
190 2c962d05 2023-08-31 op const char *version, *location = NULL;
191 04e4e993 2023-08-14 op int r;
192 04e4e993 2023-08-14 op
193 04e4e993 2023-08-14 op log_debug("> %d %s", code, reason);
194 04e4e993 2023-08-14 op
195 04e4e993 2023-08-14 op if (code >= 300 && code < 400) {
196 04e4e993 2023-08-14 op location = ctype;
197 c83e450a 2023-08-14 op ctype = "text/html;charset=UTF-8";
198 04e4e993 2023-08-14 op }
199 04e4e993 2023-08-14 op
200 2c962d05 2023-08-31 op version = "HTTP/1.1";
201 2c962d05 2023-08-31 op if (clt->req.version == HTTP_1_0)
202 2c962d05 2023-08-31 op version = "HTTP/1.0";
203 2c962d05 2023-08-31 op
204 2c962d05 2023-08-31 op r = bufio_compose_fmt(&clt->bio, "%s %d %s\r\n"
205 04e4e993 2023-08-14 op "Connection: close\r\n"
206 04e4e993 2023-08-14 op "Cache-Control: no-store\r\n"
207 04e4e993 2023-08-14 op "%s%s%s"
208 04e4e993 2023-08-14 op "%s%s%s"
209 04e4e993 2023-08-14 op "%s"
210 04e4e993 2023-08-14 op "\r\n",
211 2c962d05 2023-08-31 op version, code, reason,
212 04e4e993 2023-08-14 op ctype == NULL ? "" : "Content-Type: ",
213 04e4e993 2023-08-14 op ctype == NULL ? "" : ctype,
214 04e4e993 2023-08-14 op ctype == NULL ? "" : "\r\n",
215 04e4e993 2023-08-14 op location == NULL ? "" : "Location: ",
216 04e4e993 2023-08-14 op location == NULL ? "" : location,
217 04e4e993 2023-08-14 op location == NULL ? "" : "\r\n",
218 3634fa70 2023-08-31 op clt->chunked ? "Transfer-Encoding: chunked\r\n" : "");
219 3634fa70 2023-08-31 op if (r == -1) {
220 3634fa70 2023-08-31 op clt->err = 1;
221 04e4e993 2023-08-14 op return -1;
222 3634fa70 2023-08-31 op }
223 04e4e993 2023-08-14 op
224 6d85a326 2023-08-31 op bufio_set_chunked(&clt->bio, clt->chunked);
225 6d85a326 2023-08-31 op
226 c83e450a 2023-08-14 op if (location) {
227 3634fa70 2023-08-31 op if (http_writes(clt, "<a href='") == -1 ||
228 3634fa70 2023-08-31 op http_htmlescape(clt, location) == -1 ||
229 3634fa70 2023-08-31 op http_writes(clt, "'>") == -1 ||
230 3634fa70 2023-08-31 op http_htmlescape(clt, reason) == -1 ||
231 3634fa70 2023-08-31 op http_writes(clt, "</a>") == -1)
232 c83e450a 2023-08-14 op return -1;
233 c83e450a 2023-08-14 op }
234 c83e450a 2023-08-14 op
235 c83e450a 2023-08-14 op return 0;
236 04e4e993 2023-08-14 op }
237 04e4e993 2023-08-14 op
238 04e4e993 2023-08-14 op int
239 3634fa70 2023-08-31 op http_flush(struct client *clt)
240 04e4e993 2023-08-14 op {
241 3634fa70 2023-08-31 op if (clt->err)
242 04e4e993 2023-08-14 op return -1;
243 04e4e993 2023-08-14 op
244 3634fa70 2023-08-31 op if (clt->len == 0)
245 04e4e993 2023-08-14 op return 0;
246 04e4e993 2023-08-14 op
247 3634fa70 2023-08-31 op if (bufio_compose(&clt->bio, clt->buf, clt->len) == -1) {
248 3634fa70 2023-08-31 op clt->err = 1;
249 04e4e993 2023-08-14 op return -1;
250 04e4e993 2023-08-14 op }
251 04e4e993 2023-08-14 op
252 3634fa70 2023-08-31 op clt->len = 0;
253 04e4e993 2023-08-14 op
254 04e4e993 2023-08-14 op return 0;
255 04e4e993 2023-08-14 op }
256 04e4e993 2023-08-14 op
257 04e4e993 2023-08-14 op int
258 3634fa70 2023-08-31 op http_write(struct client *clt, const char *d, size_t len)
259 04e4e993 2023-08-14 op {
260 04e4e993 2023-08-14 op size_t avail;
261 04e4e993 2023-08-14 op
262 3634fa70 2023-08-31 op if (clt->err)
263 04e4e993 2023-08-14 op return -1;
264 04e4e993 2023-08-14 op
265 04e4e993 2023-08-14 op while (len > 0) {
266 3634fa70 2023-08-31 op avail = sizeof(clt->buf) - clt->len;
267 04e4e993 2023-08-14 op if (avail > len)
268 04e4e993 2023-08-14 op avail = len;
269 04e4e993 2023-08-14 op
270 3634fa70 2023-08-31 op memcpy(clt->buf + clt->len, d, avail);
271 3634fa70 2023-08-31 op clt->len += avail;
272 04e4e993 2023-08-14 op len -= avail;
273 04e4e993 2023-08-14 op d += avail;
274 3634fa70 2023-08-31 op if (clt->len == sizeof(clt->buf)) {
275 3634fa70 2023-08-31 op if (http_flush(clt) == -1)
276 04e4e993 2023-08-14 op return -1;
277 04e4e993 2023-08-14 op }
278 04e4e993 2023-08-14 op }
279 04e4e993 2023-08-14 op
280 04e4e993 2023-08-14 op return 0;
281 04e4e993 2023-08-14 op }
282 04e4e993 2023-08-14 op
283 04e4e993 2023-08-14 op int
284 3634fa70 2023-08-31 op http_writes(struct client *clt, const char *str)
285 04e4e993 2023-08-14 op {
286 3634fa70 2023-08-31 op return http_write(clt, str, strlen(str));
287 04e4e993 2023-08-14 op }
288 04e4e993 2023-08-14 op
289 04e4e993 2023-08-14 op int
290 3634fa70 2023-08-31 op http_fmt(struct client *clt, const char *fmt, ...)
291 04e4e993 2023-08-14 op {
292 04e4e993 2023-08-14 op va_list ap;
293 04e4e993 2023-08-14 op char *str;
294 04e4e993 2023-08-14 op int r;
295 04e4e993 2023-08-14 op
296 04e4e993 2023-08-14 op va_start(ap, fmt);
297 04e4e993 2023-08-14 op r = vasprintf(&str, fmt, ap);
298 04e4e993 2023-08-14 op va_end(ap);
299 04e4e993 2023-08-14 op
300 04e4e993 2023-08-14 op if (r == -1) {
301 04e4e993 2023-08-14 op log_warn("vasprintf");
302 3634fa70 2023-08-31 op clt->err = 1;
303 04e4e993 2023-08-14 op return -1;
304 04e4e993 2023-08-14 op }
305 04e4e993 2023-08-14 op
306 3634fa70 2023-08-31 op r = http_write(clt, str, r);
307 04e4e993 2023-08-14 op free(str);
308 04e4e993 2023-08-14 op return r;
309 04e4e993 2023-08-14 op }
310 04e4e993 2023-08-14 op
311 04e4e993 2023-08-14 op int
312 3634fa70 2023-08-31 op http_urlescape(struct client *clt, const char *str)
313 04e4e993 2023-08-14 op {
314 04e4e993 2023-08-14 op int r;
315 04e4e993 2023-08-14 op char tmp[4];
316 04e4e993 2023-08-14 op
317 04e4e993 2023-08-14 op for (; *str; ++str) {
318 04e4e993 2023-08-14 op if (iscntrl((unsigned char)*str) ||
319 04e4e993 2023-08-14 op isspace((unsigned char)*str) ||
320 04e4e993 2023-08-14 op *str == '\'' || *str == '"' || *str == '\\') {
321 04e4e993 2023-08-14 op r = snprintf(tmp, sizeof(tmp), "%%%2X",
322 04e4e993 2023-08-14 op (unsigned char)*str);
323 04e4e993 2023-08-14 op if (r < 0 || (size_t)r >= sizeof(tmp)) {
324 04e4e993 2023-08-14 op log_warn("snprintf failed");
325 3634fa70 2023-08-31 op clt->err = 1;
326 04e4e993 2023-08-14 op return -1;
327 04e4e993 2023-08-14 op }
328 3634fa70 2023-08-31 op if (http_write(clt, tmp, r) == -1)
329 04e4e993 2023-08-14 op return -1;
330 3634fa70 2023-08-31 op } else if (http_write(clt, str, 1) == -1)
331 04e4e993 2023-08-14 op return -1;
332 04e4e993 2023-08-14 op }
333 04e4e993 2023-08-14 op
334 04e4e993 2023-08-14 op return 0;
335 04e4e993 2023-08-14 op }
336 04e4e993 2023-08-14 op
337 04e4e993 2023-08-14 op int
338 3634fa70 2023-08-31 op http_htmlescape(struct client *clt, const char *str)
339 04e4e993 2023-08-14 op {
340 04e4e993 2023-08-14 op int r;
341 04e4e993 2023-08-14 op
342 04e4e993 2023-08-14 op for (; *str; ++str) {
343 04e4e993 2023-08-14 op switch (*str) {
344 04e4e993 2023-08-14 op case '<':
345 3634fa70 2023-08-31 op r = http_writes(clt, "&lt;");
346 04e4e993 2023-08-14 op break;
347 04e4e993 2023-08-14 op case '>':
348 3634fa70 2023-08-31 op r = http_writes(clt, "&gt;");
349 04e4e993 2023-08-14 op break;
350 04e4e993 2023-08-14 op case '&':
351 3634fa70 2023-08-31 op r = http_writes(clt, "&gt;");
352 04e4e993 2023-08-14 op break;
353 04e4e993 2023-08-14 op case '"':
354 3634fa70 2023-08-31 op r = http_writes(clt, "&quot;");
355 04e4e993 2023-08-14 op break;
356 04e4e993 2023-08-14 op case '\'':
357 3634fa70 2023-08-31 op r = http_writes(clt, "&apos;");
358 04e4e993 2023-08-14 op break;
359 04e4e993 2023-08-14 op default:
360 3634fa70 2023-08-31 op r = http_write(clt, str, 1);
361 04e4e993 2023-08-14 op break;
362 04e4e993 2023-08-14 op }
363 04e4e993 2023-08-14 op
364 04e4e993 2023-08-14 op if (r == -1)
365 04e4e993 2023-08-14 op return -1;
366 04e4e993 2023-08-14 op }
367 04e4e993 2023-08-14 op
368 04e4e993 2023-08-14 op return 0;
369 04e4e993 2023-08-14 op }
370 04e4e993 2023-08-14 op
371 04e4e993 2023-08-14 op int
372 3634fa70 2023-08-31 op http_close(struct client *clt)
373 04e4e993 2023-08-14 op {
374 3634fa70 2023-08-31 op if (clt->err)
375 3634fa70 2023-08-31 op return -1;
376 3634fa70 2023-08-31 op if (clt->len != 0 && http_flush(clt) == -1)
377 3634fa70 2023-08-31 op return -1;
378 3634fa70 2023-08-31 op if (bufio_compose(&clt->bio, NULL, 0) == -1)
379 3634fa70 2023-08-31 op clt->err = 1;
380 3634fa70 2023-08-31 op return (clt->err ? -1 : 0);
381 04e4e993 2023-08-14 op }
382 04e4e993 2023-08-14 op
383 04e4e993 2023-08-14 op void
384 3634fa70 2023-08-31 op http_free(struct client *clt)
385 04e4e993 2023-08-14 op {
386 3634fa70 2023-08-31 op free(clt->req.path);
387 3634fa70 2023-08-31 op free(clt->req.ctype);
388 3634fa70 2023-08-31 op free(clt->req.body);
389 3634fa70 2023-08-31 op bufio_free(&clt->bio);
390 04e4e993 2023-08-14 op }