/*
 * 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 "httpd.h"
#include "http_request.h"
#include "apr_strings.h"
#include "apr_portable.h"
#include "apr_pools.h"
#include "apr_file_io.h"
#include "util_script.h"
#include "fcgid_bridge.h"
#include "fcgid_pm.h"
#include "fcgid_proctbl.h"
#include "fcgid_proc.h"
#include "fcgid_conf.h"
#include "fcgid_spawn_ctl.h"
#include "fcgid_protocol.h"
#include "fcgid_bucket.h"
#define FCGID_APPLY_TRY_COUNT 2
#define FCGID_REQUEST_COUNT 32

static fcgid_procnode *apply_free_procnode(request_rec *r,
                                           fcgid_command * command)
{
    /* Scan idle list, find a node match inode, deviceid and groupid
       If there is no one there, return NULL */
    fcgid_procnode *previous_node, *current_node, *next_node;
    fcgid_procnode *busy_list_header, *proc_table;
    apr_ino_t inode = command->inode;
    apr_dev_t deviceid = command->deviceid;
    uid_t uid = command->uid;
    gid_t gid = command->gid;
    const char *cmdline = command->cmdline;

    proc_table = proctable_get_table_array();
    previous_node = proctable_get_idle_list();
    busy_list_header = proctable_get_busy_list();

    proctable_lock(r);
    current_node = &proc_table[previous_node->next_index];
    while (current_node != proc_table) {
        next_node = &proc_table[current_node->next_index];

        if (current_node->inode == inode
            && current_node->deviceid == deviceid
            && !strcmp(current_node->cmdline, cmdline)
            && current_node->vhost_id == command->vhost_id
            && current_node->uid == uid && current_node->gid == gid) {
            /* Unlink from idle list */
            previous_node->next_index = current_node->next_index;

            /* Link to busy list */
            current_node->next_index = busy_list_header->next_index;
            busy_list_header->next_index = current_node - proc_table;

            proctable_unlock(r);
            return current_node;
        }
        else
            previous_node = current_node;

        current_node = next_node;
    }
    proctable_unlock(r);

    /* Found nothing */
    return NULL;
}

static void
return_procnode(request_rec *r,
                fcgid_procnode *procnode, int communicate_error)
{
    fcgid_procnode *previous_node, *current_node, *next_node;
    fcgid_procnode *proc_table = proctable_get_table_array();
    fcgid_procnode *error_list_header = proctable_get_error_list();
    fcgid_procnode *idle_list_header = proctable_get_idle_list();
    fcgid_procnode *busy_list_header = proctable_get_busy_list();

    proctable_lock(r);

    /* Unlink the node from busy list first */
    previous_node = busy_list_header;
    current_node = &proc_table[previous_node->next_index];
    while (current_node != proc_table) {
        next_node = &proc_table[current_node->next_index];
        if (current_node == procnode) {
            /* Unlink from busy list */
            previous_node->next_index = current_node->next_index;
            break;
        }
        else
            previous_node = current_node;
        current_node = next_node;
    }

    /* Return to error list or idle list */
    if (communicate_error) {
        /* Link to error list */
        procnode->next_index = error_list_header->next_index;
        error_list_header->next_index = procnode - proc_table;
    }
    else {
        /* Link to idle list */
        procnode->next_index = idle_list_header->next_index;
        idle_list_header->next_index = procnode - proc_table;
    }

    proctable_unlock(r);
}

static int count_busy_processes(request_rec *r, fcgid_command *command)
{
    int result = 0;
    fcgid_procnode *previous_node, *current_node, *next_node;
    fcgid_procnode *proc_table = proctable_get_table_array();
    fcgid_procnode *busy_list_header = proctable_get_busy_list();

    proctable_lock(r);

    previous_node = busy_list_header;
    current_node = &proc_table[previous_node->next_index];
    while (current_node != proc_table) {
        if (current_node->inode == command->inode
            && current_node->deviceid == command->deviceid
            && !strcmp(current_node->cmdline, command->cmdline)
            && current_node->vhost_id == command->vhost_id
            && current_node->uid == command->uid
            && current_node->gid == command->gid) {
            result++;
        }
        next_node = &proc_table[current_node->next_index];
        current_node = next_node;
    }

    proctable_unlock(r);

    return result;
}

apr_status_t bucket_ctx_cleanup(void *thectx)
{
    /* Cleanup jobs:
       1. Free bucket buffer
       2. Return procnode
       NOTE: ipc will be clean when request pool cleanup, so I don't need to close it here
     */
    fcgid_bucket_ctx *ctx = (fcgid_bucket_ctx *) thectx;
    request_rec *r = ctx->ipc.request;

    /* Free bucket buffer */
    if (ctx->buffer) {
        apr_bucket_destroy(ctx->buffer);
        ctx->buffer = NULL;
    }

    /* proc_close_ipc() and ipc_handle_cleanup() do their own sanity
     * checks, but we'll do our own anyway
     */
    if (ctx->ipc.ipc_handle_info) {
        proc_close_ipc(&ctx->ipc);
        ctx->ipc.ipc_handle_info = NULL;
    }

    if (ctx->procnode) {
        ++ctx->procnode->requests_handled;

        /* Return procnode
           I will return this slot to idle(or error) list
         */
        if (ctx->procnode->diewhy == FCGID_DIE_BUSY_TIMEOUT) {
            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
                          "mod_fcgid: %s took longer than busy timeout "
                          "(%d secs)",
                          r->uri,
                          ctx->procnode->cmdopts.busy_timeout);
            return_procnode(r, ctx->procnode, 1 /* busy timeout */ );
        }
        else if (ctx->has_error) {
            ctx->procnode->diewhy = FCGID_DIE_COMM_ERROR;
            return_procnode(r, ctx->procnode, 1 /* communication error */ );
        }
        else if (ctx->procnode->cmdopts.max_requests_per_process
                 && ctx->procnode->requests_handled >=
                 ctx->procnode->cmdopts.max_requests_per_process) {
            ctx->procnode->diewhy = FCGID_DIE_LIFETIME_EXPIRED;
            return_procnode(r, ctx->procnode, 1 /* handled all requests */ );
        }
        else
            return_procnode(r, ctx->procnode, 0 /* communication ok */ );

        ctx->procnode = NULL;
    }

    return APR_SUCCESS;
}

static int getsfunc_fcgid_BRIGADE(char *buf, int len, void *arg)
{
    apr_bucket_brigade *bb = (apr_bucket_brigade *) arg;
    const char *dst_end = buf + len - 1;        /* leave room for terminating null */
    char *dst = buf;
    apr_bucket *e = APR_BRIGADE_FIRST(bb);
    apr_status_t rv;
    int done = 0;
    int getLF = 0;
    int getColon = 0;

    while ((dst < dst_end) && !done && e != APR_BRIGADE_SENTINEL(bb)) {
        const char *bucket_data;
        apr_size_t bucket_data_len;
        const char *src;
        const char *src_end;
        apr_bucket *next;

        rv = apr_bucket_read(e, &bucket_data, &bucket_data_len,
                             APR_BLOCK_READ);
        if (rv != APR_SUCCESS) {
            return 0;
        }

        /* Move on to next bucket if it's fastcgi header bucket */
        if (e->type == &ap_bucket_type_fcgid_header
            || e->type == &apr_bucket_type_immortal) {
            next = APR_BUCKET_NEXT(e);
            apr_bucket_delete(e);
            e = next;
            if (getLF) {
                done = 1;
            }
            continue;
        }

        if (bucket_data_len == 0)
            return 0;

        /* Base on RFC2616 section 4.2 */
        src = bucket_data;
        src_end = bucket_data + bucket_data_len;
        while ((src < src_end) && (dst < dst_end) && !done) {
            if (*src == ':')
                getColon = 1;

            if (getLF && ((*src != ' ' && *src != '\t') || !getColon)) {
                done = 1;
                getColon = 0;
                break;
            }
            else if (getLF && (*src == ' ' || *src == '\t')) {
                *dst++ = '\r';
                *dst++ = '\n';
                getLF = 0;
            }

            if (*src == '\n') {
                getLF = 1;
            }
            else if (*src != '\r') {
                *dst++ = *src;
            }
            src++;
        }

        if (src < src_end) {
            apr_bucket_split(e, src - bucket_data);
        }
        next = APR_BUCKET_NEXT(e);
        apr_bucket_delete(e);
        e = next;
    }
    *dst = 0;
    return done;
}

