@@ -133,6 +133,83 @@ static jlong JNICALL jni_ngx_create_temp_buf (JNIEnv *env, jclass cls, jlong r,
133133 return (uintptr_t )ngx_create_temp_buf (req -> pool , (size_t )size );
134134}
135135
136+ static jlong JNICALL jni_ngx_create_temp_buf_by_jstring (JNIEnv * env , jclass cls , jlong req , jstring jstr , jint last_buf ) {
137+ ngx_http_request_t * r = (ngx_http_request_t * )(uintptr_t ) req ;
138+
139+ jsize ch_size = (* env )-> GetStringLength (env , jstr );
140+ jsize utf8_size = (* env )-> GetStringUTFLength (env , jstr );
141+ ngx_buf_t * b = ngx_create_temp_buf (r -> pool , (size_t )utf8_size );
142+
143+ if (b == NULL ) {
144+ return 0 ;
145+ }
146+
147+ (* env )-> GetStringUTFRegion (env , jstr , 0 , ch_size , (char * )b -> pos );
148+ b -> last = b -> pos + utf8_size ;
149+
150+ if (last_buf & NGX_BUF_LAST_OF_RESPONSE ) {
151+ b -> last_buf = b -> last_in_chain = 1 ;
152+ }else {
153+ b -> last_in_chain = last_buf & NGX_BUF_LAST_OF_CHAIN ;
154+ }
155+
156+ if (r -> headers_out .content_length_n < 0 ) {
157+ r -> headers_out .content_length_n = utf8_size ;
158+ }else {
159+ r -> headers_out .content_length_n += utf8_size ;
160+ }
161+
162+ /*
163+ * If File and String are in the same ISeq of one response body,
164+ * we should clear the last_modified_time.
165+ */
166+ r -> headers_out .last_modified_time = -2 ;
167+ r -> headers_out .last_modified = NULL ;
168+
169+ return (uintptr_t )b ;
170+ }
171+
172+
173+ static jlong JNICALL jni_ngx_create_temp_buf_by_obj (JNIEnv * env , jclass cls , jlong req , jobject obj , jlong off , jlong len , jint last_buf ) {
174+ ngx_http_request_t * r = (ngx_http_request_t * )(uintptr_t ) req ;
175+ ngx_buf_t * b ;
176+
177+ if (len == 0 ) {
178+ return 0 ;
179+ }
180+
181+ b = ngx_calloc_buf (r -> pool );
182+ if (b == NULL ) {
183+ return 0 ;
184+ }
185+
186+ b -> start = (u_char * )ngx_http_clojure_abs_off_addr (obj , off );
187+ b -> pos = b -> start ;
188+ b -> last = b -> start + len ;
189+ b -> end = b -> last ;
190+ b -> memory = 1 ;
191+
192+ if (last_buf & NGX_BUF_LAST_OF_RESPONSE ) {
193+ b -> last_buf = b -> last_in_chain = 1 ;
194+ }else {
195+ b -> last_in_chain = last_buf & NGX_BUF_LAST_OF_CHAIN ;
196+ }
197+
198+ if (r -> headers_out .content_length_n < 0 ) {
199+ r -> headers_out .content_length_n = len ;
200+ }else {
201+ r -> headers_out .content_length_n += len ;
202+ }
203+
204+ /*
205+ * If File and String are in the same ISeq of one response body,
206+ * we should clear the last_modified_time.
207+ */
208+ r -> headers_out .last_modified_time = -2 ;
209+ r -> headers_out .last_modified = NULL ;
210+
211+ return (uintptr_t )b ;
212+ }
136213
137214static jlong JNICALL jni_ngx_create_file_buf (JNIEnv * env , jclass cls , jlong r , jlong file , jlong name_len , jint last_buf ) {
138215 ngx_http_request_t * req = (ngx_http_request_t * ) (uintptr_t )r ;
@@ -1353,6 +1430,204 @@ static jlong JNICALL jni_ngx_http_clojure_mem_init_ngx_buf(JNIEnv *env, jclass c
13531430 return (uintptr_t )b ;
13541431}
13551432
1433+ static jlong JNICALL jni_ngx_http_clojure_mem_build_temp_chain (JNIEnv * env , jclass cls , jlong req , jlong prevChain , jobject obj , jlong offset , jlong len ) {
1434+ ngx_chain_t * pre = (ngx_chain_t * )(uintptr_t )prevChain ;
1435+ ngx_http_request_t * r = (ngx_http_request_t * )(uintptr_t )req ;
1436+ ngx_buf_t * b ;
1437+ ngx_chain_t * cl ;
1438+
1439+ if (pre != NULL ) {
1440+ while (pre -> next != NULL ) {
1441+ pre = pre -> next ;
1442+ }
1443+ }
1444+
1445+ if (r -> headers_out .content_length_n < 0 ) {
1446+ r -> headers_out .content_length_n = len ;
1447+ }else {
1448+ r -> headers_out .content_length_n += len ;
1449+ }
1450+
1451+ /*
1452+ * If File and String are in the same ISeq of one response body,
1453+ * we should clear the last_modified_time.
1454+ */
1455+ r -> headers_out .last_modified_time = -2 ;
1456+ r -> headers_out .last_modified = NULL ;
1457+
1458+ b = ngx_create_temp_buf (r -> pool , (size_t )len );
1459+ if (b == NULL ){
1460+ return 0 ;
1461+ }
1462+
1463+ cl = ngx_palloc (r -> pool , sizeof (ngx_chain_t ));
1464+ if (cl == NULL ) {
1465+ return 0 ;
1466+ }
1467+
1468+ cl -> buf = b ;
1469+
1470+ if (len > 0 ) {
1471+ ngx_memcpy (b -> pos , ngx_http_clojure_abs_off_addr (obj , offset ), len );
1472+ b -> last = b -> pos + len ;
1473+ }
1474+
1475+ if (pre != NULL ) {
1476+ cl -> next = pre -> next ;
1477+ pre -> next = cl ;
1478+ b -> last_in_chain = pre -> buf -> last_in_chain ;
1479+ b -> last_buf = pre -> buf -> last_buf ;
1480+ pre -> buf -> last_in_chain = 0 ;
1481+ pre -> buf -> last_buf = 0 ;
1482+ }else {
1483+ cl -> next = NULL ;
1484+ b -> last_in_chain = 1 ;
1485+ b -> last_buf = 1 ;
1486+ }
1487+
1488+ return (uintptr_t )cl ;
1489+ }
1490+
1491+
1492+ static jlong JNICALL jni_ngx_http_clojure_mem_build_file_chain (JNIEnv * env , jclass cls , jlong req , jlong prevChain , jobject file , jlong offset , jlong len ) {
1493+ ngx_chain_t * pre = (ngx_chain_t * )(uintptr_t )prevChain ;
1494+ ngx_http_request_t * r = (ngx_http_request_t * )(uintptr_t )req ;
1495+ ngx_buf_t * b ;
1496+ ngx_chain_t * cl ;
1497+ ngx_str_t path ; // = {(ngx_int_t)name_len, (u_char *)file};
1498+ ngx_open_file_info_t of ;
1499+ ngx_http_core_loc_conf_t * clcf = ngx_http_get_module_loc_conf (r , ngx_http_core_module );
1500+ ngx_uint_t level ;
1501+ ngx_log_t * log = r -> connection -> log ;
1502+
1503+ if (pre != NULL ) {
1504+ while (pre -> next != NULL ) {
1505+ pre = pre -> next ;
1506+ }
1507+ }
1508+
1509+ /*make VS 2010 happy*/
1510+ path .data = (u_char * )ngx_http_clojure_abs_off_addr (file , offset );
1511+ path .len = (ngx_int_t )len ;
1512+
1513+ /*just like http_static module */
1514+
1515+ ngx_memzero (& of , sizeof (ngx_open_file_info_t ));
1516+
1517+ of .read_ahead = clcf -> read_ahead ;
1518+ of .directio = clcf -> directio ;
1519+ of .valid = clcf -> open_file_cache_valid ;
1520+ of .min_uses = clcf -> open_file_cache_min_uses ;
1521+ of .errors = clcf -> open_file_cache_errors ;
1522+ of .events = clcf -> open_file_cache_events ;
1523+
1524+ if (ngx_open_cached_file (clcf -> open_file_cache , & path , & of , r -> pool ) != NGX_OK ) {
1525+ ngx_int_t rc = 0 ;
1526+
1527+ switch (of .err ) {
1528+
1529+ case 0 :
1530+ return - NGX_HTTP_INTERNAL_SERVER_ERROR ;
1531+
1532+ case NGX_ENOENT :
1533+ case NGX_ENOTDIR :
1534+ case NGX_ENAMETOOLONG :
1535+
1536+ level = NGX_LOG_ERR ;
1537+ rc = NGX_HTTP_NOT_FOUND ;
1538+ break ;
1539+
1540+ case NGX_EACCES :
1541+
1542+ level = NGX_LOG_ERR ;
1543+ rc = NGX_HTTP_FORBIDDEN ;
1544+ break ;
1545+
1546+ default :
1547+
1548+ level = NGX_LOG_CRIT ;
1549+ rc = NGX_HTTP_INTERNAL_SERVER_ERROR ;
1550+ break ;
1551+ }
1552+
1553+ if (rc != NGX_HTTP_NOT_FOUND || clcf -> log_not_found ) {
1554+ ngx_log_error (level , log , of .err , "%s \"%s\" failed" , of .failed ,
1555+ path .data );
1556+ }
1557+
1558+ return - rc ;
1559+ }
1560+
1561+ if (of .is_dir ) {
1562+ return - NGX_HTTP_NOT_FOUND ;
1563+ }
1564+
1565+ #if !(NGX_WIN32 ) /* the not regular files are probably Unix specific */
1566+
1567+ if (!of .is_file ) {
1568+ ngx_log_error (NGX_LOG_CRIT , log , 0 ,
1569+ "\"%s\" is not a regular file" , path .data );
1570+
1571+ return - NGX_HTTP_NOT_FOUND ;
1572+ }
1573+
1574+ #endif
1575+
1576+ r -> allow_ranges = 1 ;
1577+
1578+ b = ngx_pcalloc (r -> pool , sizeof (ngx_buf_t ));
1579+ if (b == NULL ) {
1580+ return - NGX_HTTP_INTERNAL_SERVER_ERROR ;
1581+ }
1582+
1583+ b -> file = ngx_pcalloc (r -> pool , sizeof (ngx_file_t ));
1584+ if (b -> file == NULL ) {
1585+ return - NGX_HTTP_INTERNAL_SERVER_ERROR ;
1586+ }
1587+
1588+ b -> file_pos = 0 ;
1589+ b -> file_last = of .size ;
1590+
1591+ b -> in_file = b -> file_last ? 1 : 0 ;
1592+
1593+ b -> file -> fd = of .fd ;
1594+ b -> file -> name = path ;
1595+ b -> file -> log = log ;
1596+ b -> file -> directio = of .is_directio ;
1597+
1598+ if (r -> headers_out .content_length_n < 0 ) {
1599+ r -> headers_out .content_length_n = of .size ;
1600+ } else {
1601+ r -> headers_out .content_length_n += of .size ;
1602+ }
1603+
1604+ if (r -> headers_out .last_modified_time != -2 && r -> headers_out .last_modified_time < of .mtime ) {
1605+ r -> headers_out .last_modified_time = of .mtime ;
1606+ }
1607+
1608+ cl = ngx_palloc (r -> pool , sizeof (ngx_chain_t ));
1609+ if (cl == NULL ) {
1610+ return 0 ;
1611+ }
1612+
1613+ cl -> buf = b ;
1614+
1615+ if (pre != NULL ) {
1616+ cl -> next = pre -> next ;
1617+ pre -> next = cl ;
1618+ b -> last_in_chain = pre -> buf -> last_in_chain ;
1619+ b -> last_buf = pre -> buf -> last_buf ;
1620+ pre -> buf -> last_in_chain = 0 ;
1621+ pre -> buf -> last_buf = 0 ;
1622+ }else {
1623+ cl -> next = NULL ;
1624+ b -> last_in_chain = 1 ;
1625+ b -> last_buf = 1 ;
1626+ }
1627+
1628+ return (uintptr_t )cl ;
1629+ }
1630+
13561631static jlong JNICALL jni_ngx_http_clojure_mem_get_obj_addr (JNIEnv * env , jclass cls , jobject obj ){
13571632 return obj ? (* (uintptr_t * )obj ) : 0 ;
13581633}
@@ -1473,7 +1748,7 @@ static void JNICALL jni_ngx_http_clojure_mem_continue_current_phase(JNIEnv *env,
14731748 ngx_http_request_t * req = (ngx_http_request_t * )(uintptr_t ) r ;
14741749 ngx_http_clojure_module_ctx_t * ctx = ngx_http_get_module_ctx (req , ngx_http_clojure_module );
14751750 ctx -> phrase = ~ctx -> phrase ;
1476- req -> write_event_handler (req );
1751+ ngx_http_core_run_phases (req );
14771752}
14781753
14791754static jlong JNICALL jni_ngx_http_clojure_mem_get_module_ctx_phase (JNIEnv * env , jclass cls , jlong r ) {
@@ -1889,12 +2164,16 @@ int ngx_http_clojure_init_memory_util(ngx_int_t jvm_workers, ngx_log_t *log) {
18892164 {"ngx_list_init" , "(JJJJ)J" , jni_ngx_list_init },
18902165 {"ngx_list_push" , "(J)J" , jni_ngx_list_push },
18912166 {"ngx_create_temp_buf" , "(JJ)J" , jni_ngx_create_temp_buf },
2167+ {"ngx_create_temp_buf_by_jstring" , "(JLjava/lang/String;I)J" , jni_ngx_create_temp_buf_by_jstring },
2168+ {"ngx_create_temp_buf_by_obj" , "(JLjava/lang/Object;JJI)J" , jni_ngx_create_temp_buf_by_obj }, //JNIEnv *env, jclass cls, jlong req, jobject obj, jlong offset, jlong len, jint last_buf
18922169 {"ngx_create_file_buf" , "(JJJI)J" , jni_ngx_create_file_buf },
18932170 {"ngx_http_set_content_type" , "(J)J" , jni_ngx_http_set_content_type },
18942171 {"ngx_http_send_header" , "(J)J" , jni_ngx_http_send_header },
18952172 {"ngx_http_output_filter" , "(JJ)J" , jni_ngx_http_output_filter },
18962173 {"ngx_http_finalize_request" , "(JJ)V" , jni_ngx_http_finalize_request },
18972174 {"ngx_http_clojure_mem_init_ngx_buf" , "(JLjava/lang/Object;JJI)J" , jni_ngx_http_clojure_mem_init_ngx_buf }, //jlong buf, jlong obj, jlong offset, jlong len, jint last_buf
2175+ {"ngx_http_clojure_mem_build_temp_chain" , "(JJLjava/lang/Object;JJ)J" , jni_ngx_http_clojure_mem_build_temp_chain },
2176+ {"ngx_http_clojure_mem_build_file_chain" , "(JJLjava/lang/Object;JJ)J" , jni_ngx_http_clojure_mem_build_file_chain } ,
18982177 {"ngx_http_clojure_mem_get_obj_addr" , "(Ljava/lang/Object;)J" , jni_ngx_http_clojure_mem_get_obj_addr },
18992178 {"ngx_http_clojure_mem_get_list_size" , "(J)J" , jni_ngx_http_clojure_mem_get_list_size },
19002179 {"ngx_http_clojure_mem_get_list_item" , "(JJ)J" , jni_ngx_http_clojure_mem_get_list_item },
0 commit comments