/* 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.
 */
#include "mod_proxy.h"
#include "mod_watchdog.h"
#include "ap_slotmem.h"
#include "ap_expr.h"
#if APR_HAS_THREADS
#include "apr_thread_pool.h"
#endif
#include "http_ssl.h"

module AP_MODULE_DECLARE_DATA proxy_hcheck_module;

#define HCHECK_WATHCHDOG_NAME ("_proxy_hcheck_")
#define HC_THREADPOOL_SIZE (16)

/* Why? So we can easily set/clear HC_USE_THREADS during dev testing */
#if APR_HAS_THREADS
#ifndef HC_USE_THREADS
#define HC_USE_THREADS 1
#endif
#else
#define HC_USE_THREADS 0
#endif

typedef struct {
    char *name;
    hcmethod_t method;
    int passes;
    int fails;
    apr_interval_time_t interval;
    char *hurl;
    char *hcexpr;
} hc_template_t;

typedef struct {
    char *expr;
    ap_expr_info_t *pexpr;       /* parsed expression */
} hc_condition_t;

typedef struct {
    apr_pool_t *p;
    apr_array_header_t *templates;
    apr_table_t *conditions;
    apr_hash_t *hcworkers;
    server_rec *s;
} sctx_t;

/* Used in the HC worker via the context field */
typedef struct {
    const char *path;   /* The path of the original worker URL */
    const char *method; /* Method string for the HTTP/AJP request */
    const char *req;    /* pre-formatted HTTP/AJP request */
    proxy_worker *w;    /* Pointer to the actual worker */
    const char *protocol; /* HTTP 1.0 or 1.1? */
} wctx_t;

typedef struct {
    apr_pool_t *ptemp;
    sctx_t *ctx;
    proxy_balancer *balancer;
    proxy_worker *worker;
    proxy_worker *hc;
    apr_time_t *now;
} baton_t;

static APR_OPTIONAL_FN_TYPE(ajp_handle_cping_cpong) *ajp_handle_cping_cpong = NULL;

static void *hc_create_config(apr_pool_t *p, server_rec *s)
{
    sctx_t *ctx = apr_pcalloc(p, sizeof(sctx_t));
    ctx->s = s;
    apr_pool_create(&ctx->p, p);
    apr_pool_tag(ctx->p, "proxy_hcheck");
    ctx->templates = apr_array_make(p, 10, sizeof(hc_template_t));
    ctx->conditions = apr_table_make(p, 10);
    ctx->hcworkers = apr_hash_make(p);
    return ctx;
}

static ap_watchdog_t *watchdog;
#if HC_USE_THREADS
static apr_thread_pool_t *hctp;
static int tpsize;
#endif

/*
 * This serves double duty by not only validating (and creating)
 * the health-check template, but also ties into set_worker_param()
 * which does the actual setting of worker params in shm.
 */
static const char *set_worker_hc_param(apr_pool_t *p,
                                    server_rec *s,
                                    proxy_worker *worker,
                                    const char *key,
                                    const char *val,
                                    void *v)
{
    int ival;
    hc_template_t *temp;
    sctx_t *ctx = (sctx_t *) ap_get_module_config(s->module_config,
                                                  &proxy_hcheck_module);
    if (!worker && !v) {
        return "Bad call to set_worker_hc_param()";
    }
    if (!ctx) {
        ctx = hc_create_config(p, s);
        ap_set_module_config(s->module_config, &proxy_hcheck_module, ctx);
    }
    temp = (hc_template_t *)v;
    if (!strcasecmp(key, "hctemplate")) {
        hc_template_t *template;
        template = (hc_template_t *)ctx->templates->elts;
        for (ival = 0; ival < ctx->templates->nelts; ival++, template++) {
            if (!ap_cstr_casecmp(template->name, val)) {
                if (worker) {
                    worker->s->method = template->method;
                    worker->s->interval = template->interval;
                    worker->s->passes = template->passes;
                    worker->s->fails = template->fails;
                    PROXY_STRNCPY(worker->s->hcuri, template->hurl);
                    PROXY_STRNCPY(worker->s->hcexpr, template->hcexpr);
                } else {
                    temp->method = template->method;
                    temp->interval = template->interval;
                    temp->passes = template->passes;
                    temp->fails = template->fails;
                    temp->hurl = apr_pstrdup(p, template->hurl);
                    temp->hcexpr = apr_pstrdup(p, template->hcexpr);
                }
                return NULL;
            }
        }
        return apr_psprintf(p, "Unknown ProxyHCTemplate name: %s", val);
    }
    else if (!strcasecmp(key, "hcmethod")) {
        proxy_hcmethods_t *method = proxy_hcmethods;
        for (; method->name; method++) {
            if (!ap_cstr_casecmp(val, method->name)) {
                if (!method->implemented) {
                    return apr_psprintf(p, "Health check method %s not (yet) implemented",
                                        val);
                }
                if (worker) {
                    worker->s->method = method->method;
                } else {
                    temp->method = method->method;
                }
                return NULL;
            }
        }
        return "Unknown method";
    }
    else if (!strcasecmp(key, "hcinterval")) {
        apr_interval_time_t hci;
        apr_status_t rv;
        rv = ap_timeout_parameter_parse(val, &hci, "s");
        if (rv != APR_SUCCESS)
            return "Unparse-able hcinterval setting";
        if (hci < AP_WD_TM_SLICE)
            return apr_psprintf(p, "Interval must be a positive value greater than %"
                                APR_TIME_T_FMT "ms", apr_time_as_msec(AP_WD_TM_SLICE));
        if (worker) {
            worker->s->interval = hci;
        } else {
            temp->interval = hci;
        }
    }
    else if (!strcasecmp(key, "hcpasses")) {
        ival = atoi(val);
        if (ival < 0)
            return "Passes must be a positive value";
        if (worker) {
            worker->s->passes = ival;
        } else {
            temp->passes = ival;
        }
    }
    else if (!strcasecmp(key, "hcfails")) {
        ival = atoi(val);
        if (ival < 0)
            return "Fails must be a positive value";
        if (worker) {
            worker->s->fails = ival;
        } else {
            temp->fails = ival;
        }
    }
    else if (!strcasecmp(key, "hcuri")) {
        if (strlen(val) >= sizeof(worker->s->hcuri))
            return apr_psprintf(p, "Health check uri length must be < %d characters",
                    (int)sizeof(worker->s->hcuri));
        if (worker) {
            PROXY_STRNCPY(worker->s->hcuri, val);
        } else {
            temp->hurl = apr_pstrdup(p, val);
        }
    }
    else if (!strcasecmp(key, "hcexpr")) {
        hc_condition_t *cond;
        cond = (hc_condition_t *)apr_table_get(ctx->conditions, val);
        if (!cond) {
            return apr_psprintf(p, "Unknown health check condition expr: %s", val);
        }
        /* This check is wonky... a known expr can't be this big. Check anyway */
        if (strlen(val) >= sizeof(worker->s->hcexpr))
            return apr_psprintf(p, "Health check uri length must be < %d characters",
                    (int)sizeof(worker->s->hcexpr));
        if (worker) {
            PROXY_STRNCPY(worker->s->hcexpr, val);
        } else {
            temp->hcexpr = apr_pstrdup(p, val);
        }
    }
  else {
        return "unknown Worker hcheck parameter";
    }
    return NULL;
}

