mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-06-15 18:05:50 +00:00
ported JWSGI to the new stable api and refactored ring plugin
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
[uwsgi]
|
||||
main_plugin = jvm,jwsgi
|
||||
inherit = base
|
||||
@@ -17,6 +17,7 @@ struct uwsgi_jvm {
|
||||
jclass request_body_class;
|
||||
|
||||
jclass str_class;
|
||||
jclass str_array_class;
|
||||
jclass long_class;
|
||||
jclass int_class;
|
||||
jclass byte_class;
|
||||
@@ -96,3 +97,9 @@ jobject uwsgi_jvm_num(long);
|
||||
jobject uwsgi_jvm_request_body_input_stream(void);
|
||||
|
||||
size_t uwsgi_jvm_array_len(jobject);
|
||||
jobject uwsgi_jvm_array_get(jobject, long);
|
||||
|
||||
int uwsgi_jvm_iterator_to_response_headers(struct wsgi_request *, jobject);
|
||||
jobject uwsgi_jvm_entryset(jobject);
|
||||
|
||||
int uwsgi_jvm_object_to_response_body(struct wsgi_request *, jobject);
|
||||
|
||||
@@ -105,6 +105,189 @@ static struct uwsgi_option uwsgi_jvm_options[] = {
|
||||
{0, 0, 0, 0},
|
||||
};
|
||||
|
||||
jobject uwsgi_jvm_entryset(jobject o) {
|
||||
jclass c = uwsgi_jvm_class_from_object(o);
|
||||
if (!c) return NULL;
|
||||
jmethodID mid = uwsgi_jvm_get_method_id(c, "entrySet", "()Ljava/util/Set;");
|
||||
uwsgi_jvm_local_unref(c);
|
||||
if (!mid) return NULL;
|
||||
return uwsgi_jvm_call_object(o, mid);
|
||||
}
|
||||
|
||||
int uwsgi_jvm_object_to_response_body(struct wsgi_request *wsgi_req, jobject body) {
|
||||
|
||||
// check for string
|
||||
if (uwsgi_jvm_object_is_instance(body, ujvm.str_class)) {
|
||||
char *c_body = uwsgi_jvm_str2c(body);
|
||||
size_t c_body_len = uwsgi_jvm_strlen(body);
|
||||
uwsgi_response_write_body_do(wsgi_req, c_body, c_body_len);
|
||||
uwsgi_jvm_release_chars(body, c_body);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// check for string array
|
||||
if (uwsgi_jvm_object_is_instance(body, ujvm.str_array_class)) {
|
||||
size_t items = uwsgi_jvm_array_len(body);
|
||||
size_t i;
|
||||
for(i=0;i<items;i++) {
|
||||
jobject chunk = uwsgi_jvm_array_get(body, i);
|
||||
if (!chunk) return 0;
|
||||
if (!uwsgi_jvm_object_is_instance(chunk, ujvm.str_class)) {
|
||||
uwsgi_log("body array item must be java/lang/String !!!\n");
|
||||
uwsgi_jvm_local_unref(chunk);
|
||||
return 0;
|
||||
}
|
||||
char *c_body = uwsgi_jvm_str2c(chunk);
|
||||
size_t c_body_len = uwsgi_jvm_strlen(chunk);
|
||||
int ret = uwsgi_response_write_body_do(wsgi_req, c_body, c_body_len);
|
||||
uwsgi_jvm_release_chars(chunk, c_body);
|
||||
uwsgi_jvm_local_unref(chunk);
|
||||
if (ret) return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// check for iterable
|
||||
jobject chunks = uwsgi_jvm_auto_iterator(body);
|
||||
if (chunks) {
|
||||
while(uwsgi_jvm_iterator_hasNext(chunks)) {
|
||||
jobject chunk = uwsgi_jvm_iterator_next(chunks);
|
||||
if (!chunk) goto done;
|
||||
if (!uwsgi_jvm_object_is_instance(chunk, ujvm.str_class)) {
|
||||
uwsgi_log("body iterable item must be java/lang/String !!!\n");
|
||||
uwsgi_jvm_local_unref(chunk);
|
||||
goto done;
|
||||
}
|
||||
char *c_body = uwsgi_jvm_str2c(chunk);
|
||||
size_t c_body_len = uwsgi_jvm_strlen(chunk);
|
||||
int ret = uwsgi_response_write_body_do(wsgi_req, c_body, c_body_len);
|
||||
uwsgi_jvm_release_chars(chunk, c_body);
|
||||
uwsgi_jvm_local_unref(chunk);
|
||||
if (ret) goto done;
|
||||
}
|
||||
done:
|
||||
uwsgi_jvm_local_unref(chunks);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (uwsgi_jvm_object_is_instance(body, ujvm.file_class)) {
|
||||
jobject j_filename = uwsgi_jvm_filename(body);
|
||||
if (!j_filename) return 0;
|
||||
char *c_filename = uwsgi_jvm_str2c(j_filename);
|
||||
int fd = open(c_filename, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
uwsgi_error("java/io/File.open()");
|
||||
goto done2;
|
||||
}
|
||||
uwsgi_response_sendfile_do(wsgi_req, fd, 0, 0);
|
||||
done2:
|
||||
uwsgi_jvm_release_chars(j_filename, c_filename);
|
||||
uwsgi_jvm_local_unref(j_filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (uwsgi_jvm_object_is_instance(body, ujvm.input_stream_class)) {
|
||||
uwsgi_jvm_consume_input_stream(wsgi_req, 8192, body);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int uwsgi_jvm_iterator_to_response_headers(struct wsgi_request *wsgi_req, jobject headers) {
|
||||
int error = 0;
|
||||
while(uwsgi_jvm_iterator_hasNext(headers)) {
|
||||
jobject hh = NULL, h_key = NULL, h_value = NULL;
|
||||
|
||||
hh = uwsgi_jvm_iterator_next(headers);
|
||||
|
||||
if (!hh) { error = 1 ; goto clear;}
|
||||
h_key = uwsgi_jvm_getKey(hh);
|
||||
if (!h_key) { error = 1 ; goto clear;}
|
||||
h_value = uwsgi_jvm_getValue(hh);
|
||||
if (!h_value) { error = 1 ; goto clear;}
|
||||
|
||||
|
||||
if (!uwsgi_jvm_object_is_instance(h_key, ujvm.str_class)) {
|
||||
uwsgi_log("headers key must be java/lang/String !!!\n");
|
||||
error = 1 ; goto clear;
|
||||
}
|
||||
|
||||
// check for string
|
||||
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) error = 1;
|
||||
goto clear;
|
||||
}
|
||||
|
||||
// check for string array
|
||||
if (uwsgi_jvm_object_is_instance(h_value, ujvm.str_array_class)) {
|
||||
size_t items = uwsgi_jvm_array_len(h_value);
|
||||
size_t i;
|
||||
for(i=0;i<items;i++) {
|
||||
jobject hh_value = uwsgi_jvm_array_get(h_value, i);
|
||||
if (!uwsgi_jvm_object_is_instance(hh_value, ujvm.str_class)) {
|
||||
uwsgi_log("headers value must be java/lang/String !!!\n");
|
||||
uwsgi_jvm_local_unref(hh_value);
|
||||
error = 1 ; goto clear;
|
||||
}
|
||||
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);
|
||||
uwsgi_jvm_local_unref(hh_value);
|
||||
if (ret) { error = 1 ; goto clear;}
|
||||
}
|
||||
goto clear;
|
||||
}
|
||||
|
||||
// check for iterable
|
||||
jobject values = uwsgi_jvm_auto_iterator(h_value);
|
||||
if (values) {
|
||||
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");
|
||||
uwsgi_jvm_local_unref(hh_value);
|
||||
uwsgi_jvm_local_unref(values);
|
||||
error = 1 ; goto clear;
|
||||
}
|
||||
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);
|
||||
uwsgi_jvm_local_unref(hh_value);
|
||||
if (ret) { uwsgi_jvm_local_unref(values); error = 1 ; goto clear;}
|
||||
}
|
||||
uwsgi_jvm_local_unref(values);
|
||||
goto clear;
|
||||
}
|
||||
uwsgi_log("unsupported header value !!! (must be java/lang/String or [java/lang/String)\n");
|
||||
error = 1;
|
||||
clear:
|
||||
if (h_value)
|
||||
uwsgi_jvm_local_unref(h_value);
|
||||
if (h_key)
|
||||
uwsgi_jvm_local_unref(h_key);
|
||||
if (hh)
|
||||
uwsgi_jvm_local_unref(hh);
|
||||
if (error) return -1;;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// returns 0 if ok, -1 on exception
|
||||
int uwsgi_jvm_exception(void) {
|
||||
if ((*ujvm_env)->ExceptionCheck(ujvm_env)) {
|
||||
@@ -213,6 +396,14 @@ size_t uwsgi_jvm_array_len(jobject o) {
|
||||
return len;
|
||||
}
|
||||
|
||||
jobject uwsgi_jvm_array_get(jobject o, long index) {
|
||||
jobject ret = (*ujvm_env)->GetObjectArrayElement(ujvm_env, o, index);
|
||||
if (uwsgi_jvm_exception()) {
|
||||
return NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int uwsgi_jvm_consume_input_stream(struct wsgi_request *wsgi_req, size_t chunk, jobject o) {
|
||||
int ret = 0;
|
||||
jclass c = uwsgi_jvm_class_from_object(o);
|
||||
@@ -614,6 +805,9 @@ static void uwsgi_jvm_create(void) {
|
||||
ujvm.str_class = uwsgi_jvm_class("java/lang/String");
|
||||
if (!ujvm.str_class) exit(1);
|
||||
|
||||
ujvm.str_array_class = uwsgi_jvm_class("[Ljava/lang/String;");
|
||||
if (!ujvm.str_array_class) exit(1);
|
||||
|
||||
ujvm.int_class = uwsgi_jvm_class("java/lang/Integer");
|
||||
if (!ujvm.int_class) exit(1);
|
||||
|
||||
|
||||
+141
-122
@@ -1,158 +1,177 @@
|
||||
#include "../jvm/jvm.h"
|
||||
#include <jvm.h>
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
extern struct uwsgi_jvm ujvm;
|
||||
|
||||
static int MAX_LREFS = 16;
|
||||
#define UWSGI_JVM_REQUEST_HANDLER_JWSGI 0
|
||||
|
||||
void uwsgi_jwsgi_init(void) {
|
||||
struct uwsgi_jwsgi {
|
||||
char *app;
|
||||
jmethodID app_mid;
|
||||
jclass app_class;
|
||||
} ujwsgi;
|
||||
|
||||
static struct uwsgi_option uwsgi_jwsgi_options[] = {
|
||||
{"jwsgi", required_argument, 0, "load the specified JWSGI application (syntax class:method)", uwsgi_opt_set_str, &ujwsgi.app, 0},
|
||||
{0, 0, 0, 0},
|
||||
};
|
||||
|
||||
static int uwsgi_jwsgi_add_request_item(jobject hm, char *key, uint16_t key_len, char *value, uint16_t value_len) {
|
||||
jobject j_key = uwsgi_jvm_str(key, key_len);
|
||||
if (!j_key) return -1;
|
||||
|
||||
jobject j_value = uwsgi_jvm_str(value, value_len);
|
||||
if (!j_value) {
|
||||
uwsgi_jvm_local_unref(j_value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ret = uwsgi_jvm_hashmap_put(hm, j_key, j_value);
|
||||
uwsgi_jvm_local_unref(j_key);
|
||||
uwsgi_jvm_local_unref(j_value);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int uwsgi_jwsgi_request(struct wsgi_request *wsgi_req) {
|
||||
static int uwsgi_jwsgi_add_request_input(jobject hm, char *key, uint16_t key_len) {
|
||||
jobject j_key = uwsgi_jvm_str(key, key_len);
|
||||
if (!j_key) return -1;
|
||||
|
||||
jmethodID jmid;
|
||||
int i;
|
||||
jobject env;
|
||||
jobject hkey, hval;
|
||||
jobject response;
|
||||
|
||||
jobject status;
|
||||
jobject headers, header;
|
||||
jobject body;
|
||||
|
||||
const char* body_str;
|
||||
const char* status_str;
|
||||
const char* hkey_str;
|
||||
const char* hval_str;
|
||||
|
||||
jclass hc;
|
||||
|
||||
jmethodID hh_size, hh_get;
|
||||
int hlen;
|
||||
|
||||
if (!wsgi_req->uh.pktsize) {
|
||||
uwsgi_log("Invalid JWSGI request. skip.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (uwsgi_parse_vars(wsgi_req)) {
|
||||
uwsgi_log("Invalid JWSGI request. skip.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((*ujvm.env)->PushLocalFrame(ujvm.env, MAX_LREFS) < 0) {
|
||||
uwsgi_log("jwsgi can not allocate frame!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
jmid = uwsgi_jvm_get_static_method_id(ujvm.main_class, "jwsgi", "(Ljava/util/Hashtable;)[Ljava/lang/Object;");
|
||||
|
||||
uwsgi_log("jwsgi method id = %d\n", jmid);
|
||||
|
||||
env = uwsgi_jvm_ht_new();
|
||||
uwsgi_jvm_exception();
|
||||
|
||||
int cnt = wsgi_req->var_cnt;
|
||||
for(i=0;i<cnt;i++) {
|
||||
|
||||
if ((*ujvm.env)->PushLocalFrame(ujvm.env, MAX_LREFS) < 0) {
|
||||
uwsgi_log("jwsgi can not allocate frame!");
|
||||
return -1;
|
||||
jobject j_value = uwsgi_jvm_request_body_input_stream();
|
||||
if (!j_value) {
|
||||
uwsgi_jvm_local_unref(j_value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
hkey = uwsgi_jvm_str_new(wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len);
|
||||
hval = uwsgi_jvm_str_new(wsgi_req->hvec[i+1].iov_base, wsgi_req->hvec[i+1].iov_len);
|
||||
uwsgi_jvm_ht_put(env, hkey, hval);
|
||||
uwsgi_jvm_exception();
|
||||
int ret = uwsgi_jvm_hashmap_put(hm, j_key, j_value);
|
||||
uwsgi_jvm_local_unref(j_key);
|
||||
uwsgi_jvm_local_unref(j_value);
|
||||
return ret;
|
||||
}
|
||||
|
||||
(*ujvm.env)->PopLocalFrame(ujvm.env, NULL);
|
||||
static int uwsgi_jwsgi_request(struct wsgi_request *wsgi_req) {
|
||||
char status_str[11];
|
||||
jobject hm = NULL;
|
||||
jobject response = NULL;
|
||||
jobject r_status = NULL;
|
||||
jobject r_headers = NULL;
|
||||
jobject r_headers_entries = NULL;
|
||||
jobject r_body = NULL;
|
||||
|
||||
i++;
|
||||
}
|
||||
hm = uwsgi_jvm_hashmap();
|
||||
if (!hm) return -1;
|
||||
|
||||
uwsgi_log("env created\n");
|
||||
int i;
|
||||
for(i=0;i<wsgi_req->var_cnt;i++) {
|
||||
char *hk = wsgi_req->hvec[i].iov_base;
|
||||
uint16_t hk_l = wsgi_req->hvec[i].iov_len;
|
||||
char *hv = wsgi_req->hvec[i+1].iov_base;
|
||||
uint16_t hv_l = wsgi_req->hvec[i+1].iov_len;
|
||||
if (uwsgi_jwsgi_add_request_item(hm, hk, hk_l, hv, hv_l)) goto end;
|
||||
i++;
|
||||
}
|
||||
|
||||
uwsgi_jvm_ht_put(env, uwsgi_jvm_str("jwsgi.input"), uwsgi_jvm_fd(wsgi_req->poll.fd));
|
||||
if (uwsgi_jwsgi_add_request_input(hm, "jwsgi.input", 11)) goto end;
|
||||
|
||||
uwsgi_log("jwsgi.input created\n");
|
||||
response = uwsgi_jvm_call_object_static(ujwsgi.app_class, ujwsgi.app_mid, hm);
|
||||
if (!response) goto end;
|
||||
|
||||
response = (*ujvm.env)->CallObjectMethod(ujvm.env, ujvm.main_class, jmid, env);
|
||||
uwsgi_jvm_exception();
|
||||
if (uwsgi_jvm_array_len(response) != 3) {
|
||||
uwsgi_log("invalid JWSGI response object\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
uwsgi_log("RESPONSE SIZE %d\n", (*ujvm.env)->GetArrayLength(ujvm.env, response));
|
||||
r_status = uwsgi_jvm_array_get(response, 0);
|
||||
if (!r_status) goto end;
|
||||
|
||||
long n_status = uwsgi_jvm_number2c(r_status);
|
||||
if (n_status == -1) goto end;
|
||||
|
||||
if ((*ujvm.env)->PushLocalFrame(ujvm.env, MAX_LREFS) < 0) {
|
||||
uwsgi_log("jwsgi can not allocate frame!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
status = uwsgi_jvm_array_get(response, 0);
|
||||
uwsgi_jvm_exception();
|
||||
|
||||
status_str = uwsgi_jvm_str2c(status);
|
||||
wsgi_req->headers_size += write(wsgi_req->poll.fd, wsgi_req->protocol, wsgi_req->protocol_len);
|
||||
wsgi_req->headers_size += write(wsgi_req->poll.fd, " ", 1);
|
||||
wsgi_req->headers_size += write(wsgi_req->poll.fd, status_str, uwsgi_jvm_strlen2c(status));
|
||||
wsgi_req->headers_size += write(wsgi_req->poll.fd, "\r\n", 2);
|
||||
(*ujvm.env)->ReleaseStringUTFChars(ujvm.env, status, status_str);
|
||||
|
||||
headers = uwsgi_jvm_array_get(response, 1);
|
||||
|
||||
hc = uwsgi_jvm_get_object_class(headers);
|
||||
hh_size = uwsgi_jvm_get_method_id(hc, "size","()I");
|
||||
hh_get = uwsgi_jvm_get_method_id(hc, "get","(I)Ljava/lang/Object;");
|
||||
|
||||
hlen = (*ujvm.env)->CallIntMethod(ujvm.env, headers, hh_size);
|
||||
|
||||
for(i=0;i<hlen;i++) {
|
||||
|
||||
if ((*ujvm.env)->PushLocalFrame(ujvm.env, MAX_LREFS) < 0) {
|
||||
uwsgi_log("jwsgi can not allocate frame!");
|
||||
return -1;
|
||||
if (uwsgi_num2str2(n_status, status_str) != 3) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
header = (*ujvm.env)->CallObjectMethod(ujvm.env, headers, hh_get, i);
|
||||
hkey = uwsgi_jvm_array_get(header, 0);
|
||||
hval = uwsgi_jvm_array_get(header, 1);
|
||||
hkey_str = uwsgi_jvm_str2c(hkey);
|
||||
hval_str = uwsgi_jvm_str2c(hval);
|
||||
if (uwsgi_response_prepare_headers(wsgi_req, status_str, 3)) goto end;
|
||||
|
||||
wsgi_req->headers_size += write(wsgi_req->poll.fd, hkey_str, uwsgi_jvm_strlen2c(hkey));
|
||||
wsgi_req->headers_size += write(wsgi_req->poll.fd, ": ", 2);
|
||||
wsgi_req->headers_size += write(wsgi_req->poll.fd, hval_str, uwsgi_jvm_strlen2c(hval));
|
||||
wsgi_req->headers_size += write(wsgi_req->poll.fd, "\r\n", 2);
|
||||
r_headers = uwsgi_jvm_array_get(response, 1);
|
||||
if (!r_headers) goto end;
|
||||
|
||||
(*ujvm.env)->ReleaseStringUTFChars(ujvm.env, hkey, hkey_str);
|
||||
(*ujvm.env)->ReleaseStringUTFChars(ujvm.env, hval, hval_str);
|
||||
// get entrySet
|
||||
r_headers_entries = uwsgi_jvm_entryset(r_headers);
|
||||
if (!r_headers_entries) goto end;
|
||||
|
||||
(*ujvm.env)->PopLocalFrame(ujvm.env, NULL);
|
||||
}
|
||||
// get iterator
|
||||
jobject values = uwsgi_jvm_auto_iterator(r_headers_entries);
|
||||
if (values) {
|
||||
int ret = uwsgi_jvm_iterator_to_response_headers(wsgi_req, values);
|
||||
uwsgi_jvm_local_unref(values);
|
||||
if (ret) goto end;
|
||||
}
|
||||
else {
|
||||
uwsgi_log("unsupported response headers type !!! (must be java/util/HashMap)\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
wsgi_req->headers_size += write(wsgi_req->poll.fd, "\r\n", 2);
|
||||
r_body = uwsgi_jvm_array_get(response, 2);
|
||||
if (!r_body) goto end;
|
||||
|
||||
body = uwsgi_jvm_array_get(response, 2);
|
||||
body_str = (*ujvm.env)->GetStringUTFChars(ujvm.env, body, NULL);
|
||||
wsgi_req->response_size = write(wsgi_req->poll.fd, body_str, (*ujvm.env)->GetStringUTFLength(ujvm.env, body));
|
||||
(*ujvm.env)->ReleaseStringUTFChars(ujvm.env, body, status_str);
|
||||
if (uwsgi_jvm_object_to_response_body(wsgi_req, r_body)) {
|
||||
uwsgi_log("unsupported JWSGI response body type\n");
|
||||
}
|
||||
|
||||
(*ujvm.env)->PopLocalFrame(ujvm.env, NULL);
|
||||
end:
|
||||
if (r_status) uwsgi_jvm_local_unref(r_status);
|
||||
if (r_headers_entries) uwsgi_jvm_local_unref(r_headers_entries);
|
||||
if (r_headers) uwsgi_jvm_local_unref(r_headers);
|
||||
if (r_body) uwsgi_jvm_local_unref(r_body);
|
||||
|
||||
(*ujvm.env)->PopLocalFrame(ujvm.env, NULL);
|
||||
|
||||
return 1;
|
||||
if (response) {
|
||||
uwsgi_jvm_local_unref(response);
|
||||
}
|
||||
uwsgi_jvm_local_unref(hm);
|
||||
return UWSGI_OK;
|
||||
}
|
||||
|
||||
void uwsgi_jwsgi_after_request(struct wsgi_request *wsgi_req) {
|
||||
log_request(wsgi_req);
|
||||
static int uwsgi_jwsgi_setup() {
|
||||
|
||||
char *app = uwsgi_str(ujwsgi.app);
|
||||
|
||||
char *colon = strchr(app, ':');
|
||||
|
||||
if (!colon) {
|
||||
uwsgi_log("invalid JWSGI app definition, must be class:method\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
*colon = 0;
|
||||
|
||||
ujwsgi.app_class = uwsgi_jvm_class(app);
|
||||
if (!ujwsgi.app_class) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ujwsgi.app_mid = uwsgi_jvm_get_static_method_id(ujwsgi.app_class, colon+1, "(Ljava/util/HashMap;)[Ljava/lang/Object;");
|
||||
if (!ujwsgi.app_mid) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uwsgi_log("JWSGI app \"%s\" loaded\n", ujwsgi.app);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int uwsgi_jwsgi_init() {
|
||||
|
||||
if (!ujwsgi.app) return 0;
|
||||
|
||||
if (uwsgi_jvm_register_request_handler(UWSGI_JVM_REQUEST_HANDLER_JWSGI, uwsgi_jwsgi_setup, uwsgi_jwsgi_request)) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct uwsgi_plugin jwsgi_plugin = {
|
||||
|
||||
.name = "jwsgi",
|
||||
.modifier1 = 8,
|
||||
.request = uwsgi_jwsgi_request,
|
||||
.after_request = uwsgi_jwsgi_after_request,
|
||||
.name = "jwsgi",
|
||||
.options = uwsgi_jwsgi_options,
|
||||
.init = uwsgi_jwsgi_init,
|
||||
};
|
||||
|
||||
@@ -1,22 +1,16 @@
|
||||
import os,sys
|
||||
jvm_path = 'plugins/jvm'
|
||||
|
||||
NAME='jwsgi'
|
||||
up = {}
|
||||
try:
|
||||
execfile('%s/uwsgiplugin.py' % jvm_path, up)
|
||||
except:
|
||||
f = open('%s/uwsgiplugin.py' % jvm_path)
|
||||
exec(f.read(), up)
|
||||
f.close()
|
||||
|
||||
# Snow Leopard
|
||||
#JVM_INCPATH = "/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Headers/"
|
||||
#JVM_LIBPATH = "/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Libraries/ -framework JavaVM"
|
||||
|
||||
# Ubuntu
|
||||
JVM_INCPATH = "/usr/lib/jvm/java-6-sun-1.6.0.15/include/ -I/usr/lib/jvm/java-6-sun-1.6.0.15/include/linux"
|
||||
JVM_LIBPATH = "/usr/lib/jvm/java-6-sun-1.6.0.15/jre/lib/i386/server/"
|
||||
|
||||
|
||||
CFLAGS = ['-I' + JVM_INCPATH]
|
||||
LDFLAGS = ['-L' + JVM_LIBPATH]
|
||||
LIBS = ['-ljvm']
|
||||
NAME='ring'
|
||||
CFLAGS = up['CFLAGS']
|
||||
CFLAGS.append('-I%s' % jvm_path)
|
||||
LDFLAGS = []
|
||||
LIBS = []
|
||||
GCC_LIST = ['jwsgi_plugin']
|
||||
|
||||
if os.environ.has_key('LD_RUN_PATH'):
|
||||
os.environ['LD_RUN_PATH'] += ':' + JVM_LIBPATH
|
||||
else:
|
||||
os.environ['LD_RUN_PATH'] = JVM_LIBPATH
|
||||
|
||||
+5
-116
@@ -224,7 +224,7 @@ static jobject uwsgi_ring_response_get(jobject r, char *name, size_t len) {
|
||||
|
||||
// the request handler
|
||||
static int uwsgi_ring_request(struct wsgi_request *wsgi_req) {
|
||||
char status_str[1];
|
||||
char status_str[11];
|
||||
jobject request = NULL;
|
||||
jobject response = NULL;
|
||||
jobject entries = NULL;
|
||||
@@ -362,127 +362,16 @@ hend:
|
||||
entries = uwsgi_ring_Associative_iterator(r_headers);
|
||||
if (!entries) goto end;
|
||||
|
||||
int error = 0;
|
||||
while(uwsgi_jvm_iterator_hasNext(entries)) {
|
||||
jobject hh = NULL, h_key = NULL, h_value = NULL;
|
||||
|
||||
hh = uwsgi_jvm_iterator_next(entries);
|
||||
if (!hh) { error = 1 ; goto clear;}
|
||||
h_key = uwsgi_jvm_getKey(hh);
|
||||
if (!h_key) { error = 1 ; goto clear;}
|
||||
h_value = uwsgi_jvm_getValue(hh);
|
||||
if (!h_value) { error = 1 ; goto clear;}
|
||||
|
||||
if (!uwsgi_jvm_object_is_instance(h_key, ujvm.str_class)) {
|
||||
uwsgi_log("headers key must be java/lang/String !!!\n");
|
||||
error = 1 ; goto clear;
|
||||
}
|
||||
|
||||
// check for string
|
||||
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) error = 1;
|
||||
goto clear;
|
||||
}
|
||||
|
||||
// check for collection
|
||||
jobject values = uwsgi_jvm_auto_iterator(h_value);
|
||||
if (values) {
|
||||
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");
|
||||
uwsgi_jvm_local_unref(hh_value);
|
||||
uwsgi_jvm_local_unref(values);
|
||||
error = 1 ; goto clear;
|
||||
}
|
||||
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);
|
||||
uwsgi_jvm_local_unref(hh_value);
|
||||
if (ret) { uwsgi_jvm_local_unref(values); error = 1 ; goto clear;}
|
||||
}
|
||||
uwsgi_jvm_local_unref(values);
|
||||
goto clear;
|
||||
}
|
||||
uwsgi_log("unsupported header value !!! (must be java/lang/String or collection/seq)\n");
|
||||
error = 1;
|
||||
clear:
|
||||
if (h_value)
|
||||
uwsgi_jvm_local_unref(h_value);
|
||||
if (h_key)
|
||||
uwsgi_jvm_local_unref(h_key);
|
||||
if (hh)
|
||||
uwsgi_jvm_local_unref(hh);
|
||||
if (error) goto end;
|
||||
if (uwsgi_jvm_iterator_to_response_headers(wsgi_req, entries)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
r_body = uwsgi_ring_response_get(response, "body", 4);
|
||||
if (!r_body) goto end;
|
||||
|
||||
|
||||
if (uwsgi_jvm_object_is_instance(r_body, ujvm.str_class)) {
|
||||
char *c_body = uwsgi_jvm_str2c(r_body);
|
||||
size_t c_body_len = uwsgi_jvm_strlen(r_body);
|
||||
uwsgi_response_write_body_do(wsgi_req, c_body, c_body_len);
|
||||
uwsgi_jvm_release_chars(r_body, c_body);
|
||||
goto end;
|
||||
}
|
||||
|
||||
jobject chunks = uwsgi_jvm_auto_iterator(r_body);
|
||||
if (chunks) {
|
||||
while(uwsgi_jvm_iterator_hasNext(chunks)) {
|
||||
jobject chunk = uwsgi_jvm_iterator_next(chunks);
|
||||
if (!chunk) goto done;
|
||||
if (!uwsgi_jvm_object_is_instance(chunk, ujvm.str_class)) {
|
||||
uwsgi_log("body iSeq item must be java/lang/String !!!\n");
|
||||
uwsgi_jvm_local_unref(chunk);
|
||||
goto done;
|
||||
}
|
||||
char *c_body = uwsgi_jvm_str2c(chunk);
|
||||
size_t c_body_len = uwsgi_jvm_strlen(chunk);
|
||||
int ret = uwsgi_response_write_body_do(wsgi_req, c_body, c_body_len);
|
||||
uwsgi_jvm_release_chars(chunk, c_body);
|
||||
uwsgi_jvm_local_unref(chunk);
|
||||
if (ret) goto done;
|
||||
}
|
||||
done:
|
||||
uwsgi_jvm_local_unref(chunks);
|
||||
goto end;
|
||||
if (uwsgi_jvm_object_to_response_body(wsgi_req, r_body)) {
|
||||
uwsgi_log("unsupported clojure/ring body type\n");
|
||||
}
|
||||
|
||||
if (uwsgi_jvm_object_is_instance(r_body, ujvm.file_class)) {
|
||||
jobject j_filename = uwsgi_jvm_filename(r_body);
|
||||
if (!j_filename) goto end;
|
||||
char *c_filename = uwsgi_jvm_str2c(j_filename);
|
||||
int fd = open(c_filename, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
uwsgi_error("clojure/ring->open()");
|
||||
goto done2;
|
||||
}
|
||||
uwsgi_response_sendfile_do(wsgi_req, fd, 0, 0);
|
||||
done2:
|
||||
uwsgi_jvm_release_chars(j_filename, c_filename);
|
||||
uwsgi_jvm_local_unref(j_filename);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (uwsgi_jvm_object_is_instance(r_body, ujvm.input_stream_class)) {
|
||||
uwsgi_jvm_consume_input_stream(wsgi_req, 8192, r_body);
|
||||
goto end;
|
||||
}
|
||||
|
||||
uwsgi_log("unsupported clojure/ring body type\n");
|
||||
end:
|
||||
// destroy the request map and the response
|
||||
uwsgi_jvm_local_unref(hm);
|
||||
|
||||
Reference in New Issue
Block a user