⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 proxy_util.c

📁 Apache官方在今天放出产品系列2.2的最新版本2.2.11的源码包 最流行的HTTP服务器软件之一
💻 C
📖 第 1 页 / 共 5 页
字号:
    {        worker->cp->conn = conn;    }    /* Always return the SUCCESS */    return APR_SUCCESS;}static void socket_cleanup(proxy_conn_rec *conn){    conn->sock = NULL;    conn->connection = NULL;    apr_pool_clear(conn->scpool);}PROXY_DECLARE(apr_status_t) ap_proxy_ssl_connection_cleanup(proxy_conn_rec *conn,                                                            request_rec *r){    apr_bucket_brigade *bb;    apr_status_t rv;    /*     * If we have an existing SSL connection it might be possible that the     * server sent some SSL message we have not read so far (e.g. a SSL     * shutdown message if the server closed the keepalive connection while     * the connection was held unused in our pool).     * So ensure that if present (=> APR_NONBLOCK_READ) it is read and     * processed. We don't expect any data to be in the returned brigade.     */    if (conn->sock && conn->connection) {        bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);        rv = ap_get_brigade(conn->connection->input_filters, bb,                            AP_MODE_READBYTES, APR_NONBLOCK_READ,                            HUGE_STRING_LEN);        if ((rv != APR_SUCCESS) && !APR_STATUS_IS_EAGAIN(rv)) {            socket_cleanup(conn);        }        if (!APR_BRIGADE_EMPTY(bb)) {            apr_off_t len;            rv = apr_brigade_length(bb, 0, &len);            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r,                          "proxy: SSL cleanup brigade contained %"                          APR_OFF_T_FMT " bytes of data.", len);        }        apr_brigade_destroy(bb);    }    return APR_SUCCESS;}/* reslist constructor */static apr_status_t connection_constructor(void **resource, void *params,                                           apr_pool_t *pool){    apr_pool_t *ctx;    apr_pool_t *scpool;    proxy_conn_rec *conn;    proxy_worker *worker = (proxy_worker *)params;    /*     * Create the subpool for each connection     * This keeps the memory consumption constant     * when disconnecting from backend.     */    apr_pool_create(&ctx, pool);    apr_pool_tag(ctx, "proxy_conn_pool");    /*     * Create another subpool that manages the data for the     * socket and the connection member of the proxy_conn_rec struct as we     * destroy this data more frequently than other data in the proxy_conn_rec     * struct like hostname and addr (at least in the case where we have     * keepalive connections that timed out).     */    apr_pool_create(&scpool, ctx);    apr_pool_tag(scpool, "proxy_conn_scpool");    conn = apr_pcalloc(ctx, sizeof(proxy_conn_rec));    conn->pool   = ctx;    conn->scpool = scpool;    conn->worker = worker;#if APR_HAS_THREADS    conn->inreslist = 1;#endif    *resource = conn;    return APR_SUCCESS;}#if APR_HAS_THREADS /* only needed when threads are used *//* reslist destructor */static apr_status_t connection_destructor(void *resource, void *params,                                          apr_pool_t *pool){    proxy_conn_rec *conn = (proxy_conn_rec *)resource;    /* Destroy the pool only if not called from reslist_destroy */    if (conn->worker->cp->pool) {        apr_pool_destroy(conn->pool);    }    return APR_SUCCESS;}#endif/* * ap_proxy_initialize_worker_share() concerns itself * with initializing those parts of worker which * are, or could be, shared. Basically worker->s */PROXY_DECLARE(void) ap_proxy_initialize_worker_share(proxy_server_conf *conf,                                                     proxy_worker *worker,                                                     server_rec *s){#if PROXY_HAS_SCOREBOARD    lb_score *score = NULL;#else    void *score = NULL;#endif    if (PROXY_WORKER_IS_INITIALIZED(worker)) {        /* The worker share is already initialized */        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,              "proxy: worker %s already initialized",              worker->name);        return;    }#if PROXY_HAS_SCOREBOARD        /* Get scoreboard slot */    if (ap_scoreboard_image) {        score = ap_get_scoreboard_lb(worker->id);        if (!score) {            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,                  "proxy: ap_get_scoreboard_lb(%d) failed in child %" APR_PID_T_FMT " for worker %s",                  worker->id, getpid(), worker->name);        }        else {             ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,                  "proxy: grabbed scoreboard slot %d in child %" APR_PID_T_FMT " for worker %s",                  worker->id, getpid(), worker->name);        }    }#endif    if (!score) {        score = apr_pcalloc(conf->pool, sizeof(proxy_worker_stat));        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,              "proxy: initialized plain memory in child %" APR_PID_T_FMT " for worker %s",              getpid(), worker->name);    }    worker->s = (proxy_worker_stat *)score;    /*     * recheck to see if we've already been here. Possible     * if proxy is using scoreboard to hold shared stats     */    if (PROXY_WORKER_IS_INITIALIZED(worker)) {        /* The worker share is already initialized */        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,              "proxy: worker %s already initialized",              worker->name);        return;    }    if (worker->route) {        strcpy(worker->s->route, worker->route);    }    else {        *worker->s->route = '\0';    }    if (worker->redirect) {        strcpy(worker->s->redirect, worker->redirect);    }    else {        *worker->s->redirect = '\0';    }    worker->s->status |= (worker->status | PROXY_WORKER_INITIALIZED);}PROXY_DECLARE(apr_status_t) ap_proxy_initialize_worker(proxy_worker *worker, server_rec *s){    apr_status_t rv;#if APR_HAS_THREADS    int mpm_threads;#endif    if (worker->status & PROXY_WORKER_INITIALIZED) {        /* The worker is already initialized */        return APR_SUCCESS;    }    /* Set default parameters */    if (!worker->retry_set) {        worker->retry = apr_time_from_sec(PROXY_WORKER_DEFAULT_RETRY);    }    /* By default address is reusable unless DisableReuse is set */    if (worker->disablereuse) {        worker->is_address_reusable = 0;    }    else {        worker->is_address_reusable = 1;    }#if APR_HAS_THREADS    ap_mpm_query(AP_MPMQ_MAX_THREADS, &mpm_threads);    if (mpm_threads > 1) {        /* Set hard max to no more then mpm_threads */        if (worker->hmax == 0 || worker->hmax > mpm_threads) {            worker->hmax = mpm_threads;        }        if (worker->smax == -1 || worker->smax > worker->hmax) {            worker->smax = worker->hmax;        }        /* Set min to be lower then smax */        if (worker->min > worker->smax) {            worker->min = worker->smax;        }    }    else {        /* This will supress the apr_reslist creation */        worker->min = worker->smax = worker->hmax = 0;    }    if (worker->hmax) {        rv = apr_reslist_create(&(worker->cp->res),                                worker->min, worker->smax,                                worker->hmax, worker->ttl,                                connection_constructor, connection_destructor,                                worker, worker->cp->pool);        apr_pool_cleanup_register(worker->cp->pool, (void *)worker,                                  conn_pool_cleanup,                                  apr_pool_cleanup_null);        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,            "proxy: initialized worker %d in child %" APR_PID_T_FMT " for (%s) min=%d max=%d smax=%d",             worker->id, getpid(), worker->hostname, worker->min,             worker->hmax, worker->smax);#if (APR_MAJOR_VERSION > 0)        /* Set the acquire timeout */        if (rv == APR_SUCCESS && worker->acquire_set) {            apr_reslist_timeout_set(worker->cp->res, worker->acquire);        }#endif    }    else#endif    {        rv = connection_constructor((void **)&(worker->cp->conn), worker, worker->cp->pool);        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,             "proxy: initialized single connection worker %d in child %" APR_PID_T_FMT " for (%s)",             worker->id, getpid(), worker->hostname);    }    if (rv == APR_SUCCESS) {        worker->status |= (PROXY_WORKER_INITIALIZED);    }    return rv;}PROXY_DECLARE(int) ap_proxy_retry_worker(const char *proxy_function,                                         proxy_worker *worker,                                         server_rec *s){    if (worker->s->status & PROXY_WORKER_IN_ERROR) {        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,                    "proxy: %s: retrying the worker for (%s)",                     proxy_function, worker->hostname);        if (apr_time_now() > worker->s->error_time + worker->retry) {            ++worker->s->retries;            worker->s->status &= ~PROXY_WORKER_IN_ERROR;            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,                         "proxy: %s: worker for (%s) has been marked for retry",                         proxy_function, worker->hostname);            return OK;        }        else {            return DECLINED;        }    }    else {        return OK;    }}PROXY_DECLARE(int) ap_proxy_acquire_connection(const char *proxy_function,                                               proxy_conn_rec **conn,                                               proxy_worker *worker,                                               server_rec *s){    apr_status_t rv;    if (!PROXY_WORKER_IS_USABLE(worker)) {        /* Retry the worker */        ap_proxy_retry_worker(proxy_function, worker, s);        if (!PROXY_WORKER_IS_USABLE(worker)) {            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,                         "proxy: %s: disabled connection for (%s)",                         proxy_function, worker->hostname);            return HTTP_SERVICE_UNAVAILABLE;        }    }#if APR_HAS_THREADS    if (worker->hmax && worker->cp->res) {        rv = apr_reslist_acquire(worker->cp->res, (void **)conn);    }    else#endif    {        /* create the new connection if the previous was destroyed */        if (!worker->cp->conn) {            connection_constructor((void **)conn, worker, worker->cp->pool);        }        else {            *conn = worker->cp->conn;            worker->cp->conn = NULL;        }        rv = APR_SUCCESS;    }    if (rv != APR_SUCCESS) {        ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,                     "proxy: %s: failed to acquire connection for (%s)",                     proxy_function, worker->hostname);        return HTTP_SERVICE_UNAVAILABLE;    }    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,                 "proxy: %s: has acquired connection for (%s)",                 proxy_function, worker->hostname);    (*conn)->worker = worker;    (*conn)->close  = 0;    (*conn)->close_on_recycle = 0;#if APR_HAS_THREADS    (*conn)->inreslist = 0;#endif    return OK;}PROXY_DECLARE(int) ap_proxy_release_connection(const char *proxy_function,                                               proxy_conn_rec *conn,                                               server_rec *s){    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,                 "proxy: %s: has released connection for (%s)",                 proxy_function, conn->worker->hostname);    connection_cleanup(conn);    return OK;}PROXY_DECLARE(int)ap_proxy_determine_connection(apr_pool_t *p, request_rec *r,                              proxy_server_conf *conf,                              proxy_worker *worker,                              proxy_conn_rec *conn,                              apr_uri_t *uri,                              char **url,                              const char *proxyname,                              apr_port_t proxyport,                              char *server_portstr,                              int server_portstr_size){    int server_port;    apr_status_t err = APR_SUCCESS;    apr_status_t uerr = APR_SUCCESS;    /*     * Break up the URL to determine the host to connect to     */    /* we break the URL into host, port, uri */    if (APR_SUCCESS != apr_uri_parse(p, *url, uri)) {        return ap_proxyerror(r, HTTP_BAD_REQUEST,                             apr_pstrcat(p,"URI cannot be parsed: ", *url,                                         NULL));    }    if (!uri->port) {        uri->port = apr_uri_port_of_scheme(uri->scheme);    }    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,                 "proxy: connecting %s to %s:%d", *url, uri->hostname,                 uri->port);    /*     * allocate these out of the specified connection pool     * The scheme handler decides if this is permanent or     * short living pool.     */    /* are we connecting directly, or via a proxy? */    if (!proxyname) {        *url = apr_pstrcat(p, uri->path, uri->query ? "?" : "",                           uri->query ? uri->query : "",                           uri->fragment ? "#" : "",                           uri->fragment ? uri->fragment : "", NULL);    }    /*     * Make sure that we pick the the correct and valid worker.     * If a single keepalive connection triggers different workers,     * then we have a problem (we don't select the correct one).     * Do an expensive check in this case, where we compare the     * the hostnames associated between the two.     *     * TODO: Handle this much better...     */    if (!conn->hostname || !worker->is_address_reusable ||          worker->disablereuse ||         (r->connection->keepalives &&         (r->proxyreq == PROXYREQ_PROXY || r->proxyreq == PROXYREQ_REVERSE) &&         (strcasecmp(conn->hostname, uri->hostname) != 0) ) ) {        if (proxyname) {            conn->hostname = apr_pstrdup(conn->pool,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -