Compare commits

...
50 Commits
Author SHA1 Message Date
Roberto De Ioris e4a4942980 prepare for 2.0.3 release 2014-03-17 06:33:04 +01:00
Roberto De Ioris 6f671936fc added uwsgi::add_var to perl 2014-03-17 06:18:15 +01:00
Roberto De Ioris 7d1d992d58 fix tnetstring support #562 2014-03-17 06:02:44 +01:00
unbit 930f71c562 Merge pull request #571 from avar/avar/fix-2.0.1-perl-refactoring-regression
perl: fix one-off error in 2.0-103-gf041d10 causing warnings in e.g. Pla...
2014-03-16 05:53:54 +01:00
unbit 959bb11f77 Merge pull request #570 from avar/avar/add-sanity-check-to-offset-test
perl: add sanity checks to t/perl/test_input_with_offset.pl
2014-03-16 05:52:19 +01:00
Ævar Arnfjörð Bjarmason 13d8505738 perl: fix one-off error in 2.0-103-gf041d10 causing warnings in e.g. Plack::Request
This newly added support for read() offsets started causing "Use of
uninitialized value in subroutine entry" warnings.

This is all because there was a test for the number of items on the
stack, which ignored that the first argument is always the object, so 3
arguments to read() actually yields 4 arguments on the stack, not 3.

As a result we'd be calling SvIV() on a stack item that wasn't actually
passed in.
2014-03-15 21:05:18 +00:00
Ævar Arnfjörð Bjarmason 93fe463ca8 perl: add sanity checks to t/perl/test_input_with_offset.pl 2014-03-15 20:41:54 +00:00
unbit 5c64c21745 Merge pull request #569 from avar/avar/add-generated-file-to-gitignore
.gitignore: add /core/config_py.c to ignore
2014-03-15 15:16:12 +01:00
Ævar Arnfjörð Bjarmason f825ab542d .gitignore: add /core/config_py.c to ignore
This file added in e4903ee is generated by the build system and should
be in the ignore file.
2014-03-15 14:15:35 +00:00
unbit e744aef144 Merge pull request #568 from avar/avar/perl-add-streaming-test
perl: add a trivial streaming test program
2014-03-15 15:15:23 +01:00
Ævar Arnfjörð Bjarmason 4ded485a8e perl: add a trivial streaming test program
This came out of working on this debugging session:
https://github.com/unbit/uwsgi/issues/567
2014-03-15 14:10:20 +00:00
unbit 2ce5ec3986 Merge pull request #566 from avar/avar/psgi-spelling-error-fix
perl: fix trivial spelling error in psgi_loader.c error message
2014-03-15 14:48:35 +01:00
Ævar Arnfjörð Bjarmason af95f90fb0 perl: fix trivial spelling error in psgi_loader.c error message 2014-03-15 13:47:07 +00:00
unbit 7989dc748b Update CONTRIBUTORS 2014-03-15 14:36:51 +01:00
unbit f85f3e8178 Merge pull request #565 from avar/avar/fix-perl-stacktrace
perl: fix a regression with caller() not indicating the starting *.psgi ...
2014-03-15 14:28:14 +01:00
Ævar Arnfjörð Bjarmason 97809192c8 perl: fix a regression with caller() not indicating the starting *.psgi program
In 2.0.1-41-g3480c30 I introduced a regression with how the top-level
stackframe would appear within Perl programs. Before we'd show the
filename of the *.psgi file, but after we just showed "-e".

