Hello community,

here is the log from the commit of package uwsgi for openSUSE:Factory checked 
in at 2014-04-09 13:17:40
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/uwsgi (Old)
 and      /work/SRC/openSUSE:Factory/.uwsgi.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "uwsgi"

Changes:
--------
--- /work/SRC/openSUSE:Factory/uwsgi/uwsgi.changes      2014-03-28 
16:29:12.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.uwsgi.new/uwsgi.changes 2014-04-09 
13:17:41.000000000 +0200
@@ -1,0 +2,31 @@
+Sat Mar 29 17:28:02 UTC 2014 - jf...@funktronics.ca
+
+- Update to 2.0.3:
+  * Bugfixes
+    * fixed spooler 'at' key usage
+    * fixed a memory and fd leak with on-demand Emperor sockets
+    * on __APPLE__ use LOG_NOTICE for syslog plugin
+    * fixed mongrel2 support
+    * hack for avoiding libmongoclient to crash on broken cursor
+    * log alarm is now a uwsgi_log_verbose() wrapper
+    * fixed tuntap router memory corruption
+    * Set ECDHE curve independently from DHE parameters (Hynek Schlawack)
+    * do not wait for a whole Emperor cycle before checking for each waitpid
+    * fix a regression with caller() not indicating the starting *.psgi program
+      (Ævar Arnfjörð Bjarmason)
+  * New features
+    * The Emperor now responds to two new signals:
+      * SIGWINCH: force an emperor rescan of vassals
+      * SIGURG: cleanup the Emperor states (for now it only clears its 
blacklist)
+    * --build-plugin. Building plugins on-the-fly from git repositories
+    * uwsgi.add_var(key, value). You can now set request variables directly
+      from your app, for better integration with the internal routing
+      subsystem
+    * 'disableheaders' routing action. This new action disables the sending of
+      response headers, independently by the current request state
+    * Smarter Emperor on bad conditions. Now the Emperor completely destroys
+      internal vassal-related structures when it is impossible to correctly
+      kill a broken vassal (both for inconsistent Emperor state or for
+      internal system problems)
+
+-------------------------------------------------------------------
@@ -4 +35 @@
-- Update to 2.0.1:
+- Update to 2.0.2:

Old:
----
  uwsgi-2.0.2.tar.gz

New:
----
  uwsgi-2.0.3.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ uwsgi.spec ++++++
--- /var/tmp/diff_new_pack.jQl7rt/_old  2014-04-09 13:17:42.000000000 +0200
+++ /var/tmp/diff_new_pack.jQl7rt/_new  2014-04-09 13:17:42.000000000 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           uwsgi
-Version:        2.0.2
+Version:        2.0.3
 Release:        0
 Summary:        Application Container Server for Networked/Clustered Web 
Applications
 License:        GPL-2.0-with-GCC-exception

++++++ uwsgi-2.0.2.tar.gz -> uwsgi-2.0.3.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.2/.gitignore new/uwsgi-2.0.3/.gitignore
--- old/uwsgi-2.0.2/.gitignore  2014-02-26 17:06:47.000000000 +0100
+++ new/uwsgi-2.0.3/.gitignore  2014-03-17 06:33:04.000000000 +0100
@@ -7,6 +7,7 @@
 
 /uwsgi
 /uwsgibuild.*
+/core/config_py.c
 
 /t/ring/target
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.2/CONTRIBUTORS new/uwsgi-2.0.3/CONTRIBUTORS
--- old/uwsgi-2.0.2/CONTRIBUTORS        2014-02-26 17:06:47.000000000 +0100
+++ new/uwsgi-2.0.3/CONTRIBUTORS        2014-03-17 06:33:04.000000000 +0100
@@ -26,3 +26,4 @@
 Roberto Leandrini
 Ryan Petrello
 Danila Shtan <dan...@shtan.ru>
+Ævar Arnfjörð Bjarmason
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.2/core/alarm.c new/uwsgi-2.0.3/core/alarm.c
--- old/uwsgi-2.0.2/core/alarm.c        2014-02-26 17:06:47.000000000 +0100
+++ new/uwsgi-2.0.3/core/alarm.c        2014-03-17 06:33:04.000000000 +0100
@@ -18,18 +18,18 @@
 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);
                }
        }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.2/core/emperor.c 
new/uwsgi-2.0.3/core/emperor.c
--- old/uwsgi-2.0.2/core/emperor.c      2014-02-26 17:06:47.000000000 +0100
+++ new/uwsgi-2.0.3/core/emperor.c      2014-03-17 06:33:04.000000000 +0100
@@ -39,6 +39,70 @@
 
 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 @@
                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 @@
                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 @@
        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 @@
 
 }
 
