Skip to content

Instantly share code, notes, and snippets.

@lpereira
Last active August 29, 2015 14:11
Show Gist options
  • Save lpereira/79e6d31a5bccbfdcc3aa to your computer and use it in GitHub Desktop.
Save lpereira/79e6d31a5bccbfdcc3aa to your computer and use it in GitHub Desktop.
#include "lwan.h"
#include "lwan-cache.h"
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
struct file_info_t {
struct cache_entry_t base;
struct {
char *content;
size_t size;
} metadata;
char *key;
};
static lwan_t l;
static struct cache_t *cache;
// ham nay load file tu dia len memory
static size_t ae_load_file_to_memory(const char *filename, char **result) {
size_t size = 0;
FILE *f = fopen(filename, "rb");
if (f == NULL) {
*result = NULL;
return 0; // -1 means file opening fail
}
fseek(f, 0, SEEK_END);
size = (size_t) ftell(f);
fseek(f, 0, SEEK_SET);
*result = (char *) malloc(size);
if (*result) {
if (size != fread(*result, 1, size, f)) {
free(*result);
*result = NULL;
}
}
fclose(f);
return size;
}
// handler trong file config
lwan_http_status_t
static_handler(lwan_request_t *request,
lwan_response_t *response,
void *data __attribute__((unused))) {
struct file_info_t *fi;
fi = (struct file_info_t*) cache_coro_get_and_ref_entry(cache,
request->conn->coro, "love.jpg");
if (!fi)
return HTTP_NOT_FOUND;
response->mime_type = lwan_determine_mime_type_for_file_name("love.jpg");
// tra ra cho browser
lwan_status_info("loaded from cache: key=[%s], metadata.size=[%zu]",
fi->key, fi->metadata.size);
strbuf_set_static(response->buffer, fi->metadata.content, fi->metadata.size);
return HTTP_OK;
}
// read file and initialize cache object
static struct cache_entry_t *
create_fileinfo(const char *file_path,
void *context __attribute__((unused))) {
struct file_info_t *fi = calloc(1, sizeof (struct file_info_t));
if (!fi)
return NULL;
char *content = NULL;
size_t file_size = ae_load_file_to_memory(file_path, &content);
lwan_status_info("loaded from disk: key=[%s], metadata.size=[%zu]", file_path, file_size);
if (content && file_size) {
fi->key = strdup(file_path);
fi->metadata.content = content;
fi->metadata.size = file_size;
return (struct cache_entry_t *) fi;
}
return NULL;
}
// callback to destroy cache
static void
destroy_fileinfo(struct cache_entry_t *entry,
void *context __attribute__((unused))) {
struct file_info_t *fileinfo = (struct file_info_t *) entry;
if (!fileinfo) return;
free(fileinfo->metadata.content);
free(fileinfo->key);
free(fileinfo);
}
int
main(void)
{
lwan_init(&l);
cache = cache_create(create_fileinfo, destroy_fileinfo, NULL, 16);
lwan_main_loop(&l);
lwan_shutdown(&l);
cache_destroy(cache);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment