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

/***************************************************************************
 * Description: ajpv1.2 worker, used to call local or remote jserv hosts   *
 *              This worker is deprecated                                  *
 * Author:      Gal Shachor <shachor@il.ibm.com>                           *
 * Based on:    jserv_ajpv12.c from Jserv                                  *
 * Version:     $Revision$                                          *
 ***************************************************************************/

#include "jk_ajp12_worker.h"
#include "jk_pool.h"
#include "jk_connect.h"
#include "jk_util.h"
#include "jk_sockbuf.h"
#if defined(AS400) && !defined(AS400_UTF8)
#include "util_ebcdic.h"
#include <string.h>
#endif

#define AJP_DEF_HOST            ("localhost")
#define AJP_DEF_PORT            (8007)
#define READ_BUF_SIZE           (8*1024)
#define DEF_RETRY_ATTEMPTS      (1)

struct ajp12_worker
{
    jk_sockaddr_t worker_inet_addr;
    jk_sockaddr_t worker_source_inet_addr;
    unsigned connect_retry_attempts;
    char *name;
    jk_worker_t worker;
};

typedef struct ajp12_worker ajp12_worker_t;

struct ajp12_endpoint
{
    ajp12_worker_t *worker;

    jk_sock_t sd;
    jk_sockbuf_t sb;

    jk_endpoint_t endpoint;
};
typedef struct ajp12_endpoint ajp12_endpoint_t;

static int ajpv12_mark(ajp12_endpoint_t * p, unsigned char type);

#if defined(AS400) && !defined(AS400_UTF8)
static int ajpv12_sendasciistring(ajp12_endpoint_t * p, char *buffer);
#endif

#if defined(AS400) && !defined(AS400_UTF8)
static int ajpv12_sendstring(ajp12_endpoint_t * p, char *buffer);
#else
static int ajpv12_sendstring(ajp12_endpoint_t * p, const char *buffer);
#endif

static int ajpv12_sendint(ajp12_endpoint_t * p, int d);

static int ajpv12_sendnbytes(ajp12_endpoint_t * p,
                             const void *buffer, int bufferlen);

static int ajpv12_flush(ajp12_endpoint_t * p);

static int ajpv12_handle_response(ajp12_endpoint_t * p,
                                  jk_ws_service_t *s, jk_logger_t *l);

static int ajpv12_handle_request(ajp12_endpoint_t * p,
                                 jk_ws_service_t *s, jk_logger_t *l);

/*
 * Return values of service() method for ajp12 worker:
 * return value  is_error              reason
 * JK_FALSE      JK_HTTP_SERVER_ERROR  Invalid parameters (null values)
 *                                     Error during connect to the backend
 *                                     ajpv12_handle_request() returns false:
 *           Any error during reading a request body from the client or
 *           sending the request to the backend
 * JK_FALSE      JK_HTTP_OK            ajpv12_handle_response() returns false:
 *           Any error during reading parts of response from backend or
 *           sending to client
 * JK_TRUE       JK_HTTP_OK            All other cases
 */
static int JK_METHOD service(jk_endpoint_t *e,
                             jk_ws_service_t *s,
                             jk_logger_t *l, int *is_error)
{
    ajp12_endpoint_t *p;
    unsigned int attempt;
    int rc = -1;
    /*
     * AJP12 protocol is not recoverable.
     */

    JK_TRACE_ENTER(l);

    if (!e || !e->endpoint_private || !s || !is_error) {
        JK_LOG_NULL_PARAMS(l);
        if (is_error)
            *is_error = JK_HTTP_SERVER_ERROR;
        JK_TRACE_EXIT(l);
        return JK_FALSE;
    }

    p = e->endpoint_private;

    /* Set returned error to OK */
    *is_error = JK_HTTP_OK;

    for (attempt = 0; attempt < p->worker->connect_retry_attempts;
         attempt++) {
        p->sd =
            jk_open_socket(&p->worker->worker_inet_addr,
                           p->worker->worker_source_inet_addr.ipaddr_ptr != NULL ?
                               &p->worker->worker_source_inet_addr :
                               NULL,
                           JK_FALSE, 0, 0, 0, l);

        jk_log(l, JK_LOG_DEBUG, "In jk_endpoint_t::service, sd = %d",
               p->sd);
        if (IS_VALID_SOCKET(p->sd)) {
            break;
        }
    }
    if (IS_VALID_SOCKET(p->sd)) {

        jk_sb_open(&p->sb, p->sd);
        if (ajpv12_handle_request(p, s, l)) {
            jk_log(l, JK_LOG_DEBUG,
                   "In jk_endpoint_t::service, sent request");
            rc = ajpv12_handle_response(p, s, l);
            JK_TRACE_EXIT(l);
            return rc;
        }
    }
    jk_log(l, JK_LOG_ERROR, "In jk_endpoint_t::service, Error sd = %d",
           p->sd);
    *is_error = JK_HTTP_SERVER_ERROR;

    JK_TRACE_EXIT(l);
    return JK_FALSE;
}