+// 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 @@
        }
 
        // 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 @@
        }
 
        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 @@
                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 @@
                        uwsgi_error("socketpair()");
                        return -1;
                }
+               uwsgi_socket_nb(n_ui->pipe_config[0]);
        }
 
        if (n_ui->zerg) {
@@ -1452,6 +1519,17 @@
 
 }
 
+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 @@
        }
 
        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 @@
                                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 @@
                                                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 @@
                                        // 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 @@
                        ui_current = ui_current->ui_next;
                }
 
+
+recheck:
                // check for removed instances
                ui_current = ui;
                has_children = 0;
@@ -1720,7 +1811,7 @@
                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 @@
                                        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;
+
 
        }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.2/core/fifo.c new/uwsgi-2.0.3/core/fifo.c
--- old/uwsgi-2.0.2/core/fifo.c 2014-02-26 17:06:47.000000000 +0100
+++ new/uwsgi-2.0.3/core/fifo.c 2014-03-17 06:33:04.000000000 +0100
@@ -48,6 +48,14 @@
        }
 }
 
+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 @@
        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;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.2/core/master_utils.c 
new/uwsgi-2.0.3/core/master_utils.c
--- old/uwsgi-2.0.2/core/master_utils.c 2014-02-26 17:06:47.000000000 +0100
+++ new/uwsgi-2.0.3/core/master_utils.c 2014-03-17 06:33:04.000000000 +0100
@@ -412,9 +412,17 @@
                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...) */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.2/core/routing.c 
new/uwsgi-2.0.3/core/routing.c
--- old/uwsgi-2.0.2/core/routing.c      2014-02-26 17:06:47.000000000 +0100
+++ new/uwsgi-2.0.3/core/routing.c      2014-03-17 06:33:04.000000000 +0100
@@ -943,6 +943,20 @@
         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 @@
         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);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.2/core/spooler.c 
new/uwsgi-2.0.3/core/spooler.c
--- old/uwsgi-2.0.2/core/spooler.c      2014-02-26 17:06:47.000000000 +0100
+++ new/uwsgi-2.0.3/core/spooler.c      2014-03-17 06:33:04.000000000 +0100
@@ -190,6 +190,11 @@
         }
 
        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;
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.2/core/ssl.c new/uwsgi-2.0.3/core/ssl.c
--- old/uwsgi-2.0.2/core/ssl.c  2014-02-26 17:06:47.000000000 +0100
+++ new/uwsgi-2.0.3/core/ssl.c  2014-03-17 06:33:04.000000000 +0100
@@ -245,17 +245,19 @@
                 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);
+        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);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.2/core/websockets.c 
new/uwsgi-2.0.3/core/websockets.c
--- old/uwsgi-2.0.2/core/websockets.c   2014-02-26 17:06:47.000000000 +0100
+++ new/uwsgi-2.0.3/core/websockets.c   2014-03-17 06:33:04.000000000 +0100
@@ -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 @@
        // 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 @@
                                }
                                 goto wait;
                         }
-                        uwsgi_error("uwsgi_websockets_recv_pkt()");
+                        uwsgi_req_error("uwsgi_websockets_recv_pkt()");
                         return -1;
                 }
 
@@ -201,7 +203,7 @@
                        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 @@
                                                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 @@
                                        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;
                        }
                }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.2/plugins/corerouter/cr.h 
new/uwsgi-2.0.3/plugins/corerouter/cr.h
--- old/uwsgi-2.0.2/plugins/corerouter/cr.h     2014-02-26 17:06:47.000000000 
+0100
+++ new/uwsgi-2.0.3/plugins/corerouter/cr.h     2014-03-17 06:33:04.000000000 
+0100
@@ -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;\
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/uwsgi-2.0.2/plugins/emperor_mongodb/emperor_mongodb.cc 
new/uwsgi-2.0.3/plugins/emperor_mongodb/emperor_mongodb.cc
--- old/uwsgi-2.0.2/plugins/emperor_mongodb/emperor_mongodb.cc  2014-02-26 
17:06:47.000000000 +0100
+++ new/uwsgi-2.0.3/plugins/emperor_mongodb/emperor_mongodb.cc  2014-03-17 
06:33:04.000000000 +0100
@@ -20,7 +20,7 @@
        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 @@
 
                // 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 @@
                        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 @@
                        } 
 
                        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 @@
                                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
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.2/plugins/mongrel2/mongrel2.c 
new/uwsgi-2.0.3/plugins/mongrel2/mongrel2.c
--- old/uwsgi-2.0.2/plugins/mongrel2/mongrel2.c 2014-02-26 17:06:47.000000000 
+0100
+++ new/uwsgi-2.0.3/plugins/mongrel2/mongrel2.c 2014-03-17 06:33:04.000000000 
+0100
@@ -102,6 +102,10 @@
                }
        }
 
