diff --git a/core/reader.c b/core/reader.c index a5a1d3b6..b7af299a 100644 --- a/core/reader.c +++ b/core/reader.c @@ -30,14 +30,34 @@ int uwsgi_simple_wait_read_hook(int fd, int timeout) { void uwsgi_request_body_seek(struct wsgi_request *wsgi_req, off_t pos) { if (wsgi_req->post_file) { + if (pos < 0) { + if (fseek(wsgi_req->post_file, pos, SEEK_CUR)) { + uwsgi_error("uwsgi_request_body_seek()/fseek()"); + } + wsgi_req->post_pos = ftell(wsgi_req->post_file); + return; + } + if (fseek(wsgi_req->post_file, pos, SEEK_SET)) { uwsgi_error("uwsgi_request_body_seek()/fseek()"); } + wsgi_req->post_pos = ftell(wsgi_req->post_file); return; } if (uwsgi.post_buffering) { - wsgi_req->post_pos += pos; + if (pos < 0) { + if (pos > wsgi_req->post_pos) { + wsgi_req->post_pos = 0; + return; + } + wsgi_req->post_pos -= pos; + return; + } + if (pos >= uwsgi.post_buffering) { + pos = uwsgi.post_buffering - 1; + } + wsgi_req->post_pos = pos; } } diff --git a/core/routing.c b/core/routing.c index 8e2ffa1d..1d2fa09f 100644 --- a/core/routing.c +++ b/core/routing.c @@ -258,6 +258,7 @@ void uwsgi_opt_add_route(char *opt, char *value, void *foobar) { last_ur->is_last = 1; return; } + break; } r = r->next; } @@ -266,6 +267,32 @@ void uwsgi_opt_add_route(char *opt, char *value, void *foobar) { exit(1); } +int uwsgi_route_api_func(struct wsgi_request *wsgi_req, char *router, char *args) { + struct uwsgi_route *ur = NULL; + struct uwsgi_router *r = uwsgi.routers; + while(r) { + if (!strcmp(router, r->name)) { + goto found; + } + r = r->next; + } + return -1; +found: + ur = uwsgi_calloc(sizeof(struct uwsgi_route)); + // initialize the virtual route + if (r->func(ur, args)) { + free(ur); + return -1; + } + // call it + int ret = ur->func(wsgi_req, ur); + if (ur->free) { + ur->free(ur); + } + free(ur); + return ret; +} + // continue/last route static int uwsgi_router_continue_func(struct wsgi_request *wsgi_req, struct uwsgi_route *route) { diff --git a/plugins/python/uwsgi_pymodule.c b/plugins/python/uwsgi_pymodule.c index aaf331c3..cc73fa8f 100644 --- a/plugins/python/uwsgi_pymodule.c +++ b/plugins/python/uwsgi_pymodule.c @@ -704,6 +704,21 @@ PyObject *py_uwsgi_send(PyObject * self, PyObject * args) { } +#ifdef UWSGI_ROUTING +static PyObject *py_uwsgi_route(PyObject * self, PyObject * args) { + struct wsgi_request *wsgi_req = py_current_wsgi_req(); + char *router_name = NULL; + char *router_args = NULL; + + if (!PyArg_ParseTuple(args, "ss:route", &router_name, &router_args)) { + return NULL; + } + + int ret = uwsgi_route_api_func(wsgi_req, uwsgi_str(router_name), uwsgi_str(router_args)); + return PyInt_FromLong(ret); +} +#endif + PyObject *py_uwsgi_offload(PyObject * self, PyObject * args) { /* size_t len = 0; @@ -2437,6 +2452,10 @@ static PyMethodDef uwsgi_advanced_methods[] = { {"add_rb_timer", py_uwsgi_add_rb_timer, METH_VARARGS, ""}, {"add_cron", py_uwsgi_add_cron, METH_VARARGS, ""}, +#ifdef UWSGI_ROUTING + {"route", py_uwsgi_route, METH_VARARGS, ""}, +#endif + {"register_rpc", py_uwsgi_register_rpc, METH_VARARGS, ""}, {"rpc", py_uwsgi_rpc, METH_VARARGS, ""}, {"rpc_list", py_uwsgi_rpc_list, METH_VARARGS, ""}, diff --git a/plugins/python/wsgi_handlers.c b/plugins/python/wsgi_handlers.c index 77a34507..2f987c85 100644 --- a/plugins/python/wsgi_handlers.c +++ b/plugins/python/wsgi_handlers.c @@ -133,6 +133,19 @@ static PyObject *uwsgi_Input_close(uwsgi_Input *self, PyObject *args) { return Py_None; } +static PyObject *uwsgi_Input_seek(uwsgi_Input *self, PyObject *args) { + long pos = 0; + + if (!PyArg_ParseTuple(args, "l:seek", &pos)) { + return NULL; + } + + uwsgi_request_body_seek(self->wsgi_req, pos); + + Py_INCREF(Py_None); + return Py_None; +} + static PyObject *uwsgi_Input_fileno(uwsgi_Input *self, PyObject *args) { return PyInt_FromLong(self->wsgi_req->fd); @@ -144,6 +157,7 @@ static PyMethodDef uwsgi_Input_methods[] = { { "readlines", (PyCFunction)uwsgi_Input_readlines, METH_VARARGS, 0 }, // add close to allow mod_wsgi compatibility { "close", (PyCFunction)uwsgi_Input_close, METH_VARARGS, 0 }, + { "seek", (PyCFunction)uwsgi_Input_seek, METH_VARARGS, 0 }, { "fileno", (PyCFunction)uwsgi_Input_fileno, METH_VARARGS, 0 }, { NULL, NULL} }; diff --git a/plugins/router_http/router_http.c b/plugins/router_http/router_http.c index 855b36a9..87763dc1 100644 --- a/plugins/router_http/router_http.c +++ b/plugins/router_http/router_http.c @@ -1,10 +1,10 @@ -#include "../../uwsgi.h" +#include #ifdef UWSGI_ROUTING extern struct uwsgi_server uwsgi; -int uwsgi_routing_func_http(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) { +static int uwsgi_routing_func_http(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) { // mark a route request wsgi_req->via = UWSGI_VIA_ROUTE; @@ -60,7 +60,7 @@ int uwsgi_routing_func_http(struct wsgi_request *wsgi_req, struct uwsgi_route *u } -int uwsgi_router_http(struct uwsgi_route *ur, char *args) { +static int uwsgi_router_http(struct uwsgi_route *ur, char *args) { ur->func = uwsgi_routing_func_http; ur->data = (void *) args; @@ -83,7 +83,7 @@ int uwsgi_router_http(struct uwsgi_route *ur, char *args) { } -void router_http_register(void) { +static void router_http_register(void) { uwsgi_register_router("http", uwsgi_router_http); } diff --git a/plugins/router_uwsgi/router_uwsgi.c b/plugins/router_uwsgi/router_uwsgi.c index b27cf248..597726a0 100644 --- a/plugins/router_uwsgi/router_uwsgi.c +++ b/plugins/router_uwsgi/router_uwsgi.c @@ -1,9 +1,9 @@ -#include "../../uwsgi.h" +#include #ifdef UWSGI_ROUTING extern struct uwsgi_server uwsgi; -int uwsgi_routing_func_uwsgi_simple(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) { +static int uwsgi_routing_func_uwsgi_simple(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) { struct uwsgi_header *uh = (struct uwsgi_header *) ur->data; @@ -31,7 +31,7 @@ int uwsgi_routing_func_uwsgi_simple(struct wsgi_request *wsgi_req, struct uwsgi_ return UWSGI_ROUTE_CONTINUE; } -int uwsgi_routing_func_uwsgi_remote(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) { +static int uwsgi_routing_func_uwsgi_remote(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) { struct uwsgi_header *uh = (struct uwsgi_header *) ur->data; char *addr = ur->data + sizeof(struct uwsgi_header); @@ -47,9 +47,9 @@ int uwsgi_routing_func_uwsgi_remote(struct wsgi_request *wsgi_req, struct uwsgi_ size_t remains = wsgi_req->post_cl - wsgi_req->proto_parser_remains; struct uwsgi_buffer *ub = uwsgi_buffer_new(4 + wsgi_req->uh->pktsize + wsgi_req->proto_parser_remains); - if (uwsgi_buffer_append(ub, (char *) uh, 4)) goto end; - if (uwsgi_buffer_append(ub, wsgi_req->buffer, uh->pktsize)) goto end; uh->pktsize = wsgi_req->uh->pktsize; + if (uwsgi_buffer_append(ub, (char *) uh, 4)) goto end; + if (uwsgi_buffer_append(ub, wsgi_req->buffer, wsgi_req->uh->pktsize)) goto end; if (wsgi_req->proto_parser_remains > 0) { if (uwsgi_buffer_append(ub, wsgi_req->proto_parser_remains_buf, wsgi_req->proto_parser_remains)) { goto end; @@ -74,19 +74,23 @@ end: } -int uwsgi_router_uwsgi(struct uwsgi_route *ur, char *args) { +static void uwsgi_router_uwsgi_free(struct uwsgi_route *ur) { + free(ur->data); +} + +static int uwsgi_router_uwsgi(struct uwsgi_route *ur, char *args) { // check for commas char *comma1 = strchr(args, ','); if (!comma1) { uwsgi_log("invalid route syntax: %s\n", args); - exit(1); + return -1; } char *comma2 = strchr(comma1+1, ','); if (!comma2) { uwsgi_log("invalid route syntax: %s\n", args); - exit(1); + return -1; } char *comma3 = strchr(comma2+1, ','); @@ -102,6 +106,7 @@ int uwsgi_router_uwsgi(struct uwsgi_route *ur, char *args) { struct uwsgi_header *uh = uwsgi_calloc(sizeof(struct uwsgi_header)); ur->func = uwsgi_routing_func_uwsgi_simple; ur->data = (void *) uh; + ur->free = uwsgi_router_uwsgi_free; uh->modifier1 = atoi(comma1+1); uh->modifier2 = atoi(comma2+1); @@ -116,6 +121,7 @@ int uwsgi_router_uwsgi(struct uwsgi_route *ur, char *args) { struct uwsgi_header *uh = uwsgi_calloc(sizeof(struct uwsgi_header) + strlen(args) + 1); ur->func = uwsgi_routing_func_uwsgi_remote; ur->data = (void *) uh; + ur->free = uwsgi_router_uwsgi_free; uh->modifier1 = atoi(comma1+1); uh->modifier2 = atoi(comma2+1); @@ -135,7 +141,7 @@ int uwsgi_router_uwsgi(struct uwsgi_route *ur, char *args) { } -void router_uwsgi_register(void) { +static void router_uwsgi_register(void) { uwsgi_register_router("uwsgi", uwsgi_router_uwsgi); } diff --git a/uwsgi.h b/uwsgi.h index 02c204e1..d855e8c4 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -1064,6 +1064,9 @@ struct uwsgi_route { char *regexp; char *action; + // this is used by virtual route to free resources + void (*free)(struct uwsgi_route *); + struct uwsgi_route *next; }; @@ -3287,6 +3290,7 @@ int uwsgi_apply_routes_fast(struct wsgi_request *); void uwsgi_register_embedded_routers(void); void uwsgi_routing_dump(); struct uwsgi_buffer *uwsgi_routing_translate(struct wsgi_request *, struct uwsgi_route *, char *, uint16_t, char *, size_t); +int uwsgi_route_api_func(struct wsgi_request *, char *, char *); #endif void uwsgi_reload(char **);