111 jurl = nxt_cpymem(jurl, *jar, nxt_strlen(*jar)); 112 *jurl++ = '\0'; 113 } 114 115 return res; 116} 117 118 119static nxt_int_t 120nxt_java_start(nxt_task_t *task, nxt_process_data_t *data) 121{ 122 jint rc; 123 char *opt, *real_path; 124 char **classpath_arr, **unit_jars, **system_jars; 125 JavaVM *jvm; 126 JNIEnv *env; 127 jobject cl, classpath; 128 nxt_str_t str; 129 nxt_int_t opt_len, real_path_len; 130 nxt_uint_t i, unit_jars_count, classpath_count; 131 nxt_uint_t system_jars_count; 132 JavaVMOption *jvm_opt; 133 JavaVMInitArgs jvm_args; 134 nxt_unit_ctx_t *ctx; 135 nxt_unit_init_t java_init; 136 nxt_java_data_t java_data; 137 nxt_conf_value_t *value; 138 nxt_java_app_conf_t *c; 139 nxt_common_app_conf_t *app_conf; 140 141 //setenv("ASAN_OPTIONS", "handle_segv=0", 1); 142 143 jvm_args.version = JNI_VERSION_1_6; 144 jvm_args.nOptions = 0; 145 jvm_args.ignoreUnrecognized = 0; 146 147 app_conf = data->app; 148 c = &app_conf->u.java; 149 150 if (c->options != NULL) { 151 jvm_args.nOptions += nxt_conf_array_elements_count(c->options); 152 } 153 154 jvm_opt = nxt_malloc(jvm_args.nOptions * sizeof(JavaVMOption)); 155 if (jvm_opt == NULL) { 156 nxt_alert(task, "failed to allocate jvm_opt"); 157 return NXT_ERROR; 158 } 159 160 jvm_args.options = jvm_opt; 161 162 unit_jars_count = nxt_nitems(nxt_java_unit_jars) - 1; 163 164 unit_jars = nxt_java_module_jars(nxt_java_unit_jars, unit_jars_count); 165 if (unit_jars == NULL) { 166 nxt_alert(task, "failed to allocate buffer for unit_jars array"); 167 168 return NXT_ERROR; 169 } 170 171 system_jars_count = nxt_nitems(nxt_java_system_jars) - 1; 172 173 system_jars = nxt_java_module_jars(nxt_java_system_jars, system_jars_count); 174 if (system_jars == NULL) { 175 nxt_alert(task, "failed to allocate buffer for system_jars array"); 176 177 return NXT_ERROR; 178 } 179 180 if (c->options != NULL) { 181 182 for (i = 0; /* void */ ; i++) { 183 value = nxt_conf_get_array_element(c->options, i); 184 if (value == NULL) { 185 break; 186 } 187 188 nxt_conf_get_string(value, &str); 189 190 opt = nxt_malloc(str.length + 1); 191 if (opt == NULL) { 192 nxt_alert(task, "failed to allocate jvm_opt"); 193 return NXT_ERROR; 194 } 195 196 memcpy(opt, str.start, str.length); 197 opt[str.length] = '\0'; 198 199 jvm_opt[i].optionString = opt; 200 } 201 } 202 203 if (c->classpath != NULL) { 204 classpath_count = nxt_conf_array_elements_count(c->classpath); 205 classpath_arr = nxt_malloc(classpath_count * sizeof(char *)); 206 207 for (i = 0; /* void */ ; i++) { 208 value = nxt_conf_get_array_element(c->classpath, i); 209 if (value == NULL) { 210 break; 211 } 212 213 nxt_conf_get_string(value, &str); 214 215 opt_len = str.length + 1; 216 217 char *sc = memchr(str.start, ':', str.length); 218 if (sc == NULL && str.start[0] == '/') { 219 opt_len += nxt_length("file:"); 220 } 221 222 opt = nxt_malloc(opt_len); 223 if (opt == NULL) { 224 nxt_alert(task, "failed to allocate classpath"); 225 return NXT_ERROR; 226 } 227 228 if (sc == NULL && str.start[0] != '/') { 229 nxt_memcpy(opt, str.start, str.length); 230 opt[str.length] = '\0'; 231 232 real_path = realpath(opt, NULL); 233 if (real_path == NULL) { 234 nxt_alert(task, "realpath(%s) failed: %E", opt, nxt_errno); 235 return NXT_ERROR; 236 } 237 238 real_path_len = nxt_strlen(real_path); 239 240 free(opt); 241 242 opt_len = nxt_length("file:") + real_path_len + 1; 243 244 opt = nxt_malloc(opt_len); 245 if (opt == NULL) { 246 nxt_alert(task, "failed to allocate classpath"); 247 return NXT_ERROR; 248 } 249 250 } else { 251 real_path = (char *) str.start; /* I love this cast! */ 252 real_path_len = str.length; 253 } 254 255 classpath_arr[i] = opt; 256 257 if (sc == NULL) { 258 opt = nxt_cpymem(opt, "file:", nxt_length("file:")); 259 } 260 261 opt = nxt_cpymem(opt, real_path, real_path_len); 262 *opt = '\0'; 263 } 264 265 } else { 266 classpath_count = 0; 267 classpath_arr = NULL; 268 } 269 270 rc = JNI_CreateJavaVM(&jvm, (void **) &env, &jvm_args); 271 if (rc != JNI_OK) { 272 nxt_alert(task, "failed to create Java VM: %d", (int) rc); 273 return NXT_ERROR; 274 } 275 276 rc = nxt_java_initThread(env); 277 if (rc != NXT_UNIT_OK) { 278 nxt_alert(task, "nxt_java_initThread() failed"); 279 goto env_failed; 280 } 281 282 rc = nxt_java_initURLClassLoader(env); 283 if (rc != NXT_UNIT_OK) { 284 nxt_alert(task, "nxt_java_initURLClassLoader() failed"); 285 goto env_failed; 286 } 287 288 cl = nxt_java_newURLClassLoader(env, system_jars_count, system_jars); 289 if (cl == NULL) { 290 nxt_alert(task, "nxt_java_newURLClassLoader failed"); 291 goto env_failed; 292 } 293 294 nxt_java_setContextClassLoader(env, cl); 295 296 cl = nxt_java_newURLClassLoader_parent(env, unit_jars_count, unit_jars, cl); 297 if (cl == NULL) { 298 nxt_alert(task, "nxt_java_newURLClassLoader_parent failed"); 299 goto env_failed; 300 } 301 302 nxt_java_setContextClassLoader(env, cl); 303 304 rc = nxt_java_initContext(env, cl); 305 if (rc != NXT_UNIT_OK) { 306 nxt_alert(task, "nxt_java_initContext() failed"); 307 goto env_failed; 308 } 309 310 rc = nxt_java_initRequest(env, cl); 311 if (rc != NXT_UNIT_OK) { 312 nxt_alert(task, "nxt_java_initRequest() failed"); 313 goto env_failed; 314 } 315 316 rc = nxt_java_initResponse(env, cl); 317 if (rc != NXT_UNIT_OK) { 318 nxt_alert(task, "nxt_java_initResponse() failed"); 319 goto env_failed; 320 } 321 322 rc = nxt_java_initInputStream(env, cl); 323 if (rc != NXT_UNIT_OK) { 324 nxt_alert(task, "nxt_java_initInputStream() failed"); 325 goto env_failed; 326 } 327 328 rc = nxt_java_initOutputStream(env, cl); 329 if (rc != NXT_UNIT_OK) { 330 nxt_alert(task, "nxt_java_initOutputStream() failed"); 331 goto env_failed; 332 } 333 334 nxt_java_jni_init(env); 335 if (rc != NXT_UNIT_OK) { 336 nxt_alert(task, "nxt_java_jni_init() failed"); 337 goto env_failed; 338 } 339 340 classpath = nxt_java_newURLs(env, classpath_count, classpath_arr); 341 if (classpath == NULL) { 342 nxt_alert(task, "nxt_java_newURLs failed"); 343 goto env_failed; 344 } 345 346 java_data.env = env; 347 java_data.ctx = nxt_java_startContext(env, c->webapp, classpath); 348 349 if ((*env)->ExceptionCheck(env)) { 350 nxt_alert(task, "Unhandled exception in application start"); 351 (*env)->ExceptionDescribe(env); 352 return NXT_ERROR; 353 } 354 355 nxt_unit_default_init(task, &java_init); 356 357 java_init.callbacks.request_handler = nxt_java_request_handler; 358 java_init.callbacks.websocket_handler = nxt_java_websocket_handler; 359 java_init.callbacks.close_handler = nxt_java_close_handler; 360 java_init.request_data_size = sizeof(nxt_java_request_data_t); 361 java_init.data = &java_data; 362 java_init.shm_limit = app_conf->shm_limit; 363 364 ctx = nxt_unit_init(&java_init); 365 if (nxt_slow_path(ctx == NULL)) { 366 nxt_alert(task, "nxt_unit_init() failed"); 367 return NXT_ERROR; 368 } 369 370 rc = nxt_unit_run(ctx); 371 if (nxt_slow_path(rc != NXT_UNIT_OK)) { 372 /* TODO report error */ 373 } 374 375 nxt_java_stopContext(env, java_data.ctx); 376 377 if ((*env)->ExceptionCheck(env)) { 378 (*env)->ExceptionDescribe(env); 379 } 380 381 nxt_unit_done(ctx); 382 383 (*jvm)->DestroyJavaVM(jvm); 384 385 exit(0); 386 387 return NXT_OK; 388 389env_failed: 390 391 if ((*env)->ExceptionCheck(env)) { 392 (*env)->ExceptionDescribe(env); 393 } 394 395 return NXT_ERROR; 396} 397 398 399static void 400nxt_java_request_handler(nxt_unit_request_info_t *req) 401{ 402 JNIEnv *env; 403 jobject jreq, jresp; 404 nxt_java_data_t *java_data; 405 nxt_java_request_data_t *data; 406 407 java_data = req->unit->data; 408 env = java_data->env; 409 data = req->data; 410 411 jreq = nxt_java_newRequest(env, java_data->ctx, req); 412 if (jreq == NULL) { 413 nxt_unit_req_alert(req, "failed to create Request instance"); 414 415 if ((*env)->ExceptionCheck(env)) { 416 (*env)->ExceptionDescribe(env); 417 (*env)->ExceptionClear(env); 418 } 419 420 nxt_unit_request_done(req, NXT_UNIT_ERROR); 421 return; 422 } 423 424 jresp = nxt_java_newResponse(env, req); 425 if (jresp == NULL) { 426 nxt_unit_req_alert(req, "failed to create Response instance"); 427 428 if ((*env)->ExceptionCheck(env)) { 429 (*env)->ExceptionDescribe(env); 430 (*env)->ExceptionClear(env); 431 } 432 433 (*env)->DeleteLocalRef(env, jreq); 434 435 nxt_unit_request_done(req, NXT_UNIT_ERROR); 436 return; 437 } 438 439 data->header_size = 10 * 1024; 440 data->buf_size = 32 * 1024; /* from Jetty */ 441 data->jreq = jreq; 442 data->jresp = jresp; 443 data->buf = NULL; 444 445 nxt_unit_request_group_dup_fields(req); 446 447 nxt_java_service(env, java_data->ctx, jreq, jresp); 448 449 if ((*env)->ExceptionCheck(env)) { 450 (*env)->ExceptionDescribe(env); 451 (*env)->ExceptionClear(env); 452 } 453 454 if (!nxt_unit_response_is_init(req)) { 455 nxt_unit_response_init(req, 200, 0, 0); 456 } 457 458 if (!nxt_unit_response_is_sent(req)) { 459 nxt_unit_response_send(req); 460 } 461 462 if (data->buf != NULL) { 463 nxt_unit_buf_send(data->buf); 464 465 data->buf = NULL; 466 } 467 468 if (nxt_unit_response_is_websocket(req)) { 469 data->jreq = (*env)->NewGlobalRef(env, jreq); 470 data->jresp = (*env)->NewGlobalRef(env, jresp); 471 472 } else { 473 nxt_unit_request_done(req, NXT_UNIT_OK); 474 } 475 476 (*env)->DeleteLocalRef(env, jresp); 477 (*env)->DeleteLocalRef(env, jreq); 478} 479 480 481static void 482nxt_java_websocket_handler(nxt_unit_websocket_frame_t *ws) 483{ 484 void *b; 485 JNIEnv *env; 486 jobject jbuf; 487 nxt_java_data_t *java_data; 488 nxt_java_request_data_t *data; 489 490 java_data = ws->req->unit->data; 491 env = java_data->env; 492 data = ws->req->data; 493 494 b = malloc(ws->payload_len); 495 if (b != NULL) { 496 nxt_unit_websocket_read(ws, b, ws->payload_len); 497 498 jbuf = (*env)->NewDirectByteBuffer(env, b, ws->payload_len); 499 if (jbuf != NULL) { 500 nxt_java_Request_websocket(env, data->jreq, jbuf, 501 ws->header->opcode, ws->header->fin); 502 503 if ((*env)->ExceptionCheck(env)) { 504 (*env)->ExceptionDescribe(env); 505 (*env)->ExceptionClear(env); 506 } 507 508 (*env)->DeleteLocalRef(env, jbuf); 509 } 510 511 free(b); 512 } 513 514 nxt_unit_websocket_done(ws); 515} 516 517 518static void 519nxt_java_close_handler(nxt_unit_request_info_t *req) 520{ 521 JNIEnv *env; 522 nxt_java_data_t *java_data; 523 nxt_java_request_data_t *data; 524 525 java_data = req->unit->data; 526 env = java_data->env; 527 data = req->data; 528 529 nxt_java_Request_close(env, data->jreq); 530 531 (*env)->DeleteGlobalRef(env, data->jresp); 532 (*env)->DeleteGlobalRef(env, data->jreq); 533 534 nxt_unit_request_done(req, NXT_UNIT_OK); 535} 536
| 169 jurl = nxt_cpymem(jurl, *jar, nxt_strlen(*jar)); 170 *jurl++ = '\0'; 171 } 172 173 return res; 174} 175 176 177static nxt_int_t 178nxt_java_start(nxt_task_t *task, nxt_process_data_t *data) 179{ 180 jint rc; 181 char *opt, *real_path; 182 char **classpath_arr, **unit_jars, **system_jars; 183 JavaVM *jvm; 184 JNIEnv *env; 185 jobject cl, classpath; 186 nxt_str_t str; 187 nxt_int_t opt_len, real_path_len; 188 nxt_uint_t i, unit_jars_count, classpath_count; 189 nxt_uint_t system_jars_count; 190 JavaVMOption *jvm_opt; 191 JavaVMInitArgs jvm_args; 192 nxt_unit_ctx_t *ctx; 193 nxt_unit_init_t java_init; 194 nxt_java_data_t java_data; 195 nxt_conf_value_t *value; 196 nxt_java_app_conf_t *c; 197 nxt_common_app_conf_t *app_conf; 198 199 //setenv("ASAN_OPTIONS", "handle_segv=0", 1); 200 201 jvm_args.version = JNI_VERSION_1_6; 202 jvm_args.nOptions = 0; 203 jvm_args.ignoreUnrecognized = 0; 204 205 app_conf = data->app; 206 c = &app_conf->u.java; 207 208 if (c->options != NULL) { 209 jvm_args.nOptions += nxt_conf_array_elements_count(c->options); 210 } 211 212 jvm_opt = nxt_malloc(jvm_args.nOptions * sizeof(JavaVMOption)); 213 if (jvm_opt == NULL) { 214 nxt_alert(task, "failed to allocate jvm_opt"); 215 return NXT_ERROR; 216 } 217 218 jvm_args.options = jvm_opt; 219 220 unit_jars_count = nxt_nitems(nxt_java_unit_jars) - 1; 221 222 unit_jars = nxt_java_module_jars(nxt_java_unit_jars, unit_jars_count); 223 if (unit_jars == NULL) { 224 nxt_alert(task, "failed to allocate buffer for unit_jars array"); 225 226 return NXT_ERROR; 227 } 228 229 system_jars_count = nxt_nitems(nxt_java_system_jars) - 1; 230 231 system_jars = nxt_java_module_jars(nxt_java_system_jars, system_jars_count); 232 if (system_jars == NULL) { 233 nxt_alert(task, "failed to allocate buffer for system_jars array"); 234 235 return NXT_ERROR; 236 } 237 238 if (c->options != NULL) { 239 240 for (i = 0; /* void */ ; i++) { 241 value = nxt_conf_get_array_element(c->options, i); 242 if (value == NULL) { 243 break; 244 } 245 246 nxt_conf_get_string(value, &str); 247 248 opt = nxt_malloc(str.length + 1); 249 if (opt == NULL) { 250 nxt_alert(task, "failed to allocate jvm_opt"); 251 return NXT_ERROR; 252 } 253 254 memcpy(opt, str.start, str.length); 255 opt[str.length] = '\0'; 256 257 jvm_opt[i].optionString = opt; 258 } 259 } 260 261 if (c->classpath != NULL) { 262 classpath_count = nxt_conf_array_elements_count(c->classpath); 263 classpath_arr = nxt_malloc(classpath_count * sizeof(char *)); 264 265 for (i = 0; /* void */ ; i++) { 266 value = nxt_conf_get_array_element(c->classpath, i); 267 if (value == NULL) { 268 break; 269 } 270 271 nxt_conf_get_string(value, &str); 272 273 opt_len = str.length + 1; 274 275 char *sc = memchr(str.start, ':', str.length); 276 if (sc == NULL && str.start[0] == '/') { 277 opt_len += nxt_length("file:"); 278 } 279 280 opt = nxt_malloc(opt_len); 281 if (opt == NULL) { 282 nxt_alert(task, "failed to allocate classpath"); 283 return NXT_ERROR; 284 } 285 286 if (sc == NULL && str.start[0] != '/') { 287 nxt_memcpy(opt, str.start, str.length); 288 opt[str.length] = '\0'; 289 290 real_path = realpath(opt, NULL); 291 if (real_path == NULL) { 292 nxt_alert(task, "realpath(%s) failed: %E", opt, nxt_errno); 293 return NXT_ERROR; 294 } 295 296 real_path_len = nxt_strlen(real_path); 297 298 free(opt); 299 300 opt_len = nxt_length("file:") + real_path_len + 1; 301 302 opt = nxt_malloc(opt_len); 303 if (opt == NULL) { 304 nxt_alert(task, "failed to allocate classpath"); 305 return NXT_ERROR; 306 } 307 308 } else { 309 real_path = (char *) str.start; /* I love this cast! */ 310 real_path_len = str.length; 311 } 312 313 classpath_arr[i] = opt; 314 315 if (sc == NULL) { 316 opt = nxt_cpymem(opt, "file:", nxt_length("file:")); 317 } 318 319 opt = nxt_cpymem(opt, real_path, real_path_len); 320 *opt = '\0'; 321 } 322 323 } else { 324 classpath_count = 0; 325 classpath_arr = NULL; 326 } 327 328 rc = JNI_CreateJavaVM(&jvm, (void **) &env, &jvm_args); 329 if (rc != JNI_OK) { 330 nxt_alert(task, "failed to create Java VM: %d", (int) rc); 331 return NXT_ERROR; 332 } 333 334 rc = nxt_java_initThread(env); 335 if (rc != NXT_UNIT_OK) { 336 nxt_alert(task, "nxt_java_initThread() failed"); 337 goto env_failed; 338 } 339 340 rc = nxt_java_initURLClassLoader(env); 341 if (rc != NXT_UNIT_OK) { 342 nxt_alert(task, "nxt_java_initURLClassLoader() failed"); 343 goto env_failed; 344 } 345 346 cl = nxt_java_newURLClassLoader(env, system_jars_count, system_jars); 347 if (cl == NULL) { 348 nxt_alert(task, "nxt_java_newURLClassLoader failed"); 349 goto env_failed; 350 } 351 352 nxt_java_setContextClassLoader(env, cl); 353 354 cl = nxt_java_newURLClassLoader_parent(env, unit_jars_count, unit_jars, cl); 355 if (cl == NULL) { 356 nxt_alert(task, "nxt_java_newURLClassLoader_parent failed"); 357 goto env_failed; 358 } 359 360 nxt_java_setContextClassLoader(env, cl); 361 362 rc = nxt_java_initContext(env, cl); 363 if (rc != NXT_UNIT_OK) { 364 nxt_alert(task, "nxt_java_initContext() failed"); 365 goto env_failed; 366 } 367 368 rc = nxt_java_initRequest(env, cl); 369 if (rc != NXT_UNIT_OK) { 370 nxt_alert(task, "nxt_java_initRequest() failed"); 371 goto env_failed; 372 } 373 374 rc = nxt_java_initResponse(env, cl); 375 if (rc != NXT_UNIT_OK) { 376 nxt_alert(task, "nxt_java_initResponse() failed"); 377 goto env_failed; 378 } 379 380 rc = nxt_java_initInputStream(env, cl); 381 if (rc != NXT_UNIT_OK) { 382 nxt_alert(task, "nxt_java_initInputStream() failed"); 383 goto env_failed; 384 } 385 386 rc = nxt_java_initOutputStream(env, cl); 387 if (rc != NXT_UNIT_OK) { 388 nxt_alert(task, "nxt_java_initOutputStream() failed"); 389 goto env_failed; 390 } 391 392 nxt_java_jni_init(env); 393 if (rc != NXT_UNIT_OK) { 394 nxt_alert(task, "nxt_java_jni_init() failed"); 395 goto env_failed; 396 } 397 398 classpath = nxt_java_newURLs(env, classpath_count, classpath_arr); 399 if (classpath == NULL) { 400 nxt_alert(task, "nxt_java_newURLs failed"); 401 goto env_failed; 402 } 403 404 java_data.env = env; 405 java_data.ctx = nxt_java_startContext(env, c->webapp, classpath); 406 407 if ((*env)->ExceptionCheck(env)) { 408 nxt_alert(task, "Unhandled exception in application start"); 409 (*env)->ExceptionDescribe(env); 410 return NXT_ERROR; 411 } 412 413 nxt_unit_default_init(task, &java_init); 414 415 java_init.callbacks.request_handler = nxt_java_request_handler; 416 java_init.callbacks.websocket_handler = nxt_java_websocket_handler; 417 java_init.callbacks.close_handler = nxt_java_close_handler; 418 java_init.request_data_size = sizeof(nxt_java_request_data_t); 419 java_init.data = &java_data; 420 java_init.shm_limit = app_conf->shm_limit; 421 422 ctx = nxt_unit_init(&java_init); 423 if (nxt_slow_path(ctx == NULL)) { 424 nxt_alert(task, "nxt_unit_init() failed"); 425 return NXT_ERROR; 426 } 427 428 rc = nxt_unit_run(ctx); 429 if (nxt_slow_path(rc != NXT_UNIT_OK)) { 430 /* TODO report error */ 431 } 432 433 nxt_java_stopContext(env, java_data.ctx); 434 435 if ((*env)->ExceptionCheck(env)) { 436 (*env)->ExceptionDescribe(env); 437 } 438 439 nxt_unit_done(ctx); 440 441 (*jvm)->DestroyJavaVM(jvm); 442 443 exit(0); 444 445 return NXT_OK; 446 447env_failed: 448 449 if ((*env)->ExceptionCheck(env)) { 450 (*env)->ExceptionDescribe(env); 451 } 452 453 return NXT_ERROR; 454} 455 456 457static void 458nxt_java_request_handler(nxt_unit_request_info_t *req) 459{ 460 JNIEnv *env; 461 jobject jreq, jresp; 462 nxt_java_data_t *java_data; 463 nxt_java_request_data_t *data; 464 465 java_data = req->unit->data; 466 env = java_data->env; 467 data = req->data; 468 469 jreq = nxt_java_newRequest(env, java_data->ctx, req); 470 if (jreq == NULL) { 471 nxt_unit_req_alert(req, "failed to create Request instance"); 472 473 if ((*env)->ExceptionCheck(env)) { 474 (*env)->ExceptionDescribe(env); 475 (*env)->ExceptionClear(env); 476 } 477 478 nxt_unit_request_done(req, NXT_UNIT_ERROR); 479 return; 480 } 481 482 jresp = nxt_java_newResponse(env, req); 483 if (jresp == NULL) { 484 nxt_unit_req_alert(req, "failed to create Response instance"); 485 486 if ((*env)->ExceptionCheck(env)) { 487 (*env)->ExceptionDescribe(env); 488 (*env)->ExceptionClear(env); 489 } 490 491 (*env)->DeleteLocalRef(env, jreq); 492 493 nxt_unit_request_done(req, NXT_UNIT_ERROR); 494 return; 495 } 496 497 data->header_size = 10 * 1024; 498 data->buf_size = 32 * 1024; /* from Jetty */ 499 data->jreq = jreq; 500 data->jresp = jresp; 501 data->buf = NULL; 502 503 nxt_unit_request_group_dup_fields(req); 504 505 nxt_java_service(env, java_data->ctx, jreq, jresp); 506 507 if ((*env)->ExceptionCheck(env)) { 508 (*env)->ExceptionDescribe(env); 509 (*env)->ExceptionClear(env); 510 } 511 512 if (!nxt_unit_response_is_init(req)) { 513 nxt_unit_response_init(req, 200, 0, 0); 514 } 515 516 if (!nxt_unit_response_is_sent(req)) { 517 nxt_unit_response_send(req); 518 } 519 520 if (data->buf != NULL) { 521 nxt_unit_buf_send(data->buf); 522 523 data->buf = NULL; 524 } 525 526 if (nxt_unit_response_is_websocket(req)) { 527 data->jreq = (*env)->NewGlobalRef(env, jreq); 528 data->jresp = (*env)->NewGlobalRef(env, jresp); 529 530 } else { 531 nxt_unit_request_done(req, NXT_UNIT_OK); 532 } 533 534 (*env)->DeleteLocalRef(env, jresp); 535 (*env)->DeleteLocalRef(env, jreq); 536} 537 538 539static void 540nxt_java_websocket_handler(nxt_unit_websocket_frame_t *ws) 541{ 542 void *b; 543 JNIEnv *env; 544 jobject jbuf; 545 nxt_java_data_t *java_data; 546 nxt_java_request_data_t *data; 547 548 java_data = ws->req->unit->data; 549 env = java_data->env; 550 data = ws->req->data; 551 552 b = malloc(ws->payload_len); 553 if (b != NULL) { 554 nxt_unit_websocket_read(ws, b, ws->payload_len); 555 556 jbuf = (*env)->NewDirectByteBuffer(env, b, ws->payload_len); 557 if (jbuf != NULL) { 558 nxt_java_Request_websocket(env, data->jreq, jbuf, 559 ws->header->opcode, ws->header->fin); 560 561 if ((*env)->ExceptionCheck(env)) { 562 (*env)->ExceptionDescribe(env); 563 (*env)->ExceptionClear(env); 564 } 565 566 (*env)->DeleteLocalRef(env, jbuf); 567 } 568 569 free(b); 570 } 571 572 nxt_unit_websocket_done(ws); 573} 574 575 576static void 577nxt_java_close_handler(nxt_unit_request_info_t *req) 578{ 579 JNIEnv *env; 580 nxt_java_data_t *java_data; 581 nxt_java_request_data_t *data; 582 583 java_data = req->unit->data; 584 env = java_data->env; 585 data = req->data; 586 587 nxt_java_Request_close(env, data->jreq); 588 589 (*env)->DeleteGlobalRef(env, data->jresp); 590 (*env)->DeleteGlobalRef(env, data->jreq); 591 592 nxt_unit_request_done(req, NXT_UNIT_OK); 593} 594
|