+       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 @@
                                        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 @@
 
 // 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 @@
                }
 
                // 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 @@
                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 @@
        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 @@
 
        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 @@
        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 @@
                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_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 @@
                }
                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 @@
 #else
                uwsgi_sock->recv_flag = ZMQ_NOBLOCK;
 #endif
+next:
                uwsgi_sock = uwsgi_sock->next;
        }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.2/plugins/psgi/psgi_loader.c 
new/uwsgi-2.0.3/plugins/psgi/psgi_loader.c
--- old/uwsgi-2.0.2/plugins/psgi/psgi_loader.c  2014-02-26 17:06:47.000000000 
+0100
+++ new/uwsgi-2.0.3/plugins/psgi/psgi_loader.c  2014-03-17 06:33:04.000000000 
+0100
@@ -54,7 +54,7 @@
        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 @@
         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 @@
                // 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);
                        }
                }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.2/plugins/psgi/uwsgi_plmodule.c 
new/uwsgi-2.0.3/plugins/psgi/uwsgi_plmodule.c
--- old/uwsgi-2.0.2/plugins/psgi/uwsgi_plmodule.c       2014-02-26 
17:06:47.000000000 +0100
+++ new/uwsgi-2.0.3/plugins/psgi/uwsgi_plmodule.c       2014-03-17 
06:33:04.000000000 +0100
@@ -955,6 +955,27 @@
        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 @@
 
        psgi_xs(spooler);
        psgi_xs(spool);
+
+       psgi_xs(add_var);
        
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.2/plugins/python/python_plugin.c 
new/uwsgi-2.0.3/plugins/python/python_plugin.c
--- old/uwsgi-2.0.2/plugins/python/python_plugin.c      2014-02-26 
17:06:47.000000000 +0100
+++ new/uwsgi-2.0.3/plugins/python/python_plugin.c      2014-03-17 
06:33:04.000000000 +0100
@@ -197,6 +197,12 @@
                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 @@
 
        Py_Initialize();
 
+ready:
+
        if (!uwsgi.has_threads) {
                uwsgi_log_initial("*** Python threads support is disabled. You 
can enable it with --enable-threads ***\n");
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.2/plugins/python/uwsgi_pymodule.c 
new/uwsgi-2.0.3/plugins/python/uwsgi_pymodule.c
--- old/uwsgi-2.0.2/plugins/python/uwsgi_pymodule.c     2014-02-26 
17:06:47.000000000 +0100
+++ new/uwsgi-2.0.3/plugins/python/uwsgi_pymodule.c     2014-03-17 
06:33:04.000000000 +0100
@@ -4,6 +4,26 @@
 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 @@
 
        {"ready_fd", py_uwsgi_ready_fd, METH_VARARGS, ""},
 
+       {"add_var", py_uwsgi_add_var, METH_VARARGS, ""},
+
        {NULL, NULL},
 };
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.2/plugins/syslog/syslog_plugin.c 
new/uwsgi-2.0.3/plugins/syslog/syslog_plugin.c
--- old/uwsgi-2.0.2/plugins/syslog/syslog_plugin.c      2014-02-26 
17:06:47.000000000 +0100
+++ new/uwsgi-2.0.3/plugins/syslog/syslog_plugin.c      2014-03-17 
06:33:04.000000000 +0100
@@ -93,7 +93,11 @@
                ul->configured = 1;
        }
 
+#ifdef __APPLE__
+       syslog(LOG_NOTICE, "%.*s", (int) len, message);
+#else
        syslog(LOG_INFO, "%.*s", (int) len, message);
+#endif
        return 0;
 
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.2/plugins/tuntap/common.c 
new/uwsgi-2.0.3/plugins/tuntap/common.c
--- old/uwsgi-2.0.2/plugins/tuntap/common.c     2014-02-26 17:06:47.000000000 
+0100
+++ new/uwsgi-2.0.3/plugins/tuntap/common.c     2014-03-17 06:33:04.000000000 
+0100
@@ -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 @@
         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 @@
                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 @@
        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 @@
 
        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 @@
                        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 @@
 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;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.2/plugins/tuntap/common.h 
new/uwsgi-2.0.3/plugins/tuntap/common.h
--- old/uwsgi-2.0.2/plugins/tuntap/common.h     2014-02-26 17:06:47.000000000 
+0100
+++ new/uwsgi-2.0.3/plugins/tuntap/common.h     2014-03-17 06:33:04.000000000 
+0100
@@ -116,3 +116,5 @@
 
 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);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.2/plugins/tuntap/firewall.c 
