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); }
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; }
static void start_request(h2o_http1client_ctx_t *ctx) { char *scheme, *host, *path; uint16_t port; h2o_iovec_t *req; h2o_http1client_t *client; /* clear memory pool */ h2o_mempool_clear(&pool); /* parse URL */ if (h2o_parse_url(&pool, url, &scheme, &host, &port, &path) != 0) { fprintf(stderr, "unrecognized type of URL: %s\n", url); exit(1); } if (strcmp(scheme, "https") == 0) { fprintf(stderr, "https is not (yet) supported\n"); exit(1); } /* build request */ req = h2o_mempool_alloc(&pool, sizeof(*req)); req->base = h2o_mempool_alloc(&pool, 1024); req->len = snprintf(req->base, 1024, "GET %s HTTP/1.1\r\nhost: %s:%u\r\n\r\n", path, host, (unsigned)port); assert(req->len < 1024); /* initiate the request */ if (1) { if (sockpool == NULL) { sockpool = h2o_malloc(sizeof(*sockpool)); h2o_socketpool_init(sockpool, host, port, 10); h2o_socketpool_set_timeout(sockpool, ctx->loop, 5000 /* in msec */); } client = h2o_http1client_connect_with_pool(ctx, &pool, sockpool, on_connect); } else { client = h2o_http1client_connect(ctx, &pool, host, port, on_connect); } assert(client != NULL); client->data = req; }