summaryrefslogtreecommitdiffhomepage
path: root/src/java/nxt_jni_Request.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/java/nxt_jni_Request.c')
-rw-r--r--src/java/nxt_jni_Request.c658
1 files changed, 658 insertions, 0 deletions
diff --git a/src/java/nxt_jni_Request.c b/src/java/nxt_jni_Request.c
new file mode 100644
index 00000000..6fb9cb44
--- /dev/null
+++ b/src/java/nxt_jni_Request.c
@@ -0,0 +1,658 @@
+
+/*
+ * Copyright (C) NGINX, Inc.
+ */
+
+#include <nxt_auto_config.h>
+
+#include <nxt_unit.h>
+#include <nxt_unit_request.h>
+#include <jni.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "nxt_jni.h"
+#include "nxt_jni_Request.h"
+#include "nxt_jni_URLClassLoader.h"
+#include "nxt_jni_HeadersEnumeration.h"
+#include "nxt_jni_HeaderNamesEnumeration.h"
+
+
+static jstring JNICALL nxt_java_Request_getHeader(JNIEnv *env, jclass cls,
+ jlong req_ptr, jstring name, jint name_len);
+static jobject JNICALL nxt_java_Request_getHeaderNames(JNIEnv *env, jclass cls,
+ jlong req_ptr);
+static jobject JNICALL nxt_java_Request_getHeaders(JNIEnv *env, jclass cls,
+ jlong req_ptr, jstring name, jint name_len);
+static jint JNICALL nxt_java_Request_getIntHeader(JNIEnv *env, jclass cls,
+ jlong req_ptr, jstring name, jint name_len);
+static jstring JNICALL nxt_java_Request_getMethod(JNIEnv *env, jclass cls,
+ jlong req_ptr);
+static jstring JNICALL nxt_java_Request_getQueryString(JNIEnv *env, jclass cls,
+ jlong req_ptr);
+static jstring JNICALL nxt_java_Request_getRequestURI(JNIEnv *env, jclass cls,
+ jlong req_ptr);
+static jlong JNICALL nxt_java_Request_getContentLength(JNIEnv *env, jclass cls,
+ jlong req_ptr);
+static jstring JNICALL nxt_java_Request_getContentType(JNIEnv *env, jclass cls,
+ jlong req_ptr);
+static jstring JNICALL nxt_java_Request_getLocalAddr(JNIEnv *env, jclass cls,
+ jlong req_ptr);
+static jstring JNICALL nxt_java_Request_getLocalName(JNIEnv *env, jclass cls,
+ jlong req_ptr);
+static jint JNICALL nxt_java_Request_getLocalPort(JNIEnv *env, jclass cls,
+ jlong req_ptr);
+static jstring JNICALL nxt_java_Request_getProtocol(JNIEnv *env, jclass cls,
+ jlong req_ptr);
+static jstring JNICALL nxt_java_Request_getRemoteAddr(JNIEnv *env, jclass cls,
+ jlong req_ptr);
+static jstring JNICALL nxt_java_Request_getRemoteHost(JNIEnv *env, jclass cls,
+ jlong req_ptr);
+static jint JNICALL nxt_java_Request_getRemotePort(JNIEnv *env, jclass cls,
+ jlong req_ptr);
+static jstring JNICALL nxt_java_Request_getScheme(JNIEnv *env, jclass cls,
+ jlong req_ptr);
+static jstring JNICALL nxt_java_Request_getServerName(JNIEnv *env, jclass cls,
+ jlong req_ptr);
+static jint JNICALL nxt_java_Request_getServerPort(JNIEnv *env, jclass cls,
+ jlong req_ptr);
+static void JNICALL nxt_java_Request_log(JNIEnv *env, jclass cls,
+ jlong req_info_ptr, jstring msg, jint msg_len);
+static void JNICALL nxt_java_Request_trace(JNIEnv *env, jclass cls,
+ jlong req_info_ptr, jstring msg, jint msg_len);
+static jobject JNICALL nxt_java_Request_getResponse(JNIEnv *env, jclass cls,
+ jlong req_info_ptr);
+
+
+static jclass nxt_java_Request_class;
+static jmethodID nxt_java_Request_ctor;
+
+
+int
+nxt_java_initRequest(JNIEnv *env, jobject cl)
+{
+ int res;
+ jclass cls;
+
+ cls = nxt_java_loadClass(env, cl, "nginx.unit.Request");
+ if (cls == NULL) {
+ return NXT_UNIT_ERROR;
+ }
+
+ nxt_java_Request_class = (*env)->NewGlobalRef(env, cls);
+ (*env)->DeleteLocalRef(env, cls);
+ cls = nxt_java_Request_class;
+
+ nxt_java_Request_ctor = (*env)->GetMethodID(env, cls, "<init>", "(Lnginx/unit/Context;JJ)V");
+ if (nxt_java_Request_ctor == NULL) {
+ (*env)->DeleteGlobalRef(env, cls);
+ return NXT_UNIT_ERROR;
+ }
+
+ JNINativeMethod request_methods[] = {
+ { (char *) "getHeader",
+ (char *) "(JLjava/lang/String;I)Ljava/lang/String;",
+ nxt_java_Request_getHeader },
+
+ { (char *) "getHeaderNames",
+ (char *) "(J)Ljava/util/Enumeration;",
+ nxt_java_Request_getHeaderNames },
+
+ { (char *) "getHeaders",
+ (char *) "(JLjava/lang/String;I)Ljava/util/Enumeration;",
+ nxt_java_Request_getHeaders },
+
+ { (char *) "getIntHeader",
+ (char *) "(JLjava/lang/String;I)I",
+ nxt_java_Request_getIntHeader },
+
+ { (char *) "getMethod",
+ (char *) "(J)Ljava/lang/String;",
+ nxt_java_Request_getMethod },
+
+ { (char *) "getQueryString",
+ (char *) "(J)Ljava/lang/String;",
+ nxt_java_Request_getQueryString },
+
+ { (char *) "getRequestURI",
+ (char *) "(J)Ljava/lang/String;",
+ nxt_java_Request_getRequestURI },
+
+ { (char *) "getContentLength",
+ (char *) "(J)J",
+ nxt_java_Request_getContentLength },
+
+ { (char *) "getContentType",
+ (char *) "(J)Ljava/lang/String;",
+ nxt_java_Request_getContentType },
+
+ { (char *) "getLocalAddr",
+ (char *) "(J)Ljava/lang/String;",
+ nxt_java_Request_getLocalAddr },
+
+ { (char *) "getLocalName",
+ (char *) "(J)Ljava/lang/String;",
+ nxt_java_Request_getLocalName },
+
+ { (char *) "getLocalPort",
+ (char *) "(J)I",
+ nxt_java_Request_getLocalPort },
+
+ { (char *) "getProtocol",
+ (char *) "(J)Ljava/lang/String;",
+ nxt_java_Request_getProtocol },
+
+ { (char *) "getRemoteAddr",
+ (char *) "(J)Ljava/lang/String;",
+ nxt_java_Request_getRemoteAddr },
+
+ { (char *) "getRemoteHost",
+ (char *) "(J)Ljava/lang/String;",
+ nxt_java_Request_getRemoteHost },
+
+ { (char *) "getRemotePort",
+ (char *) "(J)I",
+ nxt_java_Request_getRemotePort },
+
+ { (char *) "getScheme",
+ (char *) "(J)Ljava/lang/String;",
+ nxt_java_Request_getScheme },
+
+ { (char *) "getServerName",
+ (char *) "(J)Ljava/lang/String;",
+ nxt_java_Request_getServerName },
+
+ { (char *) "getServerPort",
+ (char *) "(J)I",
+ nxt_java_Request_getServerPort },
+
+ { (char *) "log",
+ (char *) "(JLjava/lang/String;I)V",
+ nxt_java_Request_log },
+
+ { (char *) "trace",
+ (char *) "(JLjava/lang/String;I)V",
+ nxt_java_Request_trace },
+
+ { (char *) "getResponse",
+ (char *) "(J)Lnginx/unit/Response;",
+ nxt_java_Request_getResponse },
+
+ };
+
+ res = (*env)->RegisterNatives(env, nxt_java_Request_class,
+ request_methods,
+ sizeof(request_methods) / sizeof(request_methods[0]));
+
+ nxt_unit_debug(NULL, "registered Request methods: %d", res);
+
+ if (res != 0) {
+ nxt_unit_warn(NULL, "registering natives for Request failed");
+ goto failed;
+ }
+
+ res = nxt_java_initHeadersEnumeration(env, cl);
+ if (res != NXT_UNIT_OK) {
+ goto failed;
+ }
+
+ res = nxt_java_initHeaderNamesEnumeration(env, cl);
+ if (res != NXT_UNIT_OK) {
+ goto failed;
+ }
+
+ return NXT_UNIT_OK;
+
+failed:
+
+ (*env)->DeleteGlobalRef(env, cls);
+ return NXT_UNIT_ERROR;
+}
+
+
+jobject
+nxt_java_newRequest(JNIEnv *env, jobject ctx, nxt_unit_request_info_t *req)
+{
+ return (*env)->NewObject(env, nxt_java_Request_class,
+ nxt_java_Request_ctor, ctx, nxt_ptr2jlong(req),
+ nxt_ptr2jlong(req->request));
+}
+
+
+static jstring JNICALL
+nxt_java_Request_getHeader(JNIEnv *env, jclass cls, jlong req_ptr,
+ jstring name, jint name_len)
+{
+ const char *name_str;
+ nxt_unit_field_t *f;
+ nxt_unit_request_t *r;
+
+ name_str = (*env)->GetStringUTFChars(env, name, NULL);
+ if (name_str == NULL) {
+ return NULL;
+ }
+
+ r = nxt_jlong2ptr(req_ptr);
+
+ f = nxt_java_findHeader(r->fields, r->fields + r->fields_count,
+ name_str, name_len);
+
+ (*env)->ReleaseStringUTFChars(env, name, name_str);
+
+ if (f == NULL) {
+ return NULL;
+ }
+
+ return (*env)->NewStringUTF(env, nxt_unit_sptr_get(&f->value));
+}
+
+
+static jobject JNICALL
+nxt_java_Request_getHeaderNames(JNIEnv *env, jclass cls, jlong req_ptr)
+{
+ nxt_unit_request_t *r;
+
+ r = nxt_jlong2ptr(req_ptr);
+
+ return nxt_java_newHeaderNamesEnumeration(env, r->fields, r->fields_count);
+}
+
+
+static jobject JNICALL
+nxt_java_Request_getHeaders(JNIEnv *env, jclass cls, jlong req_ptr,
+ jstring name, jint name_len)
+{
+ const char *name_str;
+ nxt_unit_field_t *f;
+ nxt_unit_request_t *r;
+
+ name_str = (*env)->GetStringUTFChars(env, name, NULL);
+ if (name_str == NULL) {
+ return NULL;
+ }
+
+ r = nxt_jlong2ptr(req_ptr);
+
+ f = nxt_java_findHeader(r->fields, r->fields + r->fields_count,
+ name_str, name_len);
+
+ (*env)->ReleaseStringUTFChars(env, name, name_str);
+
+ if (f == NULL) {
+ f = r->fields + r->fields_count;
+ }
+
+ return nxt_java_newHeadersEnumeration(env, r->fields, r->fields_count,
+ f - r->fields);
+}
+
+
+static jint JNICALL
+nxt_java_Request_getIntHeader(JNIEnv *env, jclass cls, jlong req_ptr,
+ jstring name, jint name_len)
+{
+ jint res;
+ char *value, *end;
+ const char *name_str;
+ nxt_unit_field_t *f;
+ nxt_unit_request_t *r;
+
+ res = -1;
+
+ name_str = (*env)->GetStringUTFChars(env, name, NULL);
+ if (name_str == NULL) {
+ return res;
+ }
+
+ r = nxt_jlong2ptr(req_ptr);
+
+ f = nxt_java_findHeader(r->fields, r->fields + r->fields_count,
+ name_str, name_len);
+
+ (*env)->ReleaseStringUTFChars(env, name, name_str);
+
+ if (f == NULL) {
+ return res;
+ }
+
+ value = nxt_unit_sptr_get(&f->value);
+ end = value + f->value_length;
+
+ res = strtol(value, &end, 10);
+
+ if (end < value + f->value_length) {
+ // TODO throw NumberFormatException.forInputString(value)
+ }
+
+ return res;
+}
+
+
+static jstring JNICALL
+nxt_java_Request_getMethod(JNIEnv *env, jclass cls, jlong req_ptr)
+{
+ nxt_unit_request_t *r;
+
+ r = nxt_jlong2ptr(req_ptr);
+
+ return (*env)->NewStringUTF(env, nxt_unit_sptr_get(&r->method));
+}
+
+
+static jstring JNICALL
+nxt_java_Request_getQueryString(JNIEnv *env, jclass cls, jlong req_ptr)
+{
+ char *query;
+ nxt_unit_request_t *r;
+
+ r = nxt_jlong2ptr(req_ptr);
+
+ if (r->query.offset != 0) {
+ query = nxt_unit_sptr_get(&r->query);
+ return (*env)->NewStringUTF(env, query);
+ }
+
+ return NULL;
+}
+
+
+static jstring JNICALL
+nxt_java_Request_getRequestURI(JNIEnv *env, jclass cls, jlong req_ptr)
+{
+ char *target, *query;
+ nxt_unit_request_t *r;
+
+ r = nxt_jlong2ptr(req_ptr);
+
+ target = nxt_unit_sptr_get(&r->target);
+
+ if (r->query.offset != 0) {
+ query = nxt_unit_sptr_get(&r->query);
+ return nxt_java_newString(env, target, query - target - 1);
+ }
+
+ return (*env)->NewStringUTF(env, target);
+}
+
+
+static jlong JNICALL
+nxt_java_Request_getContentLength(JNIEnv *env, jclass cls, jlong req_ptr)
+{
+ nxt_unit_request_t *r;
+
+ r = nxt_jlong2ptr(req_ptr);
+
+ return r->content_length;
+}
+
+
+static jstring JNICALL
+nxt_java_Request_getContentType(JNIEnv *env, jclass cls, jlong req_ptr)
+{
+ nxt_unit_field_t *f;
+ nxt_unit_request_t *r;
+
+ r = nxt_jlong2ptr(req_ptr);
+
+ if (r->content_type_field != NXT_UNIT_NONE_FIELD) {
+ f = r->fields + r->content_type_field;
+
+ return (*env)->NewStringUTF(env, nxt_unit_sptr_get(&f->value));
+ }
+
+ return NULL;
+}
+
+
+static jstring JNICALL
+nxt_java_Request_getLocalAddr(JNIEnv *env, jclass cls, jlong req_ptr)
+{
+ nxt_unit_request_t *r;
+
+ r = nxt_jlong2ptr(req_ptr);
+
+ return nxt_java_newString(env, nxt_unit_sptr_get(&r->local),
+ r->local_length);
+}
+
+
+static jstring JNICALL
+nxt_java_Request_getLocalName(JNIEnv *env, jclass cls, jlong req_ptr)
+{
+ char *local, *colon;
+ nxt_unit_request_t *r;
+
+ r = nxt_jlong2ptr(req_ptr);
+
+ local = nxt_unit_sptr_get(&r->local);
+ colon = memchr(local, ':', r->local_length);
+
+ if (colon == NULL) {
+ colon = local + r->local_length;
+ }
+
+ return nxt_java_newString(env, local, colon - local);
+}
+
+
+static jint JNICALL
+nxt_java_Request_getLocalPort(JNIEnv *env, jclass cls, jlong req_ptr)
+{
+ jint res;
+ char *local, *colon, tmp;
+ nxt_unit_request_t *r;
+
+ r = nxt_jlong2ptr(req_ptr);
+
+ local = nxt_unit_sptr_get(&r->local);
+ colon = memchr(local, ':', r->local_length);
+
+ if (colon == NULL) {
+ return 80;
+ }
+
+ tmp = local[r->local_length];
+
+ local[r->local_length] = '\0';
+
+ res = strtol(colon + 1, NULL, 10);
+
+ local[r->local_length] = tmp;
+
+ return res;
+}
+
+
+static jstring JNICALL
+nxt_java_Request_getProtocol(JNIEnv *env, jclass cls, jlong req_ptr)
+{
+ nxt_unit_request_t *r;
+
+ r = nxt_jlong2ptr(req_ptr);
+
+ return (*env)->NewStringUTF(env, nxt_unit_sptr_get(&r->version));
+}
+
+
+static jstring JNICALL
+nxt_java_Request_getRemoteAddr(JNIEnv *env, jclass cls, jlong req_ptr)
+{
+ nxt_unit_request_t *r;
+
+ r = nxt_jlong2ptr(req_ptr);
+
+ return nxt_java_newString(env, nxt_unit_sptr_get(&r->remote),
+ r->remote_length);
+}
+
+
+static jstring JNICALL
+nxt_java_Request_getRemoteHost(JNIEnv *env, jclass cls, jlong req_ptr)
+{
+ char *remote, *colon;
+ nxt_unit_request_t *r;
+
+ r = nxt_jlong2ptr(req_ptr);
+
+ remote = nxt_unit_sptr_get(&r->remote);
+ colon = memchr(remote, ':', r->remote_length);
+
+ if (colon == NULL) {
+ colon = remote + r->remote_length;
+ }
+
+ return nxt_java_newString(env, remote, colon - remote);
+}
+
+
+static jint JNICALL
+nxt_java_Request_getRemotePort(JNIEnv *env, jclass cls, jlong req_ptr)
+{
+ jint res;
+ char *remote, *colon, tmp;
+ nxt_unit_request_t *r;
+
+ r = nxt_jlong2ptr(req_ptr);
+
+ remote = nxt_unit_sptr_get(&r->remote);
+ colon = memchr(remote, ':', r->remote_length);
+
+ if (colon == NULL) {
+ return 80;
+ }
+
+ tmp = remote[r->remote_length];
+
+ remote[r->remote_length] = '\0';
+
+ res = strtol(colon + 1, NULL, 10);
+
+ remote[r->remote_length] = tmp;
+
+ return res;
+}
+
+
+static jstring JNICALL
+nxt_java_Request_getScheme(JNIEnv *env, jclass cls, jlong req_ptr)
+{
+ return (*env)->NewStringUTF(env, "http");
+}
+
+
+static jstring JNICALL
+nxt_java_Request_getServerName(JNIEnv *env, jclass cls, jlong req_ptr)
+{
+ char *host, *colon;
+ nxt_unit_field_t *f;
+ nxt_unit_request_t *r;
+
+ r = nxt_jlong2ptr(req_ptr);
+
+ f = nxt_java_findHeader(r->fields, r->fields + r->fields_count,
+ "Host", 4);
+ if (f != NULL) {
+ host = nxt_unit_sptr_get(&f->value);
+
+ colon = memchr(host, ':', f->value_length);
+
+ if (colon == NULL) {
+ colon = host + f->value_length;
+ }
+
+ return nxt_java_newString(env, host, colon - host);
+ }
+
+ return nxt_java_Request_getLocalName(env, cls, req_ptr);
+}
+
+
+static jint JNICALL
+nxt_java_Request_getServerPort(JNIEnv *env, jclass cls, jlong req_ptr)
+{
+ jint res;
+ char *host, *colon, tmp;
+ nxt_unit_field_t *f;
+ nxt_unit_request_t *r;
+
+ r = nxt_jlong2ptr(req_ptr);
+
+ f = nxt_java_findHeader(r->fields, r->fields + r->fields_count,
+ "Host", 4);
+ if (f != NULL) {
+ host = nxt_unit_sptr_get(&f->value);
+
+ colon = memchr(host, ':', f->value_length);
+
+ if (colon == NULL) {
+ return 80;
+ }
+
+ tmp = host[f->value_length];
+
+ host[f->value_length] = '\0';
+
+ res = strtol(colon + 1, NULL, 10);
+
+ host[f->value_length] = tmp;
+
+ return res;
+ }
+
+ return nxt_java_Request_getLocalPort(env, cls, req_ptr);
+}
+
+
+static void JNICALL
+nxt_java_Request_log(JNIEnv *env, jclass cls, jlong req_info_ptr, jstring msg,
+ jint msg_len)
+{
+ const char *msg_str;
+ nxt_unit_request_info_t *req;
+
+ req = nxt_jlong2ptr(req_info_ptr);
+
+ msg_str = (*env)->GetStringUTFChars(env, msg, NULL);
+ if (msg_str == NULL) {
+ return;
+ }
+
+ nxt_unit_req_log(req, NXT_UNIT_LOG_INFO, "%.*s", msg_len, msg_str);
+
+ (*env)->ReleaseStringUTFChars(env, msg, msg_str);
+}
+
+
+static void JNICALL
+nxt_java_Request_trace(JNIEnv *env, jclass cls, jlong req_info_ptr, jstring msg,
+ jint msg_len)
+{
+#if (NXT_DEBUG)
+ const char *msg_str;
+ nxt_unit_request_info_t *req;
+
+ req = nxt_jlong2ptr(req_info_ptr);
+
+ msg_str = (*env)->GetStringUTFChars(env, msg, NULL);
+ if (msg_str == NULL) {
+ return;
+ }
+
+ nxt_unit_req_debug(req, "%.*s", msg_len, msg_str);
+
+ (*env)->ReleaseStringUTFChars(env, msg, msg_str);
+#endif
+}
+
+
+static jobject JNICALL
+nxt_java_Request_getResponse(JNIEnv *env, jclass cls, jlong req_info_ptr)
+{
+ nxt_unit_request_info_t *req;
+ nxt_java_request_data_t *data;
+
+ req = nxt_jlong2ptr(req_info_ptr);
+ data = req->data;
+
+ return data->jresp;
+}