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

Copyright 2009-2017 Unbit S.a.s. <info@unbit.it>
     
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

*/

#define APR_WANT_MEMFUNC
#define APR_WANT_STRFUNC
#include "apr_strings.h"
#include "apr_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"


#define UWSGI_SCHEME "uwsgi"
#define UWSGI_DEFAULT_PORT 3031

module AP_MODULE_DECLARE_DATA proxy_uwsgi_module;


static int uwsgi_canon(request_rec *r, char *url)
{
    char *host, sport[sizeof(":65535")];
    const char *err, *path;
    apr_port_t port = UWSGI_DEFAULT_PORT;

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

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

    if (port != UWSGI_DEFAULT_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:" UWSGI_SCHEME "://", host, sport, "/",
                    path, NULL);

    return OK;
}


static int uwsgi_send(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(10098)
                          "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 uwsgi header block
 */
static int uwsgi_send_headers(request_rec *r, proxy_conn_rec * conn)
{
    char *buf, *ptr;

    const apr_array_header_t *env_table;
    const apr_table_entry_t *env;

    int j;

    apr_size_t headerlen = 4;
    apr_uint16_t pktsize, keylen, vallen;
    const char *script_name;
    const char *path_info;
    const char *auth;

    ap_add_common_vars(r);
    ap_add_cgi_vars(r);

    /*
       this is not a security problem (in Linux) as uWSGI destroy the env memory area readable in /proc
       and generally if you host untrusted apps in your server and allows them to read others uid /proc/<pid>
       files you have higher problems...
     */
    auth = apr_table_get(r->headers_in, "Authorization");
    if (auth) {
        apr_table_setn(r->subprocess_env, "HTTP_AUTHORIZATION", auth);
    }

    script_name = apr_table_get(r->subprocess_env, "SCRIPT_NAME");
    path_info = apr_table_get(r->subprocess_env, "PATH_INFO");

    if (script_name && path_info) {
        if (strcmp(path_info, "/")) {
            apr_table_set(r->subprocess_env, "SCRIPT_NAME",
                          apr_pstrndup(r->pool, script_name,
                                       strlen(script_name) -
                                       strlen(path_info)));
        }
        else {
            if (!strcmp(script_name, "/")) {
                apr_table_setn(r->subprocess_env, "SCRIPT_NAME", "");
            }
        }
    }

    env_table = apr_table_elts(r->subprocess_env);
    env = (apr_table_entry_t *) env_table->elts;

    for (j = 0; j < env_table->nelts; ++j) {
        headerlen += 2 + strlen(env[j].key) + 2 + strlen(env[j].val);
    }

    ptr = buf = apr_palloc(r->pool, headerlen);

    ptr += 4;

    for (j = 0; j < env_table->nelts; ++j) {
        keylen = strlen(env[j].key);
        *ptr++ = (apr_byte_t) (keylen & 0xff);
        *ptr++ = (apr_byte_t) ((keylen >> 8) & 0xff);
        memcpy(ptr, env[j].key, keylen);
        ptr += keylen;

        vallen = strlen(env[j].val);
        *ptr++ = (apr_byte_t) (vallen & 0xff);
        *ptr++ = (apr_byte_t) ((vallen >> 8) & 0xff);
        memcpy(ptr, env[j].val, vallen);
        ptr += vallen;
    }

    pktsize = headerlen - 4;

    buf[0] = 0;
    buf[1] = (apr_byte_t) (pktsize & 0xff);
    buf[2] = (apr_byte_t) ((pktsize >> 8) & 0xff);
    buf[3] = 0;

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


static int uwsgi_send_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 = uwsgi_send(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(10099)
                          "receiving request body failed");
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    }

    return OK;
}

static request_rec *make_fake_req(conn_rec *c, request_rec *r)
{
    apr_pool_t *pool;
    request_rec *rp;

    apr_pool_create(&pool, c->pool);

    rp = apr_pcalloc(pool, sizeof(*r));

    rp->pool = pool;
    rp->status = HTTP_OK;

    rp->headers_in = apr_table_make(pool, 50);
    rp->subprocess_env = apr_table_make(pool, 50);
    rp->headers_out = apr_table_make(pool, 12);
    rp->err_headers_out = apr_table_make(pool, 5);
    rp->notes = apr_table_make(pool, 5);

    rp->server = r->server;
    rp->log = r->log;
    rp->proxyreq = r->proxyreq;
    rp->request_time = r->request_time;
    rp->connection = c;
    rp->output_filters = c->output_filters;
    rp->input_filters = c->input_filters;
    rp->proto_output_filters = c->output_filters;
    rp->proto_input_filters = c->input_filters;
    rp->useragent_ip = c->client_ip;
    rp->useragent_addr = c->client_addr;

    rp->request_config = ap_create_request_config(pool);
    proxy_run_create_req(r, rp);

    return rp;
}

