/* SPDX-License-Identifier: GPL-3.0-or-later */ /* Copyright 2022 Ivan Polyakov */ #include "response.h" #include #include #include static size_t calc_res_buff_sz(const rpd_res *res); void rpd_res_init(rpd_res *dest) { dest->status = rpd_res_st_ok; dest->location = dest->content_type = NULL; dest->body = NULL; rpd_keyval_init(&dest->cookie, 0); } int rpd_res_str(char **dest, const rpd_res *res) { size_t size = calc_res_buff_sz(res); *dest = (char *) malloc(sizeof(char) * size); if (!*dest) { return 1; } /* header */ char *ptr = *dest; ptr += sprintf(ptr, "Status: %d\r\n", res->status); if (res->content_type) { ptr += sprintf(ptr, "Content-Type: %s\r\n", res->content_type); } if (res->location) { ptr += sprintf(ptr, "Location: %s\r\n", res->location); } memcpy(ptr, "\r\n", 2); ptr += 2; /* body */ if (res->body) { int bodylen = strlen(res->body); memcpy(ptr, res->body, bodylen); ptr += bodylen; } return 0; } static size_t calc_res_buff_sz(const rpd_res *res) { size_t size = res->body ? strlen(res->body) + 2 : 0; size += strlen("Status: \r\n") + 3; if (res->location) { size += strlen("Location: \r\n") + strlen(res->location); } if (res->content_type) { size += strlen("Content-Type: \r\n") + strlen(res->content_type); } if (res->cookie.size) { size += strlen("Set-Cookie: \r\n") * res->cookie.size; for (int i = 0; i < res->cookie.size; i++) { rpd_keyval_item *item = res->cookie.items + i; size += strlen(item->key) + strlen(item->val); } } size += 2; return size; } void rpd_res_cleanup(rpd_res *res) { res->status = rpd_res_st_ok; if (res->location) { free(res->location); res->location = NULL; } if (res->content_type) { free(res->content_type); res->content_type = NULL; } if (res->body) { free(res->body); res->body = NULL; } if (res->cookie.capacity) { rpd_keyval_cleanup(&res->cookie); } }