commit cf1d89aadc0ab05c0941fcc2eb552dfa24665f2d
parent a8a910826259c357d5c35cda5bb35f1d2b7355d0
Author: Francesco Saccone <francesco@francescosaccone.com>
Date: Mon, 31 Mar 2025 19:18:22 +0200
refactor: rewrite compose_http_response to not depend on buffer_size
Signed-off-by: Francesco Saccone <francesco@francescosaccone.com>
Diffstat:
M | http.c | | | 58 | +++++++++++++++++++++++++++++++++++++++++++++------------- |
M | http.h | | | 4 | +--- |
2 files changed, 46 insertions(+), 16 deletions(-)
diff --git a/http.c b/http.c
@@ -35,18 +35,50 @@ parse_http_request(char *request) {
return result;
}
+unsigned int
+get_length_of_integer(unsigned int integer) {
+ unsigned int result = 0;
+
+ while (integer > 1) {
+ integer /= 10;
+ result++;
+ }
+
+ return result;
+}
+
void
-compose_http_response(struct http_response response,
- char *buffer,
- unsigned int buffer_size) {
- snprintf(buffer, buffer_size, "HTTP/1.1 %u %s\r\n"
- "Content-Type: %s; charset=UTF-8\r\n"
- "Content-Length: %u\r\n"
- "\r\n"
- "%s",
- status_map[response.status].code,
- status_map[response.status].message,
- response.content_type,
- response.body_length,
- response.body);
+compose_http_response(struct http_response response, char *buffer) {
+ size_t size;
+ unsigned int status_code = status_map[response.status].code,
+ body_length = response.body_length;
+ const char *template = "HTTP/1.1 %u %s\r\n"
+ "Content-Type: %s; charset=UTF-8\r\n"
+ "Content-Length: %u\r\n"
+ "\r\n"
+ "%s",
+ *status_message = status_map[response.status].message,
+ *content_type = response.content_type,
+ *body = response.body;
+
+ /*
+ * This is actually a bit inelegant: it adds the length of 'template'
+ * with the length of each component of http_response; it then removes
+ * the number of characters occupied by template patterns of the form
+ * '%x', that is, 2 times the number of template patterns used.
+ */
+ size = strlen(template)
+ + get_length_of_integer(status_code)
+ + strlen(status_message)
+ + strlen(content_type)
+ + get_length_of_integer(body_length)
+ + strlen(body)
+ - 2 * 5;
+
+ snprintf(buffer, size, template,
+ status_code,
+ status_message,
+ content_type,
+ body_length,
+ body);
}
diff --git a/http.h b/http.h
@@ -88,8 +88,6 @@ parse_http_request(char *request);
* Writes a raw HTTP response to buffer, given a http_response.
*/
void
-compose_http_response(struct http_response response,
- char *buffer,
- unsigned int buffer_size);
+compose_http_response(struct http_response response, char *buffer);
#endif