/* 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 "util_fcgi.h"
#include "util_script.h"
#include "ap_expr.h"

module AP_MODULE_DECLARE_DATA proxy_fcgi_module;

typedef struct {
    ap_expr_info_t *cond;
    ap_expr_info_t *subst;
    const char *envname;
} sei_entry;

typedef struct {
    int need_dirwalk;
} fcgi_req_config_t;

/* We will assume FPM, but still differentiate */
typedef enum {
    BACKEND_DEFAULT_UNKNOWN = 0,
    BACKEND_FPM,
    BACKEND_GENERIC,
} fcgi_backend_t;


#define FCGI_MAY_BE_FPM(dconf)                              \
        (dconf &&                                           \
        ((dconf->backend_type == BACKEND_DEFAULT_UNKNOWN) || \
        (dconf->backend_type == BACKEND_FPM)))

typedef struct {
    fcgi_backend_t backend_type;
    apr_array_header_t *env_fixups;
} fcgi_dirconf_t;

/*
 * Canonicalise http-like URLs.
 * scheme is the scheme for the URL
 * url is the URL starting with the first '/'
 * def_port is the default port for this scheme.
 */
static int proxy_fcgi_canon(request_rec *r, char *url)
{
    char *host, sport[7];
    const char *err;
    char *path;
    apr_port_t port, def_port;
    fcgi_req_config_t *rconf = NULL;
    const char *pathinfo_type = NULL;

    if (ap_cstr_casecmpn(url, "fcgi:", 5) == 0) {
        url += 5;
    }
    else {
        return DECLINED;
    }

    port = def_port = ap_proxy_port_of_scheme("fcgi");

    ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                 "canonicalising URL %s", url);
    err = ap_proxy_canon_netloc(r->pool, &url, NULL, NULL, &host, &port);
    if (err) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01059)
                      "error parsing URL %s: %s", url, err);
        return HTTP_BAD_REQUEST;
    }

    if (port != def_port)
        apr_snprintf(sport, sizeof(sport), ":%d", port);
    else
        sport[0] = '\0';

    if (ap_strchr_c(host, ':')) {
        /* if literal IPv6 address */
        host = apr_pstrcat(r->pool, "[", host, "]", NULL);
    }

    if (apr_table_get(r->notes, "proxy-nocanon")) {
        path = url;   /* this is the raw path */
    }
    else {
        path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0,
                             r->proxyreq);
    }
    if (path == NULL)
        return HTTP_BAD_REQUEST;

    r->filename = apr_pstrcat(r->pool, "proxy:fcgi://", host, sport, "/",
                              path, NULL);

    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01060)
                  "set r->filename to %s", r->filename);

    rconf = ap_get_module_config(r->request_config, &proxy_fcgi_module);
    if (rconf == NULL) {
        rconf = apr_pcalloc(r->pool, sizeof(fcgi_req_config_t));
        ap_set_module_config(r->request_config, &proxy_fcgi_module, rconf);
    }

    if (NULL != (pathinfo_type = apr_table_get(r->subprocess_env, "proxy-fcgi-pathinfo"))) {
        /* It has to be on disk for this to work */
        if (!strcasecmp(pathinfo_type, "full")) {
            rconf->need_dirwalk = 1;
            ap_unescape_url_keep2f(path, 0);
        }
        else if (!strcasecmp(pathinfo_type, "first-dot")) {
            char *split = ap_strchr(path, '.');
            if (split) {
                char *slash = ap_strchr(split, '/');
                if (slash) {
                    r->path_info = apr_pstrdup(r->pool, slash);
                    ap_unescape_url_keep2f(r->path_info, 0);
                    *slash = '\0'; /* truncate path */
                }
            }
        }
        else if (!strcasecmp(pathinfo_type, "last-dot")) {
            char *split = ap_strrchr(path, '.');
            if (split) {
                char *slash = ap_strchr(split, '/');
                if (slash) {
                    r->path_info = apr_pstrdup(r->pool, slash);
                    ap_unescape_url_keep2f(r->path_info, 0);
                    *slash = '\0'; /* truncate path */
                }
            }
        }
        else {
            /* before proxy-fcgi-pathinfo had multi-values. This requires the
             * the FCGI server to fixup PATH_INFO because it's the entire path
             */
            r->path_info = apr_pstrcat(r->pool, "/", path, NULL);
            if (!strcasecmp(pathinfo_type, "unescape")) {
                ap_unescape_url_keep2f(r->path_info, 0);
            }
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01061)
                    "set r->path_info to %s", r->path_info);
        }
    }

    return OK;
}


