Exemple #1
0
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);
}
Exemple #2
0
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);
    });
Exemple #3
0
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);
    });
Exemple #4
0
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);
}
Exemple #5
0
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;
}
Exemple #6
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);
}
Exemple #7
0
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);
}
Exemple #8
0
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);
}
Exemple #9
0
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;
}
Exemple #10
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);
}
Exemple #11
0
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;
}
Exemple #12
0
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);
}
Exemple #13
0
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);
}
Exemple #14
0
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);
}
Exemple #15
0
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);
}
Exemple #16
0
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);
    }
}
Exemple #17
0
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;
}
Exemple #18
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;
}
Exemple #19
0
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;
}
Exemple #20
0
static void dispose(h2o_logger_t *_self)
{
    struct st_h2o_access_logger_t *self = (void *)_self;

    h2o_mem_release_shared(self->fh);
}
Exemple #21
0
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;
}