/* 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.
 */

/*
 * mod_proxy_scgi.c
 * Proxy backend module for the SCGI protocol
 * (http://python.ca/scgi/protocol.txt)
 *
 * Andr� Malo (nd/perlig.de), August 2007
 */

#define APR_WANT_MEMFUNC
#define APR_WANT_STRFUNC
#include "apr_strings.h"
#include "ap_hooks.h"
#include "apr_optional_hooks.h"
#include "apr_buckets.h"

#include "httpd.h"
#include "http_config.h"
#include "http_log.h"
#include "http_protocol.h"
#include "http_request.h"
#include "util_script.h"

#include "mod_proxy.h"
#include "scgi.h"


#define SCHEME "scgi"
#define PROXY_FUNCTION "SCGI"
#define SCGI_MAGIC "SCGI"
#define SCGI_PROTOCOL_VERSION "1"

/* just protect from typos */
#define CONTENT_LENGTH "CONTENT_LENGTH"
#define GATEWAY_INTERFACE "GATEWAY_INTERFACE"

module AP_MODULE_DECLARE_DATA proxy_scgi_module;


typedef enum {
    scgi_internal_redirect,
    scgi_sendfile
} scgi_request_type;

typedef struct {
    const char *location;    /* target URL */
    scgi_request_type type;  /* type of request */
} scgi_request_config;

const char *scgi_sendfile_off = "off";
const char *scgi_sendfile_on = "X-Sendfile";
const char *scgi_internal_redirect_off = "off";
const char *scgi_internal_redirect_on = "Location";

typedef struct {
    const char *sendfile;
    const char *internal_redirect;
} scgi_config;


/*
 * We create our own bucket type, which is actually derived (c&p) from the
 * socket bucket.
 * Maybe some time this should be made more abstract (like passing an
 * interception function to read or something) and go into the ap_ or
 * even apr_ namespace.
 */

typedef struct {
    apr_socket_t *sock;
    apr_off_t *counter;
} socket_ex_data;

static apr_bucket *bucket_socket_ex_create(socket_ex_data *data,
                                           apr_bucket_alloc_t *list);


static apr_status_t bucket_socket_ex_read(apr_bucket *a, const char **str,
                                          apr_size_t *len,
                                          apr_read_type_e block)
{
    socket_ex_data *data = a->data;
    apr_socket_t *p = data->sock;
    char *buf;
    apr_status_t rv;
    apr_interval_time_t timeout;

    if (block == APR_NONBLOCK_READ) {
        apr_socket_timeout_get(p, &timeout);
        apr_socket_timeout_set(p, 0);
    }

    *str = NULL;
    *len = APR_BUCKET_BUFF_SIZE;
    buf = apr_bucket_alloc(*len, a->list);

    rv = apr_socket_recv(p, buf, len);

    if (block == APR_NONBLOCK_READ) {
        apr_socket_timeout_set(p, timeout);
    }

    if (rv != APR_SUCCESS && rv != APR_EOF) {
        apr_bucket_free(buf);
        return rv;
    }

    if (*len > 0) {
        apr_bucket_heap *h;

        /* count for stats */
        *data->counter += *len;

        /* Change the current bucket to refer to what we read */
        a = apr_bucket_heap_make(a, buf, *len, apr_bucket_free);
        h = a->data;
        h->alloc_len = APR_BUCKET_BUFF_SIZE; /* note the real buffer size */
        *str = buf;
        APR_BUCKET_INSERT_AFTER(a, bucket_socket_ex_create(data, a->list));
    }
    else {
        apr_bucket_free(buf);
        a = apr_bucket_immortal_make(a, "", 0);
        *str = a->data;
    }
    return APR_SUCCESS;
}

static const apr_bucket_type_t bucket_type_socket_ex = {
    "SOCKET_EX", 5, APR_BUCKET_DATA,
    apr_bucket_destroy_noop,
    bucket_socket_ex_read,
    apr_bucket_setaside_notimpl,
    apr_bucket_split_notimpl,
    apr_bucket_copy_notimpl
};