/*
  ProxyFCGISetEnvIf "reqenv('PATH_INFO') =~ m#/foo(\d+)\.php$#" COVENV1 "$1"
  ProxyFCGISetEnvIf "reqenv('PATH_INFO') =~ m#/foo(\d+)\.php$#" PATH_INFO "/foo.php"
  ProxyFCGISetEnvIf "reqenv('PATH_TRANSLATED') =~ m#(/.*foo)(\d+)(.*)#" PATH_TRANSLATED "$1$3"
*/
static apr_status_t fix_cgivars(request_rec *r, fcgi_dirconf_t *dconf)
{
    sei_entry *entries;
    const char *err, *src;
    int i = 0, rc = 0;
    ap_regmatch_t regm[AP_MAX_REG_MATCH];

    entries = (sei_entry *) dconf->env_fixups->elts;
    for (i = 0; i < dconf->env_fixups->nelts; i++) {
        sei_entry *entry = &entries[i];

        rc = ap_expr_exec_re(r, entry->cond, AP_MAX_REG_MATCH, regm, &src, &err);
        if (rc < 0) { 
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10241) 
                          "fix_cgivars: Condition eval returned %d: %s", 
                          rc, err);
            return APR_EGENERAL;
        }
        else if (rc == 0) { 
            continue; /* evaluated false */
        }

        if (entry->envname[0] == '!') {
            apr_table_unset(r->subprocess_env, entry->envname+1);
        }
        else {
            const char *val = ap_expr_str_exec_re(r, entry->subst, AP_MAX_REG_MATCH, regm, &src, &err);
            if (err) {
                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(03514)
                              "Error evaluating expression for replacement of %s: '%s'",
                               entry->envname, err);
                continue;
            }
            if (APLOGrtrace4(r)) {
                const char *oldval = apr_table_get(r->subprocess_env, entry->envname);
                ap_log_rerror(APLOG_MARK, APLOG_TRACE4, 0, r,
                              "fix_cgivars: override %s from '%s' to '%s'",
                              entry->envname, oldval, val);

            }
            apr_table_setn(r->subprocess_env, entry->envname, val);
        }
    }
    return APR_SUCCESS;
}

/* Wrapper for apr_socket_sendv that handles updating the worker stats. */
static apr_status_t send_data(proxy_conn_rec *conn,
                              struct iovec *vec,
                              int nvec,
                              apr_size_t *len)
{
    apr_status_t rv = APR_SUCCESS;
    apr_size_t written = 0, to_write = 0;
    int i, offset;
    apr_socket_t *s = conn->sock;

    for (i = 0; i < nvec; i++) {
        to_write += vec[i].iov_len;
    }

    offset = 0;
    while (to_write) {
        apr_size_t n = 0;
        rv = apr_socket_sendv(s, vec + offset, nvec - offset, &n);
        if (rv != APR_SUCCESS) {
            break;
        }
        if (n > 0) {
            written += n;
            if (written >= to_write)
                break;                 /* short circuit out */
            for (i = offset; i < nvec; ) {
                if (n >= vec[i].iov_len) {
                    offset++;
                    n -= vec[i++].iov_len;
                } else {
                    vec[i].iov_len -= n;
                    vec[i].iov_base = (char *) vec[i].iov_base + n;
                    break;
                }
            }
        }
    }

    conn->worker->s->transferred += written;
    *len = written;

    return rv;
}

/* Wrapper for apr_socket_recv that handles updating the worker stats. */
static apr_status_t get_data(proxy_conn_rec *conn,
                             char *buffer,
                             apr_size_t *buflen)
{
    apr_status_t rv = apr_socket_recv(conn->sock, buffer, buflen);

    if (rv == APR_SUCCESS) {
        conn->worker->s->read += *buflen;
    }

    return rv;
}

static apr_status_t get_data_full(proxy_conn_rec *conn,
                                  char *buffer,
                                  apr_size_t buflen)
{
    apr_size_t readlen;
    apr_size_t cumulative_len = 0;
    apr_status_t rv;

    do {
        readlen = buflen - cumulative_len;
        rv = get_data(conn, buffer + cumulative_len, &readlen);
        if (rv != APR_SUCCESS) {
            return rv;
        }
        cumulative_len += readlen;
    } while (cumulative_len < buflen);

    return APR_SUCCESS;
}

static apr_status_t send_begin_request(proxy_conn_rec *conn,
                                       apr_uint16_t request_id)
{
    struct iovec vec[2];
    ap_fcgi_header header;
    unsigned char farray[AP_FCGI_HEADER_LEN];
    ap_fcgi_begin_request_body brb;
    unsigned char abrb[AP_FCGI_HEADER_LEN];
    apr_size_t len;

    ap_fcgi_fill_in_header(&header, AP_FCGI_BEGIN_REQUEST, request_id,
                           sizeof(abrb), 0);

    ap_fcgi_fill_in_request_body(&brb, AP_FCGI_RESPONDER,
                                 ap_proxy_connection_reusable(conn)
                                     ? AP_FCGI_KEEP_CONN : 0);

    ap_fcgi_header_to_array(&header, farray);
    ap_fcgi_begin_request_body_to_array(&brb, abrb);

    vec[0].iov_base = (void *)farray;
    vec[0].iov_len = sizeof(farray);
    vec[1].iov_base = (void *)abrb;
    vec[1].iov_len = sizeof(abrb);

    return send_data(conn, vec, 2, &len);
}

