1
2 /*
3 * Copyright (C) NGINX, Inc.
4 */
5
6 #include <nxt_auto_config.h>
7
8 #include <nxt_unit.h>
9 #include <nxt_unit_request.h>
10 #include <jni.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13
14 #include "nxt_jni.h"
15 #include "nxt_jni_Request.h"
16 #include "nxt_jni_URLClassLoader.h"
17 #include "nxt_jni_HeadersEnumeration.h"
18 #include "nxt_jni_HeaderNamesEnumeration.h"
19
20
21 static jstring JNICALL nxt_java_Request_getHeader(JNIEnv *env, jclass cls,
22 jlong req_ptr, jstring name, jint name_len);
23 static jobject JNICALL nxt_java_Request_getHeaderNames(JNIEnv *env, jclass cls,
24 jlong req_ptr);
25 static jobject JNICALL nxt_java_Request_getHeaders(JNIEnv *env, jclass cls,
26 jlong req_ptr, jstring name, jint name_len);
27 static jint JNICALL nxt_java_Request_getIntHeader(JNIEnv *env, jclass cls,
28 jlong req_ptr, jstring name, jint name_len);
29 static jstring JNICALL nxt_java_Request_getMethod(JNIEnv *env, jclass cls,
30 jlong req_ptr);
31 static jstring JNICALL nxt_java_Request_getQueryString(JNIEnv *env, jclass cls,
32 jlong req_ptr);
33 static jstring JNICALL nxt_java_Request_getRequestURI(JNIEnv *env, jclass cls,
34 jlong req_ptr);
35 static jlong JNICALL nxt_java_Request_getContentLength(JNIEnv *env, jclass cls,
36 jlong req_ptr);
37 static jstring JNICALL nxt_java_Request_getContentType(JNIEnv *env, jclass cls,
38 jlong req_ptr);
39 static jstring JNICALL nxt_java_Request_getLocalAddr(JNIEnv *env, jclass cls,
40 jlong req_ptr);
41 static jstring JNICALL nxt_java_Request_getLocalName(JNIEnv *env, jclass cls,
42 jlong req_ptr);
43 static jint JNICALL nxt_java_Request_getLocalPort(JNIEnv *env, jclass cls,
44 jlong req_ptr);
45 static jstring JNICALL nxt_java_Request_getProtocol(JNIEnv *env, jclass cls,
46 jlong req_ptr);
47 static jstring JNICALL nxt_java_Request_getRemoteAddr(JNIEnv *env, jclass cls,
48 jlong req_ptr);
49 static jstring JNICALL nxt_java_Request_getRemoteHost(JNIEnv *env, jclass cls,
50 jlong req_ptr);
51 static jint JNICALL nxt_java_Request_getRemotePort(JNIEnv *env, jclass cls,
52 jlong req_ptr);
53 static jstring JNICALL nxt_java_Request_getScheme(JNIEnv *env, jclass cls,
54 jlong req_ptr);
55 static jstring JNICALL nxt_java_Request_getServerName(JNIEnv *env, jclass cls,
56 jlong req_ptr);
57 static jint JNICALL nxt_java_Request_getServerPort(JNIEnv *env, jclass cls,
58 jlong req_ptr);
59 static jboolean JNICALL nxt_java_Request_isSecure(JNIEnv *env, jclass cls,
60 jlong req_ptr);
61 static void JNICALL nxt_java_Request_upgrade(JNIEnv *env, jclass cls,
62 jlong req_info_ptr);
63 static jboolean JNICALL nxt_java_Request_isUpgrade(JNIEnv *env, jclass cls,
64 jlong req_info_ptr);
65 static void JNICALL nxt_java_Request_log(JNIEnv *env, jclass cls,
66 jlong req_info_ptr, jstring msg, jint msg_len);
67 static void JNICALL nxt_java_Request_trace(JNIEnv *env, jclass cls,
68 jlong req_info_ptr, jstring msg, jint msg_len);
69 static jobject JNICALL nxt_java_Request_getResponse(JNIEnv *env, jclass cls,
70 jlong req_info_ptr);
71 static void JNICALL nxt_java_Request_sendWsFrameBuf(JNIEnv *env, jclass cls,
72 jlong req_info_ptr, jobject buf, jint pos, jint len, jbyte opCode, jboolean last);
73 static void JNICALL nxt_java_Request_sendWsFrameArr(JNIEnv *env, jclass cls,
74 jlong req_info_ptr, jarray arr, jint pos, jint len, jbyte opCode, jboolean last);
75 static void JNICALL nxt_java_Request_closeWs(JNIEnv *env, jclass cls,
76 jlong req_info_ptr);
77
78
79 static jclass nxt_java_Request_class;
80 static jmethodID nxt_java_Request_ctor;
81 static jmethodID nxt_java_Request_processWsFrame;
82 static jmethodID nxt_java_Request_closeWsSession;
83
84
85 int
nxt_java_initRequest(JNIEnv * env,jobject cl)86 nxt_java_initRequest(JNIEnv *env, jobject cl)
87 {
88 int res;
89 jclass cls;
90
91 cls = nxt_java_loadClass(env, cl, "nginx.unit.Request");
92 if (cls == NULL) {
93 return NXT_UNIT_ERROR;
94 }
95
96 nxt_java_Request_class = (*env)->NewGlobalRef(env, cls);
97 (*env)->DeleteLocalRef(env, cls);
98 cls = nxt_java_Request_class;
99
100 nxt_java_Request_ctor = (*env)->GetMethodID(env, cls, "<init>", "(Lnginx/unit/Context;JJ)V");
101 if (nxt_java_Request_ctor == NULL) {
102 (*env)->DeleteGlobalRef(env, cls);
103 return NXT_UNIT_ERROR;
104 }
105
106 nxt_java_Request_processWsFrame = (*env)->GetMethodID(env, cls, "processWsFrame", "(Ljava/nio/ByteBuffer;BZ)V");
107 if (nxt_java_Request_processWsFrame == NULL) {
108 (*env)->DeleteGlobalRef(env, cls);
109 return NXT_UNIT_ERROR;
110 }
111
112 nxt_java_Request_closeWsSession = (*env)->GetMethodID(env, cls, "closeWsSession", "()V");
113 if (nxt_java_Request_closeWsSession == NULL) {
114 (*env)->DeleteGlobalRef(env, cls);
115 return NXT_UNIT_ERROR;
116 }
117
118 JNINativeMethod request_methods[] = {
119 { (char *) "getHeader",
120 (char *) "(JLjava/lang/String;I)Ljava/lang/String;",
121 nxt_java_Request_getHeader },
122
123 { (char *) "getHeaderNames",
124 (char *) "(J)Ljava/util/Enumeration;",
125 nxt_java_Request_getHeaderNames },
126
127 { (char *) "getHeaders",
128 (char *) "(JLjava/lang/String;I)Ljava/util/Enumeration;",
129 nxt_java_Request_getHeaders },
130
131 { (char *) "getIntHeader",
132 (char *) "(JLjava/lang/String;I)I",
133 nxt_java_Request_getIntHeader },
134
135 { (char *) "getMethod",
136 (char *) "(J)Ljava/lang/String;",
137 nxt_java_Request_getMethod },
138
139 { (char *) "getQueryString",
140 (char *) "(J)Ljava/lang/String;",
141 nxt_java_Request_getQueryString },
142
143 { (char *) "getRequestURI",
144 (char *) "(J)Ljava/lang/String;",
145 nxt_java_Request_getRequestURI },
146
147 { (char *) "getContentLength",
148 (char *) "(J)J",
149 nxt_java_Request_getContentLength },
150
151 { (char *) "getContentType",
152 (char *) "(J)Ljava/lang/String;",
153 nxt_java_Request_getContentType },
154
155 { (char *) "getLocalAddr",
156 (char *) "(J)Ljava/lang/String;",
157 nxt_java_Request_getLocalAddr },
158
159 { (char *) "getLocalName",
160 (char *) "(J)Ljava/lang/String;",
161 nxt_java_Request_getLocalName },
162
163 { (char *) "getLocalPort",
164 (char *) "(J)I",
165 nxt_java_Request_getLocalPort },
166
167 { (char *) "getProtocol",
168 (char *) "(J)Ljava/lang/String;",
169 nxt_java_Request_getProtocol },
170
171 { (char *) "getRemoteAddr",
172 (char *) "(J)Ljava/lang/String;",
173 nxt_java_Request_getRemoteAddr },
174
175 { (char *) "getRemoteHost",
176 (char *) "(J)Ljava/lang/String;",
177 nxt_java_Request_getRemoteHost },
178
179 { (char *) "getRemotePort",
180 (char *) "(J)I",
181 nxt_java_Request_getRemotePort },
182
183 { (char *) "getScheme",
184 (char *) "(J)Ljava/lang/String;",
185 nxt_java_Request_getScheme },
186
187 { (char *) "getServerName",
188 (char *) "(J)Ljava/lang/String;",
189 nxt_java_Request_getServerName },
190
191 { (char *) "getServerPort",
192 (char *) "(J)I",
193 nxt_java_Request_getServerPort },
194
195 { (char *) "isSecure",
196 (char *) "(J)Z",
197 nxt_java_Request_isSecure },
198
199 { (char *) "upgrade",
200 (char *) "(J)V",
201 nxt_java_Request_upgrade },
202
203 { (char *) "isUpgrade",
204 (char *) "(J)Z",
205 nxt_java_Request_isUpgrade },
206
207 { (char *) "log",
208 (char *) "(JLjava/lang/String;I)V",
209 nxt_java_Request_log },
210
211 { (char *) "trace",
212 (char *) "(JLjava/lang/String;I)V",
213 nxt_java_Request_trace },
214
215 { (char *) "getResponse",
216 (char *) "(J)Lnginx/unit/Response;",
217 nxt_java_Request_getResponse },
218
219 { (char *) "sendWsFrame",
220 (char *) "(JLjava/nio/ByteBuffer;IIBZ)V",
221 nxt_java_Request_sendWsFrameBuf },
222
223 { (char *) "sendWsFrame",
224 (char *) "(J[BIIBZ)V",
225 nxt_java_Request_sendWsFrameArr },
226
227 { (char *) "closeWs",
228 (char *) "(J)V",
229 nxt_java_Request_closeWs },
230
231 };
232
233 res = (*env)->RegisterNatives(env, nxt_java_Request_class,
234 request_methods,
235 sizeof(request_methods) / sizeof(request_methods[0]));
236
237 nxt_unit_debug(NULL, "registered Request methods: %d", res);
238
239 if (res != 0) {
240 nxt_unit_warn(NULL, "registering natives for Request failed");
241 goto failed;
242 }
243
244 res = nxt_java_initHeadersEnumeration(env, cl);
245 if (res != NXT_UNIT_OK) {
246 goto failed;
247 }
248
249 res = nxt_java_initHeaderNamesEnumeration(env, cl);
250 if (res != NXT_UNIT_OK) {
251 goto failed;
252 }
253
254 return NXT_UNIT_OK;
255
256 failed:
257
258 (*env)->DeleteGlobalRef(env, cls);
259 return NXT_UNIT_ERROR;
260 }
261
262
263 jobject
nxt_java_newRequest(JNIEnv * env,jobject ctx,nxt_unit_request_info_t * req)264 nxt_java_newRequest(JNIEnv *env, jobject ctx, nxt_unit_request_info_t *req)
265 {
266 return (*env)->NewObject(env, nxt_java_Request_class,
267 nxt_java_Request_ctor, ctx, nxt_ptr2jlong(req),
268 nxt_ptr2jlong(req->request));
269 }
270
271
272 static jstring JNICALL
nxt_java_Request_getHeader(JNIEnv * env,jclass cls,jlong req_ptr,jstring name,jint name_len)273 nxt_java_Request_getHeader(JNIEnv *env, jclass cls, jlong req_ptr,
274 jstring name, jint name_len)
275 {
276 const char *name_str;
277 nxt_unit_field_t *f;
278 nxt_unit_request_t *r;
279
280 name_str = (*env)->GetStringUTFChars(env, name, NULL);
281 if (name_str == NULL) {
282 return NULL;
283 }
284
285 r = nxt_jlong2ptr(req_ptr);
286
287 f = nxt_java_findHeader(r->fields, r->fields + r->fields_count,
288 name_str, name_len);
289
290 (*env)->ReleaseStringUTFChars(env, name, name_str);
291
292 if (f == NULL) {
293 return NULL;
294 }
295
296 return (*env)->NewStringUTF(env, nxt_unit_sptr_get(&f->value));
297 }
298
299
300 static jobject JNICALL
nxt_java_Request_getHeaderNames(JNIEnv * env,jclass cls,jlong req_ptr)301 nxt_java_Request_getHeaderNames(JNIEnv *env, jclass cls, jlong req_ptr)
302 {
303 nxt_unit_request_t *r;
304
305 r = nxt_jlong2ptr(req_ptr);
306
307 return nxt_java_newHeaderNamesEnumeration(env, r->fields, r->fields_count);
308 }
309
310
311 static jobject JNICALL
nxt_java_Request_getHeaders(JNIEnv * env,jclass cls,jlong req_ptr,jstring name,jint name_len)312 nxt_java_Request_getHeaders(JNIEnv *env, jclass cls, jlong req_ptr,
313 jstring name, jint name_len)
314 {
315 const char *name_str;
316 nxt_unit_field_t *f;
317 nxt_unit_request_t *r;
318
319 name_str = (*env)->GetStringUTFChars(env, name, NULL);
320 if (name_str == NULL) {
321 return NULL;
322 }
323
324 r = nxt_jlong2ptr(req_ptr);
325
326 f = nxt_java_findHeader(r->fields, r->fields + r->fields_count,
327 name_str, name_len);
328
329 (*env)->ReleaseStringUTFChars(env, name, name_str);
330
331 if (f == NULL) {
332 f = r->fields + r->fields_count;
333 }
334
335 return nxt_java_newHeadersEnumeration(env, r->fields, r->fields_count,
336 f - r->fields);
337 }
338
339
340 static jint JNICALL
nxt_java_Request_getIntHeader(JNIEnv * env,jclass cls,jlong req_ptr,jstring name,jint name_len)341 nxt_java_Request_getIntHeader(JNIEnv *env, jclass cls, jlong req_ptr,
342 jstring name, jint name_len)
343 {
344 jint res;
345 char *value, *end;
346 const char *name_str;
347 nxt_unit_field_t *f;
348 nxt_unit_request_t *r;
349
350 res = -1;
351
352 name_str = (*env)->GetStringUTFChars(env, name, NULL);
353 if (name_str == NULL) {
354 return res;
355 }
356
357 r = nxt_jlong2ptr(req_ptr);
358
359 f = nxt_java_findHeader(r->fields, r->fields + r->fields_count,
360 name_str, name_len);
361
362 (*env)->ReleaseStringUTFChars(env, name, name_str);
363
364 if (f == NULL) {
365 return res;
366 }
367
368 value = nxt_unit_sptr_get(&f->value);
369 end = value + f->value_length;
370
371 res = strtol(value, &end, 10);
372
373 if (end < value + f->value_length) {
374 // TODO throw NumberFormatException.forInputString(value)
375 }
376
377 return res;
378 }
379
380
381 static jstring JNICALL
nxt_java_Request_getMethod(JNIEnv * env,jclass cls,jlong req_ptr)382 nxt_java_Request_getMethod(JNIEnv *env, jclass cls, jlong req_ptr)
383 {
384 nxt_unit_request_t *r;
385
386 r = nxt_jlong2ptr(req_ptr);
387
388 return (*env)->NewStringUTF(env, nxt_unit_sptr_get(&r->method));
389 }
390
391
392 static jstring JNICALL
nxt_java_Request_getQueryString(JNIEnv * env,jclass cls,jlong req_ptr)393 nxt_java_Request_getQueryString(JNIEnv *env, jclass cls, jlong req_ptr)
394 {
395 char *query;
396 nxt_unit_request_t *r;
397
398 r = nxt_jlong2ptr(req_ptr);
399
400 if (r->query.offset != 0) {
401 query = nxt_unit_sptr_get(&r->query);
402 return (*env)->NewStringUTF(env, query);
403 }
404
405 return NULL;
406 }
407
408
409 static jstring JNICALL
nxt_java_Request_getRequestURI(JNIEnv * env,jclass cls,jlong req_ptr)410 nxt_java_Request_getRequestURI(JNIEnv *env, jclass cls, jlong req_ptr)
411 {
412 char *target, *query;
413 nxt_unit_request_t *r;
414
415 r = nxt_jlong2ptr(req_ptr);
416
417 target = nxt_unit_sptr_get(&r->target);
418
419 if (r->query.offset != 0) {
420 query = nxt_unit_sptr_get(&r->query);
421 return nxt_java_newString(env, target, query - target - 1);
422 }
423
424 return (*env)->NewStringUTF(env, target);
425 }
426
427
428 static jlong JNICALL
nxt_java_Request_getContentLength(JNIEnv * env,jclass cls,jlong req_ptr)429 nxt_java_Request_getContentLength(JNIEnv *env, jclass cls, jlong req_ptr)
430 {
431 nxt_unit_request_t *r;
432
433 r = nxt_jlong2ptr(req_ptr);
434
435 return r->content_length;
436 }
437
438
439 static jstring JNICALL
nxt_java_Request_getContentType(JNIEnv * env,jclass cls,jlong req_ptr)440 nxt_java_Request_getContentType(JNIEnv *env, jclass cls, jlong req_ptr)
441 {
442 nxt_unit_field_t *f;
443 nxt_unit_request_t *r;
444
445 r = nxt_jlong2ptr(req_ptr);
446
447 if (r->content_type_field != NXT_UNIT_NONE_FIELD) {
448 f = r->fields + r->content_type_field;
449
450 return (*env)->NewStringUTF(env, nxt_unit_sptr_get(&f->value));
451 }
452
453 return NULL;
454 }
455
456
457 static jstring JNICALL
nxt_java_Request_getLocalAddr(JNIEnv * env,jclass cls,jlong req_ptr)458 nxt_java_Request_getLocalAddr(JNIEnv *env, jclass cls, jlong req_ptr)
459 {
460 nxt_unit_request_t *r;
461
462 r = nxt_jlong2ptr(req_ptr);
463
464 return nxt_java_newString(env, nxt_unit_sptr_get(&r->local_addr),
465 r->local_addr_length);
466 }
467
468
469 static jstring JNICALL
nxt_java_Request_getLocalName(JNIEnv * env,jclass cls,jlong req_ptr)470 nxt_java_Request_getLocalName(JNIEnv *env, jclass cls, jlong req_ptr)
471 {
472 char *local, *colon;
473 nxt_unit_request_t *r;
474
475 r = nxt_jlong2ptr(req_ptr);
476
477 local = nxt_unit_sptr_get(&r->local_addr);
478 colon = memchr(local, ':', r->local_addr_length);
479
480 if (colon == NULL) {
481 colon = local + r->local_addr_length;
482 }
483
484 return nxt_java_newString(env, local, colon - local);
485 }
486
487
488 static jint JNICALL
nxt_java_Request_getLocalPort(JNIEnv * env,jclass cls,jlong req_ptr)489 nxt_java_Request_getLocalPort(JNIEnv *env, jclass cls, jlong req_ptr)
490 {
491 jint res;
492 char *local, *colon, tmp;
493 nxt_unit_request_t *r;
494
495 r = nxt_jlong2ptr(req_ptr);
496
497 local = nxt_unit_sptr_get(&r->local_addr);
498 colon = memchr(local, ':', r->local_addr_length);
499
500 if (colon == NULL) {
501 return 80;
502 }
503
504 tmp = local[r->local_addr_length];
505
506 local[r->local_addr_length] = '\0';
507
508 res = strtol(colon + 1, NULL, 10);
509
510 local[r->local_addr_length] = tmp;
511
512 return res;
513 }
514
515
516 static jstring JNICALL
nxt_java_Request_getProtocol(JNIEnv * env,jclass cls,jlong req_ptr)517 nxt_java_Request_getProtocol(JNIEnv *env, jclass cls, jlong req_ptr)
518 {
519 nxt_unit_request_t *r;
520
521 r = nxt_jlong2ptr(req_ptr);
522
523 return (*env)->NewStringUTF(env, nxt_unit_sptr_get(&r->version));
524 }
525
526
527 static jstring JNICALL
nxt_java_Request_getRemoteAddr(JNIEnv * env,jclass cls,jlong req_ptr)528 nxt_java_Request_getRemoteAddr(JNIEnv *env, jclass cls, jlong req_ptr)
529 {
530 nxt_unit_request_t *r;
531
532 r = nxt_jlong2ptr(req_ptr);
533
534 return nxt_java_newString(env, nxt_unit_sptr_get(&r->remote),
535 r->remote_length);
536 }
537
538
539 static jstring JNICALL
nxt_java_Request_getRemoteHost(JNIEnv * env,jclass cls,jlong req_ptr)540 nxt_java_Request_getRemoteHost(JNIEnv *env, jclass cls, jlong req_ptr)
541 {
542 char *remote, *colon;
543 nxt_unit_request_t *r;
544
545 r = nxt_jlong2ptr(req_ptr);
546
547 remote = nxt_unit_sptr_get(&r->remote);
548 colon = memchr(remote, ':', r->remote_length);
549
550 if (colon == NULL) {
551 colon = remote + r->remote_length;
552 }
553
554 return nxt_java_newString(env, remote, colon - remote);
555 }
556
557
558 static jint JNICALL
nxt_java_Request_getRemotePort(JNIEnv * env,jclass cls,jlong req_ptr)559 nxt_java_Request_getRemotePort(JNIEnv *env, jclass cls, jlong req_ptr)
560 {
561 jint res;
562 char *remote, *colon, tmp;
563 nxt_unit_request_t *r;
564
565 r = nxt_jlong2ptr(req_ptr);
566
567 remote = nxt_unit_sptr_get(&r->remote);
568 colon = memchr(remote, ':', r->remote_length);
569
570 if (colon == NULL) {
571 return 80;
572 }
573
574 tmp = remote[r->remote_length];
575
576 remote[r->remote_length] = '\0';
577
578 res = strtol(colon + 1, NULL, 10);
579
580 remote[r->remote_length] = tmp;
581
582 return res;
583 }
584
585
586 static jstring JNICALL
nxt_java_Request_getScheme(JNIEnv * env,jclass cls,jlong req_ptr)587 nxt_java_Request_getScheme(JNIEnv *env, jclass cls, jlong req_ptr)
588 {
589 nxt_unit_request_t *r;
590
591 r = nxt_jlong2ptr(req_ptr);
592
593 return (*env)->NewStringUTF(env, r->tls ? "https" : "http");
594 }
595
596
597 static jstring JNICALL
nxt_java_Request_getServerName(JNIEnv * env,jclass cls,jlong req_ptr)598 nxt_java_Request_getServerName(JNIEnv *env, jclass cls, jlong req_ptr)
599 {
600 char *host, *colon;
601 nxt_unit_field_t *f;
602 nxt_unit_request_t *r;
603
604 r = nxt_jlong2ptr(req_ptr);
605
606 f = nxt_java_findHeader(r->fields, r->fields + r->fields_count,
607 "Host", 4);
608 if (f != NULL) {
609 host = nxt_unit_sptr_get(&f->value);
610
611 colon = memchr(host, ':', f->value_length);
612
613 if (colon == NULL) {
614 colon = host + f->value_length;
615 }
616
617 return nxt_java_newString(env, host, colon - host);
618 }
619
620 return nxt_java_Request_getLocalName(env, cls, req_ptr);
621 }
622
623
624 static jint JNICALL
nxt_java_Request_getServerPort(JNIEnv * env,jclass cls,jlong req_ptr)625 nxt_java_Request_getServerPort(JNIEnv *env, jclass cls, jlong req_ptr)
626 {
627 jint res;
628 char *host, *colon, tmp;
629 nxt_unit_field_t *f;
630 nxt_unit_request_t *r;
631
632 r = nxt_jlong2ptr(req_ptr);
633
634 f = nxt_java_findHeader(r->fields, r->fields + r->fields_count,
635 "Host", 4);
636 if (f != NULL) {
637 host = nxt_unit_sptr_get(&f->value);
638
639 colon = memchr(host, ':', f->value_length);
640
641 if (colon == NULL) {
642 return 80;
643 }
644
645 tmp = host[f->value_length];
646
647 host[f->value_length] = '\0';
648
649 res = strtol(colon + 1, NULL, 10);
650
651 host[f->value_length] = tmp;
652
653 return res;
654 }
655
656 return nxt_java_Request_getLocalPort(env, cls, req_ptr);
657 }
658
659
660 static jboolean JNICALL
nxt_java_Request_isSecure(JNIEnv * env,jclass cls,jlong req_ptr)661 nxt_java_Request_isSecure(JNIEnv *env, jclass cls, jlong req_ptr)
662 {
663 nxt_unit_request_t *r;
664
665 r = nxt_jlong2ptr(req_ptr);
666
667 return r->tls != 0;
668 }
669
670
671 static void JNICALL
nxt_java_Request_upgrade(JNIEnv * env,jclass cls,jlong req_info_ptr)672 nxt_java_Request_upgrade(JNIEnv *env, jclass cls, jlong req_info_ptr)
673 {
674 nxt_unit_request_info_t *req;
675
676 req = nxt_jlong2ptr(req_info_ptr);
677
678 if (!nxt_unit_response_is_init(req)) {
679 nxt_unit_response_init(req, 101, 0, 0);
680 }
681
682 (void) nxt_unit_response_upgrade(req);
683 }
684
685
686 static jboolean JNICALL
nxt_java_Request_isUpgrade(JNIEnv * env,jclass cls,jlong req_info_ptr)687 nxt_java_Request_isUpgrade(JNIEnv *env, jclass cls, jlong req_info_ptr)
688 {
689 nxt_unit_request_info_t *req;
690
691 req = nxt_jlong2ptr(req_info_ptr);
692
693 return nxt_unit_request_is_websocket_handshake(req);
694 }
695
696
697 static void JNICALL
nxt_java_Request_log(JNIEnv * env,jclass cls,jlong req_info_ptr,jstring msg,jint msg_len)698 nxt_java_Request_log(JNIEnv *env, jclass cls, jlong req_info_ptr, jstring msg,
699 jint msg_len)
700 {
701 const char *msg_str;
702 nxt_unit_request_info_t *req;
703
704 req = nxt_jlong2ptr(req_info_ptr);
705
706 msg_str = (*env)->GetStringUTFChars(env, msg, NULL);
707 if (msg_str == NULL) {
708 return;
709 }
710
711 nxt_unit_req_log(req, NXT_UNIT_LOG_INFO, "%.*s", msg_len, msg_str);
712
713 (*env)->ReleaseStringUTFChars(env, msg, msg_str);
714 }
715
716
717 static void JNICALL
nxt_java_Request_trace(JNIEnv * env,jclass cls,jlong req_info_ptr,jstring msg,jint msg_len)718 nxt_java_Request_trace(JNIEnv *env, jclass cls, jlong req_info_ptr, jstring msg,
719 jint msg_len)
720 {
721 #if (NXT_DEBUG)
722 const char *msg_str;
723 nxt_unit_request_info_t *req;
724
725 req = nxt_jlong2ptr(req_info_ptr);
726
727 msg_str = (*env)->GetStringUTFChars(env, msg, NULL);
728 if (msg_str == NULL) {
729 return;
730 }
731
732 nxt_unit_req_debug(req, "%.*s", msg_len, msg_str);
733
734 (*env)->ReleaseStringUTFChars(env, msg, msg_str);
735 #endif
736 }
737
738
739 static jobject JNICALL
nxt_java_Request_getResponse(JNIEnv * env,jclass cls,jlong req_info_ptr)740 nxt_java_Request_getResponse(JNIEnv *env, jclass cls, jlong req_info_ptr)
741 {
742 nxt_unit_request_info_t *req;
743 nxt_java_request_data_t *data;
744
745 req = nxt_jlong2ptr(req_info_ptr);
746 data = req->data;
747
748 return data->jresp;
749 }
750
751
752 static void JNICALL
nxt_java_Request_sendWsFrameBuf(JNIEnv * env,jclass cls,jlong req_info_ptr,jobject buf,jint pos,jint len,jbyte opCode,jboolean last)753 nxt_java_Request_sendWsFrameBuf(JNIEnv *env, jclass cls,
754 jlong req_info_ptr, jobject buf, jint pos, jint len, jbyte opCode, jboolean last)
755 {
756 nxt_unit_request_info_t *req;
757
758 req = nxt_jlong2ptr(req_info_ptr);
759 uint8_t *b = (*env)->GetDirectBufferAddress(env, buf);
760
761 if (b != NULL) {
762 nxt_unit_websocket_send(req, opCode, last, b + pos, len);
763
764 } else {
765 nxt_unit_req_debug(req, "sendWsFrameBuf: b == NULL");
766 }
767 }
768
769
770 static void JNICALL
nxt_java_Request_sendWsFrameArr(JNIEnv * env,jclass cls,jlong req_info_ptr,jarray arr,jint pos,jint len,jbyte opCode,jboolean last)771 nxt_java_Request_sendWsFrameArr(JNIEnv *env, jclass cls,
772 jlong req_info_ptr, jarray arr, jint pos, jint len, jbyte opCode, jboolean last)
773 {
774 nxt_unit_request_info_t *req;
775
776 req = nxt_jlong2ptr(req_info_ptr);
777 uint8_t *b = (*env)->GetPrimitiveArrayCritical(env, arr, NULL);
778
779 if (b != NULL) {
780 if (!nxt_unit_response_is_sent(req)) {
781 nxt_unit_response_send(req);
782 }
783
784 nxt_unit_websocket_send(req, opCode, last, b + pos, len);
785
786 (*env)->ReleasePrimitiveArrayCritical(env, arr, b, 0);
787
788 } else {
789 nxt_unit_req_debug(req, "sendWsFrameArr: b == NULL");
790 }
791 }
792
793
794 static void JNICALL
nxt_java_Request_closeWs(JNIEnv * env,jclass cls,jlong req_info_ptr)795 nxt_java_Request_closeWs(JNIEnv *env, jclass cls, jlong req_info_ptr)
796 {
797 nxt_unit_request_info_t *req;
798 nxt_java_request_data_t *data;
799
800 req = nxt_jlong2ptr(req_info_ptr);
801
802 data = req->data;
803
804 (*env)->DeleteGlobalRef(env, data->jresp);
805 (*env)->DeleteGlobalRef(env, data->jreq);
806
807 nxt_unit_request_done(req, NXT_UNIT_OK);
808 }
809
810
811 void
nxt_java_Request_websocket(JNIEnv * env,jobject jreq,jobject jbuf,uint8_t opcode,uint8_t fin)812 nxt_java_Request_websocket(JNIEnv *env, jobject jreq, jobject jbuf,
813 uint8_t opcode, uint8_t fin)
814 {
815 (*env)->CallVoidMethod(env, jreq, nxt_java_Request_processWsFrame, jbuf, opcode, fin);
816 }
817
818
819 void
nxt_java_Request_close(JNIEnv * env,jobject jreq)820 nxt_java_Request_close(JNIEnv *env, jobject jreq)
821 {
822 (*env)->CallVoidMethod(env, jreq, nxt_java_Request_closeWsSession);
823 }
824