Exemple #1
0
static h2o_hostconf_t *create_hostconf(h2o_globalconf_t *globalconf)
{
    h2o_hostconf_t *hostconf = h2o_mem_alloc(sizeof(*hostconf));
    *hostconf = (h2o_hostconf_t){globalconf};
    h2o_config_init_pathconf(&hostconf->fallback_path, globalconf, NULL, globalconf->mimemap);
    hostconf->mimemap = globalconf->mimemap;
    h2o_mem_addref_shared(hostconf->mimemap);
    return hostconf;
}
Exemple #2
0
static int on_config_enter(h2o_configurator_t *_self, h2o_configurator_context_t *ctx, yoml_t *node)
{
    struct st_h2o_file_configurator_t *self = (void *)_self;
    ++self->vars;
    self->vars[0].index_files = dup_strlist(self->vars[-1].index_files);
    self->vars[0].mimemap = self->vars[-1].mimemap;
    self->vars[0].flags = self->vars[-1].flags;
    h2o_mem_addref_shared(self->vars[0].mimemap);
    return 0;
}
Exemple #3
0
void h2o_config_init_pathconf(h2o_pathconf_t *pathconf, h2o_globalconf_t *globalconf, const char *path, h2o_mimemap_t *mimemap)
{
    memset(pathconf, 0, sizeof(*pathconf));
    pathconf->global = globalconf;
    h2o_chunked_register(pathconf);
    if (path != NULL)
        pathconf->path = h2o_strdup_slashed(NULL, path, SIZE_MAX);
    h2o_mem_addref_shared(mimemap);
    pathconf->mimemap = mimemap;
}
Exemple #4
0
static h2o_hostconf_t *create_hostconf(h2o_globalconf_t *globalconf)
{
    h2o_hostconf_t *hostconf = h2o_mem_alloc(sizeof(*hostconf));
    *hostconf = (h2o_hostconf_t){globalconf};
    hostconf->http2.push_preload = 1; /* enabled by default */
    h2o_config_init_pathconf(&hostconf->fallback_path, globalconf, NULL, globalconf->mimemap);
    hostconf->mimemap = globalconf->mimemap;
    h2o_mem_addref_shared(hostconf->mimemap);
    return hostconf;
}
Exemple #5
0
void h2o_config_init_pathconf(h2o_pathconf_t *pathconf, h2o_globalconf_t *globalconf, const char *path, h2o_mimemap_t *mimemap)
{
    memset(pathconf, 0, sizeof(*pathconf));
    pathconf->global = globalconf;
    if (path != NULL)
        pathconf->path = h2o_strdup(NULL, path, SIZE_MAX);
    h2o_mem_addref_shared(mimemap);
    pathconf->mimemap = mimemap;
    pathconf->error_log.emit_request_errors = 1;
}
Exemple #6
0
h2o_logger_t *h2o_access_log_register(h2o_pathconf_t *pathconf, h2o_access_log_filehandle_t *fh)
{
    struct st_h2o_access_logger_t *self = (void *)h2o_create_logger(pathconf, sizeof(*self));

    self->super.dispose = dispose;
    self->super.log_access = log_access;
    self->fh = fh;
    h2o_mem_addref_shared(fh);

    return &self->super;
}
Exemple #7
0
h2o_envconf_t *h2o_config_create_envconf(h2o_envconf_t *parent)
{
    h2o_envconf_t *envconf = h2o_mem_alloc_shared(NULL, sizeof(*envconf), on_dispose_envconf);
    *envconf = (h2o_envconf_t){NULL};

    if (parent != NULL) {
        envconf->parent = parent;
        h2o_mem_addref_shared(parent);
    }
    return envconf;
}
Exemple #8
0
static h2o_configurator_context_t *create_context(h2o_configurator_context_t *parent, int is_custom_handler)
{
    h2o_configurator_context_t *ctx = h2o_mem_alloc(sizeof(*ctx));
    if (parent == NULL) {
        *ctx = (h2o_configurator_context_t){};
        return ctx;
    }
    *ctx = *parent;
    if (ctx->env != NULL)
        h2o_mem_addref_shared(ctx->env);
    ctx->parent = parent;
    return ctx;
}
Exemple #9
0
h2o_handler_t *h2o_file_register_file(h2o_pathconf_t *pathconf, const char *real_path, h2o_mimemap_type_t *mime_type, int flags)
{
    struct st_h2o_specific_file_handler_t *self = (void *)h2o_create_handler(pathconf, sizeof(*self));

    self->super.on_context_init = specific_handler_on_context_init;
    self->super.on_context_dispose = specific_handler_on_context_dispose;
    self->super.dispose = specific_handler_on_dispose;
    self->super.on_req = specific_handler_on_req;

    self->real_path = h2o_strdup(NULL, real_path, SIZE_MAX);
    h2o_mem_addref_shared(mime_type);
    self->mime_type = mime_type;
    self->flags = flags;

    return &self->super;
}
Exemple #10
0
static int on_config_enter(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;

    /* push the stack pointer */
    ++self->handles;

    /* link the handles */
    memset(self->handles, 0, sizeof(*self->handles));
    h2o_vector_reserve(NULL, (void*)self->handles, sizeof(self->handles->entries[0]), self->handles[-1].size + 1);
    for (i = 0; i != self->handles[-1].size; ++i) {
        h2o_access_log_filehandle_t *fh = self->handles[-1].entries[i];
        self->handles[0].entries[self->handles[0].size++] = fh;
        h2o_mem_addref_shared(fh);
    }

    return 0;
}
Exemple #11
0
h2o_file_handler_t *h2o_file_register(h2o_pathconf_t *pathconf, const char *real_path, const char **index_files,
                                      h2o_mimemap_t *mimemap, int flags)
{
    h2o_file_handler_t *self;
    size_t i;

    if (index_files == NULL)
        index_files = default_index_files;

    /* allocate memory */
    for (i = 0; index_files[i] != NULL; ++i)
        ;
    self =
        (void *)h2o_create_handler(pathconf, offsetof(h2o_file_handler_t, index_files[0]) + sizeof(self->index_files[0]) * (i + 1));

    /* setup callbacks */
    self->super.on_context_init = on_context_init;
    self->super.on_context_dispose = on_context_dispose;
    self->super.dispose = on_dispose;
    self->super.on_req = on_req;

    /* setup attributes */
    self->conf_path = h2o_strdup_slashed(NULL, pathconf->path.base, pathconf->path.len);
    self->real_path = h2o_strdup_slashed(NULL, real_path, SIZE_MAX);
    if (mimemap != NULL) {
        h2o_mem_addref_shared(mimemap);
        self->mimemap = mimemap;
    } else {
        self->mimemap = h2o_mimemap_create();
    }
    self->flags = flags;
    for (i = 0; index_files[i] != NULL; ++i) {
        self->index_files[i] = h2o_strdup(NULL, index_files[i], SIZE_MAX);
        if (self->max_index_file_len < self->index_files[i].len)
            self->max_index_file_len = self->index_files[i].len;
    }

    return self;
}
static void do_updates(multiple_query_ctx_t *query_ctx)
{
	thread_context_t * const ctx = H2O_STRUCT_FROM_MEMBER(thread_context_t,
	                                                      event_loop.h2o_ctx,
	                                                      query_ctx->req->conn->ctx);
	char *iter = (char *) (query_ctx->query_param + 1);
	size_t sz = MAX_UPDATE_QUERY_LEN(query_ctx->num_result);

	// Sort the results to avoid database deadlock.
	qsort(query_ctx->res, query_ctx->num_result, sizeof(*query_ctx->res), compare_items);
	query_ctx->query_param->param.command = iter;
	query_ctx->query_param->param.nParams = 0;
	query_ctx->query_param->param.on_result = on_update_result;
	query_ctx->query_param->param.paramFormats = NULL;
	query_ctx->query_param->param.paramLengths = NULL;
	query_ctx->query_param->param.paramValues = NULL;
	query_ctx->query_param->param.flags = 0;
	query_ctx->res->random_number = get_random_number(MAX_ID, &ctx->random_seed) + 1;

	int c = snprintf(iter,
	                 sz,
	                 UPDATE_QUERY_BEGIN,
	                 query_ctx->res->id,
	                 query_ctx->res->random_number);

	if ((size_t) c >= sz)
		goto error;

	iter += c;
	sz -= c;

	for (size_t i = 1; i < query_ctx->num_result; i++) {
		query_ctx->res[i].random_number = get_random_number(MAX_ID, &ctx->random_seed) + 1;
		c = snprintf(iter,
		             sz,
		             UPDATE_QUERY_ELEM,
		             query_ctx->res[i].id,
		             query_ctx->res[i].random_number);

		if ((size_t) c >= sz)
			goto error;

		iter += c;
		sz -= c;
	}

	c = snprintf(iter, sz, UPDATE_QUERY_END);

	if ((size_t) c >= sz)
		goto error;

	if (execute_query(ctx, &query_ctx->query_param->param))
		send_service_unavailable_error(DB_REQ_ERROR, query_ctx->req);
	else {
		query_ctx->num_query_in_progress++;
		h2o_mem_addref_shared(query_ctx);
	}

	return;
error:
	LIBRARY_ERROR("snprintf", "Truncated output.");
	send_error(INTERNAL_SERVER_ERROR, REQ_ERROR, query_ctx->req);
}
static int do_multiple_queries(bool do_update, bool use_cache, h2o_req_t *req)
{
	thread_context_t * const ctx = H2O_STRUCT_FROM_MEMBER(thread_context_t,
	                                                      event_loop.h2o_ctx,
	                                                      req->conn->ctx);

	const size_t num_query = get_query_number(req);

	// MAX_QUERIES is a relatively small number, so assume no overflow in the following
	// arithmetic operations.
	assert(num_query <= MAX_QUERIES);

	size_t base_size = offsetof(multiple_query_ctx_t, res) + num_query * sizeof(query_result_t);

	base_size = ((base_size + _Alignof(query_param_t) - 1) / _Alignof(query_param_t));
	base_size = base_size * _Alignof(query_param_t);

	const size_t num_query_in_progress = MIN(num_query, ctx->config->max_db_conn_num);
	size_t sz = base_size + num_query_in_progress * sizeof(query_param_t);

	if (do_update) {
		const size_t reuse_size = (num_query_in_progress - 1) * sizeof(query_param_t);
		const size_t update_query_len = MAX_UPDATE_QUERY_LEN(num_query);

		if (update_query_len > reuse_size)
			sz += update_query_len - reuse_size;
	}

	multiple_query_ctx_t * const query_ctx = h2o_mem_alloc_shared(&req->pool,
	                                                              sz,
	                                                              cleanup_multiple_query);

	if (query_ctx) {
		memset(query_ctx, 0, sz);
		query_ctx->num_query = num_query;
		query_ctx->req = req;
		query_ctx->do_update = do_update;
		query_ctx->use_cache = use_cache;
		query_ctx->query_param = (query_param_t *) ((char *) query_ctx + base_size);
		initialize_ids(num_query, query_ctx->res, &ctx->random_seed);

		if (use_cache) {
			fetch_from_cache(h2o_now(ctx->event_loop.h2o_ctx.loop),
			                 ctx->global_data->world_cache,
			                 query_ctx);

			if (query_ctx->num_result == query_ctx->num_query) {
				complete_multiple_query(query_ctx);
				return 0;
			}
		}

		query_ctx->num_query_in_progress = MIN(num_query_in_progress,
		                                       query_ctx->num_query - query_ctx->num_result);

		for (size_t i = 0; i < query_ctx->num_query_in_progress; i++) {
			query_ctx->query_param[i].ctx = query_ctx;
			// We need a copy of id because the original may be overwritten
			// by a completed query.
			query_ctx->query_param[i].id = htonl(query_ctx->res[query_ctx->num_result + i].id);
			query_ctx->query_param[i].id_format = 1;
			query_ctx->query_param[i].id_len = sizeof(query_ctx->query_param[i].id);
			query_ctx->query_param[i].id_pointer = (const char *) &query_ctx->query_param[i].id;
			query_ctx->query_param[i].param.command = WORLD_TABLE_NAME;
			query_ctx->query_param[i].param.nParams = 1;
			query_ctx->query_param[i].param.on_error = on_multiple_query_error;
			query_ctx->query_param[i].param.on_result = on_multiple_query_result;
			query_ctx->query_param[i].param.on_timeout = on_multiple_query_timeout;
			query_ctx->query_param[i].param.paramFormats = &query_ctx->query_param[i].id_format;
			query_ctx->query_param[i].param.paramLengths = &query_ctx->query_param[i].id_len;
			query_ctx->query_param[i].param.paramValues = &query_ctx->query_param[i].id_pointer;
			query_ctx->query_param[i].param.flags = IS_PREPARED;
			query_ctx->query_param[i].param.resultFormat = 1;

			if (execute_query(ctx, &query_ctx->query_param[i].param)) {
				query_ctx->num_query_in_progress = i;
				query_ctx->error = true;
				send_service_unavailable_error(DB_REQ_ERROR, req);
				return 0;
			}

			h2o_mem_addref_shared(query_ctx);
		}
	}
	else
		send_error(INTERNAL_SERVER_ERROR, REQ_ERROR, req);

	return 0;
}
Exemple #14
0
void h2o_mem_link_shared(h2o_mem_pool_t *pool, void *p)
{
    h2o_mem_addref_shared(p);
    link_shared(pool, H2O_STRUCT_FROM_MEMBER(struct st_h2o_mem_pool_shared_entry_t, bytes, p));
}