kore

An easy to use, scalable and secure web application framework for writing web APIs in C.
Commits | Files | Refs | README | LICENSE | git clone https://git.kore.io/kore.git

commit d783a1d22dc69dd0a2dcb0a4c53babe671f628b7
parent facc8b9d6c5d4547d5c496f988d4e3409e094c52
Author: Joris Vink <joris@coders.se>
Date:   Mon, 26 Dec 2016 21:15:03 +0100

Add auto generated serving functions for assets.

These functions are created by the cli tool when building
and follow the naming format: asset_serve_<name>_<ext>().

Those serving functions can be used directly in handlers and
callthrough to a http_serveable() function that uses the SHA1
of the asset as its ETag and automatically checks for if-none-match.

Diffstat:
includes/http.h | 2++
src/cli.c | 17++++++++++++++++-
src/http.c | 23+++++++++++++++++++++++
3 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/includes/http.h b/includes/http.h @@ -222,6 +222,8 @@ void http_request_wakeup(struct http_request *); void http_process_request(struct http_request *); ssize_t http_body_read(struct http_request *, void *, size_t); void http_response(struct http_request *, int, const void *, size_t); +void http_serveable(struct http_request *, const void *, + size_t, const char *); void http_response_stream(struct http_request *, int, void *, size_t, int (*cb)(struct netbuf *), void *); int http_request_header(struct http_request *, diff --git a/src/cli.c b/src/cli.c @@ -187,6 +187,16 @@ static const char *gen_dirs[] = { NULL }; +static const char *http_serveable_function = + "int asset_serve_%s_%s(struct http_request *);\n\n" + "int\n" + "asset_serve_%s_%s(struct http_request *req)\n" + "{\n" + " http_serveable(req, asset_%s_%s, asset_len_%s_%s,\n" + " asset_sha1_%s_%s);\n" + " return (KORE_RESULT_OK);\n" + "}\n"; + static const char *src_data = "#include <kore/kore.h>\n" "#include <kore/http.h>\n" @@ -830,6 +840,8 @@ cli_build_asset(char *fpath, struct dirent *dp) /* Start generating the file. */ cli_file_writef(out, "/* Auto generated */\n"); cli_file_writef(out, "#include <sys/types.h>\n\n"); + cli_file_writef(out, "#include <kore/kore.h>\n"); + cli_file_writef(out, "#include <kore/http.h>\n\n"); /* Write the file data as a byte array. */ cli_file_writef(out, "u_int8_t asset_%s_%s[] = {\n", name, ext); @@ -862,8 +874,11 @@ cli_build_asset(char *fpath, struct dirent *dp) name, ext, (u_int32_t)st.st_size); cli_file_writef(out, "time_t asset_mtime_%s_%s = %" PRI_TIME_T ";\n", name, ext, st.st_mtime); - cli_file_writef(out, "const char *asset_sha1_%s_%s = \"%s\";\n", + cli_file_writef(out, + "const char *asset_sha1_%s_%s = \"\\\"%s\\\"\";\n", name, ext, hash); + cli_file_writef(out, http_serveable_function, name, ext, + name, ext, name, ext, name, ext, name, ext); /* Write the file symbols into assets.h so they can be used. */ cli_write_asset(name, ext); diff --git a/src/http.c b/src/http.c @@ -482,6 +482,29 @@ http_request_free(struct http_request *req) } void +http_serveable(struct http_request *req, const void *data, size_t len, + const char *etag) +{ + char *match; + + if (req->method != HTTP_METHOD_GET) { + http_response_header(req, "allow", "get"); + http_response(req, HTTP_STATUS_BAD_REQUEST, NULL, 0); + return; + } + + if (http_request_header(req, "if-none-match", &match)) { + if (!strcmp(match, etag)) { + http_response(req, HTTP_STATUS_NOT_MODIFIED, NULL, 0); + return; + } + } + + http_response_header(req, "etag", etag); + http_response(req, HTTP_STATUS_OK, data, len); +} + +void http_response(struct http_request *req, int status, const void *d, size_t l) { kore_debug("http_response(%p, %d, %p, %zu)", req, status, d, l);