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.
This commit is contained in:
Joris Vink 2016-12-26 21:15:03 +01:00
parent facc8b9d6c
commit d783a1d22d
3 changed files with 41 additions and 1 deletions

View File

@ -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 *,

View File

@ -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);

View File

@ -481,6 +481,29 @@ http_request_free(struct http_request *req)
http_request_count--;
}
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)
{