static void on_context_init(h2o_handler_t *_self, h2o_context_t *ctx) { struct rp_handler_t *self = (void *)_self; /* use the loop of first context for handling socketpool timeouts */ if (self->sockpool != NULL && self->sockpool->timeout == UINT64_MAX) h2o_socketpool_set_timeout(self->sockpool, ctx->loop, self->config.keepalive_timeout); /* setup a specific client context only if we need to */ if (ctx->globalconf->proxy.io_timeout == self->config.io_timeout && !self->config.websocket.enabled && self->config.ssl_ctx == ctx->globalconf->proxy.ssl_ctx) return; h2o_http1client_ctx_t *client_ctx = h2o_mem_alloc(sizeof(*ctx)); client_ctx->loop = ctx->loop; client_ctx->getaddr_receiver = &ctx->receivers.hostinfo_getaddr; if (ctx->globalconf->proxy.io_timeout == self->config.io_timeout) { client_ctx->io_timeout = &ctx->proxy.io_timeout; } else { client_ctx->io_timeout = h2o_mem_alloc(sizeof(*client_ctx->io_timeout)); h2o_timeout_init(client_ctx->loop, client_ctx->io_timeout, self->config.io_timeout); } if (self->config.websocket.enabled) { /* FIXME avoid creating h2o_timeout_t for every path-level context in case the timeout values are the same */ client_ctx->websocket_timeout = h2o_mem_alloc(sizeof(*client_ctx->websocket_timeout)); h2o_timeout_init(client_ctx->loop, client_ctx->websocket_timeout, self->config.websocket.timeout); } else { client_ctx->websocket_timeout = NULL; } client_ctx->ssl_ctx = self->config.ssl_ctx; h2o_context_set_handler_context(ctx, &self->super, client_ctx); }
void h2o_socketpool_set_timeout(h2o_socketpool_t *pool, h2o_loop_t *loop, uint64_t msec) { pool->timeout = msec; pool->_interval_cb.loop = loop; h2o_timeout_init(loop, &pool->_interval_cb.timeout, 1000); pool->_interval_cb.entry.cb = on_timeout; h2o_timeout_link(loop, &pool->_interval_cb.timeout, &pool->_interval_cb.entry); }
void h2o_context_init(h2o_context_t *ctx, h2o_loop_t *loop, h2o_globalconf_t *config) { size_t i; assert(config->hosts.size != 0); memset(ctx, 0, sizeof(*ctx)); ctx->loop = loop; ctx->global_config = config; h2o_timeout_init(ctx->loop, &ctx->zero_timeout, 0); h2o_timeout_init(ctx->loop, &ctx->req_timeout, config->req_timeout); ctx->_module_configs = h2o_malloc(sizeof(*ctx->_module_configs) * config->_num_config_slots); memset(ctx->_module_configs, 0, sizeof(*ctx->_module_configs) * config->_num_config_slots); for (i = 0; i != config->hosts.size; ++i) { h2o_hostconf_t *hostconf = config->hosts.entries + i; on_context_init(ctx, hostconf); } }
void h2o_socketpool_register_loop(h2o_socketpool_t *pool, h2o_loop_t *loop) { if (pool->_interval_cb.loop != NULL) return; pool->_interval_cb.loop = loop; h2o_timeout_init(loop, &pool->_interval_cb.timeout, 1000); pool->_interval_cb.entry.cb = on_timeout; h2o_timeout_link(loop, &pool->_interval_cb.timeout, &pool->_interval_cb.entry); }
int main(int argc, char **argv) { h2o_http1client_ctx_t ctx = { NULL, &zero_timeout, &io_timeout }; if (argc != 2) { fprintf(stderr, "Usage: %s <url>\n", argv[0]); return 1; } url = argv[1]; h2o_mempool_init(&pool); /* setup context */ #if H2O_USE_LIBUV ctx.loop = uv_loop_new(); #else ctx.loop = h2o_evloop_create(); #endif h2o_timeout_init(ctx.loop, &zero_timeout, 0); h2o_timeout_init(ctx.loop, &io_timeout, 5000); /* 5 seconds */ /* setup the first request */ start_request(&ctx); while (cnt_left != 0) { #if H2O_USE_LIBUV uv_run(ctx.loop, UV_RUN_ONCE); #else h2o_evloop_run(ctx.loop); #endif } return 0; }
void h2o_context_init(h2o_context_t *ctx, h2o_loop_t *loop, h2o_globalconf_t *config) { size_t i, j; assert(config->hosts.size != 0); memset(ctx, 0, sizeof(*ctx)); ctx->loop = loop; ctx->globalconf = config; h2o_timeout_init(ctx->loop, &ctx->zero_timeout, 0); h2o_timeout_init(ctx->loop, &ctx->http1.req_timeout, config->http1.req_timeout); h2o_timeout_init(ctx->loop, &ctx->http2.idle_timeout, config->http2.idle_timeout); ctx->_module_configs = h2o_mem_alloc(sizeof(*ctx->_module_configs) * config->_num_config_slots); memset(ctx->_module_configs, 0, sizeof(*ctx->_module_configs) * config->_num_config_slots); for (i = 0; i != config->hosts.size; ++i) { h2o_hostconf_t *hostconf = config->hosts.entries + i; for (j = 0; j != hostconf->paths.size; ++j) { h2o_pathconf_t *pathconf = hostconf->paths.entries + j; on_context_init(ctx, pathconf); } on_context_init(ctx, &hostconf->fallback_path); } }
static void *on_context_init(h2o_handler_t *_self, h2o_context_t *ctx) { struct rp_handler_t *self = (void*)_self; h2o_http1client_ctx_t *client_ctx = h2o_mem_alloc(sizeof(*ctx) + sizeof(*client_ctx->io_timeout)); /* use the loop of first context for handling socketpool timeouts */ if (self->sockpool != NULL && self->sockpool->timeout == UINT64_MAX) h2o_socketpool_set_timeout(self->sockpool, ctx->loop, self->config.keepalive_timeout); client_ctx->loop = ctx->loop; client_ctx->zero_timeout = &ctx->zero_timeout; client_ctx->io_timeout = (void*)(client_ctx + 1); h2o_timeout_init(client_ctx->loop, client_ctx->io_timeout, self->config.io_timeout); /* TODO add a way to configure the variable */ return client_ctx; }
void h2o_context_init(h2o_context_t *ctx, h2o_loop_t *loop, h2o_globalconf_t *config) { size_t i, j; assert(config->hosts[0] != NULL); memset(ctx, 0, sizeof(*ctx)); ctx->loop = loop; ctx->globalconf = config; h2o_timeout_init(ctx->loop, &ctx->zero_timeout, 0); h2o_timeout_init(ctx->loop, &ctx->one_sec_timeout, 1000); h2o_timeout_init(ctx->loop, &ctx->hundred_ms_timeout, 100); ctx->queue = h2o_multithread_create_queue(loop); h2o_multithread_register_receiver(ctx->queue, &ctx->receivers.hostinfo_getaddr, h2o_hostinfo_getaddr_receiver); ctx->filecache = h2o_filecache_create(config->filecache.capacity); h2o_timeout_init(ctx->loop, &ctx->handshake_timeout, config->handshake_timeout); h2o_timeout_init(ctx->loop, &ctx->http1.req_timeout, config->http1.req_timeout); h2o_linklist_init_anchor(&ctx->http1._conns); h2o_timeout_init(ctx->loop, &ctx->http2.idle_timeout, config->http2.idle_timeout); h2o_linklist_init_anchor(&ctx->http2._conns); ctx->proxy.client_ctx.loop = loop; h2o_timeout_init(ctx->loop, &ctx->proxy.io_timeout, config->proxy.io_timeout); ctx->proxy.client_ctx.getaddr_receiver = &ctx->receivers.hostinfo_getaddr; ctx->proxy.client_ctx.io_timeout = &ctx->proxy.io_timeout; ctx->proxy.client_ctx.ssl_ctx = config->proxy.ssl_ctx; ctx->_module_configs = h2o_mem_alloc(sizeof(*ctx->_module_configs) * config->_num_config_slots); memset(ctx->_module_configs, 0, sizeof(*ctx->_module_configs) * config->_num_config_slots); static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_lock(&mutex); for (i = 0; config->hosts[i] != NULL; ++i) { h2o_hostconf_t *hostconf = config->hosts[i]; for (j = 0; j != hostconf->paths.size; ++j) { h2o_pathconf_t *pathconf = hostconf->paths.entries + j; h2o_context_init_pathconf_context(ctx, pathconf); } h2o_context_init_pathconf_context(ctx, &hostconf->fallback_path); } pthread_mutex_unlock(&mutex); }