quark

quark web server
git clone git://git.suckless.org/quark
Log | Files | Refs | LICENSE

commit 123f168a3b5d1e378aa2827d6306a0270b553f90
parent 601b56d27095e4340e5afcf3385465a1f7f96d98
Author: Laslo Hunhold <dev@frign.de>
Date:   Fri, 28 Aug 2020 22:32:47 +0200

Replace http_send_status() with http_prepare_error_response()

This approach fits better in line of first initializing the response
struct and then sending the header with http_send_header() later.

Signed-off-by: Laslo Hunhold <dev@frign.de>

Diffstat:
Mhttp.c | 70+++++++++++++++++++++++++++++++++++++---------------------------------
Mhttp.h | 2++
Mmain.c | 22+++++++++++-----------
3 files changed, 50 insertions(+), 44 deletions(-)

diff --git a/http.c b/http.c @@ -99,42 +99,18 @@ http_send_header(int fd, const struct response *res) esc) < 0) { return S_REQUEST_TIMEOUT; } - } - - return res->status; -} - -enum status -http_send_status(int fd, enum status s) -{ - enum status sendstatus; - - struct response res = { - .status = s, - .field[RES_CONTENT_TYPE] = "text/html; charset=utf-8", - }; - - if (s == S_METHOD_NOT_ALLOWED) { - if (esnprintf(res.field[RES_ALLOW], - sizeof(res.field[RES_ALLOW]), "%s", - "Allow: GET, HEAD")) { - return S_INTERNAL_SERVER_ERROR; + } else if (res->type == RESTYPE_ERROR) { + if (dprintf(fd, + "<!DOCTYPE html>\n<html>\n\t<head>\n" + "\t\t<title>%d %s</title>\n\t</head>\n\t<body>\n" + "\t\t<h1>%d %s</h1>\n\t</body>\n</html>\n", + res->status, status_str[res->status], + res->status, status_str[res->status]) < 0) { + return S_REQUEST_TIMEOUT; } } - if ((sendstatus = http_send_header(fd, &res)) != s) { - return sendstatus; - } - - if (dprintf(fd, - "<!DOCTYPE html>\n<html>\n\t<head>\n" - "\t\t<title>%d %s</title>\n\t</head>\n\t<body>\n" - "\t\t<h1>%d %s</h1>\n\t</body>\n</html>\n", - s, status_str[s], s, status_str[s]) < 0) { - return S_REQUEST_TIMEOUT; - } - - return s; + return res->status; } static void @@ -827,3 +803,31 @@ http_prepare_response(const struct request *req, struct response *res, return 0; } + +void +http_prepare_error_response(const struct request *req, + struct response *res, enum status s) +{ + /* used later */ + (void)req; + + /* empty all response fields */ + memset(res, 0, sizeof(*res)); + + res->type = RESTYPE_ERROR; + res->status = s; + + if (esnprintf(res->field[RES_CONTENT_TYPE], + sizeof(res->field[RES_CONTENT_TYPE]), + "text/html; charset=utf-8")) { + res->status = S_INTERNAL_SERVER_ERROR; + } + + if (res->status == S_METHOD_NOT_ALLOWED) { + if (esnprintf(res->field[RES_ALLOW], + sizeof(res->field[RES_ALLOW]), + "Allow: GET, HEAD")) { + res->status = S_INTERNAL_SERVER_ERROR; + } + } +} diff --git a/http.h b/http.h @@ -105,5 +105,7 @@ enum status http_recv_header(int, char *, size_t, size_t *); enum status http_parse_header(const char *, struct request *); enum status http_prepare_response(const struct request *, struct response *, const struct server *); +void http_prepare_error_response(const struct request *, + struct response *, enum status); #endif /* HTTP_H */ diff --git a/main.c b/main.c @@ -41,16 +41,16 @@ serve(int infd, const struct sockaddr_storage *in_sa, const struct server *srv) if ((status = http_recv_header(c.fd, c.header, LEN(c.header), &c.off)) || (status = http_parse_header(c.header, &c.req)) || (status = http_prepare_response(&c.req, &c.res, srv))) { - status = http_send_status(c.fd, status); - } else { - status = http_send_header(c.fd, &c.res); - - /* send data */ - if (c.res.type == RESTYPE_FILE) { - resp_file(c.fd, &c.res); - } else if (c.res.type == RESTYPE_DIRLISTING) { - resp_dir(c.fd, &c.res); - } + http_prepare_error_response(&c.req, &c.res, status); + } + + status = http_send_header(c.fd, &c.res); + + /* send data */ + if (c.res.type == RESTYPE_FILE) { + resp_file(c.fd, &c.res); + } else if (c.res.type == RESTYPE_DIRLISTING) { + resp_dir(c.fd, &c.res); } /* write output to log */ @@ -63,7 +63,7 @@ serve(int infd, const struct sockaddr_storage *in_sa, const struct server *srv) if (sock_get_inaddr_str(in_sa, inaddr, LEN(inaddr))) { goto cleanup; } - printf("%s\t%s\t%d\t%s\t%s\n", tstmp, inaddr, status, + printf("%s\t%s\t%d\t%s\t%s\n", tstmp, inaddr, c.res.status, c.req.field[REQ_HOST], c.req.uri); cleanup: /* clean up and finish */