jk_ajp12_worker.c

来自「以便Apache与其他服务进行整合 Mod_JK安装」· C语言 代码 · 共 671 行 · 第 1/2 页

C
671
字号
/* *  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: 559467 $                                          * ***************************************************************************/#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{    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;    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);#elsestatic int ajpv12_sendstring(ajp12_endpoint_t * p, const char *buffer);#endifstatic 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){    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,                           JK_FALSE, -1, 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);        }        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 = 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;                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);    }}#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);    }}#endifstatic 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

⌨️ 快捷键说明

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