xref: /unit/src/java/nxt_jni_Request.c (revision 2208:26af8eadc943)
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