static apr_status_t send_environment(proxy_conn_rec *conn, request_rec *r,
                                     apr_pool_t *temp_pool,
                                     apr_uint16_t request_id)
{
    const apr_array_header_t *envarr;
    const apr_table_entry_t *elts;
    struct iovec vec[2];
    ap_fcgi_header header;
    unsigned char farray[AP_FCGI_HEADER_LEN];
    char *body;
    apr_status_t rv;
    apr_size_t avail_len, len, required_len;
    int next_elem, starting_elem;
    fcgi_req_config_t *rconf = ap_get_module_config(r->request_config, &proxy_fcgi_module);
    fcgi_dirconf_t *dconf = ap_get_module_config(r->per_dir_config, &proxy_fcgi_module);

    if (rconf) {
       if (rconf->need_dirwalk) {
          ap_directory_walk(r);
       }
    }

    /* Strip proxy: prefixes */
    if (r->filename) {
        char *newfname = NULL;

        if (!strncmp(r->filename, "proxy:balancer://", 17)) {
            newfname = apr_pstrdup(r->pool, r->filename+17);
        }

        if (!FCGI_MAY_BE_FPM(dconf))  {
            if (!strncmp(r->filename, "proxy:fcgi://", 13)) {
                /* If we strip this under FPM, and any internal redirect occurs
                 * on PATH_INFO, FPM may use PATH_TRANSLATED instead of
                 * SCRIPT_FILENAME (a la mod_fastcgi + Action).
                 */
                newfname = apr_pstrdup(r->pool, r->filename+13);
            }
            /* Query string in environment only */
            if (newfname && r->args && *r->args) {
                char *qs = strrchr(newfname, '?');
                if (qs && !strcmp(qs+1, r->args)) {
                    *qs = '\0';
                }
            }
        }

        if (newfname) {
            newfname = ap_strchr(newfname, '/');
            r->filename = newfname;
        }
    }

    ap_add_common_vars(r);
    ap_add_cgi_vars(r);

    /* XXX are there any FastCGI specific env vars we need to send? */

    /* Give admins final option to fine-tune env vars */
    if (APR_SUCCESS != (rv = fix_cgivars(r, dconf))) { 
        return rv;
    }

    /* XXX mod_cgi/mod_cgid use ap_create_environment here, which fills in
     *     the TZ value specially.  We could use that, but it would mean
     *     parsing the key/value pairs back OUT of the allocated env array,
     *     not to mention allocating a totally useless array in the first
     *     place, which would suck. */

    envarr = apr_table_elts(r->subprocess_env);
    elts = (const apr_table_entry_t *) envarr->elts;

    if (APLOGrtrace8(r)) {
        int i;

        for (i = 0; i < envarr->nelts; ++i) {
            ap_log_rerror(APLOG_MARK, APLOG_TRACE8, 0, r, APLOGNO(01062)
                          "sending env var '%s' value '%s'",
                          elts[i].key, elts[i].val);
        }
    }

    /* Send envvars over in as many FastCGI records as it takes, */
    next_elem = 0; /* starting with the first one */

    avail_len = 16 * 1024; /* our limit per record, which could have been up
                            * to AP_FCGI_MAX_CONTENT_LEN
                            */

    while (next_elem < envarr->nelts) {
        starting_elem = next_elem;
        required_len = ap_fcgi_encoded_env_len(r->subprocess_env,
                                               avail_len,
                                               &next_elem);

        if (!required_len) {
            if (next_elem < envarr->nelts) {
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
                              APLOGNO(02536) "couldn't encode envvar '%s' in %"
                              APR_SIZE_T_FMT " bytes",
                              elts[next_elem].key, avail_len);
                /* skip this envvar and continue */
                ++next_elem;
                continue;
            }
            /* only an unused element at the end of the array */
            break;
        }

        body = apr_palloc(temp_pool, required_len);
        rv = ap_fcgi_encode_env(r, r->subprocess_env, body, required_len,
                                &starting_elem);
        /* we pre-compute, so we can't run out of space */
        ap_assert(rv == APR_SUCCESS);
        /* compute and encode must be in sync */
        ap_assert(starting_elem == next_elem);

        ap_fcgi_fill_in_header(&header, AP_FCGI_PARAMS, request_id,
                               (apr_uint16_t)required_len, 0);
        ap_fcgi_header_to_array(&header, farray);

        vec[0].iov_base = (void *)farray;
        vec[0].iov_len = sizeof(farray);
        vec[1].iov_base = body;
        vec[1].iov_len = required_len;

        rv = send_data(conn, vec, 2, &len);
        apr_pool_clear(temp_pool);

        if (rv) {
            return rv;
        }
    }

    /* Envvars sent, so say we're done */
    ap_fcgi_fill_in_header(&header, AP_FCGI_PARAMS, request_id, 0, 0);
    ap_fcgi_header_to_array(&header, farray);

    vec[0].iov_base = (void *)farray;
    vec[0].iov_len = sizeof(farray);

    return send_data(conn, vec, 1, &len);
}

enum {
  HDR_STATE_READING_HEADERS,
  HDR_STATE_GOT_CR,
  HDR_STATE_GOT_CRLF,
  HDR_STATE_GOT_CRLFCR,
  HDR_STATE_GOT_LF,
  HDR_STATE_DONE_WITH_HEADERS
};

/* Try to find the end of the script headers in the response from the back
 * end fastcgi server. STATE holds the current header parsing state for this
 * request.
 *
 * Returns 0 if it can't find the end of the headers, and 1 if it found the
 * end of the headers. */
static int handle_headers(request_rec *r, int *state,
                          const char *readbuf, apr_size_t readlen)
{
    const char *itr = readbuf;

    while (readlen--) {
        if (*itr == '\r') {
            switch (*state) {
                case HDR_STATE_GOT_CRLF:
                    *state = HDR_STATE_GOT_CRLFCR;
                    break;

                default:
                    *state = HDR_STATE_GOT_CR;
                    break;
            }
        }
        else if (*itr == '\n') {
            switch (*state) {
                 case HDR_STATE_GOT_LF:
                     *state = HDR_STATE_DONE_WITH_HEADERS;
                     break;

                 case HDR_STATE_GOT_CR:
                     *state = HDR_STATE_GOT_CRLF;
                     break;

                 case HDR_STATE_GOT_CRLFCR:
                     *state = HDR_STATE_DONE_WITH_HEADERS;
                     break;

                 default:
                     *state = HDR_STATE_GOT_LF;
                     break;
            }
        }
        else {
            *state = HDR_STATE_READING_HEADERS;
        }

        if (*state == HDR_STATE_DONE_WITH_HEADERS)
            break;

        ++itr;
    }

    if (*state == HDR_STATE_DONE_WITH_HEADERS) {
        return 1;
    }

    return 0;
}

