void h2o_config_setenv(h2o_envconf_t *envconf, const char *name, const char *value) { size_t name_len = strlen(name), i; h2o_iovec_t *value_slot; /* remove from the list of unsets */ for (i = 0; i != envconf->unsets.size; ++i) { if (h2o_memis(envconf->unsets.entries[i].base, envconf->unsets.entries[i].len, name, name_len)) { h2o_mem_release_shared(envconf->unsets.entries[i].base); h2o_vector_erase(&envconf->unsets, i); break; } } /* find the slot */ for (i = 0; i != envconf->sets.size; i += 2) { if (h2o_memis(envconf->sets.entries[i].base, envconf->sets.entries[i].len, name, name_len)) { value_slot = envconf->sets.entries + i + 1; h2o_mem_release_shared(value_slot->base); goto SetValue; } } /* name not found in existing sets */ h2o_vector_reserve(NULL, &envconf->sets, envconf->sets.size + 2); envconf->sets.entries[envconf->sets.size++] = h2o_strdup_shared(NULL, name, name_len); value_slot = envconf->sets.entries + envconf->sets.size++; SetValue: *value_slot = h2o_strdup_shared(NULL, value, SIZE_MAX); }
static void on_dispose(void *_mimemap) { h2o_mimemap_t *mimemap = _mimemap; const char *ext; h2o_iovec_t type; kh_foreach(mimemap->table, ext, type, { h2o_mem_release_shared((char *)ext); h2o_mem_release_shared(type.base); });
static void on_dispose(void *_mimemap) { h2o_mimemap_t *mimemap = _mimemap; const char *ext; h2o_mimemap_type_t *type; kh_destroy(typeset, mimemap->typeset); kh_foreach(mimemap->extmap, ext, type, { h2o_mem_release_shared((char *)ext); h2o_mem_release_shared(type); });
static void on_dispose_envconf(void *_envconf) { h2o_envconf_t *envconf = _envconf; size_t i; if (envconf->parent != NULL) h2o_mem_release_shared(envconf->parent); for (i = 0; i != envconf->unsets.size; ++i) h2o_mem_release_shared(envconf->unsets.entries[i].base); free(envconf->unsets.entries); for (i = 0; i != envconf->sets.size; ++i) h2o_mem_release_shared(envconf->sets.entries[i].base); free(envconf->sets.entries); }
static int on_config_mime_settypes(h2o_configurator_command_t *cmd, h2o_configurator_context_t *ctx, yoml_t *node) { struct st_h2o_file_configurator_t *self = (void *)cmd->configurator; h2o_mimemap_t *newmap = h2o_mimemap_create(); h2o_mimemap_set_default_type(newmap, h2o_mimemap_get_default_type(self->vars->mimemap), 1); if (set_mimetypes(cmd, newmap, node) != 0) { h2o_mem_release_shared(newmap); return -1; } h2o_mem_release_shared(self->vars->mimemap); self->vars->mimemap = newmap; return 0; }
static void clone_mimemap_if_clean(struct st_h2o_file_configurator_t *self) { if (self->vars->mimemap != self->vars[-1].mimemap) return; h2o_mem_release_shared(self->vars->mimemap); self->vars->mimemap = h2o_mimemap_clone(self->vars->mimemap); }
static void specific_handler_on_dispose(h2o_handler_t *_self) { struct st_h2o_specific_file_handler_t *self = (void *)_self; free(self->real_path.base); h2o_mem_release_shared(self->mime_type); }
void h2o_mem_clear_pool(h2o_mem_pool_t *pool) { /* release the refcounted chunks */ if (pool->shared_refs != NULL) { struct st_h2o_mem_pool_shared_ref_t *ref = pool->shared_refs; do { h2o_mem_release_shared(ref->entry->bytes); } while ((ref = ref->next) != NULL); pool->shared_refs = NULL; } /* release the direct chunks */ if (pool->directs != NULL) { struct st_h2o_mem_pool_direct_t *direct = pool->directs, *next; do { next = direct->next; free(direct); } while ((direct = next) != NULL); pool->directs = NULL; } /* free chunks, and reset the first chunk */ while (pool->chunks != NULL) { struct st_h2o_mem_pool_chunk_t *next = pool->chunks->next; h2o_mem_free_recycle(&mempool_allocator, pool->chunks); pool->chunks = next; } pool->chunk_offset = sizeof(pool->chunks->bytes); }
static int on_config_exit(h2o_configurator_t *_self, h2o_configurator_context_t *ctx, yoml_t *node) { struct st_h2o_file_configurator_t *self = (void *)_self; free(self->vars->index_files); h2o_mem_release_shared(self->vars->mimemap); --self->vars; return 0; }
static void destroy_context(h2o_configurator_context_t *ctx) { if (ctx->env != NULL) { if (ctx->pathconf != NULL) ctx->pathconf->env = ctx->env; else h2o_mem_release_shared(ctx->env); } free(ctx); }
static int set_mimetypes(h2o_configurator_command_t *cmd, h2o_mimemap_t *mimemap, yoml_t *node) { size_t i, j; h2o_mimemap_type_t *type = NULL; assert(node->type == YOML_TYPE_MAPPING); for (i = 0; i != node->data.mapping.size; ++i) { yoml_t *key = node->data.mapping.elements[i].key; yoml_t *value = node->data.mapping.elements[i].value; if (assert_is_mimetype(cmd, key) != 0) return -1; type = h2o_mimemap_create_extension_type(key->data.scalar); switch (value->type) { case YOML_TYPE_SCALAR: if (assert_is_extension(cmd, value) != 0) goto Error; h2o_mimemap_set_type(mimemap, value->data.scalar + 1, type, 1); break; case YOML_TYPE_SEQUENCE: for (j = 0; j != value->data.sequence.size; ++j) { yoml_t *ext_node = value->data.sequence.elements[j]; if (assert_is_extension(cmd, ext_node) != 0) goto Error; h2o_mimemap_set_type(mimemap, ext_node->data.scalar + 1, type, 1); } break; default: h2o_configurator_errprintf(cmd, value, "only scalar or sequence of scalar is permitted at the value part of the argument"); goto Error; } h2o_mem_release_shared(type); type = NULL; } return 0; Error: if (type != NULL) h2o_mem_release_shared(type); return -1; }
static void on_dispose(h2o_handler_t *_self) { h2o_file_handler_t *self = (void *)_self; size_t i; free(self->conf_path.base); free(self->real_path.base); h2o_mem_release_shared(self->mimemap); for (i = 0; self->index_files[i].base != NULL; ++i) free(self->index_files[i].base); }
void h2o_config_dispose(h2o_globalconf_t *config) { size_t i; for (i = 0; config->hosts[i] != NULL; ++i) { h2o_hostconf_t *hostconf = config->hosts[i]; destroy_hostconf(hostconf); } free(config->hosts); h2o_mem_release_shared(config->mimemap); h2o_configurator__dispose_configurators(config); }
void h2o_config_dispose_pathconf(h2o_pathconf_t *pathconf) { #define DESTROY_LIST(type, list) \ do { \ size_t i; \ for (i = 0; i != list.size; ++i) { \ type *e = list.entries[i]; \ if (e->dispose != NULL) \ e->dispose(e); \ free(e); \ } \ free(list.entries); \ } while (0) DESTROY_LIST(h2o_handler_t, pathconf->handlers); DESTROY_LIST(h2o_filter_t, pathconf->_filters); DESTROY_LIST(h2o_logger_t, pathconf->_loggers); #undef DESTROY_LIST free(pathconf->path.base); if (pathconf->mimemap != NULL) h2o_mem_release_shared(pathconf->mimemap); if (pathconf->env != NULL) h2o_mem_release_shared(pathconf->env); }
static void destroy_hostconf(h2o_hostconf_t *hostconf) { size_t i; if (hostconf->authority.hostport.base != hostconf->authority.host.base) free(hostconf->authority.hostport.base); free(hostconf->authority.host.base); for (i = 0; i != hostconf->paths.size; ++i) { h2o_pathconf_t *pathconf = hostconf->paths.entries + i; h2o_config_dispose_pathconf(pathconf); } h2o_config_dispose_pathconf(&hostconf->fallback_path); h2o_mem_release_shared(hostconf->mimemap); free(hostconf); }
void h2o_context_update_timestamp_cache(h2o_context_t *ctx) { time_t prev_sec = ctx->_timestamp_cache.tv_at.tv_sec; ctx->_timestamp_cache.uv_now_at = h2o_now(ctx->loop); gettimeofday(&ctx->_timestamp_cache.tv_at, NULL); if (ctx->_timestamp_cache.tv_at.tv_sec != prev_sec) { struct tm gmt; /* update the string cache */ if (ctx->_timestamp_cache.value != NULL) h2o_mem_release_shared(ctx->_timestamp_cache.value); ctx->_timestamp_cache.value = h2o_mem_alloc_shared(NULL, sizeof(h2o_timestamp_string_t), NULL); gmtime_r(&ctx->_timestamp_cache.tv_at.tv_sec, &gmt); h2o_time2str_rfc1123(ctx->_timestamp_cache.value->rfc1123, &gmt); h2o_time2str_log(ctx->_timestamp_cache.value->log, ctx->_timestamp_cache.tv_at.tv_sec); } }
static int on_config_exit(h2o_configurator_t *_self, h2o_configurator_context_t *ctx, const char *file, yoml_t *node) { struct st_h2o_access_log_configurator_t *self = (void*)_self; size_t i; /* register all handles, and decref them */ for (i = 0; i != self->handles->size; ++i) { h2o_access_log_filehandle_t *fh = self->handles->entries[i]; if (ctx->pathconf != NULL) h2o_access_log_register(ctx->pathconf, fh); h2o_mem_release_shared(fh); } /* free the vector */ free(self->handles->entries); /* pop the stack pointer */ --self->handles; return 0; }
void h2o_get_timestamp(h2o_context_t *ctx, h2o_mem_pool_t *pool, h2o_timestamp_t *ts) { uint64_t now = h2o_now(ctx->loop); if (ctx->_timestamp_cache.uv_now_at != now) { time_t prev_sec = ctx->_timestamp_cache.tv_at.tv_sec; ctx->_timestamp_cache.uv_now_at = now; gettimeofday(&ctx->_timestamp_cache.tv_at, NULL); if (ctx->_timestamp_cache.tv_at.tv_sec != prev_sec) { /* update the string cache */ if (ctx->_timestamp_cache.value != NULL) h2o_mem_release_shared(ctx->_timestamp_cache.value); ctx->_timestamp_cache.value = h2o_mem_alloc_shared(NULL, sizeof(h2o_timestamp_string_t), NULL); h2o_time2str_rfc1123(ctx->_timestamp_cache.value->rfc1123, ctx->_timestamp_cache.tv_at.tv_sec); h2o_time2str_log(ctx->_timestamp_cache.value->log, ctx->_timestamp_cache.tv_at.tv_sec); } } ts->at = ctx->_timestamp_cache.tv_at; h2o_mem_link_shared(pool, ctx->_timestamp_cache.value); ts->str = ctx->_timestamp_cache.value; }
void h2o_headers_append_command(h2o_headers_command_t **cmds, int cmd, h2o_iovec_t *name, h2o_iovec_t value) { h2o_headers_command_t *new_cmds; size_t cnt; if (*cmds != NULL) { for (cnt = 0; (*cmds)[cnt].cmd != H2O_HEADERS_CMD_NULL; ++cnt) ; } else { cnt = 0; } new_cmds = h2o_mem_alloc_shared(NULL, (cnt + 2) * sizeof(*new_cmds), NULL); if (*cmds != NULL) memcpy(new_cmds, *cmds, cnt * sizeof(*new_cmds)); new_cmds[cnt] = (h2o_headers_command_t){cmd, name, value}; new_cmds[cnt + 1] = (h2o_headers_command_t){H2O_HEADERS_CMD_NULL}; if (*cmds != NULL) h2o_mem_release_shared(*cmds); *cmds = new_cmds; }
static void dispose(h2o_logger_t *_self) { struct st_h2o_access_logger_t *self = (void *)_self; h2o_mem_release_shared(self->fh); }
static int on_config_custom_handler(h2o_configurator_command_t *cmd, h2o_configurator_context_t *ctx, yoml_t *node) { static const char *ignore_commands[] = {"extension", NULL}; struct st_h2o_file_configurator_t *self = (void *)cmd->configurator; h2o_pathconf_t *prev_pathconf = ctx->pathconf; yoml_t *ext_node; h2o_mimemap_type_t *type = NULL; int ret = -1; if (node->type != YOML_TYPE_MAPPING) { h2o_configurator_errprintf(cmd, node, "argument must be a MAPPING"); goto Exit; } if ((ext_node = yoml_get(node, "extension")) == NULL) { h2o_configurator_errprintf(cmd, node, "mandatory key `extension` is missing"); goto Exit; } type = h2o_mimemap_create_dynamic_type(ctx->globalconf); ctx->pathconf = &type->data.dynamic.pathconf; if (h2o_configurator_apply_commands(ctx, node, H2O_CONFIGURATOR_FLAG_EXTENSION, ignore_commands) != 0) goto Exit; switch (type->data.dynamic.pathconf.handlers.size) { case 1: break; case 0: h2o_configurator_errprintf(cmd, node, "no handler declared for given extension"); goto Exit; default: h2o_configurator_errprintf(cmd, node, "cannot assign more than one handler for given extension"); goto Exit; } clone_mimemap_if_clean(self); switch (ext_node->type) { case YOML_TYPE_SCALAR: if (assert_is_extension(cmd, ext_node) != 0) goto Exit; h2o_mimemap_set_type(self->vars->mimemap, ext_node->data.scalar + 1, type, 1); break; case YOML_TYPE_SEQUENCE: { size_t i; for (i = 0; i != ext_node->data.sequence.size; ++i) { yoml_t *n = ext_node->data.sequence.elements[i]; if (assert_is_extension(cmd, n) != 0) goto Exit; h2o_mimemap_set_type(self->vars->mimemap, n->data.scalar + 1, type, 1); } } break; default: h2o_configurator_errprintf(cmd, ext_node, "only scalar or sequence of scalar is permitted at the value part of the argument"); goto Exit; } ret = 0; Exit: if (type != NULL) h2o_mem_release_shared(type); ctx->pathconf = prev_pathconf; return ret; }