Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

added rpcraw

  • Loading branch information...
commit 61022c398c0444fe974ff8e7dbf44e7fdeadf12f 1 parent 00bd8cc
@unbit authored
View
58 core/protocol.c
@@ -2,7 +2,7 @@
extern struct uwsgi_server uwsgi;
-// this is line uwsgi_str_num but with security checks
+// this is like uwsgi_str_num but with security checks
static size_t get_content_length(char *buf, uint16_t size) {
int i;
size_t val = 0;
@@ -80,7 +80,7 @@ ssize_t send_udp_message(uint8_t modifier1, uint8_t modifier2, char *host, char
ret = sendto(fd, (char *) uh, message_size + 4, 0, (struct sockaddr *) &un_addr, sizeof(un_addr));
}
if (ret < 0) {
- uwsgi_error("sendto()");
+ uwsgi_error("send_udp_message()/sendto()");
}
close(fd);
@@ -974,6 +974,60 @@ int uwsgi_hooked_parse_array(char *buffer, size_t len, void (*hook) (uint16_t, c
}
+
+// this functions transform a raw HTTP response to a uWSGI-managed response
+int uwsgi_blob_to_response(struct wsgi_request *wsgi_req, char *body, size_t len) {
+ char *line = body;
+ size_t line_len = 0;
+ size_t i;
+ int status_managed = 0;
+ for(i=0;i<len;i++) {
+ if (body[i] == '\n') {
+ // invalid line
+ if (line_len < 1) {
+ return -1;
+ }
+ if (line[line_len-1] != '\r') {
+ return -1;
+ }
+ // end of the headers
+ if (line_len == 1) {
+ break;
+ }
+
+ if (status_managed) {
+ char *colon = memchr(line, ':', line_len-1);
+ if (!colon) return -1;
+ if (colon[1] != ' ') return -1;
+ if (uwsgi_response_add_header(wsgi_req, line, colon-line, colon+2, (line_len-1) - ((colon+2)-line))) return -1;
+ }
+ else {
+ char *space = memchr(line, ' ', line_len-1);
+ if (!space) return -1;
+ if ((line_len-1) - ((space+1)-line) < 3) return -1;
+ if (uwsgi_response_prepare_headers(wsgi_req, space+1, (line_len-1) - ((space+1)-line))) return -1;
+ status_managed = 1;
+ }
+ line = NULL;
+ line_len = 0;
+ }
+ else {
+ if (!line) {
+ line = body + i;
+ }
+ line_len++;
+ }
+ }
+
+ if ((i+1) < len) {
+ if (uwsgi_response_write_body_do(wsgi_req, body + (i + 1), len-(i+1))) {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
/*
the following functions need to take in account that POST data could be already available in wsgi_req->buffer (generally when uwsgi protocol is in use)
View
4 core/routing.c
@@ -220,6 +220,10 @@ int uwsgi_apply_routes_do(struct wsgi_request *wsgi_req, char *subject, uint16_t
if (ret == UWSGI_ROUTE_GOON) {
goon_func = routes->func;
}
+
+ if (ret == -1) {
+ return UWSGI_ROUTE_BREAK;
+ }
}
next:
subject = orig_subject;
View
60 plugins/rpc/rpc_plugin.c
@@ -148,6 +148,60 @@ static int uwsgi_routing_func_rpc_blob(struct wsgi_request *wsgi_req, struct uws
return ret;
}
+static int uwsgi_routing_func_rpc_raw(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;
+ if (size == 0) goto end;
+
+ ret = uwsgi_blob_to_response(wsgi_req, response, size);
+ free(response);
+ if (ret == 0) {
+ ret = UWSGI_ROUTE_BREAK;
+ }
+
+end:
+ for(i=0;i<ur->custom;i++) {
+ if (ubs[i] != NULL) {
+ uwsgi_buffer_destroy(ubs[i]);
+ }
+ }
+ return ret;
+}
+
// "next" || "continue" || "break(.*)" || "goon" || "goto .+"
static int uwsgi_routing_func_rpc_ret(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
@@ -299,6 +353,11 @@ static int uwsgi_router_rpc_blob(struct uwsgi_route *ur, char *args) {
return uwsgi_router_rpc_base(ur, args);
}
+static int uwsgi_router_rpc_raw(struct uwsgi_route *ur, char *args) {
+ ur->func = uwsgi_routing_func_rpc_raw;
+ return uwsgi_router_rpc_base(ur, args);
+}
+
static void router_rpc_register() {
uwsgi_register_router("call", uwsgi_router_rpc);
@@ -306,6 +365,7 @@ static void router_rpc_register() {
uwsgi_register_router("rpcret", uwsgi_router_rpc_ret);
uwsgi_register_router("rpcblob", uwsgi_router_rpc_blob);
uwsgi_register_router("rpcnext", uwsgi_router_rpc_blob);
+ uwsgi_register_router("rpcraw", uwsgi_router_rpc_raw);
}
#endif
View
2  uwsgi.h
@@ -3944,6 +3944,8 @@ char *uwsgi_get_mime_type(char *, int, size_t *);
void config_magic_table_fill(char *, char *[]);
+int uwsgi_blob_to_response(struct wsgi_request *, char *, size_t);
+
void uwsgi_check_emperor(void);
#ifdef UWSGI_AS_SHARED_LIBRARY
int uwsgi_init(int, char **, char **);
Please sign in to comment.
Something went wrong with that request. Please try again.