static apr_status_t dispatch(proxy_conn_rec *conn, proxy_dir_conf *conf,
                             request_rec *r, apr_pool_t *setaside_pool,
                             apr_uint16_t request_id, const char **err,
                             int *bad_request, int *has_responded,
                             apr_bucket_brigade *input_brigade)
{
    apr_bucket_brigade *ib, *ob;
    int seen_end_of_headers = 0, done = 0, ignore_body = 0;
    apr_status_t rv = APR_SUCCESS;
    int script_error_status = HTTP_OK;
    conn_rec *c = r->connection;
    struct iovec vec[2];
    ap_fcgi_header header;
    unsigned char farray[AP_FCGI_HEADER_LEN];
    apr_pollfd_t pfd;
    apr_pollfd_t *flushpoll = NULL;
    apr_int32_t flushpoll_fd;
    int header_state = HDR_STATE_READING_HEADERS;
    char stack_iobuf[AP_IOBUFSIZE];
    apr_size_t iobuf_size = AP_IOBUFSIZE;
    char *iobuf = stack_iobuf;

    *err = NULL;
    if (conn->worker->s->io_buffer_size_set) {
        iobuf_size = conn->worker->s->io_buffer_size;
        iobuf = apr_palloc(r->pool, iobuf_size);
    }

    pfd.desc_type = APR_POLL_SOCKET;
    pfd.desc.s = conn->sock;
    pfd.p = r->pool;
    pfd.reqevents = APR_POLLIN | APR_POLLOUT;

    if (conn->worker->s->flush_packets == flush_auto) {
        flushpoll = apr_pcalloc(r->pool, sizeof(apr_pollfd_t));
        flushpoll->reqevents = APR_POLLIN;
        flushpoll->desc_type = APR_POLL_SOCKET;
        flushpoll->desc.s = conn->sock;
    }

    ib = apr_brigade_create(r->pool, c->bucket_alloc);
    ob = apr_brigade_create(r->pool, c->bucket_alloc);

    while (! done) {
        apr_interval_time_t timeout;
        apr_size_t len;
        int n;

        /* We need SOME kind of timeout here, or virtually anything will
         * cause timeout errors. */
        apr_socket_timeout_get(conn->sock, &timeout);

        rv = apr_poll(&pfd, 1, &n, timeout);
        if (rv != APR_SUCCESS) {
            if (APR_STATUS_IS_EINTR(rv)) {
                continue;
            }
            *err = "polling";
            break;
        }

        if (pfd.rtnevents & APR_POLLOUT) {
            apr_size_t to_send, writebuflen;
            int last_stdin = 0;
            char *iobuf_cursor;

            if (APR_BRIGADE_EMPTY(input_brigade)) {
                rv = ap_get_brigade(r->input_filters, ib,
                                    AP_MODE_READBYTES, APR_BLOCK_READ,
                                    iobuf_size);
            }
            else {
                apr_bucket *e;
                APR_BRIGADE_CONCAT(ib, input_brigade);
                rv = apr_brigade_partition(ib, iobuf_size, &e);
                if (rv == APR_SUCCESS) {
                    while (e != APR_BRIGADE_SENTINEL(ib)
                           && APR_BUCKET_IS_METADATA(e)) {
                        e = APR_BUCKET_NEXT(e);
                    }
                    apr_brigade_split_ex(ib, e, input_brigade);
                }
                else if (rv == APR_INCOMPLETE) {
                    rv = APR_SUCCESS;
                }
            }
            if (rv != APR_SUCCESS) {
                *err = "reading input brigade";
                *bad_request = 1;
                break;
            }

            if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(ib))) {
                last_stdin = 1;
            }

            writebuflen = iobuf_size;

            rv = apr_brigade_flatten(ib, iobuf, &writebuflen);

            apr_brigade_cleanup(ib);

            if (rv != APR_SUCCESS) {
                *err = "flattening brigade";
                break;
            }

            to_send = writebuflen;
            iobuf_cursor = iobuf;
            while (to_send > 0) {
                int nvec = 0;
                apr_size_t write_this_time;

                write_this_time =
                    to_send < AP_FCGI_MAX_CONTENT_LEN ? to_send : AP_FCGI_MAX_CONTENT_LEN;

                ap_fcgi_fill_in_header(&header, AP_FCGI_STDIN, request_id,
                                       (apr_uint16_t)write_this_time, 0);
                ap_fcgi_header_to_array(&header, farray);

                vec[nvec].iov_base = (void *)farray;
                vec[nvec].iov_len = sizeof(farray);
                ++nvec;
                if (writebuflen) {
                    vec[nvec].iov_base = iobuf_cursor;
                    vec[nvec].iov_len = write_this_time;
                    ++nvec;
                }

                rv = send_data(conn, vec, nvec, &len);
                if (rv != APR_SUCCESS) {
                    *err = "sending stdin";
                    break;
                }

                to_send -= write_this_time;
                iobuf_cursor += write_this_time;
            }
            if (rv != APR_SUCCESS) {
                break;
            }

            if (last_stdin) {
                pfd.reqevents = APR_POLLIN; /* Done with input data */

                /* signal EOF (empty FCGI_STDIN) */
                ap_fcgi_fill_in_header(&header, AP_FCGI_STDIN, request_id,
                                       0, 0);
                ap_fcgi_header_to_array(&header, farray);

                vec[0].iov_base = (void *)farray;
                vec[0].iov_len = sizeof(farray);

                rv = send_data(conn, vec, 1, &len);
                if (rv != APR_SUCCESS) {
                    *err = "sending empty stdin";
                    break;
                }
            }
        }

        if (pfd.rtnevents & APR_POLLIN) {
            apr_size_t readbuflen;
            apr_uint16_t clen, rid;
            apr_bucket *b;
            unsigned char plen;
            unsigned char type, version;
            int mayflush = 0;

            /* First, we grab the header... */
            rv = get_data_full(conn, (char *) farray, AP_FCGI_HEADER_LEN);
            if (rv != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01067)
                              "Failed to read FastCGI header");
                break;
            }

            ap_log_rdata(APLOG_MARK, APLOG_TRACE8, r, "FastCGI header",
                         farray, AP_FCGI_HEADER_LEN, 0);

            ap_fcgi_header_fields_from_array(&version, &type, &rid,
                                             &clen, &plen, farray);

            if (version != AP_FCGI_VERSION_1) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01068)
                              "Got bogus version %d", (int)version);
                rv = APR_EINVAL;
                break;
            }

            if (rid != request_id) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01069)
                              "Got bogus rid %d, expected %d",
                              rid, request_id);
                rv = APR_EINVAL;
                break;
            }

