📄 jk_nsapi_plugin.c
字号:
/*
* 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 + -