static int
handle_request_ipc(request_rec *r, int role,
                   apr_bucket_brigade *output_brigade,
                   fcgid_bucket_ctx *bucket_ctx, const char **location_ptr)
{
    int cond_status;
    apr_status_t rv;
    apr_bucket_brigade *brigade_stdout;
    char sbuf[MAX_STRING_LEN];
    const char *location;

    /* Write output_brigade to fastcgi server */
    if ((rv = proc_write_ipc(&bucket_ctx->ipc,
                             output_brigade)) != APR_SUCCESS) {
        bucket_ctx->has_error = 1;
        return HTTP_INTERNAL_SERVER_ERROR;
    }

    /* Create brigade */
    brigade_stdout =
        apr_brigade_create(r->pool, r->connection->bucket_alloc);
    APR_BRIGADE_INSERT_TAIL(brigade_stdout,
                            ap_bucket_fcgid_header_create(r->connection->
                                                          bucket_alloc,
                                                          bucket_ctx));

    /* Check the script header first; return immediately on error. */
    if ((cond_status =
         ap_scan_script_header_err_core(r, sbuf, getsfunc_fcgid_BRIGADE,
                                        brigade_stdout)) >= 400) {
        return cond_status;
    }

    /* Check redirect */
    location = apr_table_get(r->headers_out, "Location");

    if (location && location[0] == '/' && r->status == 200) {
        /* This redirect needs to be a GET no matter what the original 
         * method was. 
         */
        r->method = apr_pstrdup(r->pool, "GET");
        r->method_number = M_GET;

        /* We already read the message body (if any), so don't allow 
         * the redirected request to think it has one.  We can ignore 
         * Transfer-Encoding, since we used REQUEST_CHUNKED_ERROR. 
         */
        apr_table_unset(r->headers_in, "Content-Length");

        *location_ptr = location;
        return HTTP_OK;
    }
    else if (location && r->status == 200) {
        /* XX Note that if a script wants to produce its own Redirect 
         * body, it now has to explicitly *say* "Status: 302" 
         */
        return HTTP_MOVED_TEMPORARILY;
    }

    /* Now pass to output filter */
    if (role == FCGI_RESPONDER
        && (rv = ap_pass_brigade(r->output_filters,
                                 brigade_stdout)) != APR_SUCCESS) {
        if (!APR_STATUS_IS_ECONNABORTED(rv)) {
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, r,
                          "mod_fcgid: ap_pass_brigade failed in "
                          "handle_request_ipc function");
        }

        return HTTP_INTERNAL_SERVER_ERROR;
    }

    return cond_status;
}