static int JK_METHOD done(jk_endpoint_t **e, jk_logger_t *l)
{
    jk_log(l, JK_LOG_DEBUG, "Into jk_endpoint_t::done");
    if (e && *e && (*e)->endpoint_private) {
        ajp12_endpoint_t *p = (*e)->endpoint_private;
        if (IS_VALID_SOCKET(p->sd)) {
            jk_shutdown_socket(p->sd, l);
        }
        free(p);
        *e = NULL;
        return JK_TRUE;
    }

    jk_log(l, JK_LOG_ERROR, "In jk_endpoint_t::done, NULL parameters");
    return JK_FALSE;
}

static int JK_METHOD validate(jk_worker_t *pThis,
                              jk_map_t *props,
                              jk_worker_env_t *we, jk_logger_t *l)
{
    jk_log(l, JK_LOG_DEBUG, "Into jk_worker_t::validate");

    if (pThis && pThis->worker_private) {
        ajp12_worker_t *p = pThis->worker_private;
        int port = jk_get_worker_port(props,
                                      p->name,
                                      AJP_DEF_PORT);

        const char *host = jk_get_worker_host(props,
                                        p->name,
                                        AJP_DEF_HOST);

        const char *source = jk_get_worker_host(props,
                                                p->name,
                                                "");

        jk_log(l, JK_LOG_DEBUG,
               "In jk_worker_t::validate for worker %s target is %s:%d",
               p->name, host, port);

        if (host) {
            if (!jk_resolve(host, port, &p->worker_inet_addr, we->pool, JK_FALSE, l)) {
                jk_log(l, JK_LOG_ERROR,
                       "In jk_worker_t::validate, host '%s:%d' resolve failed",
                       host, port);
                return JK_FALSE;
            }
        } else {
            jk_log(l, JK_LOG_ERROR,
                   "In jk_worker_t::validate, Error no host name given");
            return JK_FALSE;
        }
        if (source && *source) {
            if (!jk_resolve(source, 0, &p->worker_source_inet_addr, we->pool, JK_FALSE, l)) {
                p->worker_source_inet_addr.ipaddr_ptr = NULL;
                jk_log(l, JK_LOG_WARNING,
                       "In jk_worker_t::validate, source addr '%s' resolve failed - ignored",
                       source);
            }
        }
        return JK_TRUE;
    }
    else {
        jk_log(l, JK_LOG_ERROR,
               "In jk_worker_t::validate, NULL parameters");
    }

    return JK_FALSE;
}

static int JK_METHOD init(jk_worker_t *pThis,
                          jk_map_t *props,
                          jk_worker_env_t *we, jk_logger_t *log)
{
    /* Nothing to do for now */
    return JK_TRUE;
}

