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
nxt_java_initResponse(JNIEnv * env,jobject cl)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
nxt_java_newResponse(JNIEnv * env,nxt_unit_request_info_t * req)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
nxt_java_Response_addHeader(JNIEnv * env,jclass cls,jlong req_info_ptr,jarray name,jarray value)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 *
nxt_java_get_response_info(jlong req_info_ptr,uint32_t extra_fields,uint32_t extra_data)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
nxt_java_Response_addIntHeader(JNIEnv * env,jclass cls,jlong req_info_ptr,jarray name,jint value)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
nxt_java_add_int_header(nxt_unit_request_info_t * req,const char * name,uint8_t name_len,int value)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
nxt_java_Response_containsHeader(JNIEnv * env,jclass cls,jlong req_info_ptr,jarray name)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
nxt_java_Response_getHeader(JNIEnv * env,jclass cls,jlong req_info_ptr,jarray name)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
nxt_java_Response_getHeaderNames(JNIEnv * env,jclass cls,jlong req_info_ptr)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
nxt_java_Response_getHeaders(JNIEnv * env,jclass cls,jlong req_info_ptr,jarray name)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
nxt_java_Response_getStatus(JNIEnv * env,jclass cls,jlong req_info_ptr)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
nxt_java_Response_getRequest(JNIEnv * env,jclass cls,jlong req_info_ptr)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
nxt_java_Response_commit(JNIEnv * env,jclass cls,jlong req_info_ptr)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
nxt_java_Response_sendRedirect(JNIEnv * env,jclass cls,jlong req_info_ptr,jarray loc)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
nxt_java_response_set_header(jlong req_info_ptr,const char * name,jint name_len,const char * value,jint value_len)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
nxt_java_Response_setHeader(JNIEnv * env,jclass cls,jlong req_info_ptr,jarray name,jarray value)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
nxt_java_Response_removeHeader(JNIEnv * env,jclass cls,jlong req_info_ptr,jarray name)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
nxt_java_response_remove_header(jlong req_info_ptr,const char * name,jint name_len)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
nxt_java_Response_setIntHeader(JNIEnv * env,jclass cls,jlong req_info_ptr,jarray name,jint value)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
nxt_java_Response_setStatus(JNIEnv * env,jclass cls,jlong req_info_ptr,jint sc)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
nxt_java_Response_getContentType(JNIEnv * env,jclass cls,jlong req_info_ptr)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
nxt_java_Response_isCommitted(JNIEnv * env,jclass cls,jlong req_info_ptr)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
nxt_java_Response_reset(JNIEnv * env,jclass cls,jlong req_info_ptr)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
nxt_java_Response_resetBuffer(JNIEnv * env,jclass cls,jlong req_info_ptr)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
nxt_java_Response_setBufferSize(JNIEnv * env,jclass cls,jlong req_info_ptr,jint size)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
nxt_java_Response_getBufferSize(JNIEnv * env,jclass cls,jlong req_info_ptr)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
nxt_java_Response_setContentLength(JNIEnv * env,jclass cls,jlong req_info_ptr,jlong len)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
nxt_java_Response_setContentType(JNIEnv * env,jclass cls,jlong req_info_ptr,jarray type)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