feat(http): allow arbitrary number of response headers
ci/woodpecker/push/build Pipeline was successful
Details
ci/woodpecker/push/build Pipeline was successful
Details
parent
4427016094
commit
380605ea08
|
@ -39,8 +39,7 @@ pipeline:
|
||||||
- minio_access_key
|
- minio_access_key
|
||||||
- minio_secret_key
|
- minio_secret_key
|
||||||
when:
|
when:
|
||||||
branch:
|
branch: dev
|
||||||
exclude: [ release/* ]
|
|
||||||
event: push
|
event: push
|
||||||
|
|
||||||
publish-rel:
|
publish-rel:
|
||||||
|
|
|
@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
## [Unreleased](https://git.rustybever.be/Chewing_Bever/lander/src/branch/dev)
|
## [Unreleased](https://git.rustybever.be/Chewing_Bever/lander/src/branch/dev)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
* HTTP Loop
|
||||||
|
* Responses can now have an arbitrary number of headers
|
||||||
|
|
||||||
## [0.2.0](https://git.rustybever.be/Chewing_Bever/lander/src/tag/0.2.0)
|
## [0.2.0](https://git.rustybever.be/Chewing_Bever/lander/src/tag/0.2.0)
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
@ -24,8 +24,11 @@ typedef struct http_response {
|
||||||
size_t head_len;
|
size_t head_len;
|
||||||
size_t head_written;
|
size_t head_written;
|
||||||
http_body body;
|
http_body body;
|
||||||
http_response_header headers[4];
|
struct {
|
||||||
size_t header_count;
|
http_response_header *arr;
|
||||||
|
size_t len;
|
||||||
|
size_t cap;
|
||||||
|
} headers;
|
||||||
} http_response;
|
} http_response;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include <stdlib.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include "http/res.h"
|
#include "http/res.h"
|
||||||
|
@ -24,11 +25,25 @@ void http_res_set_body_file(http_response *res, const char *filename) {
|
||||||
|
|
||||||
void http_res_add_header(http_response *res, http_header type,
|
void http_res_add_header(http_response *res, http_header type,
|
||||||
const char *value, bool owned) {
|
const char *value, bool owned) {
|
||||||
res->headers[res->header_count].type = type;
|
// Extend the header array
|
||||||
res->headers[res->header_count].value = value;
|
if (res->headers.len == res->headers.cap) {
|
||||||
res->headers[res->header_count].owned = owned;
|
http_response_header *new_arr = realloc(
|
||||||
|
res->headers.arr, 2 * res->headers.cap * sizeof(http_response_header));
|
||||||
|
|
||||||
res->header_count++;
|
if (new_arr == NULL) {
|
||||||
|
// TODO error handling
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
res->headers.arr = new_arr;
|
||||||
|
res->headers.cap *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
res->headers.arr[res->headers.len].type = type;
|
||||||
|
res->headers.arr[res->headers.len].value = value;
|
||||||
|
res->headers.arr[res->headers.len].owned = owned;
|
||||||
|
|
||||||
|
res->headers.len++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void http_res_set_mime_type(http_response *res, http_mime_type mime_type) {
|
void http_res_set_mime_type(http_response *res, http_mime_type mime_type) {
|
||||||
|
|
|
@ -14,6 +14,10 @@ http_loop_ctx *http_loop_ctx_init(http_loop_gctx *g) {
|
||||||
ctx->g = g;
|
ctx->g = g;
|
||||||
ctx->c = g->custom_ctx_init();
|
ctx->c = g->custom_ctx_init();
|
||||||
|
|
||||||
|
// TODO error checking
|
||||||
|
ctx->res.headers.arr = malloc(4 * sizeof(http_response_header));
|
||||||
|
ctx->res.headers.cap = 4;
|
||||||
|
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +25,10 @@ void http_loop_ctx_free(http_loop_ctx *ctx) {
|
||||||
http_loop_ctx_reset(ctx);
|
http_loop_ctx_reset(ctx);
|
||||||
ctx->g->custom_ctx_free(ctx->c);
|
ctx->g->custom_ctx_free(ctx->c);
|
||||||
|
|
||||||
|
if (ctx->res.headers.cap > 0) {
|
||||||
|
free(ctx->res.headers.arr);
|
||||||
|
}
|
||||||
|
|
||||||
free(ctx);
|
free(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,13 +44,15 @@ void http_loop_ctx_reset(http_loop_ctx *ctx) {
|
||||||
http_body_reset(&ctx->req.body);
|
http_body_reset(&ctx->req.body);
|
||||||
http_body_reset(&ctx->res.body);
|
http_body_reset(&ctx->res.body);
|
||||||
|
|
||||||
for (size_t i = 0; i < ctx->res.header_count; i++) {
|
for (size_t i = 0; i < ctx->res.headers.len; i++) {
|
||||||
if (ctx->res.headers[i].owned) {
|
if (ctx->res.headers.arr[i].owned) {
|
||||||
free((void *)ctx->res.headers[i].value);
|
free((void *)ctx->res.headers.arr[i].value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->res.header_count = 0;
|
// We don't set the cap as we can just keep the original array for the next
|
||||||
|
// requests
|
||||||
|
ctx->res.headers.len = 0;
|
||||||
|
|
||||||
ctx->res.status = 0;
|
ctx->res.status = 0;
|
||||||
ctx->res.head_len = 0;
|
ctx->res.head_len = 0;
|
||||||
|
|
|
@ -25,10 +25,10 @@ void http_loop_init_header(http_response *res) {
|
||||||
response_type_name, res->body.expected_len);
|
response_type_name, res->body.expected_len);
|
||||||
|
|
||||||
// We add each header's required size
|
// We add each header's required size
|
||||||
for (size_t i = 0; i < res->header_count; i++) {
|
for (size_t i = 0; i < res->headers.len; i++) {
|
||||||
buf_size +=
|
buf_size += snprintf(NULL, 0, "%s: %s\n",
|
||||||
snprintf(NULL, 0, "%s: %s\n", http_header_names[res->headers[i].type],
|
http_header_names[res->headers.arr[i].type],
|
||||||
res->headers[i].value);
|
res->headers.arr[i].value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The + 1 is required to store the final null byte, but we will replace it
|
// The + 1 is required to store the final null byte, but we will replace it
|
||||||
|
@ -37,10 +37,10 @@ void http_loop_init_header(http_response *res) {
|
||||||
buf_size = sprintf(buf, http_response_format, res->status, response_type_name,
|
buf_size = sprintf(buf, http_response_format, res->status, response_type_name,
|
||||||
res->body.expected_len);
|
res->body.expected_len);
|
||||||
|
|
||||||
for (size_t i = 0; i < res->header_count; i++) {
|
for (size_t i = 0; i < res->headers.len; i++) {
|
||||||
buf_size +=
|
buf_size += sprintf(&buf[buf_size], "%s: %s\n",
|
||||||
sprintf(&buf[buf_size], "%s: %s\n",
|
http_header_names[res->headers.arr[i].type],
|
||||||
http_header_names[res->headers[i].type], res->headers[i].value);
|
res->headers.arr[i].value);
|
||||||
}
|
}
|
||||||
|
|
||||||
buf[buf_size] = '\n';
|
buf[buf_size] = '\n';
|
||||||
|
|
Loading…
Reference in New Issue