recv_again:
            if (clen > iobuf_size) {
                readbuflen = iobuf_size;
            } else {
                readbuflen = clen;
            }

            /* Now get the actual data.  Yes it sucks to do this in a second
             * recv call, this will eventually change when we move to real
             * nonblocking recv calls. */
            if (readbuflen != 0) {
                rv = get_data(conn, iobuf, &readbuflen);
                if (rv != APR_SUCCESS) {
                    *err = "reading response body";
                    break;
                }
            }

            switch (type) {
            case AP_FCGI_STDOUT:
                if (clen != 0) {
                    b = apr_bucket_transient_create(iobuf,
                                                    readbuflen,
                                                    c->bucket_alloc);

                    APR_BRIGADE_INSERT_TAIL(ob, b);

                    if (! seen_end_of_headers) {
                        int st = handle_headers(r, &header_state,
                                                iobuf, readbuflen);

                        if (st == 1) {
                            int status;
                            seen_end_of_headers = 1;

                            status = ap_scan_script_header_err_brigade_ex(r, ob,
                                NULL, APLOG_MODULE_INDEX);
                            /* suck in all the rest */
                            if (status != OK) {
                                apr_bucket *tmp_b;
                                apr_brigade_cleanup(ob);
                                tmp_b = apr_bucket_eos_create(c->bucket_alloc);
                                APR_BRIGADE_INSERT_TAIL(ob, tmp_b);

                                *has_responded = 1;
                                r->status = status;
                                rv = ap_pass_brigade(r->output_filters, ob);
                                if (rv != APR_SUCCESS) {
                                    *err = "passing headers brigade to output filters";
                                    break;
                                }
                                else if (status == HTTP_NOT_MODIFIED
                                         || status == HTTP_PRECONDITION_FAILED) {
                                    /* Special 'status' cases handled:
                                     * 1) HTTP 304 response MUST NOT contain
                                     *    a message-body, ignore it.
                                     * 2) HTTP 412 response.
                                     * The break is not added since there might
                                     * be more bytes to read from the FCGI
                                     * connection. Even if the message-body is
                                     * ignored (and the EOS bucket has already
                                     * been sent) we want to avoid subsequent
                                     * bogus reads. */
                                    ignore_body = 1;
                                }
                                else {
                                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01070)
                                                    "Error parsing script headers");
                                    rv = APR_EINVAL;
                                    break;
                                }
                            }

                            if (ap_proxy_should_override(conf, r->status) && ap_is_initial_req(r)) {
                                /*
                                 * set script_error_status to discard
                                 * everything after the headers
                                 */
                                script_error_status = r->status;
                                /*
                                 * prevent ap_die() from treating this as a
                                 * recursive error, initially:
                                 */
                                r->status = HTTP_OK;
                            }

                            if (script_error_status == HTTP_OK
                                && !APR_BRIGADE_EMPTY(ob) && !ignore_body) {
                                /* Send the part of the body that we read while
                                 * reading the headers.
                                 */
                                *has_responded = 1;
                                rv = ap_pass_brigade(r->output_filters, ob);
                                if (rv != APR_SUCCESS) {
                                    *err = "passing brigade to output filters";
                                    break;
                                }
                                mayflush = 1;
                            }
                            apr_brigade_cleanup(ob);

                            apr_pool_clear(setaside_pool);
                        }
                        else {
                            /* We're still looking for the end of the
                             * headers, so this part of the data will need
                             * to persist. */
                            apr_bucket_setaside(b, setaside_pool);
                        }
                    } else {
                        /* we've already passed along the headers, so now pass
                         * through the content.  we could simply continue to
                         * setaside the content and not pass until we see the
                         * 0 content-length (below, where we append the EOS),
                         * but that could be a huge amount of data; so we pass
                         * along smaller chunks
                         */
                        if (script_error_status == HTTP_OK && !ignore_body) {
                            *has_responded = 1;
                            rv = ap_pass_brigade(r->output_filters, ob);
                            if (rv != APR_SUCCESS) {
                                *err = "passing brigade to output filters";
                                break;
                            }
                            mayflush = 1;
                        }
                        apr_brigade_cleanup(ob);
                    }

                    /* If we didn't read all the data, go back and get the
                     * rest of it. */
                    if (clen > readbuflen) {
                        clen -= readbuflen;
                        goto recv_again;
                    }
                } else {
                    /* XXX what if we haven't seen end of the headers yet? */

                    if (script_error_status == HTTP_OK) {
                        b = apr_bucket_eos_create(c->bucket_alloc);
                        APR_BRIGADE_INSERT_TAIL(ob, b);

                        *has_responded = 1;
                        rv = ap_pass_brigade(r->output_filters, ob);
                        if (rv != APR_SUCCESS) {
                            *err = "passing brigade to output filters";
                            break;
                        }
                    }

                    /* XXX Why don't we cleanup here?  (logic from AJP) */
                }
                break;

            case AP_FCGI_STDERR:
                /* TODO: Should probably clean up this logging a bit... */
                if (clen) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01071)
                                  "Got error '%.*s'", (int)readbuflen, iobuf);
                }

                if (clen > readbuflen) {
                    clen -= readbuflen;
                    goto recv_again;
                }
                break;

            case AP_FCGI_END_REQUEST:
                done = 1;
                break;

            default:
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01072)
                              "Got bogus record %d", type);
                break;
            }
            /* Leave on above switch's inner error. */
            if (rv != APR_SUCCESS) {
                break;
            }

            if (plen) {
                rv = get_data_full(conn, iobuf, plen);
                if (rv != APR_SUCCESS) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(02537)
                                  "Error occurred reading padding");
                    break;
                }
            }

            if (mayflush && ((conn->worker->s->flush_packets == flush_on) ||
                             ((conn->worker->s->flush_packets == flush_auto) && 
                              (apr_poll(flushpoll, 1, &flushpoll_fd,
                               conn->worker->s->flush_wait) == APR_TIMEUP)))) {
                apr_bucket* flush_b = apr_bucket_flush_create(r->connection->bucket_alloc);
                APR_BRIGADE_INSERT_TAIL(ob, flush_b);
                rv = ap_pass_brigade(r->output_filters, ob);
                if (rv != APR_SUCCESS) {
                    *err = "passing headers brigade to output filters";
                    break;
                }
                mayflush = 0;
            }
        }
    }

    apr_brigade_destroy(ib);
    apr_brigade_destroy(ob);

    if (script_error_status != HTTP_OK) {
        ap_die(script_error_status, r); /* send ErrorDocument */
        *has_responded = 1;
    }

    return rv;
}