static const char *set_hc_condition(cmd_parms *cmd, void *dummy, const char *arg)
{
    char *name = NULL;
    char *expr;
    sctx_t *ctx;
    hc_condition_t *cond;

    const char *err = ap_check_cmd_context(cmd, NOT_IN_HTACCESS);
    if (err)
        return err;
    ctx = (sctx_t *) ap_get_module_config(cmd->server->module_config,
                                          &proxy_hcheck_module);

    name = ap_getword_conf(cmd->pool, &arg);
    if (!*name) {
        return apr_pstrcat(cmd->temp_pool, "Missing expression name for ",
                           cmd->cmd->name, NULL);
    }
    if (strlen(name) > (PROXY_WORKER_MAX_SCHEME_SIZE - 1)) {
        return apr_psprintf(cmd->temp_pool, "Expression name limited to %d characters",
                           (PROXY_WORKER_MAX_SCHEME_SIZE - 1));
    }
    /* get expr. Allow fancy new {...} quoting style */
    expr = ap_getword_conf2(cmd->temp_pool, &arg);
    if (!*expr) {
        return apr_pstrcat(cmd->temp_pool, "Missing expression for ",
                           cmd->cmd->name, NULL);
    }
    cond = apr_palloc(cmd->pool, sizeof(hc_condition_t));
    cond->pexpr = ap_expr_parse_cmd(cmd, expr, 0, &err, NULL);
    if (err) {
        return apr_psprintf(cmd->temp_pool, "Could not parse expression \"%s\": %s",
                            expr, err);
    }
    cond->expr = apr_pstrdup(cmd->pool, expr);
    apr_table_setn(ctx->conditions, name, (void *)cond);
    expr = ap_getword_conf(cmd->temp_pool, &arg);
    if (*expr) {
        return "error: extra parameter(s)";
    }
    return NULL;
}

static const char *set_hc_template(cmd_parms *cmd, void *dummy, const char *arg)
{
    char *name = NULL;
    char *word, *val;
    hc_template_t *template;
    sctx_t *ctx;

    const char *err = ap_check_cmd_context(cmd, NOT_IN_HTACCESS);
    if (err)
        return err;
    ctx = (sctx_t *) ap_get_module_config(cmd->server->module_config,
                                          &proxy_hcheck_module);

    name = ap_getword_conf(cmd->temp_pool, &arg);
    if (!*name) {
        return apr_pstrcat(cmd->temp_pool, "Missing template name for ",
                           cmd->cmd->name, NULL);
    }

    template = (hc_template_t *)apr_array_push(ctx->templates);

    template->name = apr_pstrdup(cmd->pool, name);
    template->method = template->passes = template->fails = 1;
    template->interval = apr_time_from_sec(HCHECK_WATHCHDOG_DEFAULT_INTERVAL);
    template->hurl = NULL;
    template->hcexpr = NULL;
    while (*arg) {
        word = ap_getword_conf(cmd->pool, &arg);
        val = strchr(word, '=');
        if (!val) {
            return "Invalid ProxyHCTemplate parameter. Parameter must be "
                   "in the form 'key=value'";
        }
        else
            *val++ = '\0';
        err = set_worker_hc_param(cmd->pool, ctx->s, NULL, word, val, template);

        if (err) {
            /* get rid of recently pushed (bad) template */
            apr_array_pop(ctx->templates);
            return apr_pstrcat(cmd->temp_pool, "ProxyHCTemplate: ", err, " ", word, "=", val, "; ", name, NULL);
        }
        /* No error means we have a valid template */
    }
    return NULL;
}

#if HC_USE_THREADS
static const char *set_hc_tpsize (cmd_parms *cmd, void *dummy, const char *arg)
{
    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
    if (err)
        return err;

    tpsize = atoi(arg);
    if (tpsize < 0)
        return "Invalid ProxyHCTPsize parameter. Parameter must be "
               ">= 0";
    return NULL;
}
#endif

/*
 * Create a dummy request rec, simply so we can use ap_expr.
 * Use our short-lived pool for bucket_alloc so that we can simply move
 * buckets and use them after the backend connection is released.
 */
