mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-08-22 05:25:48 +00:00
completed status and headers management for the ring plugin
This commit is contained in:
@@ -14,6 +14,8 @@ struct uwsgi_jvm {
|
||||
struct uwsgi_string_list *main_classes;
|
||||
|
||||
jclass str_class;
|
||||
jclass long_class;
|
||||
jclass int_class;
|
||||
jclass hashmap_class;
|
||||
jclass set_class;
|
||||
jclass iterator_class;
|
||||
@@ -62,3 +64,13 @@ int uwsgi_jvm_iterator_hasNext(jobject);
|
||||
jobject uwsgi_jvm_iterator_next(jobject);
|
||||
|
||||
jobject uwsgi_jvm_iterator(jobject);
|
||||
jobject uwsgi_jvm_auto_iterator(jobject);
|
||||
|
||||
jobject uwsgi_jvm_getKey(jobject);
|
||||
jobject uwsgi_jvm_getValue(jobject);
|
||||
|
||||
size_t uwsgi_jvm_strlen(jobject);
|
||||
long uwsgi_jvm_number2c(jobject);
|
||||
|
||||
long uwsgi_jvm_int2c(jobject);
|
||||
long uwsgi_jvm_long2c(jobject);
|
||||
|
||||
@@ -117,6 +117,45 @@ jobject uwsgi_jvm_object_class_name(jobject o) {
|
||||
return uwsgi_jvm_call_object(oc, mid);
|
||||
}
|
||||
|
||||
long uwsgi_jvm_int2c(jobject o) {
|
||||
static jmethodID mid = 0;
|
||||
if (!mid) {
|
||||
mid = uwsgi_jvm_get_method_id(ujvm.int_class, "intValue", "()I");
|
||||
if (!mid) return -1 ;
|
||||
}
|
||||
long value = (*ujvm_env)->CallIntMethod(ujvm_env, o, mid);
|
||||
if (uwsgi_jvm_exception()) {
|
||||
return -1;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
long uwsgi_jvm_long2c(jobject o) {
|
||||
static jmethodID mid = 0;
|
||||
if (!mid) {
|
||||
mid = uwsgi_jvm_get_method_id(ujvm.long_class, "longValue", "()J");
|
||||
if (!mid) return -1;
|
||||
}
|
||||
long value = (*ujvm_env)->CallLongMethod(ujvm_env, o, mid);
|
||||
if (uwsgi_jvm_exception()) {
|
||||
return -1;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
long uwsgi_jvm_number2c(jobject o) {
|
||||
if (uwsgi_jvm_object_is_instance(o, ujvm.int_class)) {
|
||||
return uwsgi_jvm_int2c(o);
|
||||
}
|
||||
|
||||
if (uwsgi_jvm_object_is_instance(o, ujvm.long_class)) {
|
||||
return uwsgi_jvm_long2c(o);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// returns the method id, given the method name and its signature
|
||||
jmethodID uwsgi_jvm_get_method_id(jclass cls, char *name, char *signature) {
|
||||
jmethodID mid = (*ujvm_env)->GetMethodID(ujvm_env, cls, name, signature);
|
||||
@@ -193,6 +232,30 @@ jobject uwsgi_jvm_iterator(jobject set) {
|
||||
return uwsgi_jvm_call_object(set, mid);
|
||||
}
|
||||
|
||||
jobject uwsgi_jvm_auto_iterator(jobject o) {
|
||||
jclass c = uwsgi_jvm_class_from_object(o);
|
||||
if (!c) return NULL;
|
||||
jmethodID mid = uwsgi_jvm_get_method_id(c, "iterator", "()Ljava/util/Iterator;");
|
||||
if (!mid) return NULL;
|
||||
return uwsgi_jvm_call_object(o, mid);
|
||||
}
|
||||
|
||||
jobject uwsgi_jvm_getKey(jobject item) {
|
||||
jclass c = uwsgi_jvm_class_from_object(item);
|
||||
if (!c) return NULL;
|
||||
jmethodID mid = uwsgi_jvm_get_method_id(c, "getKey", "()Ljava/lang/Object;");
|
||||
if (!mid) return NULL;
|
||||
return uwsgi_jvm_call_object(item, mid);
|
||||
}
|
||||
|
||||
jobject uwsgi_jvm_getValue(jobject item) {
|
||||
jclass c = uwsgi_jvm_class_from_object(item);
|
||||
if (!c) return NULL;
|
||||
jmethodID mid = uwsgi_jvm_get_method_id(c, "getValue", "()Ljava/lang/Object;");
|
||||
if (!mid) return NULL;
|
||||
return uwsgi_jvm_call_object(item, mid);
|
||||
}
|
||||
|
||||
int uwsgi_jvm_iterator_hasNext(jobject iterator) {
|
||||
// optimization
|
||||
static jmethodID mid = 0;
|
||||
@@ -350,6 +413,12 @@ static void uwsgi_jvm_create(void) {
|
||||
ujvm.str_class = uwsgi_jvm_class("java/lang/String");
|
||||
if (!ujvm.str_class) exit(1);
|
||||
|
||||
ujvm.int_class = uwsgi_jvm_class("java/lang/Integer");
|
||||
if (!ujvm.int_class) exit(1);
|
||||
|
||||
ujvm.long_class = uwsgi_jvm_class("java/lang/Long");
|
||||
if (!ujvm.long_class) exit(1);
|
||||
|
||||
ujvm.hashmap_class = uwsgi_jvm_class("java/util/HashMap");
|
||||
if (!ujvm.hashmap_class) exit(1);
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#define UWSGI_JVM_REQUEST_HANDLER_RING 1
|
||||
|
||||
extern struct uwsgi_jvm ujvm;
|
||||
|
||||
struct uwsgi_ring {
|
||||
char *app;
|
||||
jobject handler;
|
||||
@@ -14,6 +16,9 @@ struct uwsgi_ring {
|
||||
jclass PersistentArrayMap;
|
||||
jmethodID PersistentArrayMap_get;
|
||||
jmethodID PersistentArrayMap_entrySet;
|
||||
|
||||
jclass PersistentVector;
|
||||
jclass PersistentList;
|
||||
} uring;
|
||||
|
||||
static struct uwsgi_option uwsgi_ring_options[] = {
|
||||
@@ -65,6 +70,7 @@ static jobject uwsgi_ring_header_get(jobject headers, jobject key) {
|
||||
}
|
||||
|
||||
static int uwsgi_ring_request(struct wsgi_request *wsgi_req) {
|
||||
char status_str[1];
|
||||
uwsgi_log("managing ring request\n");
|
||||
jobject hm = uwsgi_jvm_hashmap();
|
||||
if (!hm) return -1;
|
||||
@@ -83,21 +89,77 @@ static int uwsgi_ring_request(struct wsgi_request *wsgi_req) {
|
||||
jobject r_status = uwsgi_ring_response_get(response, "status", 6);
|
||||
if (!r_status) goto error;
|
||||
|
||||
if (!uwsgi_jvm_object_is_instance(r_status, ujvm.long_class) && !uwsgi_jvm_object_is_instance(r_status, ujvm.int_class)) {
|
||||
uwsgi_log("invalid ring response status type, must be: java.lang.Long\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
long n_status = uwsgi_jvm_number2c(r_status);
|
||||
if (n_status == -1) goto error;
|
||||
|
||||
if (uwsgi_num2str2(n_status, status_str) != 3) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (uwsgi_response_prepare_headers(wsgi_req, status_str, 3)) goto error;
|
||||
|
||||
jobject r_headers = uwsgi_ring_response_get(response, "headers", 7);
|
||||
if (!r_headers) goto error;
|
||||
|
||||
char *cn = uwsgi_jvm_str2c( uwsgi_jvm_object_class_name(r_headers) );
|
||||
uwsgi_log("headers type = %s\n", cn);
|
||||
|
||||
cn = uwsgi_jvm_str2c( uwsgi_jvm_object_class_name(r_status) );
|
||||
uwsgi_log("status type = %s\n", cn);
|
||||
if (!uwsgi_jvm_object_is_instance(r_headers, uring.PersistentArrayMap)) {
|
||||
uwsgi_log("invalid ring response headers type, must be: clojure.lang.PersistentArrayMap\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
jobject entries = uwsgi_ring_PersistentArrayMap_iterator(r_headers);
|
||||
if (!entries) goto error;
|
||||
|
||||
while(uwsgi_jvm_iterator_hasNext(entries)) {
|
||||
jobject hh = uwsgi_jvm_iterator_next(entries);
|
||||
uwsgi_log("hh = %p\n", hh);
|
||||
if (!hh) goto error;
|
||||
jobject h_key = uwsgi_jvm_getKey(hh);
|
||||
if (!h_key) goto error;
|
||||
jobject h_value = uwsgi_jvm_getValue(hh);
|
||||
if (!h_value) goto error;
|
||||
|
||||
if (!uwsgi_jvm_object_is_instance(h_key, ujvm.str_class)) {
|
||||
uwsgi_log("headers key must be java/lang/String !!!\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (uwsgi_jvm_object_is_instance(h_value, ujvm.str_class)) {
|
||||
char *c_h_key = uwsgi_jvm_str2c(h_key);
|
||||
uint16_t c_h_keylen = uwsgi_jvm_strlen(h_key);
|
||||
char *c_h_value = uwsgi_jvm_str2c(h_value);
|
||||
uint16_t c_h_vallen = uwsgi_jvm_strlen(h_value);
|
||||
int ret = uwsgi_response_add_header(wsgi_req, c_h_key, c_h_keylen, c_h_value, c_h_vallen);
|
||||
uwsgi_jvm_release_chars(h_key, c_h_key);
|
||||
uwsgi_jvm_release_chars(h_value, c_h_value);
|
||||
if (ret) goto error;
|
||||
}
|
||||
else if (uwsgi_jvm_object_is_instance(h_value, uring.PersistentVector) || uwsgi_jvm_object_is_instance(h_value, uring.PersistentList)) {
|
||||
jobject values = uwsgi_jvm_auto_iterator(h_value);
|
||||
if (!values) goto error;
|
||||
while(uwsgi_jvm_iterator_hasNext(values)) {
|
||||
jobject hh_value = uwsgi_jvm_iterator_next(values);
|
||||
if (!uwsgi_jvm_object_is_instance(hh_value, ujvm.str_class)) {
|
||||
uwsgi_log("headers value must be java/lang/String !!!\n");
|
||||
goto error;
|
||||
}
|
||||
char *c_h_key = uwsgi_jvm_str2c(h_key);
|
||||
uint16_t c_h_keylen = uwsgi_jvm_strlen(h_key);
|
||||
char *c_h_value = uwsgi_jvm_str2c(hh_value);
|
||||
uint16_t c_h_vallen = uwsgi_jvm_strlen(hh_value);
|
||||
int ret = uwsgi_response_add_header(wsgi_req, c_h_key, c_h_keylen, c_h_value, c_h_vallen);
|
||||
uwsgi_jvm_release_chars(h_key, c_h_key);
|
||||
uwsgi_jvm_release_chars(hh_value, c_h_value);
|
||||
if (ret) goto error;
|
||||
}
|
||||
}
|
||||
else {
|
||||
uwsgi_log("unsupported header value !!! (must be java/lang/String, clojure/lang/PersistentVector or clojure/lang/PersistentList)\n");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
jobject ct = uwsgi_ring_header_get(r_headers, uwsgi_jvm_str("Content-Type", 0));
|
||||
if (!ct) {
|
||||
@@ -132,6 +194,16 @@ static int uwsgi_ring_setup() {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uring.PersistentVector = uwsgi_jvm_class("clojure/lang/PersistentVector");
|
||||
if (!uring.PersistentVector) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uring.PersistentList = uwsgi_jvm_class("clojure/lang/PersistentList");
|
||||
if (!uring.PersistentList) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
jmethodID clojure_loadresourcescript = uwsgi_jvm_get_static_method_id(clojure, "loadResourceScript", "(Ljava/lang/String;)V");
|
||||
if (!clojure_loadresourcescript) {
|
||||
exit(1);
|
||||
|
||||
Reference in New Issue
Block a user