Example #1
0
static int uwsgi_routing_func_rpc_blob(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
        int ret = -1;
        // this is the list of args
        char *argv[UMAX8];
        // this is the size of each argument
        uint16_t argvs[UMAX8];
        // this is a placeholder for tmp uwsgi_buffers
        struct uwsgi_buffer *ubs[UMAX8];

        char **r_argv = (char **) ur->data2;
        uint16_t *r_argvs = (uint16_t *) ur->data3;

        char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
        uint16_t *subject_len = (uint16_t *)  (((char *)(wsgi_req))+ur->subject_len);

        uint64_t i;
        for(i=0;i<ur->custom;i++) {
                ubs[i] = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, r_argv[i], r_argvs[i]);
                if (!ubs[i]) goto end;
                argv[i] = ubs[i]->buf;
                argvs[i] = ubs[i]->pos;
        }

        // ok we now need to check it it is a local call or a remote one
        char *func = uwsgi_str(ur->data);
        char *remote = NULL;
        char *at = strchr(func, '@');
        if (at) {
                *at = 0;
                remote = at+1;
        }
        uint16_t size;
        char *response = uwsgi_do_rpc(remote, func, ur->custom, argv, argvs, &size);
        free(func);
        if (!response) goto end;

        ret = UWSGI_ROUTE_NEXT;

	// optimization
	if (!wsgi_req->headers_sent) {
        	if (uwsgi_response_prepare_headers(wsgi_req, "200 OK", 6)) {free(response) ; goto end;}
        	if (uwsgi_response_add_connection_close(wsgi_req)) {free(response) ; goto end;}
	}
        uwsgi_response_write_body_do(wsgi_req, response, size);
        free(response);