static request_rec *create_request_rec(apr_pool_t *p, server_rec *s,
                                       proxy_balancer *balancer,
                                       const char *method,
                                       const char *protocol)
{
    request_rec *r;

    r = apr_pcalloc(p, sizeof(request_rec));
    r->pool            = p;
    r->server          = s;

    r->per_dir_config = r->server->lookup_defaults;
    if (balancer->section_config) {
        r->per_dir_config = ap_merge_per_dir_configs(r->pool,
                                                     r->per_dir_config,
                                                     balancer->section_config);
    }

    r->proxyreq        = PROXYREQ_RESPONSE;

    r->user            = NULL;
    r->ap_auth_type    = NULL;

    r->allowed_methods = ap_make_method_list(p, 2);

    r->headers_in      = apr_table_make(r->pool, 1);
    r->trailers_in     = apr_table_make(r->pool, 1);
    r->subprocess_env  = apr_table_make(r->pool, 25);
    r->headers_out     = apr_table_make(r->pool, 12);
    r->err_headers_out = apr_table_make(r->pool, 5);
    r->trailers_out    = apr_table_make(r->pool, 1);
    r->notes           = apr_table_make(r->pool, 5);

    r->request_config  = ap_create_request_config(r->pool);
    /* Must be set before we run create request hook */

    r->sent_bodyct     = 0;                      /* bytect isn't for body */

    r->read_length     = 0;
    r->read_body       = REQUEST_NO_BODY;

    r->status          = HTTP_OK;  /* Until further notice */
    r->the_request     = NULL;

    /* Begin by presuming any module can make its own path_info assumptions,
     * until some module interjects and changes the value.
     */
    r->used_path_info = AP_REQ_DEFAULT_PATH_INFO;


    /* Time to populate r with the data we have. */
    r->method = method;
    /* Provide quick information about the request method as soon as known */
    r->method_number = ap_method_number_of(r->method);
    if (r->method_number == M_OPTIONS
            || (r->method_number == M_GET && r->method[0] == 'H')) {
        r->header_only = 1;
    }
    else {
        r->header_only = 0;
    }
    r->protocol = "HTTP/1.0";
    r->proto_num = HTTP_VERSION(1, 0);
    if ( protocol && (protocol[7] == '1') ) {
        r->protocol = "HTTP/1.1";
        r->proto_num = HTTP_VERSION(1, 1);
    }
    r->hostname = NULL;

    return r;
}

static void set_request_connection(request_rec *r, conn_rec *conn)
{
    conn->bucket_alloc = apr_bucket_alloc_create(r->pool);
    r->connection = conn;

    r->kept_body = apr_brigade_create(r->pool, conn->bucket_alloc);
    r->output_filters = r->proto_output_filters = conn->output_filters;
    r->input_filters = r->proto_input_filters = conn->input_filters;

    r->useragent_addr = conn->client_addr;
    r->useragent_ip = conn->client_ip;
}

static void create_hcheck_req(wctx_t *wctx, proxy_worker *hc,
                              apr_pool_t *p)
{
    char *req = NULL;
    const char *method = NULL;
    const char *protocol = NULL;

    /* TODO: Fold into switch/case below? This seems more obvious */
    if ( (hc->s->method == OPTIONS11) || (hc->s->method == HEAD11) || (hc->s->method == GET11) ) {
        protocol = "HTTP/1.1";
    } else {
        protocol = "HTTP/1.0";
    }
    switch (hc->s->method) {
        case OPTIONS:
        case OPTIONS11:
            method = "OPTIONS";
            req = apr_psprintf(p,
                               "OPTIONS * %s\r\n"
                               "Host: %s:%d\r\n"
                               "\r\n", protocol,
                               hc->s->hostname_ex, (int)hc->s->port);
            break;

        case HEAD:
        case HEAD11:
            method = "HEAD";
            /* fallthru */
        case GET:
        case GET11:
            if (!method) { /* did we fall thru? If not, we are GET */
                method = "GET";
            }
            req = apr_psprintf(p,
                               "%s %s%s%s %s\r\n"
                               "Host: %s:%d\r\n"
                               "\r\n",
                               method,
                               (wctx->path ? wctx->path : ""),
                               (wctx->path && *hc->s->hcuri ? "/" : "" ),
                               (*hc->s->hcuri ? hc->s->hcuri : ""),
                               protocol,
                               hc->s->hostname_ex, (int)hc->s->port);
            break;

        default:
            break;
    }
    wctx->req = req;
    wctx->method = method;
    wctx->protocol = protocol;
}

static proxy_worker *hc_get_hcworker(sctx_t *ctx, proxy_worker *worker,
                                     apr_pool_t *p)
{
    proxy_worker *hc = NULL;
    apr_port_t port;

    hc = (proxy_worker *)apr_hash_get(ctx->hcworkers, &worker, sizeof worker);
    if (!hc) {
        apr_uri_t uri;
        apr_status_t rv;
        const char *url = worker->s->name_ex;
        wctx_t *wctx = apr_pcalloc(ctx->p, sizeof(wctx_t));

        port = (worker->s->port ? worker->s->port
                                : ap_proxy_port_of_scheme(worker->s->scheme));
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ctx->s, APLOGNO(03248)
                     "Creating hc worker %pp for %s://%s:%d",
                     worker, worker->s->scheme, worker->s->hostname_ex,
                     (int)port);

        ap_proxy_define_worker(ctx->p, &hc, NULL, NULL, worker->s->name_ex, 0);
        apr_snprintf(hc->s->name, sizeof hc->s->name, "%pp", worker);
        apr_snprintf(hc->s->name_ex, sizeof hc->s->name_ex, "%pp", worker);
        PROXY_STRNCPY(hc->s->hostname, worker->s->hostname); /* for compatibility */
        PROXY_STRNCPY(hc->s->hostname_ex, worker->s->hostname_ex);
        PROXY_STRNCPY(hc->s->scheme,   worker->s->scheme);
        PROXY_STRNCPY(hc->s->hcuri,    worker->s->hcuri);
        PROXY_STRNCPY(hc->s->hcexpr,   worker->s->hcexpr);
        hc->hash.def = hc->s->hash.def = ap_proxy_hashfunc(hc->s->name_ex,
                                                           PROXY_HASHFUNC_DEFAULT);
        hc->hash.fnv = hc->s->hash.fnv = ap_proxy_hashfunc(hc->s->name_ex,
                                                           PROXY_HASHFUNC_FNV);
        hc->s->port = port;
        hc->s->conn_timeout_set = worker->s->conn_timeout_set;
        hc->s->conn_timeout = worker->s->conn_timeout;
        hc->s->ping_timeout_set = worker->s->ping_timeout_set;
        hc->s->ping_timeout = worker->s->ping_timeout;
        hc->s->timeout_set = worker->s->timeout_set;
        hc->s->timeout = worker->s->timeout;
        /* Do not disable worker in case of errors */
        hc->s->status |= PROXY_WORKER_IGNORE_ERRORS;
        /* Mark as the "generic" worker */
        hc->s->status |= PROXY_WORKER_GENERIC;
        ap_proxy_initialize_worker(hc, ctx->s, ctx->p);
        hc->s->is_address_reusable = worker->s->is_address_reusable;
        hc->s->disablereuse = worker->s->disablereuse;
        hc->s->method = worker->s->method;
        rv = apr_uri_parse(p, url, &uri);
        if (rv == APR_SUCCESS) {
            wctx->path = apr_pstrdup(ctx->p, uri.path);
        }
        wctx->w = worker;
        create_hcheck_req(wctx, hc, ctx->p);
        hc->context = wctx;
        apr_hash_set(ctx->hcworkers, &worker, sizeof worker, hc);
    }
    /* This *could* have changed via the Balancer Manager */
    /* TODO */
    if (hc->s->method != worker->s->method) {
        wctx_t *wctx = hc->context;
        port = (worker->s->port ? worker->s->port
                                : ap_proxy_port_of_scheme(worker->s->scheme));
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ctx->s, APLOGNO(03311)
                     "Updating hc worker %pp for %s://%s:%d",
                     worker, worker->s->scheme, worker->s->hostname_ex,
                     (int)port);
        hc->s->method = worker->s->method;
        create_hcheck_req(wctx, hc, ctx->p);
    }
    return hc;
}

