bottleneck testcase based on rubbos
[bottlenecks.git] / rubbos / app / tomcat-connectors-1.2.32-src / native / jni / jk_jnicb.c
1 /*
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
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
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.
16  */
17
18 /***************************************************************************
19  * Description: JNI callbacks implementation for the JNI in process adapter*
20  * Author:      Gal Shachor <shachor@il.ibm.com>                           *
21  * Version:     $Revision: 466585 $                                           *
22  ***************************************************************************/
23
24 #include "jk_jnicb.h"
25 #include "jk_service.h"
26 #include "jk_util.h"
27 #include "jk_pool.h"
28
29 /*
30  * Class:     org_apache_tomcat_modules_server_JNIConnectionHandler
31  * Method:    getNumberOfHeaders
32  * Signature: (JJ)I
33  */
34 JNIEXPORT jint JNICALL
35     Java_org_apache_tomcat_modules_server_JNIConnectionHandler_getNumberOfHeaders
36     (JNIEnv * env, jobject o, jlong s, jlong l)
37 {
38     /* [V] Convert indirectly from jlong -> int -> pointer to shut up gcc */
39     /*     I hope it's okay on other compilers and/or machines...         */
40     jk_ws_service_t *ps = (jk_ws_service_t *)(int)s;
41     jk_logger_t *pl = (jk_logger_t *)(int)l;
42
43     jk_log(pl, JK_LOG_DEBUG,
44            "Into JNIConnectionHandler::getNumberOfHeaders\n");
45
46     if (!ps) {
47         jk_log(pl, JK_LOG_ERROR,
48                "In JNIConnectionHandler::getNumberOfHeaders, NULL ws service object\n");
49         /* [V] JNIConnectionHandler doesn't handle this */
50         return -1;
51     }
52
53     jk_log(pl, JK_LOG_DEBUG,
54            "Done JNIConnectionHandler::getNumberOfHeaders, found %d headers\n",
55            ps->num_headers);
56     return (jint) ps->num_headers;
57 }
58
59 /*
60  * Class:     org_apache_tomcat_modules_server_JNIConnectionHandler
61  * Method:    read
62  * Signature: (JJ[BII)I
63  */
64 JNIEXPORT jint JNICALL
65     Java_org_apache_tomcat_modules_server_JNIConnectionHandler_read
66     (JNIEnv * env, jobject o, jlong s, jlong l, jbyteArray buf, jint from,
67      jint cnt)
68 {
69     jk_ws_service_t *ps = (jk_ws_service_t *)(int)s;
70     jk_logger_t *pl = (jk_logger_t *)(int)l;
71     jint rc = -1;
72     jboolean iscommit;
73     jbyte *nbuf;
74     unsigned nfrom = (unsigned)from;
75     unsigned ncnt = (unsigned)cnt;
76     unsigned acc = 0;
77
78     jk_log(pl, JK_LOG_DEBUG, "Into JNIConnectionHandler::read\n");
79
80     if (!ps) {
81         jk_log(pl, JK_LOG_ERROR,
82                "In JNIConnectionHandler::read, NULL ws service object\n");
83         return -1;
84     }
85
86     nbuf = (*env)->GetByteArrayElements(env, buf, &iscommit);
87
88     if (!nbuf) {
89         jk_log(pl, JK_LOG_ERROR,
90                "In JNIConnectionHandler::read, GetByteArrayElements error\n");
91         return -1;
92     }
93
94     if (!ps->read(ps, nbuf + nfrom, ncnt, &acc)) {
95         jk_log(pl, JK_LOG_ERROR,
96                "In JNIConnectionHandler::read, failed to read from web server\n");
97     }
98     else {
99         rc = (jint) acc;
100     }
101
102     (*env)->ReleaseByteArrayElements(env, buf, nbuf, 0);
103
104     jk_log(pl, JK_LOG_DEBUG, "Done JNIConnectionHandler::read\n");
105     return rc;
106 }
107
108 /*
109  * Class:     org_apache_tomcat_modules_server_JNIConnectionHandler
110  * Method:    readEnvironment
111  * Signature: (JJ[Ljava/lang/String;)I
112  */
113 JNIEXPORT jint JNICALL
114     Java_org_apache_tomcat_modules_server_JNIConnectionHandler_readEnvironment
115     (JNIEnv * env, jobject o, jlong s, jlong l, jobjectArray envbuf)
116 {
117     jk_ws_service_t *ps = (jk_ws_service_t *)(int)s;
118     jk_logger_t *pl = (jk_logger_t *)(int)l;
119     char port[10];
120
121     jk_log(pl, JK_LOG_DEBUG,
122            "Into JNIConnectionHandler::readEnvironment. Environment follows --->\n");
123
124     if (!ps) {
125         jk_log(pl, JK_LOG_ERROR,
126                "In JNIConnectionHandler::readEnvironment, NULL ws service object\n");
127         return JK_FALSE;
128     }
129
130     sprintf(port, "%d", ps->server_port);
131
132     if (ps->method) {
133         (*env)->SetObjectArrayElement(env,
134                                       envbuf,
135                                       0,
136                                       (*env)->NewStringUTF(env, ps->method));
137         jk_log(pl, JK_LOG_DEBUG, "---> method: %s\n", ps->method);
138     }
139     if (ps->req_uri) {
140         (*env)->SetObjectArrayElement(env,
141                                       envbuf,
142                                       1,
143                                       (*env)->NewStringUTF(env, ps->req_uri));
144         jk_log(pl, JK_LOG_DEBUG, "---> req_uri: %s\n", ps->req_uri);
145     }
146     if (ps->query_string) {
147         (*env)->SetObjectArrayElement(env,
148                                       envbuf,
149                                       2,
150                                       (*env)->NewStringUTF(env,
151                                                            ps->query_string));
152         jk_log(pl, JK_LOG_DEBUG, "---> query_string: %s\n", ps->query_string);
153     }
154     if (ps->remote_addr) {
155         (*env)->SetObjectArrayElement(env,
156                                       envbuf,
157                                       3,
158                                       (*env)->NewStringUTF(env,
159                                                            ps->remote_addr));
160         jk_log(pl, JK_LOG_DEBUG, "---> remote_addr: %s\n", ps->remote_addr);
161     }
162     if (ps->remote_host) {
163         (*env)->SetObjectArrayElement(env,
164                                       envbuf,
165                                       4,
166                                       (*env)->NewStringUTF(env,
167                                                            ps->remote_host));
168         jk_log(pl, JK_LOG_DEBUG, "---> remote_host: %s\n", ps->remote_host);
169     }
170     if (ps->server_name) {
171         (*env)->SetObjectArrayElement(env,
172                                       envbuf,
173                                       5,
174                                       (*env)->NewStringUTF(env,
175                                                            ps->server_name));
176         jk_log(pl, JK_LOG_DEBUG, "---> server_name: %s\n", ps->server_name);
177     }
178
179     (*env)->SetObjectArrayElement(env,
180                                   envbuf, 6, (*env)->NewStringUTF(env, port));
181     jk_log(pl, JK_LOG_DEBUG, "---> server_port: %s\n", port);
182
183     if (ps->auth_type) {
184         (*env)->SetObjectArrayElement(env,
185                                       envbuf,
186                                       7,
187                                       (*env)->NewStringUTF(env,
188                                                            ps->auth_type));
189         jk_log(pl, JK_LOG_DEBUG, "---> auth_type: %s\n", ps->auth_type);
190     }
191     if (ps->remote_user) {
192         (*env)->SetObjectArrayElement(env,
193                                       envbuf,
194                                       8,
195                                       (*env)->NewStringUTF(env,
196                                                            ps->remote_user));
197         jk_log(pl, JK_LOG_DEBUG, "---> remote_user: %s\n", ps->remote_user);
198     }
199     if (ps->is_ssl) {
200         (*env)->SetObjectArrayElement(env,
201                                       envbuf,
202                                       9, (*env)->NewStringUTF(env, "https"));
203     }
204     else {
205         (*env)->SetObjectArrayElement(env,
206                                       envbuf,
207                                       9, (*env)->NewStringUTF(env, "http"));
208     }
209     jk_log(pl, JK_LOG_DEBUG, "---> is_ssl: %s\n", ps->is_ssl ? "yes" : "no");
210
211     if (ps->protocol) {
212         (*env)->SetObjectArrayElement(env,
213                                       envbuf,
214                                       10,
215                                       (*env)->NewStringUTF(env,
216                                                            ps->protocol));
217         jk_log(pl, JK_LOG_DEBUG, "---> protocol: %s\n", ps->protocol);
218     }
219     if (ps->server_software) {
220         (*env)->SetObjectArrayElement(env,
221                                       envbuf,
222                                       11,
223                                       (*env)->NewStringUTF(env,
224                                                            ps->
225                                                            server_software));
226         jk_log(pl, JK_LOG_DEBUG, "---> server_software: %s\n",
227                ps->server_software);
228     }
229     if (ps->is_ssl) {
230         if (ps->ssl_cert) {
231             (*env)->SetObjectArrayElement(env,
232                                           envbuf,
233                                           12,
234                                           (*env)->NewStringUTF(env,
235                                                                ps->ssl_cert));
236             jk_log(pl, JK_LOG_DEBUG, "---> ssl_cert: %s\n", ps->ssl_cert);
237         }
238
239         if (ps->ssl_cipher) {
240             (*env)->SetObjectArrayElement(env,
241                                           envbuf,
242                                           13,
243                                           (*env)->NewStringUTF(env,
244                                                                ps->
245                                                                ssl_cipher));
246             jk_log(pl, JK_LOG_DEBUG, "---> ssl_cipher: %s\n", ps->ssl_cipher);
247         }
248
249         if (ps->ssl_session) {
250             (*env)->SetObjectArrayElement(env,
251                                           envbuf,
252                                           14,
253                                           (*env)->NewStringUTF(env,
254                                                                ps->
255                                                                ssl_session));
256             jk_log(pl, JK_LOG_DEBUG, "---> ssl_session: %s\n",
257                    ps->ssl_session);
258         }
259     }
260
261     jk_log(pl, JK_LOG_DEBUG, "Done JNIConnectionHandler::readEnvironment\n");
262
263
264     return JK_TRUE;
265 }
266
267 /*
268  * Class:     org_apache_tomcat_modules_server_JNIConnectionHandler
269  * Method:    readHeaders
270  * Signature: (JJ[Ljava/lang/String;[Ljava/lang/String;)I
271  */
272 JNIEXPORT jint JNICALL
273     Java_org_apache_tomcat_modules_server_JNIConnectionHandler_readHeaders
274     (JNIEnv * env, jobject o, jlong s, jlong l, jobjectArray hnames,
275      jobjectArray hvalues)
276 {
277     jk_ws_service_t *ps = (jk_ws_service_t *)(int)s;
278     jk_logger_t *pl = (jk_logger_t *)(int)l;
279     unsigned i;
280
281     jk_log(pl, JK_LOG_DEBUG, "Into JNIConnectionHandler::readHeaders\n");
282
283     if (!ps) {
284         jk_log(pl, JK_LOG_ERROR,
285                "In JNIConnectionHandler::readHeaders, NULL ws service object\n");
286         return JK_FALSE;
287     }
288
289     jk_log(pl, JK_LOG_DEBUG,
290            "In JNIConnectionHandler::readHeaders, %d headers follow --->\n",
291            ps->num_headers);
292
293     for (i = 0; i < ps->num_headers; i++) {
294         (*env)->SetObjectArrayElement(env,
295                                       hnames,
296                                       i,
297                                       (*env)->NewStringUTF(env,
298                                                            ps->
299                                                            headers_names[i]));
300         (*env)->SetObjectArrayElement(env, hvalues, i,
301                                       (*env)->NewStringUTF(env,
302                                                            ps->
303                                                            headers_values
304                                                            [i]));
305         jk_log(pl, JK_LOG_DEBUG, "---> %s = %s\n", ps->headers_names[i],
306                ps->headers_values[i]);
307     }
308     jk_log(pl, JK_LOG_DEBUG, "Done JNIConnectionHandler::readHeaders\n");
309
310     return JK_TRUE;
311 }
312
313 /*
314  * Class:     org_apache_tomcat_modules_server_JNIConnectionHandler
315  * Method:    startReasponse
316  * Signature: (JJILjava/lang/String;[Ljava/lang/String;[Ljava/lang/String;I)I
317  */
318 JNIEXPORT jint JNICALL
319     Java_org_apache_tomcat_modules_server_JNIConnectionHandler_startReasponse
320     (JNIEnv * env, jobject o, jlong s, jlong l,
321      jint sc, jstring msg, jobjectArray hnames, jobjectArray hvalues,
322      jint hcnt)
323 {
324     jk_ws_service_t *ps = (jk_ws_service_t *)(int)s;
325     jk_logger_t *pl = (jk_logger_t *)(int)l;
326     const char *nmsg = NULL;
327     char **nhnames = NULL;
328     char **nhvalues = NULL;
329     jstring *shnames = NULL;
330     jstring *shvalues = NULL;
331     int i = 0;
332     int ok = JK_TRUE;
333
334     jk_log(pl, JK_LOG_DEBUG, "Into JNIConnectionHandler::startReasponse\n");
335
336     if (!ps) {
337         jk_log(pl, JK_LOG_ERROR,
338                "In JNIConnectionHandler::startReasponse, NULL ws service object\n");
339         return JK_FALSE;
340     }
341
342     jk_log(pl, JK_LOG_DEBUG,
343            "In JNIConnectionHandler::startReasponse, %d headers follow --->\n",
344            hcnt);
345
346     if (hcnt) {
347         ok = JK_FALSE;
348
349         nhnames = (char **)jk_pool_alloc(ps->pool, hcnt * sizeof(char *));
350         nhvalues = (char **)jk_pool_alloc(ps->pool, hcnt * sizeof(char *));
351         shnames = (jstring *) jk_pool_alloc(ps->pool, hcnt * sizeof(jstring));
352         shvalues =
353             (jstring *) jk_pool_alloc(ps->pool, hcnt * sizeof(jstring));
354
355         if (nhvalues && nhnames && shnames && shnames) {
356             for (; i < hcnt; i++) {
357                 jboolean iscommit;
358
359                 shvalues[i] = shnames[i] = NULL;
360                 nhnames[i] = nhvalues[i] = NULL;
361
362                 shnames[i] = (*env)->GetObjectArrayElement(env, hnames, i);
363                 shvalues[i] = (*env)->GetObjectArrayElement(env, hvalues, i);
364
365                 if (!shvalues[i] || !shnames[i]) {
366                     jk_log(pl, JK_LOG_ERROR,
367                            "In JNIConnectionHandler::startReasponse, GetObjectArrayElement error\n");
368                     break;
369                 }
370
371                 nhnames[i] =
372                     (char *)(*env)->GetStringUTFChars(env, shnames[i],
373                                                       &iscommit);
374                 nhvalues[i] =
375                     (char *)(*env)->GetStringUTFChars(env, shvalues[i],
376                                                       &iscommit);
377
378                 if (!nhvalues[i] || !nhnames[i]) {
379                     jk_log(pl, JK_LOG_ERROR,
380                            "In JNIConnectionHandler::startReasponse, GetStringUTFChars error\n");
381                     break;
382                 }
383
384                 jk_log(pl, JK_LOG_DEBUG, "---> %s=%s\n", nhnames[i],
385                        nhvalues[i]);
386             }
387             if (i == hcnt) {
388                 ok = JK_TRUE;
389                 jk_log(pl, JK_LOG_DEBUG,
390                        "In JNIConnectionHandler::startReasponse. ----- End headers.\n",
391                        hcnt);
392             }
393         }
394         else {
395             jk_log(pl, JK_LOG_ERROR,
396                    "In JNIConnectionHandler::startReasponse, memory allocation error\n");
397         }
398     }
399
400     if (msg && ok) {
401         jboolean iscommit;
402         nmsg = (*env)->GetStringUTFChars(env, msg, &iscommit);
403         if (!nmsg) {
404             ok = JK_FALSE;
405         }
406     }
407
408     if (ok) {
409         if (!ps->
410             start_response(ps, sc, nmsg, (const char **)nhnames,
411                            (const char **)nhvalues, hcnt)) {
412             ok = JK_FALSE;
413             jk_log(pl, JK_LOG_ERROR,
414                    "In JNIConnectionHandler::startReasponse, servers startReasponse failed\n");
415         }
416     }
417
418     if (nmsg) {
419         (*env)->ReleaseStringUTFChars(env, msg, nmsg);
420     }
421
422     if (i < hcnt) {
423         i++;
424     }
425
426     if (nhvalues) {
427         int j;
428
429         for (j = 0; j < i; j++) {
430             if (nhvalues[j]) {
431                 (*env)->ReleaseStringUTFChars(env, shvalues[j], nhvalues[j]);
432             }
433         }
434     }
435
436     if (nhnames) {
437         int j;
438
439         for (j = 0; j < i; j++) {
440             if (nhnames[j]) {
441                 (*env)->ReleaseStringUTFChars(env, shnames[j], nhnames[j]);
442             }
443         }
444     }
445     jk_log(pl, JK_LOG_DEBUG, "Done JNIConnectionHandler::startReasponse.\n");
446
447     return ok;
448 }
449
450 /*
451  * Class:     org_apache_tomcat_modules_server_JNIConnectionHandler
452  * Method:    write
453  * Signature: (JJ[BII)I
454  */
455 JNIEXPORT jint JNICALL
456     Java_org_apache_tomcat_modules_server_JNIConnectionHandler_write
457     (JNIEnv * env, jobject o, jlong s, jlong l, jbyteArray buf, jint from,
458      jint cnt)
459 {
460     jk_ws_service_t *ps = (jk_ws_service_t *)(int)s;
461     jk_logger_t *pl = (jk_logger_t *)(int)l;
462     jint rc = JK_FALSE;
463     jboolean iscommit;
464     jbyte *nbuf;
465     unsigned nfrom = (unsigned)from;
466     unsigned ncnt = (unsigned)cnt;
467
468     jk_log(pl, JK_LOG_DEBUG, "In JNIConnectionHandler::write\n");
469
470     if (!ps) {
471         jk_log(pl, JK_LOG_ERROR,
472                "In JNIConnectionHandler::write, NULL ws service object\n");
473         return JK_FALSE;
474     }
475
476     nbuf = (*env)->GetByteArrayElements(env, buf, &iscommit);
477
478     if (!nbuf) {
479         jk_log(pl, JK_LOG_ERROR,
480                "In JNIConnectionHandler::write, GetByteArrayElements error\n");
481         return JK_FALSE;
482     }
483
484     if (!ps->write(ps, nbuf + nfrom, ncnt)) {
485         jk_log(pl, JK_LOG_ERROR,
486                "In JNIConnectionHandler::write, failed to write to the web server\n");
487     }
488     else {
489         rc = (jint) JK_TRUE;
490     }
491
492     (*env)->ReleaseByteArrayElements(env, buf, nbuf, JNI_ABORT);
493
494     return rc;
495 }