|
|
@ -6,22 +6,25 @@ |
|
|
|
#include <stdlib.h> |
|
|
|
#include <stdlib.h> |
|
|
|
#include <string.h> |
|
|
|
#include <string.h> |
|
|
|
|
|
|
|
|
|
|
|
static size_t calc_res_headers_sz(const rpd_res *res); |
|
|
|
static size_t calc_res_status_sz(const rpd_res *res); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static size_t calc_res_headers_sz(const rpd_keyval *res); |
|
|
|
|
|
|
|
|
|
|
|
void rpd_res_init(rpd_res *dest) |
|
|
|
void rpd_res_init(rpd_res *dest) |
|
|
|
{ |
|
|
|
{ |
|
|
|
dest->status = rpd_res_st_ok; |
|
|
|
dest->status = rpd_res_st_ok; |
|
|
|
dest->location = dest->content_type = NULL; |
|
|
|
|
|
|
|
dest->body = NULL; |
|
|
|
dest->body = NULL; |
|
|
|
|
|
|
|
rpd_keyval_init(&dest->headers, 5); |
|
|
|
rpd_keyval_init(&dest->cookie, 0); |
|
|
|
dest->headers.unique = 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int rpd_res_headers_str(char **dest, const rpd_res *src) |
|
|
|
int rpd_res_headers_str(char **dest, const rpd_res *src) |
|
|
|
{ |
|
|
|
{ |
|
|
|
size_t size = calc_res_headers_sz(src); |
|
|
|
size_t size, i = 0; |
|
|
|
char *ptr; |
|
|
|
char *ptr; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
size = calc_res_headers_sz(&src->headers); |
|
|
|
|
|
|
|
|
|
|
|
*dest = (char *) malloc(sizeof(char) * size); |
|
|
|
*dest = (char *) malloc(sizeof(char) * size); |
|
|
|
if (!*dest) { |
|
|
|
if (!*dest) { |
|
|
|
perror("malloc"); |
|
|
|
perror("malloc"); |
|
|
@ -29,12 +32,13 @@ int rpd_res_headers_str(char **dest, const rpd_res *src) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ptr = *dest; |
|
|
|
ptr = *dest; |
|
|
|
if (src->content_type) { |
|
|
|
while (i < src->headers.size) { |
|
|
|
ptr += sprintf(ptr, "Content-Type: %s\r\n", src->content_type); |
|
|
|
ptr += sprintf( |
|
|
|
} |
|
|
|
ptr, |
|
|
|
|
|
|
|
"%s: %s\r\n", |
|
|
|
if (src->location) { |
|
|
|
src->headers.items[i].key, |
|
|
|
ptr += sprintf(ptr, "Location: %s\r\n", src->location); |
|
|
|
src->headers.items[i].val); |
|
|
|
|
|
|
|
i++; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
return 0; |
|
|
@ -44,7 +48,9 @@ int rpd_res_str(char **dest, const rpd_res *res) |
|
|
|
{ |
|
|
|
{ |
|
|
|
size_t headers_size, size; |
|
|
|
size_t headers_size, size; |
|
|
|
char *ptr, *headers; |
|
|
|
char *ptr, *headers; |
|
|
|
size = headers_size = calc_res_headers_sz(res); |
|
|
|
size = headers_size = calc_res_headers_sz(&res->headers); |
|
|
|
|
|
|
|
size += calc_res_status_sz(res); |
|
|
|
|
|
|
|
|
|
|
|
if (res->body) |
|
|
|
if (res->body) |
|
|
|
size += 2 + strlen(res->body); |
|
|
|
size += 2 + strlen(res->body); |
|
|
|
|
|
|
|
|
|
|
@ -78,25 +84,24 @@ int rpd_res_str(char **dest, const rpd_res *res) |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static size_t calc_res_headers_sz(const rpd_res *res) |
|
|
|
static size_t calc_res_status_sz(const rpd_res *res) |
|
|
|
{ |
|
|
|
{ |
|
|
|
size_t size = 0; |
|
|
|
size_t size = 0; |
|
|
|
|
|
|
|
size += strlen("Status: \r\n"); |
|
|
|
|
|
|
|
size += 3; /* plus status code */ |
|
|
|
|
|
|
|
return size; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
size += strlen("Status: \r\n") + 3; |
|
|
|
static size_t calc_res_headers_sz(const rpd_keyval *headers) |
|
|
|
if (res->location) { |
|
|
|
{ |
|
|
|
size += strlen("Location: \r\n") + strlen(res->location); |
|
|
|
size_t size = 0, i = 0; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
while (i < headers->size) { |
|
|
|
if (res->content_type) { |
|
|
|
size += strlen(headers->items[i].key); |
|
|
|
size += strlen("Content-Type: \r\n") + strlen(res->content_type); |
|
|
|
size += 2; /* plus ": " */ |
|
|
|
} |
|
|
|
size += strlen(headers->items[i].val); |
|
|
|
|
|
|
|
size += 2; /* plus CRLF */ |
|
|
|
if (res->cookie.size) { |
|
|
|
i++; |
|
|
|
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); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return size; |
|
|
|
return size; |
|
|
@ -106,22 +111,12 @@ void rpd_res_cleanup(rpd_res *res) |
|
|
|
{ |
|
|
|
{ |
|
|
|
res->status = rpd_res_st_ok; |
|
|
|
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) { |
|
|
|
if (res->body) { |
|
|
|
free(res->body); |
|
|
|
free(res->body); |
|
|
|
res->body = NULL; |
|
|
|
res->body = NULL; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (res->cookie.capacity) { |
|
|
|
if (res->headers.capacity) { |
|
|
|
rpd_keyval_cleanup(&res->cookie); |
|
|
|
rpd_keyval_cleanup(&res->headers); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|