static int hc_determine_connection(sctx_t *ctx, proxy_worker *worker,
                                   apr_sockaddr_t **addr, apr_pool_t *p)
{
    apr_status_t rv = APR_SUCCESS;
    /*
     * normally, this is done in ap_proxy_determine_connection().
     * TODO: Look at using ap_proxy_determine_connection() with a
     * fake request_rec
     */
    if (worker->cp->addr) {
        *addr = worker->cp->addr;
    }
    else {
        rv = apr_sockaddr_info_get(addr, worker->s->hostname_ex,
                                   APR_UNSPEC, worker->s->port, 0, p);
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ctx->s, APLOGNO(03249)
                         "DNS lookup failure for: %s:%d",
                         worker->s->hostname_ex, (int)worker->s->port);
        }
    }
    return (rv == APR_SUCCESS ? OK : !OK);
}

static apr_status_t hc_init_worker(sctx_t *ctx, proxy_worker *worker)
{
    apr_status_t rv = APR_SUCCESS;
    /*
     * Since this is the watchdog, workers never actually handle a
     * request here, and so the local data isn't initialized (of
     * course, the shared memory is). So we need to bootstrap
     * worker->cp. Note, we only need do this once.
     */
    if (!worker->cp) {
        rv = ap_proxy_initialize_worker(worker, ctx->s, ctx->p);
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ctx->s, APLOGNO(03250) "Cannot init worker");
            return rv;
        }
        if (worker->s->is_address_reusable && !worker->s->disablereuse &&
                hc_determine_connection(ctx, worker, &worker->cp->addr,
                                        worker->cp->pool) != OK) {
            rv = APR_EGENERAL;
        }
    }
    return rv;
}

static apr_status_t backend_cleanup(const char *proxy_function, proxy_conn_rec *backend,
                                    server_rec *s, int status)
{
    if (backend) {
        backend->close = 1;
        ap_proxy_release_connection(proxy_function, backend, s);
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(03251)
                         "Health check %s Status (%d) for %s.",
                         ap_proxy_show_hcmethod(backend->worker->s->method),
                         status,
                         backend->worker->s->name_ex);
    }
    if (status != OK) {
        return APR_EGENERAL;
    }
    return APR_SUCCESS;
}

static int hc_get_backend(const char *proxy_function, proxy_conn_rec **backend,
                          proxy_worker *hc, sctx_t *ctx, apr_pool_t *ptemp)
{
    int status;
    status = ap_proxy_acquire_connection(proxy_function, backend, hc, ctx->s);
    if (status == OK) {
        (*backend)->addr = hc->cp->addr;
        (*backend)->hostname = hc->s->hostname_ex;
        if (strcmp(hc->s->scheme, "https") == 0 || strcmp(hc->s->scheme, "wss") == 0 ) {
            if (!ap_ssl_has_outgoing_handlers()) {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ctx->s, APLOGNO(03252)
                              "mod_ssl not configured?");
                return !OK;
            }
            (*backend)->is_ssl = 1;
        }

    }
    return hc_determine_connection(ctx, hc, &(*backend)->addr, ptemp);
}

static apr_status_t hc_check_cping(baton_t *baton, apr_thread_t *thread)
{
    int status;
    sctx_t *ctx = baton->ctx;
    proxy_worker *hc = baton->hc;
    proxy_conn_rec *backend = NULL;
    apr_pool_t *ptemp = baton->ptemp;
    request_rec *r;
    apr_interval_time_t timeout;

    if (!ajp_handle_cping_cpong) {
        return APR_ENOTIMPL;
    }

    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, baton->ctx->s, "HCCPING starting");
    if ((status = hc_get_backend("HCCPING", &backend, hc, ctx, baton->ptemp)) != OK) {
        return backend_cleanup("HCCPING", backend, ctx->s, status);
    }
    if ((status = ap_proxy_connect_backend("HCCPING", backend, hc, ctx->s)) != OK) {
        return backend_cleanup("HCCPING", backend, ctx->s, status);
    }
    r = create_request_rec(ptemp, ctx->s, baton->balancer, "CPING", NULL);
    if ((status = ap_proxy_connection_create_ex("HCCPING", backend, r)) != OK) {
        return backend_cleanup("HCCPING", backend, ctx->s, status);
    }
    set_request_connection(r, backend->connection);
    backend->connection->current_thread = thread;

    if (hc->s->ping_timeout_set) {
        timeout = hc->s->ping_timeout;
    } else if ( hc->s->conn_timeout_set) {
        timeout = hc->s->conn_timeout;
    } else if ( hc->s->timeout_set) {
        timeout = hc->s->timeout;
    } else {
        /* default to socket timeout */
        apr_socket_timeout_get(backend->sock, &timeout); 
    }
    status = ajp_handle_cping_cpong(backend->sock, r, timeout);
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, baton->ctx->s, "HCCPING done %d", status);
    return backend_cleanup("HCCPING", backend, ctx->s, status);
}