static apr_bucket *bucket_socket_ex_make(apr_bucket *b, socket_ex_data *data)
{
    b->type        = &bucket_type_socket_ex;
    b->length      = (apr_size_t)(-1);
    b->start       = -1;
    b->data        = data;
    return b;
}

static apr_bucket *bucket_socket_ex_create(socket_ex_data *data,
                                           apr_bucket_alloc_t *list)
{
    apr_bucket *b = apr_bucket_alloc(sizeof(*b), list);

    APR_BUCKET_INIT(b);
    b->free = apr_bucket_free;
    b->list = list;
    return bucket_socket_ex_make(b, data);
}


/*
 * Canonicalize scgi-like URLs.
 */
static int scgi_canon(request_rec *r, char *url)
{
    char *host, sport[sizeof(":65535")];
    const char *err, *path;
    apr_port_t port, def_port;

    if (ap_cstr_casecmpn(url, SCHEME "://", sizeof(SCHEME) + 2)) {
        return DECLINED;
    }
    url += sizeof(SCHEME); /* Keep slashes */

    port = def_port = SCGI_DEF_PORT;

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

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

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

    path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0,
                             r->proxyreq);
    if (!path) {
        return HTTP_BAD_REQUEST;
    }

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

    if (apr_table_get(r->subprocess_env, "proxy-scgi-pathinfo")) {
        r->path_info = apr_pstrcat(r->pool, "/", path, NULL);
    }

    return OK;
}


/*
 * Send a block of data, ensure, everything is sent
 */
static int sendall(proxy_conn_rec *conn, const char *buf, apr_size_t length,
                   request_rec *r)
{
    apr_status_t rv;
    apr_size_t written;

    while (length > 0) {
        written = length;
        if ((rv = apr_socket_send(conn->sock, buf, &written)) != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(00858)
                          "sending data to %s:%u failed",
                          conn->hostname, conn->port);
            return HTTP_SERVICE_UNAVAILABLE;
        }

        /* count for stats */
        conn->worker->s->transferred += written;
        buf += written;
        length -= written;
    }

    return OK;
}


/*
 * Send SCGI header block
 */
static int send_headers(request_rec *r, proxy_conn_rec *conn)
{
    char *buf, *cp, *bodylen;
    const char *ns_len;
    const apr_array_header_t *env_table;
    const apr_table_entry_t *env;
    int j;
    apr_size_t len, bodylen_size;
    apr_size_t headerlen =   sizeof(CONTENT_LENGTH)
                           + sizeof(SCGI_MAGIC)
                           + sizeof(SCGI_PROTOCOL_VERSION);

    ap_add_common_vars(r);
    ap_add_cgi_vars(r);

    /*
     * The header blob basically takes the environment and concatenates
     * keys and values using 0 bytes. There are special treatments here:
     *   - GATEWAY_INTERFACE and SCGI_MAGIC are dropped
     *   - CONTENT_LENGTH is always set and must be sent as the very first
     *     variable
     *
     * Additionally it's wrapped into a so-called netstring (see SCGI spec)
     */
    env_table = apr_table_elts(r->subprocess_env);
    env = (apr_table_entry_t *)env_table->elts;
    for (j = 0; j < env_table->nelts; ++j) {
        if (   (!strcmp(env[j].key, GATEWAY_INTERFACE))
            || (!strcmp(env[j].key, CONTENT_LENGTH))
            || (!strcmp(env[j].key, SCGI_MAGIC))) {
            continue;
        }
        headerlen += strlen(env[j].key) + strlen(env[j].val) + 2;
    }
    bodylen = apr_psprintf(r->pool, "%" APR_OFF_T_FMT, r->remaining);
    bodylen_size = strlen(bodylen) + 1;
    headerlen += bodylen_size;

    ns_len = apr_psprintf(r->pool, "%" APR_SIZE_T_FMT ":", headerlen);
    len = strlen(ns_len);
    headerlen += len + 1; /* 1 == , */
    cp = buf = apr_palloc(r->pool, headerlen);
    memcpy(cp, ns_len, len);
    cp += len;

    memcpy(cp, CONTENT_LENGTH, sizeof(CONTENT_LENGTH));
    cp += sizeof(CONTENT_LENGTH);
    memcpy(cp, bodylen, bodylen_size);
    cp += bodylen_size;
    memcpy(cp, SCGI_MAGIC, sizeof(SCGI_MAGIC));
    cp += sizeof(SCGI_MAGIC);
    memcpy(cp, SCGI_PROTOCOL_VERSION, sizeof(SCGI_PROTOCOL_VERSION));
    cp += sizeof(SCGI_PROTOCOL_VERSION);

    for (j = 0; j < env_table->nelts; ++j) {
        if (   (!strcmp(env[j].key, GATEWAY_INTERFACE))
            || (!strcmp(env[j].key, CONTENT_LENGTH))
            || (!strcmp(env[j].key, SCGI_MAGIC))) {
            continue;
        }
        len = strlen(env[j].key) + 1;
        memcpy(cp, env[j].key, len);
        cp += len;
        len = strlen(env[j].val) + 1;
        memcpy(cp, env[j].val, len);
        cp += len;
    }
    *cp++ = ',';

    return sendall(conn, buf, headerlen, r);
}


