ASF Bugzilla – Attachment 15776 Details for
Bug 35862
Tomcat Connector:JK/AJP: JK Status Worker accesses freed memory for NSAPI plugin
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
patched jk_nsapi_plugin.c
jk_nsapi_plugin.c (text/plain), 15.72 KB, created by
Brian Kavanagh
on 2005-07-26 09:38:14 UTC
(
hide
)
Description:
patched jk_nsapi_plugin.c
Filename:
MIME Type:
Creator:
Brian Kavanagh
Created:
2005-07-26 09:38:14 UTC
Size:
15.72 KB
patch
obsolete
>/* > * 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: 1.24 $ * > ***************************************************************************/ > > >#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); > rc = REQ_PROCEED; > } > >/* if(wc_open(init_map, NULL, logger)) { > magnus_atrestart(jk_term, NULL); > rc = REQ_PROCEED; > } >*/ > } > } > >#ifdef NETWARE > PR_IsSocketSecure = > (int (*)(void **))ImportSymbol(GetNLMHandle(), "PR_IsSocketSecure"); >#endif > return rc; >} > >NSAPI_PUBLIC void jk_term(void *p) >{ >#ifdef NETWARE > if (NULL != PR_IsSocketSecure) { > UnimportSymbol(GetNLMHandle(), "PR_IsSocketSecure"); > PR_IsSocketSecure = NULL; > } >#endif > if (uw_map) { > uri_worker_map_free(&uw_map, logger); > } > > wc_close(logger); > if (logger) { > jk_close_file_logger(&logger); > } > > if (init_map) { > jk_map_free(&init_map); > } >} > >NSAPI_PUBLIC int jk_service(pblock * pb, Session * sn, Request * rq) >{ > char *worker_name = pblock_findval(JK_WORKER_NAME_TAG, pb); > char *uri_pattern = pblock_findval(URI_PATTERN, pb); > jk_worker_t *worker; > int rc = REQ_ABORTED; > > if (uri_pattern) { > char *uri = pblock_findval("uri", rq->reqpb); > > if (0 != shexp_match(uri, uri_pattern)) { > return REQ_NOACTION; > } > } > > if (!worker_name) { > worker_name = DEFAULT_WORKER_NAME; > } > > worker = wc_get_worker_for_name(worker_name, logger); > if (worker) { > nsapi_private_data_t private_data; > jk_ws_service_t s; > jk_pool_atom_t buf[SMALL_POOL_SIZE]; > > jk_open_pool(&private_data.p, buf, sizeof(buf)); > > private_data.request_started = JK_FALSE; > private_data.pb = pb; > private_data.sn = sn; > private_data.rq = rq; > > jk_init_ws_service(&s); > > s.ws_private = &private_data; > s.pool = &private_data.p; > > wc_maintain(logger); > if (init_ws_service(&private_data, &s)) { > jk_endpoint_t *e = NULL; > if (worker->get_endpoint(worker, &e, logger)) { > int recover = JK_FALSE; > if (e->service(e, &s, logger, &recover)) { > rc = REQ_PROCEED; > } > e->done(&e, logger); > } > } > jk_close_pool(&private_data.p); > } > > return rc; >} > >static int init_ws_service(nsapi_private_data_t * private_data, > jk_ws_service_t *s) >{ > char *tmp; > int rc; > > s->jvm_route = NULL; > s->start_response = start_response; > s->read = ws_read; > s->write = ws_write; > > /* Clear RECO status */ > s->reco_status = RECO_NONE; > > s->auth_type = pblock_findval("auth-type", private_data->rq->vars); > s->remote_user = pblock_findval("auth-user", private_data->rq->vars); > > s->content_length = 0; > tmp = NULL; > rc = request_header("content-length", > &tmp, private_data->sn, private_data->rq); > > if ((rc != REQ_ABORTED) && tmp) { > s->content_length = atoi(tmp); > } > > s->method = pblock_findval("method", private_data->rq->reqpb); > s->protocol = pblock_findval("protocol", private_data->rq->reqpb); > > s->remote_host = session_dns(private_data->sn); > s->remote_addr = pblock_findval("ip", private_data->sn->client); > > s->req_uri = pblock_findval("uri", private_data->rq->reqpb); > s->query_string = pblock_findval("query", private_data->rq->reqpb); > > s->server_name = server_hostname; > >#ifdef NETWARE > /* On NetWare, since we have virtual servers, we have a different way of > * getting the port that we need to try first. > */ > tmp = pblock_findval("server_port", private_data->sn->client); > if (NULL != tmp) > s->server_port = atoi(tmp); > else >#endif > s->server_port = server_portnum; > s->server_software = system_version(); > > > s->headers_names = NULL; > s->headers_values = NULL; > s->num_headers = 0; > s->uw_map = uw_map; > >#ifdef NETWARE > /* on NetWare, we can have virtual servers that are secure. > * PR_IsSocketSecure is an api made available with virtual servers to check > * if the socket is secure or not > */ > if (NULL != PR_IsSocketSecure) > s->is_ssl = PR_IsSocketSecure(private_data->sn->csd); > else >#endif > s->is_ssl = security_active; > > s->ssl_key_size = -1; /* required by Servlet 2.3 Api, added in jtc */ > if (s->is_ssl) { > char *ssl_cert = pblock_findval("auth-cert", private_data->rq->vars); > if (ssl_cert != NULL) { > s->ssl_cert = jk_pool_alloc(s->pool, sizeof(ssl_cert_start)+ > strlen(ssl_cert)+ > sizeof(ssl_cert_end)); > strcpy(s->ssl_cert, ssl_cert_start); > strcat(s->ssl_cert, ssl_cert); > strcat(s->ssl_cert, ssl_cert_end); > s->ssl_cert_len = strlen(s->ssl_cert); > } > s->ssl_cipher = pblock_findval("cipher", private_data->sn->client); > s->ssl_session = pblock_findval("ssl-id", private_data->sn->client); > } > else { > s->ssl_cert = NULL; > s->ssl_cert_len = 0; > s->ssl_cipher = NULL; > s->ssl_session = NULL; > } > > return setup_http_headers(private_data, s); >} > >static int setup_http_headers(nsapi_private_data_t * private_data, > jk_ws_service_t *s) >{ > int need_content_length_header = > (s->content_length == 0) ? JK_TRUE : JK_FALSE; > > pblock *headers_jar = private_data->rq->headers; > int cnt; > int i; > > for (i = 0, cnt = 0; i < headers_jar->hsize; i++) { > struct pb_entry *h = headers_jar->ht[i]; > while (h && h->param) { > cnt++; > h = h->next; > } > } > > s->headers_names = NULL; > s->headers_values = NULL; > s->num_headers = cnt; > if (cnt) { > /* allocate an extra header slot in case we need to add a content-length header */ > s->headers_names = > jk_pool_alloc(&private_data->p, (cnt + 1) * sizeof(char *)); > s->headers_values = > jk_pool_alloc(&private_data->p, (cnt + 1) * sizeof(char *)); > > if (s->headers_names && s->headers_values) { > for (i = 0, cnt = 0; i < headers_jar->hsize; i++) { > struct pb_entry *h = headers_jar->ht[i]; > while (h && h->param) { > s->headers_names[cnt] = h->param->name; > s->headers_values[cnt] = h->param->value; > if (need_content_length_header && > !strncmp(h->param->name, "content-length", 14)) { > need_content_length_header = JK_FALSE; > } > cnt++; > h = h->next; > } > } > /* Add a content-length = 0 header if needed. > * Ajp13 assumes an absent content-length header means an unknown, > * but non-zero length body. > */ > if (need_content_length_header) { > s->headers_names[cnt] = "content-length"; > s->headers_values[cnt] = "0"; > cnt++; > } > s->num_headers = cnt; > return JK_TRUE; > } > } > else { > if (need_content_length_header) { > s->headers_names = > jk_pool_alloc(&private_data->p, sizeof(char *)); > s->headers_values = > jk_pool_alloc(&private_data->p, sizeof(char *)); > if (s->headers_names && s->headers_values) { > s->headers_names[0] = "content-length"; > s->headers_values[0] = "0"; > s->num_headers++; > return JK_TRUE; > } > } > else > return JK_TRUE; > } > > return JK_FALSE; >}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 35862
: 15776