1*977Smax.romanov@gmail.com 2*977Smax.romanov@gmail.com /* 3*977Smax.romanov@gmail.com * Copyright (C) NGINX, Inc. 4*977Smax.romanov@gmail.com */ 5*977Smax.romanov@gmail.com 6*977Smax.romanov@gmail.com #include <nxt_auto_config.h> 7*977Smax.romanov@gmail.com 8*977Smax.romanov@gmail.com #include <nxt_unit.h> 9*977Smax.romanov@gmail.com #include <nxt_unit_response.h> 10*977Smax.romanov@gmail.com #include <jni.h> 11*977Smax.romanov@gmail.com #include <stdio.h> 12*977Smax.romanov@gmail.com 13*977Smax.romanov@gmail.com #include "nxt_jni.h" 14*977Smax.romanov@gmail.com #include "nxt_jni_Response.h" 15*977Smax.romanov@gmail.com #include "nxt_jni_HeadersEnumeration.h" 16*977Smax.romanov@gmail.com #include "nxt_jni_HeaderNamesEnumeration.h" 17*977Smax.romanov@gmail.com #include "nxt_jni_OutputStream.h" 18*977Smax.romanov@gmail.com #include "nxt_jni_URLClassLoader.h" 19*977Smax.romanov@gmail.com 20*977Smax.romanov@gmail.com 21*977Smax.romanov@gmail.com static jclass nxt_java_Response_class; 22*977Smax.romanov@gmail.com static jmethodID nxt_java_Response_ctor; 23*977Smax.romanov@gmail.com 24*977Smax.romanov@gmail.com 25*977Smax.romanov@gmail.com static void JNICALL nxt_java_Response_addHeader(JNIEnv *env, jclass cls, 26*977Smax.romanov@gmail.com jlong req_info_ptr, jarray name, jarray value); 27*977Smax.romanov@gmail.com 28*977Smax.romanov@gmail.com static nxt_unit_request_info_t *nxt_java_get_response_info( 29*977Smax.romanov@gmail.com jlong req_info_ptr, uint32_t extra_fields, uint32_t extra_data); 30*977Smax.romanov@gmail.com 31*977Smax.romanov@gmail.com static void JNICALL nxt_java_Response_addIntHeader(JNIEnv *env, jclass cls, 32*977Smax.romanov@gmail.com jlong req_info_ptr, jarray name, jint value); 33*977Smax.romanov@gmail.com 34*977Smax.romanov@gmail.com static void nxt_java_add_int_header(nxt_unit_request_info_t *req, 35*977Smax.romanov@gmail.com const char *name, uint8_t name_len, int value); 36*977Smax.romanov@gmail.com 37*977Smax.romanov@gmail.com static jboolean JNICALL nxt_java_Response_containsHeader(JNIEnv *env, 38*977Smax.romanov@gmail.com jclass cls, jlong req_info_ptr, jarray name); 39*977Smax.romanov@gmail.com 40*977Smax.romanov@gmail.com static jstring JNICALL nxt_java_Response_getHeader(JNIEnv *env, jclass cls, 41*977Smax.romanov@gmail.com jlong req_info_ptr, jarray name); 42*977Smax.romanov@gmail.com 43*977Smax.romanov@gmail.com static jobject JNICALL nxt_java_Response_getHeaderNames(JNIEnv *env, 44*977Smax.romanov@gmail.com jclass cls, jlong req_info_ptr); 45*977Smax.romanov@gmail.com 46*977Smax.romanov@gmail.com static jobject JNICALL nxt_java_Response_getHeaders(JNIEnv *env, jclass cls, 47*977Smax.romanov@gmail.com jlong req_info_ptr, jarray name); 48*977Smax.romanov@gmail.com 49*977Smax.romanov@gmail.com static jint JNICALL nxt_java_Response_getStatus(JNIEnv *env, jclass cls, 50*977Smax.romanov@gmail.com jlong req_info_ptr); 51*977Smax.romanov@gmail.com 52*977Smax.romanov@gmail.com static jobject JNICALL nxt_java_Response_getRequest(JNIEnv *env, jclass cls, 53*977Smax.romanov@gmail.com jlong req_info_ptr); 54*977Smax.romanov@gmail.com 55*977Smax.romanov@gmail.com static void JNICALL nxt_java_Response_commit(JNIEnv *env, jclass cls, 56*977Smax.romanov@gmail.com jlong req_info_ptr); 57*977Smax.romanov@gmail.com 58*977Smax.romanov@gmail.com static void JNICALL nxt_java_Response_sendRedirect(JNIEnv *env, jclass cls, 59*977Smax.romanov@gmail.com jlong req_info_ptr, jarray loc); 60*977Smax.romanov@gmail.com 61*977Smax.romanov@gmail.com static int nxt_java_response_set_header(jlong req_info_ptr, 62*977Smax.romanov@gmail.com const char *name, jint name_len, const char *value, jint value_len); 63*977Smax.romanov@gmail.com 64*977Smax.romanov@gmail.com static void JNICALL nxt_java_Response_setHeader(JNIEnv *env, jclass cls, 65*977Smax.romanov@gmail.com jlong req_info_ptr, jarray name, jarray value); 66*977Smax.romanov@gmail.com 67*977Smax.romanov@gmail.com static void JNICALL nxt_java_Response_removeHeader(JNIEnv *env, jclass cls, 68*977Smax.romanov@gmail.com jlong req_info_ptr, jarray name); 69*977Smax.romanov@gmail.com 70*977Smax.romanov@gmail.com static int nxt_java_response_remove_header(jlong req_info_ptr, 71*977Smax.romanov@gmail.com const char *name, jint name_len); 72*977Smax.romanov@gmail.com 73*977Smax.romanov@gmail.com static void JNICALL nxt_java_Response_setIntHeader(JNIEnv *env, jclass cls, 74*977Smax.romanov@gmail.com jlong req_info_ptr, jarray name, jint value); 75*977Smax.romanov@gmail.com 76*977Smax.romanov@gmail.com static void JNICALL nxt_java_Response_setStatus(JNIEnv *env, jclass cls, 77*977Smax.romanov@gmail.com jlong req_info_ptr, jint sc); 78*977Smax.romanov@gmail.com 79*977Smax.romanov@gmail.com static jstring JNICALL nxt_java_Response_getContentType(JNIEnv *env, 80*977Smax.romanov@gmail.com jclass cls, jlong req_info_ptr); 81*977Smax.romanov@gmail.com 82*977Smax.romanov@gmail.com static jboolean JNICALL nxt_java_Response_isCommitted(JNIEnv *env, jclass cls, 83*977Smax.romanov@gmail.com jlong req_info_ptr); 84*977Smax.romanov@gmail.com 85*977Smax.romanov@gmail.com static void JNICALL nxt_java_Response_reset(JNIEnv *env, jclass cls, 86*977Smax.romanov@gmail.com jlong req_info_ptr); 87*977Smax.romanov@gmail.com 88*977Smax.romanov@gmail.com static void JNICALL nxt_java_Response_resetBuffer(JNIEnv *env, jclass cls, 89*977Smax.romanov@gmail.com jlong req_info_ptr); 90*977Smax.romanov@gmail.com 91*977Smax.romanov@gmail.com static void JNICALL nxt_java_Response_setBufferSize(JNIEnv *env, jclass cls, 92*977Smax.romanov@gmail.com jlong req_info_ptr, jint size); 93*977Smax.romanov@gmail.com 94*977Smax.romanov@gmail.com static jint JNICALL nxt_java_Response_getBufferSize(JNIEnv *env, jclass cls, 95*977Smax.romanov@gmail.com jlong req_info_ptr); 96*977Smax.romanov@gmail.com 97*977Smax.romanov@gmail.com static void JNICALL nxt_java_Response_setContentLength(JNIEnv *env, jclass cls, 98*977Smax.romanov@gmail.com jlong req_info_ptr, jlong len); 99*977Smax.romanov@gmail.com 100*977Smax.romanov@gmail.com static void JNICALL nxt_java_Response_setContentType(JNIEnv *env, jclass cls, 101*977Smax.romanov@gmail.com jlong req_info_ptr, jarray type); 102*977Smax.romanov@gmail.com 103*977Smax.romanov@gmail.com static void JNICALL nxt_java_Response_removeContentType(JNIEnv *env, jclass cls, 104*977Smax.romanov@gmail.com jlong req_info_ptr); 105*977Smax.romanov@gmail.com 106*977Smax.romanov@gmail.com static void JNICALL nxt_java_Response_log(JNIEnv *env, jclass cls, 107*977Smax.romanov@gmail.com jlong req_info_ptr, jarray msg); 108*977Smax.romanov@gmail.com 109*977Smax.romanov@gmail.com static void JNICALL nxt_java_Response_trace(JNIEnv *env, jclass cls, 110*977Smax.romanov@gmail.com jlong req_info_ptr, jarray msg); 111*977Smax.romanov@gmail.com 112*977Smax.romanov@gmail.com int 113*977Smax.romanov@gmail.com nxt_java_initResponse(JNIEnv *env, jobject cl) 114*977Smax.romanov@gmail.com { 115*977Smax.romanov@gmail.com int res; 116*977Smax.romanov@gmail.com jclass cls; 117*977Smax.romanov@gmail.com 118*977Smax.romanov@gmail.com cls = nxt_java_loadClass(env, cl, "nginx.unit.Response"); 119*977Smax.romanov@gmail.com if (cls == NULL) { 120*977Smax.romanov@gmail.com return NXT_UNIT_ERROR; 121*977Smax.romanov@gmail.com } 122*977Smax.romanov@gmail.com 123*977Smax.romanov@gmail.com nxt_java_Response_class = (*env)->NewGlobalRef(env, cls); 124*977Smax.romanov@gmail.com (*env)->DeleteLocalRef(env, cls); 125*977Smax.romanov@gmail.com cls = nxt_java_Response_class; 126*977Smax.romanov@gmail.com 127*977Smax.romanov@gmail.com nxt_java_Response_ctor = (*env)->GetMethodID(env, cls, "<init>", "(J)V"); 128*977Smax.romanov@gmail.com if (nxt_java_Response_ctor == NULL) { 129*977Smax.romanov@gmail.com (*env)->DeleteGlobalRef(env, cls); 130*977Smax.romanov@gmail.com return NXT_UNIT_ERROR; 131*977Smax.romanov@gmail.com } 132*977Smax.romanov@gmail.com 133*977Smax.romanov@gmail.com JNINativeMethod resp_methods[] = { 134*977Smax.romanov@gmail.com { (char *) "addHeader", 135*977Smax.romanov@gmail.com (char *) "(J[B[B)V", 136*977Smax.romanov@gmail.com nxt_java_Response_addHeader }, 137*977Smax.romanov@gmail.com 138*977Smax.romanov@gmail.com { (char *) "addIntHeader", 139*977Smax.romanov@gmail.com (char *) "(J[BI)V", 140*977Smax.romanov@gmail.com nxt_java_Response_addIntHeader }, 141*977Smax.romanov@gmail.com 142*977Smax.romanov@gmail.com { (char *) "containsHeader", 143*977Smax.romanov@gmail.com (char *) "(J[B)Z", 144*977Smax.romanov@gmail.com nxt_java_Response_containsHeader }, 145*977Smax.romanov@gmail.com 146*977Smax.romanov@gmail.com { (char *) "getHeader", 147*977Smax.romanov@gmail.com (char *) "(J[B)Ljava/lang/String;", 148*977Smax.romanov@gmail.com nxt_java_Response_getHeader }, 149*977Smax.romanov@gmail.com 150*977Smax.romanov@gmail.com { (char *) "getHeaderNames", 151*977Smax.romanov@gmail.com (char *) "(J)Ljava/util/Enumeration;", 152*977Smax.romanov@gmail.com nxt_java_Response_getHeaderNames }, 153*977Smax.romanov@gmail.com 154*977Smax.romanov@gmail.com { (char *) "getHeaders", 155*977Smax.romanov@gmail.com (char *) "(J[B)Ljava/util/Enumeration;", 156*977Smax.romanov@gmail.com nxt_java_Response_getHeaders }, 157*977Smax.romanov@gmail.com 158*977Smax.romanov@gmail.com { (char *) "getStatus", 159*977Smax.romanov@gmail.com (char *) "(J)I", 160*977Smax.romanov@gmail.com nxt_java_Response_getStatus }, 161*977Smax.romanov@gmail.com 162*977Smax.romanov@gmail.com { (char *) "getRequest", 163*977Smax.romanov@gmail.com (char *) "(J)Lnginx/unit/Request;", 164*977Smax.romanov@gmail.com nxt_java_Response_getRequest }, 165*977Smax.romanov@gmail.com 166*977Smax.romanov@gmail.com { (char *) "commit", 167*977Smax.romanov@gmail.com (char *) "(J)V", 168*977Smax.romanov@gmail.com nxt_java_Response_commit }, 169*977Smax.romanov@gmail.com 170*977Smax.romanov@gmail.com { (char *) "sendRedirect", 171*977Smax.romanov@gmail.com (char *) "(J[B)V", 172*977Smax.romanov@gmail.com nxt_java_Response_sendRedirect }, 173*977Smax.romanov@gmail.com 174*977Smax.romanov@gmail.com { (char *) "setHeader", 175*977Smax.romanov@gmail.com (char *) "(J[B[B)V", 176*977Smax.romanov@gmail.com nxt_java_Response_setHeader }, 177*977Smax.romanov@gmail.com 178*977Smax.romanov@gmail.com { (char *) "removeHeader", 179*977Smax.romanov@gmail.com (char *) "(J[B)V", 180*977Smax.romanov@gmail.com nxt_java_Response_removeHeader }, 181*977Smax.romanov@gmail.com 182*977Smax.romanov@gmail.com { (char *) "setIntHeader", 183*977Smax.romanov@gmail.com (char *) "(J[BI)V", 184*977Smax.romanov@gmail.com nxt_java_Response_setIntHeader }, 185*977Smax.romanov@gmail.com 186*977Smax.romanov@gmail.com { (char *) "setStatus", 187*977Smax.romanov@gmail.com (char *) "(JI)V", 188*977Smax.romanov@gmail.com nxt_java_Response_setStatus }, 189*977Smax.romanov@gmail.com 190*977Smax.romanov@gmail.com { (char *) "getContentType", 191*977Smax.romanov@gmail.com (char *) "(J)Ljava/lang/String;", 192*977Smax.romanov@gmail.com nxt_java_Response_getContentType }, 193*977Smax.romanov@gmail.com 194*977Smax.romanov@gmail.com { (char *) "isCommitted", 195*977Smax.romanov@gmail.com (char *) "(J)Z", 196*977Smax.romanov@gmail.com nxt_java_Response_isCommitted }, 197*977Smax.romanov@gmail.com 198*977Smax.romanov@gmail.com { (char *) "reset", 199*977Smax.romanov@gmail.com (char *) "(J)V", 200*977Smax.romanov@gmail.com nxt_java_Response_reset }, 201*977Smax.romanov@gmail.com 202*977Smax.romanov@gmail.com { (char *) "resetBuffer", 203*977Smax.romanov@gmail.com (char *) "(J)V", 204*977Smax.romanov@gmail.com nxt_java_Response_resetBuffer }, 205*977Smax.romanov@gmail.com 206*977Smax.romanov@gmail.com { (char *) "setBufferSize", 207*977Smax.romanov@gmail.com (char *) "(JI)V", 208*977Smax.romanov@gmail.com nxt_java_Response_setBufferSize }, 209*977Smax.romanov@gmail.com 210*977Smax.romanov@gmail.com { (char *) "getBufferSize", 211*977Smax.romanov@gmail.com (char *) "(J)I", 212*977Smax.romanov@gmail.com nxt_java_Response_getBufferSize }, 213*977Smax.romanov@gmail.com 214*977Smax.romanov@gmail.com { (char *) "setContentLength", 215*977Smax.romanov@gmail.com (char *) "(JJ)V", 216*977Smax.romanov@gmail.com nxt_java_Response_setContentLength }, 217*977Smax.romanov@gmail.com 218*977Smax.romanov@gmail.com { (char *) "setContentType", 219*977Smax.romanov@gmail.com (char *) "(J[B)V", 220*977Smax.romanov@gmail.com nxt_java_Response_setContentType }, 221*977Smax.romanov@gmail.com 222*977Smax.romanov@gmail.com { (char *) "removeContentType", 223*977Smax.romanov@gmail.com (char *) "(J)V", 224*977Smax.romanov@gmail.com nxt_java_Response_removeContentType }, 225*977Smax.romanov@gmail.com 226*977Smax.romanov@gmail.com { (char *) "log", 227*977Smax.romanov@gmail.com (char *) "(J[B)V", 228*977Smax.romanov@gmail.com nxt_java_Response_log }, 229*977Smax.romanov@gmail.com 230*977Smax.romanov@gmail.com { (char *) "trace", 231*977Smax.romanov@gmail.com (char *) "(J[B)V", 232*977Smax.romanov@gmail.com nxt_java_Response_trace }, 233*977Smax.romanov@gmail.com 234*977Smax.romanov@gmail.com }; 235*977Smax.romanov@gmail.com 236*977Smax.romanov@gmail.com res = (*env)->RegisterNatives(env, nxt_java_Response_class, 237*977Smax.romanov@gmail.com resp_methods, 238*977Smax.romanov@gmail.com sizeof(resp_methods) 239*977Smax.romanov@gmail.com / sizeof(resp_methods[0])); 240*977Smax.romanov@gmail.com 241*977Smax.romanov@gmail.com nxt_unit_debug(NULL, "registered Response methods: %d", res); 242*977Smax.romanov@gmail.com 243*977Smax.romanov@gmail.com if (res != 0) { 244*977Smax.romanov@gmail.com (*env)->DeleteGlobalRef(env, cls); 245*977Smax.romanov@gmail.com return NXT_UNIT_ERROR; 246*977Smax.romanov@gmail.com } 247*977Smax.romanov@gmail.com 248*977Smax.romanov@gmail.com return NXT_UNIT_OK; 249*977Smax.romanov@gmail.com } 250*977Smax.romanov@gmail.com 251*977Smax.romanov@gmail.com 252*977Smax.romanov@gmail.com jobject 253*977Smax.romanov@gmail.com nxt_java_newResponse(JNIEnv *env, nxt_unit_request_info_t *req) 254*977Smax.romanov@gmail.com { 255*977Smax.romanov@gmail.com return (*env)->NewObject(env, nxt_java_Response_class, 256*977Smax.romanov@gmail.com nxt_java_Response_ctor, nxt_ptr2jlong(req)); 257*977Smax.romanov@gmail.com } 258*977Smax.romanov@gmail.com 259*977Smax.romanov@gmail.com 260*977Smax.romanov@gmail.com static void JNICALL 261*977Smax.romanov@gmail.com nxt_java_Response_addHeader(JNIEnv *env, jclass cls, jlong req_info_ptr, 262*977Smax.romanov@gmail.com jarray name, jarray value) 263*977Smax.romanov@gmail.com { 264*977Smax.romanov@gmail.com int rc; 265*977Smax.romanov@gmail.com char *name_str, *value_str; 266*977Smax.romanov@gmail.com jsize name_len, value_len; 267*977Smax.romanov@gmail.com nxt_unit_request_info_t *req; 268*977Smax.romanov@gmail.com 269*977Smax.romanov@gmail.com name_len = (*env)->GetArrayLength(env, name); 270*977Smax.romanov@gmail.com value_len = (*env)->GetArrayLength(env, value); 271*977Smax.romanov@gmail.com 272*977Smax.romanov@gmail.com req = nxt_java_get_response_info(req_info_ptr, 1, name_len + value_len + 2); 273*977Smax.romanov@gmail.com if (req == NULL) { 274*977Smax.romanov@gmail.com return; 275*977Smax.romanov@gmail.com } 276*977Smax.romanov@gmail.com 277*977Smax.romanov@gmail.com name_str = (*env)->GetPrimitiveArrayCritical(env, name, NULL); 278*977Smax.romanov@gmail.com if (name_str == NULL) { 279*977Smax.romanov@gmail.com nxt_unit_req_warn(req, "addHeader: failed to get name content"); 280*977Smax.romanov@gmail.com return; 281*977Smax.romanov@gmail.com } 282*977Smax.romanov@gmail.com 283*977Smax.romanov@gmail.com value_str = (*env)->GetPrimitiveArrayCritical(env, value, NULL); 284*977Smax.romanov@gmail.com if (value_str == NULL) { 285*977Smax.romanov@gmail.com (*env)->ReleasePrimitiveArrayCritical(env, name, name_str, 0); 286*977Smax.romanov@gmail.com nxt_unit_req_warn(req, "addHeader: failed to get value content"); 287*977Smax.romanov@gmail.com 288*977Smax.romanov@gmail.com return; 289*977Smax.romanov@gmail.com } 290*977Smax.romanov@gmail.com 291*977Smax.romanov@gmail.com rc = nxt_unit_response_add_field(req, name_str, name_len, 292*977Smax.romanov@gmail.com value_str, value_len); 293*977Smax.romanov@gmail.com if (rc != NXT_UNIT_OK) { 294*977Smax.romanov@gmail.com // throw 295*977Smax.romanov@gmail.com } 296*977Smax.romanov@gmail.com 297*977Smax.romanov@gmail.com (*env)->ReleasePrimitiveArrayCritical(env, value, value_str, 0); 298*977Smax.romanov@gmail.com (*env)->ReleasePrimitiveArrayCritical(env, name, name_str, 0); 299*977Smax.romanov@gmail.com } 300*977Smax.romanov@gmail.com 301*977Smax.romanov@gmail.com 302*977Smax.romanov@gmail.com static nxt_unit_request_info_t * 303*977Smax.romanov@gmail.com nxt_java_get_response_info(jlong req_info_ptr, uint32_t extra_fields, 304*977Smax.romanov@gmail.com uint32_t extra_data) 305*977Smax.romanov@gmail.com { 306*977Smax.romanov@gmail.com int rc; 307*977Smax.romanov@gmail.com char *p; 308*977Smax.romanov@gmail.com uint32_t max_size; 309*977Smax.romanov@gmail.com nxt_unit_buf_t *buf; 310*977Smax.romanov@gmail.com nxt_unit_request_info_t *req; 311*977Smax.romanov@gmail.com nxt_java_request_data_t *data; 312*977Smax.romanov@gmail.com 313*977Smax.romanov@gmail.com req = nxt_jlong2ptr(req_info_ptr); 314*977Smax.romanov@gmail.com 315*977Smax.romanov@gmail.com if (nxt_unit_response_is_sent(req)) { 316*977Smax.romanov@gmail.com return NULL; 317*977Smax.romanov@gmail.com } 318*977Smax.romanov@gmail.com 319*977Smax.romanov@gmail.com data = req->data; 320*977Smax.romanov@gmail.com 321*977Smax.romanov@gmail.com if (!nxt_unit_response_is_init(req)) { 322*977Smax.romanov@gmail.com max_size = nxt_unit_buf_max(); 323*977Smax.romanov@gmail.com max_size = max_size < data->header_size ? max_size : data->header_size; 324*977Smax.romanov@gmail.com 325*977Smax.romanov@gmail.com rc = nxt_unit_response_init(req, 200, 16, max_size); 326*977Smax.romanov@gmail.com if (rc != NXT_UNIT_OK) { 327*977Smax.romanov@gmail.com return NULL; 328*977Smax.romanov@gmail.com } 329*977Smax.romanov@gmail.com } 330*977Smax.romanov@gmail.com 331*977Smax.romanov@gmail.com buf = req->response_buf; 332*977Smax.romanov@gmail.com 333*977Smax.romanov@gmail.com if (extra_fields > req->response_max_fields 334*977Smax.romanov@gmail.com - req->response->fields_count 335*977Smax.romanov@gmail.com || extra_data > (uint32_t) (buf->end - buf->free)) 336*977Smax.romanov@gmail.com { 337*977Smax.romanov@gmail.com p = buf->start + req->response_max_fields * sizeof(nxt_unit_field_t); 338*977Smax.romanov@gmail.com 339*977Smax.romanov@gmail.com max_size = 2 * (buf->end - p); 340*977Smax.romanov@gmail.com if (max_size > nxt_unit_buf_max()) { 341*977Smax.romanov@gmail.com nxt_unit_req_warn(req, "required max_size is too big: %"PRIu32, 342*977Smax.romanov@gmail.com max_size); 343*977Smax.romanov@gmail.com return NULL; 344*977Smax.romanov@gmail.com } 345*977Smax.romanov@gmail.com 346*977Smax.romanov@gmail.com rc = nxt_unit_response_realloc(req, 2 * req->response_max_fields, 347*977Smax.romanov@gmail.com max_size); 348*977Smax.romanov@gmail.com if (rc != NXT_UNIT_OK) { 349*977Smax.romanov@gmail.com nxt_unit_req_warn(req, "reallocation failed: %"PRIu32", %"PRIu32, 350*977Smax.romanov@gmail.com 2 * req->response_max_fields, max_size); 351*977Smax.romanov@gmail.com return NULL; 352*977Smax.romanov@gmail.com } 353*977Smax.romanov@gmail.com } 354*977Smax.romanov@gmail.com 355*977Smax.romanov@gmail.com return req; 356*977Smax.romanov@gmail.com } 357*977Smax.romanov@gmail.com 358*977Smax.romanov@gmail.com 359*977Smax.romanov@gmail.com static void JNICALL 360*977Smax.romanov@gmail.com nxt_java_Response_addIntHeader(JNIEnv *env, jclass cls, jlong req_info_ptr, 361*977Smax.romanov@gmail.com jarray name, jint value) 362*977Smax.romanov@gmail.com { 363*977Smax.romanov@gmail.com char *name_str; 364*977Smax.romanov@gmail.com jsize name_len; 365*977Smax.romanov@gmail.com nxt_unit_request_info_t *req; 366*977Smax.romanov@gmail.com 367*977Smax.romanov@gmail.com name_len = (*env)->GetArrayLength(env, name); 368*977Smax.romanov@gmail.com 369*977Smax.romanov@gmail.com req = nxt_java_get_response_info(req_info_ptr, 1, name_len + 40); 370*977Smax.romanov@gmail.com if (req == NULL) { 371*977Smax.romanov@gmail.com return; 372*977Smax.romanov@gmail.com } 373*977Smax.romanov@gmail.com 374*977Smax.romanov@gmail.com name_str = (*env)->GetPrimitiveArrayCritical(env, name, NULL); 375*977Smax.romanov@gmail.com if (name_str == NULL) { 376*977Smax.romanov@gmail.com nxt_unit_req_warn(req, "addIntHeader: failed to get name content"); 377*977Smax.romanov@gmail.com return; 378*977Smax.romanov@gmail.com } 379*977Smax.romanov@gmail.com 380*977Smax.romanov@gmail.com nxt_java_add_int_header(req, name_str, name_len, value); 381*977Smax.romanov@gmail.com 382*977Smax.romanov@gmail.com (*env)->ReleasePrimitiveArrayCritical(env, name, name_str, 0); 383*977Smax.romanov@gmail.com } 384*977Smax.romanov@gmail.com 385*977Smax.romanov@gmail.com 386*977Smax.romanov@gmail.com static void 387*977Smax.romanov@gmail.com nxt_java_add_int_header(nxt_unit_request_info_t *req, const char *name, 388*977Smax.romanov@gmail.com uint8_t name_len, int value) 389*977Smax.romanov@gmail.com { 390*977Smax.romanov@gmail.com char *p; 391*977Smax.romanov@gmail.com nxt_unit_field_t *f; 392*977Smax.romanov@gmail.com nxt_unit_response_t *resp; 393*977Smax.romanov@gmail.com 394*977Smax.romanov@gmail.com resp = req->response; 395*977Smax.romanov@gmail.com 396*977Smax.romanov@gmail.com f = resp->fields + resp->fields_count; 397*977Smax.romanov@gmail.com p = req->response_buf->free; 398*977Smax.romanov@gmail.com 399*977Smax.romanov@gmail.com f->hash = nxt_unit_field_hash(name, name_len); 400*977Smax.romanov@gmail.com f->skip = 0; 401*977Smax.romanov@gmail.com f->name_length = name_len; 402*977Smax.romanov@gmail.com 403*977Smax.romanov@gmail.com nxt_unit_sptr_set(&f->name, p); 404*977Smax.romanov@gmail.com memcpy(p, name, name_len); 405*977Smax.romanov@gmail.com p += name_len; 406*977Smax.romanov@gmail.com 407*977Smax.romanov@gmail.com nxt_unit_sptr_set(&f->value, p); 408*977Smax.romanov@gmail.com f->value_length = snprintf(p, 40, "%d", (int) value); 409*977Smax.romanov@gmail.com p += f->value_length + 1; 410*977Smax.romanov@gmail.com 411*977Smax.romanov@gmail.com resp->fields_count++; 412*977Smax.romanov@gmail.com req->response_buf->free = p; 413*977Smax.romanov@gmail.com 414*977Smax.romanov@gmail.com } 415*977Smax.romanov@gmail.com 416*977Smax.romanov@gmail.com 417*977Smax.romanov@gmail.com static jboolean JNICALL 418*977Smax.romanov@gmail.com nxt_java_Response_containsHeader(JNIEnv *env, 419*977Smax.romanov@gmail.com jclass cls, jlong req_info_ptr, jarray name) 420*977Smax.romanov@gmail.com { 421*977Smax.romanov@gmail.com jboolean res; 422*977Smax.romanov@gmail.com char *name_str; 423*977Smax.romanov@gmail.com jsize name_len; 424*977Smax.romanov@gmail.com nxt_unit_response_t *resp; 425*977Smax.romanov@gmail.com nxt_unit_request_info_t *req; 426*977Smax.romanov@gmail.com 427*977Smax.romanov@gmail.com req = nxt_jlong2ptr(req_info_ptr); 428*977Smax.romanov@gmail.com 429*977Smax.romanov@gmail.com if (!nxt_unit_response_is_init(req)) { 430*977Smax.romanov@gmail.com nxt_unit_req_debug(req, "containsHeader: response is not initialized"); 431*977Smax.romanov@gmail.com return 0; 432*977Smax.romanov@gmail.com } 433*977Smax.romanov@gmail.com 434*977Smax.romanov@gmail.com if (nxt_unit_response_is_sent(req)) { 435*977Smax.romanov@gmail.com nxt_unit_req_debug(req, "containsHeader: response already sent"); 436*977Smax.romanov@gmail.com return 0; 437*977Smax.romanov@gmail.com } 438*977Smax.romanov@gmail.com 439*977Smax.romanov@gmail.com name_len = (*env)->GetArrayLength(env, name); 440*977Smax.romanov@gmail.com 441*977Smax.romanov@gmail.com name_str = (*env)->GetPrimitiveArrayCritical(env, name, NULL); 442*977Smax.romanov@gmail.com if (name_str == NULL) { 443*977Smax.romanov@gmail.com nxt_unit_req_warn(req, "containsHeader: failed to get name content"); 444*977Smax.romanov@gmail.com return 0; 445*977Smax.romanov@gmail.com } 446*977Smax.romanov@gmail.com 447*977Smax.romanov@gmail.com resp = req->response; 448*977Smax.romanov@gmail.com 449*977Smax.romanov@gmail.com res = nxt_java_findHeader(resp->fields, 450*977Smax.romanov@gmail.com resp->fields + resp->fields_count, 451*977Smax.romanov@gmail.com name_str, name_len) != NULL; 452*977Smax.romanov@gmail.com 453*977Smax.romanov@gmail.com (*env)->ReleasePrimitiveArrayCritical(env, name, name_str, 0); 454*977Smax.romanov@gmail.com 455*977Smax.romanov@gmail.com return res; 456*977Smax.romanov@gmail.com } 457*977Smax.romanov@gmail.com 458*977Smax.romanov@gmail.com 459*977Smax.romanov@gmail.com static jstring JNICALL 460*977Smax.romanov@gmail.com nxt_java_Response_getHeader(JNIEnv *env, jclass cls, jlong req_info_ptr, 461*977Smax.romanov@gmail.com jarray name) 462*977Smax.romanov@gmail.com { 463*977Smax.romanov@gmail.com char *name_str; 464*977Smax.romanov@gmail.com jsize name_len; 465*977Smax.romanov@gmail.com nxt_unit_field_t *f; 466*977Smax.romanov@gmail.com nxt_unit_request_info_t *req; 467*977Smax.romanov@gmail.com 468*977Smax.romanov@gmail.com req = nxt_jlong2ptr(req_info_ptr); 469*977Smax.romanov@gmail.com 470*977Smax.romanov@gmail.com if (!nxt_unit_response_is_init(req)) { 471*977Smax.romanov@gmail.com nxt_unit_req_debug(req, "getHeader: response is not initialized"); 472*977Smax.romanov@gmail.com return NULL; 473*977Smax.romanov@gmail.com } 474*977Smax.romanov@gmail.com 475*977Smax.romanov@gmail.com if (nxt_unit_response_is_sent(req)) { 476*977Smax.romanov@gmail.com nxt_unit_req_debug(req, "getHeader: response already sent"); 477*977Smax.romanov@gmail.com return NULL; 478*977Smax.romanov@gmail.com } 479*977Smax.romanov@gmail.com 480*977Smax.romanov@gmail.com name_len = (*env)->GetArrayLength(env, name); 481*977Smax.romanov@gmail.com 482*977Smax.romanov@gmail.com name_str = (*env)->GetPrimitiveArrayCritical(env, name, NULL); 483*977Smax.romanov@gmail.com if (name_str == NULL) { 484*977Smax.romanov@gmail.com nxt_unit_req_warn(req, "getHeader: failed to get name content"); 485*977Smax.romanov@gmail.com return NULL; 486*977Smax.romanov@gmail.com } 487*977Smax.romanov@gmail.com 488*977Smax.romanov@gmail.com f = nxt_java_findHeader(req->response->fields, 489*977Smax.romanov@gmail.com req->response->fields + req->response->fields_count, 490*977Smax.romanov@gmail.com name_str, name_len); 491*977Smax.romanov@gmail.com 492*977Smax.romanov@gmail.com (*env)->ReleasePrimitiveArrayCritical(env, name, name_str, 0); 493*977Smax.romanov@gmail.com 494*977Smax.romanov@gmail.com if (f == NULL) { 495*977Smax.romanov@gmail.com return NULL; 496*977Smax.romanov@gmail.com } 497*977Smax.romanov@gmail.com 498*977Smax.romanov@gmail.com return nxt_java_newString(env, nxt_unit_sptr_get(&f->value), 499*977Smax.romanov@gmail.com f->value_length); 500*977Smax.romanov@gmail.com } 501*977Smax.romanov@gmail.com 502*977Smax.romanov@gmail.com 503*977Smax.romanov@gmail.com static jobject JNICALL 504*977Smax.romanov@gmail.com nxt_java_Response_getHeaderNames(JNIEnv *env, jclass cls, jlong req_info_ptr) 505*977Smax.romanov@gmail.com { 506*977Smax.romanov@gmail.com nxt_unit_request_info_t *req; 507*977Smax.romanov@gmail.com 508*977Smax.romanov@gmail.com req = nxt_jlong2ptr(req_info_ptr); 509*977Smax.romanov@gmail.com 510*977Smax.romanov@gmail.com if (!nxt_unit_response_is_init(req)) { 511*977Smax.romanov@gmail.com nxt_unit_req_debug(req, "getHeaderNames: response is not initialized"); 512*977Smax.romanov@gmail.com return NULL; 513*977Smax.romanov@gmail.com } 514*977Smax.romanov@gmail.com 515*977Smax.romanov@gmail.com if (nxt_unit_response_is_sent(req)) { 516*977Smax.romanov@gmail.com nxt_unit_req_debug(req, "getHeaderNames: response already sent"); 517*977Smax.romanov@gmail.com return NULL; 518*977Smax.romanov@gmail.com } 519*977Smax.romanov@gmail.com 520*977Smax.romanov@gmail.com return nxt_java_newHeaderNamesEnumeration(env, req->response->fields, 521*977Smax.romanov@gmail.com req->response->fields_count); 522*977Smax.romanov@gmail.com } 523*977Smax.romanov@gmail.com 524*977Smax.romanov@gmail.com 525*977Smax.romanov@gmail.com static jobject JNICALL 526*977Smax.romanov@gmail.com nxt_java_Response_getHeaders(JNIEnv *env, jclass cls, 527*977Smax.romanov@gmail.com jlong req_info_ptr, jarray name) 528*977Smax.romanov@gmail.com { 529*977Smax.romanov@gmail.com char *name_str; 530*977Smax.romanov@gmail.com jsize name_len; 531*977Smax.romanov@gmail.com nxt_unit_field_t *f; 532*977Smax.romanov@gmail.com nxt_unit_response_t *resp; 533*977Smax.romanov@gmail.com nxt_unit_request_info_t *req; 534*977Smax.romanov@gmail.com 535*977Smax.romanov@gmail.com req = nxt_jlong2ptr(req_info_ptr); 536*977Smax.romanov@gmail.com 537*977Smax.romanov@gmail.com if (!nxt_unit_response_is_init(req)) { 538*977Smax.romanov@gmail.com nxt_unit_req_debug(req, "getHeaders: response is not initialized"); 539*977Smax.romanov@gmail.com return NULL; 540*977Smax.romanov@gmail.com } 541*977Smax.romanov@gmail.com 542*977Smax.romanov@gmail.com if (nxt_unit_response_is_sent(req)) { 543*977Smax.romanov@gmail.com nxt_unit_req_debug(req, "getHeaders: response already sent"); 544*977Smax.romanov@gmail.com return NULL; 545*977Smax.romanov@gmail.com } 546*977Smax.romanov@gmail.com 547*977Smax.romanov@gmail.com resp = req->response; 548*977Smax.romanov@gmail.com 549*977Smax.romanov@gmail.com name_len = (*env)->GetArrayLength(env, name); 550*977Smax.romanov@gmail.com 551*977Smax.romanov@gmail.com name_str = (*env)->GetPrimitiveArrayCritical(env, name, NULL); 552*977Smax.romanov@gmail.com if (name_str == NULL) { 553*977Smax.romanov@gmail.com nxt_unit_req_warn(req, "getHeaders: failed to get name content"); 554*977Smax.romanov@gmail.com return NULL; 555*977Smax.romanov@gmail.com } 556*977Smax.romanov@gmail.com 557*977Smax.romanov@gmail.com f = nxt_java_findHeader(resp->fields, resp->fields + resp->fields_count, 558*977Smax.romanov@gmail.com name_str, name_len); 559*977Smax.romanov@gmail.com 560*977Smax.romanov@gmail.com (*env)->ReleasePrimitiveArrayCritical(env, name, name_str, 0); 561*977Smax.romanov@gmail.com 562*977Smax.romanov@gmail.com if (f == NULL) { 563*977Smax.romanov@gmail.com f = resp->fields + resp->fields_count; 564*977Smax.romanov@gmail.com } 565*977Smax.romanov@gmail.com 566*977Smax.romanov@gmail.com return nxt_java_newHeadersEnumeration(env, resp->fields, resp->fields_count, 567*977Smax.romanov@gmail.com f - resp->fields); 568*977Smax.romanov@gmail.com } 569*977Smax.romanov@gmail.com 570*977Smax.romanov@gmail.com 571*977Smax.romanov@gmail.com static jint JNICALL 572*977Smax.romanov@gmail.com nxt_java_Response_getStatus(JNIEnv *env, jclass cls, jlong req_info_ptr) 573*977Smax.romanov@gmail.com { 574*977Smax.romanov@gmail.com nxt_unit_request_info_t *req; 575*977Smax.romanov@gmail.com 576*977Smax.romanov@gmail.com req = nxt_jlong2ptr(req_info_ptr); 577*977Smax.romanov@gmail.com 578*977Smax.romanov@gmail.com if (!nxt_unit_response_is_init(req)) { 579*977Smax.romanov@gmail.com nxt_unit_req_debug(req, "getStatus: response is not initialized"); 580*977Smax.romanov@gmail.com return 200; 581*977Smax.romanov@gmail.com } 582*977Smax.romanov@gmail.com 583*977Smax.romanov@gmail.com if (nxt_unit_response_is_sent(req)) { 584*977Smax.romanov@gmail.com nxt_unit_req_debug(req, "getStatus: response already sent"); 585*977Smax.romanov@gmail.com return 200; 586*977Smax.romanov@gmail.com } 587*977Smax.romanov@gmail.com 588*977Smax.romanov@gmail.com return req->response->status; 589*977Smax.romanov@gmail.com } 590*977Smax.romanov@gmail.com 591*977Smax.romanov@gmail.com 592*977Smax.romanov@gmail.com static jobject JNICALL 593*977Smax.romanov@gmail.com nxt_java_Response_getRequest(JNIEnv *env, jclass cls, jlong req_info_ptr) 594*977Smax.romanov@gmail.com { 595*977Smax.romanov@gmail.com nxt_unit_request_info_t *req; 596*977Smax.romanov@gmail.com nxt_java_request_data_t *data; 597*977Smax.romanov@gmail.com 598*977Smax.romanov@gmail.com req = nxt_jlong2ptr(req_info_ptr); 599*977Smax.romanov@gmail.com data = req->data; 600*977Smax.romanov@gmail.com 601*977Smax.romanov@gmail.com return data->jreq; 602*977Smax.romanov@gmail.com } 603*977Smax.romanov@gmail.com 604*977Smax.romanov@gmail.com 605*977Smax.romanov@gmail.com static void JNICALL 606*977Smax.romanov@gmail.com nxt_java_Response_commit(JNIEnv *env, jclass cls, jlong req_info_ptr) 607*977Smax.romanov@gmail.com { 608*977Smax.romanov@gmail.com nxt_unit_request_info_t *req; 609*977Smax.romanov@gmail.com 610*977Smax.romanov@gmail.com req = nxt_jlong2ptr(req_info_ptr); 611*977Smax.romanov@gmail.com 612*977Smax.romanov@gmail.com nxt_java_OutputStream_flush_buf(env, req); 613*977Smax.romanov@gmail.com } 614*977Smax.romanov@gmail.com 615*977Smax.romanov@gmail.com 616*977Smax.romanov@gmail.com static void JNICALL 617*977Smax.romanov@gmail.com nxt_java_Response_sendRedirect(JNIEnv *env, jclass cls, 618*977Smax.romanov@gmail.com jlong req_info_ptr, jarray loc) 619*977Smax.romanov@gmail.com { 620*977Smax.romanov@gmail.com int rc; 621*977Smax.romanov@gmail.com char *loc_str; 622*977Smax.romanov@gmail.com jsize loc_len; 623*977Smax.romanov@gmail.com nxt_unit_request_info_t *req; 624*977Smax.romanov@gmail.com 625*977Smax.romanov@gmail.com static const char location[] = "Location"; 626*977Smax.romanov@gmail.com static const uint32_t location_len = sizeof(location) - 1; 627*977Smax.romanov@gmail.com 628*977Smax.romanov@gmail.com req = nxt_jlong2ptr(req_info_ptr); 629*977Smax.romanov@gmail.com 630*977Smax.romanov@gmail.com if (nxt_unit_response_is_sent(req)) { 631*977Smax.romanov@gmail.com nxt_java_throw_IllegalStateException(env, "Response already sent"); 632*977Smax.romanov@gmail.com 633*977Smax.romanov@gmail.com return; 634*977Smax.romanov@gmail.com } 635*977Smax.romanov@gmail.com 636*977Smax.romanov@gmail.com loc_len = (*env)->GetArrayLength(env, loc); 637*977Smax.romanov@gmail.com 638*977Smax.romanov@gmail.com req = nxt_java_get_response_info(req_info_ptr, 1, 639*977Smax.romanov@gmail.com location_len + loc_len + 2); 640*977Smax.romanov@gmail.com if (req == NULL) { 641*977Smax.romanov@gmail.com return; 642*977Smax.romanov@gmail.com } 643*977Smax.romanov@gmail.com 644*977Smax.romanov@gmail.com loc_str = (*env)->GetPrimitiveArrayCritical(env, loc, NULL); 645*977Smax.romanov@gmail.com if (loc_str == NULL) { 646*977Smax.romanov@gmail.com nxt_unit_req_warn(req, "sendRedirect: failed to get loc content"); 647*977Smax.romanov@gmail.com return; 648*977Smax.romanov@gmail.com } 649*977Smax.romanov@gmail.com 650*977Smax.romanov@gmail.com req->response->status = 302; 651*977Smax.romanov@gmail.com 652*977Smax.romanov@gmail.com rc = nxt_java_response_set_header(req_info_ptr, location, location_len, 653*977Smax.romanov@gmail.com loc_str, loc_len); 654*977Smax.romanov@gmail.com if (rc != NXT_UNIT_OK) { 655*977Smax.romanov@gmail.com // throw 656*977Smax.romanov@gmail.com } 657*977Smax.romanov@gmail.com 658*977Smax.romanov@gmail.com (*env)->ReleasePrimitiveArrayCritical(env, loc, loc_str, 0); 659*977Smax.romanov@gmail.com 660*977Smax.romanov@gmail.com nxt_unit_response_send(req); 661*977Smax.romanov@gmail.com } 662*977Smax.romanov@gmail.com 663*977Smax.romanov@gmail.com 664*977Smax.romanov@gmail.com static int 665*977Smax.romanov@gmail.com nxt_java_response_set_header(jlong req_info_ptr, 666*977Smax.romanov@gmail.com const char *name, jint name_len, const char *value, jint value_len) 667*977Smax.romanov@gmail.com { 668*977Smax.romanov@gmail.com int add_field; 669*977Smax.romanov@gmail.com char *dst; 670*977Smax.romanov@gmail.com nxt_unit_field_t *f, *e; 671*977Smax.romanov@gmail.com nxt_unit_response_t *resp; 672*977Smax.romanov@gmail.com nxt_unit_request_info_t *req; 673*977Smax.romanov@gmail.com 674*977Smax.romanov@gmail.com req = nxt_java_get_response_info(req_info_ptr, 0, 0); 675*977Smax.romanov@gmail.com if (req == NULL) { 676*977Smax.romanov@gmail.com return NXT_UNIT_ERROR; 677*977Smax.romanov@gmail.com } 678*977Smax.romanov@gmail.com 679*977Smax.romanov@gmail.com resp = req->response; 680*977Smax.romanov@gmail.com 681*977Smax.romanov@gmail.com f = resp->fields; 682*977Smax.romanov@gmail.com e = f + resp->fields_count; 683*977Smax.romanov@gmail.com 684*977Smax.romanov@gmail.com add_field = 1; 685*977Smax.romanov@gmail.com 686*977Smax.romanov@gmail.com for ( ;; ) { 687*977Smax.romanov@gmail.com f = nxt_java_findHeader(f, e, name, name_len); 688*977Smax.romanov@gmail.com if (f == NULL) { 689*977Smax.romanov@gmail.com break; 690*977Smax.romanov@gmail.com } 691*977Smax.romanov@gmail.com 692*977Smax.romanov@gmail.com if (add_field && f->value_length >= (uint32_t) value_len) { 693*977Smax.romanov@gmail.com dst = nxt_unit_sptr_get(&f->value); 694*977Smax.romanov@gmail.com memcpy(dst, value, value_len); 695*977Smax.romanov@gmail.com dst[value_len] = '\0'; 696*977Smax.romanov@gmail.com f->value_length = value_len; 697*977Smax.romanov@gmail.com 698*977Smax.romanov@gmail.com add_field = 0; 699*977Smax.romanov@gmail.com f->skip = 0; 700*977Smax.romanov@gmail.com 701*977Smax.romanov@gmail.com } else { 702*977Smax.romanov@gmail.com f->skip = 1; 703*977Smax.romanov@gmail.com } 704*977Smax.romanov@gmail.com 705*977Smax.romanov@gmail.com ++f; 706*977Smax.romanov@gmail.com } 707*977Smax.romanov@gmail.com 708*977Smax.romanov@gmail.com if (!add_field) { 709*977Smax.romanov@gmail.com return NXT_UNIT_OK; 710*977Smax.romanov@gmail.com } 711*977Smax.romanov@gmail.com 712*977Smax.romanov@gmail.com req = nxt_java_get_response_info(req_info_ptr, 1, name_len + value_len + 2); 713*977Smax.romanov@gmail.com if (req == NULL) { 714*977Smax.romanov@gmail.com return NXT_UNIT_ERROR; 715*977Smax.romanov@gmail.com } 716*977Smax.romanov@gmail.com 717*977Smax.romanov@gmail.com return nxt_unit_response_add_field(req, name, name_len, value, value_len); 718*977Smax.romanov@gmail.com } 719*977Smax.romanov@gmail.com 720*977Smax.romanov@gmail.com 721*977Smax.romanov@gmail.com static void JNICALL 722*977Smax.romanov@gmail.com nxt_java_Response_setHeader(JNIEnv *env, jclass cls, 723*977Smax.romanov@gmail.com jlong req_info_ptr, jarray name, jarray value) 724*977Smax.romanov@gmail.com { 725*977Smax.romanov@gmail.com int rc; 726*977Smax.romanov@gmail.com char *name_str, *value_str; 727*977Smax.romanov@gmail.com jsize name_len, value_len; 728*977Smax.romanov@gmail.com nxt_unit_request_info_t *req; 729*977Smax.romanov@gmail.com 730*977Smax.romanov@gmail.com name_str = (*env)->GetPrimitiveArrayCritical(env, name, NULL); 731*977Smax.romanov@gmail.com if (name_str == NULL) { 732*977Smax.romanov@gmail.com req = nxt_jlong2ptr(req_info_ptr); 733*977Smax.romanov@gmail.com nxt_unit_req_warn(req, "setHeader: failed to get name content"); 734*977Smax.romanov@gmail.com return; 735*977Smax.romanov@gmail.com } 736*977Smax.romanov@gmail.com 737*977Smax.romanov@gmail.com value_str = (*env)->GetPrimitiveArrayCritical(env, value, NULL); 738*977Smax.romanov@gmail.com if (value_str == NULL) { 739*977Smax.romanov@gmail.com (*env)->ReleasePrimitiveArrayCritical(env, name, name_str, 0); 740*977Smax.romanov@gmail.com 741*977Smax.romanov@gmail.com req = nxt_jlong2ptr(req_info_ptr); 742*977Smax.romanov@gmail.com nxt_unit_req_warn(req, "setHeader: failed to get value content"); 743*977Smax.romanov@gmail.com 744*977Smax.romanov@gmail.com return; 745*977Smax.romanov@gmail.com } 746*977Smax.romanov@gmail.com 747*977Smax.romanov@gmail.com name_len = (*env)->GetArrayLength(env, name); 748*977Smax.romanov@gmail.com value_len = (*env)->GetArrayLength(env, value); 749*977Smax.romanov@gmail.com 750*977Smax.romanov@gmail.com rc = nxt_java_response_set_header(req_info_ptr, name_str, name_len, 751*977Smax.romanov@gmail.com value_str, value_len); 752*977Smax.romanov@gmail.com if (rc != NXT_UNIT_OK) { 753*977Smax.romanov@gmail.com // throw 754*977Smax.romanov@gmail.com } 755*977Smax.romanov@gmail.com 756*977Smax.romanov@gmail.com (*env)->ReleasePrimitiveArrayCritical(env, value, value_str, 0); 757*977Smax.romanov@gmail.com (*env)->ReleasePrimitiveArrayCritical(env, name, name_str, 0); 758*977Smax.romanov@gmail.com } 759*977Smax.romanov@gmail.com 760*977Smax.romanov@gmail.com 761*977Smax.romanov@gmail.com static void JNICALL 762*977Smax.romanov@gmail.com nxt_java_Response_removeHeader(JNIEnv *env, jclass cls, 763*977Smax.romanov@gmail.com jlong req_info_ptr, jarray name) 764*977Smax.romanov@gmail.com { 765*977Smax.romanov@gmail.com int rc; 766*977Smax.romanov@gmail.com char *name_str; 767*977Smax.romanov@gmail.com jsize name_len; 768*977Smax.romanov@gmail.com nxt_unit_request_info_t *req; 769*977Smax.romanov@gmail.com 770*977Smax.romanov@gmail.com name_len = (*env)->GetArrayLength(env, name); 771*977Smax.romanov@gmail.com 772*977Smax.romanov@gmail.com name_str = (*env)->GetPrimitiveArrayCritical(env, name, NULL); 773*977Smax.romanov@gmail.com if (name_str == NULL) { 774*977Smax.romanov@gmail.com req = nxt_jlong2ptr(req_info_ptr); 775*977Smax.romanov@gmail.com nxt_unit_req_warn(req, "setHeader: failed to get name content"); 776*977Smax.romanov@gmail.com return; 777*977Smax.romanov@gmail.com } 778*977Smax.romanov@gmail.com 779*977Smax.romanov@gmail.com rc = nxt_java_response_remove_header(req_info_ptr, name_str, name_len); 780*977Smax.romanov@gmail.com if (rc != NXT_UNIT_OK) { 781*977Smax.romanov@gmail.com // throw 782*977Smax.romanov@gmail.com } 783*977Smax.romanov@gmail.com 784*977Smax.romanov@gmail.com (*env)->ReleasePrimitiveArrayCritical(env, name, name_str, 0); 785*977Smax.romanov@gmail.com } 786*977Smax.romanov@gmail.com 787*977Smax.romanov@gmail.com 788*977Smax.romanov@gmail.com static int 789*977Smax.romanov@gmail.com nxt_java_response_remove_header(jlong req_info_ptr, 790*977Smax.romanov@gmail.com const char *name, jint name_len) 791*977Smax.romanov@gmail.com { 792*977Smax.romanov@gmail.com nxt_unit_field_t *f, *e; 793*977Smax.romanov@gmail.com nxt_unit_response_t *resp; 794*977Smax.romanov@gmail.com nxt_unit_request_info_t *req; 795*977Smax.romanov@gmail.com 796*977Smax.romanov@gmail.com req = nxt_java_get_response_info(req_info_ptr, 0, 0); 797*977Smax.romanov@gmail.com if (req == NULL) { 798*977Smax.romanov@gmail.com return NXT_UNIT_ERROR; 799*977Smax.romanov@gmail.com } 800*977Smax.romanov@gmail.com 801*977Smax.romanov@gmail.com resp = req->response; 802*977Smax.romanov@gmail.com 803*977Smax.romanov@gmail.com f = resp->fields; 804*977Smax.romanov@gmail.com e = f + resp->fields_count; 805*977Smax.romanov@gmail.com 806*977Smax.romanov@gmail.com for ( ;; ) { 807*977Smax.romanov@gmail.com f = nxt_java_findHeader(f, e, name, name_len); 808*977Smax.romanov@gmail.com if (f == NULL) { 809*977Smax.romanov@gmail.com break; 810*977Smax.romanov@gmail.com } 811*977Smax.romanov@gmail.com 812*977Smax.romanov@gmail.com f->skip = 1; 813*977Smax.romanov@gmail.com 814*977Smax.romanov@gmail.com ++f; 815*977Smax.romanov@gmail.com } 816*977Smax.romanov@gmail.com 817*977Smax.romanov@gmail.com return NXT_UNIT_OK; 818*977Smax.romanov@gmail.com } 819*977Smax.romanov@gmail.com 820*977Smax.romanov@gmail.com 821*977Smax.romanov@gmail.com static void JNICALL 822*977Smax.romanov@gmail.com nxt_java_Response_setIntHeader(JNIEnv *env, jclass cls, 823*977Smax.romanov@gmail.com jlong req_info_ptr, jarray name, jint value) 824*977Smax.romanov@gmail.com { 825*977Smax.romanov@gmail.com int value_len, rc; 826*977Smax.romanov@gmail.com char value_str[40]; 827*977Smax.romanov@gmail.com char *name_str; 828*977Smax.romanov@gmail.com jsize name_len; 829*977Smax.romanov@gmail.com 830*977Smax.romanov@gmail.com value_len = snprintf(value_str, sizeof(value_str), "%d", (int) value); 831*977Smax.romanov@gmail.com 832*977Smax.romanov@gmail.com name_len = (*env)->GetArrayLength(env, name); 833*977Smax.romanov@gmail.com 834*977Smax.romanov@gmail.com name_str = (*env)->GetPrimitiveArrayCritical(env, name, NULL); 835*977Smax.romanov@gmail.com if (name_str == NULL) { 836*977Smax.romanov@gmail.com nxt_unit_req_warn(nxt_jlong2ptr(req_info_ptr), 837*977Smax.romanov@gmail.com "setIntHeader: failed to get name content"); 838*977Smax.romanov@gmail.com return; 839*977Smax.romanov@gmail.com } 840*977Smax.romanov@gmail.com 841*977Smax.romanov@gmail.com rc = nxt_java_response_set_header(req_info_ptr, name_str, name_len, 842*977Smax.romanov@gmail.com value_str, value_len); 843*977Smax.romanov@gmail.com if (rc != NXT_UNIT_OK) { 844*977Smax.romanov@gmail.com // throw 845*977Smax.romanov@gmail.com } 846*977Smax.romanov@gmail.com 847*977Smax.romanov@gmail.com (*env)->ReleasePrimitiveArrayCritical(env, name, name_str, 0); 848*977Smax.romanov@gmail.com } 849*977Smax.romanov@gmail.com 850*977Smax.romanov@gmail.com 851*977Smax.romanov@gmail.com static void JNICALL 852*977Smax.romanov@gmail.com nxt_java_Response_setStatus(JNIEnv *env, jclass cls, jlong req_info_ptr, 853*977Smax.romanov@gmail.com jint sc) 854*977Smax.romanov@gmail.com { 855*977Smax.romanov@gmail.com nxt_unit_request_info_t *req; 856*977Smax.romanov@gmail.com 857*977Smax.romanov@gmail.com req = nxt_java_get_response_info(req_info_ptr, 0, 0); 858*977Smax.romanov@gmail.com if (req == NULL) { 859*977Smax.romanov@gmail.com return; 860*977Smax.romanov@gmail.com } 861*977Smax.romanov@gmail.com 862*977Smax.romanov@gmail.com req->response->status = sc; 863*977Smax.romanov@gmail.com } 864*977Smax.romanov@gmail.com 865*977Smax.romanov@gmail.com 866*977Smax.romanov@gmail.com static jstring JNICALL 867*977Smax.romanov@gmail.com nxt_java_Response_getContentType(JNIEnv *env, jclass cls, jlong req_info_ptr) 868*977Smax.romanov@gmail.com { 869*977Smax.romanov@gmail.com nxt_unit_field_t *f; 870*977Smax.romanov@gmail.com nxt_unit_request_info_t *req; 871*977Smax.romanov@gmail.com 872*977Smax.romanov@gmail.com req = nxt_jlong2ptr(req_info_ptr); 873*977Smax.romanov@gmail.com 874*977Smax.romanov@gmail.com if (!nxt_unit_response_is_init(req)) { 875*977Smax.romanov@gmail.com nxt_unit_req_debug(req, "getContentType: response is not initialized"); 876*977Smax.romanov@gmail.com return NULL; 877*977Smax.romanov@gmail.com } 878*977Smax.romanov@gmail.com 879*977Smax.romanov@gmail.com if (nxt_unit_response_is_sent(req)) { 880*977Smax.romanov@gmail.com nxt_unit_req_debug(req, "getContentType: response already sent"); 881*977Smax.romanov@gmail.com return NULL; 882*977Smax.romanov@gmail.com } 883*977Smax.romanov@gmail.com 884*977Smax.romanov@gmail.com f = nxt_java_findHeader(req->response->fields, 885*977Smax.romanov@gmail.com req->response->fields + req->response->fields_count, 886*977Smax.romanov@gmail.com "Content-Type", sizeof("Content-Type") - 1); 887*977Smax.romanov@gmail.com 888*977Smax.romanov@gmail.com if (f == NULL) { 889*977Smax.romanov@gmail.com return NULL; 890*977Smax.romanov@gmail.com } 891*977Smax.romanov@gmail.com 892*977Smax.romanov@gmail.com return nxt_java_newString(env, nxt_unit_sptr_get(&f->value), 893*977Smax.romanov@gmail.com f->value_length); 894*977Smax.romanov@gmail.com } 895*977Smax.romanov@gmail.com 896*977Smax.romanov@gmail.com 897*977Smax.romanov@gmail.com static jboolean JNICALL 898*977Smax.romanov@gmail.com nxt_java_Response_isCommitted(JNIEnv *env, jclass cls, jlong req_info_ptr) 899*977Smax.romanov@gmail.com { 900*977Smax.romanov@gmail.com nxt_unit_request_info_t *req; 901*977Smax.romanov@gmail.com 902*977Smax.romanov@gmail.com req = nxt_jlong2ptr(req_info_ptr); 903*977Smax.romanov@gmail.com 904*977Smax.romanov@gmail.com if (nxt_unit_response_is_sent(req)) { 905*977Smax.romanov@gmail.com return 1; 906*977Smax.romanov@gmail.com } 907*977Smax.romanov@gmail.com 908*977Smax.romanov@gmail.com return 0; 909*977Smax.romanov@gmail.com } 910*977Smax.romanov@gmail.com 911*977Smax.romanov@gmail.com 912*977Smax.romanov@gmail.com static void JNICALL 913*977Smax.romanov@gmail.com nxt_java_Response_reset(JNIEnv *env, jclass cls, jlong req_info_ptr) 914*977Smax.romanov@gmail.com { 915*977Smax.romanov@gmail.com nxt_unit_buf_t *buf; 916*977Smax.romanov@gmail.com nxt_unit_request_info_t *req; 917*977Smax.romanov@gmail.com nxt_java_request_data_t *data; 918*977Smax.romanov@gmail.com 919*977Smax.romanov@gmail.com req = nxt_jlong2ptr(req_info_ptr); 920*977Smax.romanov@gmail.com 921*977Smax.romanov@gmail.com if (nxt_unit_response_is_sent(req)) { 922*977Smax.romanov@gmail.com nxt_java_throw_IllegalStateException(env, "Response already sent"); 923*977Smax.romanov@gmail.com 924*977Smax.romanov@gmail.com return; 925*977Smax.romanov@gmail.com } 926*977Smax.romanov@gmail.com 927*977Smax.romanov@gmail.com data = req->data; 928*977Smax.romanov@gmail.com 929*977Smax.romanov@gmail.com if (data->buf != NULL && data->buf->free > data->buf->start) { 930*977Smax.romanov@gmail.com data->buf->free = data->buf->start; 931*977Smax.romanov@gmail.com } 932*977Smax.romanov@gmail.com 933*977Smax.romanov@gmail.com if (nxt_unit_response_is_init(req)) { 934*977Smax.romanov@gmail.com req->response->status = 200; 935*977Smax.romanov@gmail.com req->response->fields_count = 0; 936*977Smax.romanov@gmail.com 937*977Smax.romanov@gmail.com buf = req->response_buf; 938*977Smax.romanov@gmail.com 939*977Smax.romanov@gmail.com buf->free = buf->start + req->response_max_fields 940*977Smax.romanov@gmail.com * sizeof(nxt_unit_field_t); 941*977Smax.romanov@gmail.com } 942*977Smax.romanov@gmail.com } 943*977Smax.romanov@gmail.com 944*977Smax.romanov@gmail.com 945*977Smax.romanov@gmail.com static void JNICALL 946*977Smax.romanov@gmail.com nxt_java_Response_resetBuffer(JNIEnv *env, jclass cls, jlong req_info_ptr) 947*977Smax.romanov@gmail.com { 948*977Smax.romanov@gmail.com nxt_unit_request_info_t *req; 949*977Smax.romanov@gmail.com nxt_java_request_data_t *data; 950*977Smax.romanov@gmail.com 951*977Smax.romanov@gmail.com req = nxt_jlong2ptr(req_info_ptr); 952*977Smax.romanov@gmail.com data = req->data; 953*977Smax.romanov@gmail.com 954*977Smax.romanov@gmail.com if (data->buf != NULL && data->buf->free > data->buf->start) { 955*977Smax.romanov@gmail.com data->buf->free = data->buf->start; 956*977Smax.romanov@gmail.com } 957*977Smax.romanov@gmail.com } 958*977Smax.romanov@gmail.com 959*977Smax.romanov@gmail.com 960*977Smax.romanov@gmail.com static void JNICALL 961*977Smax.romanov@gmail.com nxt_java_Response_setBufferSize(JNIEnv *env, jclass cls, jlong req_info_ptr, 962*977Smax.romanov@gmail.com jint size) 963*977Smax.romanov@gmail.com { 964*977Smax.romanov@gmail.com nxt_unit_request_info_t *req; 965*977Smax.romanov@gmail.com nxt_java_request_data_t *data; 966*977Smax.romanov@gmail.com 967*977Smax.romanov@gmail.com req = nxt_jlong2ptr(req_info_ptr); 968*977Smax.romanov@gmail.com data = req->data; 969*977Smax.romanov@gmail.com 970*977Smax.romanov@gmail.com if (data->buf_size == (uint32_t) size) { 971*977Smax.romanov@gmail.com return; 972*977Smax.romanov@gmail.com } 973*977Smax.romanov@gmail.com 974*977Smax.romanov@gmail.com if (data->buf != NULL && data->buf->free > data->buf->start) { 975*977Smax.romanov@gmail.com nxt_java_throw_IllegalStateException(env, "Buffer is not empty"); 976*977Smax.romanov@gmail.com 977*977Smax.romanov@gmail.com return; 978*977Smax.romanov@gmail.com } 979*977Smax.romanov@gmail.com 980*977Smax.romanov@gmail.com data->buf_size = size; 981*977Smax.romanov@gmail.com 982*977Smax.romanov@gmail.com if (data->buf_size > nxt_unit_buf_max()) { 983*977Smax.romanov@gmail.com data->buf_size = nxt_unit_buf_max(); 984*977Smax.romanov@gmail.com } 985*977Smax.romanov@gmail.com 986*977Smax.romanov@gmail.com if (data->buf != NULL 987*977Smax.romanov@gmail.com && (uint32_t) (data->buf->end - data->buf->start) < data->buf_size) 988*977Smax.romanov@gmail.com { 989*977Smax.romanov@gmail.com nxt_unit_buf_free(data->buf); 990*977Smax.romanov@gmail.com 991*977Smax.romanov@gmail.com data->buf = NULL; 992*977Smax.romanov@gmail.com } 993*977Smax.romanov@gmail.com } 994*977Smax.romanov@gmail.com 995*977Smax.romanov@gmail.com 996*977Smax.romanov@gmail.com static jint JNICALL 997*977Smax.romanov@gmail.com nxt_java_Response_getBufferSize(JNIEnv *env, jclass cls, jlong req_info_ptr) 998*977Smax.romanov@gmail.com { 999*977Smax.romanov@gmail.com nxt_unit_request_info_t *req; 1000*977Smax.romanov@gmail.com nxt_java_request_data_t *data; 1001*977Smax.romanov@gmail.com 1002*977Smax.romanov@gmail.com req = nxt_jlong2ptr(req_info_ptr); 1003*977Smax.romanov@gmail.com data = req->data; 1004*977Smax.romanov@gmail.com 1005*977Smax.romanov@gmail.com return data->buf_size; 1006*977Smax.romanov@gmail.com } 1007*977Smax.romanov@gmail.com 1008*977Smax.romanov@gmail.com 1009*977Smax.romanov@gmail.com static void JNICALL 1010*977Smax.romanov@gmail.com nxt_java_Response_setContentLength(JNIEnv *env, jclass cls, jlong req_info_ptr, 1011*977Smax.romanov@gmail.com jlong len) 1012*977Smax.romanov@gmail.com { 1013*977Smax.romanov@gmail.com nxt_unit_request_info_t *req; 1014*977Smax.romanov@gmail.com 1015*977Smax.romanov@gmail.com req = nxt_java_get_response_info(req_info_ptr, 0, 0); 1016*977Smax.romanov@gmail.com if (req == NULL) { 1017*977Smax.romanov@gmail.com return; 1018*977Smax.romanov@gmail.com } 1019*977Smax.romanov@gmail.com 1020*977Smax.romanov@gmail.com req->response->content_length = len; 1021*977Smax.romanov@gmail.com } 1022*977Smax.romanov@gmail.com 1023*977Smax.romanov@gmail.com 1024*977Smax.romanov@gmail.com static void JNICALL 1025*977Smax.romanov@gmail.com nxt_java_Response_setContentType(JNIEnv *env, jclass cls, jlong req_info_ptr, 1026*977Smax.romanov@gmail.com jarray type) 1027*977Smax.romanov@gmail.com { 1028*977Smax.romanov@gmail.com int rc; 1029*977Smax.romanov@gmail.com char *type_str; 1030*977Smax.romanov@gmail.com jsize type_len; 1031*977Smax.romanov@gmail.com 1032*977Smax.romanov@gmail.com static const char content_type[] = "Content-Type"; 1033*977Smax.romanov@gmail.com static const uint32_t content_type_len = sizeof(content_type) - 1; 1034*977Smax.romanov@gmail.com 1035*977Smax.romanov@gmail.com type_len = (*env)->GetArrayLength(env, type); 1036*977Smax.romanov@gmail.com 1037*977Smax.romanov@gmail.com type_str = (*env)->GetPrimitiveArrayCritical(env, type, NULL); 1038*977Smax.romanov@gmail.com if (type_str == NULL) { 1039*977Smax.romanov@gmail.com return; 1040*977Smax.romanov@gmail.com } 1041*977Smax.romanov@gmail.com 1042*977Smax.romanov@gmail.com rc = nxt_java_response_set_header(req_info_ptr, 1043*977Smax.romanov@gmail.com content_type, content_type_len, 1044