/*
 * Send request body (if any)
 */
static int send_request_body(request_rec *r, proxy_conn_rec *conn)
{
    if (ap_should_client_block(r)) {
        char *buf = apr_palloc(r->pool, AP_IOBUFSIZE);
        int status;
        long readlen;

        readlen = ap_get_client_block(r, buf, AP_IOBUFSIZE);
        while (readlen > 0) {
            status = sendall(conn, buf, (apr_size_t)readlen, r);
            if (status != OK) {
                return HTTP_SERVICE_UNAVAILABLE;
            }
            readlen = ap_get_client_block(r, buf, AP_IOBUFSIZE);
        }
        if (readlen == -1) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00859)
                          "receiving request body failed");
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    }

    return OK;
}


/*
 * Fetch response from backend and pass back to the front
 */
static int pass_response(request_rec *r, proxy_conn_rec *conn)
{
    apr_bucket_brigade *bb;
    apr_bucket *b;
    const char *location;
    scgi_config *conf;
    socket_ex_data *sock_data;
    int status;

    sock_data = apr_palloc(r->pool, sizeof(*sock_data));
    sock_data->sock = conn->sock;
    sock_data->counter = &conn->worker->s->read;

    bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
    b = bucket_socket_ex_create(sock_data, r->connection->bucket_alloc);
    APR_BRIGADE_INSERT_TAIL(bb, b);
    b = apr_bucket_eos_create(r->connection->bucket_alloc);
    APR_BRIGADE_INSERT_TAIL(bb, b);

    status = ap_scan_script_header_err_brigade_ex(r, bb, NULL,
                                                  APLOG_MODULE_INDEX);
    if (status != OK) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00860)
                      "error reading response headers from %s:%u",
                      conn->hostname, conn->port);
        r->status_line = NULL;
        apr_brigade_destroy(bb);
        return status;
    }

    conf = ap_get_module_config(r->per_dir_config, &proxy_scgi_module);
    if (conf->sendfile && conf->sendfile != scgi_sendfile_off) {
        short err = 1;

        location = apr_table_get(r->err_headers_out, conf->sendfile);
        if (!location) {
            err = 0;
            location = apr_table_get(r->headers_out, conf->sendfile);
        }
        if (location) {
            scgi_request_config *req_conf = apr_palloc(r->pool,
                                                       sizeof(*req_conf));
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00861)
                          "Found %s: %s - preparing subrequest.",
                          conf->sendfile, location);

            if (err) {
                apr_table_unset(r->err_headers_out, conf->sendfile);
            }
            else {
                apr_table_unset(r->headers_out, conf->sendfile);
            }
            req_conf->location = location;
            req_conf->type = scgi_sendfile;
            ap_set_module_config(r->request_config, &proxy_scgi_module,
                                 req_conf);
            apr_brigade_destroy(bb);
            return OK;
        }
    }

    if (r->status == HTTP_OK 
        && (!conf->internal_redirect /* default === On */
            || conf->internal_redirect != scgi_internal_redirect_off)) {
        short err = 1;
        const char *location_header = conf->internal_redirect ? 
            conf->internal_redirect : scgi_internal_redirect_on;

        location = apr_table_get(r->err_headers_out, location_header);
        if (!location) {
            err = 0;
            location = apr_table_get(r->headers_out, location_header);
        }
        if (location && *location == '/') {
            scgi_request_config *req_conf = apr_palloc(r->pool,
                                                       sizeof(*req_conf));
            if (ap_cstr_casecmp(location_header, "Location")) {
                if (err) {
                    apr_table_unset(r->err_headers_out, location_header);
                }
                else {
                    apr_table_unset(r->headers_out, location_header);
                }
            }
            req_conf->location = location;
            req_conf->type = scgi_internal_redirect;
            ap_set_module_config(r->request_config, &proxy_scgi_module,
                                 req_conf);
            apr_brigade_destroy(bb);
            return OK;
        }
    }

    if (ap_pass_brigade(r->output_filters, bb)) {
        return AP_FILTER_ERROR;
    }

    return OK;
}

