static  void
ngx_tcp_proxy_init_upstream(ngx_connection_t *c, ngx_tcp_session_t *s)
{
    ngx_tcp_upstream_t       *u;
    ngx_tcp_proxy_ctx_t      *p;
    ngx_tcp_proxy_conf_t     *pcf;

    s->connection->log->action = "ngx_tcp_proxy_init_upstream";

    pcf = ngx_tcp_get_module_srv_conf(s, ngx_tcp_proxy_module);
    if (pcf->upstream.upstream == NULL) {
        ngx_tcp_finalize_session(s);
        return;
    }

    p = ngx_pcalloc(s->connection->pool, sizeof(ngx_tcp_proxy_ctx_t));
    if (p == NULL) {
        ngx_tcp_finalize_session(s);
        return;
    }

    ngx_tcp_set_ctx(s, p, ngx_tcp_proxy_module);

    if (ngx_tcp_upstream_create(s) != NGX_OK) {
        ngx_tcp_finalize_session(s);
        return;
    }

    u = s->upstream;

    u->conf = &pcf->upstream;

    u->write_event_handler = ngx_tcp_upstream_init_proxy_handler;
    u->read_event_handler = ngx_tcp_upstream_init_proxy_handler;

    p->upstream = &u->peer;

    p->buffer = ngx_create_temp_buf(s->connection->pool, pcf->buffer_size);
    if (p->buffer == NULL) {
        ngx_tcp_finalize_session(s);
        return;
    }

    ngx_tcp_upstream_init(s);

    return;
}
static  void
ngx_tcp_websocket_init_upstream(ngx_connection_t *c, ngx_tcp_session_t *s) 
{
    ngx_tcp_upstream_t           *u;
    ngx_tcp_path_upstream_t      *pu;     
    ngx_tcp_upstream_conf_t      *ucf;
    ngx_tcp_websocket_ctx_t      *wctx;
    ngx_tcp_websocket_conf_t     *wcf;
    ngx_tcp_virtual_server_t     *vs;

    s->connection->log->action = "ngx_tcp_websocket_init_upstream";

    wctx = ngx_tcp_get_module_ctx(s, ngx_tcp_websocket_module);

    vs = ngx_tcp_websocket_find_virtual_server(s, wctx);

    if (vs) {
        s->main_conf = vs->ctx->main_conf;
        s->srv_conf = vs->ctx->srv_conf;
    }

    wcf = ngx_tcp_get_module_srv_conf(s, ngx_tcp_websocket_module);
    if (wcf->upstream.upstream == NULL) {
        ngx_tcp_finalize_session(s);
        return;
    }

    ngx_log_debug3(NGX_LOG_DEBUG_TCP, s->connection->log, 0, 
                   "tcp websocket init upstream, scheme: \"%V\" "
                   "path: \"%V\", host: \"%V\"",
                   &wcf->scheme, &wctx->path, &wctx->host);

    c->write->handler = ngx_tcp_websocket_dummy_write_handler;
    c->read->handler = ngx_tcp_websocket_dummy_read_handler;

    if (ngx_tcp_upstream_create(s) != NGX_OK) {
        ngx_tcp_finalize_session(s);
        return;
    }

    u = s->upstream;

    u->conf = &wcf->upstream;

    pu = ngx_tcp_websocket_find_path_upstream(s, wctx);

    if (pu) {
        ucf = ngx_palloc(s->pool, sizeof(ngx_tcp_upstream_conf_t));
        if (ucf == NULL) {
            ngx_tcp_finalize_session(s);
            return;
        }

        ngx_memcpy(ucf, &wcf->upstream, sizeof(ngx_tcp_upstream_conf_t));

        ucf->upstream = pu->upstream;

        u->conf = ucf;
    }

    u->write_event_handler = ngx_tcp_upstream_websocket_proxy_init_handler;
    u->read_event_handler = ngx_tcp_upstream_websocket_proxy_init_handler;

    wctx->upstream = &u->peer;

    wctx->buffer = ngx_create_temp_buf(s->connection->pool, 
                                       (s->buffer->end - s->buffer->start));
    if (wctx->buffer == NULL) {
        ngx_tcp_finalize_session(s);
        return;
    }

    /* move back to the start position, send the handshake 
     * packet to backend server */
    s->buffer->pos = s->buffer->start;
    s->connection->read->ready = 1;

    ngx_tcp_upstream_init(s);

    return;
}