static apr_status_t hc_check_tcp(baton_t *baton)
{
    int status;
    sctx_t *ctx = baton->ctx;
    proxy_worker *hc = baton->hc;
    proxy_conn_rec *backend = NULL;

    status = hc_get_backend("HCTCP", &backend, hc, ctx, baton->ptemp);
    if (status == OK) {
        status = ap_proxy_connect_backend("HCTCP", backend, hc, ctx->s);
        /* does an unconditional ap_proxy_is_socket_connected() */
    }
    return backend_cleanup("HCTCP", backend, ctx->s, status);
}

static int hc_send(request_rec *r, const char *out, apr_bucket_brigade *bb)
{
    apr_status_t rv;
    conn_rec *c = r->connection;
    apr_bucket_alloc_t *ba = c->bucket_alloc;
    ap_log_error(APLOG_MARK, APLOG_TRACE7, 0, r->server, "%s", out);
    APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_pool_create(out, strlen(out),
                                                       r->pool, ba));
    APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_flush_create(ba));
    rv = ap_pass_brigade(c->output_filters, bb);
    apr_brigade_cleanup(bb);
    return (rv) ? !OK : OK;
}

static int hc_read_headers(request_rec *r)
{
    char buffer[HUGE_STRING_LEN];
    int len;
    const char *ct;

    len = ap_getline(buffer, sizeof(buffer), r, 1);
    if (len <= 0) {
        return !OK;
    }
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, APLOGNO(03254)
                 "%.*s", len, buffer);
    /* for the below, see ap_proxy_http_process_response() */
    if (apr_date_checkmask(buffer, "HTTP/#.# ###*")) {
        int major;
        char keepchar;
        int proxy_status = OK;
        const char *proxy_status_line = NULL;

        major = buffer[5] - '0';
        if ((major != 1) || (len >= sizeof(buffer)-1)) {
            return !OK;
        }

        keepchar = buffer[12];
        buffer[12] = '\0';
        proxy_status = atoi(&buffer[9]);
        if (keepchar != '\0') {
            buffer[12] = keepchar;
        } else {
            buffer[12] = ' ';
            buffer[13] = '\0';
        }
        proxy_status_line = apr_pstrdup(r->pool, &buffer[9]);
        r->status = proxy_status;
        r->status_line = proxy_status_line;
    } else {
        return !OK;
    }

    /* OK, 1st line is OK... scarf in the headers */
    while ((len = ap_getline(buffer, sizeof(buffer), r, 1)) > 0) {
        char *value, *end;
        ap_log_error(APLOG_MARK, APLOG_TRACE7, 0, r->server, "%.*s",
                     len, buffer);
        if (!(value = strchr(buffer, ':'))) {
            return !OK;
        }
        *value = '\0';
        ++value;
        while (apr_isspace(*value))
            ++value;            /* Skip to start of value   */
        for (end = &value[strlen(value)-1]; end > value && apr_isspace(*end); --end)
            *end = '\0';
        apr_table_add(r->headers_out, buffer, value);
    }

    /* Set the Content-Type for the request if set */
    if ((ct = apr_table_get(r->headers_out, "Content-Type")) != NULL)
        ap_set_content_type(r, ct);

    return OK;
}

static int hc_read_body(request_rec *r, apr_bucket_brigade *bb)
{
    apr_status_t rv = APR_SUCCESS;
    int seen_eos = 0;

    do {
        apr_size_t len = HUGE_STRING_LEN;

        apr_brigade_cleanup(bb);
        rv = ap_get_brigade(r->proto_input_filters, bb, AP_MODE_READBYTES,
                            APR_BLOCK_READ, len);

        if (rv != APR_SUCCESS) {
            if (APR_STATUS_IS_EOF(rv)) {
                rv = APR_SUCCESS;
                break;
            }
            ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, r->server, APLOGNO(03300)
                          "Error reading response body");
            break;
        }

        while (!APR_BRIGADE_EMPTY(bb)) {
            apr_bucket *bucket = APR_BRIGADE_FIRST(bb);
            if (APR_BUCKET_IS_EOS(bucket)) {
                seen_eos = 1;
                break;
            }
            if (APR_BUCKET_IS_FLUSH(bucket)) {
                apr_bucket_delete(bucket);
                continue;
            }
            APR_BUCKET_REMOVE(bucket);
            APR_BRIGADE_INSERT_TAIL(r->kept_body, bucket);
        }
    }
    while (!seen_eos);
    apr_brigade_cleanup(bb);
    return (rv == APR_SUCCESS ? OK : !OK);
}

/*
 * Send the HTTP OPTIONS, HEAD or GET request to the backend
 * server associated w/ worker. If we have Conditions,
 * then apply those to the resulting response, otherwise
 * any status code 2xx or 3xx is considered "passing"
 */