/*
 * process the request and write the response.
 */
static int fcgi_do_request(apr_pool_t *p, request_rec *r,
                           proxy_conn_rec *conn,
                           conn_rec *origin,
                           proxy_dir_conf *conf,
                           apr_uri_t *uri,
                           char *url, char *server_portstr,
                           apr_bucket_brigade *input_brigade)
{
    /* Request IDs are arbitrary numbers that we assign to a
     * single request. This would allow multiplex/pipelining of
     * multiple requests to the same FastCGI connection, but
     * we don't support that, and always use a value of '1' to
     * keep things simple. */
    apr_uint16_t request_id = 1;
    apr_status_t rv;
    apr_pool_t *temp_pool;
    const char *err;
    int bad_request = 0,
        has_responded = 0;

    /* Step 1: Send AP_FCGI_BEGIN_REQUEST */
    rv = send_begin_request(conn, request_id);
    if (rv != APR_SUCCESS) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01073)
                      "Failed Writing Request to %s:", server_portstr);
        conn->close = 1;
        return HTTP_SERVICE_UNAVAILABLE;
    }

    apr_pool_create(&temp_pool, r->pool);
    apr_pool_tag(temp_pool, "proxy_fcgi_do_request");

    /* Step 2: Send Environment via FCGI_PARAMS */
    rv = send_environment(conn, r, temp_pool, request_id);
    if (rv != APR_SUCCESS) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01074)
                      "Failed writing Environment to %s:", server_portstr);
        conn->close = 1;
        return HTTP_SERVICE_UNAVAILABLE;
    }

    /* Step 3: Read records from the back end server and handle them. */
    rv = dispatch(conn, conf, r, temp_pool, request_id,
                  &err, &bad_request, &has_responded,
                  input_brigade);
    if (rv != APR_SUCCESS) {
        /* If the client aborted the connection during retrieval or (partially)
         * sending the response, don't return a HTTP_SERVICE_UNAVAILABLE, since
         * this is not a backend problem. */
        if (r->connection->aborted) {
            ap_log_rerror(APLOG_MARK, APLOG_TRACE1, rv, r,
                          "The client aborted the connection.");
            conn->close = 1;
            return OK;
        }

        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01075)
                      "Error dispatching request to %s: %s%s%s",
                      server_portstr,
                      err ? "(" : "",
                      err ? err : "",
                      err ? ")" : "");
        conn->close = 1;
        if (has_responded) {
            return AP_FILTER_ERROR;
        }
        if (bad_request) {
            return ap_map_http_request_error(rv, HTTP_BAD_REQUEST);
        }
        if (APR_STATUS_IS_TIMEUP(rv)) {
            return HTTP_GATEWAY_TIME_OUT;
        }
        return HTTP_SERVICE_UNAVAILABLE;
    }

    return OK;
}

#define FCGI_SCHEME "FCGI"

