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:
M | http.c | | | 70 | +++++++++++++++++++++++++++++++++++++--------------------------------- |
M | http.h | | | 2 | ++ |
M | main.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 */