static apr_status_t hc_check_http(baton_t *baton, apr_thread_t *thread)
{
    int status;
    proxy_conn_rec *backend = NULL;
    sctx_t *ctx = baton->ctx;
    proxy_worker *hc = baton->hc;
    proxy_worker *worker = baton->worker;
    apr_pool_t *ptemp = baton->ptemp;
    request_rec *r;
    wctx_t *wctx;
    hc_condition_t *cond;
    apr_bucket_brigade *bb;

    wctx = (wctx_t *)hc->context;
    if (!wctx->req || !wctx->method) {
        return APR_ENOTIMPL;
    }

    if ((status = hc_get_backend("HCOH", &backend, hc, ctx, ptemp)) != OK) {
        return backend_cleanup("HCOH", backend, ctx->s, status);
    }
    if ((status = ap_proxy_connect_backend("HCOH", backend, hc, ctx->s)) != OK) {
        return backend_cleanup("HCOH", backend, ctx->s, status);
    }

    r = create_request_rec(ptemp, ctx->s, baton->balancer, wctx->method, wctx->protocol);
    if ((status = ap_proxy_connection_create_ex("HCOH", backend, r)) != OK) {
        return backend_cleanup("HCOH", backend, ctx->s, status);
    }
    set_request_connection(r, backend->connection);
    backend->connection->current_thread = thread;

    bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);

    if ((status = hc_send(r, wctx->req, bb)) != OK) {
        return backend_cleanup("HCOH", backend, ctx->s, status);
    }
    if ((status = hc_read_headers(r)) != OK) {
        return backend_cleanup("HCOH", backend, ctx->s, status);
    }
    if (!r->header_only) {
        apr_table_t *saved_headers_in = r->headers_in;
        r->headers_in = apr_table_copy(r->pool, r->headers_out);
        ap_proxy_pre_http_request(backend->connection, r);
        status = hc_read_body(r, bb);
        r->headers_in = saved_headers_in;
        if (status != OK) {
            return backend_cleanup("HCOH", backend, ctx->s, status);
        }
        r->trailers_out = apr_table_copy(r->pool, r->trailers_in);
    }

    if (*worker->s->hcexpr &&
            (cond = (hc_condition_t *)apr_table_get(ctx->conditions, worker->s->hcexpr)) != NULL) {
        const char *err;
        int ok = ap_expr_exec(r, cond->pexpr, &err);
        if (ok > 0) {
            ap_log_error(APLOG_MARK, APLOG_TRACE2, 0, ctx->s,
                         "Condition %s for %s (%s): passed", worker->s->hcexpr,
                         hc->s->name_ex, worker->s->name_ex);
        } else if (ok < 0 || err) {
            ap_log_error(APLOG_MARK, APLOG_INFO, 0, ctx->s, APLOGNO(03301)
                         "Error on checking condition %s for %s (%s): %s", worker->s->hcexpr,
                         hc->s->name_ex, worker->s->name_ex, err);
            status = !OK;
        } else {
            ap_log_error(APLOG_MARK, APLOG_TRACE2, 0, ctx->s,
                         "Condition %s for %s (%s) : failed", worker->s->hcexpr,
                         hc->s->name_ex, worker->s->name_ex);
            status = !OK;
        }
    } else if (r->status < 200 || r->status > 399) {
        ap_log_error(APLOG_MARK, APLOG_TRACE2, 0, ctx->s,
                     "Response status %i for %s (%s): failed", r->status,
                     hc->s->name_ex, worker->s->name_ex);
        status = !OK;
    }
    return backend_cleanup("HCOH", backend, ctx->s, status);
}

static void * APR_THREAD_FUNC hc_check(apr_thread_t *thread, void *b)
{
    baton_t *baton = (baton_t *)b;
    server_rec *s = baton->ctx->s;
    proxy_worker *worker = baton->worker;
    proxy_worker *hc = baton->hc;
    apr_time_t now;
    apr_status_t rv;

    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(03256)
                 "%sHealth checking %s", (thread ? "Threaded " : ""),
                 worker->s->name_ex);

    if (hc->s->method == TCP) {
        rv = hc_check_tcp(baton);
    }
    else if (hc->s->method == CPING) {
        rv = hc_check_cping(baton, thread);
    }
    else {
        rv = hc_check_http(baton, thread);
    }

    now = apr_time_now();
    if (rv == APR_ENOTIMPL) {
        ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(03257)
                         "Somehow tried to use unimplemented hcheck method: %d",
                         (int)hc->s->method);
    }
    /* what state are we in ? */
    else if (PROXY_WORKER_IS_HCFAILED(worker) || PROXY_WORKER_IS_ERROR(worker)) {
        if (rv == APR_SUCCESS) {
            worker->s->pcount += 1;
            if (worker->s->pcount >= worker->s->passes) {
                ap_proxy_set_wstatus(PROXY_WORKER_HC_FAIL_FLAG, 0, worker);
                ap_proxy_set_wstatus(PROXY_WORKER_IN_ERROR_FLAG, 0, worker);
                worker->s->pcount = 0;
                ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(03302)
                             "%sHealth check ENABLING %s", (thread ? "Threaded " : ""),
                             worker->s->name_ex);

            }
        }
    }
    else {
        if (rv != APR_SUCCESS) {
            worker->s->error_time = now;
            worker->s->fcount += 1;
            if (worker->s->fcount >= worker->s->fails) {
                ap_proxy_set_wstatus(PROXY_WORKER_HC_FAIL_FLAG, 1, worker);
                worker->s->fcount = 0;
                ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(03303)
                             "%sHealth check DISABLING %s", (thread ? "Threaded " : ""),
                             worker->s->name_ex);
            }
        }
    }
    if (baton->now) {
        *baton->now = now;
    }
    apr_pool_destroy(baton->ptemp);
    worker->s->updated = now;

    return NULL;
}

static apr_status_t hc_watchdog_callback(int state, void *data,
                                         apr_pool_t *pool)
{
    apr_status_t rv = APR_SUCCESS;
    proxy_balancer *balancer;
    sctx_t *ctx = (sctx_t *)data;
    server_rec *s = ctx->s;
    proxy_server_conf *conf;

    switch (state) {
        case AP_WATCHDOG_STATE_STARTING:
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(03258)
                         "%s watchdog started.",
                         HCHECK_WATHCHDOG_NAME);
#if HC_USE_THREADS
            if (tpsize && hctp == NULL) {
                rv =  apr_thread_pool_create(&hctp, tpsize,
                                             tpsize, ctx->p);
                if (rv != APR_SUCCESS) {
                    ap_log_error(APLOG_MARK, APLOG_INFO, rv, s, APLOGNO(03312)
                                 "apr_thread_pool_create() with %d threads failed",
                                 tpsize);
                    /* we can continue on without the threadpools */
                    hctp = NULL;
                } else {
                    ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s, APLOGNO(03313)
                                 "apr_thread_pool_create() with %d threads succeeded",
                                 tpsize);
                }
            } else {
                ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s, APLOGNO(03314)
                             "Skipping apr_thread_pool_create()");
                hctp = NULL;
            }
