feat(lnm): implement context resetting

lnm
Jef Roosens 2023-12-02 13:24:22 +01:00
parent e8bb089f5c
commit 3c1e62330c
Signed by: Jef Roosens
GPG Key ID: B75D4F293C7052DB
6 changed files with 76 additions and 6 deletions

View File

@ -49,4 +49,12 @@ typedef enum lnm_http_parse_err {
*/ */
lnm_http_parse_err lnm_http_req_parse(lnm_http_req *req, char *buf, size_t len); lnm_http_parse_err lnm_http_req_parse(lnm_http_req *req, char *buf, size_t len);
/**
* Reset the given request object, free'ing all its relevant parts and allowing
* it to be reused as a new object.
*
* @param req object to reset
*/
void lnm_http_req_reset(lnm_http_req *req);
#endif #endif

View File

@ -108,4 +108,12 @@ void lnm_http_res_body_set_buf(lnm_http_res *res, char *buf, size_t len,
*/ */
void lnm_http_res_body_set_fn(lnm_http_res *res, data_fn fn, size_t len); void lnm_http_res_body_set_fn(lnm_http_res *res, data_fn fn, size_t len);
/**
* Reset the given response object, properly free'ing any allocated buffers,
* allowing it to be reused for later connections.
*
* @param res res to reset
*/
void lnm_http_res_reset(lnm_http_res *res);
#endif #endif

View File

@ -38,12 +38,18 @@ lnm_err lnm_http_loop_ctx_init(lnm_http_loop_ctx **out,
void lnm_http_loop_ctx_reset(lnm_http_loop_ctx *ctx) { void lnm_http_loop_ctx_reset(lnm_http_loop_ctx *ctx) {
ctx->g->ctx_reset(ctx->c); ctx->g->ctx_reset(ctx->c);
// TODO actual reset stuff
lnm_http_req_reset(&ctx->req);
lnm_http_res_reset(&ctx->res);
ctx->route = NULL;
ctx->cur_step = NULL;
} }
void lnm_http_loop_ctx_free(lnm_http_loop_ctx *ctx) { void lnm_http_loop_ctx_free(lnm_http_loop_ctx *ctx) {
lnm_http_loop_ctx_reset(ctx);
ctx->g->ctx_free(ctx->c); ctx->g->ctx_free(ctx->c);
// TODO actual free stuff
free(ctx); free(ctx);
} }

View File

@ -160,7 +160,7 @@ void lnm_http_loop_process_write_headers(lnm_http_conn *conn) {
lnm_http_loop_ctx *ctx = conn->ctx; lnm_http_loop_ctx *ctx = conn->ctx;
lnm_http_res *res = &ctx->res; lnm_http_res *res = &ctx->res;
lnm_http_res_header *header = res->headers.current; lnm_http_res_header *header;
// Loop as long as we can still write new data and have headers to write // Loop as long as we can still write new data and have headers to write
while ((conn->w.size < LNM_LOOP_BUF_SIZE) && while ((conn->w.size < LNM_LOOP_BUF_SIZE) &&
@ -212,7 +212,7 @@ void lnm_http_loop_process_write_body(lnm_http_conn *conn) {
case lnm_http_res_body_type_file: case lnm_http_res_body_type_file:
written = fread(&conn->w.buf[conn->w.size], 1, to_write, res->body.data.f); written = fread(&conn->w.buf[conn->w.size], 1, to_write, res->body.data.f);
if ((written == 0) && (!ferror(res->body.data.f))) { if ((written == 0) && (ferror(res->body.data.f) != 0)) {
ctx->state = lnm_http_loop_state_finish; ctx->state = lnm_http_loop_state_finish;
} }
break; break;
@ -232,7 +232,16 @@ void lnm_http_loop_process_write_body(lnm_http_conn *conn) {
} }
} }
void lnm_http_loop_process_finish(lnm_http_conn *conn) {} void lnm_http_loop_process_finish(lnm_http_conn *conn) {
// First we ensure the write buffer is fully flushed
if (conn->w.size > 0) {
return;
}
lnm_http_loop_ctx_reset(conn->ctx);
conn->state = lnm_loop_state_req;
}
void (*process_fns[])(lnm_http_conn *conn) = { void (*process_fns[])(lnm_http_conn *conn) = {
lnm_http_loop_process_parse_req, lnm_http_loop_process_parse_req,
@ -246,7 +255,7 @@ void (*process_fns[])(lnm_http_conn *conn) = {
}; };
void lnm_http_loop_process(lnm_http_conn *conn) { void lnm_http_loop_process(lnm_http_conn *conn) {
lnm_http_loop_ctx *ctx = conn->ctx; const lnm_http_loop_ctx *ctx = conn->ctx;
lnm_http_loop_state http_loop_state; lnm_http_loop_state http_loop_state;
lnm_loop_state loop_state = conn->state; lnm_loop_state loop_state = conn->state;

View File

@ -56,3 +56,7 @@ lnm_http_parse_err lnm_http_req_parse(lnm_http_req *req, char *buf,
return lnm_http_parse_err_ok; return lnm_http_parse_err_ok;
} }
void lnm_http_req_reset(lnm_http_req *req) {
memset(req, 0, sizeof(lnm_http_req));
}

View File

@ -62,3 +62,38 @@ void lnm_http_res_body_set_fn(lnm_http_res *res, data_fn fn, size_t len) {
res->body.len = len; res->body.len = len;
res->body.type = lnm_http_res_body_type_fn; 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));
}