2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
18 /***************************************************************************
19 * Description: AJP14 next generation Bi-directional protocol. *
20 * Author: Henri Gomez <hgomez@apache.org> *
21 * Version: $Revision: 611589 $ *
22 ***************************************************************************/
24 #include "jk_context.h"
25 #include "jk_ajp14_worker.h"
29 * AJP14 Autoconf Phase
31 * CONTEXT QUERY / REPLY
34 #define MAX_URI_SIZE 512
36 static int handle_discovery(ajp_endpoint_t * ae,
38 jk_msg_buf_t *msg, jk_logger_t *l)
43 /* Not used for now */
44 jk_login_service_t *jl = ae->worker->login;
46 jk_context_item_t *ci;
53 ajp14_marshal_context_query_into_msgb(msg, we->virtual, l);
55 jk_log(l, JK_LOG_DEBUG, "send query");
57 if (ajp_connection_tcp_send_message(ae, msg, l) != JK_TRUE) {
61 jk_log(l, JK_LOG_DEBUG, "wait context reply");
65 if (ajp_connection_tcp_get_message(ae, msg, l) != JK_TRUE) {
69 if ((cmd = jk_b_get_byte(msg)) != AJP14_CONTEXT_INFO_CMD) {
70 jk_log(l, JK_LOG_ERROR,
71 "awaited command %d, received %d",
72 AJP14_CONTEXT_INFO_CMD, cmd);
77 if (context_alloc(&c, we->virtual) != JK_TRUE) {
78 jk_log(l, JK_LOG_ERROR,
79 "can't allocate context room");
84 if (ajp14_unmarshal_context_info(msg, c, l) != JK_TRUE) {
85 jk_log(l, JK_LOG_ERROR,
86 "can't get context reply");
91 jk_log(l, JK_LOG_DEBUG, "received context");
93 buf = malloc(MAX_URI_SIZE); /* Really a very long URI */
96 jk_log(l, JK_LOG_ERROR, "can't malloc buf");
101 for (i = 0; i < c->size; i++) {
103 for (j = 0; j < ci->size; j++) {
106 snprintf(buf, MAX_URI_SIZE - 1, "/%s/%s", ci->cbase, ci->uris[j]);
108 sprintf(buf, "/%s/%s", ci->cbase, ci->uris[j]);
111 jk_log(l, JK_LOG_INFO,
112 "worker %s will handle uri %s in context %s [%s]",
113 ae->worker->name, ci->uris[j], ci->cbase, buf);
115 uri_worker_map_add(we->uri_to_worker, buf, ae->worker->name, SOURCE_TYPE_DISCOVER, l);
124 uri_worker_map_add(we->uri_to_worker, "/examples/servlet/*",
125 ae->worker->name, SOURCE_TYPE_DISCOVER, l);
126 uri_worker_map_add(we->uri_to_worker, "/examples/*.jsp", ae->worker->name,
127 SOURCE_TYPE_DISCOVER, l);
128 uri_worker_map_add(we->uri_to_worker, "/examples/*.gif", ae->worker->name,
129 SOURCE_TYPE_DISCOVER, l);
140 * INIT + REPLY / NEGO + REPLY
143 static int handle_logon(ajp_endpoint_t * ae,
144 jk_msg_buf_t *msg, jk_logger_t *l)
148 jk_login_service_t *jl = ae->worker->login;
151 ajp14_marshal_login_init_into_msgb(msg, jl, l);
153 jk_log(l, JK_LOG_DEBUG, "send init");
155 if (ajp_connection_tcp_send_message(ae, msg, l) != JK_TRUE) {
159 jk_log(l, JK_LOG_DEBUG, "wait init reply");
163 if (ajp_connection_tcp_get_message(ae, msg, l) != JK_TRUE) {
167 if ((cmd = jk_b_get_byte(msg)) != AJP14_LOGSEED_CMD) {
168 jk_log(l, JK_LOG_ERROR,
169 "awaited command %d, received %d",
170 AJP14_LOGSEED_CMD, cmd);
175 if (ajp14_unmarshal_login_seed(msg, jl, l) != JK_TRUE) {
179 jk_log(l, JK_LOG_DEBUG, "received entropy %s",
182 ajp14_compute_md5(jl, l);
184 if (ajp14_marshal_login_comp_into_msgb(msg, jl, l) != JK_TRUE) {
188 if (ajp_connection_tcp_send_message(ae, msg, l) != JK_TRUE) {
194 if (ajp_connection_tcp_get_message(ae, msg, l) != JK_TRUE) {
198 switch (jk_b_get_byte(msg)) {
200 case AJP14_LOGOK_CMD:
201 if (ajp14_unmarshal_log_ok(msg, jl, l) == JK_TRUE) {
202 jk_log(l, JK_LOG_DEBUG,
203 "Successfully connected to servlet-engine %s",
204 jl->servlet_engine_name);
210 case AJP14_LOGNOK_CMD:
211 ajp14_unmarshal_log_nok(msg, l);
219 static int logon(ajp_endpoint_t * ae, jk_logger_t *l)
221 jk_pool_t *p = &ae->pool;
228 jk_b_set_buffer_size(msg, DEF_BUFFER_SZ);
230 if ((rc = handle_logon(ae, msg, l)) == JK_FALSE)
231 ajp_close_endpoint(ae, l);
237 static int discovery(ajp_endpoint_t * ae, jk_worker_env_t *we, jk_logger_t *l)
239 jk_pool_t *p = &ae->pool;
246 jk_b_set_buffer_size(msg, DEF_BUFFER_SZ);
248 if ((rc = handle_discovery(ae, we, msg, l)) == JK_FALSE)
249 ajp_close_endpoint(ae, l);
255 /* -------------------- Method -------------------- */
256 static int JK_METHOD validate(jk_worker_t *pThis,
258 jk_worker_env_t *we, jk_logger_t *l)
261 const char *secret_key;
264 if (ajp_validate(pThis, props, we, l, AJP14_PROTO) == JK_FALSE) {
268 aw = pThis->worker_private;
270 secret_key = jk_get_worker_secret_key(props, aw->name);
272 if ((!secret_key) || (!strlen(secret_key))) {
273 jk_log(l, JK_LOG_ERROR,
274 "validate error, empty or missing secretkey");
279 /* jk_log(l, JK_LOG_DEBUG, "Into ajp14:validate - secret_key=%s", secret_key); */
284 static int JK_METHOD get_endpoint(jk_worker_t *pThis,
285 jk_endpoint_t **pend, jk_logger_t *l)
289 rc = ajp_get_endpoint(pThis, pend, l, AJP14_PROTO);
294 static int JK_METHOD init(jk_worker_t *pThis,
296 jk_worker_env_t *we, jk_logger_t *l)
305 if (ajp_init(pThis, props, we, l, AJP14_PROTO) == JK_FALSE) {
309 aw = pThis->worker_private;
311 /* Set Secret Key (used at logon time) */
312 aw->login->secret_key = jk_get_worker_secret_key(props, aw->name);
314 if (aw->login->secret_key == NULL) {
315 jk_log(l, JK_LOG_ERROR, "can't malloc secret_key");
320 /* Set WebServerName (used at logon time) */
321 aw->login->web_server_name = strdup(we->server_name);
323 if (aw->login->web_server_name == NULL) {
324 jk_log(l, JK_LOG_ERROR, "can't malloc web_server_name");
329 if (get_endpoint(pThis, &je, l) == JK_FALSE) {
333 ae = je->endpoint_private;
335 if (ajp_connect_to_endpoint(ae, l) == JK_TRUE) {
337 /* connection stage passed - try to get context info
338 * this is the long awaited autoconf feature :)
340 rc = discovery(ae, we, l);
341 ajp_close_endpoint(ae, l);
351 static int JK_METHOD destroy(jk_worker_t **pThis, jk_logger_t *l)
354 ajp_worker_t *aw = (*pThis)->worker_private;
363 rc = ajp_destroy(pThis, l, AJP14_PROTO);
368 int JK_METHOD ajp14_worker_factory(jk_worker_t **w,
369 const char *name, jk_logger_t *l)
374 if (ajp_worker_factory(w, name, l) == JK_FALSE)
377 aw = (*w)->worker_private;
378 aw->proto = AJP14_PROTO;
380 aw->login = (jk_login_service_t *)malloc(sizeof(jk_login_service_t));
382 if (aw->login == NULL) {
383 jk_log(l, JK_LOG_ERROR,
384 "malloc failed for login area");
389 memset(aw->login, 0, sizeof(jk_login_service_t));
391 aw->login->negociation =
392 (AJP14_CONTEXT_INFO_NEG | AJP14_PROTO_SUPPORT_AJP14_NEG);
393 aw->login->web_server_name = NULL; /* must be set in init */
395 aw->worker.validate = validate;
396 aw->worker.init = init;
397 aw->worker.get_endpoint = get_endpoint;
398 aw->worker.destroy = destroy;
400 aw->logon = logon; /* LogOn Handler for AJP14 */
403 return JK_AJP14_WORKER_TYPE;