static int uwsgi_response(request_rec *r, proxy_conn_rec * backend,
                          proxy_server_conf * conf)
{

    char buffer[HUGE_STRING_LEN];
    const char *buf;
    char *value, *end;
    char keepchar;
    int len;
    int backend_broke = 0;
    int status_start;
    int status_end;
    int finish = 0;
    conn_rec *c = r->connection;
    apr_off_t readbytes;
    apr_status_t rv;
    apr_bucket *e;
    apr_read_type_e mode = APR_NONBLOCK_READ;
    apr_bucket_brigade *pass_bb;
    apr_bucket_brigade *bb;
    proxy_dir_conf *dconf;

    request_rec *rp = make_fake_req(backend->connection, r);
    rp->proxyreq = PROXYREQ_RESPONSE;

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

    len = ap_getline(buffer, sizeof(buffer), rp, 1);

    if (len <= 0) {
        /* oops */
        return HTTP_INTERNAL_SERVER_ERROR;
    }

    backend->worker->s->read += len;

    if (len >= sizeof(buffer) - 1) {
        /* oops */
        return HTTP_INTERNAL_SERVER_ERROR;
    }
    /* Position of http status code */
    if (apr_date_checkmask(buffer, "HTTP/#.# ###*")) {
        status_start = 9;
    }
    else if (apr_date_checkmask(buffer, "HTTP/# ###*")) {
        status_start = 7;
    }
    else {
        /* oops */
        return HTTP_INTERNAL_SERVER_ERROR;
    }
    status_end = status_start + 3;

    keepchar = buffer[status_end];
    buffer[status_end] = '\0';
    r->status = atoi(&buffer[status_start]);

    if (keepchar != '\0') {
        buffer[status_end] = keepchar;
    }
    else {
        /* 2616 requires the space in Status-Line; the origin
         * server may have sent one but ap_rgetline will
         * have stripped it. */
        buffer[status_end] = ' ';
        buffer[status_end + 1] = '\0';
    }
    r->status_line = apr_pstrdup(r->pool, &buffer[status_start]);

    /* start parsing headers */
    while ((len = ap_getline(buffer, sizeof(buffer), rp, 1)) > 0) {
        value = strchr(buffer, ':');
        /* invalid header skip */
        if (!value)
            continue;
        *value = '\0';
        ++value;
        while (apr_isspace(*value))
            ++value;
        for (end = &value[strlen(value) - 1];
             end > value && apr_isspace(*end); --end)
            *end = '\0';
        apr_table_add(r->headers_out, buffer, value);
    }

    if ((buf = apr_table_get(r->headers_out, "Content-Type"))) {
        ap_set_content_type(r, apr_pstrdup(r->pool, buf));
    }

    /* honor ProxyErrorOverride and ErrorDocument */
#if AP_MODULE_MAGIC_AT_LEAST(20101106,0)
    dconf =
        ap_get_module_config(r->per_dir_config, &proxy_module);
    if (dconf->error_override && ap_is_HTTP_ERROR(r->status)) {
#else
    if (conf->error_override && ap_is_HTTP_ERROR(r->status)) {
#endif
        int status = r->status;
        r->status = HTTP_OK;
        r->status_line = NULL;

        apr_brigade_cleanup(bb);
        apr_brigade_cleanup(pass_bb);

        return status;
    }

    while (!finish) {
        rv = ap_get_brigade(rp->input_filters, bb,
                            AP_MODE_READBYTES, mode, conf->io_buffer_size);
        if (APR_STATUS_IS_EAGAIN(rv)
            || (rv == APR_SUCCESS && APR_BRIGADE_EMPTY(bb))) {
            e = apr_bucket_flush_create(c->bucket_alloc);
            APR_BRIGADE_INSERT_TAIL(bb, e);
            if (ap_pass_brigade(r->output_filters, bb) || c->aborted) {
                break;
            }
            apr_brigade_cleanup(bb);
            mode = APR_BLOCK_READ;
            continue;
        }
        else if (rv == APR_EOF) {
            break;
        }
        else if (rv != APR_SUCCESS) {
            ap_proxy_backend_broke(r, bb);
            ap_pass_brigade(r->output_filters, bb);
            backend_broke = 1;
            break;
        }

        mode = APR_NONBLOCK_READ;
        apr_brigade_length(bb, 0, &readbytes);
        backend->worker->s->read += readbytes;

        if (APR_BRIGADE_EMPTY(bb)) {
            apr_brigade_cleanup(bb);
            break;
        }

        ap_proxy_buckets_lifetime_transform(r, bb, pass_bb);

        /* found the last brigade? */
        if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb)))
            finish = 1;

        /* do not pass chunk if it is zero_sized */
        apr_brigade_length(pass_bb, 0, &readbytes);

        if ((readbytes > 0
             && ap_pass_brigade(r->output_filters, pass_bb) != APR_SUCCESS)
            || c->aborted) {
            finish = 1;
        }

        apr_brigade_cleanup(bb);
        apr_brigade_cleanup(pass_bb);
    }

    e = apr_bucket_eos_create(c->bucket_alloc);
    APR_BRIGADE_INSERT_TAIL(bb, e);
    ap_pass_brigade(r->output_filters, bb);

    apr_brigade_cleanup(bb);

    if (c->aborted || backend_broke) {
        return DONE;
    }

    return OK;
}