new/uwsgi-2.0.3/plugins/tuntap/firewall.c
--- old/uwsgi-2.0.2/plugins/tuntap/firewall.c   2014-02-26 17:06:47.000000000 
+0100
+++ new/uwsgi-2.0.3/plugins/tuntap/firewall.c   2014-03-17 06:33:04.000000000 
+0100
@@ -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 @@
                                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 @@
                        *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 @@
                         *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 @@
                        }
                        *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 @@
        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;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.2/plugins/tuntap/tuntap.c 
new/uwsgi-2.0.3/plugins/tuntap/tuntap.c
--- old/uwsgi-2.0.2/plugins/tuntap/tuntap.c     2014-02-26 17:06:47.000000000 
+0100
+++ new/uwsgi-2.0.3/plugins/tuntap/tuntap.c     2014-03-17 06:33:04.000000000 
+0100
@@ -117,6 +117,13 @@
                                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 @@
                        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 @@
                        // 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 @@
 
                                // 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 @@
                 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;
                 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.2/t/perl/test.psgi 
new/uwsgi-2.0.3/t/perl/test.psgi
--- old/uwsgi-2.0.2/t/perl/test.psgi    2014-02-26 17:06:47.000000000 +0100
+++ new/uwsgi-2.0.3/t/perl/test.psgi    2014-03-17 06:33:04.000000000 +0100
@@ -59,6 +59,10 @@
        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;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.2/t/perl/test_input_with_offset.pl 
new/uwsgi-2.0.3/t/perl/test_input_with_offset.pl
--- old/uwsgi-2.0.2/t/perl/test_input_with_offset.pl    2014-02-26 
17:06:47.000000000 +0100
+++ new/uwsgi-2.0.3/t/perl/test_input_with_offset.pl    2014-03-17 
06:33:04.000000000 +0100
@@ -20,11 +20,13 @@
 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 = '';
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.2/t/perl/test_post.psgi 
new/uwsgi-2.0.3/t/perl/test_post.psgi
--- old/uwsgi-2.0.2/t/perl/test_post.psgi       1970-01-01 01:00:00.000000000 
+0100
+++ new/uwsgi-2.0.3/t/perl/test_post.psgi       2014-03-17 06:33:04.000000000 
+0100
@@ -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 <i...@unbit.it>
+    Date:   Wed Feb 5 11:21:01 2014 +0100
+
+        perl refactoring
+
+    :040000 040000 98a25406b7edb9bd0b9be8bbcd351a99e7ce2d33 
0087e3ca4b6bd65a087fade65d43a56085298ef0 M      plugins
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.2/t/perl/test_streaming.psgi 
new/uwsgi-2.0.3/t/perl/test_streaming.psgi
--- old/uwsgi-2.0.2/t/perl/test_streaming.psgi  1970-01-01 01:00:00.000000000 
+0100
+++ new/uwsgi-2.0.3/t/perl/test_streaming.psgi  2014-03-17 06:33:04.000000000 
+0100
@@ -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 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.2/uwsgi.gemspec 
new/uwsgi-2.0.3/uwsgi.gemspec
--- old/uwsgi-2.0.2/uwsgi.gemspec       2014-02-26 17:06:47.000000000 +0100
+++ new/uwsgi-2.0.3/uwsgi.gemspec       2014-03-17 06:33:04.000000000 +0100
@@ -2,7 +2,7 @@
   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"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.2/uwsgiconfig.py 
new/uwsgi-2.0.3/uwsgiconfig.py
--- old/uwsgi-2.0.2/uwsgiconfig.py      2014-02-26 17:06:47.000000000 +0100
+++ new/uwsgi-2.0.3/uwsgiconfig.py      2014-03-17 06:33:04.000000000 +0100
@@ -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 @@
                 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 @@
 
     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

++++++ uwsgi.dsc ++++++
--- /var/tmp/diff_new_pack.jQl7rt/_old  2014-04-09 13:17:42.000000000 +0200
+++ /var/tmp/diff_new_pack.jQl7rt/_new  2014-04-09 13:17:42.000000000 +0200
@@ -4,7 +4,7 @@
  python3-uwsgidecorators,
  uwsgi-extra
 Architecture: any all
-Version: 2.0.2-1
+Version: 2.0.3-1
 Maintainer: Janos Guljas <ja...@debian.org>
 Uploaders: Jonas Smedegaard <d...@jones.dk>
 Homepage: http://projects.unbit.it/uwsgi/

-- 
To unsubscribe, e-mail: opensuse-commit+unsubscr...@opensuse.org
For additional commands, e-mail: opensuse-commit+h...@opensuse.org

Reply via email to