⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jk_ajp12_worker.c

📁 精通tomcat书籍原代码,希望大家共同学习
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 *  Copyright 1999-2004 The Apache Software Foundation
 *
 *  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.
 */

/***************************************************************************
 * 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: 300520 $                                          *
 ***************************************************************************/

#include "jk_ajp12_worker.h"
#include "jk_pool.h"
#include "jk_connect.h"
#include "jk_util.h"
#include "jk_sockbuf.h"
#ifdef AS400
#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
{
    struct sockaddr_in worker_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;

    int 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);

#ifdef AS400
static int ajpv12_sendasciistring(ajp12_endpoint_t * p, char *buffer);
#endif

#ifdef AS400
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);

static int JK_METHOD service(jk_endpoint_t *e,
                             jk_ws_service_t *s,
                             jk_logger_t *l, int *is_error)
{
    jk_log(l, JK_LOG_DEBUG, "Into jk_endpoint_t::service");

    if (e && e->endpoint_private && s && is_error) {
        ajp12_endpoint_t *p = e->endpoint_private;
        unsigned int attempt;
        /*
         * AJP12 protocol is not recoverable.
         */
        *is_error = JK_HTTP_SERVER_ERROR;

        for (attempt = 0; attempt < p->worker->connect_retry_attempts;
             attempt++) {
            p->sd =
                jk_open_socket(&p->worker->worker_inet_addr,
                               JK_FALSE, -1, 0, l);

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

            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");
                return ajpv12_handle_response(p, s, l);
            }
        }
        jk_log(l, JK_LOG_ERROR, "In jk_endpoint_t::service, Error sd = %d",
               p->sd);
    }
    else {
        jk_log(l, JK_LOG_ERROR,
               "In jk_endpoint_t::service, NULL parameters");
    }

    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 (p->sd > 0) {
            jk_close_socket(p->sd);
        }
        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);

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

        if (port > 1024 && host) {
            if (jk_resolve(host, port, &p->worker_inet_addr)) {
                return JK_TRUE;
            }
            jk_log(l, JK_LOG_ERROR,
                   "In jk_worker_t::validate, resolve failed");
        }
        jk_log(l, JK_LOG_ERROR, "In jk_worker_t::validate, Error %s %d",
               host, port);
    }
    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 = -1;
            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;
                private_data->worker.retries = JK_RETRIES;

                *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);
    }
}

#ifdef AS400
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 = strlen(buffer))) {
#if defined(AS400) || 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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -