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 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 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 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 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 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 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 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 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 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 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 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 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), 465 r->local_length); 466 } 467 468 469 static jstring JNICALL 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); 478 colon = memchr(local, ':', r->local_length); 479 480 if (colon == NULL) { 481 colon = local + r->local_length; 482 } 483 484 return nxt_java_newString(env, local, colon - local); 485 } 486 487 488 static jint JNICALL 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); 498 colon = memchr(local, ':', r->local_length); 499 500 if (colon == NULL) { 501 return 80; 502 } 503 504 tmp = local[r->local_length]; 505 506 local[r->local_length] = '\0'; 507 508 res = strtol(colon + 1, NULL, 10); 509 510 local[r->local_length] = tmp; 511 512 return res; 513 } 514 515 516 static jstring JNICALL 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 820 nxt_java_Request_close(JNIEnv *env, jobject jreq) 821 { 822 (*env)->CallVoidMethod(env, jreq, nxt_java_Request_closeWsSession); 823 } 824