static int JK_METHOD get_endpoint(jk_worker_t *pThis,
                                  jk_endpoint_t **pend, jk_logger_t *l)
{
    jk_log(l, JK_LOG_DEBUG, "Into jk_worker_t::get_endpoint");

    if (pThis && pThis->worker_private && pend) {
        ajp12_endpoint_t *p =
            (ajp12_endpoint_t *) malloc(sizeof(ajp12_endpoint_t));
        if (p) {
            p->sd = JK_INVALID_SOCKET;
            p->worker = pThis->worker_private;
            p->endpoint.endpoint_private = p;
            p->endpoint.service = service;
            p->endpoint.done = done;
            *pend = &p->endpoint;
            return JK_TRUE;
        }
        jk_log(l, JK_LOG_ERROR,
               "In jk_worker_t::get_endpoint, malloc failed");
    }
    else {
        jk_log(l, JK_LOG_ERROR,
               "In jk_worker_t::get_endpoint, NULL parameters");
    }

    return JK_FALSE;
}

static int JK_METHOD destroy(jk_worker_t **pThis, jk_logger_t *l)
{
    jk_log(l, JK_LOG_DEBUG, "Into jk_worker_t::destroy");
    if (pThis && *pThis && (*pThis)->worker_private) {
        ajp12_worker_t *private_data = (*pThis)->worker_private;
        free(private_data->name);
        free(private_data);

        return JK_TRUE;
    }

    jk_log(l, JK_LOG_ERROR, "In jk_worker_t::destroy, NULL parameters");
    return JK_FALSE;
}

int JK_METHOD ajp12_worker_factory(jk_worker_t **w,
                                   const char *name, jk_logger_t *l)
{
    jk_log(l, JK_LOG_DEBUG, "Into ajp12_worker_factory");
    if (NULL != name && NULL != w) {
        ajp12_worker_t *private_data =
            (ajp12_worker_t *) malloc(sizeof(ajp12_worker_t));

        if (private_data) {
            private_data->name = strdup(name);

            if (private_data->name) {
                private_data->connect_retry_attempts = DEF_RETRY_ATTEMPTS;
                private_data->worker.worker_private = private_data;

                private_data->worker.validate = validate;
                private_data->worker.init = init;
                private_data->worker.get_endpoint = get_endpoint;
                private_data->worker.destroy = destroy;
                private_data->worker.maintain = NULL;

                *w = &private_data->worker;
                return JK_AJP12_WORKER_TYPE;
            }

            free(private_data);
        }
        jk_log(l, JK_LOG_ERROR, "In ajp12_worker_factory, malloc failed");
    }
    else {
        jk_log(l, JK_LOG_ERROR, "In ajp12_worker_factory, NULL parameters");
    }

    return 0;
}

static int ajpv12_sendnbytes(ajp12_endpoint_t * p,
                             const void *buffer, int bufferlen)
{
    unsigned char bytes[2];
    static const unsigned char null_b[2] =
        { (unsigned char)0xff, (unsigned char)0xff };

    if (buffer) {
        bytes[0] = (unsigned char)((bufferlen >> 8) & 0xff);
        bytes[1] = (unsigned char)(bufferlen & 0xff);

        if (jk_sb_write(&p->sb, bytes, 2)) {
            return jk_sb_write(&p->sb, buffer, bufferlen);
        }
        else {
            return JK_FALSE;
        }
    }
    else {
        return jk_sb_write(&p->sb, null_b, 2);
    }
}

#if defined(AS400) && !defined(AS400_UTF8)
static int ajpv12_sendasciistring(ajp12_endpoint_t * p, const char *buffer)
{
    int bufferlen;

    if (buffer && (bufferlen = strlen(buffer))) {
        return ajpv12_sendnbytes(p, buffer, bufferlen);
    }
    else {
        return ajpv12_sendnbytes(p, NULL, 0);
    }
}
#endif

static int ajpv12_sendstring(ajp12_endpoint_t * p, const char *buffer)
{
    int bufferlen;

    if (buffer && (bufferlen = (int)strlen(buffer))) {
#if (defined(AS400) && !defined(AS400_UTF8)) || defined(_OSD_POSIX)
        char buf[2048];
        if (bufferlen < 2048) {
            memcpy(buf, buffer, bufferlen);
            jk_xlate_to_ascii(buf, bufferlen);
            return ajpv12_sendnbytes(p, buf, bufferlen);
        }
        else
            return -1;
#else
        return ajpv12_sendnbytes(p, buffer, bufferlen);
#endif
    }
    else {
        return ajpv12_sendnbytes(p, NULL, 0);
    }
}

