commit 123f168a3b5d1e378aa2827d6306a0270b553f90
Author:     Laslo Hunhold <[email protected]>
AuthorDate: Fri Aug 28 22:32:47 2020 +0200
Commit:     Laslo Hunhold <[email protected]>
CommitDate: Fri Aug 28 22:34:46 2020 +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 <[email protected]>

diff --git a/http.c b/http.c
index b6b1ab7..5b0390d 100644
--- 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
index a9cf871..caac765 100644
--- 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
index 110af1a..fa0fa0f 100644
--- 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 */

Reply via email to