/*
 * Internal redirect / subrequest handler, working on request_status hook
 */
static int scgi_request_status(int *status, request_rec *r)
{
    scgi_request_config *req_conf;

    if (   (*status == OK)
        && (req_conf = ap_get_module_config(r->request_config,
                                            &proxy_scgi_module))) {
        switch (req_conf->type) {
        case scgi_internal_redirect:
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00862)
                          "Internal redirect to %s", req_conf->location);

            r->status_line = NULL;
            if (r->method_number != M_GET) {
                /* keep HEAD, which is passed around as M_GET, too */
                r->method = "GET";
                r->method_number = M_GET;
            }
            apr_table_unset(r->headers_in, "Content-Length");
            ap_internal_redirect_handler(req_conf->location, r);
            return OK;
            /* break; */

        case scgi_sendfile:
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00863)
                          "File subrequest to %s", req_conf->location);
            do {
                request_rec *rr;

                rr = ap_sub_req_lookup_file(req_conf->location, r,
                                            r->output_filters);
                if (rr->status == HTTP_OK && rr->finfo.filetype != APR_NOFILE) {
                    /*
                     * We don't touch Content-Length here. It might be
                     * borked (there's plenty of room for a race condition).
                     * Either the backend sets it or it's gonna be chunked.
                     */
                    ap_run_sub_req(rr);
                }
                else {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00864)
                                  "Subrequest to file '%s' not possible. "
                                  "(rr->status=%d, rr->finfo.filetype=%d)",
                                  req_conf->location, rr->status,
                                  rr->finfo.filetype);
                    *status = HTTP_INTERNAL_SERVER_ERROR;
                    return *status;
                }
            } while (0);

            return OK;
            /* break; */
        }
    }

    return DECLINED;
}


/*
 * This handles scgi:(dest) URLs
 */