static int ajpv12_mark(ajp12_endpoint_t * p, unsigned char type)
{
    if (jk_sb_write(&p->sb, &type, 1)) {
        return JK_TRUE;
    }
    else {
        return JK_FALSE;
    }
}

static int ajpv12_sendint(ajp12_endpoint_t * p, int d)
{
    char buf[20];
    sprintf(buf, "%d", d);
    return ajpv12_sendstring(p, buf);
}

static int ajpv12_flush(ajp12_endpoint_t * p)
{
    return jk_sb_flush(&p->sb);
}

static int ajpv12_handle_request(ajp12_endpoint_t * p,
                                 jk_ws_service_t *s, jk_logger_t *l)
{
    int ret;

    jk_log(l, JK_LOG_DEBUG, "Into ajpv12_handle_request");
    /*
     * Start the ajp 12 service sequence
     */
    jk_log(l, JK_LOG_DEBUG,
           "ajpv12_handle_request, sending the ajp12 start sequence");

    ret = (ajpv12_mark(p, 1) && ajpv12_sendstring(p, s->method) && ajpv12_sendstring(p, 0) &&   /* zone */
           ajpv12_sendstring(p, 0) &&   /* servlet */
           ajpv12_sendstring(p, s->server_name) && ajpv12_sendstring(p, 0) &&   /* doc root */
           ajpv12_sendstring(p, 0) &&   /* path info */
           ajpv12_sendstring(p, 0) &&   /* path translated */
#if defined(AS400) && !defined(AS400_UTF8)
           ajpv12_sendasciistring(p, s->query_string) &&
#else
           ajpv12_sendstring(p, s->query_string) &&
#endif
           ajpv12_sendstring(p, s->remote_addr) &&
           ajpv12_sendstring(p, s->remote_host) &&
           ajpv12_sendstring(p, s->remote_user) &&
           ajpv12_sendstring(p, s->auth_type) &&
           ajpv12_sendint(p, s->server_port) &&
#if defined(AS400) && !defined(AS400_UTF8)
           ajpv12_sendasciistring(p, s->method) &&
#else
           ajpv12_sendstring(p, s->method) &&
#endif
           ajpv12_sendstring(p, s->req_uri) && ajpv12_sendstring(p, 0) &&       /* */
           ajpv12_sendstring(p, 0) &&   /* SCRIPT_NAME */
#if defined(AS400) && !defined(AS400_UTF8)
           ajpv12_sendasciistring(p, s->server_name) &&
#else
           ajpv12_sendstring(p, s->server_name) &&
#endif
           ajpv12_sendint(p, s->server_port) && ajpv12_sendstring(p, s->protocol) && ajpv12_sendstring(p, 0) && /* SERVER_SIGNATURE */
           ajpv12_sendstring(p, s->server_software) && ajpv12_sendstring(p, s->route) &&    /* JSERV_ROUTE */
           ajpv12_sendstring(p, "") &&  /* JSERV ajpv12 compatibility */
           ajpv12_sendstring(p, ""));   /* JSERV ajpv12 compatibility */

    if (!ret) {
        jk_log(l, JK_LOG_ERROR,
               "In ajpv12_handle_request, failed to send the ajp12 start sequence");
        return JK_FALSE;
    }

    if (s->num_attributes > 0) {
        unsigned i;
        jk_log(l, JK_LOG_DEBUG,
               "ajpv12_handle_request, sending the environment variables");

        for (i = 0; i < s->num_attributes; i++) {
            ret = (ajpv12_mark(p, 5) &&
                   ajpv12_sendstring(p, s->attributes_names[i]) &&
                   ajpv12_sendstring(p, s->attributes_values[i]));
            if (!ret) {
                jk_log(l, JK_LOG_ERROR,
                       "In ajpv12_handle_request, failed to send environment");
                return JK_FALSE;
            }
        }
    }

    jk_log(l, JK_LOG_DEBUG, "ajpv12_handle_request, sending the headers");

    /* Send the request headers */
    if (s->num_headers) {
        unsigned i;
        for (i = 0; i < s->num_headers; ++i) {
            ret = (ajpv12_mark(p, 3) &&
                   ajpv12_sendstring(p, s->headers_names[i]) &&
                   ajpv12_sendstring(p, s->headers_values[i]));

            if (!ret) {
                jk_log(l, JK_LOG_ERROR,
                       "In ajpv12_handle_request, failed to send headers");
                return JK_FALSE;
            }
        }
    }

    jk_log(l, JK_LOG_DEBUG,
           "ajpv12_handle_request, sending the terminating mark");

    ret = (ajpv12_mark(p, 4) && ajpv12_flush(p));
    if (!ret) {
        jk_log(l, JK_LOG_ERROR,
               "In ajpv12_handle_request, failed to send the terminating mark");
        return JK_FALSE;
    }

    if (s->content_length) {
        char buf[READ_BUF_SIZE];
        jk_uint64_t so_far = 0;

        jk_log(l, JK_LOG_DEBUG,
               "ajpv12_handle_request, sending the request body");

        while (so_far < s->content_length) {
            unsigned this_time = 0;
            unsigned to_read;
            if (s->content_length > so_far + READ_BUF_SIZE) {
                to_read = READ_BUF_SIZE;
            }
            else {
                to_read = (unsigned int)(s->content_length - so_far);
            }

            if (!s->read(s, buf, to_read, &this_time)) {
                jk_log(l, JK_LOG_ERROR,
                       "In ajpv12_handle_request, failed to read from the web server");
                return JK_FALSE;
            }
            jk_log(l, JK_LOG_DEBUG, "ajpv12_handle_request, read %d bytes",
                   this_time);
            if (this_time > 0) {
                so_far += this_time;
                if ((int)this_time != send(p->sd, buf, this_time, 0)) {
                    jk_log(l, JK_LOG_ERROR,
                           "In ajpv12_handle_request, failed to write to the container");
                    return JK_FALSE;
                }
                jk_log(l, JK_LOG_DEBUG,
                       "ajpv12_handle_request, sent %d bytes", this_time);
            }
            else if (this_time == 0) {
                jk_log(l, JK_LOG_ERROR,
                       "In ajpv12_handle_request, Error: short read. content length is %" JK_UINT64_T_FMT ", read %" JK_UINT64_T_FMT,
                       s->content_length, so_far);
                return JK_FALSE;
            }
        }
    }

    jk_log(l, JK_LOG_DEBUG, "ajpv12_handle_request done");
    return JK_TRUE;
}