end:
        for(i=0;i<ur->custom;i++) {
                if (ubs[i] != NULL) {
                        uwsgi_buffer_destroy(ubs[i]);
                }
        }
        return ret;
}
Example #2
0
static int uwsgi_hook_rpc(char *arg) {

	int ret = -1;
	size_t i, argc = 0;
        char **rargv = uwsgi_split_quoted(arg, strlen(arg), " \t", &argc);
        if (!argc) goto end;
	if (argc > 256) goto destroy;

        char *argv[256];
        uint16_t argvs[256];

        char *node = NULL;
        char *func = rargv[0];

	char *at = strchr(func, '@');
	if (at) {
		*at = 0;
		node = at + 1;
	}

        for(i=0;i<(argc-1);i++) {
		size_t a_len = strlen(rargv[i+1]);
		if (a_len > 0xffff) goto destroy;
                argv[i] = rargv[i+1] ;
                argvs[i] = a_len;
        }

        uint64_t size = 0;
        // response must be always freed
        char *response = uwsgi_do_rpc(node, func, argc-1, argv, argvs, &size);
        if (response) {
		if (at) *at = '@';
		uwsgi_log("[rpc result from \"%s\"] %.*s\n", rargv[0], size, response);
                free(response);
		ret = 0;
        }

destroy:
        for(i=0;i<argc;i++) {
                free(rargv[i]);
        }
end:
	free(rargv);
	return ret;
}
Example #3
0
JNIEXPORT jobject JNICALL uwsgi_jvm_api_rpc(JNIEnv *env, jclass c, jobject j_args) {

	char *argv[256];
        uint16_t argvs[256];
	jobject argvj[256];
	uint64_t size = 0;

	size_t args = uwsgi_jvm_array_len(j_args);
	if (args < 2) return NULL;

	jobject server = uwsgi_jvm_array_get(j_args, 0);
	jobject func = uwsgi_jvm_array_get(j_args, 1);
	
	size_t i;
	for(i=0;i<(args-2);i++) {
		jobject j_arg = uwsgi_jvm_array_get(j_args, i + 2);	
		argvs[i] = uwsgi_jvm_strlen(j_arg);
		argv[i] = uwsgi_jvm_str2c(j_arg);
		// need this value to unref later
		argvj[i] = j_arg;
	}

	char *c_server = uwsgi_jvm_str2c(server);
	char *c_func = uwsgi_jvm_str2c(func);
	char *response = uwsgi_do_rpc(c_server, c_func, args-2, argv, argvs, &size);
	uwsgi_jvm_release_chars(func, c_func);
	uwsgi_jvm_release_chars(server, c_server);
	uwsgi_jvm_local_unref(server);
	uwsgi_jvm_local_unref(func);
	for(i=0;i<(args-2);i++) {
		uwsgi_jvm_release_chars(argvj[i], argv[i]);
		uwsgi_jvm_local_unref(argvj[i]);
	}
	
	if (response) {
		jobject o = uwsgi_jvm_str(response, size);
		free(response);
		return o;
	}
	
	return NULL;

}
Example #4
0
// "next" || "continue" || "break(.*)" || "goon" || "goto .+"
static int uwsgi_routing_func_rpc_ret(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
        int ret = -1;
        // this is the list of args
        char *argv[UMAX8];
        // this is the size of each argument
        uint16_t argvs[UMAX8];
        // this is a placeholder for tmp uwsgi_buffers
        struct uwsgi_buffer *ubs[UMAX8];

        char **r_argv = (char **) ur->data2;
        uint16_t *r_argvs = (uint16_t *) ur->data3;

        char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
        uint16_t *subject_len = (uint16_t *)  (((char *)(wsgi_req))+ur->subject_len);

        uint64_t i;
        for(i=0;i<ur->custom;i++) {
                ubs[i] = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, r_argv[i], r_argvs[i]);
                if (!ubs[i]) goto end;
                argv[i] = ubs[i]->buf;
                argvs[i] = ubs[i]->pos;
        }

        // ok we now need to check it it is a local call or a remote one
        char *func = uwsgi_str(ur->data);
        char *remote = NULL;
        char *at = strchr(func, '@');
        if (at) {
                *at = 0;
                remote = at+1;
        }
        uint16_t size;
        char *response = uwsgi_do_rpc(remote, func, ur->custom, argv, argvs, &size);
        free(func);
        if (!response) goto end;

        ret = UWSGI_ROUTE_CONTINUE;
	if (!uwsgi_strncmp(response, size, "next", 4 )) {
        	ret = UWSGI_ROUTE_NEXT;
	}
	else if (!uwsgi_strncmp(response, size, "continue", 8 )) {
        	ret = UWSGI_ROUTE_CONTINUE;
	}
	else if (!uwsgi_starts_with(response, size, "break", 5 )) {
        	ret = UWSGI_ROUTE_BREAK;
		if (size > 6) {
			if (uwsgi_response_prepare_headers(wsgi_req, response+6, size-6)) goto end0;
                	if (uwsgi_response_add_connection_close(wsgi_req)) goto end0;
                	if (uwsgi_response_add_content_type(wsgi_req, "text/plain", 10)) goto end0;
                	// no need to check for return value
                	uwsgi_response_write_headers_do(wsgi_req);
		}
	}
	else if (!uwsgi_starts_with(response, size, "goto ", 5)) {
		ret = UWSGI_ROUTE_BREAK;
		if (size > 5) {
		 	// find the label
        		struct uwsgi_route *routes = uwsgi.routes;
        		while(routes) {
                		if (!routes->label) goto next;
                		if (!uwsgi_strncmp(routes->label, routes->label_len, response+5, size-5)) {
					ret = UWSGI_ROUTE_NEXT;
                        		wsgi_req->route_goto = routes->pos;
                        		goto found;
                		}
next:
               			routes = routes->next;
        		}
			goto end0;	
found:
        		if (wsgi_req->route_goto <= wsgi_req->route_pc) {
                		wsgi_req->route_goto = 0;
                		uwsgi_log("[uwsgi-route] ERROR \"goto\" instruction can only jump forward (check your label !!!)\n");
				ret = UWSGI_ROUTE_BREAK;
        		}
		}
	}

end0:
        free(response);

end:
        for(i=0;i<ur->custom;i++) {
                if (ubs[i] != NULL) {
                        uwsgi_buffer_destroy(ubs[i]);
                }
        }
        return ret;
}