static int uwsgi_handler(request_rec *r, proxy_worker * worker,
                         proxy_server_conf * conf, char *url,
                         const char *proxyname, apr_port_t proxyport)
{
    int status;
    int delta = 0;
    int decode_status;
    proxy_conn_rec *backend = NULL;
    apr_pool_t *p = r->pool;
    size_t w_len;
    char server_portstr[32];
    char *u_path_info;
    apr_uri_t *uri;

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

    uri = apr_palloc(r->pool, sizeof(*uri));

    /* ADD PATH_INFO */
#if AP_MODULE_MAGIC_AT_LEAST(20111130,0)
    w_len = strlen(worker->s->name);
#else
    w_len = strlen(worker->name);
#endif
    u_path_info = r->filename + 6 + w_len;
    if (u_path_info[0] != '/') {
        delta = 1;
    }
    decode_status = ap_unescape_url(url + w_len - delta);
    if (decode_status) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10100)
                      "unable to decode uri: %s", url + w_len - delta);
        return HTTP_INTERNAL_SERVER_ERROR;
    }
    apr_table_add(r->subprocess_env, "PATH_INFO", url + w_len - delta);


    /* Create space for state information */
    status = ap_proxy_acquire_connection(UWSGI_SCHEME, &backend, worker,
                                         r->server);
    if (status != OK) {
        goto cleanup;
    }
    backend->is_ssl = 0;

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


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

    /* Step Three: Create conn_rec */
    if ((status = ap_proxy_connection_create(UWSGI_SCHEME, backend,
                                             r->connection,
                                             r->server)) != OK)
        goto cleanup;

    /* Step Four: Process the Request */
    if (((status = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR)) != OK)
        || ((status = uwsgi_send_headers(r, backend)) != OK)
        || ((status = uwsgi_send_body(r, backend)) != OK)
        || ((status = uwsgi_response(r, backend, conf)) != OK)) {
        goto cleanup;
    }

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


static void register_hooks(apr_pool_t * p)
{
    proxy_hook_scheme_handler(uwsgi_handler, NULL, NULL, APR_HOOK_FIRST);
    proxy_hook_canon_handler(uwsgi_canon, NULL, NULL, APR_HOOK_FIRST);
}


module AP_MODULE_DECLARE_DATA proxy_uwsgi_module = {
    STANDARD20_MODULE_STUFF,
    NULL,                       /* create per-directory config structure */
    NULL,                       /* merge per-directory config structures */
    NULL,                       /* create per-server config structure */
    NULL,                       /* merge per-server config structures */
    NULL,                       /* command table */
    register_hooks              /* register hooks */
};