static int
handle_request(request_rec * r, int role, fcgid_cmd_conf *cmd_conf,
               apr_bucket_brigade * output_brigade)
{
    fcgid_command fcgi_request;
    fcgid_bucket_ctx *bucket_ctx;
    int i, j, cond_status;
    const char *location = NULL;

    bucket_ctx = apr_pcalloc(r->pool, sizeof(*bucket_ctx));

    bucket_ctx->ipc.request = r;
    apr_pool_cleanup_register(r->pool, bucket_ctx,
                              bucket_ctx_cleanup, apr_pool_cleanup_null);

    /* Try to get a connected ipc handle */
    for (i = 0; i < FCGID_REQUEST_COUNT; i++) {
        /* Apply a free process slot, send a spawn request if I can't get one */
        for (j = 0; j < FCGID_APPLY_TRY_COUNT; j++) {
            /* Init spawn request */
            procmgr_init_spawn_cmd(&fcgi_request, r, cmd_conf);

            bucket_ctx->ipc.connect_timeout =
                fcgi_request.cmdopts.ipc_connect_timeout;
            bucket_ctx->ipc.communation_timeout =
                fcgi_request.cmdopts.ipc_comm_timeout;

            /* Apply a process slot */
            bucket_ctx->procnode = apply_free_procnode(r, &fcgi_request);
            if (bucket_ctx->procnode)
                break;

            /* Avoid sleeping the very first time through if there are no
               busy processes; the problem is just that we haven't spawned
               anything yet, so waiting is pointless */
            if (i > 0 || j > 0 || count_busy_processes(r, &fcgi_request)) {
                apr_sleep(apr_time_from_sec(1));

                bucket_ctx->procnode = apply_free_procnode(r, &fcgi_request);
                if (bucket_ctx->procnode)
                    break;
            }

            /* Send a spawn request if I can't get a process slot */
            procmgr_post_spawn_cmd(&fcgi_request, r);
        }

        /* Connect to the fastcgi server */
        if (bucket_ctx->procnode) {
            if (proc_connect_ipc(bucket_ctx->procnode,
                                 &bucket_ctx->ipc) != APR_SUCCESS) {
                proc_close_ipc(&bucket_ctx->ipc);
                bucket_ctx->procnode->diewhy = FCGID_DIE_CONNECT_ERROR;
                return_procnode(r, bucket_ctx->procnode, 1 /* has error */ );
                bucket_ctx->procnode = NULL;
            }
            else
                break;
        }
    }

    /* Now I get a connected ipc handle */
    if (!bucket_ctx->procnode) {
        ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
                      "mod_fcgid: can't apply process slot for %s",
                      cmd_conf->cmdline);
        return HTTP_SERVICE_UNAVAILABLE;
    }
    bucket_ctx->active_time = bucket_ctx->procnode->last_active_time =
        apr_time_now();
    bucket_ctx->procnode->diewhy = FCGID_DIE_KILLSELF;

    cond_status = handle_request_ipc(r, role, output_brigade,
                                     bucket_ctx, &location);

    /* Release the process ASAP.  This may already have been done in
     * ap_pass_brigade() by fcgid_header_bucket_read(), but not in the
     * case where handle_request_ipc() returned early without reading
     * the body of the HTTP response.  This could be because of an error,
     * or because of a role or a status code which permits us to ignore
     * the message body.
     *
     * As an example, when handling a request in the FCGI_AUTHORIZER role,
     * we don't read through to the end of the response from the process,
     * we just read the HTTP headers.  That means each phase of the
     * request handling sequence (e.g., authentication, authorization, etc.)
     * will require its own process unless we make sure to always release
     * any process we acquired regardless of whether we're reading the
     * response body.
     *
     * As another example, if we perform or cause an internal redirection
     * (for instance, by returning an error code that invokes a script
     * handler in ap_die() because of an ErrorDocument configuration), then
     * we must also release the process we acquired here so that it is
     * potentially available during the next handling phase.
     */

    apr_pool_cleanup_run(r->pool, bucket_ctx, bucket_ctx_cleanup);

    /* Perform internal redirection if necessary */
    if (location) {
        ap_internal_redirect_handler(location, r);
    }

    /* Retrun condition status */
    return cond_status;
}

