diff --git a/inc/ctorm.h b/inc/ctorm.h index ea94d26..556dd78 100644 --- a/inc/ctorm.h +++ b/inc/ctorm.h @@ -263,6 +263,15 @@ */ #define REQ_PARAM(param) ctorm_req_param(req, param) +/*! + + * Get or set a local + * @param[in] name Local name + * @param[in] ... Local value + +*/ +#define REQ_LOCAL(local, ...) ctorm_req_local(req, local, ##__VA_ARGS__) + /*! * Parse URL form encoded request body @@ -348,7 +357,7 @@ * Set response body to a formatted string * @param[in] fmt Format string - * @return Format string arguments + * @param[in] ... Arguments for the format string */ #define RES_FMT(fmt, ...) ctorm_res_fmt(res, fmt, __VA_ARGS__) diff --git a/inc/errors.h b/inc/errors.h index c15c785..4590f38 100644 --- a/inc/errors.h +++ b/inc/errors.h @@ -50,6 +50,9 @@ typedef enum { PortTooLarge = 9937, NameTooLarge = 9938, BadName = 9939, + BadLocalPointer = 9940, + BadQueryPointer = 9941, + BadParamPointer = 9942, } ctorm_error_t; /*! diff --git a/inc/log.h b/inc/log.h index be0b62b..d799688 100644 --- a/inc/log.h +++ b/inc/log.h @@ -37,8 +37,8 @@ void ctorm_debug(const char *fmt, ...); * Print messages marked as "info", you can use this * to print informative messages - * @param[in] fmt Message format string - * @param[in] ... Arguments for the formatted string + * @param[in] fmt Format string + * @param[in] ... Arguments for the format string */ void ctorm_info(const char *fmt, ...); @@ -48,8 +48,8 @@ void ctorm_info(const char *fmt, ...); * Print messages marked as "warn", you can use this * to print warnings - * @param[in] fmt Message format string - * @param[in] ... Arguments for the formatted string + * @param[in] fmt Format string + * @param[in] ... Arguments for the format string */ void ctorm_warn(const char *fmt, ...); @@ -59,8 +59,8 @@ void ctorm_warn(const char *fmt, ...); * Print messages marked as "fail", you can use this * to print failures - * @param[in] fmt Message format string - * @param[in] ... Arguments for the formatted string + * @param[in] fmt Format string + * @param[in] ... Arguments for the format string */ void ctorm_fail(const char *fmt, ...); diff --git a/inc/req.h b/inc/req.h index d512722..b6d7bc5 100644 --- a/inc/req.h +++ b/inc/req.h @@ -33,6 +33,7 @@ typedef struct { bool received_headers; /// did we receive all the HTTP headers ctorm_url_t *queries; /// HTTP queries (for example "?key=1") ctorm_pair_t *params; /// HTTP path params (for example "/blog/:slug") + ctorm_pair_t *locals; /// Local variables to pass along with the request int64_t bodysize; /// size of the HTTP body } ctorm_req_t; @@ -40,23 +41,25 @@ typedef struct { #define ctorm_req_is_valid(req) \ (NULL != (req)->version && NULL != (req)->encpath && NULL != (req)->path) // check if the request is valid -void ctorm_req_init(ctorm_req_t *, connection_t *); // setup a request -void ctorm_req_free(ctorm_req_t *); // cleanup a request -bool ctorm_req_start(ctorm_req_t *); // receive the (at least the first part) of the HTTP request -void ctorm_req_end(ctorm_req_t *); // completely receive the HTTP request +void ctorm_req_init(ctorm_req_t *req, connection_t *con); // setup a request +void ctorm_req_free(ctorm_req_t *req); // cleanup a request +bool ctorm_req_start(ctorm_req_t *req); // receive the (at least the first part) of the HTTP request +void ctorm_req_end(ctorm_req_t *req); // completely receive the HTTP request #endif -const char *ctorm_req_method(ctorm_req_t *); // get the request method (GET, POST, PUT etc.) -char *ctorm_req_query(ctorm_req_t *, char *name); // get a request URL query -char *ctorm_req_param(ctorm_req_t *, char *name); // get a request URL param -char *ctorm_req_get(ctorm_req_t *, char *header); // get a request header +const char *ctorm_req_method(ctorm_req_t *req); // get the request method (GET, POST, PUT etc.) +char *ctorm_req_query(ctorm_req_t *req, char *name); // get a request URL query +char *ctorm_req_param(ctorm_req_t *req, char *name); // get a request URL param +void *ctorm_req_local(ctorm_req_t *req, char *name, ...); // get or set a local by name +char *ctorm_req_get(ctorm_req_t *req, char *header); // get a request header -uint64_t ctorm_req_body(ctorm_req_t *, char *buf, uint64_t size); // copy given amount of bytes from body to the buffer -uint64_t ctorm_req_body_size(ctorm_req_t *); // get the body size +uint64_t ctorm_req_body( + ctorm_req_t *req, char *buf, uint64_t size); // copy given amount of bytes from body to the buffer +uint64_t ctorm_req_body_size(ctorm_req_t *req); // get the body size -char *ctorm_req_ip(ctorm_req_t *, char *); // get the requester IPv4/IPv6 address as string -#define ctorm_req_addr(r) ((r)->con->addr) // get the requester address as sockaddr +char *ctorm_req_ip(ctorm_req_t *req, char *); // get the requester IPv4/IPv6 address as string +#define ctorm_req_addr(req) ((req)->con->addr) // get the requester address as sockaddr -ctorm_url_t *ctorm_req_form(ctorm_req_t *); // parse URL encoded form body -cJSON *ctorm_req_json(ctorm_req_t *); // parse JSON encoded form body +ctorm_url_t *ctorm_req_form(ctorm_req_t *req); // parse URL encoded form body +cJSON *ctorm_req_json(ctorm_req_t *req); // parse JSON encoded form body diff --git a/src/errors.c b/src/errors.c index 16eb464..0916af0 100644 --- a/src/errors.c +++ b/src/errors.c @@ -1,7 +1,5 @@ #include "errors.h" - #include -#include struct ctorm_error_desc descs[] = { {BadTcpTimeout, "invalid TCP timeout" }, @@ -24,6 +22,9 @@ struct ctorm_error_desc descs[] = { {BadFmtPointer, "invalid string format pointer" }, {BadPathPointer, "invalid path pointer" }, {BadDataPointer, "invalid data pointer" }, + {BadLocalPointer, "invalid local name pointer" }, + {BadParamPointer, "invalid URL parameter name pointer" }, + {BadQueryPointer, "invalid URL query name pointer" }, {BadHeaderPointer, "invalid header name/value pointer" }, {BadMaxConnCount, "invalid max connection count" }, {NoJSONSupport, "library not compiled with JSON support" }, diff --git a/src/pair.c b/src/pair.c index eea9f3a..dee80a3 100644 --- a/src/pair.c +++ b/src/pair.c @@ -1,4 +1,5 @@ #include "pair.h" +#include "errors.h" #include "util.h" #include @@ -12,6 +13,12 @@ ctorm_pair_t *ctorm_pair_add(ctorm_pair_t **head, char *key, char *value) { } ctorm_pair_t *new = malloc(sizeof(ctorm_pair_t)); + + if (NULL == new) { + errno = AllocFailed; + return NULL; + } + bzero(new, sizeof(ctorm_pair_t)); if (NULL != head) { diff --git a/src/req.c b/src/req.c index 1d19caf..2ebd1d7 100644 --- a/src/req.c +++ b/src/req.c @@ -2,6 +2,7 @@ #include "errors.h" #include "http.h" +#include "pair.h" #include "util.h" #include "req.h" @@ -9,6 +10,7 @@ #include +#include #include #include @@ -92,22 +94,16 @@ void ctorm_req_init(ctorm_req_t *req, connection_t *con) { ctorm_headers_init(&req->headers); req->received_headers = false; - - req->queries = NULL; - req->params = NULL; - req->bodysize = -1; - - req->con = con; - req->cancel = false; - req->version = NULL; - req->encpath = NULL; - req->path = NULL; + req->con = con; + req->cancel = false; + req->bodysize = -1; } void ctorm_req_free(ctorm_req_t *req) { ctorm_headers_free(req->headers); ctorm_url_free(req->queries); ctorm_pair_free(req->params); + ctorm_pair_free(req->locals); free(req->encpath); free(req->path); @@ -194,21 +190,43 @@ void ctorm_req_end(ctorm_req_t *req) { } char *ctorm_req_query(ctorm_req_t *req, char *name) { - if (NULL == name) + if (NULL == name) { + errno = BadQueryPointer; return NULL; + } + return ctorm_url_get(req->queries, name); } char *ctorm_req_param(ctorm_req_t *req, char *name) { - if (NULL == name) + if (NULL == name) { + errno = BadParamPointer; return NULL; + } - ctorm_pair_t *pair = ctorm_pair_find(req->params, name); + ctorm_pair_t *param = ctorm_pair_find(req->params, name); + return NULL == param ? NULL : param->value; +} - if (NULL == pair) +void *ctorm_req_local(ctorm_req_t *req, char *name, ...) { + if (NULL == name) { + errno = BadLocalPointer; return NULL; + } + + ctorm_pair_t *local = NULL; + void *value = NULL; + va_list args; + + va_start(args, name); + + if (NULL == (value = va_arg(args, void *))) + local = ctorm_pair_find(req->locals, name); + else + local = ctorm_pair_add(&req->locals, name, value); - return pair->value; + va_end(args); + return NULL == local ? NULL : local->value; } ctorm_url_t *ctorm_req_form(ctorm_req_t *req) {