void ngx_tcp_upstream_init(ngx_tcp_session_t *s) { ngx_str_t *host; ngx_uint_t i; ngx_connection_t *c; ngx_tcp_cleanup_t *cln; ngx_resolver_ctx_t *ctx, temp; ngx_tcp_upstream_t *u; ngx_tcp_core_srv_conf_t *cscf; ngx_tcp_upstream_srv_conf_t *uscf, **uscfp; ngx_tcp_upstream_main_conf_t *umcf; c = s->connection; cscf = ngx_tcp_get_module_srv_conf(s, ngx_tcp_core_module); ngx_log_debug1(NGX_LOG_DEBUG_TCP, c->log, 0, "tcp init upstream, client timer: %d", c->read->timer_set); if (c->read->timer_set) { ngx_del_timer(c->read); } u = s->upstream; cln = ngx_tcp_cleanup_add(s, 0); cln->handler = ngx_tcp_upstream_cleanup; cln->data = s; u->cleanup = &cln->handler; if (u->resolved == NULL) { uscf = u->conf->upstream; } else { /*TODO: support variable in the proxy_pass*/ if (u->resolved->sockaddr) { if (ngx_tcp_upstream_create_round_robin_peer(s, u->resolved) != NGX_OK) { ngx_tcp_finalize_session(s); return; } ngx_tcp_upstream_connect(s, u); return; } host = &u->resolved->host; umcf = ngx_tcp_get_module_main_conf(s, ngx_tcp_upstream_module); uscfp = umcf->upstreams.elts; for (i = 0; i < umcf->upstreams.nelts; i++) { uscf = uscfp[i]; if (uscf->host.len == host->len && ((uscf->port == 0 && u->resolved->no_port) || uscf->port == u->resolved->port) && ngx_memcmp(uscf->host.data, host->data, host->len) == 0) { goto found; } } temp.name = *host; ctx = ngx_resolve_start(cscf->resolver, &temp); if (ctx == NULL) { ngx_tcp_finalize_session(s); return; } if (ctx == NGX_NO_RESOLVER) { ngx_log_error(NGX_LOG_ERR, c->log, 0, "no resolver defined to resolve %V", host); ngx_tcp_finalize_session(s); return; } ctx->name = *host; ctx->type = NGX_RESOLVE_A; ctx->handler = ngx_tcp_upstream_resolve_handler; ctx->data = s; ctx->timeout = cscf->resolver_timeout; u->resolved->ctx = ctx; if (ngx_resolve_name(ctx) != NGX_OK) { u->resolved->ctx = NULL; ngx_tcp_finalize_session(s); return; } return; } found: if (uscf->peer.init(s, uscf) != NGX_OK) { ngx_tcp_finalize_session(s); return; } ngx_tcp_upstream_connect(s, u); }
ngx_int_t ngx_tcp_lua_process_by_chunk(lua_State *L, ngx_tcp_session_t *s) { int cc_ref; lua_State *cc; ngx_tcp_lua_ctx_t *ctx; ngx_tcp_cleanup_t *cln; dd("content by chunk"); ctx = ngx_tcp_get_module_ctx(s, ngx_tcp_lua_module); if (ctx == NULL) { ctx = ngx_pcalloc(s->pool, sizeof(ngx_tcp_lua_ctx_t)); if (ctx == NULL) { return NGX_ERROR; } dd("setting new ctx, ctx = %p", ctx); ctx->cc_ref = LUA_NOREF; ctx->ctx_ref = LUA_NOREF; ctx->exited = 0; ngx_tcp_set_ctx(s, ctx, ngx_tcp_lua_module); } else { dd("reset ctx"); ngx_tcp_lua_reset_ctx(s, L, ctx); } /* {{{ new coroutine to handle request */ cc = ngx_tcp_lua_new_thread(s, L, &cc_ref); if (cc == NULL) { ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, "(lua-content-by-chunk) failed to create new coroutine " "to handle request"); return NGX_ERROR; } /* move code closure to new coroutine */ lua_xmove(L, cc, 1); /* set closure's env table to new coroutine's globals table */ lua_pushvalue(cc, LUA_GLOBALSINDEX); lua_setfenv(cc, -2); /* save nginx request in coroutine globals table */ lua_pushlightuserdata(cc, &ngx_tcp_lua_request_key); lua_pushlightuserdata(cc, s); lua_rawset(cc, LUA_GLOBALSINDEX); /* }}} */ ctx->co = cc; ctx->cc_ref = cc_ref; /* {{{ register request cleanup hooks */ if (ctx->cleanup == NULL) { cln = ngx_tcp_cleanup_add(s, 0); if (cln == NULL) { return NGX_ERROR; } cln->handler = ngx_tcp_lua_request_cleanup; cln->data = s; ctx->cleanup = &cln->handler; } /* }}} */ return ngx_tcp_lua_run_thread(L, s, ctx, 0); }