lock magic in cache_handler
This commit is contained in:
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
static magic_t magic;
|
static magic_t magic;
|
||||||
static pthread_t thread;
|
static pthread_t thread;
|
||||||
static sem_t sem_free, sem_used, sem_lock, sem_cache;
|
static sem_t sem_free, sem_used, sem_lock, sem_cache, sem_magic;
|
||||||
volatile sig_atomic_t alive = 1;
|
volatile sig_atomic_t alive = 1;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -52,6 +52,54 @@ static int magic_init(void) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void magic_mime_type(const char *restrict filename, char *buf) {
|
||||||
|
retry:
|
||||||
|
if (sem_wait(&sem_magic) != 0) {
|
||||||
|
if (errno == EINTR) {
|
||||||
|
errno = 0;
|
||||||
|
goto retry;
|
||||||
|
} else {
|
||||||
|
critical("Unable to lock magic semaphore");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
magic_setflags(magic, MAGIC_MIME_TYPE);
|
||||||
|
const char *type = magic_file(magic, filename);
|
||||||
|
|
||||||
|
if (strstarts(type, "text/")) {
|
||||||
|
if (strends(filename, ".css")) {
|
||||||
|
strcpy(buf, "text/css");
|
||||||
|
sem_post(&sem_magic);
|
||||||
|
return;
|
||||||
|
} else if (strends(filename, ".js")) {
|
||||||
|
strcpy(buf, "application/javascript");
|
||||||
|
sem_post(&sem_magic);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(buf, type);
|
||||||
|
sem_post(&sem_magic);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void magic_charset(const char *restrict filename, char *buf) {
|
||||||
|
retry:
|
||||||
|
if (sem_wait(&sem_magic) != 0) {
|
||||||
|
if (errno == EINTR) {
|
||||||
|
errno = 0;
|
||||||
|
goto retry;
|
||||||
|
} else {
|
||||||
|
critical("Unable to lock magic semaphore");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
magic_setflags(magic, MAGIC_MIME_ENCODING);
|
||||||
|
strcpy(buf, magic_file(magic, filename));
|
||||||
|
sem_post(&sem_magic);
|
||||||
|
}
|
||||||
|
|
||||||
static void cache_free(void) {
|
static void cache_free(void) {
|
||||||
for (int i = 0; i < CONFIG_MAX_HOST_CONFIG; i++) {
|
for (int i = 0; i < CONFIG_MAX_HOST_CONFIG; i++) {
|
||||||
host_config_t *hc = &config.hosts[i];
|
host_config_t *hc = &config.hosts[i];
|
||||||
@ -67,6 +115,7 @@ static void cache_free(void) {
|
|||||||
sem_destroy(&sem_free);
|
sem_destroy(&sem_free);
|
||||||
sem_destroy(&sem_used);
|
sem_destroy(&sem_used);
|
||||||
sem_destroy(&sem_cache);
|
sem_destroy(&sem_cache);
|
||||||
|
sem_destroy(&sem_magic);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cache_entry_t *cache_get_entry(cache_t *cache, const char *filename) {
|
static cache_entry_t *cache_get_entry(cache_t *cache, const char *filename) {
|
||||||
@ -166,7 +215,7 @@ static void cache_process_entry(cache_entry_t *entry) {
|
|||||||
comp_err:
|
comp_err:
|
||||||
compress = 0;
|
compress = 0;
|
||||||
} else {
|
} else {
|
||||||
if ((compress_init(&comp_ctx, COMPRESS_GZ | COMPRESS_BR)) != 0) {
|
if ((compress_init(&comp_ctx, COMPRESS_GZ | COMPRESS_BR | (mime_is_text(entry->meta.type) ? COMPRESS_UTF8 : 0))) != 0) {
|
||||||
error("Unable to init compression");
|
error("Unable to init compression");
|
||||||
compress = 0;
|
compress = 0;
|
||||||
fclose(comp_file_gz);
|
fclose(comp_file_gz);
|
||||||
@ -175,11 +224,9 @@ static void cache_process_entry(cache_entry_t *entry) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long read;
|
for (unsigned long read, avail_in, avail_out; (read = fread(buf, 1, sizeof(buf), file)) > 0;) {
|
||||||
while ((read = fread(buf, 1, sizeof(buf), file)) > 0) {
|
|
||||||
EVP_DigestUpdate(ctx, buf, read);
|
EVP_DigestUpdate(ctx, buf, read);
|
||||||
if (compress) {
|
if (compress) {
|
||||||
unsigned long avail_in, avail_out;
|
|
||||||
avail_in = read;
|
avail_in = read;
|
||||||
do {
|
do {
|
||||||
avail_out = sizeof(comp_buf);
|
avail_out = sizeof(comp_buf);
|
||||||
@ -295,7 +342,8 @@ int cache_init(void) {
|
|||||||
if (sem_init(&sem_lock, 0, 1) != 0 ||
|
if (sem_init(&sem_lock, 0, 1) != 0 ||
|
||||||
sem_init(&sem_free, 0, 1) != 0 ||
|
sem_init(&sem_free, 0, 1) != 0 ||
|
||||||
sem_init(&sem_used, 0, 0) != 0 ||
|
sem_init(&sem_used, 0, 0) != 0 ||
|
||||||
sem_init(&sem_cache, 0, 1) != 0)
|
sem_init(&sem_cache, 0, 1) != 0 ||
|
||||||
|
sem_init(&sem_magic, 0, 1) != 0)
|
||||||
{
|
{
|
||||||
critical("Unable to initialize semaphore");
|
critical("Unable to initialize semaphore");
|
||||||
return -1;
|
return -1;
|
||||||
@ -323,10 +371,10 @@ static void cache_mark_entry_dirty(cache_entry_t *entry) {
|
|||||||
if (entry->flags & CACHE_DIRTY)
|
if (entry->flags & CACHE_DIRTY)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
entry->flags |= CACHE_DIRTY;
|
||||||
memset(entry->meta.etag, 0, sizeof(entry->meta.etag));
|
memset(entry->meta.etag, 0, sizeof(entry->meta.etag));
|
||||||
memset(entry->meta.filename_comp_gz, 0, sizeof(entry->meta.filename_comp_gz));
|
memset(entry->meta.filename_comp_gz, 0, sizeof(entry->meta.filename_comp_gz));
|
||||||
memset(entry->meta.filename_comp_br, 0, sizeof(entry->meta.filename_comp_br));
|
memset(entry->meta.filename_comp_br, 0, sizeof(entry->meta.filename_comp_br));
|
||||||
entry->flags |= CACHE_DIRTY;
|
|
||||||
|
|
||||||
try_again_free:
|
try_again_free:
|
||||||
if (sem_wait(&sem_free) != 0) {
|
if (sem_wait(&sem_free) != 0) {
|
||||||
@ -366,25 +414,11 @@ static void cache_mark_entry_dirty(cache_entry_t *entry) {
|
|||||||
|
|
||||||
static void cache_update_entry(cache_entry_t *entry, const char *filename, const char *webroot) {
|
static void cache_update_entry(cache_entry_t *entry, const char *filename, const char *webroot) {
|
||||||
entry->meta.mtime = stat_mtime(filename);
|
entry->meta.mtime = stat_mtime(filename);
|
||||||
|
|
||||||
entry->webroot_len = (unsigned char) strlen(webroot);
|
entry->webroot_len = (unsigned char) strlen(webroot);
|
||||||
strcpy(entry->filename, filename);
|
strcpy(entry->filename, filename);
|
||||||
|
|
||||||
magic_setflags(magic, MAGIC_MIME_TYPE);
|
magic_mime_type(filename, entry->meta.type);
|
||||||
const char *type = magic_file(magic, filename);
|
magic_charset(filename, entry->meta.charset);
|
||||||
char type_new[URI_TYPE_SIZE];
|
|
||||||
sprintf(type_new, "%s", type);
|
|
||||||
if (strstarts(type, "text/")) {
|
|
||||||
if (strends(filename, ".css")) {
|
|
||||||
sprintf(type_new, "text/css");
|
|
||||||
} else if (strends(filename, ".js")) {
|
|
||||||
sprintf(type_new, "application/javascript");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
strcpy(entry->meta.type, type_new);
|
|
||||||
|
|
||||||
magic_setflags(magic, MAGIC_MIME_ENCODING);
|
|
||||||
strcpy(entry->meta.charset, magic_file(magic, filename));
|
|
||||||
|
|
||||||
cache_mark_entry_dirty(entry);
|
cache_mark_entry_dirty(entry);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user