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

📄 jk_nsapi_plugin.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: NSAPI plugin for Netscape servers                          *
 * Author:      Gal Shachor <shachor@il.ibm.com>                           *
 * Version:     $Revision: 358402 $                                           *
 ***************************************************************************/


#include "nsapi.h"
#include "jk_global.h"
#include "jk_util.h"
#include "jk_map.h"
#include "jk_pool.h"
#include "jk_service.h"
#include "jk_worker.h"
#include "jk_shm.h"

#define URI_PATTERN "path"
#define DEFAULT_WORKER_NAME ("ajp13")

struct nsapi_private_data
{
    jk_pool_t p;

    int request_started;

    pblock *pb;
    Session *sn;
    Request *rq;
};
typedef struct nsapi_private_data nsapi_private_data_t;

static int init_on_other_thread_is_done = JK_FALSE;
static int init_on_other_thread_is_ok = JK_FALSE;

static const char ssl_cert_start[] = "-----BEGIN CERTIFICATE-----\r\n";
static const char ssl_cert_end[] = "\r\n-----END CERTIFICATE-----\r\n";

static jk_logger_t *logger = NULL;
static jk_worker_env_t worker_env;
static jk_map_t *init_map = NULL;
static jk_uri_worker_map_t *uw_map = NULL;

#ifdef NETWARE
int (*PR_IsSocketSecure) (SYS_NETFD * csd);     /* pointer to PR_IsSocketSecure function */
#endif

static int JK_METHOD start_response(jk_ws_service_t *s,
                                    int status,
                                    const char *reason,
                                    const char *const *header_names,
                                    const char *const *header_values,
                                    unsigned num_of_headers);

static int JK_METHOD ws_read(jk_ws_service_t *s,
                             void *b, unsigned l, unsigned *a);

static int JK_METHOD ws_write(jk_ws_service_t *s, const void *b, unsigned l);

NSAPI_PUBLIC int jk_init(pblock * pb, Session * sn, Request * rq);

NSAPI_PUBLIC void jk_term(void *p);

NSAPI_PUBLIC int jk_service(pblock * pb, Session * sn, Request * rq);

static int init_ws_service(nsapi_private_data_t * private_data,
                           jk_ws_service_t *s);

static int setup_http_headers(nsapi_private_data_t * private_data,
                              jk_ws_service_t *s);

static void init_workers_on_other_threads(void *init_d)
{
    init_map = (jk_map_t *)init_d;
    /* we add the URI->WORKER MAP since workers using AJP14 will feed it */
    /* but where are they here in Netscape ? */
    if (wc_open(init_map, &worker_env, logger)) {
        if (uri_worker_map_alloc(&uw_map, NULL, logger)) {
            uw_map->fname = "";
            worker_env.uri_to_worker = uw_map;
            init_on_other_thread_is_ok = JK_TRUE;
        }
        else {
            jk_log(logger, JK_LOG_EMERG,
                   "In init_workers_on_other_threads, failed");
        }
    }
    else {
        jk_log(logger, JK_LOG_EMERG,
               "In init_workers_on_other_threads, failed");
    }

    init_on_other_thread_is_done = JK_TRUE;
}

static int JK_METHOD start_response(jk_ws_service_t *s,
                                    int status,
                                    const char *reason,
                                    const char *const *header_names,
                                    const char *const *header_values,
                                    unsigned num_of_headers)
{
    if (s && s->ws_private) {
        nsapi_private_data_t *p = s->ws_private;
        if (!p->request_started) {
            unsigned i;

            p->request_started = JK_TRUE;

            /* Remove "old" content type */
            param_free(pblock_remove("content-type", p->rq->srvhdrs));

            if (num_of_headers) {
                for (i = 0; i < (int)num_of_headers; i++) {
                    pblock_nvinsert(header_names[i],
                                    header_values[i], p->rq->srvhdrs);
                }
            }
            else {
                pblock_nvinsert("content-type", "text/plain", p->rq->srvhdrs);
            }

            protocol_status(p->sn, p->rq, status, (char *)reason);

            protocol_start_response(p->sn, p->rq);
        }
        return JK_TRUE;

    }
    return JK_FALSE;
}