#endif
            break;

        case AP_WATCHDOG_STATE_RUNNING:
            /* loop thru all workers */
            if (s) {
                int i;
                conf = (proxy_server_conf *) ap_get_module_config(s->module_config, &proxy_module);
                balancer = (proxy_balancer *)conf->balancers->elts;
                ctx->s = s;
                for (i = 0; i < conf->balancers->nelts; i++, balancer++) {
                    int n;
                    apr_time_t now;
                    proxy_worker **workers;
                    proxy_worker *worker;
                    /* Have any new balancers or workers been added dynamically? */
                    ap_proxy_sync_balancer(balancer, s, conf);
                    workers = (proxy_worker **)balancer->workers->elts;
                    now = apr_time_now();
                    for (n = 0; n < balancer->workers->nelts; n++) {
                        worker = *workers;
                        if (!PROXY_WORKER_IS(worker, PROXY_WORKER_STOPPED) &&
                            (worker->s->method != NONE) &&
                            (worker->s->updated != 0) &&
                            (now > worker->s->updated + worker->s->interval)) {
                            baton_t *baton;
                            apr_pool_t *ptemp;

                            ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, s,
                                         "Checking %s worker: %s  [%d] (%pp)", balancer->s->name,
                                         worker->s->name_ex, worker->s->method, worker);

                            if ((rv = hc_init_worker(ctx, worker)) != APR_SUCCESS) {
                                worker->s->updated = now;
                                return rv;
                            }
                            worker->s->updated = 0;

                            /* This pool has the lifetime of the check */
                            apr_pool_create(&ptemp, ctx->p);
                            apr_pool_tag(ptemp, "hc_request");
                            baton = apr_pcalloc(ptemp, sizeof(baton_t));
                            baton->ctx = ctx;
                            baton->balancer = balancer;
                            baton->worker = worker;
                            baton->ptemp = ptemp;
                            baton->hc = hc_get_hcworker(ctx, worker, ptemp);
#if HC_USE_THREADS
                            if (hctp) {
                                apr_thread_pool_push(hctp, hc_check, (void *)baton,
                                                     APR_THREAD_TASK_PRIORITY_NORMAL,
                                                     NULL);
                            }
                            else
#endif
                            {
                                baton->now = &now;
                                hc_check(NULL, baton);
                            }
                        }
                        workers++;
                    }
                }
            }
            break;

        case AP_WATCHDOG_STATE_STOPPING:
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(03261)
                         "stopping %s watchdog.",
                         HCHECK_WATHCHDOG_NAME);
#if HC_USE_THREADS
            if (hctp) {
                rv =  apr_thread_pool_destroy(hctp);
                if (rv != APR_SUCCESS) {
                    ap_log_error(APLOG_MARK, APLOG_INFO, rv, s, APLOGNO(03315)
                                 "apr_thread_pool_destroy() failed");
                }
                hctp = NULL;
            }
#endif
            break;
    }
    return rv;
}
static int hc_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
                         apr_pool_t *ptemp)
{
#if HC_USE_THREADS
    hctp = NULL;
    tpsize = HC_THREADPOOL_SIZE;
#endif

    ajp_handle_cping_cpong = APR_RETRIEVE_OPTIONAL_FN(ajp_handle_cping_cpong);
    if (ajp_handle_cping_cpong) {
       proxy_hcmethods_t *method = proxy_hcmethods;
       for (; method->name; method++) {
           if (method->method == CPING) {
               method->implemented = 1;
               break;
           }
       }
    }

    return OK;
}
static int hc_post_config(apr_pool_t *p, apr_pool_t *plog,
                       apr_pool_t *ptemp, server_rec *main_s)
{
    apr_status_t rv;
    server_rec *s = main_s;

    APR_OPTIONAL_FN_TYPE(ap_watchdog_get_instance) *hc_watchdog_get_instance;
    APR_OPTIONAL_FN_TYPE(ap_watchdog_register_callback) *hc_watchdog_register_callback;

    if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG) {
        return OK;
    }
    hc_watchdog_get_instance = APR_RETRIEVE_OPTIONAL_FN(ap_watchdog_get_instance);
    hc_watchdog_register_callback = APR_RETRIEVE_OPTIONAL_FN(ap_watchdog_register_callback);
    if (!hc_watchdog_get_instance || !hc_watchdog_register_callback) {
        ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s, APLOGNO(03262)
                     "mod_watchdog is required");
        return !OK;
    }
    rv = hc_watchdog_get_instance(&watchdog,
                                  HCHECK_WATHCHDOG_NAME,
                                  0, 1, p);
    if (rv) {
        ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(03263)
                     "Failed to create watchdog instance (%s)",
                     HCHECK_WATHCHDOG_NAME);
        return !OK;
    }
    while (s) {
        sctx_t *ctx = ap_get_module_config(s->module_config,
                                           &proxy_hcheck_module);

        if (s != ctx->s) {
            ap_log_error(APLOG_MARK, APLOG_TRACE4, 0, s, APLOGNO(10019)
                         "Missing unique per-server context: %s (%pp:%pp) (no hchecks)",
                         s->server_hostname, s, ctx->s);
            s = s->next;
            continue;
        }
        rv = hc_watchdog_register_callback(watchdog,
                AP_WD_TM_SLICE,
                ctx,
                hc_watchdog_callback);
        if (rv) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(03264)
                         "Failed to register watchdog callback (%s)",
                         HCHECK_WATHCHDOG_NAME);
            return !OK;
        }
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(03265)
                     "watchdog callback registered (%s for %s)", HCHECK_WATHCHDOG_NAME, s->server_hostname);
        s = s->next;
    }

    return OK;
}