static int ajpv12_handle_response(ajp12_endpoint_t * p,
                                  jk_ws_service_t *s, jk_logger_t *l)
{
    int status = 200;
    char *reason = NULL;
    char **names = NULL;
    char **values = NULL;
    int headers_capacity = 0;
    int headers_len = 0;
    int write_to_ws;

    jk_log(l, JK_LOG_DEBUG, "Into ajpv12_handle_response");
    /*
     * Read headers ...
     */
    while (1) {
        char *line = NULL;
        char *name = NULL;
        char *value = NULL;
#ifdef _MT_CODE_PTHREAD
        char *lasts;
#endif

        if (!jk_sb_gets(&p->sb, &line)) {
            jk_log(l, JK_LOG_ERROR,
                   "ajpv12_handle_response, error reading header line");
            return JK_FALSE;
        }
#if (defined(AS400) && !defined(AS400_UTF8)) || defined(_OSD_POSIX)
        jk_xlate_from_ascii(line, strlen(line));
#endif

        jk_log(l, JK_LOG_DEBUG, "ajpv12_handle_response, read %s", line);
        if (0 == strlen(line)) {
            jk_log(l, JK_LOG_DEBUG,
                   "ajpv12_handle_response, headers are done");
            break;              /* Empty line -> end of headers */
        }

        name = line;
        while (jk_isspace(*name) && *name) {
            name++;             /* Skip leading white chars */
        }
        if (!*name) {           /* Empty header name */
            jk_log(l, JK_LOG_ERROR,
                   "ajpv12_handle_response, empty header name");
            return JK_FALSE;
        }
        if (!(value = strchr(name, ':'))) {
            jk_log(l, JK_LOG_ERROR,
                   "ajpv12_handle_response, no value supplied");
            return JK_FALSE;    /* No value !!! */
        }
        *value = '\0';
        value++;
        while (jk_isspace(*value) && *value) {
            value++;            /* Skip leading white chars */
        }
        if (!*value) {          /* Empty header value */
            jk_log(l, JK_LOG_ERROR,
                   "ajpv12_handle_response, empty header value");
            return JK_FALSE;
        }

        jk_log(l, JK_LOG_DEBUG, "ajpv12_handle_response, read %s=%s", name,
               value);
        if (0 == strcmp("Status", name)) {
#ifdef _MT_CODE_PTHREAD
            char *numeric = strtok_r(value, " \t", &lasts);
#else
            char *numeric = strtok(value, " \t");
#endif

            status = atoi(numeric);
            if (status < 100 || status > 999) {
                jk_log(l, JK_LOG_ERROR,
                       "ajpv12_handle_response, invalid status code");
                return JK_FALSE;
            }
#ifdef _MT_CODE_PTHREAD
            reason = jk_pool_strdup(s->pool, strtok_r(NULL, " \t", &lasts));
#else
            reason = jk_pool_strdup(s->pool, strtok(NULL, " \t"));
#endif
        }
        else {
            if (headers_capacity == headers_len) {
                jk_log(l, JK_LOG_DEBUG,
                       "ajpv12_handle_response, allocating header arrays");
                names =
                    (char **)jk_pool_realloc(s->pool,
                                             sizeof(char *) *
                                             (headers_capacity + 5), names,
                                             sizeof(char *) *
                                             headers_capacity);
                values =
                    (char **)jk_pool_realloc(s->pool,
                                             sizeof(char *) *
                                             (headers_capacity + 5), values,
                                             sizeof(char *) *
                                             headers_capacity);
                if (!values || !names) {
                    jk_log(l, JK_LOG_ERROR,
                           "ajpv12_handle_response, malloc error");
                    return JK_FALSE;
                }
                headers_capacity = headers_capacity + 5;
            }
            names[headers_len] = jk_pool_strdup(s->pool, name);
            values[headers_len] = jk_pool_strdup(s->pool, value);
            headers_len++;
        }
    }

    jk_log(l, JK_LOG_DEBUG, "ajpv12_handle_response, starting response");
    if (!s->start_response(s,
                           status,
                           reason,
                           (const char *const *)names,
                           (const char *const *)values, headers_len)) {
        jk_log(l, JK_LOG_ERROR,
               "ajpv12_handle_response, error starting response");
        return JK_FALSE;
    }

    jk_log(l, JK_LOG_DEBUG,
           "ajpv12_handle_response, reading response body");
    /*
     * Read response body
     */
    write_to_ws = JK_TRUE;
    while (1) {
        unsigned to_read = READ_BUF_SIZE;
        unsigned acc = 0;
        char *buf = NULL;

        if (!jk_sb_read(&p->sb, &buf, to_read, &acc)) {
            jk_log(l, JK_LOG_ERROR,
                   "ajpv12_handle_response, error reading from ");
            return JK_FALSE;
        }

        if (!acc) {
            jk_log(l, JK_LOG_DEBUG,
                   "ajpv12_handle_response, response body is done");
            break;
        }

        if (write_to_ws) {
            if (!s->write(s, buf, acc)) {
                jk_log(l, JK_LOG_ERROR,
                       "ajpv12_handle_response, error writing back to server");
                write_to_ws = JK_FALSE;
            }
        }
    }

    jk_log(l, JK_LOG_DEBUG, "ajpv12_handle_response done");
    return JK_TRUE;
}