#define MAX_MEM_SPOOL 16384

/*
 * This handles fcgi:(dest) URLs
 */
static int proxy_fcgi_handler(request_rec *r, proxy_worker *worker,
                              proxy_server_conf *conf,
                              char *url, const char *proxyname,
                              apr_port_t proxyport)
{
    int status;
    char server_portstr[32];
    conn_rec *origin = NULL;
    proxy_conn_rec *backend = NULL;
    apr_bucket_brigade *input_brigade;
    apr_off_t input_bytes = 0;
    apr_uri_t *uri;

    proxy_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
                                                 &proxy_module);

    apr_pool_t *p = r->pool;


    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01076)
                  "url: %s proxyname: %s proxyport: %d",
                  url, proxyname, proxyport);

    if (ap_cstr_casecmpn(url, "fcgi:", 5) != 0) {
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01077) "declining URL %s", url);
        return DECLINED;
    }

    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01078) "serving URL %s", url);

    /* Create space for state information */
    status = ap_proxy_acquire_connection(FCGI_SCHEME, &backend, worker,
                                         r->server);
    if (status != OK) {
        if (backend) {
            backend->close = 1;
            ap_proxy_release_connection(FCGI_SCHEME, backend, r->server);
        }
        return status;
    }

    backend->is_ssl = 0;

    /* Step One: Determine Who To Connect To */
    uri = apr_palloc(p, sizeof(*uri));
    status = ap_proxy_determine_connection(p, r, conf, worker, backend,
                                           uri, &url, proxyname, proxyport,
                                           server_portstr,
                                           sizeof(server_portstr));
    if (status != OK) {
        goto cleanup;
    }

    /* We possibly reuse input data prefetched in previous call(s), e.g. for a
     * balancer fallback scenario.
     */
    apr_pool_userdata_get((void **)&input_brigade, "proxy-fcgi-input", p);
    if (input_brigade == NULL) {
        const char *old_te = apr_table_get(r->headers_in, "Transfer-Encoding");
        const char *old_cl = NULL;
        if (old_te) {
            apr_table_unset(r->headers_in, "Content-Length");
        }
        else {
            old_cl = apr_table_get(r->headers_in, "Content-Length");
        }

        input_brigade = apr_brigade_create(p, r->connection->bucket_alloc);
        apr_pool_userdata_setn(input_brigade, "proxy-fcgi-input", NULL, p);

        /* Prefetch (nonlocking) the request body so to increase the chance
         * to get the whole (or enough) body and determine Content-Length vs
         * chunked or spooled. By doing this before connecting or reusing the
         * backend, we want to minimize the delay between this connection is
         * considered alive and the first bytes sent (should the client's link
         * be slow or some input filter retain the data). This is a best effort
         * to prevent the backend from closing (from under us) what it thinks is
         * an idle connection, hence to reduce to the minimum the unavoidable
         * local is_socket_connected() vs remote keepalive race condition.
         */
        status = ap_proxy_prefetch_input(r, backend, input_brigade,
                                         APR_NONBLOCK_READ, &input_bytes,
                                         MAX_MEM_SPOOL);
        if (status != OK) {
            goto cleanup;
        }

        /*
         * The request body is streamed by default, using either C-L or
         * chunked T-E, like this:
         *
         *   The whole body (including no body) was received on prefetch, i.e.
         *   the input brigade ends with EOS => C-L = input_bytes.
         *
         *   C-L is known and reliable, i.e. only protocol filters in the input
         *   chain thus none should change the body => use C-L from client.
         *
         *   The administrator has not "proxy-sendcl" which prevents T-E => use
         *   T-E and chunks.
         *
         *   Otherwise we need to determine and set a content-length, so spool
         *   the entire request body to memory/temporary file (MAX_MEM_SPOOL),
         *   such that we finally know its length => C-L = input_bytes.
         */
        if (!APR_BRIGADE_EMPTY(input_brigade)
                && APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(input_brigade))) {
            /* The whole thing fit, so our decision is trivial, use the input
             * bytes for the Content-Length. If we expected no body, and read
             * no body, do not set the Content-Length.
             */
            if (old_cl || old_te || input_bytes) {
                apr_table_setn(r->headers_in, "Content-Length",
                               apr_off_t_toa(p, input_bytes));
                if (old_te) {
                    apr_table_unset(r->headers_in, "Transfer-Encoding");
                }
            }
        }
        else if (old_cl && r->input_filters == r->proto_input_filters) {
            /* Streaming is possible by preserving the existing C-L */
        }
        else if (!apr_table_get(r->subprocess_env, "proxy-sendcl")) {
            /* Streaming is possible using T-E: chunked */
        }
        else {
            /* No streaming, C-L is the only option so spool to memory/file */
            apr_bucket_brigade *tmp_bb;
            apr_off_t remaining_bytes = 0;

            AP_DEBUG_ASSERT(MAX_MEM_SPOOL >= input_bytes);
            tmp_bb = apr_brigade_create(p, r->connection->bucket_alloc);
            status = ap_proxy_spool_input(r, backend, tmp_bb, &remaining_bytes,
                                          MAX_MEM_SPOOL - input_bytes);
            if (status != OK) {
                goto cleanup;
            }

            APR_BRIGADE_CONCAT(input_brigade, tmp_bb);
            input_bytes += remaining_bytes;

            apr_table_setn(r->headers_in, "Content-Length",
                           apr_off_t_toa(p, input_bytes));
            if (old_te) {
                apr_table_unset(r->headers_in, "Transfer-Encoding");
            }
        }
    }

    /* This scheme handler does not reuse connections by default, to
     * avoid tying up a fastcgi that isn't expecting to work on
     * parallel requests.  But if the user went out of their way to
     * type the default value of disablereuse=off, we'll allow it.
     */
    backend->close = 1;
    if (worker->s->disablereuse_set && !worker->s->disablereuse) {
        backend->close = 0;
    }

    /* Step Two: Make the Connection */
    if (ap_proxy_check_connection(FCGI_SCHEME, backend, r->server, 0,
                                  PROXY_CHECK_CONN_EMPTY)
            && ap_proxy_connect_backend(FCGI_SCHEME, backend, worker,
                                        r->server)) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01079)
                      "failed to make connection to backend: %s",
                      backend->hostname);
        status = HTTP_SERVICE_UNAVAILABLE;
        goto cleanup;
    }

    /* Step Three: Process the Request */
    status = fcgi_do_request(p, r, backend, origin, dconf, uri, url,
                             server_portstr, input_brigade);

