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

📄 mod_proxy.c

📁 Apache官方在今天放出产品系列2.2的最新版本2.2.11的源码包 最流行的HTTP服务器软件之一
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements.  See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License.  You may obtain a copy of the License at * *     http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */#define CORE_PRIVATE#include "mod_proxy.h"#include "mod_core.h"#include "apr_optional.h"#include "scoreboard.h"#include "mod_status.h"#if (MODULE_MAGIC_NUMBER_MAJOR > 20020903)#include "mod_ssl.h"#elseAPR_DECLARE_OPTIONAL_FN(int, ssl_proxy_enable, (conn_rec *));APR_DECLARE_OPTIONAL_FN(int, ssl_engine_disable, (conn_rec *));APR_DECLARE_OPTIONAL_FN(int, ssl_is_https, (conn_rec *));APR_DECLARE_OPTIONAL_FN(char *, ssl_var_lookup,                        (apr_pool_t *, server_rec *,                         conn_rec *, request_rec *, char *));#endif#ifndef MAX#define MAX(x,y) ((x) >= (y) ? (x) : (y))#endif/* * A Web proxy module. Stages: * *  translate_name: set filename to proxy:<URL> *  map_to_storage: run proxy_walk (rather than directory_walk/file_walk) *                  can't trust directory_walk/file_walk since these are *                  not in our filesystem.  Prevents mod_http from serving *                  the TRACE request we will set aside to handle later. *  type_checker:   set type to PROXY_MAGIC_TYPE if filename begins proxy: *  fix_ups:        convert the URL stored in the filename to the *                  canonical form. *  handler:        handle proxy requests *//* -------------------------------------------------------------- *//* Translate the URL into a 'filename' */#define PROXY_COPY_CONF_PARAMS(w, c) \    do {                             \        (w)->timeout              = (c)->timeout;               \        (w)->timeout_set          = (c)->timeout_set;           \        (w)->recv_buffer_size     = (c)->recv_buffer_size;      \        (w)->recv_buffer_size_set = (c)->recv_buffer_size_set;  \        (w)->io_buffer_size       = (c)->io_buffer_size;        \        (w)->io_buffer_size_set   = (c)->io_buffer_size_set;    \    } while (0)static const char *set_worker_param(apr_pool_t *p,                                    proxy_worker *worker,                                    const char *key,                                    const char *val){    int ival;    apr_interval_time_t timeout;    if (!strcasecmp(key, "loadfactor")) {        /* Normalized load factor. Used with BalancerMamber,         * it is a number between 1 and 100.         */        worker->lbfactor = atoi(val);        if (worker->lbfactor < 1 || worker->lbfactor > 100)            return "LoadFactor must be number between 1..100";    }    else if (!strcasecmp(key, "retry")) {        /* If set it will give the retry timeout for the worker         * The default value is 60 seconds, meaning that if         * in error state, it will be retried after that timeout.         */        ival = atoi(val);        if (ival < 0)            return "Retry must be a positive value";        worker->retry = apr_time_from_sec(ival);        worker->retry_set = 1;    }    else if (!strcasecmp(key, "ttl")) {        /* Time in seconds that will destroy all the connections         * that exceed the smax         */        ival = atoi(val);        if (ival < 1)            return "TTL must be at least one second";        worker->ttl = apr_time_from_sec(ival);    }    else if (!strcasecmp(key, "min")) {        /* Initial number of connections to remote         */        ival = atoi(val);        if (ival < 0)            return "Min must be a positive number";        worker->min = ival;    }    else if (!strcasecmp(key, "max")) {        /* Maximum number of connections to remote         */        ival = atoi(val);        if (ival < 0)            return "Max must be a positive number";        worker->hmax = ival;    }    /* XXX: More inteligent naming needed */    else if (!strcasecmp(key, "smax")) {        /* Maximum number of connections to remote that         * will not be destroyed         */        ival = atoi(val);        if (ival < 0)            return "Smax must be a positive number";        worker->smax = ival;    }    else if (!strcasecmp(key, "acquire")) {        /* Acquire in given unit (default is milliseconds).         * If set this will be the maximum time to         * wait for a free connection.         */        if (ap_timeout_parameter_parse(val, &timeout, "ms") != APR_SUCCESS)            return "Acquire timeout has wrong format";        if (timeout < 1000)            return "Acquire must be at least one millisecond";        worker->acquire = timeout;        worker->acquire_set = 1;    }    else if (!strcasecmp(key, "timeout")) {        /* Connection timeout in seconds.         * Defaults to server timeout.         */        ival = atoi(val);        if (ival < 1)            return "Timeout must be at least one second";        worker->timeout = apr_time_from_sec(ival);        worker->timeout_set = 1;    }    else if (!strcasecmp(key, "iobuffersize")) {        long s = atol(val);        worker->io_buffer_size = ((s > AP_IOBUFSIZE) ? s : AP_IOBUFSIZE);        worker->io_buffer_size_set = 1;    }    else if (!strcasecmp(key, "receivebuffersize")) {        ival = atoi(val);        if (ival < 512 && ival != 0) {            return "ReceiveBufferSize must be >= 512 bytes, or 0 for system default.";        }        worker->recv_buffer_size = ival;        worker->recv_buffer_size_set = 1;    }    else if (!strcasecmp(key, "keepalive")) {        if (!strcasecmp(val, "on"))            worker->keepalive = 1;        else if (!strcasecmp(val, "off"))            worker->keepalive = 0;        else            return "KeepAlive must be On|Off";        worker->keepalive_set = 1;    }    else if (!strcasecmp(key, "disablereuse")) {        if (!strcasecmp(val, "on"))            worker->disablereuse = 1;        else if (!strcasecmp(val, "off"))            worker->disablereuse = 0;        else            return "DisableReuse must be On|Off";        worker->disablereuse_set = 1;    }    else if (!strcasecmp(key, "route")) {        /* Worker route.         */        if (strlen(val) > PROXY_WORKER_MAX_ROUTE_SIZ)            return "Route length must be < 64 characters";        worker->route = apr_pstrdup(p, val);    }    else if (!strcasecmp(key, "redirect")) {        /* Worker redirection route.         */        if (strlen(val) > PROXY_WORKER_MAX_ROUTE_SIZ)            return "Redirect length must be < 64 characters";        worker->redirect = apr_pstrdup(p, val);    }    else if (!strcasecmp(key, "status")) {        const char *v;        int mode = 1;        /* Worker status.         */        for (v = val; *v; v++) {            if (*v == '+') {                mode = 1;                v++;            }            else if (*v == '-') {                mode = 0;                v++;            }            if (*v == 'D' || *v == 'd') {                if (mode)                    worker->status |= PROXY_WORKER_DISABLED;                else                    worker->status &= ~PROXY_WORKER_DISABLED;            }            else if (*v == 'S' || *v == 's') {                if (mode)                    worker->status |= PROXY_WORKER_STOPPED;                else                    worker->status &= ~PROXY_WORKER_STOPPED;            }            else if (*v == 'E' || *v == 'e') {                if (mode)                    worker->status |= PROXY_WORKER_IN_ERROR;                else                    worker->status &= ~PROXY_WORKER_IN_ERROR;            }            else if (*v == 'H' || *v == 'h') {                if (mode)                    worker->status |= PROXY_WORKER_HOT_STANDBY;                else                    worker->status &= ~PROXY_WORKER_HOT_STANDBY;            }            else if (*v == 'I' || *v == 'i') {                if (mode)                    worker->status |= PROXY_WORKER_IGNORE_ERRORS;                else                    worker->status &= ~PROXY_WORKER_IGNORE_ERRORS;            }            else {                return "Unknown status parameter option";            }        }    }    else if (!strcasecmp(key, "flushpackets")) {        if (!strcasecmp(val, "on"))            worker->flush_packets = flush_on;        else if (!strcasecmp(val, "off"))            worker->flush_packets = flush_off;        else if (!strcasecmp(val, "auto"))            worker->flush_packets = flush_auto;        else            return "flushpackets must be on|off|auto";    }    else if (!strcasecmp(key, "flushwait")) {        ival = atoi(val);        if (ival > 1000 || ival < 0) {            return "flushwait must be <= 1000, or 0 for system default of 10 millseconds.";        }        if (ival == 0)            worker->flush_wait = PROXY_FLUSH_WAIT;        else            worker->flush_wait = ival * 1000;    /* change to microseconds */    }    else if (!strcasecmp(key, "lbset")) {        ival = atoi(val);        if (ival < 0 || ival > 99)            return "lbset must be between 0 and 99";        worker->lbset = ival;    }    else if (!strcasecmp(key, "ping")) {        /* Ping/Pong timeout in given unit (default is second).         */        if (ap_timeout_parameter_parse(val, &timeout, "s") != APR_SUCCESS)            return "Ping/Pong timeout has wrong format";        if (timeout < 1000)            return "Ping/Pong timeout must be at least one millisecond";        worker->ping_timeout = timeout;        worker->ping_timeout_set = 1;    }    else if (!strcasecmp(key, "connectiontimeout")) {        /* Request timeout in given unit (default is second).         * Defaults to connection timeout         */        if (ap_timeout_parameter_parse(val, &timeout, "s") != APR_SUCCESS)            return "Connectiontimeout has wrong format";        if (timeout < 1000)            return "Connectiontimeout must be at least one millisecond.";        worker->conn_timeout = timeout;        worker->conn_timeout_set = 1;    }    else {        return "unknown Worker parameter";    }    return NULL;}static const char *set_balancer_param(proxy_server_conf *conf,                                      apr_pool_t *p,                                      proxy_balancer *balancer,                                      const char *key,                                      const char *val){    int ival;    if (!strcasecmp(key, "stickysession")) {        /* Balancer sticky session name.         * Set to something like JSESSIONID or         * PHPSESSIONID, etc..,         */        balancer->sticky = apr_pstrdup(p, val);    }    else if (!strcasecmp(key, "nofailover")) {        /* If set to 'on' the session will break         * if the worker is in error state or         * disabled.         */        if (!strcasecmp(val, "on"))            balancer->sticky_force = 1;        else if (!strcasecmp(val, "off"))            balancer->sticky_force = 0;        else            return "failover must be On|Off";    }    else if (!strcasecmp(key, "timeout")) {        /* Balancer timeout in seconds.         * If set this will be the maximum time to         * wait for a free worker.         * Default is not to wait.         */        ival = atoi(val);        if (ival < 1)            return "timeout must be at least one second";        balancer->timeout = apr_time_from_sec(ival);    }    else if (!strcasecmp(key, "maxattempts")) {        /* Maximum number of failover attempts before         * giving up.         */        ival = atoi(val);        if (ival < 0)            return "maximum number of attempts must be a positive number";        balancer->max_attempts = ival;        balancer->max_attempts_set = 1;    }    else if (!strcasecmp(key, "lbmethod")) {        proxy_balancer_method *provider;        provider = ap_lookup_provider(PROXY_LBMETHOD, val, "0");        if (provider) {            balancer->lbmethod = provider;            return NULL;        }        return "unknown lbmethod";    }    else if (!strcasecmp(key, "scolonpathdelim")) {        /* If set to 'on' then ';' will also be         * used as a session path separator/delim (ala         * mod_jk)         */        if (!strcasecmp(val, "on"))            balancer->scolonsep = 1;        else if (!strcasecmp(val, "off"))            balancer->scolonsep = 0;        else            return "scolonpathdelim must be On|Off";    }    else {        return "unknown Balancer parameter";

⌨️ 快捷键说明

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