We can retain the bugfix I added in 2.0.1-41-g3480c30 while having a
sensible stacktrace by overriding the file via the #line directive.
2014-03-15 13:10:30 +00:00
Roberto De Ioris 5f74e6d964 fixed stupid bug with python add_var 2014-03-15 12:51:15 +01:00
Roberto De Ioris ae87fdd0f7 added uwsgi.add_var 2014-03-15 12:47:59 +01:00
Roberto De Ioris 36c44c83af added disableheaders routing action 2014-03-15 12:04:01 +01:00
Roberto De Ioris 48e13bfc65 add a check for already initialized python vm 2014-03-15 08:48:07 +01:00
Unbit 16cd55637d added support for mongrel2 URL_SCHEME #562 2014-03-14 11:48:36 +01:00
Unbit 39cf2887c4 added SIGURG to the Emperor 2014-03-14 11:28:53 +01:00
Unbit 671bf8a258 try to avoid vassal pipe to have invalid fd numbers 2014-03-14 11:21:20 +01:00
Unbit 89a8ceea81 allows building plugins from git repositories 2014-03-13 14:11:12 +01:00
Roberto De Ioris 6699f4046e better error reporting on websockets errors 2014-03-13 07:35:18 +01:00
Roberto De Ioris 88474b3d96 do not wait for a whole Emperor cycle before checking for each waitpid 2014-03-13 07:03:50 +01:00
unbit 32b6463d06 Merge pull request #559 from hynek/master
Set ECDHE curve independently from DHE parameters
2014-03-13 06:19:11 +01:00
Hynek Schlawack 63cc29a61d Set ECDHE curve independently from DHE parameters 2014-03-12 21:19:52 +01:00
Unbit d58f79eeab fixed #558 2014-03-11 16:18:32 +01:00
Unbit 7b24d2f5de allows vassals to request a config chunk from the emperor 2014-03-11 07:04:23 +01:00
Unbit a93db73d0c Merge branch 'master' of github.com:unbit/uwsgi 2014-03-10 14:52:35 +01:00
Unbit c118c75bfe beter management of failed emperor kills 2014-03-10 14:52:30 +01:00
Unbit 624631d443 fixed tuntap 2014-03-08 13:57:15 +01:00
Unbit b681eab385 fixed SIGWINCH in emperor and added emperor rescan master fifo command 2014-03-08 08:13:30 +01:00
Unbit 91dfe779ff fixed typo 2014-03-08 06:38:50 +01:00
Unbit 0ad50711c0 report key in corerouters 2014-03-08 06:36:38 +01:00
Unbit df6ed26479 more debug for tuntap 2014-03-08 06:24:45 +01:00
Unbit d08778b39c removed useless tuntap debug 2014-03-08 05:59:59 +01:00
Unbit 0c8c2932cf Merge branch 'master' of https://github.com/unbit/uwsgi 2014-03-08 05:44:05 +01:00
Unbit 131bd7da2f try to improve nb tuntap gateway 2014-03-08 05:43:54 +01:00
Unbit d247424442 more useful log alarm 2014-03-07 16:09:04 +01:00
Roberto De Ioris 332fab2150 hack for avoiding libmongoclient to crash on broken cursor 2014-03-07 07:31:42 +01:00
Roberto De Ioris 62d74951db support for git-based plugins 2014-03-05 08:28:17 +01:00
Roberto De Ioris 839638a0ad report socket name on invalid zeromq syntax 2014-03-04 06:38:42 +01:00
Roberto De Ioris 536ae8d013 fixed mongrel2 post_fork hook 2014-03-04 06:32:40 +01:00
Roberto De Ioris 367c4b9bab added on_demand sockets support to mongodb Emperor plugin 2014-03-04 06:08:16 +01:00
Roberto De Ioris 3965c01880 on __APPLE__ use LOG_NOTICE for syslog plugin 2014-03-04 05:44:18 +01:00
Unbit 7e4341a7cd force on demand unix socket to 666 2014-03-02 10:14:58 +01:00
Unbit 8c118c8f62 fixed (and improved) on demand emperor socket 2014-03-02 09:36:17 +01:00
Unbit 5d76b63fac fixed #555 2014-03-01 08:25:35 +01:00
28 changed files with 497 additions and 117 deletions
+1
View File
@@ -7,6 +7,7 @@
/uwsgi
/uwsgibuild.*
/core/config_py.c
/t/ring/target
+1
View File
@@ -26,3 +26,4 @@ Natanael Copa
Roberto Leandrini
Ryan Petrello
Danila Shtan <danila@shtan.ru>
Ævar Arnfjörð Bjarmason
+4 -4
View File
@@ -18,18 +18,18 @@ void uwsgi_alarm_init_log(struct uwsgi_alarm_instance *uai) {
void uwsgi_alarm_func_log(struct uwsgi_alarm_instance *uai, char *msg, size_t len) {
if (msg[len-1] != '\n') {
if (uai->arg && strlen(uai->arg) > 0) {
uwsgi_log_alarm("] %s %.*s\n", uai->arg, len, msg);
uwsgi_log_verbose("ALARM: %s %.*s\n", uai->arg, len, msg);
}
else {
uwsgi_log_alarm("] %.*s\n", len, msg);
uwsgi_log_verbose("ALARM: %.*s\n", len, msg);
}
}
else {
if (uai->arg && strlen(uai->arg) > 0) {
uwsgi_log_alarm("] %s %.*s", uai->arg, len, msg);
uwsgi_log_verbose("ALARM: %s %.*s", uai->arg, len, msg);
}
else {
uwsgi_log_alarm("] %.*s", len, msg);
uwsgi_log_verbose("ALARM: %.*s", len, msg);
}
}
}
+140 -38
View File
@@ -39,6 +39,70 @@ struct uwsgi_emperor_blacklist_item {
struct uwsgi_emperor_blacklist_item *emperor_blacklist;
/*
this should be placed in core/socket.c but we realized it was needed
only after 2.0 so we cannot change uwsgi.h
basically it is a stripped down bind_to_tcp/bind_to_unix with rollback
*/
static int on_demand_bind(char *socket_name) {
union uwsgi_sockaddr us;
socklen_t addr_len = sizeof(struct sockaddr_un);
char *is_tcp = strchr(socket_name, ':');
int af_family = is_tcp ? AF_INET : AF_UNIX;
int fd = socket(af_family, SOCK_STREAM, 0);
if (fd < 0) return -1;
memset(&us, 0, sizeof(union uwsgi_sockaddr));
if (is_tcp) {
int reuse = 1;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void *) &reuse, sizeof(int)) < 0) {
goto error;
}
us.sa_in.sin_family = AF_INET;
us.sa_in.sin_port = htons(atoi(is_tcp+1));
*is_tcp = 0;
if (socket_name[0] != 0) {
us.sa_in.sin_addr.s_addr = inet_addr(socket_name);
}
else {
us.sa_in.sin_addr.s_addr = INADDR_ANY;
}
*is_tcp = ':';
addr_len = sizeof(struct sockaddr_in);
}
else {
if (unlink(socket_name) != 0 && errno != ENOENT) {
goto error;
}
us.sa_un.sun_family = AF_UNIX;
memcpy(us.sa_un.sun_path, socket_name, UMIN(strlen(socket_name), 102));
addr_len = strlen(socket_name) + ((void *) us.sa_un.sun_path - (void *) &us.sa_un);
}
if (bind(fd, (struct sockaddr *) &us, addr_len) != 0) {
goto error;
}
if (!is_tcp) {
if (chmod(socket_name, 0666)) {
goto error;
}
}
if (listen(fd, uwsgi.listen_queue) != 0) {
goto error;
}
return fd;
error:
close(fd);
return -1;
}
struct uwsgi_emperor_blacklist_item *uwsgi_emperor_blacklist_check(char *id) {
struct uwsgi_emperor_blacklist_item *uebi = emperor_blacklist;
while (uebi) {
@@ -157,7 +221,7 @@ static char *emperor_check_on_demand_socket(char *filename) {
if (fd < 0) return NULL;
char *ret = uwsgi_read_fd(fd, &len, 1);
close(fd);
// change the first non prinabel character to 0
// change the first non printable character to 0
size_t i;
for(i=0;i<len;i++) {
if (ret[i] < 32) {
@@ -629,6 +693,10 @@ void emperor_del(struct uwsgi_instance *c_ui) {
free(c_ui->socket_name);
}
if (c_ui->on_demand_fd != -1) {
close(c_ui->on_demand_fd);
}
free(c_ui);
}
@@ -637,8 +705,10 @@ void emperor_stop(struct uwsgi_instance *c_ui) {
if (c_ui->status == 1) return;
// remove uWSGI instance
if (write(c_ui->pipe[0], "\0", 1) != 1) {
uwsgi_error("emperor_stop()/write()");
if (c_ui->pid != -1) {
if (write(c_ui->pipe[0], "\0", 1) != 1) {
uwsgi_error("emperor_stop()/write()");
}
}
c_ui->status = 1;
@@ -658,10 +728,27 @@ void emperor_curse(struct uwsgi_instance *c_ui) {
}
// send configuration (if required to the vassal)
static void emperor_push_config(struct uwsgi_instance *c_ui) {
struct uwsgi_header uh;
if (c_ui->use_config) {
uh.modifier1 = 115;
uh.pktsize = c_ui->config_len;
uh.modifier2 = 0;
if (write(c_ui->pipe_config[0], &uh, 4) != 4) {
uwsgi_error("[uwsgi-emperor] write() header config");
}
else {
if (write(c_ui->pipe_config[0], c_ui->config, c_ui->config_len) != (long) c_ui->config_len) {
uwsgi_error("[uwsgi-emperor] write() config");
}
}
}
}
void emperor_respawn(struct uwsgi_instance *c_ui, time_t mod) {
struct uwsgi_header uh;
// reload the uWSGI instance
if (write(c_ui->pipe[0], "\1", 1) != 1) {
@@ -669,20 +756,7 @@ void emperor_respawn(struct uwsgi_instance *c_ui, time_t mod) {
}
// push the config to the config pipe (if needed)
if (c_ui->use_config) {
uh.modifier1 = 115;
uh.pktsize = c_ui->config_len;
uh.modifier2 = 0;
if (write(c_ui->pipe_config[0], &uh, 4) != 4) {
uwsgi_error("[uwsgi-emperor] write() header config");
}
else {
if (write(c_ui->pipe_config[0], c_ui->config, c_ui->config_len) != (long) c_ui->config_len) {
uwsgi_error("[uwsgi-emperor] write() config");
}
}
}
emperor_push_config(c_ui);
c_ui->respawns++;
c_ui->last_mod = mod;
@@ -794,21 +868,12 @@ void emperor_add(struct uwsgi_emperor_scanner *ues, char *name, time_t born, cha
}
n_ui->pid = -1;
n_ui->pipe[0] = -1;
n_ui->pipe[1] = -1;
// ok here we check if we need to bind to the specified socket or continue with the activation
if (socket_name) {
char *tcp_port = strchr(socket_name, ':');
if (tcp_port) {
// disable deferred accept for this socket
int current_defer_accept = uwsgi.no_defer_accept;
uwsgi.no_defer_accept = 1;
n_ui->on_demand_fd = bind_to_tcp(socket_name, uwsgi.listen_queue, tcp_port);
uwsgi.no_defer_accept = current_defer_accept;
}
else {
n_ui->on_demand_fd = bind_to_unix(socket_name, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
}
n_ui->on_demand_fd = on_demand_bind(socket_name);
if (n_ui->on_demand_fd < 0) {
uwsgi_error("emperor_add()/bind()");
free(n_ui);
@@ -838,6 +903,7 @@ int uwsgi_emperor_vassal_start(struct uwsgi_instance *n_ui) {
uwsgi_error("socketpair()");
return -1;
}
uwsgi_socket_nb(n_ui->pipe[0]);
event_queue_add_fd_read(uwsgi.emperor_queue, n_ui->pipe[0]);
@@ -846,6 +912,7 @@ int uwsgi_emperor_vassal_start(struct uwsgi_instance *n_ui) {
uwsgi_error("socketpair()");
return -1;
}
uwsgi_socket_nb(n_ui->pipe_config[0]);
}
if (n_ui->zerg) {
@@ -1452,6 +1519,17 @@ int uwsgi_emperor_scanner_event(int fd) {
}
static void emperor_wakeup(int sn) {}
static void emperor_cleanup() {
uwsgi_log_verbose("[uwsgi-emperor] cleaning up blacklist ...\n");
struct uwsgi_instance *ui_current = ui;
while (ui_current->ui_next) {
uwsgi_emperor_blacklist_remove(ui_current->name);
ui_current = ui_current->ui_next;
}
}
void emperor_loop() {
// monitor a directory
@@ -1480,11 +1558,13 @@ void emperor_loop() {
}
signal(SIGPIPE, SIG_IGN);
signal(SIGWINCH, emperor_wakeup);
uwsgi_unix_signal(SIGINT, royal_death);
uwsgi_unix_signal(SIGTERM, royal_death);
uwsgi_unix_signal(SIGQUIT, royal_death);
uwsgi_unix_signal(SIGUSR1, emperor_stats);
uwsgi_unix_signal(SIGHUP, emperor_massive_reload);
uwsgi_unix_signal(SIGURG, emperor_cleanup);
memset(&ui_base, 0, sizeof(struct uwsgi_instance));
@@ -1552,7 +1632,11 @@ void emperor_loop() {
ui_current = ui->ui_next;
while (ui_current) {
uwsgi_log_verbose("[emperor] NO MERCY for vassal %s !!!\n", ui_current->name);
kill(ui_current->pid, SIGKILL);
if (kill(ui_current->pid, SIGKILL) < 0) {
uwsgi_error("[emperor] kill()");
emperor_del(ui_current);
break;
}
ui_current = ui_current->ui_next;
}
break;
@@ -1635,6 +1719,9 @@ void emperor_loop() {
ui_current->last_ready = uwsgi_now();
uwsgi_log_verbose("[emperor] vassal %s has been spawned\n", ui_current->name);
}
else if (byte == 2) {
emperor_push_config(ui_current);
}
}
}
else {
@@ -1667,8 +1754,10 @@ void emperor_loop() {
// set last_heartbeat to 0 avoiding races
ui_current->last_heartbeat = 0;
if (ui_current->pid > 0) {
if (kill(ui_current->pid, SIGKILL)) {
if (kill(ui_current->pid, SIGKILL) < 0) {
uwsgi_error("[emperor] kill()");
emperor_del(ui_current);
break;
}
}
}
@@ -1676,6 +1765,8 @@ void emperor_loop() {
ui_current = ui_current->ui_next;
}
recheck:
// check for removed instances
ui_current = ui;
has_children = 0;
@@ -1720,7 +1811,7 @@ void emperor_loop() {
while (ui_current->ui_next) {
ui_current = ui_current->ui_next;
time_t now = uwsgi_now();
if (ui_current->pid == diedpid) {
if (diedpid > 0 && ui_current->pid == diedpid) {
if (ui_current->status == 0) {
// respawn an accidentally dead instance if its exit code is not UWSGI_EXILE_CODE
if (WIFEXITED(waitpid_status) && WEXITSTATUS(waitpid_status) == UWSGI_EXILE_CODE) {
@@ -1743,15 +1834,26 @@ void emperor_loop() {
break;
}
}
else if (ui_current->cursed_at > 0 && now - ui_current->cursed_at >= uwsgi.emperor_curse_tolerance) {
ui_current->cursed_at = now;
if (kill(ui_current->pid, SIGKILL)) {
uwsgi_error("[emperor] kill");
else if (ui_current->cursed_at > 0) {
if (ui_current->pid == -1) {
emperor_del(ui_current);
break;
}
else if (now - ui_current->cursed_at >= uwsgi.emperor_curse_tolerance) {
ui_current->cursed_at = now;
if (kill(ui_current->pid, SIGKILL) < 0) {
uwsgi_error("[emperor] kill()");
// delete the vassal, something is seriously wrong better to not leak memory...
emperor_del(ui_current);
}
break;
}
break;
}
}
// if waitpid returned an item, let's check for another (potential) one
if (diedpid > 0) goto recheck;
}
+9
View File
@@ -48,6 +48,14 @@ static void subscriptions_blocker() {
}
}
static void emperor_rescan() {
if (uwsgi.emperor_pid > 0) {
if (kill(uwsgi.emperor_pid, SIGWINCH)) {
uwsgi_error("emperor_rescan()/kill()");
}
}
}
/*
this is called as soon as possibile allowing plugins (or hooks) to override it
@@ -74,6 +82,7 @@ void uwsgi_master_fifo_prepare() {
uwsgi_fifo_table['+'] = uwsgi_cheaper_increase;
uwsgi_fifo_table['c'] = uwsgi_chain_reload;
uwsgi_fifo_table['C'] = uwsgi_go_cheap;
uwsgi_fifo_table['E'] = emperor_rescan;
uwsgi_fifo_table['f'] = uwsgi_refork_master;
uwsgi_fifo_table['l'] = uwsgi_log_reopen;
uwsgi_fifo_table['L'] = uwsgi_log_rotate;
+9 -1
View File
@@ -412,9 +412,17 @@ void uwsgi_reload(char **argv) {
uwsgi_log("fork()'ing uWSGI...\n");
}
// ask for configuration (if needed)
if (uwsgi.has_emperor && uwsgi.emperor_fd_config > -1) {
char byte = 2;
if (write(uwsgi.emperor_fd, &byte, 1) != 1) {
uwsgi_error("uwsgi_reload()/write()");
}
}
uwsgi_log("chdir() to %s\n", uwsgi.cwd);
if (chdir(uwsgi.cwd)) {
uwsgi_error("chdir()");
uwsgi_error("uwsgi_reload()/chdir()");
}
/* check fd table (a module can obviosly open some fd on initialization...) */
+15
View File
@@ -943,6 +943,20 @@ static int uwsgi_router_clearheaders(struct uwsgi_route *ur, char *arg) {
return 0;
}
// disable headers
static int uwsgi_router_disableheaders_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
wsgi_req->headers_sent = 1;
return UWSGI_ROUTE_NEXT;
}
static int uwsgi_router_disableheaders(struct uwsgi_route *ur, char *arg) {
ur->func = uwsgi_router_disableheaders_func;
ur->data = arg;
ur->data_len = strlen(arg);
return 0;
}
// signal route
static int uwsgi_router_signal_func(struct wsgi_request *wsgi_req, struct uwsgi_route *route) {
@@ -1737,6 +1751,7 @@ void uwsgi_register_embedded_routers() {
uwsgi_register_router("remheader", uwsgi_router_remheader);
uwsgi_register_router("clearheaders", uwsgi_router_clearheaders);
uwsgi_register_router("resetheaders", uwsgi_router_clearheaders);
uwsgi_register_router("disableheaders", uwsgi_router_disableheaders);
uwsgi_register_router("signal", uwsgi_router_signal);
uwsgi_register_router("send", uwsgi_router_send);
uwsgi_register_router("send-crnl", uwsgi_router_send_crnl);
+5
View File
@@ -190,6 +190,11 @@ static void spooler_req_parser_hook(char *key, uint16_t key_len, char *value, ui
}
if (!uwsgi_strncmp(key, key_len, "at", 2)) {
// at can be a float...
char *dot = memchr(value, '.', value_len);
if (dot) {
value_len = dot - value;
}
sr->at = uwsgi_str_num(value, value_len);
return;
}
+9 -7
View File
@@ -245,17 +245,19 @@ SSL_CTX *uwsgi_ssl_new_server_context(char *name, char *crt, char *key, char *ci
if (dh) {
SSL_CTX_set_tmp_dh(ctx, dh);
DH_free(dh);
}
}
#if OPENSSL_VERSION_NUMBER >= 0x0090800fL
#ifndef OPENSSL_NO_ECDH
#ifdef NID_X9_62_prime256v1
EC_KEY *ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
SSL_CTX_set_tmp_ecdh(ctx, ecdh);
EC_KEY_free(ecdh);
#endif
#endif
#endif
}
EC_KEY *ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
if (ecdh) {
SSL_CTX_set_tmp_ecdh(ctx, ecdh);
EC_KEY_free(ecdh);
}
#endif
#endif
#endif
if (crt_need_free) free(crt);
+9 -7
View File
@@ -1,4 +1,4 @@
#include "uwsgi.h"
#include <uwsgi.h>
/*
@@ -10,6 +10,8 @@
extern struct uwsgi_server uwsgi;
#define REQ_DATA wsgi_req->method_len, wsgi_req->method, wsgi_req->uri_len, wsgi_req->uri, wsgi_req->remote_addr_len, wsgi_req->remote_addr
static struct uwsgi_buffer *uwsgi_websocket_message(struct wsgi_request *wsgi_req, char *msg, size_t len, uint8_t opcode) {
struct uwsgi_buffer *ub = wsgi_req->websocket_send_buf;
if (!ub) {
@@ -61,7 +63,7 @@ static int uwsgi_websockets_check_pingpong(struct wsgi_request *wsgi_req) {
// pong not received ?
if (wsgi_req->websocket_last_pong < wsgi_req->websocket_last_ping) {
if (wsgi_req->websocket_last_ping - wsgi_req->websocket_last_pong > uwsgi.websockets_pong_tolerance) {
uwsgi_log("[uwsgi-websocket] no PONG received in %d seconds !!!\n", uwsgi.websockets_pong_tolerance);
uwsgi_log("[uwsgi-websocket] \"%.*s %.*s\" (%.*s) no PONG received in %d seconds !!!\n", REQ_DATA, uwsgi.websockets_pong_tolerance);
return -1;
}
return 0;
@@ -189,7 +191,7 @@ static ssize_t uwsgi_websockets_recv_pkt(struct wsgi_request *wsgi_req, int nb)
}
goto wait;
}
uwsgi_error("uwsgi_websockets_recv_pkt()");
uwsgi_req_error("uwsgi_websockets_recv_pkt()");
return -1;
}
@@ -201,7 +203,7 @@ wait:
if (rlen <= 0) return -1;
}
if (ret < 0) {
uwsgi_error("uwsgi_websockets_recv_pkt()");
uwsgi_req_error("uwsgi_websockets_recv_pkt()");
return -1;
}
// send unsolicited pong
@@ -254,11 +256,11 @@ static struct uwsgi_buffer *uwsgi_websocket_recv_do(struct wsgi_request *wsgi_re
wsgi_req->websocket_size = uwsgi_be64(wsgi_req->websocket_buf->buf+2);
}
else {
uwsgi_log("[uwsgi-websocket] BUG error in websocket parser\n");
uwsgi_log("[uwsgi-websocket] \"%.*s %.*s\" (%.*s) BUG error in websocket parser\n", REQ_DATA);
return NULL;
}
if (wsgi_req->websocket_size > (uwsgi.websockets_max_size*1024)) {
uwsgi_log("[uwsgi-websocket] invalid packet size received: %llu, max allowed: %llu\n", wsgi_req->websocket_size, uwsgi.websockets_max_size * 1024);
uwsgi_log("[uwsgi-websocket] \"%.*s %.*s\" (%.*s) invalid packet size received: %llu, max allowed: %llu\n", REQ_DATA, wsgi_req->websocket_size, uwsgi.websockets_max_size * 1024);
return NULL;
}
wsgi_req->websocket_phase = 2;
@@ -312,7 +314,7 @@ static struct uwsgi_buffer *uwsgi_websocket_recv_do(struct wsgi_request *wsgi_re
break;
// oops
default:
uwsgi_log("[uwsgi-websocket] BUG error in websocket parser\n");
uwsgi_log("[uwsgi-websocket] \"%.*s %.*s\" (%.*s) BUG error in websocket parser\n", REQ_DATA);
return NULL;
}
}
+2 -2
View File
@@ -7,8 +7,8 @@
#define cr_add_timeout_fast(u, x, t) uwsgi_add_rb_timer(u->timeouts, t+u->socket_timeout, x)
#define cr_del_timeout(u, x) uwsgi_del_rb_timer(u->timeouts, x->timeout); free(x->timeout);
#define uwsgi_cr_error(x, y) uwsgi_log("[uwsgi-%s client_addr: %s client_port: %s] %s: %s [%s line %d]\n", x->session->corerouter->short_name, x->session->client_address, x->session->client_port, y, strerror(errno), __FILE__, __LINE__)
#define uwsgi_cr_log(x, y, ...) uwsgi_log("[uwsgi-%s client_addr: %s client_port: %s]" y, x->session->corerouter->short_name, x->session->client_address, x->session->client_port, __VA_ARGS__)
#define uwsgi_cr_error(x, y) uwsgi_log("[uwsgi-%s key: %.*s client_addr: %s client_port: %s] %s: %s [%s line %d]\n", x->session->corerouter->short_name, x->session->main_peer ? x->session->main_peer->key_len : 0, x->session->main_peer ? x->session->main_peer->key: "", x->session->client_address, x->session->client_port, y, strerror(errno), __FILE__, __LINE__)
#define uwsgi_cr_log(x, y, ...) uwsgi_log("[uwsgi-%s key: %.*s client_addr: %s client_port: %s]" y, x->session->corerouter->short_name, x->session->main_peer ? x->session->main_peer->key_len : 0, x->session->main_peer ? x->session->main_peer->key : "", x->session->client_address, x->session->client_port, __VA_ARGS__)
#define cr_try_again if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) {\
errno = EINPROGRESS;\
+5 -2
View File
@@ -20,7 +20,7 @@ extern "C" void uwsgi_imperial_monitor_mongodb(struct uwsgi_emperor_scanner *ues
try {
// requested fields
mongo::BSONObj p = BSON( "name" << 1 << "config" << 1 << "ts" << 1 << "uid" << 1 << "gid" << 1 );
mongo::BSONObj p = BSON( "name" << 1 << "config" << 1 << "ts" << 1 << "uid" << 1 << "gid" << 1 << "socket" << 1 );
mongo::BSONObj q = mongo::fromjson(uems->json);
// the connection object (will be automatically destroyed at each cycle)
mongo::DBClientConnection c;
@@ -31,7 +31,7 @@ extern "C" void uwsgi_imperial_monitor_mongodb(struct uwsgi_emperor_scanner *ues
// run the query
std::auto_ptr<mongo::DBClientCursor> cursor = c.query(uems->collection, q, 0, 0, &p);
while( cursor->more() ) {
while(cursor.get() && cursor->more() ) {
mongo::BSONObj p = cursor->next();
// checking for an empty string is not required, but we reduce the load
@@ -40,6 +40,7 @@ extern "C" void uwsgi_imperial_monitor_mongodb(struct uwsgi_emperor_scanner *ues
if (strlen(name) == 0) continue;
const char *config = p.getStringField("config");
if (strlen(config) == 0) config = NULL;
time_t vassal_ts = 0;
// ts must be a Date object !!!
@@ -61,6 +62,7 @@ extern "C" void uwsgi_imperial_monitor_mongodb(struct uwsgi_emperor_scanner *ues
}
const char *socket_name = p.getStringField("socket");
if (strlen(socket_name) == 0) socket_name = NULL;
uwsgi_emperor_simple_do(ues, (char *) name, (char *) config, vassal_ts/1000, vassal_uid, vassal_gid, (char *) socket_name);
}
@@ -76,6 +78,7 @@ extern "C" void uwsgi_imperial_monitor_mongodb(struct uwsgi_emperor_scanner *ues
b.append("name", c_ui->name);
mongo::BSONObj q2 = b.obj();
cursor = c.query(uems->collection, q2, 0, 0, &p);
if (!cursor.get()) return;
#ifdef UWSGI_DEBUG
uwsgi_log("JSON: %s\n", q2.toString().c_str());
#endif
+46 -33
View File
@@ -102,6 +102,10 @@ static int uwsgi_mongrel2_json_parse(json_t * root, struct wsgi_request *wsgi_re
}
}
if ((json_val = uwsgi_mongrel2_json_get_string(root, "URL_SCHEME"))) {
wsgi_req->uh->pktsize += proto_base_add_uwsgi_var(wsgi_req, "UWSGI_SCHEME", 12, json_val, strlen(json_val));
}
if ((json_val = uwsgi_mongrel2_json_get_string(root, "host"))) {
char *colon = strchr(json_val, ':');
if (colon) {
@@ -210,6 +214,9 @@ static int uwsgi_mongrel2_tnetstring_parse(struct wsgi_request *wsgi_req, char *
wsgi_req->uh->pktsize += proto_base_add_uwsgi_var(wsgi_req, "REQUEST_URI", 11, val, vallen);
}
}
else if (!uwsgi_strncmp("URL_SCHEME", 10, key, keylen)) {
wsgi_req->uh->pktsize += proto_base_add_uwsgi_var(wsgi_req, "UWSGI_SCHEME", 12, val, vallen);
}
}
else {
// add header
@@ -299,6 +306,13 @@ void uwsgi_proto_zeromq_thread_fixup(struct uwsgi_socket *uwsgi_sock, int async_
// fake function, the body is in a file or completely in memory
ssize_t uwsgi_proto_zeromq_read_body(struct wsgi_request *wsgi_req, char *buf, size_t len) {
size_t remains = wsgi_req->post_cl - wsgi_req->proto_parser_status;
if (remains > 0) {
if (len > remains) len = remains;
memcpy(buf, wsgi_req->proto_parser_buf + wsgi_req->proto_parser_buf_size + wsgi_req->proto_parser_status, len);
wsgi_req->proto_parser_status += len;
return len;
}
return 0;
}
@@ -410,7 +424,8 @@ int uwsgi_proto_zeromq_accept(struct wsgi_request *wsgi_req, int fd) {
}
// pre-build the mongrel2 response_header
wsgi_req->proto_parser_buf = uwsgi_malloc(req_uuid_len + 1 + 11 + 1 + req_id_len + 1 + 1);
wsgi_req->proto_parser_buf_size = req_uuid_len + 1 + 11 + 1 + req_id_len + 1 + 1;
wsgi_req->proto_parser_buf = uwsgi_malloc(wsgi_req->proto_parser_buf_size);
memcpy(wsgi_req->proto_parser_buf, req_uuid, req_uuid_len);
((char *) wsgi_req->proto_parser_buf)[req_uuid_len] = ' ';
resp_id_len = uwsgi_num2str2(req_id_len, wsgi_req->proto_parser_buf + req_uuid_len + 1);
@@ -422,13 +437,22 @@ int uwsgi_proto_zeromq_accept(struct wsgi_request *wsgi_req, int fd) {
wsgi_req->proto_parser_pos = (uint64_t) req_uuid_len + 1 + resp_id_len + 1 + req_id_len + 1 + 1;
// handle post data (in memory)
// reallocate wsgi_req->proto_parser_buf and change its size to be able to store request body
// the parser status holds the current position for read_body hook
if (wsgi_req->post_cl > 0 && !wsgi_req->post_file) {
if (uwsgi_netstring(post_data, message_size - (post_data - message_ptr), &message_ptr, &wsgi_req->post_cl)) {
char *tmp = realloc(wsgi_req->proto_parser_buf, wsgi_req->proto_parser_buf_size + wsgi_req->post_cl);
if (!tmp) {
uwsgi_error("realloc()");
exit(1);
}
wsgi_req->proto_parser_buf = tmp;
// status is an offset...
wsgi_req->proto_parser_status = 0;
#ifdef UWSGI_DEBUG
uwsgi_log("post_size: %d\n", wsgi_req->post_cl);
#endif
wsgi_req->post_read_buf = uwsgi_malloc(wsgi_req->post_cl);
memcpy(wsgi_req->post_read_buf, message_ptr, wsgi_req->post_cl);
memcpy(wsgi_req->proto_parser_buf + wsgi_req->proto_parser_buf_size, message_ptr, wsgi_req->post_cl);
}
}
@@ -452,33 +476,7 @@ retry:
return -1;
}
void uwsgi_proto_zeromq_close(struct wsgi_request *wsgi_req) {
zmq_msg_t reply;
// check for already freed wsgi_req->proto_parser_buf/wsgi_req->proto_parser_pos
if (!wsgi_req->proto_parser_pos)
return;
// no need to pass a free function (the buffer will be freed during cloe_request)
zmq_msg_init_data(&reply, wsgi_req->proto_parser_buf, wsgi_req->proto_parser_pos, NULL, NULL);
if (uwsgi.threads > 1)
pthread_mutex_lock(&wsgi_req->socket->lock);
#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3,0,0)
if (zmq_sendmsg(wsgi_req->socket->pub, &reply, 0)) {
uwsgi_error("uwsgi_proto_zeromq_close()/zmq_sendmsg()");
#else
if (zmq_send(wsgi_req->socket->pub, &reply, 0)) {
uwsgi_error("uwsgi_proto_zeromq_close()/zmq_send()");
#endif
}
if (uwsgi.threads > 1)
pthread_mutex_unlock(&wsgi_req->socket->lock);
zmq_msg_close(&reply);
}
int uwsgi_proto_zeromq_write(struct wsgi_request *wsgi_req, char *buf, size_t len) {
static int uwsgi_proto_zeromq_write_do(struct wsgi_request *wsgi_req, char *buf, size_t len) {
zmq_msg_t reply;
if (zmq_msg_init_size(&reply, wsgi_req->proto_parser_pos + len)) {
@@ -489,7 +487,8 @@ int uwsgi_proto_zeromq_write(struct wsgi_request *wsgi_req, char *buf, size_t le
char *zmq_body = zmq_msg_data(&reply);
memcpy(zmq_body, wsgi_req->proto_parser_buf, wsgi_req->proto_parser_pos);
memcpy(zmq_body + wsgi_req->proto_parser_pos, buf, len);
if (len > 0)
memcpy(zmq_body + wsgi_req->proto_parser_pos, buf, len);
if (uwsgi.threads > 1)
pthread_mutex_lock(&wsgi_req->socket->lock);
@@ -510,6 +509,18 @@ int uwsgi_proto_zeromq_write(struct wsgi_request *wsgi_req, char *buf, size_t le
return UWSGI_OK;
}
int uwsgi_proto_zeromq_write(struct wsgi_request *wsgi_req, char *buf, size_t len) {
int ret = uwsgi_proto_zeromq_write_do(wsgi_req, buf, len);
if (ret == UWSGI_OK) {
wsgi_req->write_pos += len;
}
return ret;
}
void uwsgi_proto_zeromq_close(struct wsgi_request *wsgi_req) {
uwsgi_proto_zeromq_write_do(wsgi_req, "", 0);
}
/*
we have a problem... recent Mongrel2 releases introduced a ring buffer that limit the amount of messages we can send (or better, the amount of
@@ -532,7 +543,7 @@ int uwsgi_proto_zeromq_sendfile(struct wsgi_request *wsgi_req, int fd, size_t po
return -1;
}
wsgi_req->write_pos += rlen;
if (uwsgi_proto_zeromq_write(wsgi_req, tmp_buf, rlen) < 0) {
if (uwsgi_proto_zeromq_write_do(wsgi_req, tmp_buf, rlen) < 0) {
free(tmp_buf);
return -1;
}
@@ -574,6 +585,7 @@ static void mongrel2_register_proto() {
static void mongrel2_connect() {
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
while(uwsgi_sock) {
if (uwsgi_sock->proto != uwsgi_proto_zeromq_parser) goto next;
uwsgi_sock->ctx = zmq_init(1);
if (!uwsgi_sock->ctx) {
uwsgi_error("mongrel2_connect()/zmq_init()");
@@ -581,7 +593,7 @@ static void mongrel2_connect() {
}
char *responder = strchr(uwsgi_sock->name, ',');
if (!responder) {
uwsgi_log("invalid zeromq address\n");
uwsgi_log("invalid zeromq address: %s\n", uwsgi_sock->name);
exit(1);
}
uwsgi_sock->receiver = uwsgi_concat2n(uwsgi_sock->name, responder - uwsgi_sock->name, "", 0);
@@ -653,6 +665,7 @@ static void mongrel2_connect() {
#else
uwsgi_sock->recv_flag = ZMQ_NOBLOCK;
#endif
next:
uwsgi_sock = uwsgi_sock->next;
}
}
+7 -3
View File
@@ -54,7 +54,7 @@ XS(XS_psgix_logger) {
psgi_check_args(1);
HV *hv_args = (HV *) (SvRV(ST(0)));
if (!hv_exists(hv_args, "level", 5) || !hv_exists(hv_args, "message", 7)) {
Perl_croak(aTHX_ "psgix.logger requires bot level and message items");
Perl_croak(aTHX_ "psgix.logger requires both level and message items");
}
char *level = SvPV_nolen(*(hv_fetch(hv_args, "level", 5, 0)));
char *message = SvPV_nolen(*(hv_fetch(hv_args, "message", 7, 0)));
@@ -108,7 +108,7 @@ XS(XS_input_read) {
unsigned long arg_len = SvIV(ST(2));
long offset = 0;
if (items > 2) {
if (items > 3) {
offset = (long) SvIV(ST(3));
}
@@ -370,12 +370,16 @@ int init_psgi_app(struct wsgi_request *wsgi_req, char *app, uint16_t app_len, Pe
// uperl.embedding as an argument so we won't execute
// BEGIN blocks in app_name twice.
{
char *perl_init_arg[] = { "", "-e", "0" };
char *perl_e_arg = uwsgi_concat2("#line 0 ", app_name);
char *perl_init_arg[] = { "", "-e", perl_e_arg };
if (perl_parse(interpreters[i], xs_init, 3, perl_init_arg, NULL)) {
// what to do here ? i hope no-one will use threads with dynamic apps... but clear the whole stuff...
free(callables);
free(perl_e_arg);
uwsgi_perl_free_stashes();
goto clear;
} else {
free(perl_e_arg);
}
}
+23
View File
@@ -955,6 +955,27 @@ XS(XS_spool) {
XSRETURN_UNDEF;
}
XS(XS_add_var) {
dXSARGS;
psgi_check_args(2);
struct wsgi_request *wsgi_req = current_wsgi_req();
STRLEN keylen;
char *key = SvPV(ST(0), keylen);
STRLEN vallen;
char *val = SvPV(ST(1), vallen);
if (!uwsgi_req_append(wsgi_req, key, keylen, val, vallen)) {
croak("unable to add request var, check your buffer size");
XSRETURN_UNDEF;
}
XSRETURN_YES;
}
void init_perl_embedded_module() {
psgi_xs(reload);
@@ -1016,5 +1037,7 @@ void init_perl_embedded_module() {
psgi_xs(spooler);
psgi_xs(spool);
psgi_xs(add_var);
}
+8
View File
@@ -197,6 +197,12 @@ int uwsgi_python_init() {
uwsgi_log_initial("Python version: %.*s %s\n", pyversion-Py_GetVersion(), Py_GetVersion(), Py_GetCompiler()+1);
}
if (Py_IsInitialized()) {
uwsgi_log("--- Python VM already initialized ---\n");
PyGILState_Ensure();
goto ready;
}
if (up.home != NULL) {
#ifdef PYTHREE
// check for PEP 405 virtualenv (starting from python 3.3)
@@ -251,6 +257,8 @@ pep405:
Py_Initialize();
ready:
if (!uwsgi.has_threads) {
uwsgi_log_initial("*** Python threads support is disabled. You can enable it with --enable-threads ***\n");
}
+22
View File
@@ -4,6 +4,26 @@ extern struct uwsgi_server uwsgi;
extern struct uwsgi_python up;
extern struct uwsgi_plugin python_plugin;
static PyObject *py_uwsgi_add_var(PyObject * self, PyObject * args) {
char *key = NULL;
Py_ssize_t keylen = 0;
char *val = NULL;
Py_ssize_t vallen = 0;
struct wsgi_request *wsgi_req = py_current_wsgi_req();
if (!PyArg_ParseTuple(args, "s#s#", &key, &keylen, &val, &vallen)) {
return NULL;
}
if (!uwsgi_req_append(wsgi_req, key, keylen, val, vallen)) {
return PyErr_Format(PyExc_ValueError, "unable to add request var, check your buffer size");
}
Py_INCREF(Py_True);
return Py_True;
}
static PyObject *py_uwsgi_signal_wait(PyObject * self, PyObject * args) {
struct wsgi_request *wsgi_req = py_current_wsgi_req();
@@ -2417,6 +2437,8 @@ static PyMethodDef uwsgi_advanced_methods[] = {
{"ready_fd", py_uwsgi_ready_fd, METH_VARARGS, ""},
{"add_var", py_uwsgi_add_var, METH_VARARGS, ""},
{NULL, NULL},
};
+4
View File
@@ -93,7 +93,11 @@ ssize_t uwsgi_syslog_logger(struct uwsgi_logger *ul, char *message, size_t len)
ul->configured = 1;
}
#ifdef __APPLE__
syslog(LOG_NOTICE, "%.*s", (int) len, message);
#else
syslog(LOG_INFO, "%.*s", (int) len, message);
#endif
return 0;
}
+18 -8
View File
@@ -2,6 +2,16 @@
extern struct uwsgi_tuntap utt;
// error reporting
void uwsgi_tuntap_error_do(struct uwsgi_tuntap_peer *uttp, char *msg, char *file, int line) {
if (uttp) {
uwsgi_log_verbose("[tuntap] peer fd: %d ip: %s %s: %s [%s line %d]\n", uttp->fd, uttp->ip, msg, strerror(errno), file, line);
}
else {
uwsgi_log_verbose("[tuntap] %s: %s [%s line %d]\n", msg, strerror(errno), file, line);
}
}
// create a new peer
struct uwsgi_tuntap_peer *uwsgi_tuntap_peer_create(struct uwsgi_tuntap_router *uttr, int fd, int is_router) {
@@ -183,7 +193,7 @@ int uwsgi_tuntap_register_addr(struct uwsgi_tuntap_router *uttr, struct uwsgi_tu
char ip[INET_ADDRSTRLEN + 1];
memset(ip, 0, INET_ADDRSTRLEN + 1);
if (!inet_ntop(AF_INET, &uttp->addr, ip, INET_ADDRSTRLEN)) {
uwsgi_error("uwsgi_tuntap_register_addr()/inet_ntop()");
uwsgi_tuntap_error(uttp, "uwsgi_tuntap_register_addr()/inet_ntop()");
return -1;
}
if (uttp != tmp_uttp) {
@@ -205,7 +215,7 @@ int uwsgi_tuntap_peer_dequeue(struct uwsgi_tuntap_router *uttr, struct uwsgi_tun
if (rlen < 0) {
if (uwsgi_is_again())
return 0;
uwsgi_error("uwsgi_tuntap_peer_dequeue()/read()");
uwsgi_tuntap_error(uttp, "uwsgi_tuntap_peer_dequeue()/read()");
return -1;
}
uttp->buf_pos += rlen;
@@ -265,7 +275,7 @@ enqueue:
if (rlen < 0) {
if (uwsgi_is_again())
return 0;
uwsgi_error("uwsgi_tuntap_peer_dequeue()/read()");
uwsgi_tuntap_error(uttp, "uwsgi_tuntap_peer_dequeue()/read()");
return -1;
}
uttp->header_pos += rlen;
@@ -282,14 +292,14 @@ int uwsgi_tuntap_peer_enqueue(struct uwsgi_tuntap_router *uttr, struct uwsgi_tun
ssize_t rlen = write(uttp->fd, uttp->write_buf + uttp->written, uttp->write_buf_pktsize - uttp->written);
if (rlen == 0) {
uwsgi_error("uwsgi_tuntap_peer_enqueue()/write()");
uwsgi_tuntap_error(uttp, "uwsgi_tuntap_peer_enqueue()/write()");
return -1;
}
if (rlen < 0) {
if (uwsgi_is_again())
goto retry;
uwsgi_error("uwsgi_tuntap_peer_enqueue()/write()");
uwsgi_tuntap_error(uttp, "uwsgi_tuntap_peer_enqueue()/write()");
return -1;
}
@@ -303,13 +313,13 @@ int uwsgi_tuntap_peer_enqueue(struct uwsgi_tuntap_router *uttr, struct uwsgi_tun
if (uttr->wait_for_write) {
uttp->blocked_read = 1;
if (event_queue_del_fd(uttr->queue, uttp->fd, event_queue_write())) {
uwsgi_error("uwsgi_tuntap_peer_enqueue()/event_queue_del_fd()");
uwsgi_tuntap_error(uttp, "uwsgi_tuntap_peer_enqueue()/event_queue_del_fd()");
return -1;
}
}
else {
if (event_queue_fd_readwrite_to_read(uttr->queue, uttp->fd)) {
uwsgi_error("uwsgi_tuntap_peer_enqueue()/event_queue_fd_write_to_read()");
uwsgi_tuntap_error(uttp, "uwsgi_tuntap_peer_enqueue()/event_queue_fd_write_to_read()");
return -1;
}
}
@@ -324,7 +334,7 @@ int uwsgi_tuntap_peer_enqueue(struct uwsgi_tuntap_router *uttr, struct uwsgi_tun
retry:
if (!uttp->wait_for_write) {
if (event_queue_fd_read_to_readwrite(uttr->queue, uttp->fd)) {
uwsgi_error("uwsgi_tuntap_peer_enqueue()/event_queue_fd_read_to_write()");
uwsgi_tuntap_error(uttp, "uwsgi_tuntap_peer_enqueue()/event_queue_fd_read_to_write()");
return -1;
}
uttp->wait_for_write = 1;
+2
View File
@@ -116,3 +116,5 @@ int uwsgi_tuntap_register_addr(struct uwsgi_tuntap_router *, struct uwsgi_tuntap
void uwsgi_tuntap_peer_send_rules(int, struct uwsgi_tuntap_peer *);
int uwsgi_tuntap_peer_rules_check(struct uwsgi_tuntap_router *, struct uwsgi_tuntap_peer *, char *, size_t, int);
#define uwsgi_tuntap_error(x, y) uwsgi_tuntap_error_do(x, y, __FILE__, __LINE__)
void uwsgi_tuntap_error_do(struct uwsgi_tuntap_peer *, char *, char *, int);
+24 -5
View File
@@ -1,6 +1,7 @@
#include "common.h"
extern struct uwsgi_tuntap utt;
extern struct uwsgi_server uwsgi;
int uwsgi_tuntap_peer_rules_check(struct uwsgi_tuntap_router *uttr, struct uwsgi_tuntap_peer *uttp, char *pkt, size_t len, int direction) {
if (uttp->rules_cnt == 0) return 0;
@@ -51,7 +52,25 @@ int uwsgi_tuntap_peer_rules_check(struct uwsgi_tuntap_router *uttr, struct uwsgi
sin.sin_port = rule->target_port;
sin.sin_addr.s_addr = rule->target;
if (sendto(uttr->gateway_fd, pkt, len, 0, (struct sockaddr *) &sin, sizeof(struct sockaddr_in)) < 0) {
uwsgi_error("uwsgi_tuntap_route_check()/sendto()");
if (uwsgi_is_again()) {
// suspend and retry
struct pollfd pfd;
memset(&pfd, 0, sizeof(struct pollfd));
pfd.fd = uttr->gateway_fd;
pfd.events = POLLOUT;
int ret = poll(&pfd, 1, uwsgi.socket_timeout * 1000);
if (ret > 0) {
if (sendto(uttr->gateway_fd, pkt, len, 0, (struct sockaddr *) &sin, sizeof(struct sockaddr_in)) < 0) {
uwsgi_tuntap_error(uttp,"uwsgi_tuntap_route_check()/sendto()");
}
}
else {
uwsgi_tuntap_error(uttp,"uwsgi_tuntap_route_check()/poll()");
}
}
else {
uwsgi_tuntap_error(uttp,"uwsgi_tuntap_route_check()/sendto()");
}
}
}
return 2;
@@ -305,7 +324,7 @@ void uwsgi_tuntap_peer_send_rules(int fd, struct uwsgi_tuntap_peer *peer) {
*slash = 0;
}
if (inet_pton(AF_INET, argv[1], &utpr.src) != 1) {
uwsgi_error("uwsgi_tuntap_peer_send_rules()/inet_pton()");
uwsgi_tuntap_error(peer, "uwsgi_tuntap_peer_send_rules()/inet_pton()");
exit(1);
}
if (slash) *slash = '/';
@@ -317,7 +336,7 @@ void uwsgi_tuntap_peer_send_rules(int fd, struct uwsgi_tuntap_peer *peer) {
*slash = 0;
}
if (inet_pton(AF_INET, argv[2], &utpr.dst) != 1) {
uwsgi_error("uwsgi_tuntap_peer_send_rules()/inet_pton()");
uwsgi_tuntap_error(peer, "uwsgi_tuntap_peer_send_rules()/inet_pton()");
exit(1);
}
if (slash) *slash = '/';
@@ -352,7 +371,7 @@ void uwsgi_tuntap_peer_send_rules(int fd, struct uwsgi_tuntap_peer *peer) {
}
*colon = 0;
if (inet_pton(AF_INET, argv[4], &utpr.target) != 1) {
uwsgi_error("uwsgi_tuntap_peer_send_rules()/inet_pton()");
uwsgi_tuntap_error(peer, "uwsgi_tuntap_peer_send_rules()/inet_pton()");
exit(1);
}
*colon = ':';
@@ -370,7 +389,7 @@ void uwsgi_tuntap_peer_send_rules(int fd, struct uwsgi_tuntap_peer *peer) {
size_t len = ub->pos;
uwsgi_buffer_destroy(ub);
if (write(fd,peer->rules, len) != (ssize_t)len) {
uwsgi_error("uwsgi_tuntap_peer_send_rules()/write()");
uwsgi_tuntap_error(peer, "uwsgi_tuntap_peer_send_rules()/write()");
exit(1);
}
return;
+11 -4
View File
@@ -117,6 +117,13 @@ static void *uwsgi_tuntap_loop(void *arg) {
uwsgi_error("uwsgi_tuntap_loop()/read()");
exit(1);
}
// check for full write buffer
if (uttp->write_buf_pktsize + 4 + rlen > utt.buffer_size) {
uttp->dropped++;
continue;
}
uint16_t pktsize = rlen;
char *ptr = uttp->write_buf + uttp->write_buf_pktsize;
memcpy(ptr + 4, uttr->buf, rlen);
@@ -126,7 +133,7 @@ static void *uwsgi_tuntap_loop(void *arg) {
ptr[3] = 0;
uttp->write_buf_pktsize+= pktsize+4;
if (uwsgi_tuntap_peer_enqueue(uttr, uttp)) {
uwsgi_log("server disconnected...\n");
uwsgi_log_verbose("tuntap server disconnected...\n");
exit(1);
}
continue;
@@ -137,7 +144,7 @@ static void *uwsgi_tuntap_loop(void *arg) {
// read from the client
if (!uttp->wait_for_write) {
if (uwsgi_tuntap_peer_dequeue(uttr, uttp, 0)) {
uwsgi_log("server disconnected...\n");
uwsgi_log_verbose("tuntap server disconnected...\n");
exit(1);
}
}
@@ -149,7 +156,7 @@ static void *uwsgi_tuntap_loop(void *arg) {
// write to the client
if (uwsgi_tuntap_peer_enqueue(uttr, uttp)) {
uwsgi_log("server disconnected...\n");
uwsgi_log_verbose("tuntap server disconnected...\n");
exit(1);
}
}
@@ -507,7 +514,7 @@ void tuntaprouter_send_stats(struct uwsgi_tuntap_router *uttr) {
ssize_t res = write(client_fd, us->base + pos, remains);
if (res <= 0) {
if (res < 0) {
uwsgi_error("write()");
uwsgi_error("tuntaprouter_send_stats()/write()");
}
goto end0;
}
+4
View File
@@ -59,6 +59,10 @@ my $app = sub {
uwsgi::signal(17);
uwsgi::signal(30);
my ($package, $filename, $line) = caller;
die "Expecting reasonable caller() return values, not [$package, $filename, $line]"
unless $package eq 'main' and $filename =~ /\btest\.psgi$/s and $line == 0;
if ($env->{'psgix.cleanup'}) {
print "cleanup supported\n";
push @{$env->{'psgix.cleanup.handlers'}}, $one;
+3 -1
View File
@@ -20,11 +20,13 @@ push @tests, ['1', 'HELLO', "oHELLOo_three_four"];
push @tests, ['3', 'HELLO', "oneHELLOthree_four"];
push @tests, ['30', 'HELLO', "one_two_three_four\0\0\0\0\0\0\0\0\0\0\0\0HELLO"];
@ARGV or die "You must provide a host to test on, e.g. localhost:8080";
foreach(@tests) {
print "testing: offset(".$_->[0].") body(".$_->[1].")\n";
my $req = "POST /?".$base." HTTP/1.0\r\nContent-Length: ".length($_->[1])."\r\nuWSGI-Offset: ".$_->[0]."\r\n\r\n".$_->[1];
my $s = IO::Socket::INET->new(PeerAddr => $ARGV[0]);
my $s = IO::Socket::INET->new(PeerAddr => $ARGV[0]) or die "PANIC: Unable to construct socket";
$s->send($req);
my $response = '';
+47
View File
@@ -0,0 +1,47 @@
use strict;
use warnings;
sub {
my $env = shift;
my $cl = $env->{CONTENT_LENGTH};
$env->{'psgi.input'}->seek(0,0);
my $content = '';
while ($cl) {
$env->{'psgi.input'}->read(my $chunk, $cl < 8192 ? $cl : 8192);
my $read = length $chunk;
$cl -= $read;
$content .= $chunk;
}
return [200, [], [ "Your content was: <$content>" ]];
};
__END__
This is a trival test that prints out a POST request, it's here to
test a regression introduced in 2.0-103-gf041d10 where doing reads
without offsets, e.g.:
$ http_proxy= curl -d '{ "what": "ever" }' http://localhost:8080/
Your content was: $VAR1 = '{ "what": "ever" }';
Would result in:
Use of uninitialized value in subroutine entry at
/home/v-perlbrew/perl5/perlbrew/perls/perl-5.19.6/lib/site_perl/5.19.6/Plack/Request.pm
line 280.
Which is due to this commit having a one-off error in counting stack
items.
$ git bisect good
f041d1095ddf7541c4b275e16d2ed3355a8e2be9 is the first bad commit
commit f041d1095ddf7541c4b275e16d2ed3355a8e2be9
Author: Unbit <info@unbit.it>
Date: Wed Feb 5 11:21:01 2014 +0100
perl refactoring
:040000 040000 98a25406b7edb9bd0b9be8bbcd351a99e7ce2d33 0087e3ca4b6bd65a087fade65d43a56085298ef0 M plugins
+48
View File
@@ -0,0 +1,48 @@
use strict;
use warnings;
sub {
my $env = shift;
return sub {
my $responder = shift;
my $writer = $responder->([ 200, [ 'Content-Type', 'text/plain' ]]);
sleep 3;
$writer->write("hello\n");
sleep 3;
$writer->write("world\n");
$writer->close;
return;
};
}
__END__
Making a request to this will give you:
$ date; curl -s -N -D - 'http://localhost:8080'
Sat Mar 15 14:08:25 UTC 2014
HTTP/1.1 200 OK
Content-Type: text/plain
hello
world
And monitoring it with tcpflow shows how the output (including
headers) is flushed right away:
$ sudo tcpflow -i lo -c port 8080 | perl -pe 's/^/localtime . " "/ge'
Sat Mar 15 14:09:08 2014 127.000.000.001.55058-127.000.000.001.08080: GET / HTTP/1.1
Sat Mar 15 14:09:08 2014 User-Agent: curl/7.35.0
Sat Mar 15 14:09:08 2014 Host: localhost:8080
Sat Mar 15 14:09:08 2014 Accept: */*
Sat Mar 15 14:09:08 2014
Sat Mar 15 14:09:08 2014
Sat Mar 15 14:09:08 2014 127.000.000.001.08080-127.000.000.001.55058: HTTP/1.1 200 OK
Sat Mar 15 14:09:08 2014 Content-Type: text/plain
Sat Mar 15 14:09:08 2014
Sat Mar 15 14:09:08 2014
Sat Mar 15 14:09:11 2014 127.000.000.001.08080-127.000.000.001.55058: hello
Sat Mar 15 14:09:11 2014
Sat Mar 15 14:09:14 2014 127.000.000.001.08080-127.000.000.001.55058: world
Sat Mar 15 14:09:14 2014
+1 -1
View File
@@ -2,7 +2,7 @@ Gem::Specification.new do |s|
s.name = 'uwsgi'
s.license = 'GPL-2'
s.version = `python -c "import uwsgiconfig as uc; print uc.uwsgi_version"`.sub(/-dev-.*/,'')
s.date = '2014-02-26'
s.date = '2014-03-17'
s.summary = "uWSGI"
s.description = "The uWSGI server for Ruby/Rack"
s.authors = ["Unbit"]
+20 -1
View File
@@ -1,6 +1,6 @@
# uWSGI build system
uwsgi_version = '2.0.2'
uwsgi_version = '2.0.3'
import os
import re
@@ -367,6 +367,15 @@ def build_uwsgi(uc, print_only=False, gcll=None):
if len(kv) > 1:
p = kv[1]
p = p.strip()
if p.startswith('http://') or p.startswith('https://') or p.startswith('git://') or p.startswith('ssh://'):
git_dir = p.split('/').pop()
if not os.path.isdir(git_dir):
if os.system('git clone %s' % p) != 0:
sys.exit(1)
else:
if os.system('cd %s ; git pull' % git_dir) != 0:
sys.exit(1)
p = git_dir
path = os.path.abspath(p)
else:
p = kv[0]
@@ -1275,6 +1284,16 @@ def build_plugin(path, uc, cflags, ldflags, libs, name = None):
up = {}
if path.startswith('http://') or path.startswith('https://') or path.startswith('git://') or path.startswith('ssh://'):
git_dir = path.split('/').pop()
if not os.path.isdir(git_dir):
if os.system('git clone %s' % path) != 0:
sys.exit(1)
else:
if os.system('cd %s ; git pull' % git_dir) != 0:
sys.exit(1)
path = os.path.abspath(git_dir)
if os.path.isfile(path):
bname = os.path.basename(path)
# override path