100 lines
2.5 KiB
C
100 lines
2.5 KiB
C
#include <string.h>
|
|
|
|
#include "lnm/http/res.h"
|
|
|
|
lnm_err lnm_http_res_add_header(lnm_http_res *res, lnm_http_header type,
|
|
char *value, bool value_owned) {
|
|
return lnm_http_res_add_header_len(res, type, value, strlen(value),
|
|
value_owned);
|
|
}
|
|
|
|
lnm_err lnm_http_res_add_header_len(lnm_http_res *res, lnm_http_header type,
|
|
char *value, size_t value_len,
|
|
bool value_owned) {
|
|
lnm_http_res_header *header = calloc(1, sizeof(lnm_http_res_header));
|
|
|
|
if (header == NULL) {
|
|
return lnm_err_failed_alloc;
|
|
}
|
|
|
|
lnm_http_res_header **next_ptr = &res->headers.head;
|
|
|
|
while ((*next_ptr) != NULL) {
|
|
next_ptr = &(*next_ptr)->next;
|
|
}
|
|
|
|
*next_ptr = header;
|
|
|
|
// Initialize the current pointer to the head of the linked list
|
|
if (res->headers.current == NULL) {
|
|
res->headers.current = header;
|
|
}
|
|
|
|
header->name.s = (char *)lnm_http_header_names[type];
|
|
header->name.len = strlen(lnm_http_header_names[type]);
|
|
header->name.owned = false;
|
|
|
|
header->value.s = value;
|
|
header->value.len = value_len;
|
|
header->value.owned = value_owned;
|
|
|
|
return lnm_err_ok;
|
|
}
|
|
|
|
void lnm_http_res_body_set_file(lnm_http_res *res, FILE *f, size_t len,
|
|
bool owned) {
|
|
res->body.data.f = f;
|
|
res->body.len = len;
|
|
res->body.owned = owned;
|
|
res->body.type = lnm_http_res_body_type_file;
|
|
}
|
|
|
|
void lnm_http_res_body_set_buf(lnm_http_res *res, char *buf, size_t len,
|
|
bool owned) {
|
|
res->body.data.buf = buf;
|
|
res->body.len = len;
|
|
res->body.owned = owned;
|
|
res->body.type = lnm_http_res_body_type_buf;
|
|
}
|
|
|
|
void lnm_http_res_body_set_fn(lnm_http_res *res, data_fn fn, size_t len) {
|
|
res->body.data.fn = fn;
|
|
res->body.len = len;
|
|
res->body.type = lnm_http_res_body_type_fn;
|
|
}
|
|
|
|
void lnm_http_res_reset(lnm_http_res *res) {
|
|
lnm_http_res_header *header = res->headers.head;
|
|
|
|
while (header != NULL) {
|
|
lnm_http_res_header *next = header->next;
|
|
|
|
if (header->name.owned) {
|
|
free(header->name.s);
|
|
}
|
|
|
|
if (header->value.owned) {
|
|
free(header->value.s);
|
|
}
|
|
|
|
free(header);
|
|
|
|
header = next;
|
|
}
|
|
|
|
if (res->body.owned) {
|
|
switch (res->body.type) {
|
|
case lnm_http_res_body_type_file:
|
|
fclose(res->body.data.f);
|
|
break;
|
|
case lnm_http_res_body_type_buf:
|
|
free(res->body.data.buf);
|
|
break;
|
|
case lnm_http_res_body_type_fn:
|
|
break;
|
|
}
|
|
}
|
|
|
|
memset(res, 0, sizeof(lnm_http_res));
|
|
}
|