static int add_request_body(request_rec *r, apr_pool_t *request_pool,
                            apr_bucket_brigade *output_brigade)
{
    apr_bucket *bucket_input, *bucket_header;
    apr_file_t *fd = NULL;
    apr_off_t cur_pos = 0, request_size = 0;
    apr_status_t rv;
    FCGI_Header *stdin_request_header;
    fcgid_server_conf *sconf = ap_get_module_config(r->server->module_config,
                                                    &fcgid_module);
    int seen_eos;

    /* Stdin header and body */
    /* I have to read all the request into memory before sending it 
       to fastcgi application server, this prevents slow clients from 
       keeping the server in processing too long. 
       But sometimes it's not acceptable (think about uploading a large attachment)
       Request will be stored in tmp file if the size larger than max_mem_request_len
     */
    seen_eos = 0;
    do {
        apr_bucket_brigade *input_brigade = apr_brigade_create(request_pool,
                                                               r->connection->
                                                               bucket_alloc);

        if ((rv = ap_get_brigade(r->input_filters, input_brigade,
                                 AP_MODE_READBYTES,
                                 APR_BLOCK_READ,
                                 HUGE_STRING_LEN)) != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, r,
                          "mod_fcgid: can't get data from http client");
            apr_brigade_destroy(output_brigade);
            apr_brigade_destroy(input_brigade);
            return HTTP_INTERNAL_SERVER_ERROR;
        }

        for (bucket_input = APR_BRIGADE_FIRST(input_brigade);
             bucket_input != APR_BRIGADE_SENTINEL(input_brigade);
             bucket_input = APR_BUCKET_NEXT(bucket_input)) {
            const char *data;
            apr_size_t len;
            apr_bucket *bucket_stdin;

            if (APR_BUCKET_IS_EOS(bucket_input)) {
                seen_eos = 1;
                break;
            }

            if (APR_BUCKET_IS_METADATA(bucket_input))
                continue;

            if ((rv = apr_bucket_read(bucket_input, &data, &len,
                                      APR_BLOCK_READ)) != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, r,
                              "mod_fcgid: can't read request from HTTP client");
                apr_brigade_destroy(input_brigade);
                apr_brigade_destroy(output_brigade);
                return HTTP_INTERNAL_SERVER_ERROR;
            }

            /* Append a header, and the the bucket */
            stdin_request_header = apr_bucket_alloc(sizeof(FCGI_Header),
                                                    r->connection->
                                                    bucket_alloc);
            bucket_header =
                apr_bucket_heap_create((const char *) stdin_request_header,
                                       sizeof(*stdin_request_header),
                                       apr_bucket_free,
                                       r->connection->bucket_alloc);

            request_size += len;
            if (request_size > sconf->max_request_len) {
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
                              "mod_fcgid: HTTP request length %" APR_OFF_T_FMT
                              " (so far) exceeds MaxRequestLen (%"
                              APR_OFF_T_FMT ")", request_size,
                              sconf->max_request_len);
                return HTTP_INTERNAL_SERVER_ERROR;
            }

            if (request_size > sconf->max_mem_request_len) {
                apr_size_t wrote_len;
                static const char *fd_key = "fcgid_fd";

                if (fd == NULL) {
                    void *tmp;
                    apr_pool_userdata_get(&tmp, fd_key, r->connection->pool);
                    fd = tmp;

                    if (fd != NULL) {
                        if ((rv = apr_file_trunc(fd, 0)) != APR_SUCCESS) {
                            ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, r,
                                          "mod_fcgid: can't truncate existing "
                                          "temporary file");
                            return HTTP_INTERNAL_SERVER_ERROR;
                        }
                    }
                }

                if (fd == NULL) {
                    const char *tempdir = NULL;
                    char *template;

                    rv = apr_temp_dir_get(&tempdir, r->pool);
                    if (rv != APR_SUCCESS) {
                        ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, r,
                                      "mod_fcgid: can't get tmp dir");
                        return HTTP_INTERNAL_SERVER_ERROR;
                    }

                    apr_filepath_merge(&template, tempdir,
                                       "fcgid.tmp.XXXXXX",
                                       APR_FILEPATH_NATIVE, r->pool);
                    rv = apr_file_mktemp(&fd, template, 0,
                                         r->connection->pool);
                    if (rv != APR_SUCCESS) {
                        ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, r,
                                      "mod_fcgid: can't open tmp file fot stdin request");
                        return HTTP_INTERNAL_SERVER_ERROR;
                    }
                    apr_pool_userdata_set((const void *) fd, fd_key,
                                          apr_pool_cleanup_null,
                                          r->connection->pool);
                }

                /* Write request to tmp file */
                if ((rv =
                     apr_file_write_full(fd, (const void *) data, len,
                                         &wrote_len)) != APR_SUCCESS
                    || len != wrote_len) {
                    ap_log_rerror(APLOG_MARK, APLOG_WARNING,
                                  rv, r,
                                  "mod_fcgid: can't write tmp file for stdin request");
                    return HTTP_INTERNAL_SERVER_ERROR;
                }
                /* Create file bucket */
                bucket_stdin =
                    apr_bucket_file_create(fd, cur_pos, len, r->pool,
                                           r->connection->bucket_alloc);
                cur_pos += len;
            }
            else {
                if (APR_BUCKET_IS_HEAP(bucket_input))
                    apr_bucket_copy(bucket_input, &bucket_stdin);
                else {
                    /* mod_ssl have a bug? */
                    char *pcopydata =
                        apr_bucket_alloc(len, r->connection->bucket_alloc);
                    memcpy(pcopydata, data, len);
                    bucket_stdin =
                        apr_bucket_heap_create(pcopydata, len,
                                               apr_bucket_free,
                                               r->connection->bucket_alloc);
                }
            }

            if (!init_header(FCGI_STDIN, 1, len, 0, stdin_request_header)) {
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
                              "mod_fcgid: header overflow");
                apr_brigade_destroy(input_brigade);
                apr_brigade_destroy(output_brigade);
                return HTTP_INTERNAL_SERVER_ERROR;
            }
            APR_BRIGADE_INSERT_TAIL(output_brigade, bucket_header);
            APR_BRIGADE_INSERT_TAIL(output_brigade, bucket_stdin);
        }

        apr_brigade_destroy(input_brigade);
    }
    while (!seen_eos);

    /* Append an empty body stdin header */
    stdin_request_header = apr_bucket_alloc(sizeof(FCGI_Header),
                                            r->connection->bucket_alloc);
    bucket_header =
        apr_bucket_heap_create((const char *) stdin_request_header,
                               sizeof(*stdin_request_header),
                               apr_bucket_free, r->connection->bucket_alloc);
    if (!init_header(FCGI_STDIN, 1, 0, 0, stdin_request_header)) {
        ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
                      "mod_fcgid: header overflow");
        return HTTP_INTERNAL_SERVER_ERROR;
    }
    APR_BRIGADE_INSERT_TAIL(output_brigade, bucket_header);

    return 0;
}

int bridge_request(request_rec * r, int role, fcgid_cmd_conf *cmd_conf)
{
    apr_bucket_brigade *output_brigade;
    apr_bucket *bucket_eos;
    char **envp = ap_create_environment(r->pool,
                                        r->subprocess_env);
    int rc;

    /* Create brigade for the request to fastcgi server */
    output_brigade =
        apr_brigade_create(r->pool, r->connection->bucket_alloc);

    /* Build the begin request and environ request, append them to output_brigade */
    if (!build_begin_block
        (role, r, r->connection->bucket_alloc, output_brigade)
        || !build_env_block(r, envp, r->connection->bucket_alloc,
                            output_brigade)) {
        ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
                      "mod_fcgid: can't build begin or env request");
        return HTTP_INTERNAL_SERVER_ERROR;
    }

    if (role == FCGI_RESPONDER) {
        rc = add_request_body(r, r->pool, output_brigade);
        if (rc) {
            return rc;
        }
    }

    /* The eos bucket now */
    bucket_eos = apr_bucket_eos_create(r->connection->bucket_alloc);
    APR_BRIGADE_INSERT_TAIL(output_brigade, bucket_eos);

    /* Bridge the request */
    return handle_request(r, role, cmd_conf, output_brigade);
}