static void hc_show_exprs(request_rec *r)
{
    const apr_table_entry_t *elts;
    const apr_array_header_t *hdr;
    int i;
    sctx_t *ctx = (sctx_t *) ap_get_module_config(r->server->module_config,
                                                  &proxy_hcheck_module);
    if (!ctx)
        return;
    if (apr_is_empty_table(ctx->conditions))
        return;

    ap_rputs("\n\n<table>"
             "<tr><th colspan='2'>Health check cond. expressions:</th></tr>\n"
             "<tr><th>Expr name</th><th>Expression</th></tr>\n", r);

    hdr = apr_table_elts(ctx->conditions);
    elts = (const apr_table_entry_t *) hdr->elts;
    for (i = 0; i < hdr->nelts; ++i) {
        hc_condition_t *cond;
        if (!elts[i].key) {
            continue;
        }
        cond = (hc_condition_t *)elts[i].val;
        ap_rprintf(r, "<tr><td>%s</td><td>%s</td></tr>\n",
                   ap_escape_html(r->pool, elts[i].key),
                   ap_escape_html(r->pool, cond->expr));
    }
    ap_rputs("</table><hr/>\n", r);
}

static void hc_select_exprs(request_rec *r, const char *expr)
{
    const apr_table_entry_t *elts;
    const apr_array_header_t *hdr;
    int i;
    sctx_t *ctx = (sctx_t *) ap_get_module_config(r->server->module_config,
                                                  &proxy_hcheck_module);
    if (!ctx)
        return;
    if (apr_is_empty_table(ctx->conditions))
        return;

    hdr = apr_table_elts(ctx->conditions);
    elts = (const apr_table_entry_t *) hdr->elts;
    for (i = 0; i < hdr->nelts; ++i) {
        if (!elts[i].key) {
            continue;
        }
        ap_rprintf(r, "<option value='%s' %s >%s</option>\n",
                   ap_escape_html(r->pool, elts[i].key),
                   (!strcmp(elts[i].key, expr)) ? "selected" : "",
                           ap_escape_html(r->pool, elts[i].key));
    }
}

static int hc_valid_expr(request_rec *r, const char *expr)
{
    const apr_table_entry_t *elts;
    const apr_array_header_t *hdr;
    int i;
    sctx_t *ctx = (sctx_t *) ap_get_module_config(r->server->module_config,
                                                  &proxy_hcheck_module);
    if (!ctx)
        return 0;
    if (apr_is_empty_table(ctx->conditions))
        return 0;

    hdr = apr_table_elts(ctx->conditions);
    elts = (const apr_table_entry_t *) hdr->elts;
    for (i = 0; i < hdr->nelts; ++i) {
        if (!elts[i].key) {
            continue;
        }
        if (!strcmp(elts[i].key, expr))
            return 1;
    }
    return 0;
}

static const char *hc_get_body(request_rec *r)
{
    apr_off_t length;
    apr_size_t len;
    apr_status_t rv;
    char *buf;

    if (!r || !r->kept_body)
        return "";

    rv = apr_brigade_length(r->kept_body, 1, &length);
    len = (apr_size_t)length;
    if (rv != APR_SUCCESS || len == 0)
        return "";

    buf = apr_palloc(r->pool, len + 1);
    rv = apr_brigade_flatten(r->kept_body, buf, &len);
    if (rv != APR_SUCCESS)
        return "";
    buf[len] = '\0'; /* ensure */
    return (const char*)buf;
}

static const char *hc_expr_var_fn(ap_expr_eval_ctx_t *ctx, const void *data)
{
    char *var = (char *)data;

    if (var && *var && ctx->r && ap_cstr_casecmp(var, "BODY") == 0) {
        return hc_get_body(ctx->r);
    }
    return NULL;
}

static const char *hc_expr_func_fn(ap_expr_eval_ctx_t *ctx, const void *data,
                                const char *arg)
{
    char *var = (char *)arg;

    if (var && *var && ctx->r && ap_cstr_casecmp(var, "BODY") == 0) {
        return hc_get_body(ctx->r);
    }
    return NULL;
}

static int hc_expr_lookup(ap_expr_lookup_parms *parms)
{
    switch (parms->type) {
    case AP_EXPR_FUNC_VAR:
        /* for now, we just handle everything that starts with HC_.
         */
        if (strncasecmp(parms->name, "HC_", 3) == 0) {
            *parms->func = hc_expr_var_fn;
            *parms->data = parms->name + 3;
            return OK;
        }
        break;
    case AP_EXPR_FUNC_STRING:
        /* Function HC() is implemented by us.
         */
        if (strcasecmp(parms->name, "HC") == 0) {
            *parms->func = hc_expr_func_fn;
            *parms->data = parms->arg;
            return OK;
        }
        break;
    }
    return DECLINED;
}

static const command_rec command_table[] = {
    AP_INIT_RAW_ARGS("ProxyHCTemplate", set_hc_template, NULL, OR_FILEINFO,
                     "Health check template"),
    AP_INIT_RAW_ARGS("ProxyHCExpr", set_hc_condition, NULL, OR_FILEINFO,
                     "Define a health check condition ruleset expression"),
#if HC_USE_THREADS
    AP_INIT_TAKE1("ProxyHCTPsize", set_hc_tpsize, NULL, RSRC_CONF,
                     "Set size of health check thread pool"),
#endif
    { NULL }
};

static void hc_register_hooks(apr_pool_t *p)
{
    static const char *const aszPre[] = { "mod_proxy_balancer.c", "mod_proxy.c", NULL};
    static const char *const aszSucc[] = { "mod_watchdog.c", NULL};
    APR_REGISTER_OPTIONAL_FN(set_worker_hc_param);
    APR_REGISTER_OPTIONAL_FN(hc_show_exprs);
    APR_REGISTER_OPTIONAL_FN(hc_select_exprs);
    APR_REGISTER_OPTIONAL_FN(hc_valid_expr);
    ap_hook_pre_config(hc_pre_config, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_post_config(hc_post_config, aszPre, aszSucc, APR_HOOK_LAST);
    ap_hook_expr_lookup(hc_expr_lookup, NULL, NULL, APR_HOOK_MIDDLE);
}

/* the main config structure */

AP_DECLARE_MODULE(proxy_hcheck) =
{
    STANDARD20_MODULE_STUFF,
    NULL,              /* create per-dir config structures */
    NULL,              /* merge  per-dir config structures */
    hc_create_config,  /* create per-server config structures */
    NULL,              /* merge  per-server config structures */
    command_table,     /* table of config file commands */
    hc_register_hooks  /* register hooks */
};