static int scgi_handler(request_rec *r, proxy_worker *worker,
                        proxy_server_conf *conf, char *url,
                        const char *proxyname, apr_port_t proxyport)
{
    int status;
    proxy_conn_rec *backend = NULL;
    apr_pool_t *p = r->pool;
    apr_uri_t *uri;
    char dummy;

    if (ap_cstr_casecmpn(url, SCHEME "://", sizeof(SCHEME) + 2)) {
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00865)
                      "declining URL %s", url);
        return DECLINED;
    }

    /* Create space for state information */
    status = ap_proxy_acquire_connection(PROXY_FUNCTION, &backend, worker,
                                         r->server);
    if (status != OK) {
        goto cleanup;
    }
    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,
                                           &dummy, 1);
    if (status != OK) {
        goto cleanup;
    }

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

    /* Step Three: Process the Request */
    if (   ((status = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR)) != OK)
        || ((status = send_headers(r, backend)) != OK)
        || ((status = send_request_body(r, backend)) != OK)
        || ((status = pass_response(r, backend)) != OK)) {
        goto cleanup;
    }

cleanup:
    if (backend) {
        backend->close = 1; /* always close the socket */
        ap_proxy_release_connection(PROXY_FUNCTION, backend, r->server);
    }
    return status;
}


static void *create_scgi_config(apr_pool_t *p, char *dummy)
{
    scgi_config *conf=apr_palloc(p, sizeof(*conf));

    conf->sendfile = NULL; /* === default (off) */
    conf->internal_redirect = NULL; /* === default (on) */

    return conf;
}


static void *merge_scgi_config(apr_pool_t *p, void *base_, void *add_)
{
    scgi_config *base=base_, *add=add_, *conf=apr_palloc(p, sizeof(*conf));

    conf->sendfile = add->sendfile ? add->sendfile: base->sendfile;
    conf->internal_redirect = add->internal_redirect
                              ? add->internal_redirect
                              : base->internal_redirect;
    return conf;
}


static const char *scgi_set_send_file(cmd_parms *cmd, void *mconfig,
                                      const char *arg)
{
    scgi_config *conf=mconfig;

    if (!strcasecmp(arg, "Off")) {
        conf->sendfile = scgi_sendfile_off;
    }
    else if (!strcasecmp(arg, "On")) {
        conf->sendfile = scgi_sendfile_on;
    }
    else {
        conf->sendfile = arg;
    }
    return NULL;
}


static const char *scgi_set_internal_redirect(cmd_parms *cmd, void *mconfig,
                                              const char *arg)
{
    scgi_config *conf = mconfig;

    if (!strcasecmp(arg, "Off")) {
        conf->internal_redirect = scgi_internal_redirect_off;
    }
    else if (!strcasecmp(arg, "On")) {
        conf->internal_redirect = scgi_internal_redirect_on;
    }
    else {
        conf->internal_redirect = arg;
    }
    return NULL;
}


static const command_rec scgi_cmds[] =
{
    AP_INIT_TAKE1("ProxySCGISendfile", scgi_set_send_file, NULL,
                  RSRC_CONF|ACCESS_CONF,
                  "The name of the X-Sendfile pseudo response header or "
                  "On or Off"),
    AP_INIT_TAKE1("ProxySCGIInternalRedirect", scgi_set_internal_redirect, NULL,
                  RSRC_CONF|ACCESS_CONF,
                  "The name of the pseudo response header or On or Off"),
    {NULL}
};


static void register_hooks(apr_pool_t *p)
{
    proxy_hook_scheme_handler(scgi_handler, NULL, NULL, APR_HOOK_FIRST);
    proxy_hook_canon_handler(scgi_canon, NULL, NULL, APR_HOOK_FIRST);
    APR_OPTIONAL_HOOK(proxy, request_status, scgi_request_status, NULL, NULL,
                      APR_HOOK_MIDDLE);
}


AP_DECLARE_MODULE(proxy_scgi) = {
    STANDARD20_MODULE_STUFF,
    create_scgi_config,  /* create per-directory config structure */
    merge_scgi_config,   /* merge per-directory config structures */
    NULL,                /* create per-server config structure */
    NULL,                /* merge per-server config structures */
    scgi_cmds,           /* command table */
    register_hooks       /* register hooks */
};