cleanup:
    ap_proxy_release_connection(FCGI_SCHEME, backend, r->server);
    return status;
}

static void *fcgi_create_dconf(apr_pool_t *p, char *path)
{
    fcgi_dirconf_t *a;

    a = (fcgi_dirconf_t *)apr_pcalloc(p, sizeof(fcgi_dirconf_t));
    a->backend_type = BACKEND_DEFAULT_UNKNOWN;
    a->env_fixups = apr_array_make(p, 20, sizeof(sei_entry));

    return a;
}

static void *fcgi_merge_dconf(apr_pool_t *p, void *basev, void *overridesv)
{
    fcgi_dirconf_t *a, *base, *over;

    a     = (fcgi_dirconf_t *)apr_pcalloc(p, sizeof(fcgi_dirconf_t));
    base  = (fcgi_dirconf_t *)basev;
    over  = (fcgi_dirconf_t *)overridesv;

    a->backend_type = (over->backend_type != BACKEND_DEFAULT_UNKNOWN)
                      ? over->backend_type
                      : base->backend_type;
    a->env_fixups = apr_array_append(p, base->env_fixups, over->env_fixups);
    return a;
}

static const char *cmd_servertype(cmd_parms *cmd, void *in_dconf,
                                   const char *val)
{
    fcgi_dirconf_t *dconf = in_dconf;

    if (!strcasecmp(val, "GENERIC")) {
       dconf->backend_type = BACKEND_GENERIC;
    }
    else if (!strcasecmp(val, "FPM")) {
       dconf->backend_type = BACKEND_FPM;
    }
    else {
        return "ProxyFCGIBackendType requires one of the following arguments: "
               "'GENERIC', 'FPM'";
    }

    return NULL;
}


static const char *cmd_setenv(cmd_parms *cmd, void *in_dconf,
                              const char *arg1, const char *arg2,
                              const char *arg3)
{
    fcgi_dirconf_t *dconf = in_dconf;
    const char *err;
    sei_entry *new;
    const char *envvar = arg2;

    new = apr_array_push(dconf->env_fixups);
    new->cond = ap_expr_parse_cmd(cmd, arg1, 0, &err, NULL);
    if (err) {
        return apr_psprintf(cmd->pool, "Could not parse expression \"%s\": %s",
                            arg1, err);
    }

    if (envvar[0] == '!') {
        /* Unset mode. */
        if (arg3) {
            return apr_psprintf(cmd->pool, "Third argument (\"%s\") is not "
                                "allowed when using ProxyFCGISetEnvIf's unset "
                                "mode (%s)", arg3, envvar);
        }
        else if (!envvar[1]) {
            /* i.e. someone tried to give us a name of just "!" */
            return "ProxyFCGISetEnvIf: \"!\" is not a valid variable name";
        }

        new->subst = NULL;
    }
    else {
        /* Set mode. */
        if (!arg3) {
            /* A missing expr-value should be treated as empty. */
            arg3 = "";
        }

        new->subst = ap_expr_parse_cmd(cmd, arg3, AP_EXPR_FLAG_STRING_RESULT, &err, NULL);
        if (err) {
            return apr_psprintf(cmd->pool, "Could not parse expression \"%s\": %s",
                                arg3, err);
        }
    }

    new->envname = envvar;

    return NULL;
}
static void register_hooks(apr_pool_t *p)
{
    proxy_hook_scheme_handler(proxy_fcgi_handler, NULL, NULL, APR_HOOK_FIRST);
    proxy_hook_canon_handler(proxy_fcgi_canon, NULL, NULL, APR_HOOK_FIRST);
}

static const command_rec command_table[] = {
    AP_INIT_TAKE1("ProxyFCGIBackendType", cmd_servertype, NULL, OR_FILEINFO,
                  "Specify the type of FastCGI server: 'Generic', 'FPM'"),
    AP_INIT_TAKE23("ProxyFCGISetEnvIf", cmd_setenv, NULL, OR_FILEINFO,
                  "expr-condition env-name expr-value"),
    { NULL }
};

AP_DECLARE_MODULE(proxy_fcgi) = {
    STANDARD20_MODULE_STUFF,
    fcgi_create_dconf,          /* create per-directory config structure */
    fcgi_merge_dconf,           /* merge per-directory config structures */
    NULL,                       /* create per-server config structure */
    NULL,                       /* merge per-server config structures */
    command_table,              /* command apr_table_t */
    register_hooks              /* register hooks */
};