static int JK_METHOD ws_read(jk_ws_service_t *s,
                             void *b, unsigned l, unsigned *a)
{
    if (s && s->ws_private && b && a) {
        nsapi_private_data_t *p = s->ws_private;

        *a = 0;
        if (l) {
            char *buf = b;
            unsigned i;
            netbuf *inbuf = p->sn->inbuf;

/* Until we get a service pack for NW5.1 and earlier that has the latest */
/* Enterprise Server, we have to go through the else version of this code*/
#if defined(netbuf_getbytes) && !defined(NETWARE)
            i = netbuf_getbytes(inbuf, b, l);
            if (NETBUF_EOF == i || NETBUF_ERROR == i) {
                return JK_FALSE;
            }

#else
            int ch;
            for (i = 0; i < l; i++) {
                ch = netbuf_getc(inbuf);
                /*
                 * IO_EOF is 0 (zero) which is a very reasonable byte
                 * when it comes to binary data. So we are not breaking
                 * out of the read loop when reading it.
                 *
                 * We are protected from an infinit loop by the Java part of
                 * Tomcat.
                 */
                if (IO_ERROR == ch) {
                    break;
                }

                buf[i] = ch;
            }

            if (0 == i) {
                return JK_FALSE;
            }
#endif
            *a = i;

        }
        return JK_TRUE;
    }
    return JK_FALSE;
}

static int JK_METHOD ws_write(jk_ws_service_t *s, const void *b, unsigned l)
{
    if (s && s->ws_private && b) {
        nsapi_private_data_t *p = s->ws_private;

        if (l) {
            if (!p->request_started) {
                start_response(s, 200, NULL, NULL, NULL, 0);
            }

            if (net_write(p->sn->csd, (char *)b, (int)l) == IO_ERROR) {
                return JK_FALSE;
            }
        }

        return JK_TRUE;

    }
    return JK_FALSE;
}

NSAPI_PUBLIC int jk_init(pblock * pb, Session * sn, Request * rq)
{
    char *worker_prp_file = pblock_findval(JK_WORKER_FILE_TAG, pb);
    char *log_level_str = pblock_findval(JK_LOG_LEVEL_TAG, pb);
    char *log_file = pblock_findval(JK_LOG_FILE_TAG, pb);
    char *shm_file = pblock_findval(JK_SHM_FILE_TAG, pb);

    int rc = REQ_ABORTED;

    fprintf(stderr,
            "In jk_init.\n   Worker file = %s.\n   Log level = %s.\n   Log File = %s\n",
            worker_prp_file, log_level_str, log_file);
    if (!worker_prp_file) {
        worker_prp_file = JK_WORKER_FILE_DEF;
    }

    if (!log_level_str) {
        log_level_str = JK_LOG_LEVEL_DEF;
    }

    if (!jk_open_file_logger(&logger, log_file,
                             jk_parse_log_level(log_level_str))) {
        logger = NULL;
    }
    
    jk_shm_open(shm_file, JK_SHM_DEF_SIZE, logger);
    if (jk_map_alloc(&init_map)) {
        if (jk_map_read_properties(init_map, worker_prp_file, NULL)) {
            int sleep_cnt;
            SYS_THREAD s;

            s = systhread_start(SYSTHREAD_DEFAULT_PRIORITY,
                                0, init_workers_on_other_threads, init_map);
            for (sleep_cnt = 0; sleep_cnt < 60; sleep_cnt++) {
                systhread_sleep(1000);
                jk_log(logger, JK_LOG_DEBUG, "jk_init, a second passed");
                if (init_on_other_thread_is_done) {
                    break;
                }
            }

            if (init_on_other_thread_is_done && init_on_other_thread_is_ok) {
                magnus_atrestart(jk_term, NULL);

⌨️ 快捷键说明

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